HLSL: Smear scalars to match vectors for relational operations.
authorJohn Kessenich <cepheus@frii.com>
Mon, 8 Aug 2016 01:14:22 +0000 (19:14 -0600)
committerJohn Kessenich <cepheus@frii.com>
Mon, 8 Aug 2016 01:14:22 +0000 (19:14 -0600)
Yield a vector relational compare and a vector result.

SPIRV/GlslangToSpv.cpp
Test/baseResults/hlsl.shapeConv.frag.out
Test/hlsl.shapeConv.frag
glslang/Include/revision.h
glslang/MachineIndependent/Intermediate.cpp
glslang/MachineIndependent/ParseHelper.cpp

index 6aec9e6..5993e16 100755 (executable)
@@ -3082,11 +3082,9 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
 
     // Handle comparison instructions
 
-    if (reduceComparison && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left))) {
-        assert(op == glslang::EOpEqual || op == glslang::EOpNotEqual);
-
+    if (reduceComparison && (op == glslang::EOpEqual || op == glslang::EOpNotEqual)
+                         && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left)))
         return builder.createCompositeCompare(precision, left, right, op == glslang::EOpEqual);
-    }
 
     switch (op) {
     case glslang::EOpLessThan:
index e9b7389..6389595 100755 (executable)
@@ -2,7 +2,7 @@ hlsl.shapeConv.frag
 Shader version: 450
 gl_FragCoord origin is upper left
 0:? Sequence
-0:14  Function Definition: PixelShaderFunction(vf4;f1; (global 4-component vector of float)
+0:23  Function Definition: PixelShaderFunction(vf4;f1; (global 4-component vector of float)
 0:2    Function Parameters: 
 0:2      'input' (in 4-component vector of float)
 0:2      'f' (in float)
@@ -42,8 +42,48 @@ gl_FragCoord origin is upper left
 0:10        Construct vec3 (temp 3-component vector of float)
 0:10          Construct float (temp float)
 0:10            'f' (in float)
-0:12      Branch: Return with expression
-0:12        'input' (in 4-component vector of float)
+0:11      Sequence
+0:11        move second child to first child (temp 2-component vector of float)
+0:11          'w' (temp 2-component vector of float)
+0:11          Constant:
+0:11            2.000000
+0:11            2.000000
+0:12      Sequence
+0:12        move second child to first child (temp float)
+0:12          'V' (temp float)
+0:12          Constant:
+0:12            1.000000
+0:13      Sequence
+0:13        move second child to first child (temp 3-component vector of float)
+0:13          'MyVal' (temp 3-component vector of float)
+0:13          Construct vec3 (temp 3-component vector of float)
+0:13            'V' (temp float)
+0:16      Compare Greater Than (temp bool)
+0:16        'foo' (temp 3-component vector of float)
+0:16        Constant:
+0:16          4.000000
+0:16          4.000000
+0:16          4.000000
+0:17      Compare Greater Than or Equal (temp bool)
+0:17        'foo' (temp 3-component vector of float)
+0:17        Constant:
+0:17          5.000000
+0:17          5.000000
+0:17          5.000000
+0:18      Compare Less Than (temp bool)
+0:18        Constant:
+0:18          6.000000
+0:18          6.000000
+0:18          6.000000
+0:18        'foo' (temp 3-component vector of float)
+0:19      Compare Less Than or Equal (temp bool)
+0:19        Constant:
+0:19          7.000000
+0:19          7.000000
+0:19          7.000000
+0:19        'foo' (temp 3-component vector of float)
+0:21      Branch: Return with expression
+0:21        'input' (in 4-component vector of float)
 0:?   Linker Objects
 
 
@@ -53,7 +93,7 @@ Linked fragment stage:
 Shader version: 450
 gl_FragCoord origin is upper left
 0:? Sequence
-0:14  Function Definition: PixelShaderFunction(vf4;f1; (global 4-component vector of float)
+0:23  Function Definition: PixelShaderFunction(vf4;f1; (global 4-component vector of float)
 0:2    Function Parameters: 
 0:2      'input' (in 4-component vector of float)
 0:2      'f' (in float)
@@ -93,13 +133,53 @@ gl_FragCoord origin is upper left
 0:10        Construct vec3 (temp 3-component vector of float)
 0:10          Construct float (temp float)
 0:10            'f' (in float)
-0:12      Branch: Return with expression
-0:12        'input' (in 4-component vector of float)
+0:11      Sequence
+0:11        move second child to first child (temp 2-component vector of float)
+0:11          'w' (temp 2-component vector of float)
+0:11          Constant:
+0:11            2.000000
+0:11            2.000000
+0:12      Sequence
+0:12        move second child to first child (temp float)
+0:12          'V' (temp float)
+0:12          Constant:
+0:12            1.000000
+0:13      Sequence
+0:13        move second child to first child (temp 3-component vector of float)
+0:13          'MyVal' (temp 3-component vector of float)
+0:13          Construct vec3 (temp 3-component vector of float)
+0:13            'V' (temp float)
+0:16      Compare Greater Than (temp bool)
+0:16        'foo' (temp 3-component vector of float)
+0:16        Constant:
+0:16          4.000000
+0:16          4.000000
+0:16          4.000000
+0:17      Compare Greater Than or Equal (temp bool)
+0:17        'foo' (temp 3-component vector of float)
+0:17        Constant:
+0:17          5.000000
+0:17          5.000000
+0:17          5.000000
+0:18      Compare Less Than (temp bool)
+0:18        Constant:
+0:18          6.000000
+0:18          6.000000
+0:18          6.000000
+0:18        'foo' (temp 3-component vector of float)
+0:19      Compare Less Than or Equal (temp bool)
+0:19        Constant:
+0:19          7.000000
+0:19          7.000000
+0:19          7.000000
+0:19        'foo' (temp 3-component vector of float)
+0:21      Branch: Return with expression
+0:21        'input' (in 4-component vector of float)
 0:?   Linker Objects
 
 // Module Version 10000
 // Generated by (magic number): 80001
-// Id's are bound by 32
+// Id's are bound by 58
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
@@ -113,6 +193,10 @@ gl_FragCoord origin is upper left
                               Name 12  "f"
                               Name 15  "v"
                               Name 24  "u"
+                              Name 31  "w"
+                              Name 33  "V"
+                              Name 34  "MyVal"
+                              Name 37  "foo"
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeFloat 32
@@ -128,6 +212,18 @@ gl_FragCoord origin is upper left
               23:             TypePointer Function 22(fvec3)
               25:   22(fvec3) ConstantComposite 16 16 16
               26:   22(fvec3) ConstantComposite 18 18 18
+              29:             TypeVector 6(float) 2
+              30:             TypePointer Function 29(fvec2)
+              32:   29(fvec2) ConstantComposite 18 18
+              39:    6(float) Constant 1082130432
+              40:   22(fvec3) ConstantComposite 39 39 39
+              41:             TypeBool
+              44:    6(float) Constant 1084227584
+              45:   22(fvec3) ConstantComposite 44 44 44
+              47:    6(float) Constant 1086324736
+              48:   22(fvec3) ConstantComposite 47 47 47
+              51:    6(float) Constant 1088421888
+              52:   22(fvec3) ConstantComposite 51 51 51
          4(main):           2 Function None 3
                5:             Label
                               FunctionEnd
@@ -137,6 +233,10 @@ gl_FragCoord origin is upper left
               14:             Label
            15(v):      8(ptr) Variable Function
            24(u):     23(ptr) Variable Function
+           31(w):     30(ptr) Variable Function
+           33(V):      9(ptr) Variable Function
+       34(MyVal):     23(ptr) Variable Function
+         37(foo):     23(ptr) Variable Function
                               Store 15(v) 17
                               Store 15(v) 19
               20:    6(float) Load 12(f)
@@ -147,6 +247,19 @@ gl_FragCoord origin is upper left
               27:    6(float) Load 12(f)
               28:   22(fvec3) CompositeConstruct 27 27 27
                               Store 24(u) 28
-              29:    7(fvec4) Load 11(input)
-                              ReturnValue 29
+                              Store 31(w) 32
+                              Store 33(V) 16
+              35:    6(float) Load 33(V)
+              36:   22(fvec3) CompositeConstruct 35 35 35
+                              Store 34(MyVal) 36
+              38:   22(fvec3) Load 37(foo)
+              42:    41(bool) FOrdGreaterThan 38 40
+              43:   22(fvec3) Load 37(foo)
+              46:    41(bool) FOrdGreaterThanEqual 43 45
+              49:   22(fvec3) Load 37(foo)
+              50:    41(bool) FOrdLessThan 48 49
+              53:   22(fvec3) Load 37(foo)
+              54:    41(bool) FOrdLessThanEqual 52 53
+              55:    7(fvec4) Load 11(input)
+                              ReturnValue 55
                               FunctionEnd
index 1e6dec6..3147b61 100644 (file)
@@ -8,6 +8,15 @@ float4 PixelShaderFunction(float4 input, float f) : COLOR0
     u = float(1);
     u = float(2.0);
     u = float(f);
+    float2 w = 2.0;
+    float V = 1;\r
+    float3 MyVal = V;
+
+    float3 foo;\r
+    foo > 4.0;\r
+    foo >= 5.0;\r
+    6.0 < foo;
+    7.0 <= foo;
 
     return input;
 }
index 18057dc..eca09e7 100644 (file)
@@ -2,5 +2,5 @@
 // For the version, it uses the latest git tag followed by the number of commits.
 // For the date, it uses the current date (when then script is run).
 
-#define GLSLANG_REVISION "SPIRV99.1390"
-#define GLSLANG_DATE "05-Aug-2016"
+#define GLSLANG_REVISION "SPIRV99.1391"
+#define GLSLANG_DATE "07-Aug-2016"
index be828e9..4d871ed 100644 (file)
@@ -118,6 +118,10 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
             return 0;
     }
 
+    // Convert the children's type shape to be compatible.
+    right = addShapeConversion(op,  left->getType(), right);
+    left  = addShapeConversion(op, right->getType(),  left);
+
     //
     // Need a new node holding things together.  Make
     // one and promote it to the right type.
@@ -694,6 +698,10 @@ TIntermTyped* TIntermediate::addShapeConversion(TOperator op, const TType& type,
     // some operations don't do this
     switch (op) {
     case EOpAssign:
+    case EOpLessThan:
+    case EOpGreaterThan:
+    case EOpLessThanEqual:
+    case EOpGreaterThanEqual:
         break;
     default:
         return node;
@@ -705,7 +713,6 @@ TIntermTyped* TIntermediate::addShapeConversion(TOperator op, const TType& type,
         return node;
 
     // The new node that handles the conversion
-    TIntermTyped* conversionNode = node;
     TOperator constructorOp = mapTypeToConstructorOp(type);
 
     // scalar -> smeared -> vector
@@ -1624,11 +1631,11 @@ bool TIntermBinary::promote()
     case EOpGreaterThan:
     case EOpLessThanEqual:
     case EOpGreaterThanEqual:
-        // Relational comparisons need matching numeric types and will promote to scalar Boolean.
-        if (left->getBasicType() == EbtBool || left->getType().isVector() || left->getType().isMatrix())
+        // Relational comparisons need numeric types and will promote to scalar Boolean.
+        if (left->getBasicType() == EbtBool)
             return false;
-
-        // Fall through
+        setType(TType(EbtBool));
+        break;
 
     case EOpEqual:
     case EOpNotEqual:
index b117024..d01804e 100644 (file)
@@ -761,13 +761,32 @@ void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredS
 }
 
 // Handle seeing a binary node with a math operation.
+// Returns nullptr if not semantically allowed.
 TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right)
 {
     rValueErrorCheck(loc, str, left->getAsTyped());
     rValueErrorCheck(loc, str, right->getAsTyped());
 
-    TIntermTyped* result = intermediate.addBinaryMath(op, left, right, loc);
-    if (! result)
+    bool allowed = true;
+    switch (op) {
+    // TODO: Bring more source language-specific checks up from intermediate.cpp
+    // to the specific parse helpers for that source language.
+    case EOpLessThan:
+    case EOpGreaterThan:
+    case EOpLessThanEqual:
+    case EOpGreaterThanEqual:
+        if (! left->isScalar() || ! right->isScalar())
+            allowed = false;
+        break;
+    default:
+        break;
+    }
+
+    TIntermTyped* result = nullptr;
+    if (allowed)
+        result = intermediate.addBinaryMath(op, left, right, loc);
+
+    if (result == nullptr)
         binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString());
 
     return result;