Commit 85244d74 by steve-lunarg

HLSL: Enable component-wise vector comparisons from operators

This PR only changes a few lines of code, but is subtle. In HLSL, comparison operators (<,>,<=,>=,==,!=) operate component-wise when given a vector operand. If a whole vector equality or inequality is desired, then all() or any() can be used on the resulting bool vector. This PR enables this change. Existing shape conversion is used when one of the two arguments is a vector and one is a scalar. Some existing HLSL tests had assumed == and != meant vector-wise instead of component-wise comparisons. These tests have been changed to add an explicit any() or all() to the test source. This verifably does not change the final SPIR-V binary relative to the old behavior for == and !=. The AST does change for the (now explicit, formerly implicit) any() and all(). Also, a few tests changes where they previously had the return type wrong, e.g, from a vec < vec comparison in hlsl.shapeConv.frag. Promotion of comparison opcodes to vector forms (EOpEqual->EOpVectorEqual) is handled in promoteBinary(), as is setting the proper vector type of the result. EOpVectorEqual and EOpVectorNotEqual are now accepted as either aggregate or binary nodes, similar to how the other operators are handled. Partial support already existed for this: it has been fleshed out in the printing functions in intermOut.cpp. There is an existing defect around shape conversion with 1-vectors, but that is orthogonal to this PR and not addressed by it.
parent 0d628c17
......@@ -18,9 +18,10 @@ gl_FragCoord origin is upper left
0:4 No loop body
0:5 Loop with condition not tested first
0:5 Loop Condition
0:5 Compare Equal (temp bool)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 all (global bool)
0:5 Equal (temp 4-component vector of bool)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 Loop Body
0:5 Sequence
0:5 move second child to first child (temp 4-component vector of float)
......@@ -54,9 +55,10 @@ gl_FragCoord origin is upper left
0:4 No loop body
0:5 Loop with condition not tested first
0:5 Loop Condition
0:5 Compare Equal (temp bool)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 all (global bool)
0:5 Equal (temp 4-component vector of bool)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 Loop Body
0:5 Sequence
0:5 move second child to first child (temp 4-component vector of float)
......
......@@ -19,16 +19,18 @@ gl_FragCoord origin is upper left
0:? Sequence
0:5 Loop with condition tested first
0:5 Loop Condition
0:5 Compare Not Equal (temp bool)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 any (global bool)
0:5 NotEqual (temp 4-component vector of bool)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 No loop body
0:? Sequence
0:6 Loop with condition tested first
0:6 Loop Condition
0:6 Compare Not Equal (temp bool)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 any (global bool)
0:6 NotEqual (temp 4-component vector of bool)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 Loop Body
0:? Sequence
0:6 Sequence
......@@ -42,9 +44,10 @@ gl_FragCoord origin is upper left
0:7 'input' (layout(location=0 ) in 4-component vector of float)
0:7 Loop with condition tested first
0:7 Loop Condition
0:7 Compare Not Equal (temp bool)
0:7 'input' (layout(location=0 ) in 4-component vector of float)
0:7 'input' (layout(location=0 ) in 4-component vector of float)
0:7 any (global bool)
0:7 NotEqual (temp 4-component vector of bool)
0:7 'input' (layout(location=0 ) in 4-component vector of float)
0:7 'input' (layout(location=0 ) in 4-component vector of float)
0:7 Loop Body
0:? Sequence
0:7 Sequence
......@@ -141,16 +144,18 @@ gl_FragCoord origin is upper left
0:? Sequence
0:5 Loop with condition tested first
0:5 Loop Condition
0:5 Compare Not Equal (temp bool)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 any (global bool)
0:5 NotEqual (temp 4-component vector of bool)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 'input' (layout(location=0 ) in 4-component vector of float)
0:5 No loop body
0:? Sequence
0:6 Loop with condition tested first
0:6 Loop Condition
0:6 Compare Not Equal (temp bool)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 any (global bool)
0:6 NotEqual (temp 4-component vector of bool)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 Loop Body
0:? Sequence
0:6 Sequence
......@@ -164,9 +169,10 @@ gl_FragCoord origin is upper left
0:7 'input' (layout(location=0 ) in 4-component vector of float)
0:7 Loop with condition tested first
0:7 Loop Condition
0:7 Compare Not Equal (temp bool)
0:7 'input' (layout(location=0 ) in 4-component vector of float)
0:7 'input' (layout(location=0 ) in 4-component vector of float)
0:7 any (global bool)
0:7 NotEqual (temp 4-component vector of bool)
0:7 'input' (layout(location=0 ) in 4-component vector of float)
0:7 'input' (layout(location=0 ) in 4-component vector of float)
0:7 Loop Body
0:? Sequence
0:7 Sequence
......
......@@ -8,9 +8,10 @@ gl_FragCoord origin is upper left
0:? Sequence
0:3 Test condition and select (temp void)
0:3 Condition
0:3 Compare Equal (temp bool)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 all (global bool)
0:3 Equal (temp 4-component vector of bool)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 true case
0:4 Sequence
0:4 move second child to first child (temp 4-component vector of float)
......@@ -19,9 +20,10 @@ gl_FragCoord origin is upper left
0:4 Branch: Return
0:6 Test condition and select (temp void)
0:6 Condition
0:6 Compare Equal (temp bool)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 all (global bool)
0:6 Equal (temp 4-component vector of bool)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 true case
0:7 Sequence
0:7 move second child to first child (temp 4-component vector of float)
......@@ -37,21 +39,24 @@ gl_FragCoord origin is upper left
0:9 Branch: Return
0:11 Test condition and select (temp void)
0:11 Condition
0:11 Compare Equal (temp bool)
0:11 'input' (layout(location=0 ) in 4-component vector of float)
0:11 'input' (layout(location=0 ) in 4-component vector of float)
0:11 all (global bool)
0:11 Equal (temp 4-component vector of bool)
0:11 'input' (layout(location=0 ) in 4-component vector of float)
0:11 'input' (layout(location=0 ) in 4-component vector of float)
0:11 true case is null
0:14 Test condition and select (temp void)
0:14 Condition
0:14 Compare Equal (temp bool)
0:14 'input' (layout(location=0 ) in 4-component vector of float)
0:14 'input' (layout(location=0 ) in 4-component vector of float)
0:14 all (global bool)
0:14 Equal (temp 4-component vector of bool)
0:14 'input' (layout(location=0 ) in 4-component vector of float)
0:14 'input' (layout(location=0 ) in 4-component vector of float)
0:14 true case is null
0:19 Test condition and select (temp void)
0:19 Condition
0:19 Compare Equal (temp bool)
0:19 'input' (layout(location=0 ) in 4-component vector of float)
0:19 'input' (layout(location=0 ) in 4-component vector of float)
0:19 all (global bool)
0:19 Equal (temp 4-component vector of bool)
0:19 'input' (layout(location=0 ) in 4-component vector of float)
0:19 'input' (layout(location=0 ) in 4-component vector of float)
0:19 true case
0:? Sequence
0:20 Sequence
......@@ -61,9 +66,10 @@ gl_FragCoord origin is upper left
0:20 Branch: Return
0:23 Test condition and select (temp void)
0:23 Condition
0:23 Compare Equal (temp bool)
0:23 'input' (layout(location=0 ) in 4-component vector of float)
0:23 'input' (layout(location=0 ) in 4-component vector of float)
0:23 all (global bool)
0:23 Equal (temp 4-component vector of bool)
0:23 'input' (layout(location=0 ) in 4-component vector of float)
0:23 'input' (layout(location=0 ) in 4-component vector of float)
0:23 true case
0:? Sequence
0:24 Sequence
......@@ -109,9 +115,10 @@ gl_FragCoord origin is upper left
0:? Sequence
0:3 Test condition and select (temp void)
0:3 Condition
0:3 Compare Equal (temp bool)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 all (global bool)
0:3 Equal (temp 4-component vector of bool)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 true case
0:4 Sequence
0:4 move second child to first child (temp 4-component vector of float)
......@@ -120,9 +127,10 @@ gl_FragCoord origin is upper left
0:4 Branch: Return
0:6 Test condition and select (temp void)
0:6 Condition
0:6 Compare Equal (temp bool)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 all (global bool)
0:6 Equal (temp 4-component vector of bool)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 'input' (layout(location=0 ) in 4-component vector of float)
0:6 true case
0:7 Sequence
0:7 move second child to first child (temp 4-component vector of float)
......@@ -138,21 +146,24 @@ gl_FragCoord origin is upper left
0:9 Branch: Return
0:11 Test condition and select (temp void)
0:11 Condition
0:11 Compare Equal (temp bool)
0:11 'input' (layout(location=0 ) in 4-component vector of float)
0:11 'input' (layout(location=0 ) in 4-component vector of float)
0:11 all (global bool)
0:11 Equal (temp 4-component vector of bool)
0:11 'input' (layout(location=0 ) in 4-component vector of float)
0:11 'input' (layout(location=0 ) in 4-component vector of float)
0:11 true case is null
0:14 Test condition and select (temp void)
0:14 Condition
0:14 Compare Equal (temp bool)
0:14 'input' (layout(location=0 ) in 4-component vector of float)
0:14 'input' (layout(location=0 ) in 4-component vector of float)
0:14 all (global bool)
0:14 Equal (temp 4-component vector of bool)
0:14 'input' (layout(location=0 ) in 4-component vector of float)
0:14 'input' (layout(location=0 ) in 4-component vector of float)
0:14 true case is null
0:19 Test condition and select (temp void)
0:19 Condition
0:19 Compare Equal (temp bool)
0:19 'input' (layout(location=0 ) in 4-component vector of float)
0:19 'input' (layout(location=0 ) in 4-component vector of float)
0:19 all (global bool)
0:19 Equal (temp 4-component vector of bool)
0:19 'input' (layout(location=0 ) in 4-component vector of float)
0:19 'input' (layout(location=0 ) in 4-component vector of float)
0:19 true case
0:? Sequence
0:20 Sequence
......@@ -162,9 +173,10 @@ gl_FragCoord origin is upper left
0:20 Branch: Return
0:23 Test condition and select (temp void)
0:23 Condition
0:23 Compare Equal (temp bool)
0:23 'input' (layout(location=0 ) in 4-component vector of float)
0:23 'input' (layout(location=0 ) in 4-component vector of float)
0:23 all (global bool)
0:23 Equal (temp 4-component vector of bool)
0:23 'input' (layout(location=0 ) in 4-component vector of float)
0:23 'input' (layout(location=0 ) in 4-component vector of float)
0:23 true case
0:? Sequence
0:24 Sequence
......
......@@ -8,9 +8,10 @@ gl_FragCoord origin is upper left
0:? Sequence
0:3 Loop with condition tested first
0:3 Loop Condition
0:3 Compare Not Equal (temp bool)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 any (global bool)
0:3 NotEqual (temp 4-component vector of bool)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 Loop Body
0:? Sequence
0:3 Sequence
......@@ -50,9 +51,10 @@ gl_FragCoord origin is upper left
0:? Sequence
0:3 Loop with condition tested first
0:3 Loop Condition
0:3 Compare Not Equal (temp bool)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 any (global bool)
0:3 NotEqual (temp 4-component vector of bool)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 'input' (layout(location=0 ) in 4-component vector of float)
0:3 Loop Body
0:? Sequence
0:3 Sequence
......
uniform float4 uf4;
void Bug1( float4 a )
{
float4 v04 = float4( 0.0, 0.0, 0.0, 0.0 );
float v01 = 0.0;
bool4 r00 = a == v04;
bool4 r01 = a != v04;
bool4 r02 = a < v04;
bool4 r03 = a > v04;
bool4 r10 = a == v01;
bool4 r11 = a != v01;
bool4 r12 = a < v01;
bool4 r13 = a > v01;
bool4 r20 = v01 == a;
bool4 r21 = v01 != a;
bool4 r22 = v01 < a;
bool4 r23 = v01 > a;
}
struct PS_OUTPUT
{
float4 Color : SV_Target0;
};
PS_OUTPUT main()
{
PS_OUTPUT psout;
psout.Color = 0;
return psout;
}
......@@ -2,5 +2,5 @@ float4 PixelShaderFunction(float4 input) : COLOR0
{
[unroll] do {} while (false);
[unroll] do {;} while (false);
do { return input; } while (input == input);
do { return input; } while (all(input == input));
}
......@@ -2,9 +2,9 @@ float4 PixelShaderFunction(float4 input) : COLOR0
{
for (;;) ;
for (++input; ; ) ;
[unroll] for (; input != input; ) {}
for (; input != input; ) { return -input; }
for (--input; input != input; input += 2) { return -input; }
[unroll] for (; any(input != input); ) {}
for (; any(input != input); ) { return -input; }
for (--input; any(input != input); input += 2) { return -input; }
for (;;) if (input.x > 2.0) break;
for (;;) if (input.x > 2.0) continue;
float ii;
......
float4 PixelShaderFunction(float4 input) : COLOR0
{
if (input == input)
if (all(input == input))
return input;
if (input == input)
if (all(input == input))
return input;
else
return -input;
if (input == input)
if (all(input == input))
;
if (input == input)
if (all(input == input))
;
else
;
[flatten] if (input == input) {
[flatten] if (all(input == input)) {
return input;
}
if (input == input) {
if (all(input == input)) {
return input;
} else {
return -input;
......
......@@ -18,8 +18,8 @@ float4 PixelShaderFunction(float4 input, float f) : COLOR0
6.0 < foo;
7.0 <= foo;
v.x == v;
f != v;
all(v.x == v);
any(f != v);
float1 f1;
......
float4 PixelShaderFunction(float4 input) : COLOR0
{
while (input != input) { return input; }
while (any(input != input)) { return input; }
while (false) ;
[unroll] while (false) { }
while ((false)) { }
......
......@@ -1892,13 +1892,26 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
// Relational comparisons need numeric types and will promote to scalar Boolean.
if (left->getBasicType() == EbtBool)
return false;
node.setType(TType(EbtBool));
node.setType(TType(EbtBool, EvqTemporary, left->getVectorSize()));
break;
case EOpEqual:
case EOpNotEqual:
// All the above comparisons result in a bool (but not the vector compares)
node.setType(TType(EbtBool));
if (getSource() == EShSourceHlsl) {
const int resultWidth = std::max(left->getVectorSize(), right->getVectorSize());
// In HLSL, == or != on vectors means component-wise comparison.
if (resultWidth > 1) {
op = (op == EOpEqual) ? EOpVectorEqual : EOpVectorNotEqual;
node.setOp(op);
}
node.setType(TType(EbtBool, EvqTemporary, resultWidth));
} else {
// All the above comparisons result in a bool (but not the vector compares)
node.setType(TType(EbtBool));
}
break;
case EOpLogicalAnd:
......@@ -1973,6 +1986,8 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
case EOpEqual:
case EOpNotEqual:
case EOpVectorEqual:
case EOpVectorNotEqual:
case EOpLogicalAnd:
case EOpLogicalOr:
......
......@@ -163,6 +163,8 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break;
case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
case EOpVectorEqual: out.debug << "Equal"; break;
case EOpVectorNotEqual: out.debug << "NotEqual"; break;
case EOpVectorTimesScalar: out.debug << "vector-scale"; break;
case EOpVectorTimesMatrix: out.debug << "vector-times-matrix"; break;
......
......@@ -91,6 +91,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.calculatelod.dx10.frag", "main"},
{"hlsl.calculatelodunclamped.dx10.frag", "main"},
{"hlsl.cast.frag", "PixelShaderFunction"},
{"hlsl.comparison.vec.frag", "main"},
{"hlsl.conditional.frag", "PixelShaderFunction"},
{"hlsl.constructexpr.frag", "main"},
{"hlsl.depthGreater.frag", "PixelShaderFunction"},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment