shader_ir/decode: Fix half float pre-operations and remove MetaHalfArithmetic

Operations done before the main half float operation (like HAdd) were
managing a packed value instead of the unpacked one. Adding an unpacked
operation allows us to drop the per-operand MetaHalfArithmetic entry,
simplifying the code overall.
This commit is contained in:
ReinUsesLisp
2019-04-15 19:48:11 -03:00
parent abcbcb1b2a
commit f43995ec53
9 changed files with 72 additions and 85 deletions

View File

@ -109,12 +109,13 @@ enum class OperationCode {
UBitfieldExtract, /// (MetaArithmetic, uint value, int offset, int offset) -> uint
UBitCount, /// (MetaArithmetic, uint) -> uint
HAdd, /// (MetaHalfArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
HMul, /// (MetaHalfArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
HFma, /// (MetaHalfArithmetic, f16vec2 a, f16vec2 b, f16vec2 c) -> f16vec2
HAdd, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
HMul, /// (MetaArithmetic, f16vec2 a, f16vec2 b) -> f16vec2
HFma, /// (MetaArithmetic, f16vec2 a, f16vec2 b, f16vec2 c) -> f16vec2
HAbsolute, /// (f16vec2 a) -> f16vec2
HNegate, /// (f16vec2 a, bool first, bool second) -> f16vec2
HClamp, /// (f16vec2 src, float min, float max) -> f16vec2
HUnpack, /// (Tegra::Shader::HalfType, T value) -> f16vec2
HMergeF32, /// (f16vec2 src) -> float
HMergeH0, /// (f16vec2 dest, f16vec2 src) -> f16vec2
HMergeH1, /// (f16vec2 dest, f16vec2 src) -> f16vec2
@ -287,13 +288,6 @@ struct MetaArithmetic {
bool precise{};
};
struct MetaHalfArithmetic {
bool precise{};
std::array<Tegra::Shader::HalfType, 3> types = {Tegra::Shader::HalfType::H0_H1,
Tegra::Shader::HalfType::H0_H1,
Tegra::Shader::HalfType::H0_H1};
};
struct MetaTexture {
const Sampler& sampler;
Node array{};
@ -305,11 +299,10 @@ struct MetaTexture {
u32 element{};
};
constexpr MetaArithmetic PRECISE = {true};
constexpr MetaArithmetic NO_PRECISE = {false};
constexpr MetaHalfArithmetic HALF_NO_PRECISE = {false};
inline constexpr MetaArithmetic PRECISE = {true};
inline constexpr MetaArithmetic NO_PRECISE = {false};
using Meta = std::variant<MetaArithmetic, MetaHalfArithmetic, MetaTexture>;
using Meta = std::variant<MetaArithmetic, MetaTexture, Tegra::Shader::HalfType>;
/// Holds any kind of operation that can be done in the IR
class OperationNode final {
@ -713,6 +706,8 @@ private:
/// Unpacks a half immediate from an instruction
Node UnpackHalfImmediate(Tegra::Shader::Instruction instr, bool has_negation);
/// Unpacks a binary value into a half float pair with a type format
Node UnpackHalfFloat(Node value, Tegra::Shader::HalfType type);
/// Merges a half pair into another value
Node HalfMerge(Node dest, Node src, Tegra::Shader::HalfMerge merge);
/// Conditionally absolute/negated half float pair. Absolute is applied first
@ -726,8 +721,7 @@ private:
Node GetPredicateComparisonInteger(Tegra::Shader::PredCondition condition, bool is_signed,
Node op_a, Node op_b);
/// Returns a predicate comparing two half floats. meta consumes how both pairs will be compared
Node GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition,
const MetaHalfArithmetic& meta, Node op_a, Node op_b);
Node GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition, Node op_a, Node op_b);
/// Returns a predicate combiner operation
OperationCode GetPredicateCombiner(Tegra::Shader::PredOperation operation);