HLSL: various SPIR-V compute shader IDs must be a 3-vector of integers.

This PR forces the external definition of SV_GroupID variables to 3-vectors.
The conversion process between the shader-declared type and the external type
happens in wrapped main IO variable conversion.

The same applies to SV_DispatchThreadID and SV_GroupThreadID.

Fixes: #1371
This commit is contained in:
LoopDawg 2018-05-15 14:52:14 -06:00
parent 1831087e48
commit 91a8178efb
6 changed files with 237 additions and 67 deletions

View File

@ -15,17 +15,19 @@ local_size = (1, 1, 1)
0:? Sequence 0:? Sequence
0:4 move second child to first child ( temp int) 0:4 move second child to first child ( temp int)
0:? 'dti' ( 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:4 move second child to first child ( temp int)
0:? 'gti' ( 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:4 Function Call: @main(i1;i1; ( temp void)
0:? 'dti' ( temp int) 0:? 'dti' ( temp int)
0:? 'gti' ( temp int) 0:? 'gti' ( temp int)
0:? Linker Objects 0:? Linker Objects
0:? 'a' ( shared 100-element array of 4-component vector of float) 0:? 'a' ( shared 100-element array of 4-component vector of float)
0:? 'dti' ( in int GlobalInvocationID) 0:? 'dti' ( in 3-component vector of int GlobalInvocationID)
0:? 'gti' ( in int LocalInvocationID) 0:? 'gti' ( in 3-component vector of int LocalInvocationID)
Linked compute stage: Linked compute stage:
@ -47,26 +49,28 @@ local_size = (1, 1, 1)
0:? Sequence 0:? Sequence
0:4 move second child to first child ( temp int) 0:4 move second child to first child ( temp int)
0:? 'dti' ( 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:4 move second child to first child ( temp int)
0:? 'gti' ( 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:4 Function Call: @main(i1;i1; ( temp void)
0:? 'dti' ( temp int) 0:? 'dti' ( temp int)
0:? 'gti' ( temp int) 0:? 'gti' ( temp int)
0:? Linker Objects 0:? Linker Objects
0:? 'a' ( shared 100-element array of 4-component vector of float) 0:? 'a' ( shared 100-element array of 4-component vector of float)
0:? 'dti' ( in int GlobalInvocationID) 0:? 'dti' ( in 3-component vector of int GlobalInvocationID)
0:? 'gti' ( in int LocalInvocationID) 0:? 'gti' ( in 3-component vector of int LocalInvocationID)
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80006 // Generated by (magic number): 80006
// Id's are bound by 35 // Id's are bound by 38
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint GLCompute 4 "main" 18 21 EntryPoint GLCompute 4 "main" 19 23
ExecutionMode 4 LocalSize 1 1 1 ExecutionMode 4 LocalSize 1 1 1
Source HLSL 500 Source HLSL 500
Name 4 "main" Name 4 "main"
@ -74,44 +78,47 @@ local_size = (1, 1, 1)
Name 9 "dti" Name 9 "dti"
Name 10 "gti" Name 10 "gti"
Name 16 "dti" Name 16 "dti"
Name 18 "dti" Name 19 "dti"
Name 20 "gti" Name 22 "gti"
Name 21 "gti" Name 23 "gti"
Name 23 "param" Name 26 "param"
Name 25 "param" Name 28 "param"
Name 34 "a" Name 37 "a"
Decorate 18(dti) BuiltIn GlobalInvocationId Decorate 19(dti) BuiltIn GlobalInvocationId
Decorate 21(gti) BuiltIn LocalInvocationId Decorate 23(gti) BuiltIn LocalInvocationId
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 1 6: TypeInt 32 1
7: TypePointer Function 6(int) 7: TypePointer Function 6(int)
8: TypeFunction 2 7(ptr) 7(ptr) 8: TypeFunction 2 7(ptr) 7(ptr)
17: TypePointer Input 6(int) 17: TypeVector 6(int) 3
18(dti): 17(ptr) Variable Input 18: TypePointer Input 17(ivec3)
21(gti): 17(ptr) Variable Input 19(dti): 18(ptr) Variable Input
28: TypeFloat 32 23(gti): 18(ptr) Variable Input
29: TypeVector 28(float) 4 31: TypeFloat 32
30: TypeInt 32 0 32: TypeVector 31(float) 4
31: 30(int) Constant 100 33: TypeInt 32 0
32: TypeArray 29(fvec4) 31 34: 33(int) Constant 100
33: TypePointer Workgroup 32 35: TypeArray 32(fvec4) 34
34(a): 33(ptr) Variable Workgroup 36: TypePointer Workgroup 35
37(a): 36(ptr) Variable Workgroup
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
16(dti): 7(ptr) Variable Function 16(dti): 7(ptr) Variable Function
20(gti): 7(ptr) Variable Function 22(gti): 7(ptr) Variable Function
23(param): 7(ptr) Variable Function 26(param): 7(ptr) Variable Function
25(param): 7(ptr) Variable Function 28(param): 7(ptr) Variable Function
19: 6(int) Load 18(dti) 20: 17(ivec3) Load 19(dti)
Store 16(dti) 19 21: 6(int) CompositeExtract 20 0
22: 6(int) Load 21(gti) Store 16(dti) 21
Store 20(gti) 22 24: 17(ivec3) Load 23(gti)
24: 6(int) Load 16(dti) 25: 6(int) CompositeExtract 24 0
Store 23(param) 24 Store 22(gti) 25
26: 6(int) Load 20(gti) 27: 6(int) Load 16(dti)
Store 25(param) 26 Store 26(param) 27
27: 2 FunctionCall 11(@main(i1;i1;) 23(param) 25(param) 29: 6(int) Load 22(gti)
Store 28(param) 29
30: 2 FunctionCall 11(@main(i1;i1;) 26(param) 28(param)
Return Return
FunctionEnd FunctionEnd
11(@main(i1;i1;): 2 Function None 8 11(@main(i1;i1;): 2 Function None 8

View File

@ -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

View File

@ -56,13 +56,14 @@ local_size = (256, 1, 1)
0:? Sequence 0:? Sequence
0:12 move second child to first child ( temp uint) 0:12 move second child to first child ( temp uint)
0:? 'dispatchId' ( 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:12 Function Call: @main(u1; ( temp void)
0:? 'dispatchId' ( temp uint) 0:? 'dispatchId' ( temp uint)
0:? Linker Objects 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_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:? '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: Linked compute stage:
@ -125,24 +126,25 @@ local_size = (256, 1, 1)
0:? Sequence 0:? Sequence
0:12 move second child to first child ( temp uint) 0:12 move second child to first child ( temp uint)
0:? 'dispatchId' ( 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:12 Function Call: @main(u1; ( temp void)
0:? 'dispatchId' ( temp uint) 0:? 'dispatchId' ( temp uint)
0:? Linker Objects 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_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:? '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 // Module Version 10000
// Generated by (magic number): 80006 // Generated by (magic number): 80006
// Id's are bound by 61 // Id's are bound by 63
Capability Shader Capability Shader
Capability ImageBuffer Capability ImageBuffer
Capability StorageImageExtendedFormats Capability StorageImageExtendedFormats
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint GLCompute 4 "main" 56 EntryPoint GLCompute 4 "main" 57
ExecutionMode 4 LocalSize 256 1 1 ExecutionMode 4 LocalSize 256 1 1
Source HLSL 500 Source HLSL 500
Name 4 "main" Name 4 "main"
@ -160,8 +162,8 @@ local_size = (256, 1, 1)
Name 45 "param" Name 45 "param"
Name 50 "g_output" Name 50 "g_output"
Name 54 "dispatchId" Name 54 "dispatchId"
Name 56 "dispatchId" Name 57 "dispatchId"
Name 58 "param" Name 60 "param"
Decorate 8 ArrayStride 4 Decorate 8 ArrayStride 4
MemberDecorate 9 0 NonWritable MemberDecorate 9 0 NonWritable
MemberDecorate 9 0 Offset 0 MemberDecorate 9 0 Offset 0
@ -171,7 +173,7 @@ local_size = (256, 1, 1)
Decorate 44(g_input) Binding 0 Decorate 44(g_input) Binding 0
Decorate 50(g_output) DescriptorSet 0 Decorate 50(g_output) DescriptorSet 0
Decorate 50(g_output) Binding 1 Decorate 50(g_output) Binding 1
Decorate 56(dispatchId) BuiltIn GlobalInvocationId Decorate 57(dispatchId) BuiltIn GlobalInvocationId
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeInt 32 0 6: TypeInt 32 0
@ -193,17 +195,19 @@ local_size = (256, 1, 1)
48: TypeImage 6(int) Buffer nonsampled format:Rg32ui 48: TypeImage 6(int) Buffer nonsampled format:Rg32ui
49: TypePointer UniformConstant 48 49: TypePointer UniformConstant 48
50(g_output): 49(ptr) Variable UniformConstant 50(g_output): 49(ptr) Variable UniformConstant
55: TypePointer Input 6(int) 55: TypeVector 6(int) 3
56(dispatchId): 55(ptr) Variable Input 56: TypePointer Input 55(ivec3)
57(dispatchId): 56(ptr) Variable Input
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
54(dispatchId): 7(ptr) Variable Function 54(dispatchId): 7(ptr) Variable Function
58(param): 7(ptr) Variable Function 60(param): 7(ptr) Variable Function
57: 6(int) Load 56(dispatchId) 58: 55(ivec3) Load 57(dispatchId)
Store 54(dispatchId) 57 59: 6(int) CompositeExtract 58 0
59: 6(int) Load 54(dispatchId) Store 54(dispatchId) 59
Store 58(param) 59 61: 6(int) Load 54(dispatchId)
60: 2 FunctionCall 19(@main(u1;) 58(param) Store 60(param) 61
62: 2 FunctionCall 19(@main(u1;) 60(param)
Return Return
FunctionEnd FunctionEnd
15(testLoad(u1;block--u1[0]1;): 11(ivec2) Function None 12 15(testLoad(u1;block--u1[0]1;): 11(ivec2) Function None 12

9
Test/hlsl.groupid.comp Normal file
View File

@ -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);
}

View File

@ -195,6 +195,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.hull.void.tesc", "main"}, {"hlsl.hull.void.tesc", "main"},
{"hlsl.hull.ctrlpt-1.tesc", "main"}, {"hlsl.hull.ctrlpt-1.tesc", "main"},
{"hlsl.hull.ctrlpt-2.tesc", "main"}, {"hlsl.hull.ctrlpt-2.tesc", "main"},
{"hlsl.groupid.comp", "main"},
{"hlsl.identifier.sample.frag", "main"}, {"hlsl.identifier.sample.frag", "main"},
{"hlsl.if.frag", "PixelShaderFunction"}, {"hlsl.if.frag", "PixelShaderFunction"},
{"hlsl.imagefetch-subvec4.comp", "main"}, {"hlsl.imagefetch-subvec4.comp", "main"},

View File

@ -1475,22 +1475,17 @@ bool HlslParseContext::isClipOrCullDistance(TBuiltInVariable builtIn)
void HlslParseContext::fixBuiltInIoType(TType& type) void HlslParseContext::fixBuiltInIoType(TType& type)
{ {
int requiredArraySize = 0; int requiredArraySize = 0;
int requiredVectorSize = 0;
switch (type.getQualifier().builtIn) { switch (type.getQualifier().builtIn) {
case EbvTessLevelOuter: requiredArraySize = 4; break; case EbvTessLevelOuter: requiredArraySize = 4; break;
case EbvTessLevelInner: requiredArraySize = 2; break; case EbvTessLevelInner: requiredArraySize = 2; break;
case EbvTessCoord: case EbvWorkGroupId: requiredVectorSize = 3; break;
{ case EbvGlobalInvocationId: requiredVectorSize = 3; break;
// tesscoord is always a vec3 for the IO variable, no matter the shader's case EbvLocalInvocationId: requiredVectorSize = 3; break;
// declared vector size. case EbvTessCoord: requiredVectorSize = 3; break;
TType tessCoordType(type.getBasicType(), type.getQualifier().storage, 3);
tessCoordType.getQualifier() = type.getQualifier();
type.shallowCopy(tessCoordType);
break;
}
default: default:
if (isClipOrCullDistance(type)) { if (isClipOrCullDistance(type)) {
const int loc = type.getQualifier().layoutLocation; const int loc = type.getQualifier().layoutLocation;
@ -1511,6 +1506,14 @@ void HlslParseContext::fixBuiltInIoType(TType& type)
return; 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. // Alter or set array size as needed.
if (requiredArraySize > 0) { if (requiredArraySize > 0) {
if (!type.isArray() || type.getOuterArraySize() != requiredArraySize) { if (!type.isArray() || type.getOuterArraySize() != requiredArraySize) {