diff options
| author | 2018-12-20 23:01:03 -0300 | |
|---|---|---|
| committer | 2019-01-15 17:54:49 -0300 | |
| commit | bf07272695b718d09f8ef532539ba625dab01d3c (patch) | |
| tree | 756b0848eb8b0e94b4e650a2b3371a32e46b63a4 /src | |
| parent | shader_ir: Add half float helpers (diff) | |
| download | yuzu-bf07272695b718d09f8ef532539ba625dab01d3c.tar.gz yuzu-bf07272695b718d09f8ef532539ba625dab01d3c.tar.xz yuzu-bf07272695b718d09f8ef532539ba625dab01d3c.zip | |
shader_ir: Add comparison helpers
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 97 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 9 |
2 files changed, 106 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) { | |||
| 212 | return value; | 212 | return value; |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) { | ||
| 216 | static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = { | ||
| 217 | {PredCondition::LessThan, OperationCode::LogicalFLessThan}, | ||
| 218 | {PredCondition::Equal, OperationCode::LogicalFEqual}, | ||
| 219 | {PredCondition::LessEqual, OperationCode::LogicalFLessEqual}, | ||
| 220 | {PredCondition::GreaterThan, OperationCode::LogicalFGreaterThan}, | ||
| 221 | {PredCondition::NotEqual, OperationCode::LogicalFNotEqual}, | ||
| 222 | {PredCondition::GreaterEqual, OperationCode::LogicalFGreaterEqual}, | ||
| 223 | {PredCondition::LessThanWithNan, OperationCode::LogicalFLessThan}, | ||
| 224 | {PredCondition::NotEqualWithNan, OperationCode::LogicalFNotEqual}, | ||
| 225 | {PredCondition::LessEqualWithNan, OperationCode::LogicalFLessEqual}, | ||
| 226 | {PredCondition::GreaterThanWithNan, OperationCode::LogicalFGreaterThan}, | ||
| 227 | {PredCondition::GreaterEqualWithNan, OperationCode::LogicalFGreaterEqual}}; | ||
| 228 | |||
| 229 | const auto comparison{PredicateComparisonTable.find(condition)}; | ||
| 230 | UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), | ||
| 231 | "Unknown predicate comparison operation"); | ||
| 232 | |||
| 233 | Node predicate = Operation(comparison->second, NO_PRECISE, op_a, op_b); | ||
| 234 | |||
| 235 | if (condition == PredCondition::LessThanWithNan || | ||
| 236 | condition == PredCondition::NotEqualWithNan || | ||
| 237 | condition == PredCondition::LessEqualWithNan || | ||
| 238 | condition == PredCondition::GreaterThanWithNan || | ||
| 239 | condition == PredCondition::GreaterEqualWithNan) { | ||
| 240 | |||
| 241 | predicate = Operation(OperationCode::LogicalOr, predicate, | ||
| 242 | Operation(OperationCode::LogicalFIsNan, op_a)); | ||
| 243 | predicate = Operation(OperationCode::LogicalOr, predicate, | ||
| 244 | Operation(OperationCode::LogicalFIsNan, op_b)); | ||
| 245 | } | ||
| 246 | |||
| 247 | return predicate; | ||
| 248 | } | ||
| 249 | |||
| 250 | Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_signed, Node op_a, | ||
| 251 | Node op_b) { | ||
| 252 | static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = { | ||
| 253 | {PredCondition::LessThan, OperationCode::LogicalILessThan}, | ||
| 254 | {PredCondition::Equal, OperationCode::LogicalIEqual}, | ||
| 255 | {PredCondition::LessEqual, OperationCode::LogicalILessEqual}, | ||
| 256 | {PredCondition::GreaterThan, OperationCode::LogicalIGreaterThan}, | ||
| 257 | {PredCondition::NotEqual, OperationCode::LogicalINotEqual}, | ||
| 258 | {PredCondition::GreaterEqual, OperationCode::LogicalIGreaterEqual}, | ||
| 259 | {PredCondition::LessThanWithNan, OperationCode::LogicalILessThan}, | ||
| 260 | {PredCondition::NotEqualWithNan, OperationCode::LogicalINotEqual}, | ||
| 261 | {PredCondition::LessEqualWithNan, OperationCode::LogicalILessEqual}, | ||
| 262 | {PredCondition::GreaterThanWithNan, OperationCode::LogicalIGreaterThan}, | ||
| 263 | {PredCondition::GreaterEqualWithNan, OperationCode::LogicalIGreaterEqual}}; | ||
| 264 | |||
| 265 | const auto comparison{PredicateComparisonTable.find(condition)}; | ||
| 266 | UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), | ||
| 267 | "Unknown predicate comparison operation"); | ||
| 268 | |||
| 269 | Node predicate = SignedOperation(comparison->second, is_signed, NO_PRECISE, op_a, op_b); | ||
| 270 | |||
| 271 | UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan || | ||
| 272 | condition == PredCondition::NotEqualWithNan || | ||
| 273 | condition == PredCondition::LessEqualWithNan || | ||
| 274 | condition == PredCondition::GreaterThanWithNan || | ||
| 275 | condition == PredCondition::GreaterEqualWithNan, | ||
| 276 | "NaN comparisons for integers are not implemented"); | ||
| 277 | return predicate; | ||
| 278 | } | ||
| 279 | |||
| 280 | Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition, | ||
| 281 | const MetaHalfArithmetic& meta, Node op_a, Node op_b) { | ||
| 282 | |||
| 283 | UNIMPLEMENTED_IF_MSG(condition == PredCondition::LessThanWithNan || | ||
| 284 | condition == PredCondition::NotEqualWithNan || | ||
| 285 | condition == PredCondition::LessEqualWithNan || | ||
| 286 | condition == PredCondition::GreaterThanWithNan || | ||
| 287 | condition == PredCondition::GreaterEqualWithNan, | ||
| 288 | "Unimplemented NaN comparison for half floats"); | ||
| 289 | |||
| 290 | static const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = { | ||
| 291 | {PredCondition::LessThan, OperationCode::LogicalHLessThan}, | ||
| 292 | {PredCondition::Equal, OperationCode::LogicalHEqual}, | ||
| 293 | {PredCondition::LessEqual, OperationCode::LogicalHLessEqual}, | ||
| 294 | {PredCondition::GreaterThan, OperationCode::LogicalHGreaterThan}, | ||
| 295 | {PredCondition::NotEqual, OperationCode::LogicalHNotEqual}, | ||
| 296 | {PredCondition::GreaterEqual, OperationCode::LogicalHGreaterEqual}, | ||
| 297 | {PredCondition::LessThanWithNan, OperationCode::LogicalHLessThan}, | ||
| 298 | {PredCondition::NotEqualWithNan, OperationCode::LogicalHNotEqual}, | ||
| 299 | {PredCondition::LessEqualWithNan, OperationCode::LogicalHLessEqual}, | ||
| 300 | {PredCondition::GreaterThanWithNan, OperationCode::LogicalHGreaterThan}, | ||
| 301 | {PredCondition::GreaterEqualWithNan, OperationCode::LogicalHGreaterEqual}}; | ||
| 302 | |||
| 303 | const auto comparison{PredicateComparisonTable.find(condition)}; | ||
| 304 | UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(), | ||
| 305 | "Unknown predicate comparison operation"); | ||
| 306 | |||
| 307 | const Node predicate = Operation(comparison->second, meta, op_a, op_b); | ||
| 308 | |||
| 309 | return predicate; | ||
| 310 | } | ||
| 311 | |||
| 215 | void ShaderIR::SetRegister(BasicBlock& bb, Register dest, Node src) { | 312 | void ShaderIR::SetRegister(BasicBlock& bb, Register dest, Node src) { |
| 216 | bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), src)); | 313 | bb.push_back(Operation(OperationCode::Assign, GetRegister(dest), src)); |
| 217 | } | 314 | } |
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index f3b17d2eb..372ed10da 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -660,6 +660,15 @@ private: | |||
| 660 | /// Conditionally absolute/negated half float pair. Absolute is applied first | 660 | /// Conditionally absolute/negated half float pair. Absolute is applied first |
| 661 | Node GetOperandAbsNegHalf(Node value, bool absolute, bool negate); | 661 | Node GetOperandAbsNegHalf(Node value, bool absolute, bool negate); |
| 662 | 662 | ||
| 663 | /// Returns a predicate comparing two floats | ||
| 664 | Node GetPredicateComparisonFloat(Tegra::Shader::PredCondition condition, Node op_a, Node op_b); | ||
| 665 | /// Returns a predicate comparing two integers | ||
| 666 | Node GetPredicateComparisonInteger(Tegra::Shader::PredCondition condition, bool is_signed, | ||
| 667 | Node op_a, Node op_b); | ||
| 668 | /// Returns a predicate comparing two half floats. meta consumes how both pairs will be compared | ||
| 669 | Node GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition, | ||
| 670 | const MetaHalfArithmetic& meta, Node op_a, Node op_b); | ||
| 671 | |||
| 663 | template <typename... T> | 672 | template <typename... T> |
| 664 | inline Node Operation(OperationCode code, const T*... operands) { | 673 | inline Node Operation(OperationCode code, const T*... operands) { |
| 665 | return StoreNode(OperationNode(code, operands...)); | 674 | return StoreNode(OperationNode(code, operands...)); |