Merge pull request #1756 from KhronosGroup/fix-1753

HLSL: Fix NumWorkgroups for SPIR-V 1.4+
diff --git a/main.cpp b/main.cpp
index e5b4e3a..6cb539c 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1407,12 +1407,7 @@
 	if (args.hlsl)
 	{
 		auto *hlsl_compiler = static_cast<CompilerHLSL *>(compiler.get());
-		uint32_t new_builtin = hlsl_compiler->remap_num_workgroups_builtin();
-		if (new_builtin)
-		{
-			hlsl_compiler->set_decoration(new_builtin, DecorationDescriptorSet, 0);
-			hlsl_compiler->set_decoration(new_builtin, DecorationBinding, 0);
-		}
+		hlsl_compiler->remap_num_workgroups_builtin();
 	}
 
 	if (args.hlsl)
diff --git a/reference/opt/shaders-hlsl/comp/num-workgroups-alone.comp b/reference/opt/shaders-hlsl/comp/num-workgroups-alone.comp
index dc87dc8..ff71a0e 100644
--- a/reference/opt/shaders-hlsl/comp/num-workgroups-alone.comp
+++ b/reference/opt/shaders-hlsl/comp/num-workgroups-alone.comp
@@ -1,7 +1,7 @@
 static const uint3 gl_WorkGroupSize = uint3(1u, 1u, 1u);
 
 RWByteAddressBuffer _10 : register(u0);
-cbuffer SPIRV_Cross_NumWorkgroups : register(b0)
+cbuffer SPIRV_Cross_NumWorkgroups
 {
     uint3 SPIRV_Cross_NumWorkgroups_1_count : packoffset(c0);
 };
diff --git a/reference/opt/shaders-hlsl/comp/num-workgroups-with-builtins.comp b/reference/opt/shaders-hlsl/comp/num-workgroups-with-builtins.comp
index 2e2ad55..cc326db 100644
--- a/reference/opt/shaders-hlsl/comp/num-workgroups-with-builtins.comp
+++ b/reference/opt/shaders-hlsl/comp/num-workgroups-with-builtins.comp
@@ -1,7 +1,7 @@
 static const uint3 gl_WorkGroupSize = uint3(1u, 1u, 1u);
 
 RWByteAddressBuffer _10 : register(u0);
-cbuffer SPIRV_Cross_NumWorkgroups : register(b0)
+cbuffer SPIRV_Cross_NumWorkgroups
 {
     uint3 SPIRV_Cross_NumWorkgroups_1_count : packoffset(c0);
 };
diff --git a/reference/shaders-hlsl-no-opt/asm/comp/num-workgroups.spv14.asm.comp b/reference/shaders-hlsl-no-opt/asm/comp/num-workgroups.spv14.asm.comp
new file mode 100644
index 0000000..e771d77
--- /dev/null
+++ b/reference/shaders-hlsl-no-opt/asm/comp/num-workgroups.spv14.asm.comp
@@ -0,0 +1,24 @@
+static const uint3 gl_WorkGroupSize = uint3(1u, 1u, 1u);
+
+RWByteAddressBuffer _3 : register(u1);
+cbuffer UBO : register(b0)
+{
+    uint3 _5_w : packoffset(c0);
+};
+
+cbuffer SPIRV_Cross_NumWorkgroups
+{
+    uint3 SPIRV_Cross_NumWorkgroups_1_count : packoffset(c0);
+};
+
+
+void comp_main()
+{
+    _3.Store3(0, SPIRV_Cross_NumWorkgroups_1_count + _5_w);
+}
+
+[numthreads(1, 1, 1)]
+void main()
+{
+    comp_main();
+}
diff --git a/reference/shaders-hlsl/comp/num-workgroups-alone.comp b/reference/shaders-hlsl/comp/num-workgroups-alone.comp
index dc87dc8..ff71a0e 100644
--- a/reference/shaders-hlsl/comp/num-workgroups-alone.comp
+++ b/reference/shaders-hlsl/comp/num-workgroups-alone.comp
@@ -1,7 +1,7 @@
 static const uint3 gl_WorkGroupSize = uint3(1u, 1u, 1u);
 
 RWByteAddressBuffer _10 : register(u0);
-cbuffer SPIRV_Cross_NumWorkgroups : register(b0)
+cbuffer SPIRV_Cross_NumWorkgroups
 {
     uint3 SPIRV_Cross_NumWorkgroups_1_count : packoffset(c0);
 };
