summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/shader/shader_ir.cpp120
1 files changed, 67 insertions, 53 deletions
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp
index c1f2b88c8..b10d376cb 100644
--- a/src/video_core/shader/shader_ir.cpp
+++ b/src/video_core/shader/shader_ir.cpp
@@ -2,8 +2,9 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <algorithm>
+#include <array>
#include <cmath>
-#include <unordered_map>
#include "common/assert.h"
#include "common/common_types.h"
@@ -271,21 +272,24 @@ Node ShaderIR::GetSaturatedHalfFloat(Node value, bool saturate) {
}
Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, Node op_b) {
- 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(),
+ static constexpr std::array comparison_table{
+ std::pair{PredCondition::LessThan, OperationCode::LogicalFLessThan},
+ std::pair{PredCondition::Equal, OperationCode::LogicalFEqual},
+ std::pair{PredCondition::LessEqual, OperationCode::LogicalFLessEqual},
+ std::pair{PredCondition::GreaterThan, OperationCode::LogicalFGreaterThan},
+ std::pair{PredCondition::NotEqual, OperationCode::LogicalFNotEqual},
+ std::pair{PredCondition::GreaterEqual, OperationCode::LogicalFGreaterEqual},
+ std::pair{PredCondition::LessThanWithNan, OperationCode::LogicalFLessThan},
+ std::pair{PredCondition::NotEqualWithNan, OperationCode::LogicalFNotEqual},
+ std::pair{PredCondition::LessEqualWithNan, OperationCode::LogicalFLessEqual},
+ std::pair{PredCondition::GreaterThanWithNan, OperationCode::LogicalFGreaterThan},
+ std::pair{PredCondition::GreaterEqualWithNan, OperationCode::LogicalFGreaterEqual},
+ };
+
+ const auto comparison =
+ std::find_if(comparison_table.cbegin(), comparison_table.cend(),
+ [condition](const auto entry) { return condition == entry.first; });
+ UNIMPLEMENTED_IF_MSG(comparison == comparison_table.cend(),
"Unknown predicate comparison operation");
Node predicate = Operation(comparison->second, NO_PRECISE, op_a, op_b);
@@ -306,21 +310,24 @@ Node ShaderIR::GetPredicateComparisonFloat(PredCondition condition, Node op_a, N
Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_signed, Node op_a,
Node op_b) {
- 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(),
+ static constexpr std::array comparison_table{
+ std::pair{PredCondition::LessThan, OperationCode::LogicalILessThan},
+ std::pair{PredCondition::Equal, OperationCode::LogicalIEqual},
+ std::pair{PredCondition::LessEqual, OperationCode::LogicalILessEqual},
+ std::pair{PredCondition::GreaterThan, OperationCode::LogicalIGreaterThan},
+ std::pair{PredCondition::NotEqual, OperationCode::LogicalINotEqual},
+ std::pair{PredCondition::GreaterEqual, OperationCode::LogicalIGreaterEqual},
+ std::pair{PredCondition::LessThanWithNan, OperationCode::LogicalILessThan},
+ std::pair{PredCondition::NotEqualWithNan, OperationCode::LogicalINotEqual},
+ std::pair{PredCondition::LessEqualWithNan, OperationCode::LogicalILessEqual},
+ std::pair{PredCondition::GreaterThanWithNan, OperationCode::LogicalIGreaterThan},
+ std::pair{PredCondition::GreaterEqualWithNan, OperationCode::LogicalIGreaterEqual},
+ };
+
+ const auto comparison =
+ std::find_if(comparison_table.cbegin(), comparison_table.cend(),
+ [condition](const auto entry) { return condition == entry.first; });
+ UNIMPLEMENTED_IF_MSG(comparison == comparison_table.cend(),
"Unknown predicate comparison operation");
Node predicate = SignedOperation(comparison->second, is_signed, NO_PRECISE, std::move(op_a),
@@ -337,36 +344,43 @@ Node ShaderIR::GetPredicateComparisonInteger(PredCondition condition, bool is_si
Node ShaderIR::GetPredicateComparisonHalf(Tegra::Shader::PredCondition condition, Node op_a,
Node op_b) {
- const std::unordered_map<PredCondition, OperationCode> PredicateComparisonTable = {
- {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::Logical2HLessThanWithNan},
- {PredCondition::NotEqualWithNan, OperationCode::Logical2HNotEqualWithNan},
- {PredCondition::LessEqualWithNan, OperationCode::Logical2HLessEqualWithNan},
- {PredCondition::GreaterThanWithNan, OperationCode::Logical2HGreaterThanWithNan},
- {PredCondition::GreaterEqualWithNan, OperationCode::Logical2HGreaterEqualWithNan}};
-
- const auto comparison{PredicateComparisonTable.find(condition)};
- UNIMPLEMENTED_IF_MSG(comparison == PredicateComparisonTable.end(),
+ static constexpr std::array comparison_table{
+ std::pair{PredCondition::LessThan, OperationCode::Logical2HLessThan},
+ std::pair{PredCondition::Equal, OperationCode::Logical2HEqual},
+ std::pair{PredCondition::LessEqual, OperationCode::Logical2HLessEqual},
+ std::pair{PredCondition::GreaterThan, OperationCode::Logical2HGreaterThan},
+ std::pair{PredCondition::NotEqual, OperationCode::Logical2HNotEqual},
+ std::pair{PredCondition::GreaterEqual, OperationCode::Logical2HGreaterEqual},
+ std::pair{PredCondition::LessThanWithNan, OperationCode::Logical2HLessThanWithNan},
+ std::pair{PredCondition::NotEqualWithNan, OperationCode::Logical2HNotEqualWithNan},
+ std::pair{PredCondition::LessEqualWithNan, OperationCode::Logical2HLessEqualWithNan},
+ std::pair{PredCondition::GreaterThanWithNan, OperationCode::Logical2HGreaterThanWithNan},
+ std::pair{PredCondition::GreaterEqualWithNan, OperationCode::Logical2HGreaterEqualWithNan},
+ };
+
+ const auto comparison =
+ std::find_if(comparison_table.cbegin(), comparison_table.cend(),
+ [condition](const auto entry) { return condition == entry.first; });
+ UNIMPLEMENTED_IF_MSG(comparison == comparison_table.cend(),
"Unknown predicate comparison operation");
return Operation(comparison->second, NO_PRECISE, std::move(op_a), std::move(op_b));
}
OperationCode ShaderIR::GetPredicateCombiner(PredOperation operation) {
- const std::unordered_map<PredOperation, OperationCode> PredicateOperationTable = {
- {PredOperation::And, OperationCode::LogicalAnd},
- {PredOperation::Or, OperationCode::LogicalOr},
- {PredOperation::Xor, OperationCode::LogicalXor},
+ static constexpr std::array operation_table{
+ OperationCode::LogicalAnd,
+ OperationCode::LogicalOr,
+ OperationCode::LogicalXor,
};
- const auto op = PredicateOperationTable.find(operation);
- UNIMPLEMENTED_IF_MSG(op == PredicateOperationTable.end(), "Unknown predicate operation");
- return op->second;
+ const auto index = static_cast<std::size_t>(operation);
+ if (index >= operation_table.size()) {
+ UNIMPLEMENTED_MSG("Unknown predicate operation.");
+ return {};
+ }
+
+ return operation_table[index];
}
Node ShaderIR::GetConditionCode(Tegra::Shader::ConditionCode cc) const {