Merge pull request #1379 from LoopDawg/groupid-fix

HLSL: various SPIR-V compute shader IDs must be 3-vectors of integers
diff --git a/Test/baseResults/hlsl.basic.comp.out b/Test/baseResults/hlsl.basic.comp.out
index 48cd680..884c64c 100755
--- a/Test/baseResults/hlsl.basic.comp.out
+++ b/Test/baseResults/hlsl.basic.comp.out
@@ -15,17 +15,19 @@
 0:?     Sequence
 0:4      move second child to first child ( temp int)
 0:?         'dti' ( temp int)
-0:?         'dti' ( in int GlobalInvocationID)
+0:?         Construct int ( temp int)
+0:?           'dti' ( in 3-component vector of int GlobalInvocationID)
 0:4      move second child to first child ( temp int)
 0:?         'gti' ( temp int)
-0:?         'gti' ( in int LocalInvocationID)
+0:?         Construct int ( temp int)
+0:?           'gti' ( in 3-component vector of int LocalInvocationID)
 0:4      Function Call: @main(i1;i1; ( temp void)
 0:?         'dti' ( temp int)
 0:?         'gti' ( temp int)
 0:?   Linker Objects
 0:?     'a' ( shared 100-element array of 4-component vector of float)
-0:?     'dti' ( in int GlobalInvocationID)
-0:?     'gti' ( in int LocalInvocationID)
+0:?     'dti' ( in 3-component vector of int GlobalInvocationID)
+0:?     'gti' ( in 3-component vector of int LocalInvocationID)
 
 
 Linked compute stage:
@@ -47,26 +49,28 @@
 0:?     Sequence
 0:4      move second child to first child ( temp int)
 0:?         'dti' ( temp int)
-0:?         'dti' ( in int GlobalInvocationID)
+0:?         Construct int ( temp int)
+0:?           'dti' ( in 3-component vector of int GlobalInvocationID)
 0:4      move second child to first child ( temp int)
 0:?         'gti' ( temp int)
-0:?         'gti' ( in int LocalInvocationID)
+0:?         Construct int ( temp int)
+0:?           'gti' ( in 3-component vector of int LocalInvocationID)
 0:4      Function Call: @main(i1;i1; ( temp void)
 0:?         'dti' ( temp int)
 0:?         'gti' ( temp int)
 0:?   Linker Objects
 0:?     'a' ( shared 100-element array of 4-component vector of float)
-0:?     'dti' ( in int GlobalInvocationID)
-0:?     'gti' ( in int LocalInvocationID)
+0:?     'dti' ( in 3-component vector of int GlobalInvocationID)
+0:?     'gti' ( in 3-component vector of int LocalInvocationID)
 
 // Module Version 10000
 // Generated by (magic number): 80006
-// Id's are bound by 35
+// Id's are bound by 38
 
                               Capability Shader
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint GLCompute 4  "main" 18 21
+                              EntryPoint GLCompute 4  "main" 19 23
                               ExecutionMode 4 LocalSize 1 1 1
                               Source HLSL 500
                               Name 4  "main"
@@ -74,44 +78,47 @@
                               Name 9  "dti"
                               Name 10  "gti"
                               Name 16  "dti"
-                              Name 18  "dti"
-                              Name 20  "gti"
-                              Name 21  "gti"
-                              Name 23  "param"
-                              Name 25  "param"
-                              Name 34  "a"
-                              Decorate 18(dti) BuiltIn GlobalInvocationId
-                              Decorate 21(gti) BuiltIn LocalInvocationId
+                              Name 19  "dti"
+                              Name 22  "gti"
+                              Name 23  "gti"
+                              Name 26  "param"
+                              Name 28  "param"
+                              Name 37  "a"
+                              Decorate 19(dti) BuiltIn GlobalInvocationId
+                              Decorate 23(gti) BuiltIn LocalInvocationId
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeInt 32 1
                7:             TypePointer Function 6(int)
                8:             TypeFunction 2 7(ptr) 7(ptr)
-              17:             TypePointer Input 6(int)
-         18(dti):     17(ptr) Variable Input
-         21(gti):     17(ptr) Variable Input
-              28:             TypeFloat 32
-              29:             TypeVector 28(float) 4
-              30:             TypeInt 32 0
-              31:     30(int) Constant 100
-              32:             TypeArray 29(fvec4) 31
-              33:             TypePointer Workgroup 32
-           34(a):     33(ptr) Variable Workgroup
+              17:             TypeVector 6(int) 3
+              18:             TypePointer Input 17(ivec3)
+         19(dti):     18(ptr) Variable Input
+         23(gti):     18(ptr) Variable Input
+              31:             TypeFloat 32
+              32:             TypeVector 31(float) 4
+              33:             TypeInt 32 0
+              34:     33(int) Constant 100
+              35:             TypeArray 32(fvec4) 34
+              36:             TypePointer Workgroup 35
+           37(a):     36(ptr) Variable Workgroup
          4(main):           2 Function None 3
                5:             Label
          16(dti):      7(ptr) Variable Function
-         20(gti):      7(ptr) Variable Function
-       23(param):      7(ptr) Variable Function
-       25(param):      7(ptr) Variable Function
-              19:      6(int) Load 18(dti)
-                              Store 16(dti) 19
-              22:      6(int) Load 21(gti)
-                              Store 20(gti) 22
-              24:      6(int) Load 16(dti)
-                              Store 23(param) 24
-              26:      6(int) Load 20(gti)
-                              Store 25(param) 26
-              27:           2 FunctionCall 11(@main(i1;i1;) 23(param) 25(param)
+         22(gti):      7(ptr) Variable Function
+       26(param):      7(ptr) Variable Function
+       28(param):      7(ptr) Variable Function
+              20:   17(ivec3) Load 19(dti)
+              21:      6(int) CompositeExtract 20 0
+                              Store 16(dti) 21
+              24:   17(ivec3) Load 23(gti)
+              25:      6(int) CompositeExtract 24 0
+                              Store 22(gti) 25
+              27:      6(int) Load 16(dti)
+                              Store 26(param) 27
+              29:      6(int) Load 22(gti)
+                              Store 28(param) 29
+              30:           2 FunctionCall 11(@main(i1;i1;) 26(param) 28(param)
                               Return
                               FunctionEnd
 11(@main(i1;i1;):           2 Function None 8
diff --git a/Test/baseResults/hlsl.groupid.comp.out b/Test/baseResults/hlsl.groupid.comp.out
new file mode 100644
index 0000000..3404551
--- /dev/null
+++ b/Test/baseResults/hlsl.groupid.comp.out
@@ -0,0 +1,146 @@
+hlsl.groupid.comp
+Shader version: 500
+local_size = (8, 8, 1)
+0:? Sequence
+0:7  Function Definition: @main(vu2; ( temp void)
+0:7    Function Parameters: 
+0:7      'vGroupId' ( in 2-component vector of uint)
+0:?     Sequence
+0:8      Sequence
+0:8        move second child to first child ( temp 4-component vector of float)
+0:8          'storeTemp' ( temp 4-component vector of float)
+0:?           Constant:
+0:?             1.000000
+0:?             0.000000
+0:?             0.000000
+0:?             1.000000
+0:8        imageStore ( temp void)
+0:8          'OutputTexture' (layout( rgba32f) uniform image2D)
+0:8          vector swizzle ( temp 2-component vector of uint)
+0:8            'vGroupId' ( in 2-component vector of uint)
+0:8            Sequence
+0:8              Constant:
+0:8                0 (const int)
+0:8              Constant:
+0:8                1 (const int)
+0:8          'storeTemp' ( temp 4-component vector of float)
+0:8        'storeTemp' ( temp 4-component vector of float)
+0:7  Function Definition: main( ( temp void)
+0:7    Function Parameters: 
+0:?     Sequence
+0:7      move second child to first child ( temp 2-component vector of uint)
+0:?         'vGroupId' ( temp 2-component vector of uint)
+0:?         Construct uvec2 ( temp 2-component vector of uint)
+0:?           'vGroupId' ( in 3-component vector of uint WorkGroupID)
+0:7      Function Call: @main(vu2; ( temp void)
+0:?         'vGroupId' ( temp 2-component vector of uint)
+0:?   Linker Objects
+0:?     'OutputTexture' (layout( rgba32f) uniform image2D)
+0:?     'vGroupId' ( in 3-component vector of uint WorkGroupID)
+
+
+Linked compute stage:
+
+
+Shader version: 500
+local_size = (8, 8, 1)
+0:? Sequence
+0:7  Function Definition: @main(vu2; ( temp void)
+0:7    Function Parameters: 
+0:7      'vGroupId' ( in 2-component vector of uint)
+0:?     Sequence
+0:8      Sequence
+0:8        move second child to first child ( temp 4-component vector of float)
+0:8          'storeTemp' ( temp 4-component vector of float)
+0:?           Constant:
+0:?             1.000000
+0:?             0.000000
+0:?             0.000000
+0:?             1.000000
+0:8        imageStore ( temp void)
+0:8          'OutputTexture' (layout( rgba32f) uniform image2D)
+0:8          vector swizzle ( temp 2-component vector of uint)
+0:8            'vGroupId' ( in 2-component vector of uint)
+0:8            Sequence
+0:8              Constant:
+0:8                0 (const int)
+0:8              Constant:
+0:8                1 (const int)
+0:8          'storeTemp' ( temp 4-component vector of float)
+0:8        'storeTemp' ( temp 4-component vector of float)
+0:7  Function Definition: main( ( temp void)
+0:7    Function Parameters: 
+0:?     Sequence
+0:7      move second child to first child ( temp 2-component vector of uint)
+0:?         'vGroupId' ( temp 2-component vector of uint)
+0:?         Construct uvec2 ( temp 2-component vector of uint)
+0:?           'vGroupId' ( in 3-component vector of uint WorkGroupID)
+0:7      Function Call: @main(vu2; ( temp void)
+0:?         'vGroupId' ( temp 2-component vector of uint)
+0:?   Linker Objects
+0:?     'OutputTexture' (layout( rgba32f) uniform image2D)
+0:?     'vGroupId' ( in 3-component vector of uint WorkGroupID)
+
+// Module Version 10000
+// Generated by (magic number): 80006
+// Id's are bound by 37
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint GLCompute 4  "main" 29
+                              ExecutionMode 4 LocalSize 8 8 1
+                              Source HLSL 500
+                              Name 4  "main"
+                              Name 11  "@main(vu2;"
+                              Name 10  "vGroupId"
+                              Name 16  "storeTemp"
+                              Name 22  "OutputTexture"
+                              Name 26  "vGroupId"
+                              Name 29  "vGroupId"
+                              Name 34  "param"
+                              Decorate 22(OutputTexture) DescriptorSet 0
+                              Decorate 29(vGroupId) BuiltIn WorkgroupId
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 0
+               7:             TypeVector 6(int) 2
+               8:             TypePointer Function 7(ivec2)
+               9:             TypeFunction 2 8(ptr)
+              13:             TypeFloat 32
+              14:             TypeVector 13(float) 4
+              15:             TypePointer Function 14(fvec4)
+              17:   13(float) Constant 1065353216
+              18:   13(float) Constant 0
+              19:   14(fvec4) ConstantComposite 17 18 18 17
+              20:             TypeImage 13(float) 2D nonsampled format:Rgba32f
+              21:             TypePointer UniformConstant 20
+22(OutputTexture):     21(ptr) Variable UniformConstant
+              27:             TypeVector 6(int) 3
+              28:             TypePointer Input 27(ivec3)
+    29(vGroupId):     28(ptr) Variable Input
+         4(main):           2 Function None 3
+               5:             Label
+    26(vGroupId):      8(ptr) Variable Function
+       34(param):      8(ptr) Variable Function
+              30:   27(ivec3) Load 29(vGroupId)
+              31:      6(int) CompositeExtract 30 0
+              32:      6(int) CompositeExtract 30 1
+              33:    7(ivec2) CompositeConstruct 31 32
+                              Store 26(vGroupId) 33
+              35:    7(ivec2) Load 26(vGroupId)
+                              Store 34(param) 35
+              36:           2 FunctionCall 11(@main(vu2;) 34(param)
+                              Return
+                              FunctionEnd
+  11(@main(vu2;):           2 Function None 9
+    10(vGroupId):      8(ptr) FunctionParameter
+              12:             Label
+   16(storeTemp):     15(ptr) Variable Function
+                              Store 16(storeTemp) 19
+              23:          20 Load 22(OutputTexture)
+              24:    7(ivec2) Load 10(vGroupId)
+              25:   14(fvec4) Load 16(storeTemp)
+                              ImageWrite 23 24 25
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/hlsl.structbuffer.fn2.comp.out b/Test/baseResults/hlsl.structbuffer.fn2.comp.out
index 95f2b85..ca5a980 100644
--- a/Test/baseResults/hlsl.structbuffer.fn2.comp.out
+++ b/Test/baseResults/hlsl.structbuffer.fn2.comp.out
@@ -56,13 +56,14 @@
 0:?     Sequence
 0:12      move second child to first child ( temp uint)
 0:?         'dispatchId' ( temp uint)
-0:?         'dispatchId' ( in uint GlobalInvocationID)
+0:?         Construct uint ( temp uint)
+0:?           'dispatchId' ( in 3-component vector of uint GlobalInvocationID)
 0:12      Function Call: @main(u1; ( temp void)
 0:?         'dispatchId' ( temp uint)
 0:?   Linker Objects
 0:?     'g_input' (layout( binding=0 row_major std430) readonly buffer block{layout( row_major std430) buffer unsized 1-element array of uint @data})
 0:?     'g_output' (layout( binding=1 rg32ui) uniform uimageBuffer)
-0:?     'dispatchId' ( in uint GlobalInvocationID)
+0:?     'dispatchId' ( in 3-component vector of uint GlobalInvocationID)
 
 
 Linked compute stage:
@@ -125,24 +126,25 @@
 0:?     Sequence
 0:12      move second child to first child ( temp uint)
 0:?         'dispatchId' ( temp uint)
-0:?         'dispatchId' ( in uint GlobalInvocationID)
+0:?         Construct uint ( temp uint)
+0:?           'dispatchId' ( in 3-component vector of uint GlobalInvocationID)
 0:12      Function Call: @main(u1; ( temp void)
 0:?         'dispatchId' ( temp uint)
 0:?   Linker Objects
 0:?     'g_input' (layout( binding=0 row_major std430) readonly buffer block{layout( row_major std430) buffer unsized 1-element array of uint @data})
 0:?     'g_output' (layout( binding=1 rg32ui) uniform uimageBuffer)
-0:?     'dispatchId' ( in uint GlobalInvocationID)
+0:?     'dispatchId' ( in 3-component vector of uint GlobalInvocationID)
 
 // Module Version 10000
 // Generated by (magic number): 80006
-// Id's are bound by 61
+// Id's are bound by 63
 
                               Capability Shader
                               Capability ImageBuffer
                               Capability StorageImageExtendedFormats
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
-                              EntryPoint GLCompute 4  "main" 56
+                              EntryPoint GLCompute 4  "main" 57
                               ExecutionMode 4 LocalSize 256 1 1
                               Source HLSL 500
                               Name 4  "main"
@@ -160,8 +162,8 @@
                               Name 45  "param"
                               Name 50  "g_output"
                               Name 54  "dispatchId"
-                              Name 56  "dispatchId"
-                              Name 58  "param"
+                              Name 57  "dispatchId"
+                              Name 60  "param"
                               Decorate 8 ArrayStride 4
                               MemberDecorate 9 0 NonWritable
                               MemberDecorate 9 0 Offset 0
@@ -171,7 +173,7 @@
                               Decorate 44(g_input) Binding 0
                               Decorate 50(g_output) DescriptorSet 0
                               Decorate 50(g_output) Binding 1
-                              Decorate 56(dispatchId) BuiltIn GlobalInvocationId
+                              Decorate 57(dispatchId) BuiltIn GlobalInvocationId
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeInt 32 0
@@ -193,17 +195,19 @@
               48:             TypeImage 6(int) Buffer nonsampled format:Rg32ui
               49:             TypePointer UniformConstant 48
     50(g_output):     49(ptr) Variable UniformConstant
-              55:             TypePointer Input 6(int)
-  56(dispatchId):     55(ptr) Variable Input
+              55:             TypeVector 6(int) 3
+              56:             TypePointer Input 55(ivec3)
+  57(dispatchId):     56(ptr) Variable Input
          4(main):           2 Function None 3
                5:             Label
   54(dispatchId):      7(ptr) Variable Function
-       58(param):      7(ptr) Variable Function
-              57:      6(int) Load 56(dispatchId)
-                              Store 54(dispatchId) 57
-              59:      6(int) Load 54(dispatchId)
-                              Store 58(param) 59
-              60:           2 FunctionCall 19(@main(u1;) 58(param)
+       60(param):      7(ptr) Variable Function
+              58:   55(ivec3) Load 57(dispatchId)
+              59:      6(int) CompositeExtract 58 0
+                              Store 54(dispatchId) 59
+              61:      6(int) Load 54(dispatchId)
+                              Store 60(param) 61
+              62:           2 FunctionCall 19(@main(u1;) 60(param)
                               Return
                               FunctionEnd
 15(testLoad(u1;block--u1[0]1;):   11(ivec2) Function None 12
diff --git a/Test/hlsl.groupid.comp b/Test/hlsl.groupid.comp
new file mode 100644
index 0000000..e5b0de4
--- /dev/null
+++ b/Test/hlsl.groupid.comp
@@ -0,0 +1,9 @@
+RWTexture2D < float4 > OutputTexture;
+
+// Test conversion between SPIR-V required uint3 group id, and sub-vec3 shader declaration.
+
+[ numthreads ( 8 , 8 , 1 ) ] 
+void main ( uint2 vGroupId : SV_GroupID ) 
+{ 
+    OutputTexture[ vGroupId . xy ] = float4(1.0, 0.0, 0.0, 1.0); 
+}
diff --git a/gtests/Hlsl.FromFile.cpp b/gtests/Hlsl.FromFile.cpp
index feeee99..7cf1cbf 100644
--- a/gtests/Hlsl.FromFile.cpp
+++ b/gtests/Hlsl.FromFile.cpp
@@ -195,6 +195,7 @@
         {"hlsl.hull.void.tesc", "main"},
         {"hlsl.hull.ctrlpt-1.tesc", "main"},
         {"hlsl.hull.ctrlpt-2.tesc", "main"},
+        {"hlsl.groupid.comp", "main"},
         {"hlsl.identifier.sample.frag", "main"},
         {"hlsl.if.frag", "PixelShaderFunction"},
         {"hlsl.imagefetch-subvec4.comp", "main"},
diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp
index 9f842b7..e6d29ea 100755
--- a/hlsl/hlslParseHelper.cpp
+++ b/hlsl/hlslParseHelper.cpp
@@ -1475,22 +1475,17 @@
 void HlslParseContext::fixBuiltInIoType(TType& type)
 {
     int requiredArraySize = 0;
+    int requiredVectorSize = 0;
 
     switch (type.getQualifier().builtIn) {
     case EbvTessLevelOuter: requiredArraySize = 4; break;
     case EbvTessLevelInner: requiredArraySize = 2; break;
 
-    case EbvTessCoord:
-        {
-            // tesscoord is always a vec3 for the IO variable, no matter the shader's
-            // declared vector size.
-            TType tessCoordType(type.getBasicType(), type.getQualifier().storage, 3);
+    case EbvWorkGroupId:        requiredVectorSize = 3; break;
+    case EbvGlobalInvocationId: requiredVectorSize = 3; break;
+    case EbvLocalInvocationId:  requiredVectorSize = 3; break;
+    case EbvTessCoord:          requiredVectorSize = 3; break;
 
-            tessCoordType.getQualifier() = type.getQualifier();
-            type.shallowCopy(tessCoordType);
-
-            break;
-        }
     default:
         if (isClipOrCullDistance(type)) {
             const int loc = type.getQualifier().layoutLocation;
@@ -1511,6 +1506,14 @@
         return;
     }
 
+    // Alter or set vector size as needed.
+    if (requiredVectorSize > 0) {
+        TType newType(type.getBasicType(), type.getQualifier().storage, requiredVectorSize);
+        newType.getQualifier() = type.getQualifier();
+
+        type.shallowCopy(newType);
+    }
+
     // Alter or set array size as needed.
     if (requiredArraySize > 0) {
         if (!type.isArray() || type.getOuterArraySize() != requiredArraySize) {