diff --git a/reference/shaders-hlsl/comp/num-workgroups-with-builtins.comp b/reference/shaders-hlsl/comp/num-workgroups-with-builtins.comp
index 2e2ad55..cc326db 100644
--- a/reference/shaders-hlsl/comp/num-workgroups-with-builtins.comp
+++ b/reference/shaders-hlsl/comp/num-workgroups-with-builtins.comp
@@ -1,7 +1,7 @@
 static const uint3 gl_WorkGroupSize = uint3(1u, 1u, 1u);
 
 RWByteAddressBuffer _10 : register(u0);
-cbuffer SPIRV_Cross_NumWorkgroups : register(b0)
+cbuffer SPIRV_Cross_NumWorkgroups
 {
     uint3 SPIRV_Cross_NumWorkgroups_1_count : packoffset(c0);
 };
diff --git a/shaders-hlsl-no-opt/asm/comp/num-workgroups.spv14.asm.comp b/shaders-hlsl-no-opt/asm/comp/num-workgroups.spv14.asm.comp
new file mode 100644
index 0000000..e820da5
--- /dev/null
+++ b/shaders-hlsl-no-opt/asm/comp/num-workgroups.spv14.asm.comp
@@ -0,0 +1,57 @@
+; SPIR-V
+; Version: 1.4
+; Generator: Khronos Glslang Reference Front End; 10
+; Bound: 27
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint GLCompute %main "main" %_ %gl_NumWorkGroups %__0
+               OpExecutionMode %main LocalSize 1 1 1
+               OpSource GLSL 450
+               OpName %main "main"
+               OpName %SSBO "SSBO"
+               OpMemberName %SSBO 0 "v"
+               OpName %_ ""
+               OpName %gl_NumWorkGroups "gl_NumWorkGroups"
+               OpName %UBO "UBO"
+               OpMemberName %UBO 0 "w"
+               OpName %__0 ""
+               OpMemberDecorate %SSBO 0 Offset 0
+               OpDecorate %SSBO Block
+               OpDecorate %_ DescriptorSet 0
+               OpDecorate %_ Binding 1
+               OpDecorate %gl_NumWorkGroups BuiltIn NumWorkgroups
+               OpMemberDecorate %UBO 0 Offset 0
+               OpDecorate %UBO Block
+               OpDecorate %__0 DescriptorSet 0
+               OpDecorate %__0 Binding 0
+               OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+       %uint = OpTypeInt 32 0
+     %v3uint = OpTypeVector %uint 3
+       %SSBO = OpTypeStruct %v3uint
+%_ptr_StorageBuffer_SSBO = OpTypePointer StorageBuffer %SSBO
+          %_ = OpVariable %_ptr_StorageBuffer_SSBO StorageBuffer
+        %int = OpTypeInt 32 1
+      %int_0 = OpConstant %int 0
+%_ptr_Input_v3uint = OpTypePointer Input %v3uint
+%gl_NumWorkGroups = OpVariable %_ptr_Input_v3uint Input
+        %UBO = OpTypeStruct %v3uint
+%_ptr_Uniform_UBO = OpTypePointer Uniform %UBO
+        %__0 = OpVariable %_ptr_Uniform_UBO Uniform
+%_ptr_Uniform_v3uint = OpTypePointer Uniform %v3uint
+%_ptr_StorageBuffer_v3uint = OpTypePointer StorageBuffer %v3uint
+     %uint_1 = OpConstant %uint 1
+%gl_WorkGroupSize = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %15 = OpLoad %v3uint %gl_NumWorkGroups
+         %20 = OpAccessChain %_ptr_Uniform_v3uint %__0 %int_0
+         %21 = OpLoad %v3uint %20
+         %22 = OpIAdd %v3uint %15 %21
+         %24 = OpAccessChain %_ptr_StorageBuffer_v3uint %_ %int_0
+               OpStore %24 %22
+               OpReturn
+               OpFunctionEnd
diff --git a/spirv_hlsl.cpp b/spirv_hlsl.cpp
index 3ca4c2f..1f04c40 100644
--- a/spirv_hlsl.cpp
+++ b/spirv_hlsl.cpp
@@ -5696,6 +5696,7 @@
 	ir.meta[variable_id].decoration.alias = "SPIRV_Cross_NumWorkgroups";
 
 	num_workgroups_builtin = variable_id;
+	get_entry_point().interface_variables.push_back(num_workgroups_builtin);
 	return variable_id;
 }