Merge pull request #632 from steve-lunarg/structure-splitting
HLSL: inter-stage structure splitting.
diff --git a/Test/baseResults/hlsl.basic.geom.out b/Test/baseResults/hlsl.basic.geom.out
index 2c20b43..67477fb 100644
--- a/Test/baseResults/hlsl.basic.geom.out
+++ b/Test/baseResults/hlsl.basic.geom.out
@@ -9,7 +9,7 @@
0:16 Function Parameters:
0:16 'VertexID' (layout(location=0 ) in 3-element array of uint)
0:16 'test' (layout(location=3 ) in 3-element array of uint)
-0:16 'OutputStream' (out structure{temp float myfloat, temp int something})
+0:16 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:? Sequence
0:19 move second child to first child (temp float)
0:19 myfloat: direct index for structure (temp float)
@@ -43,20 +43,19 @@
0:20 0 (const int)
0:22 Sequence
0:22 move second child to first child (temp structure{temp float myfloat, temp int something})
-0:22 'OutputStream' (out structure{temp float myfloat, temp int something})
+0:22 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:22 'Vert' (temp structure{temp float myfloat, temp int something})
0:22 EmitVertex (temp void)
0:23 Sequence
0:23 move second child to first child (temp structure{temp float myfloat, temp int something})
-0:23 'OutputStream' (out structure{temp float myfloat, temp int something})
+0:23 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:23 'Vert' (temp structure{temp float myfloat, temp int something})
0:23 EmitVertex (temp void)
0:24 EndPrimitive (temp void)
0:? Linker Objects
0:? 'VertexID' (layout(location=0 ) in 3-element array of uint)
0:? 'test' (layout(location=3 ) in 3-element array of uint)
-0:? 'myfloat' (layout(location=0 ) out float)
-0:? 'something' (layout(location=1 ) out int)
+0:? 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
Linked geometry stage:
@@ -72,7 +71,7 @@
0:16 Function Parameters:
0:16 'VertexID' (layout(location=0 ) in 3-element array of uint)
0:16 'test' (layout(location=3 ) in 3-element array of uint)
-0:16 'OutputStream' (out structure{temp float myfloat, temp int something})
+0:16 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:? Sequence
0:19 move second child to first child (temp float)
0:19 myfloat: direct index for structure (temp float)
@@ -106,29 +105,28 @@
0:20 0 (const int)
0:22 Sequence
0:22 move second child to first child (temp structure{temp float myfloat, temp int something})
-0:22 'OutputStream' (out structure{temp float myfloat, temp int something})
+0:22 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:22 'Vert' (temp structure{temp float myfloat, temp int something})
0:22 EmitVertex (temp void)
0:23 Sequence
0:23 move second child to first child (temp structure{temp float myfloat, temp int something})
-0:23 'OutputStream' (out structure{temp float myfloat, temp int something})
+0:23 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
0:23 'Vert' (temp structure{temp float myfloat, temp int something})
0:23 EmitVertex (temp void)
0:24 EndPrimitive (temp void)
0:? Linker Objects
0:? 'VertexID' (layout(location=0 ) in 3-element array of uint)
0:? 'test' (layout(location=3 ) in 3-element array of uint)
-0:? 'myfloat' (layout(location=0 ) out float)
-0:? 'something' (layout(location=1 ) out int)
+0:? 'OutputStream' (layout(location=0 ) out structure{temp float myfloat, temp int something})
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 45
+// Id's are bound by 41
Capability Geometry
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Geometry 4 "main" 16 31 38 42 44
+ EntryPoint Geometry 4 "main" 16 31 38
ExecutionMode 4 Triangles
ExecutionMode 4 Invocations 1
ExecutionMode 4 OutputLineStrip
@@ -141,12 +139,9 @@
Name 16 "test"
Name 31 "VertexID"
Name 38 "OutputStream"
- Name 42 "myfloat"
- Name 44 "something"
Decorate 16(test) Location 3
Decorate 31(VertexID) Location 0
- Decorate 42(myfloat) Location 0
- Decorate 44(something) Location 1
+ Decorate 38(OutputStream) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
@@ -167,10 +162,6 @@
35: TypePointer Function 7(int)
37: TypePointer Output 8(PSInput)
38(OutputStream): 37(ptr) Variable Output
- 41: TypePointer Output 6(float)
- 42(myfloat): 41(ptr) Variable Output
- 43: TypePointer Output 7(int)
- 44(something): 43(ptr) Variable Output
4(main): 2 Function None 3
5: Label
10(Vert): 9(ptr) Variable Function
diff --git a/Test/baseResults/hlsl.entry-in.frag.out b/Test/baseResults/hlsl.entry-in.frag.out
index 04e3935..686b355 100755
--- a/Test/baseResults/hlsl.entry-in.frag.out
+++ b/Test/baseResults/hlsl.entry-in.frag.out
@@ -4,84 +4,48 @@
0:? Sequence
0:8 Function Definition: fun(struct-InParam-vf2-vf4-vi21; (temp float)
0:8 Function Parameters:
-0:8 'p' (in structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:8 'p' (in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:? Sequence
0:9 Branch: Return with expression
0:9 add (temp float)
0:9 direct index (temp float)
0:9 v: direct index for structure (temp 2-component vector of float)
-0:9 'p' (in structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:9 'p' (in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:9 Constant:
0:9 0 (const int)
0:9 Constant:
0:9 1 (const int)
0:9 direct index (temp float)
0:9 fragCoord: direct index for structure (temp 4-component vector of float FragCoord)
-0:9 'p' (in structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:9 'p' (in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:9 Constant:
0:9 1 (const int)
0:9 Constant:
0:9 0 (const int)
0:13 Function Definition: PixelShaderFunction(struct-InParam-vf2-vf4-vi21; (temp 4-component vector of float)
0:13 Function Parameters:
-0:13 'i' (in structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:13 'i' (layout(location=0 ) in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:? Sequence
-0:15 Sequence
-0:15 move second child to first child (temp 2-component vector of float)
-0:15 v: direct index for structure (temp 2-component vector of float)
-0:15 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:15 Constant:
-0:15 0 (const int)
-0:? 'v' (layout(location=0 ) in 2-component vector of float)
-0:15 move second child to first child (temp 4-component vector of float)
-0:15 fragCoord: direct index for structure (temp 4-component vector of float)
-0:15 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:15 Constant:
-0:15 1 (const int)
-0:? 'fragCoord' (in 4-component vector of float FragCoord)
-0:15 move second child to first child (temp 2-component vector of int)
-0:15 i2: direct index for structure (temp 2-component vector of int)
-0:15 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:15 Constant:
-0:15 2 (const int)
-0:? 'i2' (layout(location=1 ) in 2-component vector of int)
+0:15 move second child to first child (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
+0:15 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
+0:15 'i' (layout(location=0 ) in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:16 Sequence
0:16 move second child to first child (temp float)
0:16 'ret1' (temp float)
0:16 Function Call: fun(struct-InParam-vf2-vf4-vi21; (temp float)
-0:16 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:16 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:17 Sequence
0:17 move second child to first child (temp float)
0:17 'ret2' (temp float)
0:17 Function Call: fun(struct-InParam-vf2-vf4-vi21; (temp float)
-0:17 Comma (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:17 Sequence
-0:17 move second child to first child (temp 2-component vector of float)
-0:17 v: direct index for structure (temp 2-component vector of float)
-0:17 'aggShadow' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:17 Constant:
-0:17 0 (const int)
-0:? 'v' (layout(location=0 ) in 2-component vector of float)
-0:17 move second child to first child (temp 4-component vector of float)
-0:17 fragCoord: direct index for structure (temp 4-component vector of float)
-0:17 'aggShadow' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:17 Constant:
-0:17 1 (const int)
-0:? 'fragCoord' (in 4-component vector of float FragCoord)
-0:17 move second child to first child (temp 2-component vector of int)
-0:17 i2: direct index for structure (temp 2-component vector of int)
-0:17 'aggShadow' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:17 Constant:
-0:17 2 (const int)
-0:? 'i2' (layout(location=1 ) in 2-component vector of int)
-0:17 'aggShadow' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:17 'i' (layout(location=0 ) in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:19 Sequence
0:19 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:19 vector-scale (temp 4-component vector of float)
0:19 vector-scale (temp 4-component vector of float)
-0:19 fragCoord: direct index for structure (temp 4-component vector of float)
-0:19 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:19 fragCoord: direct index for structure (temp 4-component vector of float FragCoord)
+0:19 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:19 Constant:
0:19 1 (const int)
0:19 'ret1' (temp float)
@@ -89,9 +53,7 @@
0:19 Branch: Return
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
-0:? 'v' (layout(location=0 ) in 2-component vector of float)
-0:? 'fragCoord' (in 4-component vector of float FragCoord)
-0:? 'i2' (layout(location=1 ) in 2-component vector of int)
+0:? 'i' (layout(location=0 ) in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
Linked fragment stage:
@@ -102,84 +64,48 @@
0:? Sequence
0:8 Function Definition: fun(struct-InParam-vf2-vf4-vi21; (temp float)
0:8 Function Parameters:
-0:8 'p' (in structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:8 'p' (in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:? Sequence
0:9 Branch: Return with expression
0:9 add (temp float)
0:9 direct index (temp float)
0:9 v: direct index for structure (temp 2-component vector of float)
-0:9 'p' (in structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:9 'p' (in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:9 Constant:
0:9 0 (const int)
0:9 Constant:
0:9 1 (const int)
0:9 direct index (temp float)
0:9 fragCoord: direct index for structure (temp 4-component vector of float FragCoord)
-0:9 'p' (in structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:9 'p' (in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:9 Constant:
0:9 1 (const int)
0:9 Constant:
0:9 0 (const int)
0:13 Function Definition: PixelShaderFunction(struct-InParam-vf2-vf4-vi21; (temp 4-component vector of float)
0:13 Function Parameters:
-0:13 'i' (in structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:13 'i' (layout(location=0 ) in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:? Sequence
-0:15 Sequence
-0:15 move second child to first child (temp 2-component vector of float)
-0:15 v: direct index for structure (temp 2-component vector of float)
-0:15 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:15 Constant:
-0:15 0 (const int)
-0:? 'v' (layout(location=0 ) in 2-component vector of float)
-0:15 move second child to first child (temp 4-component vector of float)
-0:15 fragCoord: direct index for structure (temp 4-component vector of float)
-0:15 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:15 Constant:
-0:15 1 (const int)
-0:? 'fragCoord' (in 4-component vector of float FragCoord)
-0:15 move second child to first child (temp 2-component vector of int)
-0:15 i2: direct index for structure (temp 2-component vector of int)
-0:15 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:15 Constant:
-0:15 2 (const int)
-0:? 'i2' (layout(location=1 ) in 2-component vector of int)
+0:15 move second child to first child (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
+0:15 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
+0:15 'i' (layout(location=0 ) in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:16 Sequence
0:16 move second child to first child (temp float)
0:16 'ret1' (temp float)
0:16 Function Call: fun(struct-InParam-vf2-vf4-vi21; (temp float)
-0:16 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:16 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:17 Sequence
0:17 move second child to first child (temp float)
0:17 'ret2' (temp float)
0:17 Function Call: fun(struct-InParam-vf2-vf4-vi21; (temp float)
-0:17 Comma (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:17 Sequence
-0:17 move second child to first child (temp 2-component vector of float)
-0:17 v: direct index for structure (temp 2-component vector of float)
-0:17 'aggShadow' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:17 Constant:
-0:17 0 (const int)
-0:? 'v' (layout(location=0 ) in 2-component vector of float)
-0:17 move second child to first child (temp 4-component vector of float)
-0:17 fragCoord: direct index for structure (temp 4-component vector of float)
-0:17 'aggShadow' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:17 Constant:
-0:17 1 (const int)
-0:? 'fragCoord' (in 4-component vector of float FragCoord)
-0:17 move second child to first child (temp 2-component vector of int)
-0:17 i2: direct index for structure (temp 2-component vector of int)
-0:17 'aggShadow' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
-0:17 Constant:
-0:17 2 (const int)
-0:? 'i2' (layout(location=1 ) in 2-component vector of int)
-0:17 'aggShadow' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:17 'i' (layout(location=0 ) in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:19 Sequence
0:19 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:19 vector-scale (temp 4-component vector of float)
0:19 vector-scale (temp 4-component vector of float)
-0:19 fragCoord: direct index for structure (temp 4-component vector of float)
-0:19 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float fragCoord, temp 2-component vector of int i2})
+0:19 fragCoord: direct index for structure (temp 4-component vector of float FragCoord)
+0:19 'local' (temp structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
0:19 Constant:
0:19 1 (const int)
0:19 'ret1' (temp float)
@@ -187,18 +113,16 @@
0:19 Branch: Return
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
-0:? 'v' (layout(location=0 ) in 2-component vector of float)
-0:? 'fragCoord' (in 4-component vector of float FragCoord)
-0:? 'i2' (layout(location=1 ) in 2-component vector of int)
+0:? 'i' (layout(location=0 ) in structure{temp 2-component vector of float v, temp 4-component vector of float FragCoord fragCoord, temp 2-component vector of int i2})
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 71
+// Id's are bound by 52
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "PixelShaderFunction" 32 37 43 63
+ EntryPoint Fragment 4 "PixelShaderFunction" 32 43
ExecutionMode 4 OriginUpperLeft
Name 4 "PixelShaderFunction"
Name 11 "InParam"
@@ -208,19 +132,15 @@
Name 15 "fun(struct-InParam-vf2-vf4-vi21;"
Name 14 "p"
Name 30 "local"
- Name 32 "v"
- Name 37 "fragCoord"
- Name 43 "i2"
- Name 47 "ret1"
- Name 48 "param"
- Name 51 "ret2"
- Name 52 "aggShadow"
- Name 59 "param"
- Name 63 "@entryPointOutput"
- Decorate 32(v) Location 0
- Decorate 37(fragCoord) BuiltIn FragCoord
- Decorate 43(i2) Location 1
- Decorate 63(@entryPointOutput) Location 0
+ Name 32 "i"
+ Name 34 "ret1"
+ Name 35 "param"
+ Name 38 "ret2"
+ Name 39 "param"
+ Name 43 "@entryPointOutput"
+ MemberDecorate 11(InParam) 1 BuiltIn FragCoord
+ Decorate 32(i) Location 0
+ Decorate 43(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
@@ -237,59 +157,35 @@
20: TypePointer Function 6(float)
23: 9(int) Constant 1
24: 18(int) Constant 0
- 31: TypePointer Input 7(fvec2)
- 32(v): 31(ptr) Variable Input
- 34: TypePointer Function 7(fvec2)
- 36: TypePointer Input 8(fvec4)
- 37(fragCoord): 36(ptr) Variable Input
- 39: TypePointer Function 8(fvec4)
- 41: 9(int) Constant 2
- 42: TypePointer Input 10(ivec2)
- 43(i2): 42(ptr) Variable Input
- 45: TypePointer Function 10(ivec2)
- 62: TypePointer Output 8(fvec4)
-63(@entryPointOutput): 62(ptr) Variable Output
+ 31: TypePointer Input 11(InParam)
+ 32(i): 31(ptr) Variable Input
+ 42: TypePointer Output 8(fvec4)
+43(@entryPointOutput): 42(ptr) Variable Output
+ 44: TypePointer Function 8(fvec4)
4(PixelShaderFunction): 2 Function None 3
5: Label
30(local): 12(ptr) Variable Function
- 47(ret1): 20(ptr) Variable Function
- 48(param): 12(ptr) Variable Function
- 51(ret2): 20(ptr) Variable Function
- 52(aggShadow): 12(ptr) Variable Function
- 59(param): 12(ptr) Variable Function
- 33: 7(fvec2) Load 32(v)
- 35: 34(ptr) AccessChain 30(local) 17
- Store 35 33
- 38: 8(fvec4) Load 37(fragCoord)
- 40: 39(ptr) AccessChain 30(local) 23
- Store 40 38
- 44: 10(ivec2) Load 43(i2)
- 46: 45(ptr) AccessChain 30(local) 41
- Store 46 44
- 49: 11(InParam) Load 30(local)
- Store 48(param) 49
- 50: 6(float) FunctionCall 15(fun(struct-InParam-vf2-vf4-vi21;) 48(param)
- Store 47(ret1) 50
- 53: 7(fvec2) Load 32(v)
- 54: 34(ptr) AccessChain 52(aggShadow) 17
- Store 54 53
- 55: 8(fvec4) Load 37(fragCoord)
- 56: 39(ptr) AccessChain 52(aggShadow) 23
- Store 56 55
- 57: 10(ivec2) Load 43(i2)
- 58: 45(ptr) AccessChain 52(aggShadow) 41
- Store 58 57
- 60: 11(InParam) Load 52(aggShadow)
- Store 59(param) 60
- 61: 6(float) FunctionCall 15(fun(struct-InParam-vf2-vf4-vi21;) 59(param)
- Store 51(ret2) 61
- 64: 39(ptr) AccessChain 30(local) 23
- 65: 8(fvec4) Load 64
- 66: 6(float) Load 47(ret1)
- 67: 8(fvec4) VectorTimesScalar 65 66
- 68: 6(float) Load 51(ret2)
- 69: 8(fvec4) VectorTimesScalar 67 68
- Store 63(@entryPointOutput) 69
+ 34(ret1): 20(ptr) Variable Function
+ 35(param): 12(ptr) Variable Function
+ 38(ret2): 20(ptr) Variable Function
+ 39(param): 12(ptr) Variable Function
+ 33: 11(InParam) Load 32(i)
+ Store 30(local) 33
+ 36: 11(InParam) Load 30(local)
+ Store 35(param) 36
+ 37: 6(float) FunctionCall 15(fun(struct-InParam-vf2-vf4-vi21;) 35(param)
+ Store 34(ret1) 37
+ 40: 11(InParam) Load 32(i)
+ Store 39(param) 40
+ 41: 6(float) FunctionCall 15(fun(struct-InParam-vf2-vf4-vi21;) 39(param)
+ Store 38(ret2) 41
+ 45: 44(ptr) AccessChain 30(local) 23
+ 46: 8(fvec4) Load 45
+ 47: 6(float) Load 34(ret1)
+ 48: 8(fvec4) VectorTimesScalar 46 47
+ 49: 6(float) Load 38(ret2)
+ 50: 8(fvec4) VectorTimesScalar 48 49
+ Store 43(@entryPointOutput) 50
Return
FunctionEnd
15(fun(struct-InParam-vf2-vf4-vi21;): 6(float) Function None 13
diff --git a/Test/baseResults/hlsl.gather.basic.dx10.vert.out b/Test/baseResults/hlsl.gather.basic.dx10.vert.out
index a893675..3226769 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 @@
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 @@
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 @@
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 @@
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 @@
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 c1c90f4..77316b1 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 @@
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 @@
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 @@
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 a86f0ae..7441d49 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 @@
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 @@
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 @@
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 @@
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 @@
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 f6d37c3..d7ea386 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 @@
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 @@
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 @@
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 @@
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 @@
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 04d0870..35a9ede 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 @@
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 @@
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 @@
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 @@
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 @@
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.frag.out b/Test/baseResults/hlsl.struct.frag.out
index c14018e..e2b2f72 100755
--- a/Test/baseResults/hlsl.struct.frag.out
+++ b/Test/baseResults/hlsl.struct.frag.out
@@ -9,7 +9,7 @@
0:34 Function Definition: PixelShaderFunction(vf4;struct-IN_S-vf4-b1-vf1-vf2-b1-b1-b1-vf41; (temp 4-component vector of float)
0:34 Function Parameters:
0:34 'input' (layout(location=0 ) in 4-component vector of float)
-0:34 's' (in structure{temp 4-component vector of float a, temp bool b, temp 1-component vector of float c, temp 2-component vector of float d, temp bool ff1, temp bool ff2, temp bool ff3, temp 4-component vector of float ff4})
+0:34 's' (layout(location=1 ) in structure{smooth temp 4-component vector of float a, flat temp bool b, centroid noperspective temp 1-component vector of float c, centroid sample temp 2-component vector of float d, temp bool Face ff1, layout(offset=4 ) temp bool ff2, layout(binding=0 offset=4 ) temp bool ff3, layout(binding=0 offset=4 ) temp 4-component vector of float ff4})
0:? Sequence
0:39 Compare Equal (temp bool)
0:39 's3' (temp structure{temp 3-component vector of bool b3})
@@ -19,7 +19,10 @@
0:40 's2' (global structure{temp 4-component vector of float i})
0:40 Constant:
0:40 0 (const int)
-0:? 'ff4' (layout(location=7 binding=0 offset=4 ) in 4-component vector of float)
+0:40 ff4: direct index for structure (layout(binding=0 offset=4 ) temp 4-component vector of float)
+0:40 's' (layout(location=1 ) in structure{smooth temp 4-component vector of float a, flat temp bool b, centroid noperspective temp 1-component vector of float c, centroid sample temp 2-component vector of float d, temp bool Face ff1, layout(offset=4 ) temp bool ff2, layout(binding=0 offset=4 ) temp bool ff3, layout(binding=0 offset=4 ) temp 4-component vector of float ff4})
+0:40 Constant:
+0:40 7 (const int)
0:42 Sequence
0:42 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
@@ -28,14 +31,7 @@
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:? 'input' (layout(location=0 ) in 4-component vector of float)
-0:? 'a' (layout(location=1 ) smooth in 4-component vector of float)
-0:? 'b' (layout(location=2 ) flat in bool)
-0:? 'c' (layout(location=3 ) centroid noperspective in 1-component vector of float)
-0:? 'd' (layout(location=4 ) centroid sample in 2-component vector of float)
-0:? 'ff1' (in bool Face)
-0:? 'ff2' (layout(location=5 offset=4 ) in bool)
-0:? 'ff3' (layout(location=6 binding=0 offset=4 ) in bool)
-0:? 'ff4' (layout(location=7 binding=0 offset=4 ) in 4-component vector of float)
+0:? 's' (layout(location=1 ) in structure{smooth temp 4-component vector of float a, flat temp bool b, centroid noperspective temp 1-component vector of float c, centroid sample temp 2-component vector of float d, temp bool Face ff1, layout(offset=4 ) temp bool ff2, layout(binding=0 offset=4 ) temp bool ff3, layout(binding=0 offset=4 ) temp 4-component vector of float ff4})
0:? 's2' (global structure{temp 4-component vector of float i})
0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform structure{temp bool b, temp bool c, temp 4-component vector of float a, temp 4-component vector of float d} s1, layout(binding=5 offset=1620 ) uniform float ff5, layout(binding=8 offset=1636 ) uniform float ff6})
@@ -49,7 +45,7 @@
0:34 Function Definition: PixelShaderFunction(vf4;struct-IN_S-vf4-b1-vf1-vf2-b1-b1-b1-vf41; (temp 4-component vector of float)
0:34 Function Parameters:
0:34 'input' (layout(location=0 ) in 4-component vector of float)
-0:34 's' (in structure{temp 4-component vector of float a, temp bool b, temp 1-component vector of float c, temp 2-component vector of float d, temp bool ff1, temp bool ff2, temp bool ff3, temp 4-component vector of float ff4})
+0:34 's' (layout(location=1 ) in structure{smooth temp 4-component vector of float a, flat temp bool b, centroid noperspective temp 1-component vector of float c, centroid sample temp 2-component vector of float d, temp bool Face ff1, layout(offset=4 ) temp bool ff2, layout(binding=0 offset=4 ) temp bool ff3, layout(binding=0 offset=4 ) temp 4-component vector of float ff4})
0:? Sequence
0:39 Compare Equal (temp bool)
0:39 's3' (temp structure{temp 3-component vector of bool b3})
@@ -59,7 +55,10 @@
0:40 's2' (global structure{temp 4-component vector of float i})
0:40 Constant:
0:40 0 (const int)
-0:? 'ff4' (layout(location=7 binding=0 offset=4 ) in 4-component vector of float)
+0:40 ff4: direct index for structure (layout(binding=0 offset=4 ) temp 4-component vector of float)
+0:40 's' (layout(location=1 ) in structure{smooth temp 4-component vector of float a, flat temp bool b, centroid noperspective temp 1-component vector of float c, centroid sample temp 2-component vector of float d, temp bool Face ff1, layout(offset=4 ) temp bool ff2, layout(binding=0 offset=4 ) temp bool ff3, layout(binding=0 offset=4 ) temp 4-component vector of float ff4})
+0:40 Constant:
+0:40 7 (const int)
0:42 Sequence
0:42 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
@@ -68,25 +67,18 @@
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:? 'input' (layout(location=0 ) in 4-component vector of float)
-0:? 'a' (layout(location=1 ) smooth in 4-component vector of float)
-0:? 'b' (layout(location=2 ) flat in bool)
-0:? 'c' (layout(location=3 ) centroid noperspective in 1-component vector of float)
-0:? 'd' (layout(location=4 ) centroid sample in 2-component vector of float)
-0:? 'ff1' (in bool Face)
-0:? 'ff2' (layout(location=5 offset=4 ) in bool)
-0:? 'ff3' (layout(location=6 binding=0 offset=4 ) in bool)
-0:? 'ff4' (layout(location=7 binding=0 offset=4 ) in 4-component vector of float)
+0:? 's' (layout(location=1 ) in structure{smooth temp 4-component vector of float a, flat temp bool b, centroid noperspective temp 1-component vector of float c, centroid sample temp 2-component vector of float d, temp bool Face ff1, layout(offset=4 ) temp bool ff2, layout(binding=0 offset=4 ) temp bool ff3, layout(binding=0 offset=4 ) temp 4-component vector of float ff4})
0:? 's2' (global structure{temp 4-component vector of float i})
0:? 'anon@0' (layout(row_major std140 ) uniform block{layout(offset=0 ) uniform structure{temp bool b, temp bool c, temp 4-component vector of float a, temp 4-component vector of float d} s1, layout(binding=5 offset=1620 ) uniform float ff5, layout(binding=8 offset=1636 ) uniform float ff6})
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 50
+// Id's are bound by 44
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint Fragment 4 "PixelShaderFunction" 25 30 31 34 36 38 41 42 43 44
+ EntryPoint Fragment 4 "PixelShaderFunction" 27 35 36
ExecutionMode 4 OriginUpperLeft
Name 4 "PixelShaderFunction"
Name 8 "FS"
@@ -95,54 +87,41 @@
Name 19 ""
MemberName 19 0 "i"
Name 21 "s2"
- Name 25 "ff4"
- Name 30 "@entryPointOutput"
- Name 31 "input"
- Name 34 "a"
- Name 36 "b"
- Name 38 "c"
- Name 41 "d"
- Name 42 "ff1"
- Name 43 "ff2"
- Name 44 "ff3"
- Name 46 "myS"
- MemberName 46(myS) 0 "b"
- MemberName 46(myS) 1 "c"
- MemberName 46(myS) 2 "a"
- MemberName 46(myS) 3 "d"
- Name 47 "$Global"
- MemberName 47($Global) 0 "s1"
- MemberName 47($Global) 1 "ff5"
- MemberName 47($Global) 2 "ff6"
- Name 49 ""
- Decorate 25(ff4) Offset 4
- Decorate 25(ff4) Location 7
- Decorate 25(ff4) Binding 0
- Decorate 30(@entryPointOutput) Location 0
- Decorate 31(input) Location 0
- Decorate 34(a) Location 1
- Decorate 36(b) Flat
- Decorate 36(b) Location 2
- Decorate 38(c) NoPerspective
- Decorate 38(c) Centroid
- Decorate 38(c) Location 3
- Decorate 41(d) Centroid
- Decorate 41(d) Location 4
- Decorate 42(ff1) BuiltIn FrontFacing
- Decorate 43(ff2) Offset 4
- Decorate 43(ff2) Location 5
- Decorate 44(ff3) Offset 4
- Decorate 44(ff3) Location 6
- Decorate 44(ff3) Binding 0
- MemberDecorate 46(myS) 0 Offset 0
- MemberDecorate 46(myS) 1 Offset 4
- MemberDecorate 46(myS) 2 Offset 16
- MemberDecorate 46(myS) 3 Offset 32
- MemberDecorate 47($Global) 0 Offset 0
- MemberDecorate 47($Global) 1 Offset 1620
- MemberDecorate 47($Global) 2 Offset 1636
- Decorate 47($Global) Block
- Decorate 49 DescriptorSet 0
+ Name 25 "IN_S"
+ MemberName 25(IN_S) 0 "a"
+ MemberName 25(IN_S) 1 "b"
+ MemberName 25(IN_S) 2 "c"
+ MemberName 25(IN_S) 3 "d"
+ MemberName 25(IN_S) 4 "ff1"
+ MemberName 25(IN_S) 5 "ff2"
+ MemberName 25(IN_S) 6 "ff3"
+ MemberName 25(IN_S) 7 "ff4"
+ Name 27 "s"
+ Name 35 "@entryPointOutput"
+ Name 36 "input"
+ Name 40 "myS"
+ MemberName 40(myS) 0 "b"
+ MemberName 40(myS) 1 "c"
+ MemberName 40(myS) 2 "a"
+ MemberName 40(myS) 3 "d"
+ Name 41 "$Global"
+ MemberName 41($Global) 0 "s1"
+ MemberName 41($Global) 1 "ff5"
+ MemberName 41($Global) 2 "ff6"
+ Name 43 ""
+ MemberDecorate 25(IN_S) 4 BuiltIn FrontFacing
+ Decorate 27(s) Location 1
+ Decorate 35(@entryPointOutput) Location 0
+ Decorate 36(input) Location 0
+ MemberDecorate 40(myS) 0 Offset 0
+ MemberDecorate 40(myS) 1 Offset 4
+ MemberDecorate 40(myS) 2 Offset 16
+ MemberDecorate 40(myS) 3 Offset 32
+ MemberDecorate 41($Global) 0 Offset 0
+ MemberDecorate 41($Global) 1 Offset 1620
+ MemberDecorate 41($Global) 2 Offset 1636
+ Decorate 41($Global) Block
+ Decorate 43 DescriptorSet 0
2: TypeVoid
3: TypeFunction 2
6: TypeBool
@@ -156,28 +135,21 @@
21(s2): 20(ptr) Variable Private
22: TypeInt 32 1
23: 22(int) Constant 0
- 24: TypePointer Input 18(fvec4)
- 25(ff4): 24(ptr) Variable Input
- 27: TypePointer Private 18(fvec4)
- 29: TypePointer Output 18(fvec4)
-30(@entryPointOutput): 29(ptr) Variable Output
- 31(input): 24(ptr) Variable Input
- 34(a): 24(ptr) Variable Input
- 35: TypePointer Input 6(bool)
- 36(b): 35(ptr) Variable Input
- 37: TypePointer Input 17(float)
- 38(c): 37(ptr) Variable Input
- 39: TypeVector 17(float) 2
- 40: TypePointer Input 39(fvec2)
- 41(d): 40(ptr) Variable Input
- 42(ff1): 35(ptr) Variable Input
- 43(ff2): 35(ptr) Variable Input
- 44(ff3): 35(ptr) Variable Input
- 45: TypeInt 32 0
- 46(myS): TypeStruct 45(int) 45(int) 18(fvec4) 18(fvec4)
- 47($Global): TypeStruct 46(myS) 17(float) 17(float)
- 48: TypePointer Uniform 47($Global)
- 49: 48(ptr) Variable Uniform
+ 24: TypeVector 17(float) 2
+ 25(IN_S): TypeStruct 18(fvec4) 6(bool) 17(float) 24(fvec2) 6(bool) 6(bool) 6(bool) 18(fvec4)
+ 26: TypePointer Input 25(IN_S)
+ 27(s): 26(ptr) Variable Input
+ 28: 22(int) Constant 7
+ 29: TypePointer Input 18(fvec4)
+ 32: TypePointer Private 18(fvec4)
+ 34: TypePointer Output 18(fvec4)
+35(@entryPointOutput): 34(ptr) Variable Output
+ 36(input): 29(ptr) Variable Input
+ 39: TypeInt 32 0
+ 40(myS): TypeStruct 39(int) 39(int) 18(fvec4) 18(fvec4)
+ 41($Global): TypeStruct 40(myS) 17(float) 17(float)
+ 42: TypePointer Uniform 41($Global)
+ 43: 42(ptr) Variable Uniform
4(PixelShaderFunction): 2 Function None 3
5: Label
10(s3): 9(ptr) Variable Function
@@ -187,10 +159,11 @@
14: 7(bvec3) CompositeExtract 12 0
15: 7(bvec3) LogicalEqual 13 14
16: 6(bool) All 15
- 26: 18(fvec4) Load 25(ff4)
- 28: 27(ptr) AccessChain 21(s2) 23
- Store 28 26
- 32: 18(fvec4) Load 31(input)
- Store 30(@entryPointOutput) 32
+ 30: 29(ptr) AccessChain 27(s) 28
+ 31: 18(fvec4) Load 30
+ 33: 32(ptr) AccessChain 21(s2) 23
+ Store 33 31
+ 37: 18(fvec4) Load 36(input)
+ Store 35(@entryPointOutput) 37
Return
FunctionEnd
diff --git a/Test/baseResults/hlsl.struct.split-1.vert.out b/Test/baseResults/hlsl.struct.split-1.vert.out
new file mode 100644
index 0000000..62431ac
--- /dev/null
+++ b/Test/baseResults/hlsl.struct.split-1.vert.out
@@ -0,0 +1,209 @@
+hlsl.struct.split-1.vert
+Shader version: 450
+0:? Sequence
+0:17 Function Definition: main(struct-VS_INPUT-i1-vf4-i11;vf4; (temp structure{temp int x0_out, temp 4-component vector of float Position Pos_out, temp int x1_out})
+0:17 Function Parameters:
+0:17 'vsin' (in structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:17 'Pos_loose' (in 4-component vector of float Position)
+0:? Sequence
+0:20 move second child to first child (temp int)
+0:20 x0_out: direct index for structure (temp int)
+0:20 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:20 Constant:
+0:20 0 (const int)
+0:? 'x0_in' (layout(location=0 ) in int)
+0:21 move second child to first child (temp 4-component vector of float)
+0:21 Pos_out: direct index for structure (temp 4-component vector of float)
+0:21 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:21 Constant:
+0:21 1 (const int)
+0:21 add (temp 4-component vector of float)
+0:? 'Pos_in' (in 4-component vector of float Position)
+0:21 'Pos_loose' (in 4-component vector of float Position)
+0:22 move second child to first child (temp int)
+0:22 x1_out: direct index for structure (temp int)
+0:22 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:22 Constant:
+0:22 2 (const int)
+0:? 'x1_in' (layout(location=1 ) in int)
+0:24 Sequence
+0:24 Sequence
+0:24 move second child to first child (temp int)
+0:24 x0_out: direct index for structure (temp int)
+0:24 '@entryPointOutput' (layout(location=0 ) out structure{temp int x0_out, temp int x1_out})
+0:24 Constant:
+0:24 0 (const int)
+0:24 x0_out: direct index for structure (temp int)
+0:24 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:24 Constant:
+0:24 0 (const int)
+0:24 move second child to first child (temp 4-component vector of float)
+0:? 'Pos_out' (out 4-component vector of float Position)
+0:24 Pos_out: direct index for structure (temp 4-component vector of float)
+0:24 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:24 Constant:
+0:24 1 (const int)
+0:24 move second child to first child (temp int)
+0:24 x1_out: direct index for structure (temp int)
+0:24 '@entryPointOutput' (layout(location=0 ) out structure{temp int x0_out, temp int x1_out})
+0:24 Constant:
+0:24 1 (const int)
+0:24 x1_out: direct index for structure (temp int)
+0:24 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:24 Constant:
+0:24 2 (const int)
+0:24 Branch: Return
+0:? Linker Objects
+0:? '@entryPointOutput' (layout(location=0 ) out structure{temp int x0_out, temp int x1_out})
+0:? 'x0_in' (layout(location=0 ) in int)
+0:? 'Pos_in' (in 4-component vector of float Position)
+0:? 'x1_in' (layout(location=1 ) in int)
+0:? 'Pos_loose' (in 4-component vector of float Position)
+0:? 'Pos_out' (out 4-component vector of float Position)
+
+
+Linked vertex stage:
+
+
+Shader version: 450
+0:? Sequence
+0:17 Function Definition: main(struct-VS_INPUT-i1-vf4-i11;vf4; (temp structure{temp int x0_out, temp 4-component vector of float Position Pos_out, temp int x1_out})
+0:17 Function Parameters:
+0:17 'vsin' (in structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:17 'Pos_loose' (in 4-component vector of float Position)
+0:? Sequence
+0:20 move second child to first child (temp int)
+0:20 x0_out: direct index for structure (temp int)
+0:20 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:20 Constant:
+0:20 0 (const int)
+0:? 'x0_in' (layout(location=0 ) in int)
+0:21 move second child to first child (temp 4-component vector of float)
+0:21 Pos_out: direct index for structure (temp 4-component vector of float)
+0:21 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:21 Constant:
+0:21 1 (const int)
+0:21 add (temp 4-component vector of float)
+0:? 'Pos_in' (in 4-component vector of float Position)
+0:21 'Pos_loose' (in 4-component vector of float Position)
+0:22 move second child to first child (temp int)
+0:22 x1_out: direct index for structure (temp int)
+0:22 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:22 Constant:
+0:22 2 (const int)
+0:? 'x1_in' (layout(location=1 ) in int)
+0:24 Sequence
+0:24 Sequence
+0:24 move second child to first child (temp int)
+0:24 x0_out: direct index for structure (temp int)
+0:24 '@entryPointOutput' (layout(location=0 ) out structure{temp int x0_out, temp int x1_out})
+0:24 Constant:
+0:24 0 (const int)
+0:24 x0_out: direct index for structure (temp int)
+0:24 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:24 Constant:
+0:24 0 (const int)
+0:24 move second child to first child (temp 4-component vector of float)
+0:? 'Pos_out' (out 4-component vector of float Position)
+0:24 Pos_out: direct index for structure (temp 4-component vector of float)
+0:24 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:24 Constant:
+0:24 1 (const int)
+0:24 move second child to first child (temp int)
+0:24 x1_out: direct index for structure (temp int)
+0:24 '@entryPointOutput' (layout(location=0 ) out structure{temp int x0_out, temp int x1_out})
+0:24 Constant:
+0:24 1 (const int)
+0:24 x1_out: direct index for structure (temp int)
+0:24 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:24 Constant:
+0:24 2 (const int)
+0:24 Branch: Return
+0:? Linker Objects
+0:? '@entryPointOutput' (layout(location=0 ) out structure{temp int x0_out, temp int x1_out})
+0:? 'x0_in' (layout(location=0 ) in int)
+0:? 'Pos_in' (in 4-component vector of float Position)
+0:? 'x1_in' (layout(location=1 ) in int)
+0:? 'Pos_loose' (in 4-component vector of float Position)
+0:? 'Pos_out' (out 4-component vector of float Position)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 46
+
+ Capability Shader
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Vertex 4 "main" 14 20 22 28 33 39
+ Name 4 "main"
+ Name 9 "VS_OUTPUT"
+ MemberName 9(VS_OUTPUT) 0 "x0_out"
+ MemberName 9(VS_OUTPUT) 1 "Pos_out"
+ MemberName 9(VS_OUTPUT) 2 "x1_out"
+ Name 11 "vsout"
+ Name 14 "x0_in"
+ Name 20 "Pos_in"
+ Name 22 "Pos_loose"
+ Name 28 "x1_in"
+ Name 31 "VS_OUTPUT"
+ MemberName 31(VS_OUTPUT) 0 "x0_out"
+ MemberName 31(VS_OUTPUT) 1 "x1_out"
+ Name 33 "@entryPointOutput"
+ Name 39 "Pos_out"
+ Decorate 14(x0_in) Location 0
+ Decorate 20(Pos_in) BuiltIn Position
+ Decorate 22(Pos_loose) BuiltIn Position
+ Decorate 28(x1_in) Location 1
+ Decorate 33(@entryPointOutput) Location 0
+ Decorate 39(Pos_out) BuiltIn Position
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 1
+ 7: TypeFloat 32
+ 8: TypeVector 7(float) 4
+ 9(VS_OUTPUT): TypeStruct 6(int) 8(fvec4) 6(int)
+ 10: TypePointer Function 9(VS_OUTPUT)
+ 12: 6(int) Constant 0
+ 13: TypePointer Input 6(int)
+ 14(x0_in): 13(ptr) Variable Input
+ 16: TypePointer Function 6(int)
+ 18: 6(int) Constant 1
+ 19: TypePointer Input 8(fvec4)
+ 20(Pos_in): 19(ptr) Variable Input
+ 22(Pos_loose): 19(ptr) Variable Input
+ 25: TypePointer Function 8(fvec4)
+ 27: 6(int) Constant 2
+ 28(x1_in): 13(ptr) Variable Input
+ 31(VS_OUTPUT): TypeStruct 6(int) 6(int)
+ 32: TypePointer Output 31(VS_OUTPUT)
+33(@entryPointOutput): 32(ptr) Variable Output
+ 36: TypePointer Output 6(int)
+ 38: TypePointer Output 8(fvec4)
+ 39(Pos_out): 38(ptr) Variable Output
+ 4(main): 2 Function None 3
+ 5: Label
+ 11(vsout): 10(ptr) Variable Function
+ 15: 6(int) Load 14(x0_in)
+ 17: 16(ptr) AccessChain 11(vsout) 12
+ Store 17 15
+ 21: 8(fvec4) Load 20(Pos_in)
+ 23: 8(fvec4) Load 22(Pos_loose)
+ 24: 8(fvec4) FAdd 21 23
+ 26: 25(ptr) AccessChain 11(vsout) 18
+ Store 26 24
+ 29: 6(int) Load 28(x1_in)
+ 30: 16(ptr) AccessChain 11(vsout) 27
+ Store 30 29
+ 34: 16(ptr) AccessChain 11(vsout) 12
+ 35: 6(int) Load 34
+ 37: 36(ptr) AccessChain 33(@entryPointOutput) 12
+ Store 37 35
+ 40: 25(ptr) AccessChain 11(vsout) 18
+ 41: 8(fvec4) Load 40
+ Store 39(Pos_out) 41
+ 42: 16(ptr) AccessChain 11(vsout) 27
+ 43: 6(int) Load 42
+ 44: 36(ptr) AccessChain 33(@entryPointOutput) 18
+ Store 44 43
+ Return
+ FunctionEnd
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 0000000..e8921b6
--- /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.call.vert.out b/Test/baseResults/hlsl.struct.split.call.vert.out
new file mode 100644
index 0000000..d7a19e4
--- /dev/null
+++ b/Test/baseResults/hlsl.struct.split.call.vert.out
@@ -0,0 +1,317 @@
+hlsl.struct.split.call.vert
+Shader version: 450
+0:? Sequence
+0:17 Function Definition: Fn1(struct-VS_INPUT-i1-vf4-i11;struct-VS_OUTPUT-i1-vf4-i11; (temp void)
+0:17 Function Parameters:
+0:17 'fn1_in' (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:17 'fn1_out' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:? Sequence
+0:18 add (temp 4-component vector of float)
+0:18 Pos_in: direct index for structure (temp 4-component vector of float)
+0:18 'fn1_in' (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:18 Constant:
+0:18 1 (const int)
+0:18 Pos_out: direct index for structure (temp 4-component vector of float)
+0:18 'fn1_out' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:18 Constant:
+0:18 1 (const int)
+0:22 Function Definition: main(struct-VS_INPUT-i1-vf4-i11; (temp structure{temp int x0_out, temp 4-component vector of float Position Pos_out, temp int x1_out})
+0:22 Function Parameters:
+0:22 'vsin' (in structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:? Sequence
+0:25 move second child to first child (temp int)
+0:25 x0_out: direct index for structure (temp int)
+0:25 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:25 Constant:
+0:25 0 (const int)
+0:? 'x0_in' (layout(location=0 ) in int)
+0:26 move second child to first child (temp 4-component vector of float)
+0:26 Pos_out: direct index for structure (temp 4-component vector of float)
+0:26 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:26 Constant:
+0:26 1 (const int)
+0:? 'Pos_in' (in 4-component vector of float Position)
+0:27 move second child to first child (temp int)
+0:27 x1_out: direct index for structure (temp int)
+0:27 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:27 Constant:
+0:27 2 (const int)
+0:? 'x1_in' (layout(location=1 ) in int)
+0:29 Function Call: Fn1(struct-VS_INPUT-i1-vf4-i11;struct-VS_OUTPUT-i1-vf4-i11; (temp void)
+0:29 Comma (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:29 Sequence
+0:29 move second child to first child (temp int)
+0:29 x0_in: direct index for structure (temp int)
+0:29 'aggShadow' (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:29 Constant:
+0:29 0 (const int)
+0:? 'x0_in' (layout(location=0 ) in int)
+0:29 move second child to first child (temp 4-component vector of float)
+0:29 Pos_in: direct index for structure (temp 4-component vector of float)
+0:29 'aggShadow' (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:29 Constant:
+0:29 1 (const int)
+0:? 'Pos_in' (in 4-component vector of float Position)
+0:29 move second child to first child (temp int)
+0:29 x1_in: direct index for structure (temp int)
+0:29 'aggShadow' (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:29 Constant:
+0:29 2 (const int)
+0:? 'x1_in' (layout(location=1 ) in int)
+0:29 'aggShadow' (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:29 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:31 Sequence
+0:31 Sequence
+0:31 move second child to first child (temp int)
+0:31 x0_out: direct index for structure (temp int)
+0:31 '@entryPointOutput' (layout(location=0 ) out structure{temp int x0_out, temp int x1_out})
+0:31 Constant:
+0:31 0 (const int)
+0:31 x0_out: direct index for structure (temp int)
+0:31 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:31 Constant:
+0:31 0 (const int)
+0:31 move second child to first child (temp 4-component vector of float)
+0:? 'Pos_out' (out 4-component vector of float Position)
+0:31 Pos_out: direct index for structure (temp 4-component vector of float)
+0:31 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:31 Constant:
+0:31 1 (const int)
+0:31 move second child to first child (temp int)
+0:31 x1_out: direct index for structure (temp int)
+0:31 '@entryPointOutput' (layout(location=0 ) out structure{temp int x0_out, temp int x1_out})
+0:31 Constant:
+0:31 1 (const int)
+0:31 x1_out: direct index for structure (temp int)
+0:31 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:31 Constant:
+0:31 2 (const int)
+0:31 Branch: Return
+0:? Linker Objects
+0:? '@entryPointOutput' (layout(location=0 ) out structure{temp int x0_out, temp int x1_out})
+0:? 'x0_in' (layout(location=0 ) in int)
+0:? 'Pos_in' (in 4-component vector of float Position)
+0:? 'x1_in' (layout(location=1 ) in int)
+0:? 'Pos_out' (out 4-component vector of float Position)
+
+
+Linked vertex stage:
+
+
+Shader version: 450
+0:? Sequence
+0:17 Function Definition: Fn1(struct-VS_INPUT-i1-vf4-i11;struct-VS_OUTPUT-i1-vf4-i11; (temp void)
+0:17 Function Parameters:
+0:17 'fn1_in' (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:17 'fn1_out' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:? Sequence
+0:18 add (temp 4-component vector of float)
+0:18 Pos_in: direct index for structure (temp 4-component vector of float)
+0:18 'fn1_in' (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:18 Constant:
+0:18 1 (const int)
+0:18 Pos_out: direct index for structure (temp 4-component vector of float)
+0:18 'fn1_out' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:18 Constant:
+0:18 1 (const int)
+0:22 Function Definition: main(struct-VS_INPUT-i1-vf4-i11; (temp structure{temp int x0_out, temp 4-component vector of float Position Pos_out, temp int x1_out})
+0:22 Function Parameters:
+0:22 'vsin' (in structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:? Sequence
+0:25 move second child to first child (temp int)
+0:25 x0_out: direct index for structure (temp int)
+0:25 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:25 Constant:
+0:25 0 (const int)
+0:? 'x0_in' (layout(location=0 ) in int)
+0:26 move second child to first child (temp 4-component vector of float)
+0:26 Pos_out: direct index for structure (temp 4-component vector of float)
+0:26 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:26 Constant:
+0:26 1 (const int)
+0:? 'Pos_in' (in 4-component vector of float Position)
+0:27 move second child to first child (temp int)
+0:27 x1_out: direct index for structure (temp int)
+0:27 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:27 Constant:
+0:27 2 (const int)
+0:? 'x1_in' (layout(location=1 ) in int)
+0:29 Function Call: Fn1(struct-VS_INPUT-i1-vf4-i11;struct-VS_OUTPUT-i1-vf4-i11; (temp void)
+0:29 Comma (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:29 Sequence
+0:29 move second child to first child (temp int)
+0:29 x0_in: direct index for structure (temp int)
+0:29 'aggShadow' (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:29 Constant:
+0:29 0 (const int)
+0:? 'x0_in' (layout(location=0 ) in int)
+0:29 move second child to first child (temp 4-component vector of float)
+0:29 Pos_in: direct index for structure (temp 4-component vector of float)
+0:29 'aggShadow' (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:29 Constant:
+0:29 1 (const int)
+0:? 'Pos_in' (in 4-component vector of float Position)
+0:29 move second child to first child (temp int)
+0:29 x1_in: direct index for structure (temp int)
+0:29 'aggShadow' (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:29 Constant:
+0:29 2 (const int)
+0:? 'x1_in' (layout(location=1 ) in int)
+0:29 'aggShadow' (temp structure{temp int x0_in, temp 4-component vector of float Pos_in, temp int x1_in})
+0:29 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:31 Sequence
+0:31 Sequence
+0:31 move second child to first child (temp int)
+0:31 x0_out: direct index for structure (temp int)
+0:31 '@entryPointOutput' (layout(location=0 ) out structure{temp int x0_out, temp int x1_out})
+0:31 Constant:
+0:31 0 (const int)
+0:31 x0_out: direct index for structure (temp int)
+0:31 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:31 Constant:
+0:31 0 (const int)
+0:31 move second child to first child (temp 4-component vector of float)
+0:? 'Pos_out' (out 4-component vector of float Position)
+0:31 Pos_out: direct index for structure (temp 4-component vector of float)
+0:31 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:31 Constant:
+0:31 1 (const int)
+0:31 move second child to first child (temp int)
+0:31 x1_out: direct index for structure (temp int)
+0:31 '@entryPointOutput' (layout(location=0 ) out structure{temp int x0_out, temp int x1_out})
+0:31 Constant:
+0:31 1 (const int)
+0:31 x1_out: direct index for structure (temp int)
+0:31 'vsout' (temp structure{temp int x0_out, temp 4-component vector of float Pos_out, temp int x1_out})
+0:31 Constant:
+0:31 2 (const int)
+0:31 Branch: Return
+0:? Linker Objects
+0:? '@entryPointOutput' (layout(location=0 ) out structure{temp int x0_out, temp int x1_out})
+0:? 'x0_in' (layout(location=0 ) in int)
+0:? 'Pos_in' (in 4-component vector of float Position)
+0:? 'x1_in' (layout(location=1 ) in int)
+0:? 'Pos_out' (out 4-component vector of float Position)
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 69
+
+ Capability Shader
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Vertex 4 "main" 28 33 37 56 62
+ Name 4 "main"
+ Name 9 "VS_INPUT"
+ MemberName 9(VS_INPUT) 0 "x0_in"
+ MemberName 9(VS_INPUT) 1 "Pos_in"
+ MemberName 9(VS_INPUT) 2 "x1_in"
+ Name 11 "VS_OUTPUT"
+ MemberName 11(VS_OUTPUT) 0 "x0_out"
+ MemberName 11(VS_OUTPUT) 1 "Pos_out"
+ MemberName 11(VS_OUTPUT) 2 "x1_out"
+ Name 16 "Fn1(struct-VS_INPUT-i1-vf4-i11;struct-VS_OUTPUT-i1-vf4-i11;"
+ Name 14 "fn1_in"
+ Name 15 "fn1_out"
+ Name 25 "vsout"
+ Name 28 "x0_in"
+ Name 33 "Pos_in"
+ Name 37 "x1_in"
+ Name 40 "VS_INPUT"
+ MemberName 40(VS_INPUT) 0 "x0_in"
+ MemberName 40(VS_INPUT) 1 "Pos_in"
+ MemberName 40(VS_INPUT) 2 "x1_in"
+ Name 42 "aggShadow"
+ Name 49 "param"
+ Name 51 "param"
+ Name 54 "VS_OUTPUT"
+ MemberName 54(VS_OUTPUT) 0 "x0_out"
+ MemberName 54(VS_OUTPUT) 1 "x1_out"
+ Name 56 "@entryPointOutput"
+ Name 62 "Pos_out"
+ Decorate 28(x0_in) Location 0
+ Decorate 33(Pos_in) BuiltIn Position
+ Decorate 37(x1_in) Location 1
+ Decorate 56(@entryPointOutput) Location 0
+ Decorate 62(Pos_out) BuiltIn Position
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 1
+ 7: TypeFloat 32
+ 8: TypeVector 7(float) 4
+ 9(VS_INPUT): TypeStruct 6(int) 8(fvec4) 6(int)
+ 10: TypePointer Function 9(VS_INPUT)
+ 11(VS_OUTPUT): TypeStruct 6(int) 8(fvec4) 6(int)
+ 12: TypePointer Function 11(VS_OUTPUT)
+ 13: TypeFunction 2 10(ptr) 12(ptr)
+ 18: 6(int) Constant 1
+ 19: TypePointer Function 8(fvec4)
+ 26: 6(int) Constant 0
+ 27: TypePointer Input 6(int)
+ 28(x0_in): 27(ptr) Variable Input
+ 30: TypePointer Function 6(int)
+ 32: TypePointer Input 8(fvec4)
+ 33(Pos_in): 32(ptr) Variable Input
+ 36: 6(int) Constant 2
+ 37(x1_in): 27(ptr) Variable Input
+ 40(VS_INPUT): TypeStruct 6(int) 8(fvec4) 6(int)
+ 41: TypePointer Function 40(VS_INPUT)
+ 54(VS_OUTPUT): TypeStruct 6(int) 6(int)
+ 55: TypePointer Output 54(VS_OUTPUT)
+56(@entryPointOutput): 55(ptr) Variable Output
+ 59: TypePointer Output 6(int)
+ 61: TypePointer Output 8(fvec4)
+ 62(Pos_out): 61(ptr) Variable Output
+ 4(main): 2 Function None 3
+ 5: Label
+ 25(vsout): 12(ptr) Variable Function
+ 42(aggShadow): 41(ptr) Variable Function
+ 49(param): 41(ptr) Variable Function
+ 51(param): 12(ptr) Variable Function
+ 29: 6(int) Load 28(x0_in)
+ 31: 30(ptr) AccessChain 25(vsout) 26
+ Store 31 29
+ 34: 8(fvec4) Load 33(Pos_in)
+ 35: 19(ptr) AccessChain 25(vsout) 18
+ Store 35 34
+ 38: 6(int) Load 37(x1_in)
+ 39: 30(ptr) AccessChain 25(vsout) 36
+ Store 39 38
+ 43: 6(int) Load 28(x0_in)
+ 44: 30(ptr) AccessChain 42(aggShadow) 26
+ Store 44 43
+ 45: 8(fvec4) Load 33(Pos_in)
+ 46: 19(ptr) AccessChain 42(aggShadow) 18
+ Store 46 45
+ 47: 6(int) Load 37(x1_in)
+ 48: 30(ptr) AccessChain 42(aggShadow) 36
+ Store 48 47
+ 50:40(VS_INPUT) Load 42(aggShadow)
+ Store 49(param) 50
+ 52:11(VS_OUTPUT) Load 25(vsout)
+ Store 51(param) 52
+ 53: 2 FunctionCall 16(Fn1(struct-VS_INPUT-i1-vf4-i11;struct-VS_OUTPUT-i1-vf4-i11;) 49(param) 51(param)
+ 57: 30(ptr) AccessChain 25(vsout) 26
+ 58: 6(int) Load 57
+ 60: 59(ptr) AccessChain 56(@entryPointOutput) 26
+ Store 60 58
+ 63: 19(ptr) AccessChain 25(vsout) 18
+ 64: 8(fvec4) Load 63
+ Store 62(Pos_out) 64
+ 65: 30(ptr) AccessChain 25(vsout) 36
+ 66: 6(int) Load 65
+ 67: 59(ptr) AccessChain 56(@entryPointOutput) 18
+ Store 67 66
+ Return
+ FunctionEnd
+16(Fn1(struct-VS_INPUT-i1-vf4-i11;struct-VS_OUTPUT-i1-vf4-i11;): 2 Function None 13
+ 14(fn1_in): 10(ptr) FunctionParameter
+ 15(fn1_out): 12(ptr) FunctionParameter
+ 17: Label
+ 20: 19(ptr) AccessChain 14(fn1_in) 18
+ 21: 8(fvec4) Load 20
+ 22: 19(ptr) AccessChain 15(fn1_out) 18
+ 23: 8(fvec4) Load 22
+ 24: 8(fvec4) FAdd 21 23
+ 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 0000000..3dd8d9f
--- /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 0000000..8448ac4
--- /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
new file mode 100644
index 0000000..bdf156c
--- /dev/null
+++ b/Test/baseResults/hlsl.struct.split.trivial.vert.out
@@ -0,0 +1,108 @@
+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 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)
+0:? Sequence
+0:19 move second child to first child (temp 4-component vector of float)
+0:19 Pos: direct index for structure (temp 4-component vector of float)
+0:19 'vsout' (temp structure{temp 4-component vector of float Pos})
+0:19 Constant:
+0:19 0 (const int)
+0:19 add (temp 4-component vector of float)
+0:? 'Pos_in' (in 4-component vector of float Position)
+0:19 'Pos_loose' (in 4-component vector of float Position)
+0:21 Sequence
+0:21 Sequence
+0:21 move second child to first child (temp 4-component vector of float)
+0:? 'Pos' (out 4-component vector of float Position)
+0:21 Pos: direct index for structure (temp 4-component vector of float)
+0:21 'vsout' (temp structure{temp 4-component vector of float Pos})
+0:21 Constant:
+0:21 0 (const int)
+0:21 Branch: Return
+0:? Linker Objects
+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:
+
+
+Shader version: 450
+0:? Sequence
+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)
+0:? Sequence
+0:19 move second child to first child (temp 4-component vector of float)
+0:19 Pos: direct index for structure (temp 4-component vector of float)
+0:19 'vsout' (temp structure{temp 4-component vector of float Pos})
+0:19 Constant:
+0:19 0 (const int)
+0:19 add (temp 4-component vector of float)
+0:? 'Pos_in' (in 4-component vector of float Position)
+0:19 'Pos_loose' (in 4-component vector of float Position)
+0:21 Sequence
+0:21 Sequence
+0:21 move second child to first child (temp 4-component vector of float)
+0:? 'Pos' (out 4-component vector of float Position)
+0:21 Pos: direct index for structure (temp 4-component vector of float)
+0:21 'vsout' (temp structure{temp 4-component vector of float Pos})
+0:21 Constant:
+0:21 0 (const int)
+0:21 Branch: Return
+0:? Linker Objects
+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
+// Id's are bound by 26
+
+ Capability Shader
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Vertex 4 "main" 14 16 22
+ Name 4 "main"
+ Name 8 "VS_OUTPUT"
+ MemberName 8(VS_OUTPUT) 0 "Pos"
+ Name 10 "vsout"
+ Name 14 "Pos_in"
+ Name 16 "Pos_loose"
+ Name 22 "Pos"
+ Decorate 14(Pos_in) BuiltIn Position
+ Decorate 16(Pos_loose) BuiltIn Position
+ Decorate 22(Pos) BuiltIn Position
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeFloat 32
+ 7: TypeVector 6(float) 4
+ 8(VS_OUTPUT): TypeStruct 7(fvec4)
+ 9: TypePointer Function 8(VS_OUTPUT)
+ 11: TypeInt 32 1
+ 12: 11(int) Constant 0
+ 13: TypePointer Input 7(fvec4)
+ 14(Pos_in): 13(ptr) Variable Input
+ 16(Pos_loose): 13(ptr) Variable Input
+ 19: TypePointer Function 7(fvec4)
+ 21: TypePointer Output 7(fvec4)
+ 22(Pos): 21(ptr) Variable Output
+ 4(main): 2 Function None 3
+ 5: Label
+ 10(vsout): 9(ptr) Variable Function
+ 15: 7(fvec4) Load 14(Pos_in)
+ 17: 7(fvec4) Load 16(Pos_loose)
+ 18: 7(fvec4) FAdd 15 17
+ 20: 19(ptr) AccessChain 10(vsout) 12
+ Store 20 18
+ 23: 19(ptr) AccessChain 10(vsout) 12
+ 24: 7(fvec4) Load 23
+ Store 22(Pos) 24
+ Return
+ FunctionEnd
diff --git a/Test/baseResults/hlsl.structarray.flatten.geom.out b/Test/baseResults/hlsl.structarray.flatten.geom.out
index 0994af8..0922bae 100644
--- a/Test/baseResults/hlsl.structarray.flatten.geom.out
+++ b/Test/baseResults/hlsl.structarray.flatten.geom.out
@@ -1,52 +1,82 @@
hlsl.structarray.flatten.geom
-ERROR: 0:10: 'vin' : recursive type not yet supported in GS input
-ERROR: 1 compilation errors. No code generated.
-
-
Shader version: 450
invocations = -1
max_vertices = 4
input primitive = lines
output primitive = triangle_strip
-ERROR: node is still EOpNull!
-0:10 Function Definition: main(struct-VertexData-vf4-vf4-vf21[2];struct-VertexData-vf4-vf4-vf21; (temp void)
-0:10 Function Parameters:
-0:10 'vin' (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:10 'outStream' (out structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv})
+0:? Sequence
+0:16 Function Definition: main(struct-VertexData-vf4-vf4-vf21[2];struct-PS_IN-vf4-vf4-vf21; (temp void)
+0:16 Function Parameters:
+0:16 '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:16 'outStream' (out structure{temp 4-component vector of float Position position, temp 4-component vector of float color, temp 2-component vector of float uv})
0:? Sequence
-0:13 move second child to first child (temp 4-component vector of float)
-0:13 color: direct index for structure (temp 4-component vector of float)
-0:13 '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:13 Constant:
-0:13 1 (const int)
-0:? 'vin[0].color' (layout(location=1 ) in 4-component vector of float)
-0:14 move second child to first child (temp 2-component vector of float)
-0:14 uv: direct index for structure (temp 2-component vector of float)
-0:14 '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:14 Constant:
-0:14 2 (const int)
-0:? 'vin[0].uv' (layout(location=2 ) in 2-component vector of float)
-0:15 move second child to first child (temp 4-component vector of float)
-0:15 position: direct index for structure (temp 4-component vector of float)
-0:15 '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:15 Constant:
-0:15 0 (const int)
-0:? 'vin[0].position' (layout(location=0 ) in 4-component vector of float)
-0:16 Sequence
-0:16 move second child to first child (temp structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv})
-0:16 'outStream' (out structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv})
-0:16 '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:16 EmitVertex (temp void)
+0:19 move second child to first child (temp 4-component vector of float)
+0:19 color: direct index for structure (temp 4-component vector of float)
+0:19 '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:19 Constant:
+0:19 1 (const int)
+0:19 color: direct index for structure (temp 4-component vector of float)
+0:19 direct index (layout(location=0 ) temp structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv})
+0:19 '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:19 Constant:
+0:19 1 (const int)
+0:19 Constant:
+0:19 1 (const int)
+0:20 move second child to first child (temp 2-component vector of float)
+0:20 uv: direct index for structure (temp 2-component vector of float)
+0:20 '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:20 Constant:
+0:20 2 (const int)
+0:20 uv: direct index for structure (temp 2-component vector of float)
+0:20 direct index (layout(location=0 ) temp structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv})
+0:20 '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:20 Constant:
+0:20 1 (const int)
+0:20 Constant:
+0:20 2 (const int)
+0:21 move second child to first child (temp 4-component vector of float)
+0:21 position: direct index for structure (temp 4-component vector of float)
+0:21 '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:21 Constant:
+0:21 0 (const int)
+0:21 position: direct index for structure (temp 4-component vector of float)
+0:21 direct index (layout(location=0 ) temp structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv})
+0:21 '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:21 Constant:
+0:21 1 (const int)
+0:21 Constant:
+0:21 0 (const int)
+0:22 Sequence
+0:22 Sequence
+0:22 move second child to first child (temp 4-component vector of float)
+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:
+0:22 0 (const int)
+0:22 move second child to first child (temp 4-component vector of float)
+0:22 color: direct index for structure (temp 4-component vector of float)
+0:22 'outStream' (layout(location=0 ) out structure{temp 4-component vector of float color, temp 2-component vector of float uv})
+0:22 Constant:
+0:22 0 (const int)
+0:22 color: 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:
+0:22 1 (const int)
+0:22 move second child to first child (temp 2-component vector of float)
+0:22 uv: direct index for structure (temp 2-component vector of float)
+0:22 'outStream' (layout(location=0 ) out structure{temp 4-component vector of float color, temp 2-component vector of float uv})
+0:22 Constant:
+0:22 1 (const int)
+0:22 uv: direct index for structure (temp 2-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:
+0:22 2 (const int)
+0:22 EmitVertex (temp void)
0:? Linker Objects
-0:? 'vin[0].position' (layout(location=0 ) in 4-component vector of float)
-0:? 'vin[0].color' (layout(location=1 ) in 4-component vector of float)
-0:? 'vin[0].uv' (layout(location=2 ) in 2-component vector of float)
-0:? 'vin[1].position' (layout(location=3 ) in 4-component vector of float)
-0:? 'vin[1].color' (layout(location=4 ) in 4-component vector of float)
-0:? 'vin[1].uv' (layout(location=5 ) in 2-component vector of float)
-0:? 'position' (layout(location=0 ) out 4-component vector of float)
-0:? 'color' (layout(location=1 ) out 4-component vector of float)
-0:? 'uv' (layout(location=2 ) out 2-component vector of float)
+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:? 'outStream.position' (out 4-component vector of float Position)
Linked geometry stage:
@@ -57,44 +87,164 @@
max_vertices = 4
input primitive = lines
output primitive = triangle_strip
-ERROR: node is still EOpNull!
-0:10 Function Definition: main(struct-VertexData-vf4-vf4-vf21[2];struct-VertexData-vf4-vf4-vf21; (temp void)
-0:10 Function Parameters:
-0:10 'vin' (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:10 'outStream' (out structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv})
+0:? Sequence
+0:16 Function Definition: main(struct-VertexData-vf4-vf4-vf21[2];struct-PS_IN-vf4-vf4-vf21; (temp void)
+0:16 Function Parameters:
+0:16 '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:16 'outStream' (out structure{temp 4-component vector of float Position position, temp 4-component vector of float color, temp 2-component vector of float uv})
0:? Sequence
-0:13 move second child to first child (temp 4-component vector of float)
-0:13 color: direct index for structure (temp 4-component vector of float)
-0:13 '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:13 Constant:
-0:13 1 (const int)
-0:? 'vin[0].color' (layout(location=1 ) in 4-component vector of float)
-0:14 move second child to first child (temp 2-component vector of float)
-0:14 uv: direct index for structure (temp 2-component vector of float)
-0:14 '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:14 Constant:
-0:14 2 (const int)
-0:? 'vin[0].uv' (layout(location=2 ) in 2-component vector of float)
-0:15 move second child to first child (temp 4-component vector of float)
-0:15 position: direct index for structure (temp 4-component vector of float)
-0:15 '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:15 Constant:
-0:15 0 (const int)
-0:? 'vin[0].position' (layout(location=0 ) in 4-component vector of float)
-0:16 Sequence
-0:16 move second child to first child (temp structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv})
-0:16 'outStream' (out structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv})
-0:16 '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:16 EmitVertex (temp void)
+0:19 move second child to first child (temp 4-component vector of float)
+0:19 color: direct index for structure (temp 4-component vector of float)
+0:19 '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:19 Constant:
+0:19 1 (const int)
+0:19 color: direct index for structure (temp 4-component vector of float)
+0:19 direct index (layout(location=0 ) temp structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv})
+0:19 '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:19 Constant:
+0:19 1 (const int)
+0:19 Constant:
+0:19 1 (const int)
+0:20 move second child to first child (temp 2-component vector of float)
+0:20 uv: direct index for structure (temp 2-component vector of float)
+0:20 '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:20 Constant:
+0:20 2 (const int)
+0:20 uv: direct index for structure (temp 2-component vector of float)
+0:20 direct index (layout(location=0 ) temp structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv})
+0:20 '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:20 Constant:
+0:20 1 (const int)
+0:20 Constant:
+0:20 2 (const int)
+0:21 move second child to first child (temp 4-component vector of float)
+0:21 position: direct index for structure (temp 4-component vector of float)
+0:21 '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:21 Constant:
+0:21 0 (const int)
+0:21 position: direct index for structure (temp 4-component vector of float)
+0:21 direct index (layout(location=0 ) temp structure{temp 4-component vector of float position, temp 4-component vector of float color, temp 2-component vector of float uv})
+0:21 '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:21 Constant:
+0:21 1 (const int)
+0:21 Constant:
+0:21 0 (const int)
+0:22 Sequence
+0:22 Sequence
+0:22 move second child to first child (temp 4-component vector of float)
+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:
+0:22 0 (const int)
+0:22 move second child to first child (temp 4-component vector of float)
+0:22 color: direct index for structure (temp 4-component vector of float)
+0:22 'outStream' (layout(location=0 ) out structure{temp 4-component vector of float color, temp 2-component vector of float uv})
+0:22 Constant:
+0:22 0 (const int)
+0:22 color: 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:
+0:22 1 (const int)
+0:22 move second child to first child (temp 2-component vector of float)
+0:22 uv: direct index for structure (temp 2-component vector of float)
+0:22 'outStream' (layout(location=0 ) out structure{temp 4-component vector of float color, temp 2-component vector of float uv})
+0:22 Constant:
+0:22 1 (const int)
+0:22 uv: direct index for structure (temp 2-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:
+0:22 2 (const int)
+0:22 EmitVertex (temp void)
0:? Linker Objects
-0:? 'vin[0].position' (layout(location=0 ) in 4-component vector of float)
-0:? 'vin[0].color' (layout(location=1 ) in 4-component vector of float)
-0:? 'vin[0].uv' (layout(location=2 ) in 2-component vector of float)
-0:? 'vin[1].position' (layout(location=3 ) in 4-component vector of float)
-0:? 'vin[1].color' (layout(location=4 ) in 4-component vector of float)
-0:? 'vin[1].uv' (layout(location=5 ) in 2-component vector of float)
-0:? 'position' (layout(location=0 ) out 4-component vector of float)
-0:? 'color' (layout(location=1 ) out 4-component vector of float)
-0:? 'uv' (layout(location=2 ) out 2-component vector of float)
+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:? 'outStream.position' (out 4-component vector of float Position)
-SPIR-V is not generated for failed compile or link
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 49
+
+ Capability Geometry
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint Geometry 4 "main" 19 36 41
+ ExecutionMode 4 InputLines
+ ExecutionMode 4 Invocations 1
+ ExecutionMode 4 OutputTriangleStrip
+ ExecutionMode 4 OutputVertices 4
+ Name 4 "main"
+ Name 9 "PS_IN"
+ MemberName 9(PS_IN) 0 "position"
+ MemberName 9(PS_IN) 1 "color"
+ MemberName 9(PS_IN) 2 "uv"
+ Name 11 "vout"
+ Name 14 "VertexData"
+ MemberName 14(VertexData) 0 "position"
+ MemberName 14(VertexData) 1 "color"
+ MemberName 14(VertexData) 2 "uv"
+ Name 19 "vin"
+ 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(outStream.position) BuiltIn Position
+ Decorate 41(outStream) Location 0
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeFloat 32
+ 7: TypeVector 6(float) 4
+ 8: TypeVector 6(float) 2
+ 9(PS_IN): TypeStruct 7(fvec4) 7(fvec4) 8(fvec2)
+ 10: TypePointer Function 9(PS_IN)
+ 12: TypeInt 32 1
+ 13: 12(int) Constant 1
+ 14(VertexData): TypeStruct 7(fvec4) 7(fvec4) 8(fvec2)
+ 15: TypeInt 32 0
+ 16: 15(int) Constant 2
+ 17: TypeArray 14(VertexData) 16
+ 18: TypePointer Input 17
+ 19(vin): 18(ptr) Variable Input
+ 20: TypePointer Input 7(fvec4)
+ 23: TypePointer Function 7(fvec4)
+ 25: 12(int) Constant 2
+ 26: TypePointer Input 8(fvec2)
+ 29: TypePointer Function 8(fvec2)
+ 31: 12(int) Constant 0
+ 35: TypePointer Output 7(fvec4)
+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
+ 47: TypePointer Output 8(fvec2)
+ 4(main): 2 Function None 3
+ 5: Label
+ 11(vout): 10(ptr) Variable Function
+ 21: 20(ptr) AccessChain 19(vin) 13 13
+ 22: 7(fvec4) Load 21
+ 24: 23(ptr) AccessChain 11(vout) 13
+ Store 24 22
+ 27: 26(ptr) AccessChain 19(vin) 13 25
+ 28: 8(fvec2) Load 27
+ 30: 29(ptr) AccessChain 11(vout) 25
+ Store 30 28
+ 32: 20(ptr) AccessChain 19(vin) 13 31
+ 33: 7(fvec4) Load 32
+ 34: 23(ptr) AccessChain 11(vout) 31
+ Store 34 33
+ 37: 23(ptr) AccessChain 11(vout) 31
+ 38: 7(fvec4) Load 37
+ Store 36(outStream.position) 38
+ 42: 23(ptr) AccessChain 11(vout) 13
+ 43: 7(fvec4) Load 42
+ 44: 35(ptr) AccessChain 41(outStream) 31
+ Store 44 43
+ 45: 29(ptr) AccessChain 11(vout) 25
+ 46: 8(fvec2) Load 45
+ 48: 47(ptr) AccessChain 41(outStream) 13
+ Store 48 46
+ EmitVertex
+ Return
+ FunctionEnd
diff --git a/Test/baseResults/hlsl.structin.vert.out b/Test/baseResults/hlsl.structin.vert.out
index a5feea8..5e83ed4 100755
--- a/Test/baseResults/hlsl.structin.vert.out
+++ b/Test/baseResults/hlsl.structin.vert.out
@@ -28,50 +28,42 @@
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:? 'm[0]' (layout(location=0 ) out 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 '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 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 move second child to first child (temp 4-component vector of float)
-0:? 'm[1]' (layout(location=1 ) out 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 '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 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})
0:13 Constant:
0:13 1 (const int)
-0:13 move second child to first child (temp 2-component vector of uint)
-0:? 'coord' (layout(location=2 ) out 2-component vector of uint)
0:13 coord: direct index for structure (temp 2-component vector of uint)
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 1 (const int)
0:13 move second child to first child (temp 4-component vector of float)
-0:? 'b' (layout(location=3 ) smooth out 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)
0:13 b: direct index for structure (temp 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 2 (const int)
0:13 Branch: Return
0:? Linker Objects
-0:? 'm[0]' (layout(location=0 ) out 4-component vector of float)
-0:? 'm[1]' (layout(location=1 ) out 4-component vector of float)
-0:? 'coord' (layout(location=2 ) out 2-component vector of uint)
-0:? 'b' (layout(location=3 ) smooth out 4-component vector of float)
+0:? '@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:? 'd' (layout(location=0 ) in 4-component vector of float)
0:? 'm[0]' (layout(location=1 ) in 4-component vector of float)
0:? 'm[1]' (layout(location=2 ) in 4-component vector of float)
0:? 'coord' (layout(location=3 ) in 2-component vector of uint)
-0:? 'b' (layout(location=4 ) in 4-component vector of float)
+0:? 'b' (layout(location=4 ) smooth in 4-component vector of float)
0:? 'e' (layout(location=5 ) in 4-component vector of float)
-0:? 'm[0]' (layout(location=0 ) out 4-component vector of float)
-0:? 'm[1]' (layout(location=1 ) out 4-component vector of float)
0:? 'm[0]' (layout(location=1 ) in 4-component vector of float)
0:? 'm[1]' (layout(location=2 ) in 4-component vector of float)
@@ -108,61 +100,53 @@
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:? 'm[0]' (layout(location=0 ) out 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 '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 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 move second child to first child (temp 4-component vector of float)
-0:? 'm[1]' (layout(location=1 ) out 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 '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 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})
0:13 Constant:
0:13 1 (const int)
-0:13 move second child to first child (temp 2-component vector of uint)
-0:? 'coord' (layout(location=2 ) out 2-component vector of uint)
0:13 coord: direct index for structure (temp 2-component vector of uint)
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 1 (const int)
0:13 move second child to first child (temp 4-component vector of float)
-0:? 'b' (layout(location=3 ) smooth out 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)
0:13 b: direct index for structure (temp 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 2 (const int)
0:13 Branch: Return
0:? Linker Objects
-0:? 'm[0]' (layout(location=0 ) out 4-component vector of float)
-0:? 'm[1]' (layout(location=1 ) out 4-component vector of float)
-0:? 'coord' (layout(location=2 ) out 2-component vector of uint)
-0:? 'b' (layout(location=3 ) smooth out 4-component vector of float)
+0:? '@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:? 'd' (layout(location=0 ) in 4-component vector of float)
0:? 'm[0]' (layout(location=1 ) in 4-component vector of float)
0:? 'm[1]' (layout(location=2 ) in 4-component vector of float)
0:? 'coord' (layout(location=3 ) in 2-component vector of uint)
-0:? 'b' (layout(location=4 ) in 4-component vector of float)
+0:? 'b' (layout(location=4 ) smooth in 4-component vector of float)
0:? 'e' (layout(location=5 ) in 4-component vector of float)
-0:? 'm[0]' (layout(location=0 ) out 4-component vector of float)
-0:? 'm[1]' (layout(location=1 ) out 4-component vector of float)
0:? 'm[0]' (layout(location=1 ) in 4-component vector of float)
0:? 'm[1]' (layout(location=2 ) in 4-component vector of float)
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 59
+// 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 41 45 50 54 58
+ EntryPoint Vertex 4 "main" 18 20 24 32 35 42 60
Name 4 "main"
Name 12 "VI"
MemberName 12(VI) 0 "m"
@@ -174,21 +158,19 @@
Name 24 "coord"
Name 32 "d"
Name 35 "e"
- Name 41 "m[0]"
- Name 45 "m[1]"
- Name 50 "coord"
- Name 54 "b"
- Name 58 "b"
+ Name 40 "VI"
+ MemberName 40(VI) 0 "m"
+ MemberName 40(VI) 1 "coord"
+ MemberName 40(VI) 2 "b"
+ Name 42 "@entryPointOutput"
+ 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 41(m[0]) Location 0
- Decorate 45(m[1]) Location 1
- Decorate 50(coord) Location 2
- Decorate 54(b) Location 3
- Decorate 58(b) Location 4
+ Decorate 42(@entryPointOutput) BuiltIn Position
+ Decorate 60(b) Location 4
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
@@ -211,16 +193,17 @@
32(d): 17(ptr) Variable Input
35(e): 17(ptr) Variable Input
38: TypePointer Function 7(fvec4)
- 40: TypePointer Output 7(fvec4)
- 41(m[0]): 40(ptr) Variable Output
- 42: 15(int) Constant 0
- 45(m[1]): 40(ptr) Variable Output
- 46: 15(int) Constant 1
- 49: TypePointer Output 11(ivec2)
- 50(coord): 49(ptr) Variable Output
- 51: TypePointer Function 11(ivec2)
- 54(b): 40(ptr) Variable Output
- 58(b): 17(ptr) Variable Input
+ 40(VI): TypeStruct 10 11(ivec2) 7(fvec4)
+ 41: TypePointer Output 40(VI)
+42(@entryPointOutput): 41(ptr) Variable Output
+ 43: 15(int) Constant 0
+ 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
@@ -238,17 +221,17 @@
37: 7(fvec4) FAdd 34 36
39: 38(ptr) AccessChain 14(local) 16
Store 39 37
- 43: 38(ptr) AccessChain 14(local) 42 42
- 44: 7(fvec4) Load 43
- Store 41(m[0]) 44
- 47: 38(ptr) AccessChain 14(local) 42 46
- 48: 7(fvec4) Load 47
- Store 45(m[1]) 48
- 52: 51(ptr) AccessChain 14(local) 46
- 53: 11(ivec2) Load 52
- Store 50(coord) 53
+ 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
- Store 54(b) 56
+ 58: 57(ptr) AccessChain 42(@entryPointOutput) 16
+ Store 58 56
Return
FunctionEnd
diff --git a/Test/hlsl.flatten.return.frag b/Test/hlsl.flatten.return.frag
index c633e67..4aa3f50 100644
--- a/Test/hlsl.flatten.return.frag
+++ b/Test/hlsl.flatten.return.frag
@@ -9,7 +9,7 @@
PS_OUTPUT Func1()
{
- return PS_OUTPUT(float4(1), 2, 3, 4);
+ return PS_OUTPUT(float4(1,1,1,1), 2, 3, 4);
}
PS_OUTPUT main()
diff --git a/Test/hlsl.pp.tokenpasting.frag b/Test/hlsl.pp.tokenpasting.frag
new file mode 100644
index 0000000..5415670
--- /dev/null
+++ b/Test/hlsl.pp.tokenpasting.frag
@@ -0,0 +1,18 @@
+
+#define foobarblee zzzz
+
+#define ar qqqq
+
+#define MACRO1(x,y) foo##x##y
+// #define MACRO2 abc##def
+
+// #define SPACE_IN_MACRO int var1
+
+float4 main() : SV_Target0
+{
+ // float MACRO2 = 10;
+ float MACRO1(b##ar,blee) = 3;
+
+ return float4(foobarblee,0,0,0);
+}
+
diff --git a/Test/hlsl.struct.split-1.vert b/Test/hlsl.struct.split-1.vert
new file mode 100644
index 0000000..ce5f51f
--- /dev/null
+++ b/Test/hlsl.struct.split-1.vert
@@ -0,0 +1,25 @@
+
+struct VS_INPUT
+{
+ int x0_in : foo0;
+ float4 Pos_in : SV_Position;
+ int x1_in : foo1;
+};
+
+struct VS_OUTPUT
+{
+ int x0_out : foo0;
+ float4 Pos_out : SV_Position;
+ int x1_out : foo1;
+};
+
+VS_OUTPUT main(VS_INPUT vsin, float4 Pos_loose : SV_Position)
+{
+ VS_OUTPUT vsout;
+
+ vsout.x0_out = vsin.x0_in;
+ vsout.Pos_out = vsin.Pos_in + Pos_loose;
+ vsout.x1_out = vsin.x1_in;
+
+ return vsout;
+}
diff --git a/Test/hlsl.struct.split.array.geom b/Test/hlsl.struct.split.array.geom
new file mode 100644
index 0000000..9008df1
--- /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<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;
+}
diff --git a/Test/hlsl.struct.split.call.vert b/Test/hlsl.struct.split.call.vert
new file mode 100644
index 0000000..543adeb
--- /dev/null
+++ b/Test/hlsl.struct.split.call.vert
@@ -0,0 +1,32 @@
+// Test passing split structs to functions.
+
+struct VS_INPUT
+{
+ int x0_in : foo0;
+ float4 Pos_in : SV_Position;
+ int x1_in : foo1;
+};
+
+struct VS_OUTPUT
+{
+ int x0_out : foo0;
+ float4 Pos_out : SV_Position;
+ int x1_out : foo1;
+};
+
+void Fn1(VS_INPUT fn1_in, VS_OUTPUT fn1_out) {
+ fn1_in.Pos_in + fn1_out.Pos_out;
+}
+
+VS_OUTPUT main(VS_INPUT vsin)
+{
+ VS_OUTPUT vsout;
+
+ vsout.x0_out = vsin.x0_in;
+ vsout.Pos_out = vsin.Pos_in;
+ vsout.x1_out = vsin.x1_in;
+
+ Fn1(vsin, vsout);
+
+ return vsout;
+}
diff --git a/Test/hlsl.struct.split.nested.geom b/Test/hlsl.struct.split.nested.geom
new file mode 100644
index 0000000..03bf38f
--- /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 <GS_OUT> 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 0000000..343da38
--- /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 <GS_OUT> ts)
+{
+ GS_OUT o;
+
+ for (int x=0; x<3; ++x) {
+ o.pos = i[x].pos;
+ ts.Append(o);
+ }
+}
diff --git a/Test/hlsl.struct.split.trivial.vert b/Test/hlsl.struct.split.trivial.vert
new file mode 100644
index 0000000..351e418
--- /dev/null
+++ b/Test/hlsl.struct.split.trivial.vert
@@ -0,0 +1,22 @@
+
+// Test trivial case for structure splitting: the IN and OUT structs have ONLY an interstage IO.
+// This should fall back to flattening, and not produce any empty structures.
+
+struct VS_INPUT
+{
+ float4 Pos_in : SV_Position;
+};
+
+struct VS_OUTPUT
+{
+ float4 Pos : SV_Position;
+};
+
+VS_OUTPUT main(VS_INPUT vsin, float4 Pos_loose : SV_Position)
+{
+ VS_OUTPUT vsout;
+
+ vsout.Pos = vsin.Pos_in + Pos_loose;
+
+ return vsout;
+}
diff --git a/Test/hlsl.structarray.flatten.geom b/Test/hlsl.structarray.flatten.geom
index 1b05dc1..990532d 100644
--- a/Test/hlsl.structarray.flatten.geom
+++ b/Test/hlsl.structarray.flatten.geom
@@ -1,17 +1,23 @@
struct VertexData {
- float4 position : POSITION;
- float4 color : COLOR0;
- float2 uv : TEXCOORD0;
+ float4 position : POSITION;
+ float4 color : COLOR0;
+ float2 uv : TEXCOORD0;
+};
+
+struct PS_IN {
+ float4 position : SV_POSITION;
+ float4 color : COLOR0;
+ float2 uv : TEXCOORD0;
};
[maxvertexcount(4)]
-void main(line VertexData vin[2], inout TriangleStream<VertexData> outStream)
+void main(line VertexData vin[2], inout TriangleStream<PS_IN> outStream)
{
- VertexData vout;
+ PS_IN vout;
- vout.color = vin[0].color;
- vout.uv = vin[0].uv;
- vout.position = vin[0].position;
+ vout.color = vin[1].color;
+ vout.uv = vin[1].uv;
+ vout.position = vin[1].position;
outStream.Append(vout);
}
diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index ae40465..6bd201d 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -1223,6 +1223,16 @@
typeName = NewPoolTString(copyOf.typeName->c_str());
}
+ // Recursively make temporary
+ void makeTemporary()
+ {
+ getQualifier().makeTemporary();
+
+ if (isStruct())
+ for (unsigned int i = 0; i < structure->size(); ++i)
+ (*structure)[i].type->makeTemporary();
+ }
+
TType* clone() const
{
TType *newType = new TType();
@@ -1309,6 +1319,20 @@
virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); }
virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); }
+ // Return true if this is interstage IO
+ virtual bool isBuiltInInterstageIO() const
+ {
+ switch (getQualifier().builtIn) {
+ case EbvPosition:
+ case EbvPointSize:
+ case EbvClipDistance:
+ case EbvCullDistance:
+ return true;
+ default:
+ return false;
+ }
+ }
+
// Recursively checks if the type contains the given basic type
virtual bool containsBasicType(TBasicType checkType) const
{
@@ -1376,6 +1400,34 @@
return false;
}
+ // Recursively checks if the type contains an interstage IO builtin
+ virtual bool containsBuiltInInterstageIO() const
+ {
+ if (isBuiltInInterstageIO())
+ return true;
+
+ if (! structure)
+ return false;
+ for (unsigned int i = 0; i < structure->size(); ++i) {
+ if ((*structure)[i].type->containsBuiltInInterstageIO())
+ return true;
+ }
+ return false;
+ }
+
+ // Recursively checks whether a struct contains only interstage IO
+ virtual bool containsOnlyBuiltInInterstageIO() const
+ {
+ if (! structure)
+ return isBuiltInInterstageIO();
+
+ for (unsigned int i = 0; i < structure->size(); ++i) {
+ if (!(*structure)[i].type->containsOnlyBuiltInInterstageIO())
+ return false;
+ }
+ return true;
+ }
+
virtual bool containsNonOpaque() const
{
// list all non-opaque types
diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp
index 41372f6..fd35af3 100644
--- a/gtests/Hlsl.FromFile.cpp
+++ b/gtests/Hlsl.FromFile.cpp
@@ -207,6 +207,12 @@
{"hlsl.shapeConvRet.frag", "main"},
{"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"},
{"hlsl.structin.vert", "main"},
diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp
index d0f3b00..22f4c0d 100755
--- a/hlsl/hlslGrammar.cpp
+++ b/hlsl/hlslGrammar.cpp
@@ -478,7 +478,7 @@
// 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 8791d4c..613b18a 100755
--- a/hlsl/hlslParseHelper.cpp
+++ b/hlsl/hlslParseHelper.cpp
@@ -59,9 +59,12 @@
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 @@
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(loc, base, indexValue);
+ 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 @@
}
} 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.
@@ -834,15 +837,21 @@
}
}
if (fieldFound) {
- if (base->getAsSymbolNode() && (wasFlattened(base) || shouldFlatten(base->getType())))
- result = flattenAccess(loc, base, member);
- else {
- if (base->getType().getQualifier().storage == EvqConst)
- result = intermediate.foldDereference(base, member, loc);
- else {
- TIntermTyped* index = intermediate.addConstantUnion(member, loc);
- result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
- result->setType(*(*fields)[member].type);
+ if (base->getAsSymbolNode() && (wasFlattened(base) || shouldFlatten(base->getType()))) {
+ result = flattenAccess(base, member);
+ } else {
+ // Update the base and member to access if this was a split structure.
+ result = splitAccessStruct(loc, base, member);
+ fields = base->getType().getStruct();
+
+ if (result == nullptr) {
+ if (base->getType().getQualifier().storage == EvqConst)
+ result = intermediate.foldDereference(base, member, loc);
+ else {
+ TIntermTyped* index = intermediate.addConstantUnion(member, loc);
+ result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
+ result->setType(*(*fields)[member].type);
+ }
}
}
} else
@@ -853,6 +862,102 @@
return result;
}
+// Determine whether we should split this type
+bool HlslParseContext::shouldSplit(const TType& type)
+{
+ if (! inEntryPoint)
+ return false;
+
+ const TStorageQualifier qualifier = type.getQualifier().storage;
+
+ // If it contains interstage IO, but not ONLY interstage IO, split the struct.
+ return type.isStruct() && type.containsBuiltInInterstageIO() &&
+ (qualifier == EvqVaryingIn || qualifier == EvqVaryingOut);
+}
+
+// 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.
+void HlslParseContext::split(TIntermTyped* node)
+{
+ if (node == nullptr)
+ return;
+
+ TIntermSymbol* symNode = node->getAsSymbolNode();
+
+ if (symNode == nullptr)
+ return;
+
+ // Create a new variable:
+ TType& splitType = split(*symNode->getType().clone(), symNode->getName());
+
+ splitIoVars[symNode->getId()] = makeInternalVariable(symNode->getName(), splitType);
+}
+
+// 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:
+ 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, 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 builtin iterstage IO members
+ const auto firstIo = std::stable_partition(userStructure->begin(), userStructure->end(),
+ [](const TTypeLoc& t) {return !t.type->isBuiltInInterstageIO();});
+
+ // 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(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(), outerStructType->getQualifier());
+ }
+
+ // Erase the IO vars from the user structure.
+ userStructure->erase(firstIo, userStructure->end());
+
+ // Recurse further into the members.
+ for (unsigned int i = 0; i < userStructure->size(); ++i)
+ split(*(*userStructure)[i].type,
+ name + (name.empty() ? "" : ".") + (*userStructure)[i].type->getFieldName(),
+ outerStructType);
+ }
+
+ return type;
+}
+
// Determine whether we should flatten an arbitrary type.
bool HlslParseContext::shouldFlatten(const TType& type) const
{
@@ -868,9 +973,11 @@
const TStorageQualifier qualifier = type.getQualifier().storage;
- return type.isStruct() &&
- (qualifier == EvqVaryingIn ||
- qualifier == EvqVaryingOut);
+ if (!type.isStruct())
+ return false;
+
+ return ((language == EShLangVertex && qualifier == EvqVaryingIn) ||
+ (language == EShLangFragment && qualifier == EvqVaryingOut));
}
// Is this a uniform array which should be flattened?
@@ -891,7 +998,7 @@
// emplace gives back a pair whose .first is an iterator to the item...
auto entry = flattenMap.emplace(variable.getUniqueId(),
TFlattenData(type.getQualifier().layoutBinding));
-
+
// ... and the item is a map pair, so first->second is the TFlattenData itself.
flatten(loc, variable, type, entry.first->second, "");
}
@@ -926,13 +1033,6 @@
int HlslParseContext::flatten(const TSourceLoc& loc, const TVariable& variable, const TType& type,
TFlattenData& flattenData, TString name)
{
- // TODO: when struct splitting is in place we can remove this restriction.
- if (language == EShLangGeometry) {
- const TType derefType(type, 0);
- if (!isFinalFlattening(derefType) && type.getQualifier().storage == EvqVaryingIn)
- error(loc, "recursive type not yet 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())
@@ -953,7 +1053,7 @@
{
if (isFinalFlattening(type)) {
// This is as far as we flatten. Insert the variable.
- TVariable* memberVariable = makeInternalVariable(memberName.c_str(), type);
+ TVariable* memberVariable = makeInternalVariable(memberName, type);
mergeQualifiers(memberVariable->getWritableType().getQualifier(), variable.getType().getQualifier());
if (flattenData.nextBinding != TQualifier::layoutBindingEnd)
@@ -1043,16 +1143,22 @@
// Return true if we have flattened this node.
bool HlslParseContext::wasFlattened(const TIntermTyped* node) const
{
- return node != nullptr &&
- node->getAsSymbolNode() != nullptr &&
+ return node != nullptr && node->getAsSymbolNode() != nullptr &&
wasFlattened(node->getAsSymbolNode()->getId());
}
+// Return true if we have split this structure
+bool HlslParseContext::wasSplit(const TIntermTyped* node) const
+{
+ return node != nullptr && node->getAsSymbolNode() != nullptr &&
+ wasSplit(node->getAsSymbolNode()->getId());
+}
+
// Turn an access into an aggregate that was flattened to instead be
// an access to the individual variable the member was flattened to.
// Assumes shouldFlatten() or equivalent was called first.
-TIntermTyped* HlslParseContext::flattenAccess(const TSourceLoc&, TIntermTyped* base, int member)
+TIntermTyped* HlslParseContext::flattenAccess(TIntermTyped* base, int member)
{
const TType dereferencedType(base->getType(), member); // dereferenced type
@@ -1078,6 +1184,115 @@
}
}
+// Find and return the split IO TVariable for id, or nullptr if none.
+TVariable* HlslParseContext::getSplitIoVar(int id) const
+{
+ const auto splitIoVar = splitIoVars.find(id);
+
+ if (splitIoVar == splitIoVars.end())
+ return nullptr;
+
+ return splitIoVar->second;
+}
+
+// Find and return the split IO TVariable for variable, or nullptr if none.
+TVariable* HlslParseContext::getSplitIoVar(const TVariable* var) const
+{
+ if (var == nullptr)
+ return nullptr;
+
+ return getSplitIoVar(var->getUniqueId());
+}
+
+// Find and return the split IO TVariable for symbol in this node, or nullptr if none.
+TVariable* HlslParseContext::getSplitIoVar(const TIntermTyped* node) const
+{
+ if (node == nullptr)
+ return nullptr;
+
+ const TIntermSymbol* symbolNode = node->getAsSymbolNode();
+
+ if (symbolNode == nullptr)
+ return nullptr;
+
+ 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);
+
+ // 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)
+ 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)
+ return nullptr;
+
+ const TTypeList& members = *base->getType().getStruct();
+
+ 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->isBuiltInInterstageIO())
+ ++newMember;
+
+ member = newMember;
+
+ return nullptr;
+ }
+}
+
// Variables that correspond to the user-interface in and out of a stage
// (not the built-in interface) are assigned locations and
// registered as a linkage node (part of the stage's external interface).
@@ -1105,8 +1320,17 @@
auto& memberList = flattenMap[variable.getUniqueId()].members;
for (auto member = memberList.begin(); member != memberList.end(); ++member)
assignLocation(**member);
- } else
+ } else if (wasSplit(variable.getUniqueId())) {
+ 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);
+ }
}
//
@@ -1150,6 +1374,23 @@
return function;
}
+
+// Add interstage IO variables to the linkage in canonical order.
+void HlslParseContext::addInterstageIoToLinkage()
+{
+ std::vector<tInterstageIoData> io;
+ io.reserve(interstageBuiltInIo.size());
+
+ for (auto ioVar = interstageBuiltInIo.begin(); ioVar != interstageBuiltInIo.end(); ++ioVar)
+ io.push_back(ioVar->first);
+
+ // Our canonical order is the TBuiltInVariable numeric order.
+ std::sort(io.begin(), io.end());
+
+ for (int idx = 0; idx < int(io.size()); ++idx)
+ trackLinkageDeferred(*interstageBuiltInIo[io[idx]]);
+}
+
//
// Handle seeing the function prototype in front of a function definition in the grammar.
// The body is handled after this function returns.
@@ -1188,6 +1429,8 @@
if (entryPointOutput) {
if (shouldFlatten(entryPointOutput->getType()))
flatten(loc, *entryPointOutput);
+ if (shouldSplit(entryPointOutput->getType()))
+ split(*entryPointOutput);
assignLocations(*entryPointOutput);
}
} else
@@ -1215,7 +1458,15 @@
for (int i = 0; i < function.getParamCount(); i++) {
TParameter& param = function[i];
if (param.name != nullptr) {
- TVariable *variable = new TVariable(param.name, *param.type);
+ TType* sanitizedType;
+
+ // If we're not in the entry point, parameters are sanitized types.
+ if (inEntryPoint)
+ sanitizedType = param.type;
+ else
+ sanitizedType = sanitizeType(param.type);
+
+ TVariable *variable = new TVariable(param.name, *sanitizedType);
// Insert the parameters with name in the symbol table.
if (! symbolTable.insert(*variable))
@@ -1225,6 +1476,8 @@
if (inEntryPoint) {
if (shouldFlatten(*param.type))
flatten(loc, *variable);
+ if (shouldSplit(*param.type))
+ split(*variable);
assignLocations(*variable);
}
@@ -1239,6 +1492,7 @@
} else
paramNodes = intermediate.growAggregate(paramNodes, intermediate.addSymbol(*param.type, loc), loc);
}
+
intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), loc);
loopNestingLevel = 0;
controlFlowNestingLevel = 0;
@@ -1373,10 +1627,12 @@
return intermediate.addBranch(EOpReturn, value, loc);
}
-void HlslParseContext::handleFunctionArgument(TFunction* function, TIntermTyped*& arguments, TIntermTyped* newArg)
+void HlslParseContext::handleFunctionArgument(TFunction* function,
+ TIntermTyped*& arguments, TIntermTyped* newArg)
{
TParameter param = { 0, new TType, nullptr };
param.type->shallowCopy(newArg->getType());
+
function->addParameter(param);
if (arguments)
arguments = intermediate.growAggregate(arguments, newArg);
@@ -1392,14 +1648,15 @@
if (left == nullptr || right == nullptr)
return nullptr;
- const auto mustFlatten = [&](const TIntermTyped& node) {
- return wasFlattened(&node) && node.getAsSymbolNode() &&
- flattenMap.find(node.getAsSymbolNode()->getId()) != flattenMap.end();
- };
+ const bool isSplitLeft = wasSplit(left);
+ const bool isSplitRight = wasSplit(right);
- const bool flattenLeft = mustFlatten(*left);
- const bool flattenRight = mustFlatten(*right);
- if (! flattenLeft && ! flattenRight)
+ 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 (! isFlattenLeft && ! isFlattenRight && !isSplitLeft && !isSplitRight)
return intermediate.addAssign(op, left, right, loc);
TIntermAggregate* assignList = nullptr;
@@ -1425,10 +1682,10 @@
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:
@@ -1456,73 +1713,118 @@
int memberIdx = 0;
- const auto getMember = [&](bool flatten, 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 (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;
};
- // 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 {
- // 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);
-
- 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, right, *rightVariables, element,
- EOpIndexDirect, dereferencedType);
- TIntermTyped* subLeft = getMember(flattenLeft, left, *leftVariables, element,
- EOpIndexDirect, dereferencedType);
-
- if (isFinalFlattening(dereferencedType))
- assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subLeft, subRight, loc), loc);
- else
- traverse(subLeft, subRight);
- }
- } else if (left->getType().isStruct()) {
- // struct case
- const auto& members = *left->getType().getStruct();
-
- for (int member = 0; member < (int)members.size(); ++member) {
- TIntermTyped* subRight = getMember(flattenRight, right, *rightVariables, member,
- EOpIndexDirectStruct, *members[member].type);
- TIntermTyped* subLeft = getMember(flattenLeft, left, *leftVariables, member,
- EOpIndexDirectStruct, *members[member].type);
-
- if (isFinalFlattening(*members[member].type))
- assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subLeft, subRight, loc), loc);
- else
- traverse(subLeft, subRight);
- }
- } else {
- assert(0); // we should never be called on a non-flattenable thing, because
- // that case bails out above to a simple copy.
- }
-
- };
-
// Use the proper RHS node: a new symbol from a TVariable, copy
// of an TIntermSymbol node, or sometimes the right node directly.
right = rhsTempVar ? intermediate.addSymbol(*rhsTempVar, loc) :
cloneSymNode ? intermediate.addSymbol(*cloneSymNode) :
right;
+ // 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, 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()) {
+ 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* 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, 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,
+ // which we traverse in parallel.
+ int memberL = 0;
+ int memberR = 0;
+
+ for (int member = 0; member < int(membersL.size()); ++member) {
+ const TType& typeL = *membersL[member].type;
+ const TType& typeR = *membersR[member].type;
+
+ TIntermTyped* subLeft = getMember(true, left, member, left, member);
+ TIntermTyped* subRight = getMember(false, right, member, right, member);
+
+ // 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 {
+ traverse(subLeft, subRight, subSplitLeft, subSplitRight);
+ }
+
+ memberL += (typeL.isBuiltInInterstageIO() ? 0 : 1);
+ memberR += (typeR.isBuiltInInterstageIO() ? 0 : 1);
+ }
+ } else {
+ assert(0); // we should never be called on a non-flattenable thing, because
+ // that case bails out above to a simple copy.
+ }
+
+ };
+
+ 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);
@@ -2214,9 +2516,9 @@
emit->setType(TType(EbtVoid));
sequence = intermediate.growAggregate(sequence,
- intermediate.addAssign(EOpAssign,
- argAggregate->getSequence()[0]->getAsTyped(),
- argAggregate->getSequence()[1]->getAsTyped(), loc),
+ handleAssign(loc, EOpAssign,
+ argAggregate->getSequence()[0]->getAsTyped(),
+ argAggregate->getSequence()[1]->getAsTyped()),
loc);
sequence = intermediate.growAggregate(sequence, emit);
@@ -2840,7 +3142,7 @@
else
error(arg->getLoc(), "cannot convert input argument, argument", "", "%d", i);
} else {
- if (wasFlattened(arg)) {
+ if (wasFlattened(arg) || wasSplit(arg)) {
// Will make a two-level subtree.
// The deepest will copy member-by-member to build the structure to pass.
// The level above that will be a two-operand EOpComma sequence that follows the copy by the
@@ -4781,6 +5083,43 @@
error(loc, "name already defined", "typedef", identifier.c_str());
}
+// Type sanitization: return existing sanitized (temporary) type if there is one, else make new one.
+TType* HlslParseContext::sanitizeType(TType* type)
+{
+ // We only do this for structs.
+ if (!type->isStruct())
+ return type;
+
+ // Type sanitization: if this is declaring a variable of a type that contains
+ // interstage IO, we want to make it a temporary.
+ const auto sanitizedTypeIter = sanitizedTypeMap.find(type->getStruct());
+
+ if (sanitizedTypeIter != sanitizedTypeMap.end()) {
+ // We've sanitized this before. Use that one.
+ 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->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();
+ sanitizedType->makeTemporary();
+ sanitizedTypeMap[type->getStruct()] = sanitizedType;
+ return sanitizedType;
+ } else {
+ // This means the type has no interstage IO, so we can use it as is.
+ return type;
+ }
+ }
+}
+
//
// Do everything necessary to handle a variable (non-block) declaration.
// Either redeclaring a variable, or making a new one, updating the symbol
@@ -4806,15 +5145,20 @@
inheritGlobalDefaults(type.getQualifier());
const bool flattenVar = shouldFlatten(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.
+ TType* sanitizedType = sanitizeType(&type);
// Declare the variable
if (type.isArray()) {
// array case
- declareArray(loc, identifier, type, symbol, !flattenVar);
+ declareArray(loc, identifier, *sanitizedType, symbol, !flattenVar);
} else {
// non-array case
if (! symbol)
- symbol = declareNonArray(loc, identifier, type, !flattenVar);
+ symbol = declareNonArray(loc, identifier, *sanitizedType, !flattenVar);
else if (type != symbol->getType())
error(loc, "cannot change the type of", "redeclaration", symbol->getName().c_str());
}
@@ -4822,6 +5166,9 @@
if (flattenVar)
flatten(loc, *symbol->getAsVariable());
+ if (splitVar)
+ split(*symbol->getAsVariable());
+
if (! symbol)
return nullptr;
@@ -5863,4 +6210,13 @@
name = new TString(intermediate.getEntryPointName().c_str());
}
+// post-processing
+void HlslParseContext::finish()
+{
+ addInterstageIoToLinkage();
+
+ TParseContextBase::finish();
+}
+
+
} // end namespace glslang
diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h
index 229f697..47ea5aa 100755
--- a/hlsl/hlslParseHelper.h
+++ b/hlsl/hlslParseHelper.h
@@ -186,6 +186,9 @@
void fixConstInit(const TSourceLoc&, TString& identifier, TType& type, TIntermTyped*& initializer);
void inheritGlobalDefaults(TQualifier& dst) const;
TVariable* makeInternalVariable(const char* name, const TType&) const;
+ TVariable* makeInternalVariable(const TString& name, const TType& type) const {
+ return makeInternalVariable(name.c_str(), type);
+ }
TVariable* declareNonArray(const TSourceLoc&, TString& identifier, TType&, bool track);
void declareArray(const TSourceLoc&, TString& identifier, const TType&, TSymbol*&, bool track);
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
@@ -198,7 +201,7 @@
// Array and struct flattening
bool shouldFlatten(const TType& type) const;
- TIntermTyped* flattenAccess(const TSourceLoc&, TIntermTyped* base, int member);
+ TIntermTyped* flattenAccess(TIntermTyped* base, int member);
bool shouldFlattenIO(const TType&) const;
bool shouldFlattenUniform(const TType&) const;
bool wasFlattened(const TIntermTyped* node) const;
@@ -206,11 +209,30 @@
int addFlattenedMember(const TSourceLoc& loc, const TVariable&, const TType&, TFlattenData&, const TString& name, bool track);
bool isFinalFlattening(const TType& type) const { return !(type.isStruct() || type.isArray()); }
+ // Structure splitting (splits interstage builtin types into its own struct)
+ 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;
+ bool wasSplit(int id) const { return splitIoVars.find(id) != splitIoVars.end(); }
+ TVariable* getSplitIoVar(const TIntermTyped* node) const;
+ TVariable* getSplitIoVar(const TVariable* var) const;
+ TVariable* getSplitIoVar(int id) const;
+ void addInterstageIoToLinkage();
+
void flatten(const TSourceLoc& loc, const TVariable& variable);
int flatten(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name);
int flattenStruct(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name);
int flattenArray(const TSourceLoc& loc, const TVariable& variable, const TType&, TFlattenData&, TString name);
+ // Type sanitization: return existing sanitized (temporary) type if there is one, else make new one.
+ TType* sanitizeType(TType*);
+
+ void finish(); // post-processing
+
// Current state of parsing
struct TPragma contextPragma;
int loopNestingLevel; // 0 if outside all loops
@@ -276,6 +298,38 @@
TVector<int> flattenLevel; // nested postfix operator level for flattening
TVector<int> flattenOffset; // cumulative offset for flattening
+ // Sanitized type map. During declarations we use the sanitized form of the type
+ // if it exists.
+ TMap<const TTypeList*, TType*> sanitizedTypeMap;
+
+ // Structure splitting data:
+ 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;