summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader/shader_ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/shader/shader_ir.cpp')
-rw-r--r--src/video_core/shader/shader_ir.cpp97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index 5951bdc7b..20a1a50ef 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -212,6 +212,103 @@ Node ShaderIR::GetOperandAbsNegHalf(Node value, bool absolute, bool negate) {
return value;
}
+Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) {
+ static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
+ {PredCondition::LessThan, OperationCode::LogicalFLessThan},
+ {PredCondition::Equal, OperationCode::LogicalFEqual},
+ {PredCondition::LessEqual, OperationCode::LogicalFLessEqual},
+ {PredCondition::GreaterThan, OperationCode::LogicalFGreaterThan},
+ {PredCondition::NotEqual, OperationCode::LogicalFNotEqual},
+ {PredCondition::GreaterEqual, OperationCode::LogicalFGreaterEqual},
+ {PredCondition::LessThanWithNan, OperationCode::LogicalFLessThan},
+ {PredCondition::NotEqualWithNan, OperationCode::LogicalFNotEqual},
+ {PredCondition::LessEqualWithNan, OperationCode::LogicalFLessEqual},
+ {PredCondition::GreaterThanWithNan, OperationCode::LogicalFGreaterThan},
+ {PredCondition::GreaterEqualWithNan, OperationCode::LogicalFGreaterEqual}};
+
+ const auto comparison{PredicateComparisonTable.find(condition)};
+ UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
+ "Unknown predicate comparison operation");
+
+ Node predicate = Operation(comparison->second, NO_PRECISE, op_a, op_b);
+
+ if (condition == PredCondition::LessThanWithNan ||
+ condition == PredCondition::NotEqualWithNan ||
+ condition == PredCondition::LessEqualWithNan ||
+ condition == PredCondition::GreaterThanWithNan ||
+ condition == PredCondition::GreaterEqualWithNan) {
+
+ predicate = Operation(OperationCode::LogicalOr, predicate,
+ Operation(OperationCode::LogicalFIsNan, op_a));
+ predicate = Operation(OperationCode::LogicalOr, predicate,
+ Operation(OperationCode::LogicalFIsNan, op_b));
+ }
+
+ return predicate;
+}
+
+Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_signed, Node op_a,
+ Node op_b) {
+ static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
+ {PredCondition::LessThan, OperationCode::LogicalILessThan},
+ {PredCondition::Equal, OperationCode::LogicalIEqual},
+ {PredCondition::LessEqual, OperationCode::LogicalILessEqual},
+ {PredCondition::GreaterThan, OperationCode::LogicalIGreaterThan},
+ {PredCondition::NotEqual, OperationCode::LogicalINotEqual},
+ {PredCondition::GreaterEqual, OperationCode::LogicalIGreaterEqual},
+ {PredCondition::LessThanWithNan, OperationCode::LogicalILessThan},
+ {PredCondition::NotEqualWithNan, OperationCode::LogicalINotEqual},
+ {PredCondition::LessEqualWithNan, OperationCode::LogicalILessEqual},
+ {PredCondition::GreaterThanWithNan, OperationCode::LogicalIGreaterThan},
+ {PredCondition::GreaterEqualWithNan, OperationCode::LogicalIGreaterEqual}};
+
+ const auto comparison{PredicateComparisonTable.find(condition)};
+ UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
+ "Unknown predicate comparison operation");
+
+ Node predicate = SignedOperation(comparison->second, is_signed, NO_PRECISE, op_a, op_b);
+
+ UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan ||
+ condition == PredCondition::NotEqualWithNan ||
+ condition == PredCondition::LessEqualWithNan ||
+ condition == PredCondition::GreaterThanWithNan ||
+ condition == PredCondition::GreaterEqualWithNan,
+ "NaN comparisons for integers are not implemented");
+ return predicate;
+}
+
+Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition,
+ const MetaHalfArithmetic& meta, Node op_a, Node op_b) {
+
+ UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan ||
+ condition == PredCondition::NotEqualWithNan ||
+ condition == PredCondition::LessEqualWithNan ||
+ condition == PredCondition::GreaterThanWithNan ||
+ condition == PredCondition::GreaterEqualWithNan,
+ "Unimplemented NaN comparison for half floats");
+
+ static const std::unordered_map<PredCondition, OperationCode> 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}};
+
+ const auto comparison{PredicateComparisonTable.find(condition)};
+ UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
+ "Unknown predicate comparison operation");
+
+ const Node predicate = Operation(comparison->second, meta, op_a, op_b);
+
+ return predicate;
+}
+
void ShaderIR::SetRegister(BasicBlock& bb, Register dest, Node src) {
bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), src));
}