diff --git a/Test/baseResults/hlsl.gather.basic.dx10.vert.out b/Test/baseResults/hlsl.gather.basic.dx10.vert.out index a8936753..3226769d 100644 --- a/Test/baseResults/hlsl.gather.basic.dx10.vert.out +++ b/Test/baseResults/hlsl.gather.basic.dx10.vert.out @@ -1,7 +1,7 @@ hlsl.gather.basic.dx10.vert Shader version: 450 0:? Sequence -0:28 Function Definition: main( (temp structure{temp 4-component vector of float Pos}) +0:28 Function Definition: main( (temp structure{temp 4-component vector of float Position Pos}) 0:28 Function Parameters: 0:? Sequence 0:33 Sequence @@ -87,7 +87,6 @@ Shader version: 450 0:45 0 (const int) 0:45 Branch: Return 0:? Linker Objects -0:? 'Pos' (out 4-component vector of float Position) 0:? 'g_sSamp' (layout(binding=0 ) uniform sampler) 0:? 'g_sSamp2d' (uniform sampler) 0:? 'g_tTex1df4a' (layout(binding=1 ) uniform texture1D) @@ -103,6 +102,7 @@ Shader version: 450 0:? 'g_tTexcdf4' (uniform textureCube) 0:? 'g_tTexcdi4' (uniform itextureCube) 0:? 'g_tTexcdu4' (uniform utextureCube) +0:? 'Pos' (out 4-component vector of float Position) Linked vertex stage: @@ -110,7 +110,7 @@ Linked vertex stage: Shader version: 450 0:? Sequence -0:28 Function Definition: main( (temp structure{temp 4-component vector of float Pos}) +0:28 Function Definition: main( (temp structure{temp 4-component vector of float Position Pos}) 0:28 Function Parameters: 0:? Sequence 0:33 Sequence @@ -196,7 +196,6 @@ Shader version: 450 0:45 0 (const int) 0:45 Branch: Return 0:? Linker Objects -0:? 'Pos' (out 4-component vector of float Position) 0:? 'g_sSamp' (layout(binding=0 ) uniform sampler) 0:? 'g_sSamp2d' (uniform sampler) 0:? 'g_tTex1df4a' (layout(binding=1 ) uniform texture1D) @@ -212,6 +211,7 @@ Shader version: 450 0:? 'g_tTexcdf4' (uniform textureCube) 0:? 'g_tTexcdi4' (uniform itextureCube) 0:? 'g_tTexcdu4' (uniform utextureCube) +0:? 'Pos' (out 4-component vector of float Position) // Module Version 10000 // Generated by (magic number): 80001 diff --git a/Test/baseResults/hlsl.getdimensions.dx10.vert.out b/Test/baseResults/hlsl.getdimensions.dx10.vert.out index c1c90f4b..77316b12 100644 --- a/Test/baseResults/hlsl.getdimensions.dx10.vert.out +++ b/Test/baseResults/hlsl.getdimensions.dx10.vert.out @@ -1,7 +1,7 @@ hlsl.getdimensions.dx10.vert Shader version: 450 0:? Sequence -0:11 Function Definition: main( (temp structure{temp 4-component vector of float Pos}) +0:11 Function Definition: main( (temp structure{temp 4-component vector of float Position Pos}) 0:11 Function Parameters: 0:? Sequence 0:21 Sequence @@ -46,9 +46,9 @@ Shader version: 450 0:26 0 (const int) 0:26 Branch: Return 0:? Linker Objects -0:? 'Pos' (out 4-component vector of float Position) 0:? 'g_sSamp' (layout(binding=0 ) uniform sampler) 0:? 'g_tTex1df4' (layout(binding=0 ) uniform texture1D) +0:? 'Pos' (out 4-component vector of float Position) Linked vertex stage: @@ -56,7 +56,7 @@ Linked vertex stage: Shader version: 450 0:? Sequence -0:11 Function Definition: main( (temp structure{temp 4-component vector of float Pos}) +0:11 Function Definition: main( (temp structure{temp 4-component vector of float Position Pos}) 0:11 Function Parameters: 0:? Sequence 0:21 Sequence @@ -101,9 +101,9 @@ Shader version: 450 0:26 0 (const int) 0:26 Branch: Return 0:? Linker Objects -0:? 'Pos' (out 4-component vector of float Position) 0:? 'g_sSamp' (layout(binding=0 ) uniform sampler) 0:? 'g_tTex1df4' (layout(binding=0 ) uniform texture1D) +0:? 'Pos' (out 4-component vector of float Position) // Module Version 10000 // Generated by (magic number): 80001 diff --git a/Test/baseResults/hlsl.load.basic.dx10.vert.out b/Test/baseResults/hlsl.load.basic.dx10.vert.out index a86f0aea..7441d49e 100644 --- a/Test/baseResults/hlsl.load.basic.dx10.vert.out +++ b/Test/baseResults/hlsl.load.basic.dx10.vert.out @@ -1,7 +1,7 @@ hlsl.load.basic.dx10.vert Shader version: 450 0:? Sequence -0:47 Function Definition: main( (temp structure{temp 4-component vector of float Pos}) +0:47 Function Definition: main( (temp structure{temp 4-component vector of float Position Pos}) 0:47 Function Parameters: 0:? Sequence 0:51 textureFetch (temp 4-component vector of float) @@ -195,7 +195,6 @@ Shader version: 450 0:69 0 (const int) 0:69 Branch: Return 0:? Linker Objects -0:? 'Pos' (out 4-component vector of float Position) 0:? 'g_sSamp' (layout(binding=0 ) uniform sampler) 0:? 'g_tTex1df4' (layout(binding=0 ) uniform texture1D) 0:? 'g_tTex1di4' (uniform itexture1D) @@ -219,6 +218,7 @@ Shader version: 450 0:? 'g_tTexcdi4a' (uniform itextureCubeArray) 0:? 'g_tTexcdu4a' (uniform utextureCubeArray) 0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int c1, layout(offset=8 ) uniform 2-component vector of int c2, layout(offset=16 ) uniform 3-component vector of int c3, layout(offset=32 ) uniform 4-component vector of int c4, layout(offset=48 ) uniform int o1, layout(offset=56 ) uniform 2-component vector of int o2, layout(offset=64 ) uniform 3-component vector of int o3, layout(offset=80 ) uniform 4-component vector of int o4}) +0:? 'Pos' (out 4-component vector of float Position) Linked vertex stage: @@ -226,7 +226,7 @@ Linked vertex stage: Shader version: 450 0:? Sequence -0:47 Function Definition: main( (temp structure{temp 4-component vector of float Pos}) +0:47 Function Definition: main( (temp structure{temp 4-component vector of float Position Pos}) 0:47 Function Parameters: 0:? Sequence 0:51 textureFetch (temp 4-component vector of float) @@ -420,7 +420,6 @@ Shader version: 450 0:69 0 (const int) 0:69 Branch: Return 0:? Linker Objects -0:? 'Pos' (out 4-component vector of float Position) 0:? 'g_sSamp' (layout(binding=0 ) uniform sampler) 0:? 'g_tTex1df4' (layout(binding=0 ) uniform texture1D) 0:? 'g_tTex1di4' (uniform itexture1D) @@ -444,6 +443,7 @@ Shader version: 450 0:? 'g_tTexcdi4a' (uniform itextureCubeArray) 0:? 'g_tTexcdu4a' (uniform utextureCubeArray) 0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform int c1, layout(offset=8 ) uniform 2-component vector of int c2, layout(offset=16 ) uniform 3-component vector of int c3, layout(offset=32 ) uniform 4-component vector of int c4, layout(offset=48 ) uniform int o1, layout(offset=56 ) uniform 2-component vector of int o2, layout(offset=64 ) uniform 3-component vector of int o3, layout(offset=80 ) uniform 4-component vector of int o4}) +0:? 'Pos' (out 4-component vector of float Position) // Module Version 10000 // Generated by (magic number): 80001 diff --git a/Test/baseResults/hlsl.samplegrad.basic.dx10.vert.out b/Test/baseResults/hlsl.samplegrad.basic.dx10.vert.out index f6d37c3b..d7ea3862 100644 --- a/Test/baseResults/hlsl.samplegrad.basic.dx10.vert.out +++ b/Test/baseResults/hlsl.samplegrad.basic.dx10.vert.out @@ -1,7 +1,7 @@ hlsl.samplegrad.basic.dx10.vert Shader version: 450 0:? Sequence -0:27 Function Definition: main( (temp structure{temp 4-component vector of float Pos}) +0:27 Function Definition: main( (temp structure{temp 4-component vector of float Position Pos}) 0:27 Function Parameters: 0:? Sequence 0:30 Sequence @@ -225,7 +225,6 @@ Shader version: 450 0:48 0 (const int) 0:48 Branch: Return 0:? Linker Objects -0:? 'Pos' (out 4-component vector of float Position) 0:? 'g_sSamp' (layout(binding=0 ) uniform sampler) 0:? 'g_tTex1df4a' (layout(binding=1 ) uniform texture1D) 0:? 'g_tTex1df4' (layout(binding=0 ) uniform texture1D) @@ -240,6 +239,7 @@ Shader version: 450 0:? 'g_tTexcdf4' (uniform textureCube) 0:? 'g_tTexcdi4' (uniform itextureCube) 0:? 'g_tTexcdu4' (uniform utextureCube) +0:? 'Pos' (out 4-component vector of float Position) Linked vertex stage: @@ -247,7 +247,7 @@ Linked vertex stage: Shader version: 450 0:? Sequence -0:27 Function Definition: main( (temp structure{temp 4-component vector of float Pos}) +0:27 Function Definition: main( (temp structure{temp 4-component vector of float Position Pos}) 0:27 Function Parameters: 0:? Sequence 0:30 Sequence @@ -471,7 +471,6 @@ Shader version: 450 0:48 0 (const int) 0:48 Branch: Return 0:? Linker Objects -0:? 'Pos' (out 4-component vector of float Position) 0:? 'g_sSamp' (layout(binding=0 ) uniform sampler) 0:? 'g_tTex1df4a' (layout(binding=1 ) uniform texture1D) 0:? 'g_tTex1df4' (layout(binding=0 ) uniform texture1D) @@ -486,6 +485,7 @@ Shader version: 450 0:? 'g_tTexcdf4' (uniform textureCube) 0:? 'g_tTexcdi4' (uniform itextureCube) 0:? 'g_tTexcdu4' (uniform utextureCube) +0:? 'Pos' (out 4-component vector of float Position) // Module Version 10000 // Generated by (magic number): 80001 diff --git a/Test/baseResults/hlsl.samplelevel.basic.dx10.vert.out b/Test/baseResults/hlsl.samplelevel.basic.dx10.vert.out index 04d0870e..35a9ede2 100644 --- a/Test/baseResults/hlsl.samplelevel.basic.dx10.vert.out +++ b/Test/baseResults/hlsl.samplelevel.basic.dx10.vert.out @@ -1,7 +1,7 @@ hlsl.samplelevel.basic.dx10.vert Shader version: 450 0:? Sequence -0:27 Function Definition: main( (temp structure{temp 4-component vector of float Pos}) +0:27 Function Definition: main( (temp structure{temp 4-component vector of float Position Pos}) 0:27 Function Parameters: 0:? Sequence 0:30 Sequence @@ -171,7 +171,6 @@ Shader version: 450 0:48 0 (const int) 0:48 Branch: Return 0:? Linker Objects -0:? 'Pos' (out 4-component vector of float Position) 0:? 'g_sSamp' (layout(binding=0 ) uniform sampler) 0:? 'g_tTex1df4a' (layout(binding=1 ) uniform texture1D) 0:? 'g_tTex1df4' (layout(binding=0 ) uniform texture1D) @@ -186,6 +185,7 @@ Shader version: 450 0:? 'g_tTexcdf4' (uniform textureCube) 0:? 'g_tTexcdi4' (uniform itextureCube) 0:? 'g_tTexcdu4' (uniform utextureCube) +0:? 'Pos' (out 4-component vector of float Position) Linked vertex stage: @@ -193,7 +193,7 @@ Linked vertex stage: Shader version: 450 0:? Sequence -0:27 Function Definition: main( (temp structure{temp 4-component vector of float Pos}) +0:27 Function Definition: main( (temp structure{temp 4-component vector of float Position Pos}) 0:27 Function Parameters: 0:? Sequence 0:30 Sequence @@ -363,7 +363,6 @@ Shader version: 450 0:48 0 (const int) 0:48 Branch: Return 0:? Linker Objects -0:? 'Pos' (out 4-component vector of float Position) 0:? 'g_sSamp' (layout(binding=0 ) uniform sampler) 0:? 'g_tTex1df4a' (layout(binding=1 ) uniform texture1D) 0:? 'g_tTex1df4' (layout(binding=0 ) uniform texture1D) @@ -378,6 +377,7 @@ Shader version: 450 0:? 'g_tTexcdf4' (uniform textureCube) 0:? 'g_tTexcdi4' (uniform itextureCube) 0:? 'g_tTexcdu4' (uniform utextureCube) +0:? 'Pos' (out 4-component vector of float Position) // Module Version 10000 // Generated by (magic number): 80001 diff --git a/Test/baseResults/hlsl.struct.split.array.geom.out b/Test/baseResults/hlsl.struct.split.array.geom.out new file mode 100644 index 00000000..e8921b68 --- /dev/null +++ b/Test/baseResults/hlsl.struct.split.array.geom.out @@ -0,0 +1,295 @@ +hlsl.struct.split.array.geom +Shader version: 450 +invocations = -1 +max_vertices = 4 +input primitive = points +output primitive = triangle_strip +0:? Sequence +0:13 Function Definition: main(u1[1];struct-PSInput-vf4-vf2-vf3-u11; (temp void) +0:13 Function Parameters: +0:13 'v' (layout(location=0 ) in 1-element array of uint) +0:13 'OutputStream' (out structure{temp 4-component vector of float Position Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:? Sequence +0:16 Sequence +0:16 move second child to first child (temp structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:16 'Out' (temp structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:16 Constant: +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0 (const uint) +0:18 Sequence +0:18 move second child to first child (temp int) +0:18 'x' (temp int) +0:18 Constant: +0:18 0 (const int) +0:18 Loop with condition tested first +0:18 Loop Condition +0:18 Compare Less Than (temp bool) +0:18 'x' (temp int) +0:18 Constant: +0:18 2 (const int) +0:18 Loop Body +0:19 Sequence +0:19 move second child to first child (temp int) +0:19 'y' (temp int) +0:19 Constant: +0:19 0 (const int) +0:19 Loop with condition tested first +0:19 Loop Condition +0:19 Compare Less Than (temp bool) +0:19 'y' (temp int) +0:19 Constant: +0:19 2 (const int) +0:19 Loop Body +0:20 move second child to first child (temp structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:20 indirect index (temp structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:20 indirect index (temp 3-element array of structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:20 'Verts' (temp 2-element array of 3-element array of structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:20 'x' (temp int) +0:20 'y' (temp int) +0:20 'Out' (temp structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:19 Loop Terminal Expression +0:19 Pre-Increment (temp int) +0:19 'y' (temp int) +0:18 Loop Terminal Expression +0:18 Pre-Increment (temp int) +0:18 'x' (temp int) +0:? Linker Objects +0:? 'v' (layout(location=0 ) in 1-element array of uint) +0:? 'OutputStream' (layout(location=0 ) out structure{temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:? 'OutputStream.Pos' (out 4-component vector of float Position) + + +Linked geometry stage: + + +Shader version: 450 +invocations = 1 +max_vertices = 4 +input primitive = points +output primitive = triangle_strip +0:? Sequence +0:13 Function Definition: main(u1[1];struct-PSInput-vf4-vf2-vf3-u11; (temp void) +0:13 Function Parameters: +0:13 'v' (layout(location=0 ) in 1-element array of uint) +0:13 'OutputStream' (out structure{temp 4-component vector of float Position Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:? Sequence +0:16 Sequence +0:16 move second child to first child (temp structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:16 'Out' (temp structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:16 Constant: +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0 (const uint) +0:18 Sequence +0:18 move second child to first child (temp int) +0:18 'x' (temp int) +0:18 Constant: +0:18 0 (const int) +0:18 Loop with condition tested first +0:18 Loop Condition +0:18 Compare Less Than (temp bool) +0:18 'x' (temp int) +0:18 Constant: +0:18 2 (const int) +0:18 Loop Body +0:19 Sequence +0:19 move second child to first child (temp int) +0:19 'y' (temp int) +0:19 Constant: +0:19 0 (const int) +0:19 Loop with condition tested first +0:19 Loop Condition +0:19 Compare Less Than (temp bool) +0:19 'y' (temp int) +0:19 Constant: +0:19 2 (const int) +0:19 Loop Body +0:20 move second child to first child (temp structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:20 indirect index (temp structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:20 indirect index (temp 3-element array of structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:20 'Verts' (temp 2-element array of 3-element array of structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:20 'x' (temp int) +0:20 'y' (temp int) +0:20 'Out' (temp structure{temp 4-component vector of float Pos, temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:19 Loop Terminal Expression +0:19 Pre-Increment (temp int) +0:19 'y' (temp int) +0:18 Loop Terminal Expression +0:18 Pre-Increment (temp int) +0:18 'x' (temp int) +0:? Linker Objects +0:? 'v' (layout(location=0 ) in 1-element array of uint) +0:? 'OutputStream' (layout(location=0 ) out structure{temp 2-component vector of float TexCoord, temp 3-component vector of float TerrainPos, temp uint VertexID}) +0:? 'OutputStream.Pos' (out 4-component vector of float Position) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 89 + + Capability Geometry + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Geometry 4 "main" 83 86 88 + ExecutionMode 4 InputPoints + ExecutionMode 4 Invocations 1 + ExecutionMode 4 OutputTriangleStrip + ExecutionMode 4 OutputVertices 4 + Name 4 "main" + Name 11 "PSInput" + MemberName 11(PSInput) 0 "Pos" + MemberName 11(PSInput) 1 "TexCoord" + MemberName 11(PSInput) 2 "TerrainPos" + MemberName 11(PSInput) 3 "VertexID" + Name 13 "Out" + Name 14 "PSInput" + MemberName 14(PSInput) 0 "Pos" + MemberName 14(PSInput) 1 "TexCoord" + MemberName 14(PSInput) 2 "TerrainPos" + MemberName 14(PSInput) 3 "VertexID" + Name 39 "x" + Name 48 "y" + Name 56 "PSInput" + MemberName 56(PSInput) 0 "Pos" + MemberName 56(PSInput) 1 "TexCoord" + MemberName 56(PSInput) 2 "TerrainPos" + MemberName 56(PSInput) 3 "VertexID" + Name 62 "Verts" + Name 83 "v" + Name 84 "PSInput" + MemberName 84(PSInput) 0 "TexCoord" + MemberName 84(PSInput) 1 "TerrainPos" + MemberName 84(PSInput) 2 "VertexID" + Name 86 "OutputStream" + Name 88 "OutputStream.Pos" + MemberDecorate 14(PSInput) 0 BuiltIn Position + Decorate 83(v) Location 0 + Decorate 86(OutputStream) Location 0 + Decorate 88(OutputStream.Pos) BuiltIn Position + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypeVector 6(float) 2 + 9: TypeVector 6(float) 3 + 10: TypeInt 32 0 + 11(PSInput): TypeStruct 7(fvec4) 8(fvec2) 9(fvec3) 10(int) + 12: TypePointer Function 11(PSInput) + 14(PSInput): TypeStruct 7(fvec4) 8(fvec2) 9(fvec3) 10(int) + 15: 6(float) Constant 0 + 16: 7(fvec4) ConstantComposite 15 15 15 15 + 17: 8(fvec2) ConstantComposite 15 15 + 18: 9(fvec3) ConstantComposite 15 15 15 + 19: 10(int) Constant 0 + 20: 14(PSInput) ConstantComposite 16 17 18 19 + 22: TypeInt 32 1 + 23: 22(int) Constant 0 + 24: TypePointer Function 7(fvec4) + 27: 22(int) Constant 1 + 28: TypePointer Function 8(fvec2) + 31: 22(int) Constant 2 + 32: TypePointer Function 9(fvec3) + 35: 22(int) Constant 3 + 36: TypePointer Function 10(int) + 38: TypePointer Function 22(int) + 46: TypeBool + 56(PSInput): TypeStruct 7(fvec4) 8(fvec2) 9(fvec3) 10(int) + 57: 10(int) Constant 3 + 58: TypeArray 56(PSInput) 57 + 59: 10(int) Constant 2 + 60: TypeArray 58 59 + 61: TypePointer Function 60 + 66: TypePointer Function 56(PSInput) + 80: 10(int) Constant 1 + 81: TypeArray 10(int) 80 + 82: TypePointer Input 81 + 83(v): 82(ptr) Variable Input + 84(PSInput): TypeStruct 8(fvec2) 9(fvec3) 10(int) + 85: TypePointer Output 84(PSInput) +86(OutputStream): 85(ptr) Variable Output + 87: TypePointer Output 7(fvec4) +88(OutputStream.Pos): 87(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + 13(Out): 12(ptr) Variable Function + 39(x): 38(ptr) Variable Function + 48(y): 38(ptr) Variable Function + 62(Verts): 61(ptr) Variable Function + 21: 7(fvec4) CompositeExtract 20 0 + 25: 24(ptr) AccessChain 13(Out) 23 + Store 25 21 + 26: 8(fvec2) CompositeExtract 20 1 + 29: 28(ptr) AccessChain 13(Out) 27 + Store 29 26 + 30: 9(fvec3) CompositeExtract 20 2 + 33: 32(ptr) AccessChain 13(Out) 31 + Store 33 30 + 34: 10(int) CompositeExtract 20 3 + 37: 36(ptr) AccessChain 13(Out) 35 + Store 37 34 + Store 39(x) 23 + Branch 40 + 40: Label + LoopMerge 42 43 None + Branch 44 + 44: Label + 45: 22(int) Load 39(x) + 47: 46(bool) SLessThan 45 31 + BranchConditional 47 41 42 + 41: Label + Store 48(y) 23 + Branch 49 + 49: Label + LoopMerge 51 52 None + Branch 53 + 53: Label + 54: 22(int) Load 48(y) + 55: 46(bool) SLessThan 54 31 + BranchConditional 55 50 51 + 50: Label + 63: 22(int) Load 39(x) + 64: 22(int) Load 48(y) + 65: 11(PSInput) Load 13(Out) + 67: 66(ptr) AccessChain 62(Verts) 63 64 + 68: 7(fvec4) CompositeExtract 65 0 + 69: 24(ptr) AccessChain 67 23 + Store 69 68 + 70: 8(fvec2) CompositeExtract 65 1 + 71: 28(ptr) AccessChain 67 27 + Store 71 70 + 72: 9(fvec3) CompositeExtract 65 2 + 73: 32(ptr) AccessChain 67 31 + Store 73 72 + 74: 10(int) CompositeExtract 65 3 + 75: 36(ptr) AccessChain 67 35 + Store 75 74 + Branch 52 + 52: Label + 76: 22(int) Load 48(y) + 77: 22(int) IAdd 76 27 + Store 48(y) 77 + Branch 49 + 51: Label + Branch 43 + 43: Label + 78: 22(int) Load 39(x) + 79: 22(int) IAdd 78 27 + Store 39(x) 79 + Branch 40 + 42: Label + Return + FunctionEnd diff --git a/Test/baseResults/hlsl.struct.split.nested.geom.out b/Test/baseResults/hlsl.struct.split.nested.geom.out new file mode 100644 index 00000000..3dd8d9f8 --- /dev/null +++ b/Test/baseResults/hlsl.struct.split.nested.geom.out @@ -0,0 +1,271 @@ +hlsl.struct.split.nested.geom +Shader version: 450 +invocations = -1 +max_vertices = 3 +input primitive = triangles +output primitive = triangle_strip +0:? Sequence +0:24 Function Definition: main(struct-PS_IN-vf4-vf21[3];struct-GS_OUT-struct-PS_IN-vf4-vf21-struct-STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO-f1[2]-i111; (temp void) +0:24 Function Parameters: +0:24 'tin' (in 3-element array of structure{temp 4-component vector of float Position pos, temp 2-component vector of float tc}) +0:24 'ts' (out structure{temp structure{temp 4-component vector of float Position pos, temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:? Sequence +0:27 move second child to first child (temp 4-component vector of float) +0:27 pos: direct index for structure (temp 4-component vector of float) +0:27 psIn: direct index for structure (temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc}) +0:27 'o' (temp structure{temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:27 Constant: +0:27 0 (const int) +0:27 Constant: +0:27 0 (const int) +0:? Constant: +0:? 1.000000 +0:? 2.000000 +0:? 3.000000 +0:? 4.000000 +0:28 move second child to first child (temp 2-component vector of float) +0:28 tc: direct index for structure (temp 2-component vector of float) +0:28 psIn: direct index for structure (temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc}) +0:28 'o' (temp structure{temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:28 Constant: +0:28 0 (const int) +0:28 Constant: +0:28 1 (const int) +0:? Constant: +0:? 5.000000 +0:? 6.000000 +0:30 Sequence +0:30 Sequence +0:30 move second child to first child (temp 4-component vector of float) +0:? 'ts.psIn.pos' (out 4-component vector of float Position) +0:30 pos: direct index for structure (temp 4-component vector of float) +0:30 psIn: direct index for structure (temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc}) +0:30 'o' (temp structure{temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:30 Constant: +0:30 0 (const int) +0:30 Constant: +0:30 0 (const int) +0:30 move second child to first child (temp 2-component vector of float) +0:30 tc: direct index for structure (temp 2-component vector of float) +0:30 psIn: direct index for structure (temp structure{temp 2-component vector of float tc}) +0:30 'ts' (layout(location=0 ) out structure{temp structure{temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:30 Constant: +0:30 0 (const int) +0:30 Constant: +0:30 0 (const int) +0:30 tc: direct index for structure (temp 2-component vector of float) +0:30 psIn: direct index for structure (temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc}) +0:30 'o' (temp structure{temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:30 Constant: +0:30 0 (const int) +0:30 Constant: +0:30 1 (const int) +0:30 move second child to first child (temp structure{temp 2-element array of float m0_array, temp int m1}) +0:30 contains_no_builtin_io: direct index for structure (temp structure{temp 2-element array of float m0_array, temp int m1}) +0:30 'ts' (layout(location=0 ) out structure{temp structure{temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:30 Constant: +0:30 1 (const int) +0:30 contains_no_builtin_io: direct index for structure (temp structure{temp 2-element array of float m0_array, temp int m1}) +0:30 'o' (temp structure{temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:30 Constant: +0:30 1 (const int) +0:30 EmitVertex (temp void) +0:? Linker Objects +0:? 'tin' (layout(location=0 ) in 3-element array of structure{temp 2-component vector of float tc}) +0:? 'ts' (layout(location=0 ) out structure{temp structure{temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:? 'tin.pos' (in 3-element array of 4-component vector of float Position) +0:? 'ts.psIn.pos' (out 4-component vector of float Position) + + +Linked geometry stage: + + +Shader version: 450 +invocations = 1 +max_vertices = 3 +input primitive = triangles +output primitive = triangle_strip +0:? Sequence +0:24 Function Definition: main(struct-PS_IN-vf4-vf21[3];struct-GS_OUT-struct-PS_IN-vf4-vf21-struct-STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO-f1[2]-i111; (temp void) +0:24 Function Parameters: +0:24 'tin' (in 3-element array of structure{temp 4-component vector of float Position pos, temp 2-component vector of float tc}) +0:24 'ts' (out structure{temp structure{temp 4-component vector of float Position pos, temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:? Sequence +0:27 move second child to first child (temp 4-component vector of float) +0:27 pos: direct index for structure (temp 4-component vector of float) +0:27 psIn: direct index for structure (temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc}) +0:27 'o' (temp structure{temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:27 Constant: +0:27 0 (const int) +0:27 Constant: +0:27 0 (const int) +0:? Constant: +0:? 1.000000 +0:? 2.000000 +0:? 3.000000 +0:? 4.000000 +0:28 move second child to first child (temp 2-component vector of float) +0:28 tc: direct index for structure (temp 2-component vector of float) +0:28 psIn: direct index for structure (temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc}) +0:28 'o' (temp structure{temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:28 Constant: +0:28 0 (const int) +0:28 Constant: +0:28 1 (const int) +0:? Constant: +0:? 5.000000 +0:? 6.000000 +0:30 Sequence +0:30 Sequence +0:30 move second child to first child (temp 4-component vector of float) +0:? 'ts.psIn.pos' (out 4-component vector of float Position) +0:30 pos: direct index for structure (temp 4-component vector of float) +0:30 psIn: direct index for structure (temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc}) +0:30 'o' (temp structure{temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:30 Constant: +0:30 0 (const int) +0:30 Constant: +0:30 0 (const int) +0:30 move second child to first child (temp 2-component vector of float) +0:30 tc: direct index for structure (temp 2-component vector of float) +0:30 psIn: direct index for structure (temp structure{temp 2-component vector of float tc}) +0:30 'ts' (layout(location=0 ) out structure{temp structure{temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:30 Constant: +0:30 0 (const int) +0:30 Constant: +0:30 0 (const int) +0:30 tc: direct index for structure (temp 2-component vector of float) +0:30 psIn: direct index for structure (temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc}) +0:30 'o' (temp structure{temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:30 Constant: +0:30 0 (const int) +0:30 Constant: +0:30 1 (const int) +0:30 move second child to first child (temp structure{temp 2-element array of float m0_array, temp int m1}) +0:30 contains_no_builtin_io: direct index for structure (temp structure{temp 2-element array of float m0_array, temp int m1}) +0:30 'ts' (layout(location=0 ) out structure{temp structure{temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:30 Constant: +0:30 1 (const int) +0:30 contains_no_builtin_io: direct index for structure (temp structure{temp 2-element array of float m0_array, temp int m1}) +0:30 'o' (temp structure{temp structure{temp 4-component vector of float pos, temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:30 Constant: +0:30 1 (const int) +0:30 EmitVertex (temp void) +0:? Linker Objects +0:? 'tin' (layout(location=0 ) in 3-element array of structure{temp 2-component vector of float tc}) +0:? 'ts' (layout(location=0 ) out structure{temp structure{temp 2-component vector of float tc} psIn, temp structure{temp 2-element array of float m0_array, temp int m1} contains_no_builtin_io}) +0:? 'tin.pos' (in 3-element array of 4-component vector of float Position) +0:? 'ts.psIn.pos' (out 4-component vector of float Position) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 64 + + Capability Geometry + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Geometry 4 "main" 33 40 60 63 + ExecutionMode 4 Triangles + ExecutionMode 4 Invocations 1 + ExecutionMode 4 OutputTriangleStrip + ExecutionMode 4 OutputVertices 3 + Name 4 "main" + Name 9 "PS_IN" + MemberName 9(PS_IN) 0 "pos" + MemberName 9(PS_IN) 1 "tc" + Name 14 "STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO" + MemberName 14(STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO) 0 "m0_array" + MemberName 14(STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO) 1 "m1" + Name 15 "GS_OUT" + MemberName 15(GS_OUT) 0 "psIn" + MemberName 15(GS_OUT) 1 "contains_no_builtin_io" + Name 17 "o" + Name 33 "ts.psIn.pos" + Name 36 "PS_IN" + MemberName 36(PS_IN) 0 "tc" + Name 37 "STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO" + MemberName 37(STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO) 0 "m0_array" + MemberName 37(STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO) 1 "m1" + Name 38 "GS_OUT" + MemberName 38(GS_OUT) 0 "psIn" + MemberName 38(GS_OUT) 1 "contains_no_builtin_io" + Name 40 "ts" + Name 56 "PS_IN" + MemberName 56(PS_IN) 0 "tc" + Name 60 "tin" + Name 63 "tin.pos" + Decorate 33(ts.psIn.pos) BuiltIn Position + Decorate 40(ts) Location 0 + Decorate 60(tin) Location 0 + Decorate 63(tin.pos) BuiltIn Position + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8: TypeVector 6(float) 2 + 9(PS_IN): TypeStruct 7(fvec4) 8(fvec2) + 10: TypeInt 32 0 + 11: 10(int) Constant 2 + 12: TypeArray 6(float) 11 + 13: TypeInt 32 1 +14(STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO): TypeStruct 12 13(int) + 15(GS_OUT): TypeStruct 9(PS_IN) 14(STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO) + 16: TypePointer Function 15(GS_OUT) + 18: 13(int) Constant 0 + 19: 6(float) Constant 1065353216 + 20: 6(float) Constant 1073741824 + 21: 6(float) Constant 1077936128 + 22: 6(float) Constant 1082130432 + 23: 7(fvec4) ConstantComposite 19 20 21 22 + 24: TypePointer Function 7(fvec4) + 26: 13(int) Constant 1 + 27: 6(float) Constant 1084227584 + 28: 6(float) Constant 1086324736 + 29: 8(fvec2) ConstantComposite 27 28 + 30: TypePointer Function 8(fvec2) + 32: TypePointer Output 7(fvec4) + 33(ts.psIn.pos): 32(ptr) Variable Output + 36(PS_IN): TypeStruct 8(fvec2) +37(STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO): TypeStruct 12 13(int) + 38(GS_OUT): TypeStruct 36(PS_IN) 37(STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO) + 39: TypePointer Output 38(GS_OUT) + 40(ts): 39(ptr) Variable Output + 43: TypePointer Output 8(fvec2) + 45: TypePointer Function 14(STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO) + 48: TypePointer Output 37(STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO) + 51: TypePointer Output 12 + 54: TypePointer Output 13(int) + 56(PS_IN): TypeStruct 8(fvec2) + 57: 10(int) Constant 3 + 58: TypeArray 56(PS_IN) 57 + 59: TypePointer Input 58 + 60(tin): 59(ptr) Variable Input + 61: TypeArray 7(fvec4) 57 + 62: TypePointer Input 61 + 63(tin.pos): 62(ptr) Variable Input + 4(main): 2 Function None 3 + 5: Label + 17(o): 16(ptr) Variable Function + 25: 24(ptr) AccessChain 17(o) 18 18 + Store 25 23 + 31: 30(ptr) AccessChain 17(o) 18 26 + Store 31 29 + 34: 24(ptr) AccessChain 17(o) 18 18 + 35: 7(fvec4) Load 34 + Store 33(ts.psIn.pos) 35 + 41: 30(ptr) AccessChain 17(o) 18 26 + 42: 8(fvec2) Load 41 + 44: 43(ptr) AccessChain 40(ts) 18 18 + Store 44 42 + 46: 45(ptr) AccessChain 17(o) 26 + 47:14(STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO) Load 46 + 49: 48(ptr) AccessChain 40(ts) 26 + 50: 12 CompositeExtract 47 0 + 52: 51(ptr) AccessChain 49 18 + Store 52 50 + 53: 13(int) CompositeExtract 47 1 + 55: 54(ptr) AccessChain 49 26 + Store 55 53 + EmitVertex + Return + FunctionEnd diff --git a/Test/baseResults/hlsl.struct.split.trivial.geom.out b/Test/baseResults/hlsl.struct.split.trivial.geom.out new file mode 100644 index 00000000..8448ac4a --- /dev/null +++ b/Test/baseResults/hlsl.struct.split.trivial.geom.out @@ -0,0 +1,175 @@ +hlsl.struct.split.trivial.geom +Shader version: 450 +invocations = -1 +max_vertices = 3 +input primitive = triangles +output primitive = triangle_strip +0:? Sequence +0:14 Function Definition: main(struct-PS_IN-vf41[3];struct-GS_OUT-vf41; (temp void) +0:14 Function Parameters: +0:14 'i' (in 3-element array of structure{temp 4-component vector of float Position pos}) +0:14 'ts' (out structure{temp 4-component vector of float Position pos}) +0:? Sequence +0:17 Sequence +0:17 move second child to first child (temp int) +0:17 'x' (temp int) +0:17 Constant: +0:17 0 (const int) +0:17 Loop with condition tested first +0:17 Loop Condition +0:17 Compare Less Than (temp bool) +0:17 'x' (temp int) +0:17 Constant: +0:17 3 (const int) +0:17 Loop Body +0:? Sequence +0:18 move second child to first child (temp 4-component vector of float) +0:18 pos: direct index for structure (temp 4-component vector of float) +0:18 'o' (temp structure{temp 4-component vector of float pos}) +0:18 Constant: +0:18 0 (const int) +0:18 indirect index (temp 4-component vector of float Position) +0:18 'i.pos' (in 3-element array of 4-component vector of float Position) +0:18 'x' (temp int) +0:19 Sequence +0:19 Sequence +0:19 move second child to first child (temp 4-component vector of float) +0:? 'ts.pos' (out 4-component vector of float Position) +0:19 pos: direct index for structure (temp 4-component vector of float) +0:19 'o' (temp structure{temp 4-component vector of float pos}) +0:19 Constant: +0:19 0 (const int) +0:19 EmitVertex (temp void) +0:17 Loop Terminal Expression +0:17 Pre-Increment (temp int) +0:17 'x' (temp int) +0:? Linker Objects +0:? 'i.pos' (in 3-element array of 4-component vector of float Position) +0:? 'ts.pos' (out 4-component vector of float Position) + + +Linked geometry stage: + + +Shader version: 450 +invocations = 1 +max_vertices = 3 +input primitive = triangles +output primitive = triangle_strip +0:? Sequence +0:14 Function Definition: main(struct-PS_IN-vf41[3];struct-GS_OUT-vf41; (temp void) +0:14 Function Parameters: +0:14 'i' (in 3-element array of structure{temp 4-component vector of float Position pos}) +0:14 'ts' (out structure{temp 4-component vector of float Position pos}) +0:? Sequence +0:17 Sequence +0:17 move second child to first child (temp int) +0:17 'x' (temp int) +0:17 Constant: +0:17 0 (const int) +0:17 Loop with condition tested first +0:17 Loop Condition +0:17 Compare Less Than (temp bool) +0:17 'x' (temp int) +0:17 Constant: +0:17 3 (const int) +0:17 Loop Body +0:? Sequence +0:18 move second child to first child (temp 4-component vector of float) +0:18 pos: direct index for structure (temp 4-component vector of float) +0:18 'o' (temp structure{temp 4-component vector of float pos}) +0:18 Constant: +0:18 0 (const int) +0:18 indirect index (temp 4-component vector of float Position) +0:18 'i.pos' (in 3-element array of 4-component vector of float Position) +0:18 'x' (temp int) +0:19 Sequence +0:19 Sequence +0:19 move second child to first child (temp 4-component vector of float) +0:? 'ts.pos' (out 4-component vector of float Position) +0:19 pos: direct index for structure (temp 4-component vector of float) +0:19 'o' (temp structure{temp 4-component vector of float pos}) +0:19 Constant: +0:19 0 (const int) +0:19 EmitVertex (temp void) +0:17 Loop Terminal Expression +0:17 Pre-Increment (temp int) +0:17 'x' (temp int) +0:? Linker Objects +0:? 'i.pos' (in 3-element array of 4-component vector of float Position) +0:? 'ts.pos' (out 4-component vector of float Position) + +// Module Version 10000 +// Generated by (magic number): 80001 +// Id's are bound by 42 + + Capability Geometry + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Geometry 4 "main" 28 36 + ExecutionMode 4 Triangles + ExecutionMode 4 Invocations 1 + ExecutionMode 4 OutputTriangleStrip + ExecutionMode 4 OutputVertices 3 + Name 4 "main" + Name 8 "x" + Name 21 "GS_OUT" + MemberName 21(GS_OUT) 0 "pos" + Name 23 "o" + Name 28 "i.pos" + Name 36 "ts.pos" + Decorate 28(i.pos) BuiltIn Position + Decorate 36(ts.pos) BuiltIn Position + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeInt 32 1 + 7: TypePointer Function 6(int) + 9: 6(int) Constant 0 + 16: 6(int) Constant 3 + 17: TypeBool + 19: TypeFloat 32 + 20: TypeVector 19(float) 4 + 21(GS_OUT): TypeStruct 20(fvec4) + 22: TypePointer Function 21(GS_OUT) + 24: TypeInt 32 0 + 25: 24(int) Constant 3 + 26: TypeArray 20(fvec4) 25 + 27: TypePointer Input 26 + 28(i.pos): 27(ptr) Variable Input + 30: TypePointer Input 20(fvec4) + 33: TypePointer Function 20(fvec4) + 35: TypePointer Output 20(fvec4) + 36(ts.pos): 35(ptr) Variable Output + 40: 6(int) Constant 1 + 4(main): 2 Function None 3 + 5: Label + 8(x): 7(ptr) Variable Function + 23(o): 22(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) + 18: 17(bool) SLessThan 15 16 + BranchConditional 18 11 12 + 11: Label + 29: 6(int) Load 8(x) + 31: 30(ptr) AccessChain 28(i.pos) 29 + 32: 20(fvec4) Load 31 + 34: 33(ptr) AccessChain 23(o) 9 + Store 34 32 + 37: 33(ptr) AccessChain 23(o) 9 + 38: 20(fvec4) Load 37 + Store 36(ts.pos) 38 + EmitVertex + Branch 13 + 13: Label + 39: 6(int) Load 8(x) + 41: 6(int) IAdd 39 40 + Store 8(x) 41 + Branch 10 + 12: Label + Return + FunctionEnd diff --git a/Test/baseResults/hlsl.struct.split.trivial.vert.out b/Test/baseResults/hlsl.struct.split.trivial.vert.out index d8846d2c..bdf156c4 100644 --- a/Test/baseResults/hlsl.struct.split.trivial.vert.out +++ b/Test/baseResults/hlsl.struct.split.trivial.vert.out @@ -1,7 +1,7 @@ hlsl.struct.split.trivial.vert Shader version: 450 0:? Sequence -0:16 Function Definition: main(struct-VS_INPUT-vf41;vf4; (temp structure{temp 4-component vector of float Pos}) +0:16 Function Definition: main(struct-VS_INPUT-vf41;vf4; (temp structure{temp 4-component vector of float Position Pos}) 0:16 Function Parameters: 0:16 'vsin' (in structure{temp 4-component vector of float Pos_in}) 0:16 'Pos_loose' (in 4-component vector of float Position) @@ -24,9 +24,9 @@ Shader version: 450 0:21 0 (const int) 0:21 Branch: Return 0:? Linker Objects -0:? 'Pos' (out 4-component vector of float Position) 0:? 'Pos_in' (in 4-component vector of float Position) 0:? 'Pos_loose' (in 4-component vector of float Position) +0:? 'Pos' (out 4-component vector of float Position) Linked vertex stage: @@ -34,7 +34,7 @@ Linked vertex stage: Shader version: 450 0:? Sequence -0:16 Function Definition: main(struct-VS_INPUT-vf41;vf4; (temp structure{temp 4-component vector of float Pos}) +0:16 Function Definition: main(struct-VS_INPUT-vf41;vf4; (temp structure{temp 4-component vector of float Position Pos}) 0:16 Function Parameters: 0:16 'vsin' (in structure{temp 4-component vector of float Pos_in}) 0:16 'Pos_loose' (in 4-component vector of float Position) @@ -57,9 +57,9 @@ Shader version: 450 0:21 0 (const int) 0:21 Branch: Return 0:? Linker Objects -0:? 'Pos' (out 4-component vector of float Position) 0:? 'Pos_in' (in 4-component vector of float Position) 0:? 'Pos_loose' (in 4-component vector of float Position) +0:? 'Pos' (out 4-component vector of float Position) // Module Version 10000 // Generated by (magic number): 80001 diff --git a/Test/baseResults/hlsl.structarray.flatten.geom.out b/Test/baseResults/hlsl.structarray.flatten.geom.out index b17618be..0922bae8 100644 --- a/Test/baseResults/hlsl.structarray.flatten.geom.out +++ b/Test/baseResults/hlsl.structarray.flatten.geom.out @@ -49,7 +49,7 @@ output primitive = triangle_strip 0:22 Sequence 0:22 Sequence 0:22 move second child to first child (temp 4-component vector of float) -0:? 'position' (out 4-component vector of float Position) +0:? 'outStream.position' (out 4-component vector of float Position) 0:22 position: direct index for structure (temp 4-component vector of float) 0:22 'vout' (temp structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv}) 0:22 Constant: @@ -76,7 +76,7 @@ output primitive = triangle_strip 0:? Linker Objects 0:? 'vin' (layout(location=0 ) in 2-element array of structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv}) 0:? 'outStream' (layout(location=0 ) out structure{temp 4-component vector of float color, temp 2-component vector of float uv}) -0:? 'position' (out 4-component vector of float Position) +0:? 'outStream.position' (out 4-component vector of float Position) Linked geometry stage: @@ -132,7 +132,7 @@ output primitive = triangle_strip 0:22 Sequence 0:22 Sequence 0:22 move second child to first child (temp 4-component vector of float) -0:? 'position' (out 4-component vector of float Position) +0:? 'outStream.position' (out 4-component vector of float Position) 0:22 position: direct index for structure (temp 4-component vector of float) 0:22 'vout' (temp structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv}) 0:22 Constant: @@ -159,7 +159,7 @@ output primitive = triangle_strip 0:? Linker Objects 0:? 'vin' (layout(location=0 ) in 2-element array of structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv}) 0:? 'outStream' (layout(location=0 ) out structure{temp 4-component vector of float color, temp 2-component vector of float uv}) -0:? 'position' (out 4-component vector of float Position) +0:? 'outStream.position' (out 4-component vector of float Position) // Module Version 10000 // Generated by (magic number): 80001 @@ -184,13 +184,13 @@ output primitive = triangle_strip MemberName 14(VertexData) 1 "color" MemberName 14(VertexData) 2 "uv" Name 19 "vin" - Name 36 "position" + Name 36 "outStream.position" Name 39 "PS_IN" MemberName 39(PS_IN) 0 "color" MemberName 39(PS_IN) 1 "uv" Name 41 "outStream" Decorate 19(vin) Location 0 - Decorate 36(position) BuiltIn Position + Decorate 36(outStream.position) BuiltIn Position Decorate 41(outStream) Location 0 2: TypeVoid 3: TypeFunction 2 @@ -214,7 +214,7 @@ output primitive = triangle_strip 29: TypePointer Function 8(fvec2) 31: 12(int) Constant 0 35: TypePointer Output 7(fvec4) - 36(position): 35(ptr) Variable Output +36(outStream.position): 35(ptr) Variable Output 39(PS_IN): TypeStruct 7(fvec4) 8(fvec2) 40: TypePointer Output 39(PS_IN) 41(outStream): 40(ptr) Variable Output @@ -236,7 +236,7 @@ output primitive = triangle_strip Store 34 33 37: 23(ptr) AccessChain 11(vout) 31 38: 7(fvec4) Load 37 - Store 36(position) 38 + Store 36(outStream.position) 38 42: 23(ptr) AccessChain 11(vout) 13 43: 7(fvec4) Load 42 44: 35(ptr) AccessChain 41(outStream) 31 diff --git a/Test/baseResults/hlsl.structin.vert.out b/Test/baseResults/hlsl.structin.vert.out index 61954716..5e83ed4f 100755 --- a/Test/baseResults/hlsl.structin.vert.out +++ b/Test/baseResults/hlsl.structin.vert.out @@ -28,36 +28,15 @@ Shader version: 450 0:11 'e' (layout(location=5 ) in 4-component vector of float) 0:13 Sequence 0:13 Sequence -0:13 move second child to first child (temp 4-component vector of float) -0:13 direct index (temp 4-component vector of float) -0:13 m: direct index for structure (temp 2-element array of 4-component vector of float) -0:13 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) -0:13 Constant: -0:13 0 (const int) +0:13 move second child to first child (temp 2-element array of 4-component vector of float) +0:13 m: direct index for structure (temp 2-element array of 4-component vector of float) +0:13 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) 0:13 Constant: 0:13 0 (const int) -0:13 direct index (temp 4-component vector of float) -0:13 m: direct index for structure (temp 2-element array of 4-component vector of float) -0:13 'local' (temp structure{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) -0:13 Constant: -0:13 0 (const int) +0:13 m: direct index for structure (temp 2-element array of 4-component vector of float) +0:13 'local' (temp structure{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) 0:13 Constant: 0:13 0 (const int) -0:13 move second child to first child (temp 4-component vector of float) -0:13 direct index (temp 4-component vector of float) -0:13 m: direct index for structure (temp 2-element array of 4-component vector of float) -0:13 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) -0:13 Constant: -0:13 0 (const int) -0:13 Constant: -0:13 1 (const int) -0:13 direct index (temp 4-component vector of float) -0:13 m: direct index for structure (temp 2-element array of 4-component vector of float) -0:13 'local' (temp structure{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) -0:13 Constant: -0:13 0 (const int) -0:13 Constant: -0:13 1 (const int) 0:13 move second child to first child (temp 2-component vector of uint) 0:13 coord: direct index for structure (temp 2-component vector of uint) 0:13 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) @@ -68,7 +47,7 @@ Shader version: 450 0:13 Constant: 0:13 1 (const int) 0:13 move second child to first child (temp 4-component vector of float) -0:13 b: direct index for structure (temp 4-component vector of float) +0:13 b: direct index for structure (smooth temp 4-component vector of float) 0:13 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) 0:13 Constant: 0:13 2 (const int) @@ -121,36 +100,15 @@ Shader version: 450 0:11 'e' (layout(location=5 ) in 4-component vector of float) 0:13 Sequence 0:13 Sequence -0:13 move second child to first child (temp 4-component vector of float) -0:13 direct index (temp 4-component vector of float) -0:13 m: direct index for structure (temp 2-element array of 4-component vector of float) -0:13 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) -0:13 Constant: -0:13 0 (const int) +0:13 move second child to first child (temp 2-element array of 4-component vector of float) +0:13 m: direct index for structure (temp 2-element array of 4-component vector of float) +0:13 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) 0:13 Constant: 0:13 0 (const int) -0:13 direct index (temp 4-component vector of float) -0:13 m: direct index for structure (temp 2-element array of 4-component vector of float) -0:13 'local' (temp structure{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) -0:13 Constant: -0:13 0 (const int) +0:13 m: direct index for structure (temp 2-element array of 4-component vector of float) +0:13 'local' (temp structure{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) 0:13 Constant: 0:13 0 (const int) -0:13 move second child to first child (temp 4-component vector of float) -0:13 direct index (temp 4-component vector of float) -0:13 m: direct index for structure (temp 2-element array of 4-component vector of float) -0:13 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) -0:13 Constant: -0:13 0 (const int) -0:13 Constant: -0:13 1 (const int) -0:13 direct index (temp 4-component vector of float) -0:13 m: direct index for structure (temp 2-element array of 4-component vector of float) -0:13 'local' (temp structure{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, temp 4-component vector of float b}) -0:13 Constant: -0:13 0 (const int) -0:13 Constant: -0:13 1 (const int) 0:13 move second child to first child (temp 2-component vector of uint) 0:13 coord: direct index for structure (temp 2-component vector of uint) 0:13 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) @@ -161,7 +119,7 @@ Shader version: 450 0:13 Constant: 0:13 1 (const int) 0:13 move second child to first child (temp 4-component vector of float) -0:13 b: direct index for structure (temp 4-component vector of float) +0:13 b: direct index for structure (smooth temp 4-component vector of float) 0:13 '@entryPointOutput' (out structure Position{temp 2-element array of 4-component vector of float m, temp 2-component vector of uint coord, smooth temp 4-component vector of float b}) 0:13 Constant: 0:13 2 (const int) @@ -183,12 +141,12 @@ Shader version: 450 // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 62 +// Id's are bound by 61 Capability Shader 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint Vertex 4 "main" 18 20 24 32 35 42 61 + EntryPoint Vertex 4 "main" 18 20 24 32 35 42 60 Name 4 "main" Name 12 "VI" MemberName 12(VI) 0 "m" @@ -205,14 +163,14 @@ Shader version: 450 MemberName 40(VI) 1 "coord" MemberName 40(VI) 2 "b" Name 42 "@entryPointOutput" - Name 61 "b" + Name 60 "b" Decorate 18(m[1]) Location 2 Decorate 20(m[0]) Location 1 Decorate 24(coord) Location 3 Decorate 32(d) Location 0 Decorate 35(e) Location 5 Decorate 42(@entryPointOutput) BuiltIn Position - Decorate 61(b) Location 4 + Decorate 60(b) Location 4 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -239,11 +197,13 @@ Shader version: 450 41: TypePointer Output 40(VI) 42(@entryPointOutput): 41(ptr) Variable Output 43: 15(int) Constant 0 - 46: TypePointer Output 7(fvec4) - 48: 15(int) Constant 1 - 52: TypePointer Function 11(ivec2) - 55: TypePointer Output 11(ivec2) - 61(b): 17(ptr) Variable Input + 44: TypePointer Function 10 + 47: TypePointer Output 10 + 49: 15(int) Constant 1 + 50: TypePointer Function 11(ivec2) + 53: TypePointer Output 11(ivec2) + 57: TypePointer Output 7(fvec4) + 60(b): 17(ptr) Variable Input 4(main): 2 Function None 3 5: Label 14(local): 13(ptr) Variable Function @@ -261,21 +221,17 @@ Shader version: 450 37: 7(fvec4) FAdd 34 36 39: 38(ptr) AccessChain 14(local) 16 Store 39 37 - 44: 38(ptr) AccessChain 14(local) 43 43 - 45: 7(fvec4) Load 44 - 47: 46(ptr) AccessChain 42(@entryPointOutput) 43 43 - Store 47 45 - 49: 38(ptr) AccessChain 14(local) 43 48 - 50: 7(fvec4) Load 49 - 51: 46(ptr) AccessChain 42(@entryPointOutput) 43 48 - Store 51 50 - 53: 52(ptr) AccessChain 14(local) 48 - 54: 11(ivec2) Load 53 - 56: 55(ptr) AccessChain 42(@entryPointOutput) 48 - Store 56 54 - 57: 38(ptr) AccessChain 14(local) 16 - 58: 7(fvec4) Load 57 - 59: 46(ptr) AccessChain 42(@entryPointOutput) 16 - Store 59 58 + 45: 44(ptr) AccessChain 14(local) 43 + 46: 10 Load 45 + 48: 47(ptr) AccessChain 42(@entryPointOutput) 43 + Store 48 46 + 51: 50(ptr) AccessChain 14(local) 49 + 52: 11(ivec2) Load 51 + 54: 53(ptr) AccessChain 42(@entryPointOutput) 49 + Store 54 52 + 55: 38(ptr) AccessChain 14(local) 16 + 56: 7(fvec4) Load 55 + 58: 57(ptr) AccessChain 42(@entryPointOutput) 16 + Store 58 56 Return FunctionEnd diff --git a/Test/hlsl.struct.split.array.geom b/Test/hlsl.struct.split.array.geom new file mode 100644 index 00000000..9008df16 --- /dev/null +++ b/Test/hlsl.struct.split.array.geom @@ -0,0 +1,21 @@ +struct PSInput +{ + float4 Pos : SV_POSITION; + float2 TexCoord : TEXCOORD; + float3 TerrainPos : TERRAINPOS; + uint VertexID : VertexID; +}; + +typedef PSInput foo_t[2][3]; + +[maxvertexcount(4)] +void main(point uint v[1] : VertexID, inout TriangleStream OutputStream) +{ + foo_t Verts; + + PSInput Out = (PSInput) 0; + + for (int x=0; x<2; ++x) + for (int y=0; y<2; ++y) + Verts[x][y] = Out; +} diff --git a/Test/hlsl.struct.split.nested.geom b/Test/hlsl.struct.split.nested.geom new file mode 100644 index 00000000..03bf38f3 --- /dev/null +++ b/Test/hlsl.struct.split.nested.geom @@ -0,0 +1,31 @@ + +struct STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO +{ + float m0_array[2]; + int m1; +}; + +struct PS_IN +{ + float4 pos : SV_Position; + float2 tc : TEXCOORD0; + // float c : SV_ClipDistance0; +}; + +struct GS_OUT +{ + PS_IN psIn; + STRUCT_WITH_NO_BUILTIN_INTERSTAGE_IO contains_no_builtin_io; +}; + + +[maxvertexcount(3)] +void main(triangle PS_IN tin[3], inout TriangleStream ts ) +{ + GS_OUT o; + + o.psIn.pos = float4(1,2,3,4); + o.psIn.tc = float2(5,6); + + ts.Append(o); +} diff --git a/Test/hlsl.struct.split.trivial.geom b/Test/hlsl.struct.split.trivial.geom new file mode 100644 index 00000000..343da38e --- /dev/null +++ b/Test/hlsl.struct.split.trivial.geom @@ -0,0 +1,21 @@ + +struct PS_IN +{ + float4 pos : SV_Position; +}; + +struct GS_OUT +{ + float4 pos : SV_Position; +}; + +[maxvertexcount(3)] +void main(triangle PS_IN i[3], inout TriangleStream ts) +{ + GS_OUT o; + + for (int x=0; x<3; ++x) { + o.pos = i[x].pos; + ts.Append(o); + } +} diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index bbadac5f..6bd201d4 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -1320,7 +1320,7 @@ public: virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); } // Return true if this is interstage IO - virtual bool isInterstageIO() const + virtual bool isBuiltInInterstageIO() const { switch (getQualifier().builtIn) { case EbvPosition: @@ -1401,28 +1401,28 @@ public: } // Recursively checks if the type contains an interstage IO builtin - virtual bool containsInterstageIO() const + virtual bool containsBuiltInInterstageIO() const { - if (isInterstageIO()) + if (isBuiltInInterstageIO()) return true; if (! structure) return false; for (unsigned int i = 0; i < structure->size(); ++i) { - if ((*structure)[i].type->containsInterstageIO()) + if ((*structure)[i].type->containsBuiltInInterstageIO()) return true; } return false; } // Recursively checks whether a struct contains only interstage IO - virtual bool containsOnlyInterstageIO() const + virtual bool containsOnlyBuiltInInterstageIO() const { if (! structure) - return isInterstageIO(); + return isBuiltInInterstageIO(); for (unsigned int i = 0; i < structure->size(); ++i) { - if (!(*structure)[i].type->containsOnlyInterstageIO()) + if (!(*structure)[i].type->containsOnlyBuiltInInterstageIO()) return false; } return true; diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp index 7fdca871..3faf63ab 100644 --- a/gtests/Hlsl.FromFile.cpp +++ b/gtests/Hlsl.FromFile.cpp @@ -205,7 +205,10 @@ INSTANTIATE_TEST_CASE_P( {"hlsl.stringtoken.frag", "main"}, {"hlsl.string.frag", "main"}, {"hlsl.struct.split-1.vert", "main"}, + {"hlsl.struct.split.array.geom", "main"}, {"hlsl.struct.split.call.vert", "main"}, + {"hlsl.struct.split.nested.geom", "main"}, + {"hlsl.struct.split.trivial.geom", "main"}, {"hlsl.struct.split.trivial.vert", "main"}, {"hlsl.structarray.flatten.frag", "main"}, {"hlsl.structarray.flatten.geom", "main"}, diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index b874aa8c..bce43ed2 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -478,7 +478,7 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type) // type_specifier if (! acceptType(type)) { // If this is not a type, we may have inadvertently gone down a wrong path - // py parsing "sample", which can be treated like either an identifier or a + // by parsing "sample", which can be treated like either an identifier or a // qualifier. Back it out, if we did. if (qualifier.sample) recedeToken(); diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index c81c3a21..1b1a7824 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -59,9 +59,12 @@ HlslParseContext::HlslParseContext(TSymbolTable& symbolTable, TIntermediate& int loopNestingLevel(0), annotationNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0), postEntryPointReturn(false), limits(resources.limits), + inEntryPoint(false), entryPointOutput(nullptr), nextInLocation(0), nextOutLocation(0), - sourceEntryPointName(sourceEntryPointName) + sourceEntryPointName(sourceEntryPointName), + builtInIoIndex(nullptr), + builtInIoBase(nullptr) { globalUniformDefaults.clear(); globalUniformDefaults.layoutMatrix = ElmRowMajor; @@ -656,11 +659,13 @@ TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc, if (base->getAsSymbolNode() && (wasFlattened(base) || shouldFlatten(base->getType()))) { if (index->getQualifier().storage != EvqConst) - error(loc, "Invalid variable index to flattened uniform array", base->getAsSymbolNode()->getName().c_str(), ""); + error(loc, "Invalid variable index to flattened array", base->getAsSymbolNode()->getName().c_str(), ""); result = flattenAccess(base, indexValue); flattened = (result != base); } else { + splitAccessArray(loc, base, index); + if (index->getQualifier().storage == EvqConst) { if (base->getType().isImplicitlySizedArray()) updateImplicitArraySize(loc, base, indexValue); @@ -765,11 +770,9 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt } } else if (field == "Append" || field == "RestartStrip") { - // These methods only valid on stage in variables - // TODO: ... which are stream out types, if there's any way to test that here. - if (base->getType().getQualifier().storage == EvqVaryingOut) { - return intermediate.addMethod(base, TType(EbtVoid), &field, loc); - } + // We cannot check the type here: it may be sanitized if we're not compiling a geometry shader, but + // the code is around in the shader source. + return intermediate.addMethod(base, TType(EbtVoid), &field, loc); } // It's not .length() if we get to here. @@ -838,7 +841,7 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt result = flattenAccess(base, member); } else { // Update the base and member to access if this was a split structure. - result = splitAccess(loc, base, member); + result = splitAccessStruct(loc, base, member); fields = base->getType().getStruct(); if (result == nullptr) { @@ -859,23 +862,20 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt return result; } -// Determine whether we should split this structure -bool HlslParseContext::shouldSplit(const TSourceLoc& loc, const TType& type) +// Determine whether we should split this type +bool HlslParseContext::shouldSplit(const TType& type) { if (! inEntryPoint) return false; const TStorageQualifier qualifier = type.getQualifier().storage; - if (type.containsInterstageIO() && type.containsStructure()) - error(loc, "structure splitting not yet supported on nested structures", "", ""); - // If it contains interstage IO, but not ONLY interstage IO, split the struct. - return (type.containsInterstageIO() && !type.containsOnlyInterstageIO()) && + return type.isStruct() && type.containsBuiltInInterstageIO() && (qualifier == EvqVaryingIn || qualifier == EvqVaryingOut); } -// Split the type of the node into two structs: +// Split the type of the given node into two structs: // 1. interstage IO // 2. everything else // IO members are put into the ioStruct. The type is modified to remove them. @@ -890,38 +890,59 @@ void HlslParseContext::split(TIntermTyped* node) return; // Create a new variable: - splitIoVars[symNode->getId()] = makeInternalVariable(symNode->getName(), split(*symNode->getType().clone())); + TType& splitType = split(*symNode->getType().clone(), symNode->getName()); + + splitIoVars[symNode->getId()] = makeInternalVariable(symNode->getName(), splitType); } -// Split the type of the variable into two structs: +// Split the type of the given variable into two structs: void HlslParseContext::split(const TVariable& variable) { const TType& type = variable.getType(); + TString name = (&variable == entryPointOutput) ? "" : variable.getName(); + // Create a new variable: - splitIoVars[variable.getUniqueId()] = makeInternalVariable(variable.getName(), split(*type.clone())); + TType& splitType = split(*type.clone(), name); + + splitIoVars[variable.getUniqueId()] = makeInternalVariable(variable.getName(), splitType); } // Recursive implementation of split(const TVariable& variable). // Returns reference to the modified type. -TType& HlslParseContext::split(TType& type) +TType& HlslParseContext::split(TType& type, TString name, const TType* outerStructType) { + const TArraySizes* arraySizes = nullptr; + + // At the outer-most scope, remember the struct type so we can examine its storage class + // at deeper levels. + if (outerStructType == nullptr) + outerStructType = &type; + + if (type.isArray()) + arraySizes = &type.getArraySizes(); + // We can ignore arrayness: it's uninvolved. if (type.isStruct()) { TTypeList* userStructure = type.getWritableStruct(); - // Get iterator to (now at end) set of iterstage IO members + // Get iterator to (now at end) set of builtin iterstage IO members const auto firstIo = std::stable_partition(userStructure->begin(), userStructure->end(), - [](const TTypeLoc& t) {return !t.type->isInterstageIO();}); + [](const TTypeLoc& t) {return !t.type->isBuiltInInterstageIO();}); - // Move these to the IO. + // Move those to the builtin IO. However, we also propagate arrayness (just one level is handled + // now) to this variable. for (auto ioType = firstIo; ioType != userStructure->end(); ++ioType) { const TType& memberType = *ioType->type; - TVariable* ioVar = makeInternalVariable(memberType.getFieldName(), memberType); + TVariable* ioVar = makeInternalVariable(name + (name.empty() ? "" : ".") + memberType.getFieldName(), memberType); + + if (arraySizes) + ioVar->getWritableType().newArraySizes(*arraySizes); + + interstageBuiltInIo[tInterstageIoData(memberType, *outerStructType)] = ioVar; // Merge qualifier from the user structure - mergeQualifiers(ioVar->getWritableType().getQualifier(), type.getQualifier()); - interstageIo[memberType.getQualifier().builtIn] = ioVar; + mergeQualifiers(ioVar->getWritableType().getQualifier(), outerStructType->getQualifier()); } // Erase the IO vars from the user structure. @@ -929,7 +950,9 @@ TType& HlslParseContext::split(TType& type) // Recurse further into the members. for (unsigned int i = 0; i < userStructure->size(); ++i) - split(*(*userStructure)[i].type); + split(*(*userStructure)[i].type, + name + (name.empty() ? "" : ".") + (*userStructure)[i].type->getFieldName(), + outerStructType); } return type; @@ -953,11 +976,6 @@ bool HlslParseContext::shouldFlattenIO(const TType& type) const if (!type.isStruct()) return false; - // Regardless of stage, we flatten IO structs containing only interstage IO, - // to avoid degenerate structure splitting. - if (type.containsOnlyInterstageIO()) - return true; - return ((language == EShLangVertex && qualifier == EvqVaryingIn) || (language == EShLangFragment && qualifier == EvqVaryingOut)); } @@ -1015,13 +1033,6 @@ void HlslParseContext::flatten(const TSourceLoc& loc, const TVariable& variable) int HlslParseContext::flatten(const TSourceLoc& loc, const TVariable& variable, const TType& type, TFlattenData& flattenData, TString name) { - // This should be handled by structure splitting, not flattening. - if (language == EShLangGeometry) { - const TType derefType(type, 0); - if (!isFinalFlattening(derefType) && type.getQualifier().storage == EvqVaryingIn) - error(loc, "recursive type not supported in GS input", variable.getName().c_str(), ""); - } - // If something is an arrayed struct, the array flattener will recursively call flatten() // to then flatten the struct, so this is an "if else": we don't do both. if (type.isArray()) @@ -1207,16 +1218,39 @@ TVariable* HlslParseContext::getSplitIoVar(const TIntermTyped* node) const return getSplitIoVar(symbolNode->getId()); } +// Remember the index used to dereference into this structure, in case it has to be moved to a +// split-off builtin IO member. +void HlslParseContext::splitAccessArray(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index) +{ + const TVariable* splitIoVar = getSplitIoVar(base); -// Turn an access into an aggregate that was split to instead be -// an access to either the modified variable, or one of the split -// member variables. -TIntermTyped* HlslParseContext::splitAccess(const TSourceLoc& loc, TIntermTyped*& base, int& member) + // Not a split structure + if (splitIoVar == nullptr) + return; + + if (builtInIoBase) { + error(loc, "only one array dimension supported for builtIn IO variable", "", ""); + return; + } + + builtInIoBase = base; + builtInIoIndex = index; +} + + +// Turn an access into an struct that was split to instead be an +// access to either the modified structure, or a direct reference to +// one of the split member variables. +TIntermTyped* HlslParseContext::splitAccessStruct(const TSourceLoc& loc, TIntermTyped*& base, int& member) { // nothing to do - if (base == nullptr || base->getAsSymbolNode() == nullptr) + if (base == nullptr) return nullptr; + // We have a pending bracket reference to an outer struct that we may want to move to an inner member. + if (builtInIoBase) + base = builtInIoBase; + const TVariable* splitIoVar = getSplitIoVar(base); if (splitIoVar == nullptr) @@ -1224,16 +1258,33 @@ TIntermTyped* HlslParseContext::splitAccess(const TSourceLoc& loc, TIntermTyped* const TTypeList& members = *base->getType().getStruct(); - if (members[member].type->isInterstageIO()) { - // It's one of the interstage IO variables we split out. - return intermediate.addSymbol(*interstageIo[members[member].type->getQualifier().builtIn], loc); + const TType& memberType = *members[member].type; + + if (memberType.isBuiltInInterstageIO()) { + // It's one of the interstage IO variables we split off. + TIntermTyped* builtIn = intermediate.addSymbol(*interstageBuiltInIo[tInterstageIoData(memberType, base->getType())], loc); + + // If there's an array reference to an outer split struct, we re-apply it here. + if (builtInIoIndex != nullptr) { + if (builtInIoIndex->getQualifier().storage == EvqConst) + builtIn = intermediate.addIndex(EOpIndexDirect, builtIn, builtInIoIndex, loc); + else + builtIn = intermediate.addIndex(EOpIndexIndirect, builtIn, builtInIoIndex, loc); + + builtIn->setType(memberType); + + builtInIoIndex = nullptr; + builtInIoBase = nullptr; + } + + return builtIn; } else { // It's not an IO variable. Find the equivalent index into the new variable. base = intermediate.addSymbol(*splitIoVar, loc); int newMember = 0; for (int m=0; misInterstageIO()) + if (!members[m].type->isBuiltInInterstageIO()) ++newMember; member = newMember; @@ -1270,7 +1321,13 @@ void HlslParseContext::assignLocations(TVariable& variable) for (auto member = memberList.begin(); member != memberList.end(); ++member) assignLocation(**member); } else if (wasSplit(variable.getUniqueId())) { - assignLocation(*getSplitIoVar(&variable)); + TVariable* splitIoVar = getSplitIoVar(&variable); + const TTypeList* structure = splitIoVar->getType().getStruct(); + // Struct splitting can produce empty structures if the only members of the + // struct were builtin interstage IO types. Only assign locations if it + // isn't a struct, or is a non-empty struct. + if (structure == nullptr || !structure->empty()) + assignLocation(*splitIoVar); } else { assignLocation(variable); } @@ -1321,19 +1378,17 @@ TFunction& HlslParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFu // Add interstage IO variables to the linkage in canonical order. void HlslParseContext::addInterstageIoToLinkage() { - if (inEntryPoint) { - std::vector io; - io.reserve(interstageIo.size()); + std::vector io; + io.reserve(interstageBuiltInIo.size()); - for (auto ioVar = interstageIo.begin(); ioVar != interstageIo.end(); ++ioVar) - io.push_back(ioVar->first); + for (auto ioVar = interstageBuiltInIo.begin(); ioVar != interstageBuiltInIo.end(); ++ioVar) + io.push_back(ioVar->first); - // Our canonical order is the TBuiltInVariable value order. - std::sort(io.begin(), io.end()); + // Our canonical order is the TBuiltInVariable numeric order. + std::sort(io.begin(), io.end()); - for (int ioVar = 0; ioVar < int(io.size()); ++ioVar) - trackLinkageDeferred(*interstageIo[io[ioVar]]); - } + for (int idx = 0; idx < int(io.size()); ++idx) + trackLinkageDeferred(*interstageBuiltInIo[io[idx]]); } // @@ -1374,7 +1429,7 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l if (entryPointOutput) { if (shouldFlatten(entryPointOutput->getType())) flatten(loc, *entryPointOutput); - if (shouldSplit(loc, entryPointOutput->getType())) + if (shouldSplit(entryPointOutput->getType())) split(*entryPointOutput); assignLocations(*entryPointOutput); } @@ -1421,7 +1476,7 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l if (inEntryPoint) { if (shouldFlatten(*param.type)) flatten(loc, *variable); - if (shouldSplit(loc, *param.type)) + if (shouldSplit(*param.type)) split(*variable); assignLocations(*variable); } @@ -1593,15 +1648,15 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op if (left == nullptr || right == nullptr) return nullptr; - const bool splitLeft = wasSplit(left); - const bool splitRight = wasSplit(right); + const bool isSplitLeft = wasSplit(left); + const bool isSplitRight = wasSplit(right); - const bool flattenLeft = wasFlattened(left); - const bool flattenRight = wasFlattened(right); + const bool isFlattenLeft = wasFlattened(left); + const bool isFlattenRight = wasFlattened(right); // OK to do a single assign if both are split, or both are unsplit. But if one is and the other // isn't, we fall back to a memberwise copy. - if (! flattenLeft && ! flattenRight && !splitLeft && !splitRight) + if (! isFlattenLeft && ! isFlattenRight && !isSplitLeft && !isSplitRight) return intermediate.addAssign(op, left, right, loc); TIntermAggregate* assignList = nullptr; @@ -1627,10 +1682,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op if (left->getType().isArray()) memberCount = left->getType().getCumulativeArraySize(); - if (flattenLeft) + if (isFlattenLeft) leftVariables = &flattenMap.find(left->getAsSymbolNode()->getId())->second.members; - if (flattenRight) { + if (isFlattenRight) { rightVariables = &flattenMap.find(right->getAsSymbolNode()->getId())->second.members; } else { // The RHS is not flattened. There are several cases: @@ -1658,19 +1713,30 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op int memberIdx = 0; - const auto getMember = [&](bool flatten, bool split, TIntermTyped* node, - const TVector& memberVariables, int member, - TOperator op, const TType& memberType) -> TIntermTyped * { + // We track the outer-most aggregate, so that we can use its storage class later. + const TIntermTyped* outerLeft = left; + const TIntermTyped* outerRight = right; + + const auto getMember = [&](bool isLeft, TIntermTyped* node, int member, TIntermTyped* splitNode, int splitMember) -> TIntermTyped * { TIntermTyped* subTree; - if (split && memberType.isInterstageIO()) { - // copy from interstage IO variable if needed - subTree = intermediate.addSymbol(*interstageIo.find(memberType.getQualifier().builtIn)->second); - } else if (flatten && isFinalFlattening(memberType)) { - subTree = intermediate.addSymbol(*memberVariables[memberIdx++]); + const bool flattened = isLeft ? isFlattenLeft : isFlattenRight; + const bool split = isLeft ? isSplitLeft : isSplitRight; + const TIntermTyped* outer = isLeft ? outerLeft : outerRight; + const TVector& flatVariables = isLeft ? *leftVariables : *rightVariables; + const TOperator op = node->getType().isArray() ? EOpIndexDirect : EOpIndexDirectStruct; + const TType derefType(node->getType(), member); + + if (split && derefType.isBuiltInInterstageIO()) { + // copy from interstage IO builtin if needed + subTree = intermediate.addSymbol(*interstageBuiltInIo.find(tInterstageIoData(derefType, outer->getType()))->second); + } else if (flattened && isFinalFlattening(derefType)) { + subTree = intermediate.addSymbol(*flatVariables[memberIdx++]); } else { - subTree = intermediate.addIndex(op, node, intermediate.addConstantUnion(member, loc), loc); - subTree->setType(memberType); + const TType splitDerefType(splitNode->getType(), splitMember); + + subTree = intermediate.addIndex(op, splitNode, intermediate.addConstantUnion(splitMember, loc), loc); + subTree->setType(splitDerefType); } return subTree; @@ -1682,44 +1748,34 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op cloneSymNode ? intermediate.addSymbol(*cloneSymNode) : right; - TIntermTyped* leftVar = left; - TIntermTyped* rightVar = right; - // If either left or right was a split structure, use the split form when reading and writing - if (splitLeft) - leftVar = intermediate.addSymbol(*getSplitIoVar(left), loc); - - if (splitRight) - rightVar = intermediate.addSymbol(*getSplitIoVar(right), loc); - // Cannot use auto here, because this is recursive, and auto can't work out the type without seeing the // whole thing. So, we'll resort to an explicit type via std::function. - const std::function - traverse = [&](TIntermTyped* left, TIntermTyped* right) -> void { + const std::function + traverse = [&](TIntermTyped* left, TIntermTyped* right, TIntermTyped* splitLeft, TIntermTyped* splitRight) -> void { // If we get here, we are assigning to or from a whole array or struct that must be // flattened, so have to do member-by-member assignment: if (left->getType().isArray()) { - // array case const TType dereferencedType(left->getType(), 0); + // array case for (int element=0; element < left->getType().getOuterArraySize(); ++element) { // Add a new AST symbol node if we have a temp variable holding a complex RHS. - TIntermTyped* subRight = getMember(flattenRight, splitRight, right, *rightVariables, element, - EOpIndexDirect, dereferencedType); - TIntermTyped* subLeft = getMember(flattenLeft, splitLeft, left, *leftVariables, element, - EOpIndexDirect, dereferencedType); + TIntermTyped* subLeft = getMember(true, left, element, left, element); + TIntermTyped* subRight = getMember(false, right, element, right, element); if (isFinalFlattening(dereferencedType)) assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subLeft, subRight, loc), loc); else - traverse(subLeft, subRight); + traverse(subLeft, subRight, splitLeft, splitRight); } } else if (left->getType().isStruct()) { // struct case const auto& membersL = *left->getType().getStruct(); const auto& membersR = *right->getType().getStruct(); - // These track the members in the split structures corresponding to the same in the unsplit structures. + // These track the members in the split structures corresponding to the same in the unsplit structures, + // which we traverse in parallel. int memberL = 0; int memberR = 0; @@ -1727,21 +1783,27 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op const TType& typeL = *membersL[member].type; const TType& typeR = *membersR[member].type; - TIntermTyped* subLeft = getMember(flattenLeft, splitLeft, leftVar, *leftVariables, - memberL, EOpIndexDirectStruct, typeL); - TIntermTyped* subRight = getMember(flattenRight, splitRight, rightVar, *rightVariables, - memberR, EOpIndexDirectStruct, typeR); + TIntermTyped* subLeft = getMember(true, left, member, left, member); + TIntermTyped* subRight = getMember(false, right, member, right, member); - if (!isFinalFlattening(typeL)) { - // TODO: if we're not flattening, that means we got here because of struct splitting, and - // we could copy whole sub-structures at once as long as they do not contain interstage IO themselves. - traverse(subLeft, subRight); + // If there is no splitting, use the same values to avoid inefficiency. + TIntermTyped* subSplitLeft = isSplitLeft ? getMember(true, left, member, splitLeft, memberL) : subLeft; + TIntermTyped* subSplitRight = isSplitRight ? getMember(false, right, member, splitRight, memberR) : subRight; + + // If this is the final flattening (no nested types below to flatten) we'll copy the member, else + // recurse into the type hierarchy. However, if splitting the struct, that means we can copy a whole + // subtree here IFF it does not itself contain any interstage built-in IO variables, so we only have to + // recurse into it if there's something for splitting to do. That can save a lot of AST verbosity for + // a bunch of memberwise copies. + if (isFinalFlattening(typeL) || (!isFlattenLeft && !isFlattenRight && + !typeL.containsBuiltInInterstageIO() && !typeR.containsBuiltInInterstageIO())) { + assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subSplitLeft, subSplitRight, loc), loc); } else { - assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subLeft, subRight, loc), loc); + traverse(subLeft, subRight, subSplitLeft, subSplitRight); } - memberL += (typeL.isInterstageIO() ? 0 : 1); - memberR += (typeR.isInterstageIO() ? 0 : 1); + memberL += (typeL.isBuiltInInterstageIO() ? 0 : 1); + memberR += (typeR.isBuiltInInterstageIO() ? 0 : 1); } } else { assert(0); // we should never be called on a non-flattenable thing, because @@ -1750,8 +1812,19 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op }; + TIntermTyped* splitLeft = left; + TIntermTyped* splitRight = right; + + // If either left or right was a split structure, we must read or write it, but still have to + // parallel-recurse through the unsplit structure to identify the builtin IO vars. + if (isSplitLeft) + splitLeft = intermediate.addSymbol(*getSplitIoVar(left), loc); + + if (isSplitRight) + splitRight = intermediate.addSymbol(*getSplitIoVar(right), loc); + // This makes the whole assignment, recursing through subtypes as needed. - traverse(left, right); + traverse(left, right, splitLeft, splitRight); assert(assignList != nullptr); assignList->setOperator(EOpSequence); @@ -4962,9 +5035,17 @@ TType* HlslParseContext::sanitizeType(TType* type) if (sanitizedTypeIter != sanitizedTypeMap.end()) { // We've sanitized this before. Use that one. - return sanitizedTypeIter->second; + TType* sanitizedType = new TType(); + sanitizedType->shallowCopy(*sanitizedTypeIter->second); + + // Arrayness is not part of the sanitized type. Use the input type's arrayness. + if (type->isArray()) + sanitizedType->newArraySizes(type->getArraySizes()); + else + sanitizedType->clearArraySizes(); + return sanitizedType; } else { - if (type->containsInterstageIO()) { + if (type->containsBuiltInInterstageIO()) { // This means the type contains interstage IO, but we've never encountered it before. // Copy it, sanitize it, and remember it in the sanitizedTypeMap TType* sanitizedType = type->clone(); @@ -5000,7 +5081,7 @@ TIntermNode* HlslParseContext::declareVariable(const TSourceLoc& loc, TString& i inheritGlobalDefaults(type.getQualifier()); const bool flattenVar = shouldFlatten(type); - const bool splitVar = shouldSplit(loc, type); + const bool splitVar = shouldSplit(type); // Type sanitization: if this is declaring a variable of a type that contains // interstage IO, we want to make it a temporary. diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index 6e7d77a9..6b4cc1d2 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -209,9 +209,10 @@ protected: bool isFinalFlattening(const TType& type) const { return !(type.isStruct() || type.isArray()); } // Structure splitting (splits interstage builtin types into its own struct) - bool shouldSplit(const TSourceLoc& loc, const TType&); - TIntermTyped* splitAccess(const TSourceLoc& loc, TIntermTyped*& base, int& member); - TType& split(TType& type); + bool shouldSplit(const TType&); + TIntermTyped* splitAccessStruct(const TSourceLoc& loc, TIntermTyped*& base, int& member); + void splitAccessArray(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index); + TType& split(TType& type, TString name, const TType* outerStructType = nullptr); void split(TIntermTyped*); void split(const TVariable&); bool wasSplit(const TIntermTyped* node) const; @@ -301,8 +302,32 @@ protected: TMap sanitizedTypeMap; // Structure splitting data: - TMap interstageIo; // new structure created for interstage IO from user structs. - TMap splitIoVars; // individual flattened variables + TMap splitIoVars; // variables with the builtin interstage IO removed, indexed by unique ID. + + // The builtin interstage IO map considers e.g, EvqPosition on input and output separately, so that we + // can build the linkage correctly if position appears on both sides. Otherwise, multiple positions + // are considered identical. + struct tInterstageIoData { + tInterstageIoData(const TType& memberType, const TType& storageType) : + builtIn(memberType.getQualifier().builtIn), + storage(storageType.getQualifier().storage) { } + + TBuiltInVariable builtIn; + TStorageQualifier storage; + + // ordering for maps + bool operator<(const tInterstageIoData d) const { + return (builtIn != d.builtIn) ? (builtIn < d.builtIn) : (storage < d.storage); + } + }; + + TMap interstageBuiltInIo; // individual builtin interstage IO vars, inxed by builtin type. + + // We have to move array references to structs containing builtin interstage IO to the split variables. + // This is only handled for one level. This stores the index, because we'll need it in the future, since + // unlike normal array references, here the index happens before we discover what it applies to. + TIntermTyped* builtInIoIndex; + TIntermTyped* builtInIoBase; unsigned int nextInLocation; unsigned int nextOutLocation;