SPIR-V requires that tessellation factor arrays be size 4 (outer) or 2 (inner).
HLSL allows other sizes such as 3, or even scalars. This commit converts
between them by forcing the IO types to be the SPIR-V size, and allowing
copies between the internal and IO types to handle these cases.
0:? Sequence
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 0 (const int)
0:? direct index ( temp float)
0:? 0 (const int)
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 1 (const int)
0:? direct index ( temp float)
0:? 'm_cpid' ( in uint InvocationID)
0:? 'pid' ( in uint PrimitiveID)
0:? '@patchConstantOutput' (layout( location=1) patch out structure{})
-0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter)
Linked tessellation control stage:
0:? Sequence
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 0 (const int)
0:? direct index ( temp float)
0:? 0 (const int)
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 1 (const int)
0:? direct index ( temp float)
0:? 'm_cpid' ( in uint InvocationID)
0:? 'pid' ( in uint PrimitiveID)
0:? '@patchConstantOutput' (layout( location=1) patch out structure{})
-0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter)
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 88
+// Id's are bound by 89
Capability Tessellation
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint TessellationControl 4 "main" 40 44 47 62 67 87
+ EntryPoint TessellationControl 4 "main" 40 44 47 62 68 88
ExecutionMode 4 OutputVertices 4
Name 4 "main"
Name 8 "VS_OUT"
Name 61 "@patchConstantResult"
Name 62 "pid"
Name 63 "param"
- Name 67 "@patchConstantOutput_edges"
- Name 77 "output"
- Name 85 "HS_CONSTANT_OUT"
- Name 87 "@patchConstantOutput"
+ Name 68 "@patchConstantOutput_edges"
+ Name 78 "output"
+ Name 86 "HS_CONSTANT_OUT"
+ Name 88 "@patchConstantOutput"
Decorate 40(ip) Location 0
Decorate 44(m_cpid) BuiltIn InvocationId
Decorate 47(@entryPointOutput) Location 0
Decorate 62(pid) BuiltIn PrimitiveId
- Decorate 67(@patchConstantOutput_edges) Patch
- Decorate 67(@patchConstantOutput_edges) BuiltIn TessLevelOuter
- Decorate 87(@patchConstantOutput) Patch
- Decorate 87(@patchConstantOutput) Location 1
+ Decorate 68(@patchConstantOutput_edges) Patch
+ Decorate 68(@patchConstantOutput_edges) BuiltIn TessLevelOuter
+ Decorate 88(@patchConstantOutput) Patch
+ Decorate 88(@patchConstantOutput) Location 1
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
56: TypeBool
60: TypePointer Function 22(HS_CONSTANT_OUT)
62(pid): 43(ptr) Variable Input
- 66: TypePointer Output 21
-67(@patchConstantOutput_edges): 66(ptr) Variable Output
- 68: TypePointer Function 6(float)
- 71: TypePointer Output 6(float)
- 73: 29(int) Constant 1
- 78: 6(float) Constant 1073741824
- 80: 6(float) Constant 1090519040
-85(HS_CONSTANT_OUT): TypeStruct
- 86: TypePointer Output 85(HS_CONSTANT_OUT)
-87(@patchConstantOutput): 86(ptr) Variable Output
+ 66: TypeArray 6(float) 10
+ 67: TypePointer Output 66
+68(@patchConstantOutput_edges): 67(ptr) Variable Output
+ 69: TypePointer Function 6(float)
+ 72: TypePointer Output 6(float)
+ 74: 29(int) Constant 1
+ 79: 6(float) Constant 1073741824
+ 81: 6(float) Constant 1090519040
+86(HS_CONSTANT_OUT): TypeStruct
+ 87: TypePointer Output 86(HS_CONSTANT_OUT)
+88(@patchConstantOutput): 87(ptr) Variable Output
4(main): 2 Function None 3
5: Label
38(ip): 12(ptr) Variable Function
Store 63(param) 64
65:22(HS_CONSTANT_OUT) FunctionCall 25(PCF(u1;) 63(param)
Store 61(@patchConstantResult) 65
- 69: 68(ptr) AccessChain 61(@patchConstantResult) 30 30
- 70: 6(float) Load 69
- 72: 71(ptr) AccessChain 67(@patchConstantOutput_edges) 30
- Store 72 70
- 74: 68(ptr) AccessChain 61(@patchConstantResult) 30 73
- 75: 6(float) Load 74
- 76: 71(ptr) AccessChain 67(@patchConstantOutput_edges) 73
- Store 76 75
+ 70: 69(ptr) AccessChain 61(@patchConstantResult) 30 30
+ 71: 6(float) Load 70
+ 73: 72(ptr) AccessChain 68(@patchConstantOutput_edges) 30
+ Store 73 71
+ 75: 69(ptr) AccessChain 61(@patchConstantResult) 30 74
+ 76: 6(float) Load 75
+ 77: 72(ptr) AccessChain 68(@patchConstantOutput_edges) 74
+ Store 77 76
Branch 59
59: Label
Return
25(PCF(u1;):22(HS_CONSTANT_OUT) Function None 23
24(pid): 13(ptr) FunctionParameter
26: Label
- 77(output): 60(ptr) Variable Function
- 79: 68(ptr) AccessChain 77(output) 30 30
- Store 79 78
- 81: 68(ptr) AccessChain 77(output) 30 73
- Store 81 80
- 82:22(HS_CONSTANT_OUT) Load 77(output)
- ReturnValue 82
+ 78(output): 60(ptr) Variable Function
+ 80: 69(ptr) AccessChain 78(output) 30 30
+ Store 80 79
+ 82: 69(ptr) AccessChain 78(output) 30 74
+ Store 82 81
+ 83:22(HS_CONSTANT_OUT) Load 78(output)
+ ReturnValue 83
FunctionEnd
0:? Sequence
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 0 (const int)
0:? direct index ( temp float)
0:? 0 (const int)
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 1 (const int)
0:? direct index ( temp float)
0:? 'pos' ( in 4-component vector of float Position)
0:? 'InvocationId' ( in uint InvocationID)
0:? '@patchConstantOutput' (layout( location=1) patch out structure{})
-0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter)
Linked tessellation control stage:
0:? Sequence
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 0 (const int)
0:? direct index ( temp float)
0:? 0 (const int)
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 1 (const int)
0:? direct index ( temp float)
0:? 'pos' ( in 4-component vector of float Position)
0:? 'InvocationId' ( in uint InvocationID)
0:? '@patchConstantOutput' (layout( location=1) patch out structure{})
-0:? '@patchConstantOutput_edges' ( patch out 2-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_edges' ( patch out 4-element array of float TessLevelOuter)
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 90
+// Id's are bound by 91
Capability Tessellation
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint TessellationControl 4 "main" 42 45 52 60 62 69 89
+ EntryPoint TessellationControl 4 "main" 42 45 52 60 62 70 90
ExecutionMode 4 OutputVertices 4
Name 4 "main"
Name 8 "VS_OUT"
Name 62 "pos"
Name 63 "param"
Name 65 "param"
- Name 69 "@patchConstantOutput_edges"
- Name 79 "output"
- Name 87 "HS_CONSTANT_OUT"
- Name 89 "@patchConstantOutput"
+ Name 70 "@patchConstantOutput_edges"
+ Name 80 "output"
+ Name 88 "HS_CONSTANT_OUT"
+ Name 90 "@patchConstantOutput"
Decorate 42(ip) Location 0
Decorate 45(@entryPointOutput) Location 0
Decorate 52(InvocationId) BuiltIn InvocationId
Decorate 60(pid) BuiltIn PrimitiveId
Decorate 62(pos) BuiltIn Position
- Decorate 69(@patchConstantOutput_edges) Patch
- Decorate 69(@patchConstantOutput_edges) BuiltIn TessLevelOuter
- Decorate 89(@patchConstantOutput) Patch
- Decorate 89(@patchConstantOutput) Location 1
+ Decorate 70(@patchConstantOutput_edges) Patch
+ Decorate 70(@patchConstantOutput_edges) BuiltIn TessLevelOuter
+ Decorate 90(@patchConstantOutput) Patch
+ Decorate 90(@patchConstantOutput) Location 1
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
60(pid): 51(ptr) Variable Input
61: TypePointer Input 19(fvec4)
62(pos): 61(ptr) Variable Input
- 68: TypePointer Output 22
-69(@patchConstantOutput_edges): 68(ptr) Variable Output
- 70: TypePointer Function 6(float)
- 73: TypePointer Output 6(float)
- 75: 31(int) Constant 1
- 80: 6(float) Constant 1073741824
- 82: 6(float) Constant 1090519040
-87(HS_CONSTANT_OUT): TypeStruct
- 88: TypePointer Output 87(HS_CONSTANT_OUT)
-89(@patchConstantOutput): 88(ptr) Variable Output
+ 68: TypeArray 6(float) 10
+ 69: TypePointer Output 68
+70(@patchConstantOutput_edges): 69(ptr) Variable Output
+ 71: TypePointer Function 6(float)
+ 74: TypePointer Output 6(float)
+ 76: 31(int) Constant 1
+ 81: 6(float) Constant 1073741824
+ 83: 6(float) Constant 1090519040
+88(HS_CONSTANT_OUT): TypeStruct
+ 89: TypePointer Output 88(HS_CONSTANT_OUT)
+90(@patchConstantOutput): 89(ptr) Variable Output
4(main): 2 Function None 3
5: Label
40(ip): 12(ptr) Variable Function
Store 65(param) 66
67:23(HS_CONSTANT_OUT) FunctionCall 27(PCF(u1;vf4;) 63(param) 65(param)
Store 59(@patchConstantResult) 67
- 71: 70(ptr) AccessChain 59(@patchConstantResult) 32 32
- 72: 6(float) Load 71
- 74: 73(ptr) AccessChain 69(@patchConstantOutput_edges) 32
- Store 74 72
- 76: 70(ptr) AccessChain 59(@patchConstantResult) 32 75
- 77: 6(float) Load 76
- 78: 73(ptr) AccessChain 69(@patchConstantOutput_edges) 75
- Store 78 77
+ 72: 71(ptr) AccessChain 59(@patchConstantResult) 32 32
+ 73: 6(float) Load 72
+ 75: 74(ptr) AccessChain 70(@patchConstantOutput_edges) 32
+ Store 75 73
+ 77: 71(ptr) AccessChain 59(@patchConstantResult) 32 76
+ 78: 6(float) Load 77
+ 79: 74(ptr) AccessChain 70(@patchConstantOutput_edges) 76
+ Store 79 78
Branch 57
57: Label
Return
25(pid): 18(ptr) FunctionParameter
26(pos): 20(ptr) FunctionParameter
28: Label
- 79(output): 58(ptr) Variable Function
- 81: 70(ptr) AccessChain 79(output) 32 32
- Store 81 80
- 83: 70(ptr) AccessChain 79(output) 32 75
- Store 83 82
- 84:23(HS_CONSTANT_OUT) Load 79(output)
- ReturnValue 84
+ 80(output): 58(ptr) Variable Function
+ 82: 71(ptr) AccessChain 80(output) 32 32
+ Store 82 81
+ 84: 71(ptr) AccessChain 80(output) 32 76
+ Store 84 83
+ 85:23(HS_CONSTANT_OUT) Load 80(output)
+ ReturnValue 85
FunctionEnd
0:? Sequence
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 0 (const int)
0:? direct index ( temp float)
0:? 0 (const int)
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 1 (const int)
0:? direct index ( temp float)
0:? 1 (const int)
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 2 (const int)
0:? direct index ( temp float)
0:? Constant:
0:? 2 (const int)
0:? move second child to first child ( temp float)
-0:? '@patchConstantOutput_flInFactor' ( patch out float TessLevelInner)
+0:? direct index ( patch out float TessLevelInner)
+0:? '@patchConstantOutput_flInFactor' ( patch out 2-element array of float TessLevelInner)
+0:? Constant:
+0:? 0 (const int)
0:? flInFactor: direct index for structure ( temp float)
0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor})
0:? Constant:
0:? 'i' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float val})
0:? 'cpid' ( in uint InvocationID)
0:? '@patchConstantOutput' (layout( location=1) patch out structure{})
-0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter)
-0:? '@patchConstantOutput_flInFactor' ( patch out float TessLevelInner)
+0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_flInFactor' ( patch out 2-element array of float TessLevelInner)
Linked tessellation control stage:
0:? Sequence
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 0 (const int)
0:? direct index ( temp float)
0:? 0 (const int)
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 1 (const int)
0:? direct index ( temp float)
0:? 1 (const int)
0:? move second child to first child ( temp float)
0:? direct index ( patch out float TessLevelOuter)
-0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter)
0:? Constant:
0:? 2 (const int)
0:? direct index ( temp float)
0:? Constant:
0:? 2 (const int)
0:? move second child to first child ( temp float)
-0:? '@patchConstantOutput_flInFactor' ( patch out float TessLevelInner)
+0:? direct index ( patch out float TessLevelInner)
+0:? '@patchConstantOutput_flInFactor' ( patch out 2-element array of float TessLevelInner)
+0:? Constant:
+0:? 0 (const int)
0:? flInFactor: direct index for structure ( temp float)
0:? '@patchConstantResult' ( temp structure{ temp 3-element array of float tfactor, temp float flInFactor})
0:? Constant:
0:? 'i' (layout( location=0) in 3-element array of structure{ temp 3-component vector of float val})
0:? 'cpid' ( in uint InvocationID)
0:? '@patchConstantOutput' (layout( location=1) patch out structure{})
-0:? '@patchConstantOutput_tfactor' ( patch out 3-element array of float TessLevelOuter)
-0:? '@patchConstantOutput_flInFactor' ( patch out float TessLevelInner)
+0:? '@patchConstantOutput_tfactor' ( patch out 4-element array of float TessLevelOuter)
+0:? '@patchConstantOutput_flInFactor' ( patch out 2-element array of float TessLevelInner)
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 119
+// Id's are bound by 124
Capability Tessellation
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
- EntryPoint TessellationControl 4 "main" 41 45 48 89 101 118
+ EntryPoint TessellationControl 4 "main" 41 45 48 91 105 123
ExecutionMode 4 OutputVertices 3
Name 4 "main"
Name 8 "hs_in_t"
Name 79 "param"
Name 81 "param"
Name 85 "@patchConstantResult"
- Name 89 "@patchConstantOutput_tfactor"
- Name 101 "@patchConstantOutput_flInFactor"
- Name 104 "o"
- Name 116 "hs_pcf_t"
- Name 118 "@patchConstantOutput"
+ Name 91 "@patchConstantOutput_tfactor"
+ Name 105 "@patchConstantOutput_flInFactor"
+ Name 109 "o"
+ Name 121 "hs_pcf_t"
+ Name 123 "@patchConstantOutput"
Decorate 41(i) Location 0
Decorate 45(cpid) BuiltIn InvocationId
Decorate 48(@entryPointOutput) Location 0
- Decorate 89(@patchConstantOutput_tfactor) Patch
- Decorate 89(@patchConstantOutput_tfactor) BuiltIn TessLevelOuter
- Decorate 101(@patchConstantOutput_flInFactor) Patch
- Decorate 101(@patchConstantOutput_flInFactor) BuiltIn TessLevelInner
- Decorate 118(@patchConstantOutput) Patch
- Decorate 118(@patchConstantOutput) Location 1
+ Decorate 91(@patchConstantOutput_tfactor) Patch
+ Decorate 91(@patchConstantOutput_tfactor) BuiltIn TessLevelOuter
+ Decorate 105(@patchConstantOutput_flInFactor) Patch
+ Decorate 105(@patchConstantOutput_flInFactor) BuiltIn TessLevelInner
+ Decorate 123(@patchConstantOutput) Patch
+ Decorate 123(@patchConstantOutput) Location 1
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
70: 29(int) Constant 1
77: 29(int) Constant 2
84: TypePointer Function 22(hs_pcf_t)
- 88: TypePointer Output 21
-89(@patchConstantOutput_tfactor): 88(ptr) Variable Output
- 90: TypePointer Function 6(float)
- 93: TypePointer Output 6(float)
-101(@patchConstantOutput_flInFactor): 93(ptr) Variable Output
- 111: 6(float) Constant 1082130432
- 116(hs_pcf_t): TypeStruct
- 117: TypePointer Output 116(hs_pcf_t)
-118(@patchConstantOutput): 117(ptr) Variable Output
+ 88: 9(int) Constant 4
+ 89: TypeArray 6(float) 88
+ 90: TypePointer Output 89
+91(@patchConstantOutput_tfactor): 90(ptr) Variable Output
+ 92: TypePointer Function 6(float)
+ 95: TypePointer Output 6(float)
+ 103: TypeArray 6(float) 54
+ 104: TypePointer Output 103
+105(@patchConstantOutput_flInFactor): 104(ptr) Variable Output
+ 116: 6(float) Constant 1082130432
+ 121(hs_pcf_t): TypeStruct
+ 122: TypePointer Output 121(hs_pcf_t)
+123(@patchConstantOutput): 122(ptr) Variable Output
4(main): 2 Function None 3
5: Label
39(i): 12(ptr) Variable Function
86: 20 Load 63(pcf_out)
87:22(hs_pcf_t) FunctionCall 25(PCF(struct-hs_out_t-vf31[3];) 86
Store 85(@patchConstantResult) 87
- 91: 90(ptr) AccessChain 85(@patchConstantResult) 30 30
- 92: 6(float) Load 91
- 94: 93(ptr) AccessChain 89(@patchConstantOutput_tfactor) 30
- Store 94 92
- 95: 90(ptr) AccessChain 85(@patchConstantResult) 30 70
- 96: 6(float) Load 95
- 97: 93(ptr) AccessChain 89(@patchConstantOutput_tfactor) 70
- Store 97 96
- 98: 90(ptr) AccessChain 85(@patchConstantResult) 30 77
- 99: 6(float) Load 98
- 100: 93(ptr) AccessChain 89(@patchConstantOutput_tfactor) 77
- Store 100 99
- 102: 90(ptr) AccessChain 85(@patchConstantResult) 70
- 103: 6(float) Load 102
- Store 101(@patchConstantOutput_flInFactor) 103
+ 93: 92(ptr) AccessChain 85(@patchConstantResult) 30 30
+ 94: 6(float) Load 93
+ 96: 95(ptr) AccessChain 91(@patchConstantOutput_tfactor) 30
+ Store 96 94
+ 97: 92(ptr) AccessChain 85(@patchConstantResult) 30 70
+ 98: 6(float) Load 97
+ 99: 95(ptr) AccessChain 91(@patchConstantOutput_tfactor) 70
+ Store 99 98
+ 100: 92(ptr) AccessChain 85(@patchConstantResult) 30 77
+ 101: 6(float) Load 100
+ 102: 95(ptr) AccessChain 91(@patchConstantOutput_tfactor) 77
+ Store 102 101
+ 106: 92(ptr) AccessChain 85(@patchConstantResult) 70
+ 107: 6(float) Load 106
+ 108: 95(ptr) AccessChain 105(@patchConstantOutput_flInFactor) 30
+ Store 108 107
Branch 61
61: Label
Return
25(PCF(struct-hs_out_t-vf31[3];):22(hs_pcf_t) Function None 23
24(pcf_out): 20 FunctionParameter
26: Label
- 104(o): 84(ptr) Variable Function
- 105: 6(float) CompositeExtract 24(pcf_out) 0 0 0
- 106: 90(ptr) AccessChain 104(o) 30 30
- Store 106 105
- 107: 6(float) CompositeExtract 24(pcf_out) 1 0 0
- 108: 90(ptr) AccessChain 104(o) 30 70
- Store 108 107
- 109: 6(float) CompositeExtract 24(pcf_out) 2 0 0
- 110: 90(ptr) AccessChain 104(o) 30 77
- Store 110 109
- 112: 90(ptr) AccessChain 104(o) 70
- Store 112 111
- 113:22(hs_pcf_t) Load 104(o)
- ReturnValue 113
+ 109(o): 84(ptr) Variable Function
+ 110: 6(float) CompositeExtract 24(pcf_out) 0 0 0
+ 111: 92(ptr) AccessChain 109(o) 30 30
+ Store 111 110
+ 112: 6(float) CompositeExtract 24(pcf_out) 1 0 0
+ 113: 92(ptr) AccessChain 109(o) 30 70
+ Store 113 112
+ 114: 6(float) CompositeExtract 24(pcf_out) 2 0 0
+ 115: 92(ptr) AccessChain 109(o) 30 77
+ Store 115 114
+ 117: 92(ptr) AccessChain 109(o) 70
+ Store 117 116
+ 118:22(hs_pcf_t) Load 109(o)
+ ReturnValue 118
FunctionEnd
struct hs_pcf_t
{
- float tfactor[3] : SV_TessFactor;
- float flInFactor : SV_InsideTessFactor;
+ float tfactor[3] : SV_TessFactor; // must turn into a size 4 array in SPIR-V
+ float flInFactor : SV_InsideTessFactor; // must turn into a size 2 array in SPIR-V
};
struct hs_out_t
if (arraySizes)
ioVar->getWritableType().newArraySizes(*arraySizes);
+ fixBuiltInArrayType(ioVar->getWritableType());
+
interstageBuiltInIo[tInterstageIoData(memberType, *outerStructType)] = ioVar;
// Merge qualifier from the user structure
}
+// Some types require fixed array sizes in SPIR-V, but can be scalars or
+// arrays of sizes SPIR-V doesn't allow. For example, tessellation factors.
+// This creates the right size. A conversion is performed when the internal
+// type is copied to or from the external
+void HlslParseContext::fixBuiltInArrayType(TType& type)
+{
+ int requiredSize = 0;
+
+ switch (type.getQualifier().builtIn) {
+ case EbvTessLevelOuter: requiredSize = 4; break;
+ case EbvTessLevelInner: requiredSize = 2; break;
+ case EbvClipDistance: // TODO: ...
+ case EbvCullDistance: // TODO: ...
+ default:
+ return;
+ }
+
+ if (type.isArray()) {
+ // Already an array. Fix the size.
+ type.changeOuterArraySize(requiredSize);
+ } else {
+ // it wasn't an array, but needs to be.
+ TArraySizes arraySizes;
+ arraySizes.addInnerSize(requiredSize);
+ type.newArraySizes(arraySizes);
+ }
+}
+
// 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).
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;
+
+ // Index operator if it's an aggregate, else EOpNull
+ const TOperator op = node->getType().isArray() ? EOpIndexDirect :
+ node->getType().isStruct() ? EOpIndexDirectStruct : EOpNull;
+
const TType derefType(node->getType(), member);
if (split && derefType.isBuiltInInterstageIO(language)) {
} else if (flattened && isFinalFlattening(derefType)) {
subTree = intermediate.addSymbol(*flatVariables[memberIdx++]);
} else {
- const TType splitDerefType(splitNode->getType(), splitMember);
+ if (op == EOpNull) {
+ subTree = splitNode;
+ } else {
+ const TType splitDerefType(splitNode->getType(), splitMember);
- subTree = intermediate.addIndex(op, splitNode, intermediate.addConstantUnion(splitMember, loc), loc);
- subTree->setType(splitDerefType);
+ subTree = intermediate.addIndex(op, splitNode, intermediate.addConstantUnion(splitMember, loc), loc);
+ subTree->setType(splitDerefType);
+ }
}
return subTree;
// 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);
+ if (left->getType().isArray() || right->getType().isArray()) {
+ const int elementsL = left->getType().isArray() ? left->getType().getOuterArraySize() : 1;
+ const int elementsR = right->getType().isArray() ? right->getType().getOuterArraySize() : 1;
+
+ // The arrays may not be the same size, e.g, if the size has been forced for EbvTe\ 1ssLevelInner or Outer.
+ const int elementsToCopy = std::min(elementsL, elementsR);
// array case
- for (int element=0; element < left->getType().getOuterArraySize(); ++element) {
+ for (int element=0; element < elementsToCopy; ++element) {
arrayElement.push_back(element);
// Add a new AST symbol node if we have a temp variable holding a complex RHS.
TIntermTyped* subSplitLeft = isSplitLeft ? getMember(true, left, element, splitLeft, element) : subLeft;
TIntermTyped* subSplitRight = isSplitRight ? getMember(false, right, element, splitRight, element) : subRight;
- if (isFinalFlattening(dereferencedType))
- assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subLeft, subRight, loc), loc);
- else
- traverse(subLeft, subRight, subSplitLeft, subSplitRight);
+ traverse(subLeft, subRight, subSplitLeft, subSplitRight);
arrayElement.pop_back();
}
// 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(language) && !typeR.containsBuiltInInterstageIO(language))) {
+ if ((!isFlattenLeft && !isFlattenRight &&
+ !typeL.containsBuiltInInterstageIO(language) && !typeR.containsBuiltInInterstageIO(language))) {
assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, subSplitLeft, subSplitRight, loc), loc);
} else {
traverse(subLeft, subRight, subSplitLeft, subSplitRight);
memberR += (typeR.isBuiltInInterstageIO(language) ? 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.
+ // Member copy
+ assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, left, right, loc), loc);
}
};
void addInterstageIoToLinkage();
void addPatchConstantInvocation();
+ void fixBuiltInArrayType(TType&);
+
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);