HLSL: struct splitting: assignments of hierarchical split types

This commit adds support for copying nested hierarchical types of split
types.  E.g, a struct of a struct containing both user and builtin interstage
IO variables.

When copying split types, if any subtree does NOT contain builtin interstage
IO, we can copy the whole subtree with one assignment, which saves a bunch
of AST verbosity for memberwise copies of that subtree.
This commit is contained in:
steve-lunarg 2016-12-19 15:48:01 -07:00
parent a2e7531057
commit 132d331870
19 changed files with 1113 additions and 234 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 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 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 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 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 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 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

View File

@ -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<PSInput> 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;
}

View File

@ -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 <GS_OUT> ts )
{
GS_OUT o;
o.psIn.pos = float4(1,2,3,4);
o.psIn.tc = float2(5,6);
ts.Append(o);
}

View File

@ -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 <GS_OUT> ts)
{
GS_OUT o;
for (int x=0; x<3; ++x) {
o.pos = i[x].pos;
ts.Append(o);
}
}

View File

@ -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;

View File

@ -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"},

View File

@ -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();

View File

@ -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,12 +770,10 @@ 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) {
// 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; m<member; ++m)
if (!members[m].type->isInterstageIO())
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<TBuiltInVariable> io;
io.reserve(interstageIo.size());
std::vector<tInterstageIoData> io;
io.reserve(interstageBuiltInIo.size());
for (auto ioVar = interstageIo.begin(); ioVar != interstageIo.end(); ++ioVar)
for (auto ioVar = interstageBuiltInIo.begin(); ioVar != interstageBuiltInIo.end(); ++ioVar)
io.push_back(ioVar->first);
// Our canonical order is the TBuiltInVariable value order.
// 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<TVariable*>& 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<TVariable*>& 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<void(TIntermTyped* left, TIntermTyped* right)>
traverse = [&](TIntermTyped* left, TIntermTyped* right) -> void {
const std::function<void(TIntermTyped* left, TIntermTyped* right, TIntermTyped* splitLeft, TIntermTyped* splitRight)>
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.

View File

@ -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<const TTypeList*, TType*> sanitizedTypeMap;
// Structure splitting data:
TMap<TBuiltInVariable, TVariable*> interstageIo; // new structure created for interstage IO from user structs.
TMap<int, TVariable*> splitIoVars; // individual flattened variables
TMap<int, TVariable*> 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<tInterstageIoData, TVariable*> 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;