|
|
|
@ -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));
|
|
|
|
|
}
|
|
|
|
|