HLSL: Allow expressions in attributes
authorsteve-lunarg <steve_gh@khasekhemwy.net>
Fri, 11 Nov 2016 15:17:44 +0000 (08:17 -0700)
committersteve-lunarg <steve_gh@khasekhemwy.net>
Fri, 11 Nov 2016 15:23:03 +0000 (08:23 -0700)
For example:

[numthreads(2+2, 2*3, (1+FOO)*BAR)]

This will result in a thread count (4, 6, 8).

Test/baseResults/hlsl.attribute.expression.comp.out [new file with mode: 0644]
Test/hlsl.attribute.expression.comp [new file with mode: 0644]
gtests/Hlsl.FromFile.cpp
hlsl/hlslGrammar.cpp

diff --git a/Test/baseResults/hlsl.attribute.expression.comp.out b/Test/baseResults/hlsl.attribute.expression.comp.out
new file mode 100644 (file)
index 0000000..2316cd9
--- /dev/null
@@ -0,0 +1,138 @@
+hlsl.attribute.expression.comp
+Shader version: 450
+local_size = (4, 6, 8)
+0:? Sequence
+0:9  Function Definition: main( (temp 4-component vector of float)
+0:9    Function Parameters: 
+0:?     Sequence
+0:11      Sequence
+0:11        move second child to first child (temp int)
+0:11          'x' (temp int)
+0:11          Constant:
+0:11            0 (const int)
+0:11        Loop with condition tested first
+0:11          Loop Condition
+0:11          Compare Less Than (temp bool)
+0:11            'x' (temp int)
+0:11            bound: direct index for structure (layout(offset=0 ) uniform int)
+0:11              'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int bound})
+0:11              Constant:
+0:11                0 (const uint)
+0:11          No loop body
+0:11          Loop Terminal Expression
+0:11          Pre-Increment (temp int)
+0:11            'x' (temp int)
+0:14      Sequence
+0:14        move second child to first child (temp 4-component vector of float)
+0:?           '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
+0:?           Constant:
+0:?             0.000000
+0:?             0.000000
+0:?             0.000000
+0:?             0.000000
+0:14        Branch: Return
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
+0:?     'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int bound})
+
+
+Linked compute stage:
+
+
+Shader version: 450
+local_size = (4, 6, 8)
+0:? Sequence
+0:9  Function Definition: main( (temp 4-component vector of float)
+0:9    Function Parameters: 
+0:?     Sequence
+0:11      Sequence
+0:11        move second child to first child (temp int)
+0:11          'x' (temp int)
+0:11          Constant:
+0:11            0 (const int)
+0:11        Loop with condition tested first
+0:11          Loop Condition
+0:11          Compare Less Than (temp bool)
+0:11            'x' (temp int)
+0:11            bound: direct index for structure (layout(offset=0 ) uniform int)
+0:11              'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int bound})
+0:11              Constant:
+0:11                0 (const uint)
+0:11          No loop body
+0:11          Loop Terminal Expression
+0:11          Pre-Increment (temp int)
+0:11            'x' (temp int)
+0:14      Sequence
+0:14        move second child to first child (temp 4-component vector of float)
+0:?           '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
+0:?           Constant:
+0:?             0.000000
+0:?             0.000000
+0:?             0.000000
+0:?             0.000000
+0:14        Branch: Return
+0:?   Linker Objects
+0:?     '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
+0:?     'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int bound})
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 34
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint GLCompute 4  "main" 30
+                              ExecutionMode 4 LocalSize 4 6 8
+                              Name 4  "main"
+                              Name 8  "x"
+                              Name 16  "$Global"
+                              MemberName 16($Global) 0  "bound"
+                              Name 18  ""
+                              Name 30  "@entryPointOutput"
+                              MemberDecorate 16($Global) 0 Offset 0
+                              Decorate 16($Global) Block
+                              Decorate 18 DescriptorSet 0
+                              Decorate 30(@entryPointOutput) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 1
+               7:             TypePointer Function 6(int)
+               9:      6(int) Constant 0
+     16($Global):             TypeStruct 6(int)
+              17:             TypePointer Uniform 16($Global)
+              18:     17(ptr) Variable Uniform
+              19:             TypePointer Uniform 6(int)
+              22:             TypeBool
+              25:      6(int) Constant 1
+              27:             TypeFloat 32
+              28:             TypeVector 27(float) 4
+              29:             TypePointer Output 28(fvec4)
+30(@entryPointOutput):     29(ptr) Variable Output
+              31:   27(float) Constant 0
+              32:   28(fvec4) ConstantComposite 31 31 31 31
+         4(main):           2 Function None 3
+               5:             Label
+            8(x):      7(ptr) Variable Function
+                              Store 8(x) 9
+                              Branch 10
+              10:             Label
+                              LoopMerge 12 13 None
+                              Branch 14
+              14:             Label
+              15:      6(int) Load 8(x)
+              20:     19(ptr) AccessChain 18 9
+              21:      6(int) Load 20
+              23:    22(bool) SLessThan 15 21
+                              BranchConditional 23 11 12
+              11:               Label
+                                Branch 13
+              13:               Label
+              24:      6(int)   Load 8(x)
+              26:      6(int)   IAdd 24 25
+                                Store 8(x) 26
+                                Branch 10
+              12:             Label
+                              Store 30(@entryPointOutput) 32
+                              Return
+                              FunctionEnd
diff --git a/Test/hlsl.attribute.expression.comp b/Test/hlsl.attribute.expression.comp
new file mode 100644 (file)
index 0000000..535fbad
--- /dev/null
@@ -0,0 +1,15 @@
+
+uniform int bound;
+
+#define FOO 3
+#define BAR 2
+
+[numthreads(2+2, 2*3, (1+FOO)*BAR)]
+float4 main() : SV_TARGET
+{
+    [unroll(5*2 + 1) ]
+        for (int x=0; x<bound; ++x)
+            ;
+    
+    return float4(0,0,0,0);
+}
index 66fba2e..17e2133 100644 (file)
@@ -86,6 +86,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.array.multidim.frag", "main"},
         {"hlsl.assoc.frag", "PixelShaderFunction"},
         {"hlsl.attribute.frag", "PixelShaderFunction"},
+        {"hlsl.attribute.expression.comp", "main"},
         {"hlsl.basic.comp", "main"},
         {"hlsl.buffer.frag", "PixelShaderFunction"},
         {"hlsl.calculatelod.dx10.frag", "main"},
index e16c4b5..e6f4b60 100755 (executable)
@@ -2453,27 +2453,29 @@ void HlslGrammar::acceptAttributes(TAttributeMap& attributes)
             advanceToken();
         }
 
-        TIntermAggregate* literals = nullptr;
+        TIntermAggregate* expressions = nullptr;
 
         // (x, ...)
         if (acceptTokenClass(EHTokLeftParen)) {
-            literals = new TIntermAggregate;
+            expressions = new TIntermAggregate;
 
             TIntermTyped* node;
-            bool expectingLiteral = false;
+            bool expectingExpression = false;
             
-            while (acceptLiteral(node)) {
-                expectingLiteral = false;
-                literals->getSequence().push_back(node);
+            while (acceptAssignmentExpression(node)) {
+                expectingExpression = false;
+                expressions->getSequence().push_back(node);
                 if (acceptTokenClass(EHTokComma))
-                    expectingLiteral = true;
+                    expectingExpression = true;
             }
 
-            // 'literals' is an aggregate with the literals in it
+            // 'expressions' is an aggregate with the expressions in it
             if (! acceptTokenClass(EHTokRightParen))
                 expected(")");
-            if (expectingLiteral || literals->getSequence().empty())
-                expected("literal");
+
+            // Error for partial or missing expression
+            if (expectingExpression || expressions->getSequence().empty())
+                expected("expression");
         }
 
         // RIGHT_BRACKET
@@ -2484,7 +2486,7 @@ void HlslGrammar::acceptAttributes(TAttributeMap& attributes)
 
         // Add any values we found into the attribute map.  This accepts
         // (and ignores) values not mapping to a known TAttributeType;
-        attributes.setAttribute(idToken.string, literals);
+        attributes.setAttribute(idToken.string, expressions);
     } while (true);
 }