HLSL: require tessellation factors to be fixed size arrays
authorsteve-lunarg <steve_gh@khasekhemwy.net>
Sat, 18 Mar 2017 00:51:05 +0000 (18:51 -0600)
committersteve-lunarg <steve_gh@khasekhemwy.net>
Thu, 30 Mar 2017 20:37:02 +0000 (14:37 -0600)
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.

Test/baseResults/hlsl.hull.1.tesc.out
Test/baseResults/hlsl.hull.2.tesc.out
Test/baseResults/hlsl.hull.ctrlpt-1.tesc.out
Test/hlsl.hull.ctrlpt-1.tesc
hlsl/hlslParseHelper.cpp
hlsl/hlslParseHelper.h

index a9f6386..e6f965c 100644 (file)
@@ -51,7 +51,7 @@ vertices = 4
 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)
@@ -63,7 +63,7 @@ vertices = 4
 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)
@@ -105,7 +105,7 @@ vertices = 4
 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:
@@ -163,7 +163,7 @@ vertices = 4
 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)
@@ -175,7 +175,7 @@ vertices = 4
 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)
@@ -217,16 +217,16 @@ vertices = 4
 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"
@@ -251,18 +251,18 @@ vertices = 4
                               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
@@ -294,16 +294,17 @@ vertices = 4
               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
@@ -332,14 +333,14 @@ vertices = 4
                                 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
@@ -359,11 +360,11 @@ vertices = 4
      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
index b66ead0..8ad1308 100644 (file)
@@ -47,7 +47,7 @@ vertices = 4
 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)
@@ -59,7 +59,7 @@ vertices = 4
 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)
@@ -103,7 +103,7 @@ vertices = 4
 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:
@@ -157,7 +157,7 @@ vertices = 4
 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)
@@ -169,7 +169,7 @@ vertices = 4
 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)
@@ -213,16 +213,16 @@ vertices = 4
 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"
@@ -247,19 +247,19 @@ vertices = 4
                               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
@@ -295,16 +295,17 @@ vertices = 4
          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
@@ -330,14 +331,14 @@ vertices = 4
                                 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
@@ -357,11 +358,11 @@ vertices = 4
          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
index a6c202b..b408975 100644 (file)
@@ -74,7 +74,7 @@ vertices = 3
 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)
@@ -86,7 +86,7 @@ vertices = 3
 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)
@@ -98,7 +98,7 @@ vertices = 3
 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)
@@ -109,7 +109,10 @@ vertices = 3
 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:
@@ -186,8 +189,8 @@ vertices = 3
 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:
@@ -268,7 +271,7 @@ vertices = 3
 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)
@@ -280,7 +283,7 @@ vertices = 3
 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)
@@ -292,7 +295,7 @@ vertices = 3
 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)
@@ -303,7 +306,10 @@ vertices = 3
 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:
@@ -380,17 +386,17 @@ vertices = 3
 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"
@@ -424,20 +430,20 @@ vertices = 3
                               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
@@ -472,15 +478,19 @@ vertices = 3
               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
@@ -535,21 +545,22 @@ vertices = 3
               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
@@ -570,18 +581,18 @@ vertices = 3
 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
index 389c7cb..3e329f2 100644 (file)
@@ -9,8 +9,8 @@ struct hs_in_t
 
 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
index 7ce6544..d643463 100755 (executable)
@@ -1047,6 +1047,8 @@ TType& HlslParseContext::split(TType& type, TString name, const TType* outerStru
             if (arraySizes)
                 ioVar->getWritableType().newArraySizes(*arraySizes);
 
+            fixBuiltInArrayType(ioVar->getWritableType());
+
             interstageBuiltInIo[tInterstageIoData(memberType, *outerStructType)] = ioVar;
 
             // Merge qualifier from the user structure
@@ -1381,6 +1383,34 @@ void HlslParseContext::trackLinkage(TSymbol& symbol)
 }
 
 
+// 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).
@@ -2031,7 +2061,11 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
         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)) {
@@ -2047,10 +2081,14 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
         } 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;
@@ -2069,11 +2107,15 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
         // 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.
@@ -2083,10 +2125,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
                 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();
             }
@@ -2120,8 +2159,8 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
                 // 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);
@@ -2131,8 +2170,8 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
                 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);
         }
 
     };
index f5f2d07..3ace114 100755 (executable)
@@ -248,6 +248,8 @@ protected:
     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);