static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_query";
static const char* const E_SPV_KHR_fragment_shading_rate = "SPV_KHR_fragment_shading_rate";
static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_terminate_invocation";
+static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
#endif // #ifndef GLSLextKHR_H
case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock;
case glslang::EvqVaryingIn: return spv::DecorationBlock;
case glslang::EvqVaryingOut: return spv::DecorationBlock;
+ case glslang::EvqShared: return spv::DecorationBlock;
#ifndef GLSLANG_WEB
case glslang::EvqPayload: return spv::DecorationBlock;
case glslang::EvqPayloadIn: return spv::DecorationBlock;
break;
case glslang::EbtBlock:
switch (type.getQualifier().storage) {
+ case glslang::EvqShared:
case glslang::EvqUniform:
case glslang::EvqBuffer:
switch (type.getQualifier().layoutPacking) {
return spv::StorageClassUniformConstant;
}
+ if (type.getQualifier().storage == glslang::EvqShared && type.getBasicType() == glslang::EbtBlock) {
+ builder.addExtension(spv::E_SPV_KHR_workgroup_memory_explicit_layout);
+ builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR);
+ return spv::StorageClassWorkgroup;
+ }
+
switch (type.getQualifier().storage) {
case glslang::EvqGlobal: return spv::StorageClassPrivate;
case glslang::EvqConstReadOnly: return spv::StorageClassFunction;
break;
#endif
default:
+ if (storageClass == spv::StorageClassWorkgroup &&
+ node->getType().getBasicType() == glslang::EbtBlock) {
+ builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR);
+ break;
+ }
if (node->getType().contains16BitFloat())
builder.addCapability(spv::CapabilityFloat16);
if (node->getType().contains16BitInt())
} else if (storageClass == spv::StorageClassStorageBuffer) {
builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
builder.addCapability(spv::CapabilityStorageBuffer8BitAccess);
+ } else if (storageClass == spv::StorageClassWorkgroup &&
+ node->getType().getBasicType() == glslang::EbtBlock) {
+ builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR);
} else {
builder.addCapability(spv::CapabilityInt8);
}
// has to be a uniform or buffer block or task in/out blocks
if (type.getQualifier().storage != glslang::EvqUniform &&
type.getQualifier().storage != glslang::EvqBuffer &&
+ type.getQualifier().storage != glslang::EvqShared &&
!type.getQualifier().isTaskMemory())
return glslang::ElpNone;
memoryModel = spv::MemoryModelVulkanKHR;
addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5);
}
+
+ // Add Aliased decoration if there's more than one Workgroup Block variable.
+ if (capabilities.find(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR) != capabilities.end()) {
+ assert(entryPoints.size() == 1);
+ auto &ep = entryPoints[0];
+
+ std::vector<Id> workgroup_variables;
+ for (int i = 0; i < (int)ep->getNumOperands(); i++) {
+ if (!ep->isIdOperand(i))
+ continue;
+
+ const Id id = ep->getIdOperand(i);
+ const Instruction *instr = module.getInstruction(id);
+ if (instr->getOpCode() != spv::OpVariable)
+ continue;
+
+ if (instr->getImmediateOperand(0) == spv::StorageClassWorkgroup)
+ workgroup_variables.push_back(id);
+ }
+
+ if (workgroup_variables.size() > 1) {
+ for (size_t i = 0; i < workgroup_variables.size(); i++)
+ addDecoration(workgroup_variables[i], spv::DecorationAliased);
+ }
+ }
}
#endif
spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization);
spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
+ spvValidatorOptionsSetWorkgroupScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
spvValidateWithOptions(context, options, &binary, &diagnostic);
// report
case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT";
case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT";
+ case CapabilityWorkgroupMemoryExplicitLayoutKHR: return "CapabilityWorkgroupMemoryExplicitLayoutKHR";
+ case CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR";
+ case CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR";
+
default: return "Bad";
}
}
ERROR: 0:39: 'location qualifier on input' : not supported in this stage: compute
ERROR: 0:40: 'in' : global storage input qualifier cannot be used in a compute shader
ERROR: 0:41: 'out' : global storage output qualifier cannot be used in a compute shader
-ERROR: 0:44: 'shared' : cannot apply layout qualifiers to a shared variable
+ERROR: 0:44: 'shared block' : not supported for this version or the enabled extensions
ERROR: 0:44: 'location' : can only apply to uniform, buffer, in, or out storage qualifiers
ERROR: 0:45: 'shared' : initializer can only be a null initializer ('{}')
ERROR: 0:47: 'local_size' : can only apply to 'in'
ERROR: 0:184: 'textureQueryLod' : no matching overloaded function found
ERROR: 0:184: 'assign' : cannot convert from ' const float' to ' temp 2-component vector of float'
ERROR: 0:197: 'subroutine' : feature not yet implemented
-ERROR: 0:197: '' : default qualifier requires 'uniform', 'buffer', 'in', or 'out' storage qualification
+ERROR: 0:197: '' : default qualifier requires 'uniform', 'buffer', 'in', 'out' or 'shared' storage qualification
ERROR: 0:198: 'subroutine' : feature not yet implemented
ERROR: 0:199: 'subroutine' : feature not yet implemented
ERROR: 0:201: '' : syntax error, unexpected PRECISE, expecting IDENTIFIER
ERROR: 0:43: 'location qualifier on input' : not supported in this stage: compute
ERROR: 0:44: 'in' : global storage input qualifier cannot be used in a compute shader
ERROR: 0:45: 'out' : global storage output qualifier cannot be used in a compute shader
-ERROR: 0:48: 'shared' : cannot apply layout qualifiers to a shared variable
+ERROR: 0:48: 'shared block' : not supported for this version or the enabled extensions
ERROR: 0:48: 'location' : can only apply to uniform, buffer, in, or out storage qualifiers
ERROR: 0:49: 'shared' : initializer can only be a null initializer ('{}')
ERROR: 0:52: 'local_size' : cannot change previously set size
--- /dev/null
+spv.WorkgroupMemoryExplicitLayout.16BitAccess.comp
+// Module Version 10400
+// Generated by (magic number): 8000a
+// Id's are bound by 25
+
+ Capability Shader
+ Capability Float16
+ Capability Int16
+ Capability CapabilityWorkgroupMemoryExplicitLayoutKHR
+ Capability CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR
+ Extension "SPV_KHR_workgroup_memory_explicit_layout"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint GLCompute 4 "main" 10
+ ExecutionMode 4 LocalSize 2 1 1
+ Source GLSL 430
+ SourceExtension "GL_EXT_shader_explicit_arithmetic_types"
+ SourceExtension "GL_EXT_shared_memory_block"
+ Name 4 "main"
+ Name 8 "first"
+ MemberName 8(first) 0 "a"
+ MemberName 8(first) 1 "f"
+ Name 10 ""
+ MemberDecorate 8(first) 0 Offset 0
+ MemberDecorate 8(first) 1 Offset 2
+ Decorate 8(first) Block
+ Decorate 24 BuiltIn WorkgroupSize
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 16 1
+ 7: TypeFloat 16
+ 8(first): TypeStruct 6(int16_t) 7(float16_t)
+ 9: TypePointer Workgroup 8(first)
+ 10: 9(ptr) Variable Workgroup
+ 11: TypeInt 32 1
+ 12: 11(int) Constant 0
+ 13: 6(int16_t) Constant 3
+ 14: TypePointer Workgroup 6(int16_t)
+ 16: 11(int) Constant 1
+ 17:7(float16_t) Constant 18982
+ 18: TypePointer Workgroup 7(float16_t)
+ 20: TypeInt 32 0
+ 21: TypeVector 20(int) 3
+ 22: 20(int) Constant 2
+ 23: 20(int) Constant 1
+ 24: 21(ivec3) ConstantComposite 22 23 23
+ 4(main): 2 Function None 3
+ 5: Label
+ 15: 14(ptr) AccessChain 10 12
+ Store 15 13
+ 19: 18(ptr) AccessChain 10 16
+ Store 19 17
+ Return
+ FunctionEnd
--- /dev/null
+spv.WorkgroupMemoryExplicitLayout.8BitAccess.comp
+// Module Version 10400
+// Generated by (magic number): 8000a
+// Id's are bound by 20
+
+ Capability Shader
+ Capability Int8
+ Capability CapabilityWorkgroupMemoryExplicitLayoutKHR
+ Capability CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR
+ Extension "SPV_KHR_workgroup_memory_explicit_layout"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint GLCompute 4 "main" 9
+ ExecutionMode 4 LocalSize 2 1 1
+ Source GLSL 430
+ SourceExtension "GL_EXT_shader_explicit_arithmetic_types"
+ SourceExtension "GL_EXT_shared_memory_block"
+ Name 4 "main"
+ Name 7 "first"
+ MemberName 7(first) 0 "a"
+ Name 9 ""
+ MemberDecorate 7(first) 0 Offset 0
+ Decorate 7(first) Block
+ Decorate 19 BuiltIn WorkgroupSize
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 8 1
+ 7(first): TypeStruct 6(int8_t)
+ 8: TypePointer Workgroup 7(first)
+ 9: 8(ptr) Variable Workgroup
+ 10: TypeInt 32 1
+ 11: 10(int) Constant 0
+ 12: 6(int8_t) Constant 2
+ 13: TypePointer Workgroup 6(int8_t)
+ 15: TypeInt 32 0
+ 16: TypeVector 15(int) 3
+ 17: 15(int) Constant 2
+ 18: 15(int) Constant 1
+ 19: 16(ivec3) ConstantComposite 17 18 18
+ 4(main): 2 Function None 3
+ 5: Label
+ 14: 13(ptr) AccessChain 9 11
+ Store 14 12
+ Return
+ FunctionEnd
--- /dev/null
+spv.WorkgroupMemoryExplicitLayout.MixBlockNonBlock_Errors.comp
+ERROR: Linking compute stage: cannot mix use of shared variables inside and outside blocks
+
+SPIR-V is not generated for failed compile or link
--- /dev/null
+spv.WorkgroupMemoryExplicitLayout.MultiBlock.comp
+// Module Version 10400
+// Generated by (magic number): 8000a
+// Id's are bound by 24
+
+ Capability Shader
+ Capability CapabilityWorkgroupMemoryExplicitLayoutKHR
+ Extension "SPV_KHR_workgroup_memory_explicit_layout"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint GLCompute 4 "main" 9 16
+ ExecutionMode 4 LocalSize 8 1 1
+ Source GLSL 430
+ SourceExtension "GL_EXT_shared_memory_block"
+ Name 4 "main"
+ Name 7 "first"
+ MemberName 7(first) 0 "a"
+ Name 9 ""
+ Name 14 "second"
+ MemberName 14(second) 0 "b"
+ Name 16 ""
+ MemberDecorate 7(first) 0 Offset 0
+ Decorate 7(first) Block
+ MemberDecorate 14(second) 0 Offset 0
+ Decorate 14(second) Block
+ Decorate 23 BuiltIn WorkgroupSize
+ Decorate 9 Aliased
+ Decorate 16 Aliased
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 1
+ 7(first): TypeStruct 6(int)
+ 8: TypePointer Workgroup 7(first)
+ 9: 8(ptr) Variable Workgroup
+ 10: 6(int) Constant 0
+ 11: 6(int) Constant 2
+ 12: TypePointer Workgroup 6(int)
+ 14(second): TypeStruct 6(int)
+ 15: TypePointer Workgroup 14(second)
+ 16: 15(ptr) Variable Workgroup
+ 17: 6(int) Constant 3
+ 19: TypeInt 32 0
+ 20: TypeVector 19(int) 3
+ 21: 19(int) Constant 8
+ 22: 19(int) Constant 1
+ 23: 20(ivec3) ConstantComposite 21 22 22
+ 4(main): 2 Function None 3
+ 5: Label
+ 13: 12(ptr) AccessChain 9 10
+ Store 13 11
+ 18: 12(ptr) AccessChain 16 10
+ Store 18 17
+ Return
+ FunctionEnd
--- /dev/null
+spv.WorkgroupMemoryExplicitLayout.NonBlock.comp
+// Module Version 10400
+// Generated by (magic number): 8000a
+// Id's are bound by 17
+
+ Capability Shader
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint GLCompute 4 "main" 8 10
+ ExecutionMode 4 LocalSize 8 1 1
+ Source GLSL 430
+ SourceExtension "GL_EXT_shared_memory_block"
+ Name 4 "main"
+ Name 8 "a"
+ Name 10 "b"
+ Decorate 16 BuiltIn WorkgroupSize
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 1
+ 7: TypePointer Workgroup 6(int)
+ 8(a): 7(ptr) Variable Workgroup
+ 9: 6(int) Constant 2
+ 10(b): 7(ptr) Variable Workgroup
+ 11: 6(int) Constant 3
+ 12: TypeInt 32 0
+ 13: TypeVector 12(int) 3
+ 14: 12(int) Constant 8
+ 15: 12(int) Constant 1
+ 16: 13(ivec3) ConstantComposite 14 15 15
+ 4(main): 2 Function None 3
+ 5: Label
+ Store 8(a) 9
+ Store 10(b) 11
+ Return
+ FunctionEnd
--- /dev/null
+spv.WorkgroupMemoryExplicitLayout.SingleBlock.comp
+// Module Version 10400
+// Generated by (magic number): 8000a
+// Id's are bound by 19
+
+ Capability Shader
+ Capability CapabilityWorkgroupMemoryExplicitLayoutKHR
+ Extension "SPV_KHR_workgroup_memory_explicit_layout"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint GLCompute 4 "main" 9
+ ExecutionMode 4 LocalSize 8 1 1
+ Source GLSL 430
+ SourceExtension "GL_EXT_shared_memory_block"
+ Name 4 "main"
+ Name 7 "first"
+ MemberName 7(first) 0 "a"
+ Name 9 ""
+ MemberDecorate 7(first) 0 Offset 0
+ Decorate 7(first) Block
+ Decorate 18 BuiltIn WorkgroupSize
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 1
+ 7(first): TypeStruct 6(int)
+ 8: TypePointer Workgroup 7(first)
+ 9: 8(ptr) Variable Workgroup
+ 10: 6(int) Constant 0
+ 11: 6(int) Constant 2
+ 12: TypePointer Workgroup 6(int)
+ 14: TypeInt 32 0
+ 15: TypeVector 14(int) 3
+ 16: 14(int) Constant 8
+ 17: 14(int) Constant 1
+ 18: 15(ivec3) ConstantComposite 16 17 17
+ 4(main): 2 Function None 3
+ 5: Label
+ 13: 12(ptr) AccessChain 9 10
+ Store 13 11
+ Return
+ FunctionEnd
--- /dev/null
+spv.WorkgroupMemoryExplicitLayout.scalar.comp
+// Module Version 10400
+// Generated by (magic number): 8000a
+// Id's are bound by 29
+
+ Capability Shader
+ Capability CapabilityWorkgroupMemoryExplicitLayoutKHR
+ Extension "SPV_KHR_workgroup_memory_explicit_layout"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint GLCompute 4 "main" 28
+ ExecutionMode 4 LocalSize 8 1 1
+ Source GLSL 430
+ SourceExtension "GL_EXT_scalar_block_layout"
+ SourceExtension "GL_EXT_shared_memory_block"
+ Name 4 "main"
+ Name 17 "T"
+ MemberName 17(T) 0 "t"
+ Name 24 "S"
+ MemberName 24(S) 0 "f"
+ MemberName 24(S) 1 "v2"
+ MemberName 24(S) 2 "v3"
+ MemberName 24(S) 3 "v4"
+ MemberName 24(S) 4 "t"
+ MemberName 24(S) 5 "f_array"
+ MemberName 24(S) 6 "v2_array"
+ MemberName 24(S) 7 "v3_array"
+ MemberName 24(S) 8 "v4_array"
+ MemberName 24(S) 9 "t_array"
+ Name 26 "Block"
+ MemberName 26(Block) 0 "s"
+ MemberName 26(Block) 1 "s_array"
+ Name 28 ""
+ Decorate 10 BuiltIn WorkgroupSize
+ Decorate 16 ArrayStride 4
+ MemberDecorate 17(T) 0 Offset 0
+ Decorate 19 ArrayStride 4
+ Decorate 20 ArrayStride 8
+ Decorate 21 ArrayStride 12
+ Decorate 22 ArrayStride 16
+ Decorate 23 ArrayStride 12
+ MemberDecorate 24(S) 0 Offset 0
+ MemberDecorate 24(S) 1 Offset 4
+ MemberDecorate 24(S) 2 Offset 12
+ MemberDecorate 24(S) 3 Offset 24
+ MemberDecorate 24(S) 4 Offset 40
+ MemberDecorate 24(S) 5 Offset 52
+ MemberDecorate 24(S) 6 Offset 76
+ MemberDecorate 24(S) 7 Offset 124
+ MemberDecorate 24(S) 8 Offset 196
+ MemberDecorate 24(S) 9 Offset 292
+ Decorate 25 ArrayStride 364
+ MemberDecorate 26(Block) 0 Offset 0
+ MemberDecorate 26(Block) 1 Offset 364
+ Decorate 26(Block) Block
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 0
+ 7: TypeVector 6(int) 3
+ 8: 6(int) Constant 8
+ 9: 6(int) Constant 1
+ 10: 7(ivec3) ConstantComposite 8 9 9
+ 11: TypeFloat 32
+ 12: TypeVector 11(float) 2
+ 13: TypeVector 11(float) 3
+ 14: TypeVector 11(float) 4
+ 15: 6(int) Constant 3
+ 16: TypeArray 11(float) 15
+ 17(T): TypeStruct 16
+ 18: 6(int) Constant 6
+ 19: TypeArray 11(float) 18
+ 20: TypeArray 12(fvec2) 18
+ 21: TypeArray 13(fvec3) 18
+ 22: TypeArray 14(fvec4) 18
+ 23: TypeArray 17(T) 18
+ 24(S): TypeStruct 11(float) 12(fvec2) 13(fvec3) 14(fvec4) 17(T) 19 20 21 22 23
+ 25: TypeArray 24(S) 18
+ 26(Block): TypeStruct 24(S) 25
+ 27: TypePointer Workgroup 26(Block)
+ 28: 27(ptr) Variable Workgroup
+ 4(main): 2 Function None 3
+ 5: Label
+ Return
+ FunctionEnd
--- /dev/null
+spv.WorkgroupMemoryExplicitLayout.std140.comp
+// Module Version 10400
+// Generated by (magic number): 8000a
+// Id's are bound by 29
+
+ Capability Shader
+ Capability CapabilityWorkgroupMemoryExplicitLayoutKHR
+ Extension "SPV_KHR_workgroup_memory_explicit_layout"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint GLCompute 4 "main" 28
+ ExecutionMode 4 LocalSize 8 1 1
+ Source GLSL 430
+ SourceExtension "GL_EXT_shared_memory_block"
+ Name 4 "main"
+ Name 17 "T"
+ MemberName 17(T) 0 "t"
+ Name 24 "S"
+ MemberName 24(S) 0 "f"
+ MemberName 24(S) 1 "v2"
+ MemberName 24(S) 2 "v3"
+ MemberName 24(S) 3 "v4"
+ MemberName 24(S) 4 "t"
+ MemberName 24(S) 5 "f_array"
+ MemberName 24(S) 6 "v2_array"
+ MemberName 24(S) 7 "v3_array"
+ MemberName 24(S) 8 "v4_array"
+ MemberName 24(S) 9 "t_array"
+ Name 26 "Block"
+ MemberName 26(Block) 0 "s"
+ MemberName 26(Block) 1 "s_array"
+ Name 28 ""
+ Decorate 10 BuiltIn WorkgroupSize
+ Decorate 16 ArrayStride 16
+ MemberDecorate 17(T) 0 Offset 0
+ Decorate 19 ArrayStride 16
+ Decorate 20 ArrayStride 16
+ Decorate 21 ArrayStride 16
+ Decorate 22 ArrayStride 16
+ Decorate 23 ArrayStride 48
+ MemberDecorate 24(S) 0 Offset 0
+ MemberDecorate 24(S) 1 Offset 8
+ MemberDecorate 24(S) 2 Offset 16
+ MemberDecorate 24(S) 3 Offset 32
+ MemberDecorate 24(S) 4 Offset 48
+ MemberDecorate 24(S) 5 Offset 96
+ MemberDecorate 24(S) 6 Offset 192
+ MemberDecorate 24(S) 7 Offset 288
+ MemberDecorate 24(S) 8 Offset 384
+ MemberDecorate 24(S) 9 Offset 480
+ Decorate 25 ArrayStride 768
+ MemberDecorate 26(Block) 0 Offset 0
+ MemberDecorate 26(Block) 1 Offset 768
+ Decorate 26(Block) Block
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 0
+ 7: TypeVector 6(int) 3
+ 8: 6(int) Constant 8
+ 9: 6(int) Constant 1
+ 10: 7(ivec3) ConstantComposite 8 9 9
+ 11: TypeFloat 32
+ 12: TypeVector 11(float) 2
+ 13: TypeVector 11(float) 3
+ 14: TypeVector 11(float) 4
+ 15: 6(int) Constant 3
+ 16: TypeArray 11(float) 15
+ 17(T): TypeStruct 16
+ 18: 6(int) Constant 6
+ 19: TypeArray 11(float) 18
+ 20: TypeArray 12(fvec2) 18
+ 21: TypeArray 13(fvec3) 18
+ 22: TypeArray 14(fvec4) 18
+ 23: TypeArray 17(T) 18
+ 24(S): TypeStruct 11(float) 12(fvec2) 13(fvec3) 14(fvec4) 17(T) 19 20 21 22 23
+ 25: TypeArray 24(S) 18
+ 26(Block): TypeStruct 24(S) 25
+ 27: TypePointer Workgroup 26(Block)
+ 28: 27(ptr) Variable Workgroup
+ 4(main): 2 Function None 3
+ 5: Label
+ Return
+ FunctionEnd
--- /dev/null
+spv.WorkgroupMemoryExplicitLayout.std430.comp
+// Module Version 10400
+// Generated by (magic number): 8000a
+// Id's are bound by 29
+
+ Capability Shader
+ Capability CapabilityWorkgroupMemoryExplicitLayoutKHR
+ Extension "SPV_KHR_workgroup_memory_explicit_layout"
+ 1: ExtInstImport "GLSL.std.450"
+ MemoryModel Logical GLSL450
+ EntryPoint GLCompute 4 "main" 28
+ ExecutionMode 4 LocalSize 8 1 1
+ Source GLSL 430
+ SourceExtension "GL_EXT_shared_memory_block"
+ Name 4 "main"
+ Name 17 "T"
+ MemberName 17(T) 0 "t"
+ Name 24 "S"
+ MemberName 24(S) 0 "f"
+ MemberName 24(S) 1 "v2"
+ MemberName 24(S) 2 "v3"
+ MemberName 24(S) 3 "v4"
+ MemberName 24(S) 4 "t"
+ MemberName 24(S) 5 "f_array"
+ MemberName 24(S) 6 "v2_array"
+ MemberName 24(S) 7 "v3_array"
+ MemberName 24(S) 8 "v4_array"
+ MemberName 24(S) 9 "t_array"
+ Name 26 "Block"
+ MemberName 26(Block) 0 "s"
+ MemberName 26(Block) 1 "s_array"
+ Name 28 ""
+ Decorate 10 BuiltIn WorkgroupSize
+ Decorate 16 ArrayStride 4
+ MemberDecorate 17(T) 0 Offset 0
+ Decorate 19 ArrayStride 4
+ Decorate 20 ArrayStride 8
+ Decorate 21 ArrayStride 16
+ Decorate 22 ArrayStride 16
+ Decorate 23 ArrayStride 12
+ MemberDecorate 24(S) 0 Offset 0
+ MemberDecorate 24(S) 1 Offset 8
+ MemberDecorate 24(S) 2 Offset 16
+ MemberDecorate 24(S) 3 Offset 32
+ MemberDecorate 24(S) 4 Offset 48
+ MemberDecorate 24(S) 5 Offset 60
+ MemberDecorate 24(S) 6 Offset 88
+ MemberDecorate 24(S) 7 Offset 144
+ MemberDecorate 24(S) 8 Offset 240
+ MemberDecorate 24(S) 9 Offset 336
+ Decorate 25 ArrayStride 416
+ MemberDecorate 26(Block) 0 Offset 0
+ MemberDecorate 26(Block) 1 Offset 416
+ Decorate 26(Block) Block
+ 2: TypeVoid
+ 3: TypeFunction 2
+ 6: TypeInt 32 0
+ 7: TypeVector 6(int) 3
+ 8: 6(int) Constant 8
+ 9: 6(int) Constant 1
+ 10: 7(ivec3) ConstantComposite 8 9 9
+ 11: TypeFloat 32
+ 12: TypeVector 11(float) 2
+ 13: TypeVector 11(float) 3
+ 14: TypeVector 11(float) 4
+ 15: 6(int) Constant 3
+ 16: TypeArray 11(float) 15
+ 17(T): TypeStruct 16
+ 18: 6(int) Constant 6
+ 19: TypeArray 11(float) 18
+ 20: TypeArray 12(fvec2) 18
+ 21: TypeArray 13(fvec3) 18
+ 22: TypeArray 14(fvec4) 18
+ 23: TypeArray 17(T) 18
+ 24(S): TypeStruct 11(float) 12(fvec2) 13(fvec3) 14(fvec4) 17(T) 19 20 21 22 23
+ 25: TypeArray 24(S) 18
+ 26(Block): TypeStruct 24(S) 25
+ 27: TypePointer Workgroup 26(Block)
+ 28: 27(ptr) Variable Workgroup
+ 4(main): 2 Function None 3
+ 5: Label
+ Return
+ FunctionEnd
--- /dev/null
+#version 430 core
+
+#extension GL_EXT_shared_memory_block : enable
+#extension GL_EXT_shader_explicit_arithmetic_types: enable
+
+layout(local_size_x = 2) in;
+
+shared first
+{
+ int16_t a;
+ float16_t f;
+};
+
+void main()
+{
+ a = int16_t(3);
+ f = float16_t(12.3);
+}
--- /dev/null
+#version 430 core
+
+#extension GL_EXT_shared_memory_block : enable
+#extension GL_EXT_shader_explicit_arithmetic_types: enable
+
+layout(local_size_x = 2) in;
+
+shared first
+{
+ int8_t a;
+};
+
+void main()
+{
+ a = int8_t(2);
+}
--- /dev/null
+#version 430 core
+
+#extension GL_EXT_shared_memory_block : enable
+
+layout(local_size_x = 8) in;
+
+shared first
+{
+ int a;
+};
+
+shared int b;
+
+// Cannot mix shared block and shared non-block, will fail at linking.
+
+void main()
+{
+ a = 2;
+ b = 3;
+}
--- /dev/null
+#version 430 core
+
+#extension GL_EXT_shared_memory_block : enable
+
+layout(local_size_x = 8) in;
+
+shared first
+{
+ int a;
+};
+
+shared second
+{
+ int b;
+};
+
+void main()
+{
+ a = 2;
+ b = 3;
+}
--- /dev/null
+#version 430 core
+
+#extension GL_EXT_shared_memory_block : enable
+
+layout(local_size_x = 8) in;
+
+shared int a;
+shared int b;
+
+void main()
+{
+ a = 2;
+ b = 3;
+}
--- /dev/null
+#version 430 core
+
+#extension GL_EXT_shared_memory_block : enable
+
+layout(local_size_x = 8) in;
+
+shared first
+{
+ int a;
+};
+
+void main()
+{
+ a = 2;
+}
--- /dev/null
+#version 430 core
+
+#extension GL_EXT_scalar_block_layout : enable
+#extension GL_EXT_shared_memory_block : enable
+
+layout(local_size_x = 8) in;
+
+struct T
+{
+ float t[3];
+};
+
+struct S
+{
+ float f;
+ vec2 v2;
+ vec3 v3;
+ vec4 v4;
+ T t;
+
+ float f_array[6];
+ vec2 v2_array[6];
+ vec3 v3_array[6];
+ vec4 v4_array[6];
+ T t_array[6];
+};
+
+// Use a default qualifier.
+layout(scalar) shared;
+
+shared Block
+{
+ S s;
+ S s_array[6];
+};
+
+void main()
+{
+}
--- /dev/null
+#version 430 core
+
+#extension GL_EXT_shared_memory_block : enable
+
+layout(local_size_x = 8) in;
+
+struct T
+{
+ float t[3];
+};
+
+struct S
+{
+ float f;
+ vec2 v2;
+ vec3 v3;
+ vec4 v4;
+ T t;
+
+ float f_array[6];
+ vec2 v2_array[6];
+ vec3 v3_array[6];
+ vec4 v4_array[6];
+ T t_array[6];
+};
+
+layout(std140) shared Block
+{
+ S s;
+ S s_array[6];
+};
+
+void main()
+{
+}
--- /dev/null
+#version 430 core
+
+#extension GL_EXT_shared_memory_block : enable
+
+layout(local_size_x = 8) in;
+
+struct T
+{
+ float t[3];
+};
+
+struct S
+{
+ float f;
+ vec2 v2;
+ vec3 v3;
+ vec4 v4;
+ T t;
+
+ float f_array[6];
+ vec2 v2_array[6];
+ vec3 v3_array[6];
+ vec4 v4_array[6];
+ T t_array[6];
+};
+
+layout(std430) shared Block
+{
+ S s;
+ S s_array[6];
+};
+
+void main()
+{
+}
globalInputDefaults.clear();
globalOutputDefaults.clear();
+ globalSharedDefaults.clear();
+ globalSharedDefaults.layoutMatrix = ElmColumnMajor;
+ globalSharedDefaults.layoutPacking = ElpStd430;
+
#ifndef GLSLANG_WEB
// "Shaders in the transform
// feedback capturing mode have an initial global default of
}
}
+static bool storageCanHaveLayoutInBlock(const enum TStorageQualifier storage)
+{
+ switch (storage) {
+ case EvqUniform:
+ case EvqBuffer:
+ case EvqShared:
+ return true;
+ default:
+ return false;
+ }
+}
+
// Do layout error checking that can be done within a layout qualifier proper, not needing to know
// if there are blocks, atomic counters, variables, etc.
void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier& qualifier)
{
- if (qualifier.storage == EvqShared && qualifier.hasLayout())
- error(loc, "cannot apply layout qualifiers to a shared variable", "shared", "");
+ if (qualifier.storage == EvqShared && qualifier.hasLayout()) {
+ if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_4) {
+ error(loc, "shared block requires at least SPIR-V 1.4", "shared block", "");
+ }
+ profileRequires(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shared_memory_block, "shared block");
+ }
// "It is a compile-time error to use *component* without also specifying the location qualifier (order does not matter)."
if (qualifier.hasComponent() && ! qualifier.hasLocation())
error(loc, "can only be used on an output", "xfb layout qualifier", "");
}
if (qualifier.hasUniformLayout()) {
- if (! qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory()) {
+ if (!storageCanHaveLayoutInBlock(qualifier.storage) && !qualifier.isTaskMemory()) {
if (qualifier.hasMatrix() || qualifier.hasPacking())
error(loc, "matrix or packing qualifiers can only be used on a uniform or buffer", "layout", "");
if (qualifier.hasOffset() || qualifier.hasAlign())
case EvqBuffer: defaultQualification = globalBufferDefaults; break;
case EvqVaryingIn: defaultQualification = globalInputDefaults; break;
case EvqVaryingOut: defaultQualification = globalOutputDefaults; break;
+ case EvqShared: defaultQualification = globalSharedDefaults; break;
default: defaultQualification.clear(); break;
}
error(loc, "output blocks cannot be used in a task shader", "out", "");
}
break;
+ case EvqShared:
+ if (spvVersion.spv > 0 && spvVersion.spv < EShTargetSpv_1_4) {
+ error(loc, "shared block requires at least SPIR-V 1.4", "shared block", "");
+ }
+ profileRequires(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shared_memory_block, "shared block");
+ break;
#ifndef GLSLANG_WEB
case EvqPayload:
profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadNV block");
//
void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typeList)
{
- if (!qualifier.isUniformOrBuffer() && !qualifier.isTaskMemory())
+ if (!storageCanHaveLayoutInBlock(qualifier.storage) && !qualifier.isTaskMemory())
return;
if (qualifier.layoutPacking != ElpStd140 && qualifier.layoutPacking != ElpStd430 && qualifier.layoutPacking != ElpScalar)
return;
}
#endif
break;
+ case EvqShared:
+ if (qualifier.hasMatrix())
+ globalSharedDefaults.layoutMatrix = qualifier.layoutMatrix;
+ if (qualifier.hasPacking())
+ globalSharedDefaults.layoutPacking = qualifier.layoutPacking;
+ break;
default:
- error(loc, "default qualifier requires 'uniform', 'buffer', 'in', or 'out' storage qualification", "", "");
+ error(loc, "default qualifier requires 'uniform', 'buffer', 'in', 'out' or 'shared' storage qualification", "", "");
return;
}
TQualifier globalUniformDefaults;
TQualifier globalInputDefaults;
TQualifier globalOutputDefaults;
+ TQualifier globalSharedDefaults;
TString currentCaller; // name of last function body entered (not valid when at global scope)
#ifndef GLSLANG_WEB
int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point
extensionBehavior[E_GL_EXT_fragment_shading_rate] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_image_int64] = EBhDisable;
extensionBehavior[E_GL_EXT_terminate_invocation] = EBhDisable;
+ extensionBehavior[E_GL_EXT_shared_memory_block] = EBhDisable;
// OVR extensions
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
"#define GL_EXT_demote_to_helper_invocation 1\n"
"#define GL_EXT_debug_printf 1\n"
"#define GL_EXT_fragment_shading_rate 1\n"
+ "#define GL_EXT_shared_memory_block 1\n"
// GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n"
const char* const E_GL_EXT_fragment_shading_rate = "GL_EXT_fragment_shading_rate";
const char* const E_GL_EXT_shader_image_int64 = "GL_EXT_shader_image_int64";
const char* const E_GL_EXT_null_initializer = "GL_EXT_null_initializer";
+const char* const E_GL_EXT_shared_memory_block = "GL_EXT_shared_memory_block";
// Arrays of extensions for the above viewportEXTs duplications
#endif
}
+void TIntermediate::sharedBlockCheck(TInfoSink& infoSink)
+{
+ bool has_shared_block = false;
+ bool has_shared_non_block = false;
+ TIntermSequence& linkObjects = findLinkerObjects()->getSequence();
+ for (size_t i = 0; i < linkObjects.size(); ++i) {
+ const TType& type = linkObjects[i]->getAsTyped()->getType();
+ const TQualifier& qualifier = type.getQualifier();
+ if (qualifier.storage == glslang::EvqShared) {
+ if (type.getBasicType() == glslang::EbtBlock)
+ has_shared_block = true;
+ else
+ has_shared_non_block = true;
+ }
+ }
+ if (has_shared_block && has_shared_non_block)
+ error(infoSink, "cannot mix use of shared variables inside and outside blocks");
+}
+
//
// Do final link-time error checking of a complete (merged) intermediate representation.
// (Much error checking was done during merging).
error(infoSink, "post_depth_coverage requires early_fragment_tests");
break;
case EShLangCompute:
+ sharedBlockCheck(infoSink);
break;
case EShLangRayGen:
case EShLangIntersect:
case EShLangTaskNV:
if (numTaskNVBlocks > 1)
error(infoSink, "Only one taskNV interface block is allowed per shader");
+ sharedBlockCheck(infoSink);
break;
default:
error(infoSink, "Unknown Stage.");
void checkCallGraphCycles(TInfoSink&);
void checkCallGraphBodies(TInfoSink&, bool keepUncalled);
void inOutLocationCheck(TInfoSink&);
+ void sharedBlockCheck(TInfoSink&);
bool userOutputUsed() const;
bool isSpecializationOperation(const TIntermOperator&) const;
bool isNonuniformPropagating(TOperator) const;
"spv.ext.World3x4.rahit",
"spv.ext.AccelDecl.frag",
"spv.ext.RayQueryDecl.frag",
+
+ // SPV_KHR_workgroup_memory_explicit_layout depends on SPIR-V 1.4.
+ "spv.WorkgroupMemoryExplicitLayout.SingleBlock.comp",
+ "spv.WorkgroupMemoryExplicitLayout.MultiBlock.comp",
+ "spv.WorkgroupMemoryExplicitLayout.8BitAccess.comp",
+ "spv.WorkgroupMemoryExplicitLayout.16BitAccess.comp",
+ "spv.WorkgroupMemoryExplicitLayout.NonBlock.comp",
+ "spv.WorkgroupMemoryExplicitLayout.MixBlockNonBlock_Errors.comp",
+ "spv.WorkgroupMemoryExplicitLayout.std140.comp",
+ "spv.WorkgroupMemoryExplicitLayout.std430.comp",
+ "spv.WorkgroupMemoryExplicitLayout.scalar.comp",
})),
FileNameAsCustomTestSuffix
);