|
|
|
@ -2075,47 +2075,49 @@ private: |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
void AlphaTest(Id pointer) { |
|
|
|
const Id true_label = OpLabel(); |
|
|
|
const Id skip_label = OpLabel(); |
|
|
|
const Id alpha_reference = Constant(t_float, specialization.alpha_test_ref); |
|
|
|
const Id alpha_value = OpLoad(t_float, pointer); |
|
|
|
Id condition; |
|
|
|
Id MaxwellToSpirvComparison(Maxwell::ComparisonOp compare_op, Id operand_1, Id operand_2) { |
|
|
|
using Compare = Maxwell::ComparisonOp; |
|
|
|
switch (specialization.alpha_test_func) { |
|
|
|
switch (compare_op) { |
|
|
|
case Compare::NeverOld: |
|
|
|
condition = v_false; // Never true
|
|
|
|
break; |
|
|
|
return v_false; // Never let the test pass
|
|
|
|
case Compare::LessOld: |
|
|
|
condition = OpFOrdLessThan(t_bool, alpha_reference, alpha_value); |
|
|
|
break; |
|
|
|
return OpFOrdLessThan(t_bool, operand_1, operand_2); |
|
|
|
case Compare::EqualOld: |
|
|
|
condition = OpFOrdEqual(t_bool, alpha_reference, alpha_value); |
|
|
|
break; |
|
|
|
// Note: not accurate when tested against a unit test
|
|
|
|
// TODO: confirm if used by games
|
|
|
|
return OpFOrdEqual(t_bool, operand_1, operand_2); |
|
|
|
case Compare::LessEqualOld: |
|
|
|
condition = OpFOrdLessThanEqual(t_bool, alpha_reference, alpha_value); |
|
|
|
break; |
|
|
|
return OpFOrdLessThanEqual(t_bool, operand_1, operand_2); |
|
|
|
case Compare::GreaterOld: |
|
|
|
// Note: requires "Equal" to properly work for ssbu. perhaps a precision issue
|
|
|
|
condition = OpFOrdGreaterThanEqual(t_bool, alpha_reference, alpha_value); |
|
|
|
break; |
|
|
|
return OpFOrdGreaterThan(t_bool, operand_1, operand_2); |
|
|
|
case Compare::NotEqualOld: |
|
|
|
// Note: not accurate when tested against a unit test
|
|
|
|
// TODO: confirm if used by games
|
|
|
|
condition = OpFOrdNotEqual(t_bool, alpha_reference, alpha_value); |
|
|
|
break; |
|
|
|
return OpFOrdNotEqual(t_bool, operand_1, operand_2); |
|
|
|
case Compare::GreaterEqualOld: |
|
|
|
condition = OpFOrdGreaterThanEqual(t_bool, alpha_reference, alpha_value); |
|
|
|
break; |
|
|
|
case Compare::AlwaysOld: |
|
|
|
return; |
|
|
|
return OpFOrdGreaterThanEqual(t_bool, operand_1, operand_2); |
|
|
|
default: |
|
|
|
UNREACHABLE(); |
|
|
|
} |
|
|
|
OpBranchConditional(condition, true_label, skip_label); |
|
|
|
AddLabel(true_label); |
|
|
|
} |
|
|
|
|
|
|
|
void AlphaTest(Id pointer) { |
|
|
|
if (specialization.alpha_test_func == Maxwell::ComparisonOp::AlwaysOld) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
const Id true_label = OpLabel(); |
|
|
|
const Id discard_label = OpLabel(); |
|
|
|
const Id alpha_reference = Constant(t_float, specialization.alpha_test_ref); |
|
|
|
const Id alpha_value = OpLoad(t_float, pointer); |
|
|
|
|
|
|
|
const Id condition = |
|
|
|
MaxwellToSpirvComparison(specialization.alpha_test_func, alpha_value, alpha_reference); |
|
|
|
|
|
|
|
OpBranchConditional(condition, true_label, discard_label); |
|
|
|
AddLabel(discard_label); |
|
|
|
OpKill(); |
|
|
|
AddLabel(skip_label); |
|
|
|
AddLabel(true_label); |
|
|
|
} |
|
|
|
|
|
|
|
void PreExit() { |
|
|
|
|