diff --git a/src/video_core/shader/decode/half_set_predicate.cpp b/src/video_core/shader/decode/half_set_predicate.cpp index d7d63d50a4..72cc3d5c85 100644 --- a/src/video_core/shader/decode/half_set_predicate.cpp +++ b/src/video_core/shader/decode/half_set_predicate.cpp @@ -39,10 +39,12 @@ u32 ShaderIR::DecodeHalfSetPredicate(BasicBlock& bb, u32 pc) { const Node second_pred = GetPredicate(instr.hsetp2.pred39, instr.hsetp2.neg_pred != 0); const OperationCode combiner = GetPredicateCombiner(instr.hsetp2.op); + const OperationCode pair_combiner = + instr.hsetp2.h_and ? OperationCode::LogicalAll2 : OperationCode::LogicalAny2; - MetaHalfArithmetic meta = { - false, {instr.hsetp2.type_a, instr.hsetp2.type_b}, instr.hsetp2.h_and != 0}; - const Node first_pred = GetPredicateComparisonHalf(instr.hsetp2.cond, meta, op_a, op_b); + MetaHalfArithmetic meta = {false, {instr.hsetp2.type_a, instr.hsetp2.type_b}}; + const Node comparison = GetPredicateComparisonHalf(instr.hsetp2.cond, meta, op_a, op_b); + const Node first_pred = Operation(pair_combiner, comparison); // Set the primary predicate to the result of Predicate OP SecondPredicate const Node value = Operation(combiner, first_pred, second_pred); diff --git a/src/video_core/shader/glsl_decompiler.cpp b/src/video_core/shader/glsl_decompiler.cpp index c364a43cec..8a2cc3c311 100644 --- a/src/video_core/shader/glsl_decompiler.cpp +++ b/src/video_core/shader/glsl_decompiler.cpp @@ -31,7 +31,7 @@ using Operation = const OperationNode&; enum : u32 { POSITION_VARYING_LOCATION = 0, GENERIC_VARYING_START_LOCATION = 1 }; constexpr u32 MAX_CONSTBUFFER_ELEMENTS = 65536 / 16; // TODO(Rodrigo): Use rasterizer's value -enum class Type { Bool, Float, Int, Uint, HalfFloat }; +enum class Type { Bool, Bool2, Float, Int, Uint, HalfFloat }; class ShaderWriter { public: @@ -541,6 +541,7 @@ private: switch (type) { case Type::Bool: + case Type::Bool2: case Type::Float: return value; case Type::Int: @@ -1011,38 +1012,42 @@ private: return GenerateUnary(operation, "!", Type::Bool, Type::Bool, false); } - std::string LogicalHComparison(Operation operation, const std::string& func) { - const auto& meta = std::get(operation.GetMeta()); - const std::string op_a = VisitOperand(operation, 0, Type::HalfFloat); - const std::string op_b = VisitOperand(operation, 1, Type::HalfFloat); - - std::string value = meta.and_comparison ? "all" : "any"; - value += '(' + func + '(' + op_a + ", " + op_b + "))"; - return value; + std::string LogicalAll2(Operation operation) { + return GenerateUnary(operation, "all", Type::Bool, Type::Bool2); } - std::string LogicalHLessThan(Operation operation) { - return LogicalHComparison(operation, "lessThan"); + std::string LogicalAny2(Operation operation) { + return GenerateUnary(operation, "any", Type::Bool, Type::Bool2); } - std::string LogicalHEqual(Operation operation) { - return LogicalHComparison(operation, "equal"); + std::string Logical2HLessThan(Operation operation) { + return GenerateBinaryCall(operation, "lessThan", Type::Bool2, Type::HalfFloat, + Type::HalfFloat); } - std::string LogicalHLessEqual(Operation operation) { - return LogicalHComparison(operation, "lessThanEqual"); + std::string Logical2HEqual(Operation operation) { + return GenerateBinaryCall(operation, "equal", Type::Bool2, Type::HalfFloat, + Type::HalfFloat); } - std::string LogicalHGreaterThan(Operation operation) { - return LogicalHComparison(operation, "greaterThan"); + std::string Logical2HLessEqual(Operation operation) { + return GenerateBinaryCall(operation, "lessThanEqual", Type::Bool2, Type::HalfFloat, + Type::HalfFloat); } - std::string LogicalHNotEqual(Operation operation) { - return LogicalHComparison(operation, "notEqual"); + std::string Logical2HGreaterThan(Operation operation) { + return GenerateBinaryCall(operation, "greaterThan", Type::Bool2, Type::HalfFloat, + Type::HalfFloat); } - std::string LogicalHGreaterEqual(Operation operation) { - return LogicalHComparison(operation, "greaterThanEqual"); + std::string Logical2HNotEqual(Operation operation) { + return GenerateBinaryCall(operation, "notEqual", Type::Bool2, Type::HalfFloat, + Type::HalfFloat); + } + + std::string Logical2HGreaterEqual(Operation operation) { + return GenerateBinaryCall(operation, "greaterThanEqual", Type::Bool2, Type::HalfFloat, + Type::HalfFloat); } std::string F4Texture(Operation operation) { @@ -1301,6 +1306,8 @@ private: &LogicalOr, &LogicalXor, &LogicalNegate, + &LogicalAll2, + &LogicalAny2, &LogicalLessThan, &LogicalEqual, @@ -1324,12 +1331,12 @@ private: &LogicalNotEqual, &LogicalGreaterEqual, - &LogicalHLessThan, - &LogicalHEqual, - &LogicalHLessEqual, - &LogicalHGreaterThan, - &LogicalHNotEqual, - &LogicalHGreaterEqual, + &Logical2HLessThan, + &Logical2HEqual, + &Logical2HLessEqual, + &Logical2HGreaterThan, + &Logical2HNotEqual, + &Logical2HGreaterEqual, &F4Texture, &F4TextureLod, diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index 1fc838d15d..b076425178 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp @@ -289,17 +289,17 @@ Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition "Unimplemented NaN comparison for half floats"); static const std::unordered_map PredicateComparisonTable = { - {PredCondition::LessThan, OperationCode::LogicalHLessThan}, - {PredCondition::Equal, OperationCode::LogicalHEqual}, - {PredCondition::LessEqual, OperationCode::LogicalHLessEqual}, - {PredCondition::GreaterThan, OperationCode::LogicalHGreaterThan}, - {PredCondition::NotEqual, OperationCode::LogicalHNotEqual}, - {PredCondition::GreaterEqual, OperationCode::LogicalHGreaterEqual}, - {PredCondition::LessThanWithNan, OperationCode::LogicalHLessThan}, - {PredCondition::NotEqualWithNan, OperationCode::LogicalHNotEqual}, - {PredCondition::LessEqualWithNan, OperationCode::LogicalHLessEqual}, - {PredCondition::GreaterThanWithNan, OperationCode::LogicalHGreaterThan}, - {PredCondition::GreaterEqualWithNan, OperationCode::LogicalHGreaterEqual}}; + {PredCondition::LessThan, OperationCode::Logical2HLessThan}, + {PredCondition::Equal, OperationCode::Logical2HEqual}, + {PredCondition::LessEqual, OperationCode::Logical2HLessEqual}, + {PredCondition::GreaterThan, OperationCode::Logical2HGreaterThan}, + {PredCondition::NotEqual, OperationCode::Logical2HNotEqual}, + {PredCondition::GreaterEqual, OperationCode::Logical2HGreaterEqual}, + {PredCondition::LessThanWithNan, OperationCode::Logical2HLessThan}, + {PredCondition::NotEqualWithNan, OperationCode::Logical2HNotEqual}, + {PredCondition::LessEqualWithNan, OperationCode::Logical2HLessEqual}, + {PredCondition::GreaterThanWithNan, OperationCode::Logical2HGreaterThan}, + {PredCondition::GreaterEqualWithNan, OperationCode::Logical2HGreaterEqual}}; const auto comparison{PredicateComparisonTable.find(condition)}; UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 928e3e7d58..5ef0a7779d 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h @@ -122,6 +122,8 @@ enum class OperationCode { LogicalOr, /// (bool a, bool b) -> bool LogicalXor, /// (bool a, bool b) -> bool LogicalNegate, /// (bool a) -> bool + LogicalAll2, /// (bool2 a) -> bool + LogicalAny2, /// (bool2 a) -> bool LogicalFLessThan, /// (float a, float b) -> bool LogicalFEqual, /// (float a, float b) -> bool @@ -145,12 +147,12 @@ enum class OperationCode { LogicalUNotEqual, /// (uint a, uint b) -> bool LogicalUGreaterEqual, /// (uint a, uint b) -> bool - LogicalHLessThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool - LogicalHEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool - LogicalHLessEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool - LogicalHGreaterThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool - LogicalHNotEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool - LogicalHGreaterEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool + Logical2HLessThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 + Logical2HEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 + Logical2HLessEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 + Logical2HGreaterThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 + Logical2HNotEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 + Logical2HGreaterEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2 F4Texture, /// (MetaTexture, float[N] coords, float[M] params) -> float4 F4TextureLod, /// (MetaTexture, float[N] coords, float[M] params) -> float4 @@ -263,7 +265,6 @@ struct MetaHalfArithmetic { std::array types = {Tegra::Shader::HalfType::H0_H1, Tegra::Shader::HalfType::H0_H1, Tegra::Shader::HalfType::H0_H1}; - bool and_comparison{}; }; struct MetaTexture {