|
|
|
@ -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 { |
|
|
|
|