From 7b211a370b69676db64cca7be9391281f928b4d6 Mon Sep 17 00:00:00 2001 From: steve-lunarg Date: Thu, 13 Oct 2016 12:26:18 -0600 Subject: [PATCH] HLSL: allow multi-dimensional arrays 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 | 210 ++++++++++++++++++ Test/hlsl.array.implicit-size.frag | 8 +- Test/hlsl.array.multidim.frag | 20 ++ gtests/Hlsl.FromFile.cpp | 1 + hlsl/hlslGrammar.cpp | 47 ++-- 5 files changed, 261 insertions(+), 25 deletions(-) create mode 100644 Test/baseResults/hlsl.array.multidim.frag.out create mode 100644 Test/hlsl.array.multidim.frag diff --git a/Test/baseResults/hlsl.array.multidim.frag.out b/Test/baseResults/hlsl.array.multidim.frag.out new file mode 100644 index 000000000..a2df1a8d1 --- /dev/null +++ b/Test/baseResults/hlsl.array.multidim.frag.out @@ -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 diff --git a/Test/hlsl.array.implicit-size.frag b/Test/hlsl.array.implicit-size.frag index 29e2c1bae..78a9283da 100644 --- a/Test/hlsl.array.implicit-size.frag +++ b/Test/hlsl.array.implicit-size.frag @@ -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 index 000000000..524a8896e --- /dev/null +++ b/Test/hlsl.array.multidim.frag @@ -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; +} diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 7b642171f..1e45fda25 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -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"}, diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 626d29912..a53b9f4e0 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -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; - - // Array sizing expression is optional. If ommitted, array is implicitly sized. - const bool hasArraySize = acceptAssignmentExpression(sizeExpr); - - if (! acceptTokenClass(EHTokRightBracket)) { - expected("]"); - return; - } - + // If we get here, we have at least one array dimension. This will track the sizes we find. arraySizes = new TArraySizes; - - if (hasArraySize) { - TArraySize arraySize; - parseContext.arraySizeCheck(loc, sizeExpr, arraySize); - arraySizes->addInnerSize(arraySize); - } else { - arraySizes->addInnerSize(); // implicitly sized + + // Collect each array dimension. + while (acceptTokenClass(EHTokLeftBracket)) { + TSourceLoc loc = token.loc; + TIntermTyped* sizeExpr = nullptr; + + // Array sizing expression is optional. If ommitted, array will be later sized by initializer list. + const bool hasArraySize = acceptAssignmentExpression(sizeExpr); + + if (! acceptTokenClass(EHTokRightBracket)) { + expected("]"); + return; + } + + if (hasArraySize) { + TArraySize arraySize; + parseContext.arraySizeCheck(loc, sizeExpr, arraySize); + arraySizes->addInnerSize(arraySize); + } else { + arraySizes->addInnerSize(0); // sized by initializers. + } } }