HLSL: allow multi-dimensional arrays
authorsteve-lunarg <steve_gh@khasekhemwy.net>
Thu, 13 Oct 2016 18:26:18 +0000 (12:26 -0600)
committersteve-lunarg <steve_gh@khasekhemwy.net>
Thu, 13 Oct 2016 18:32:04 +0000 (12:32 -0600)
All the underpinnings are there; this just parses multiple array dimensions
and passes them through to the existing mechanisms.

Also, minor comment fixes, and add a new test for multi-dim arrays.

Test/baseResults/hlsl.array.multidim.frag.out [new file with mode: 0644]
Test/hlsl.array.implicit-size.frag
Test/hlsl.array.multidim.frag [new file with mode: 0644]
gtests/Hlsl.FromFile.cpp
hlsl/hlslGrammar.cpp

diff --git a/Test/baseResults/hlsl.array.multidim.frag.out b/Test/baseResults/hlsl.array.multidim.frag.out
new file mode 100644 (file)
index 0000000..a2df1a8
--- /dev/null
@@ -0,0 +1,210 @@
+hlsl.array.multidim.frag
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:10  Function Definition: main( (temp structure{temp 4-component vector of float Color})
+0:10    Function Parameters: 
+0:?     Sequence
+0:14      move second child to first child (temp 4-component vector of float)
+0:14        direct index (temp 4-component vector of float)
+0:14          direct index (temp 3-element array of 4-component vector of float)
+0:14            'float4_array_1' (temp 2-element array of 3-element array of 4-component vector of float)
+0:14            Constant:
+0:14              1 (const int)
+0:14          Constant:
+0:14            2 (const int)
+0:14        Construct vec4 (temp 4-component vector of float)
+0:14          direct index (layout(offset=0 ) temp float)
+0:14            direct index (layout(offset=0 ) temp 3-element array of float)
+0:14              direct index (layout(offset=0 ) temp 4-element array of 3-element array of float)
+0:14                float_array: direct index for structure (layout(offset=0 ) uniform 5-element array of 4-element array of 3-element array of float)
+0:14                  'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 5-element array of 4-element array of 3-element array of float float_array})
+0:14                  Constant:
+0:14                    0 (const uint)
+0:14                Constant:
+0:14                  2 (const int)
+0:14              Constant:
+0:14                3 (const int)
+0:14            Constant:
+0:14              1 (const int)
+0:15      move second child to first child (temp 3-element array of 4-component vector of float)
+0:15        direct index (temp 3-element array of 4-component vector of float)
+0:15          'float4_array_2' (temp 5-element array of 3-element array of 4-component vector of float)
+0:15          Constant:
+0:15            1 (const int)
+0:15        direct index (temp 3-element array of 4-component vector of float)
+0:15          'float4_array_1' (temp 2-element array of 3-element array of 4-component vector of float)
+0:15          Constant:
+0:15            0 (const int)
+0:18      move second child to first child (temp 4-component vector of float)
+0:18        Color: direct index for structure (temp 4-component vector of float)
+0:18          'psout' (temp structure{temp 4-component vector of float Color})
+0:18          Constant:
+0:18            0 (const int)
+0:18        direct index (temp 4-component vector of float)
+0:18          direct index (temp 3-element array of 4-component vector of float)
+0:18            'float4_array_1' (temp 2-element array of 3-element array of 4-component vector of float)
+0:18            Constant:
+0:18              1 (const int)
+0:18          Constant:
+0:18            2 (const int)
+0:19      Sequence
+0:19        Sequence
+0:19          move second child to first child (temp 4-component vector of float)
+0:?             'Color' (layout(location=0 ) out 4-component vector of float)
+0:19            Color: direct index for structure (temp 4-component vector of float)
+0:19              'psout' (temp structure{temp 4-component vector of float Color})
+0:19              Constant:
+0:19                0 (const int)
+0:19        Branch: Return
+0:?   Linker Objects
+0:?     'Color' (layout(location=0 ) out 4-component vector of float)
+0:?     'anon@0' (uniform block{layout(offset=0 ) uniform 5-element array of 4-element array of 3-element array of float float_array})
+
+
+Linked fragment stage:
+
+
+Shader version: 450
+gl_FragCoord origin is upper left
+0:? Sequence
+0:10  Function Definition: main( (temp structure{temp 4-component vector of float Color})
+0:10    Function Parameters: 
+0:?     Sequence
+0:14      move second child to first child (temp 4-component vector of float)
+0:14        direct index (temp 4-component vector of float)
+0:14          direct index (temp 3-element array of 4-component vector of float)
+0:14            'float4_array_1' (temp 2-element array of 3-element array of 4-component vector of float)
+0:14            Constant:
+0:14              1 (const int)
+0:14          Constant:
+0:14            2 (const int)
+0:14        Construct vec4 (temp 4-component vector of float)
+0:14          direct index (layout(offset=0 ) temp float)
+0:14            direct index (layout(offset=0 ) temp 3-element array of float)
+0:14              direct index (layout(offset=0 ) temp 4-element array of 3-element array of float)
+0:14                float_array: direct index for structure (layout(offset=0 ) uniform 5-element array of 4-element array of 3-element array of float)
+0:14                  'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform 5-element array of 4-element array of 3-element array of float float_array})
+0:14                  Constant:
+0:14                    0 (const uint)
+0:14                Constant:
+0:14                  2 (const int)
+0:14              Constant:
+0:14                3 (const int)
+0:14            Constant:
+0:14              1 (const int)
+0:15      move second child to first child (temp 3-element array of 4-component vector of float)
+0:15        direct index (temp 3-element array of 4-component vector of float)
+0:15          'float4_array_2' (temp 5-element array of 3-element array of 4-component vector of float)
+0:15          Constant:
+0:15            1 (const int)
+0:15        direct index (temp 3-element array of 4-component vector of float)
+0:15          'float4_array_1' (temp 2-element array of 3-element array of 4-component vector of float)
+0:15          Constant:
+0:15            0 (const int)
+0:18      move second child to first child (temp 4-component vector of float)
+0:18        Color: direct index for structure (temp 4-component vector of float)
+0:18          'psout' (temp structure{temp 4-component vector of float Color})
+0:18          Constant:
+0:18            0 (const int)
+0:18        direct index (temp 4-component vector of float)
+0:18          direct index (temp 3-element array of 4-component vector of float)
+0:18            'float4_array_1' (temp 2-element array of 3-element array of 4-component vector of float)
+0:18            Constant:
+0:18              1 (const int)
+0:18          Constant:
+0:18            2 (const int)
+0:19      Sequence
+0:19        Sequence
+0:19          move second child to first child (temp 4-component vector of float)
+0:?             'Color' (layout(location=0 ) out 4-component vector of float)
+0:19            Color: direct index for structure (temp 4-component vector of float)
+0:19              'psout' (temp structure{temp 4-component vector of float Color})
+0:19              Constant:
+0:19                0 (const int)
+0:19        Branch: Return
+0:?   Linker Objects
+0:?     'Color' (layout(location=0 ) out 4-component vector of float)
+0:?     'anon@0' (uniform block{layout(offset=0 ) uniform 5-element array of 4-element array of 3-element array of float float_array})
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 52
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Fragment 4  "main" 48
+                              ExecutionMode 4 OriginUpperLeft
+                              Name 4  "main"
+                              Name 14  "float4_array_1"
+                              Name 23  "$Global"
+                              MemberName 23($Global) 0  "float_array"
+                              Name 25  ""
+                              Name 36  "float4_array_2"
+                              Name 41  "PS_OUTPUT"
+                              MemberName 41(PS_OUTPUT) 0  "Color"
+                              Name 43  "psout"
+                              Name 48  "Color"
+                              Decorate 18 ArrayStride 16
+                              Decorate 20 ArrayStride 48
+                              Decorate 22 ArrayStride 192
+                              MemberDecorate 23($Global) 0 Offset 0
+                              Decorate 23($Global) Block
+                              Decorate 25 DescriptorSet 0
+                              Decorate 48(Color) Location 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+               8:             TypeInt 32 0
+               9:      8(int) Constant 3
+              10:             TypeArray 7(fvec4) 9
+              11:      8(int) Constant 2
+              12:             TypeArray 10 11
+              13:             TypePointer Function 12
+              15:             TypeInt 32 1
+              16:     15(int) Constant 1
+              17:     15(int) Constant 2
+              18:             TypeArray 6(float) 9
+              19:      8(int) Constant 4
+              20:             TypeArray 18 19
+              21:      8(int) Constant 5
+              22:             TypeArray 20 21
+     23($Global):             TypeStruct 22
+              24:             TypePointer Uniform 23($Global)
+              25:     24(ptr) Variable Uniform
+              26:     15(int) Constant 0
+              27:     15(int) Constant 3
+              28:             TypePointer Uniform 6(float)
+              32:             TypePointer Function 7(fvec4)
+              34:             TypeArray 10 21
+              35:             TypePointer Function 34
+              37:             TypePointer Function 10
+   41(PS_OUTPUT):             TypeStruct 7(fvec4)
+              42:             TypePointer Function 41(PS_OUTPUT)
+              47:             TypePointer Output 7(fvec4)
+       48(Color):     47(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+14(float4_array_1):     13(ptr) Variable Function
+36(float4_array_2):     35(ptr) Variable Function
+       43(psout):     42(ptr) Variable Function
+              29:     28(ptr) AccessChain 25 26 17 27 16
+              30:    6(float) Load 29
+              31:    7(fvec4) CompositeConstruct 30 30 30 30
+              33:     32(ptr) AccessChain 14(float4_array_1) 16 17
+                              Store 33 31
+              38:     37(ptr) AccessChain 14(float4_array_1) 26
+              39:          10 Load 38
+              40:     37(ptr) AccessChain 36(float4_array_2) 16
+                              Store 40 39
+              44:     32(ptr) AccessChain 14(float4_array_1) 16 17
+              45:    7(fvec4) Load 44
+              46:     32(ptr) AccessChain 43(psout) 26
+                              Store 46 45
+              49:     32(ptr) AccessChain 43(psout) 26
+              50:    7(fvec4) Load 49
+                              Store 48(Color) 50
+                              Return
+                              FunctionEnd
index 29e2c1b..78a9283 100644 (file)
@@ -1,11 +1,11 @@
 
-// implicit sized array
+// array size from initializer
 static float g_array [ ] = { 1, 2, 3, 4, 5 };
 
-// Unused implicit sized array
+// Unused: array size from initializer
 static float g_array_unused [ ] = { 1, 2, 3, 4, 5, 6, 7 };
 
-// Test implicit size arrayed structs
+// Test initializer sizing for arrayed structs
 static struct mystruct {
     int i;
     float f;
@@ -24,7 +24,7 @@ struct PS_OUTPUT { float4 color : SV_Target0; };
 
 void main(out PS_OUTPUT ps_output)
 {
-    // implicit sized local array
+    // local array sized from initializers
     float l_array[] = { 1, 2, 3 };
 
     ps_output.color = g_array[0] + g_array[4] + l_array[1] + g_mystruct[0].f + g_array[idx];
diff --git a/Test/hlsl.array.multidim.frag b/Test/hlsl.array.multidim.frag
new file mode 100644 (file)
index 0000000..524a889
--- /dev/null
@@ -0,0 +1,20 @@
+
+float float_array[5][4][3];
+
+struct PS_OUTPUT
+{
+    float4 Color : SV_Target0;
+};
+
+PS_OUTPUT main()
+{
+    float4 float4_array_1[2][3];
+    float4 float4_array_2[5][3];
+
+    float4_array_1[1][2] = float_array[2][3][1];
+    float4_array_2[1] = float4_array_1[0];
+
+    PS_OUTPUT psout;
+    psout.Color = float4_array_1[1][2];
+    return psout;
+}
index 7b64217..1e45fda 100644 (file)
@@ -83,6 +83,7 @@ INSTANTIATE_TEST_CASE_P(
         {"hlsl.amend.frag", "f1"},
         {"hlsl.array.frag", "PixelShaderFunction"},
         {"hlsl.array.implicit-size.frag", "PixelShaderFunction"},
+        {"hlsl.array.multidim.frag", "main"},
         {"hlsl.assoc.frag", "PixelShaderFunction"},
         {"hlsl.attribute.frag", "PixelShaderFunction"},
         {"hlsl.buffer.frag", "PixelShaderFunction"},
index 626d299..a53b9f4 100755 (executable)
@@ -2676,35 +2676,40 @@ bool HlslGrammar::acceptDefaultLabel(TIntermNode*& statement)
 }
 
 // array_specifier
-//      : LEFT_BRACKET integer_expression RGHT_BRACKET post_decls // optional
-//      : LEFT_BRACKET RGHT_BRACKET post_decls // optional
+//      : LEFT_BRACKET integer_expression RGHT_BRACKET ... // optional
+//      : LEFT_BRACKET RGHT_BRACKET // optional
 //
 void HlslGrammar::acceptArraySpecifier(TArraySizes*& arraySizes)
 {
     arraySizes = nullptr;
 
-    if (! acceptTokenClass(EHTokLeftBracket))
+    // Early-out if there aren't any array dimensions
+    if (!peekTokenClass(EHTokLeftBracket))
         return;
 
-    TSourceLoc loc = token.loc;
-    TIntermTyped* sizeExpr = nullptr;
+    // If we get here, we have at least one array dimension.  This will track the sizes we find.
+    arraySizes = new TArraySizes;
 
-    // Array sizing expression is optional.  If ommitted, array is implicitly sized.
-    const bool hasArraySize = acceptAssignmentExpression(sizeExpr);
+    // Collect each array dimension.
+    while (acceptTokenClass(EHTokLeftBracket)) {
+        TSourceLoc loc = token.loc;
+        TIntermTyped* sizeExpr = nullptr;
 
-    if (! acceptTokenClass(EHTokRightBracket)) {
-        expected("]");
-        return;
-    }
+        // Array sizing expression is optional.  If ommitted, array will be later sized by initializer list.
+        const bool hasArraySize = acceptAssignmentExpression(sizeExpr);
 
-    arraySizes = new TArraySizes;
-    
-    if (hasArraySize) {
-        TArraySize arraySize;
-        parseContext.arraySizeCheck(loc, sizeExpr, arraySize);
-        arraySizes->addInnerSize(arraySize);
-    } else {
-        arraySizes->addInnerSize();  // implicitly sized
+        if (! acceptTokenClass(EHTokRightBracket)) {
+            expected("]");
+            return;
+        }
+
+        if (hasArraySize) {
+            TArraySize arraySize;
+            parseContext.arraySizeCheck(loc, sizeExpr, arraySize);
+            arraySizes->addInnerSize(arraySize);
+        } else {
+            arraySizes->addInnerSize(0);  // sized by initializers.
+        }
     }
 }