Add support for GL_EXT_shared_memory_block
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Tue, 2 Jun 2020 23:58:51 +0000 (16:58 -0700)
committerCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Fri, 29 Jan 2021 19:23:05 +0000 (11:23 -0800)
Uses SPV_KHR_workgroup_memory_explicit_layout.  Note that if
GL_EXT_scalar_block_layout is enabled, Workgroup blocks can also use
scalar layout.

33 files changed:
SPIRV/GLSL.ext.KHR.h
SPIRV/GlslangToSpv.cpp
SPIRV/SpvPostProcess.cpp
SPIRV/SpvTools.cpp
SPIRV/doc.cpp
Test/baseResults/310.comp.out
Test/baseResults/400.frag.out
Test/baseResults/430.comp.out
Test/baseResults/spv.WorkgroupMemoryExplicitLayout.16BitAccess.comp.out [new file with mode: 0644]
Test/baseResults/spv.WorkgroupMemoryExplicitLayout.8BitAccess.comp.out [new file with mode: 0644]
Test/baseResults/spv.WorkgroupMemoryExplicitLayout.MixBlockNonBlock_Errors.comp.out [new file with mode: 0644]
Test/baseResults/spv.WorkgroupMemoryExplicitLayout.MultiBlock.comp.out [new file with mode: 0644]
Test/baseResults/spv.WorkgroupMemoryExplicitLayout.NonBlock.comp.out [new file with mode: 0644]
Test/baseResults/spv.WorkgroupMemoryExplicitLayout.SingleBlock.comp.out [new file with mode: 0644]
Test/baseResults/spv.WorkgroupMemoryExplicitLayout.scalar.comp.out [new file with mode: 0644]
Test/baseResults/spv.WorkgroupMemoryExplicitLayout.std140.comp.out [new file with mode: 0644]
Test/baseResults/spv.WorkgroupMemoryExplicitLayout.std430.comp.out [new file with mode: 0644]
Test/spv.WorkgroupMemoryExplicitLayout.16BitAccess.comp [new file with mode: 0644]
Test/spv.WorkgroupMemoryExplicitLayout.8BitAccess.comp [new file with mode: 0644]
Test/spv.WorkgroupMemoryExplicitLayout.MixBlockNonBlock_Errors.comp [new file with mode: 0644]
Test/spv.WorkgroupMemoryExplicitLayout.MultiBlock.comp [new file with mode: 0644]
Test/spv.WorkgroupMemoryExplicitLayout.NonBlock.comp [new file with mode: 0644]
Test/spv.WorkgroupMemoryExplicitLayout.SingleBlock.comp [new file with mode: 0644]
Test/spv.WorkgroupMemoryExplicitLayout.scalar.comp [new file with mode: 0644]
Test/spv.WorkgroupMemoryExplicitLayout.std140.comp [new file with mode: 0644]
Test/spv.WorkgroupMemoryExplicitLayout.std430.comp [new file with mode: 0644]
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.h
glslang/MachineIndependent/Versions.cpp
glslang/MachineIndependent/Versions.h
glslang/MachineIndependent/linkValidate.cpp
glslang/MachineIndependent/localintermediate.h
gtests/Spv.FromFile.cpp

index 9610c6e..175fa8d 100644 (file)
@@ -50,5 +50,6 @@ static const char* const E_SPV_KHR_ray_tracing                  = "SPV_KHR_ray_t
 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
index 49baf97..5ad2d33 100644 (file)
@@ -380,6 +380,7 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto
         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;
@@ -436,6 +437,7 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T
             break;
         case glslang::EbtBlock:
             switch (type.getQualifier().storage) {
+            case glslang::EvqShared:
             case glslang::EvqUniform:
             case glslang::EvqBuffer:
                 switch (type.getQualifier().layoutPacking) {
@@ -1278,6 +1280,12 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
         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;
@@ -3623,6 +3631,11 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
             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())
@@ -3641,6 +3654,9 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
         } 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);
         }
@@ -4407,6 +4423,7 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang:
     // 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;
 
index 36d568f..23d7b5a 100644 (file)
@@ -443,6 +443,31 @@ void Builder::postProcessFeatures() {
         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
 
index 56eb248..5cfc426 100644 (file)
@@ -154,6 +154,7 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<
     spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
     spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization);
     spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
+    spvValidatorOptionsSetWorkgroupScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
     spvValidateWithOptions(context, options, &binary, &diagnostic);
 
     // report
index 5327f22..6805c3a 100644 (file)
@@ -967,6 +967,10 @@ const char* CapabilityString(int info)
     case CapabilityAtomicFloat32AddEXT:                     return "AtomicFloat32AddEXT";
     case CapabilityAtomicFloat64AddEXT:                     return "AtomicFloat64AddEXT";
 
+    case CapabilityWorkgroupMemoryExplicitLayoutKHR:            return "CapabilityWorkgroupMemoryExplicitLayoutKHR";
+    case CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR:  return "CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR";
+    case CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR";
+
     default: return "Bad";
     }
 }
index 8874e20..85b0116 100644 (file)
@@ -7,7 +7,7 @@ ERROR: 0:39: 'in' : global storage input qualifier cannot be used in a compute s
 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' 
index 90f73dc..b7e88df 100644 (file)
@@ -34,7 +34,7 @@ ERROR: 0:183: 'assign' :  cannot convert from ' const float' to ' temp 2-compone
 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
index ee126a0..4d8495b 100644 (file)
@@ -5,7 +5,7 @@ ERROR: 0:43: 'in' : global storage input qualifier cannot be used in a compute s
 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 
diff --git a/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.16BitAccess.comp.out b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.16BitAccess.comp.out
new file mode 100644 (file)
index 0000000..31dd2dd
--- /dev/null
@@ -0,0 +1,54 @@
+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
diff --git a/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.8BitAccess.comp.out b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.8BitAccess.comp.out
new file mode 100644 (file)
index 0000000..3447791
--- /dev/null
@@ -0,0 +1,45 @@
+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
diff --git a/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.MixBlockNonBlock_Errors.comp.out b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.MixBlockNonBlock_Errors.comp.out
new file mode 100644 (file)
index 0000000..82495d1
--- /dev/null
@@ -0,0 +1,4 @@
+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
diff --git a/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.MultiBlock.comp.out b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.MultiBlock.comp.out
new file mode 100644 (file)
index 0000000..b578bd3
--- /dev/null
@@ -0,0 +1,54 @@
+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
diff --git a/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.NonBlock.comp.out b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.NonBlock.comp.out
new file mode 100644 (file)
index 0000000..19bcff6
--- /dev/null
@@ -0,0 +1,35 @@
+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
diff --git a/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.SingleBlock.comp.out b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.SingleBlock.comp.out
new file mode 100644 (file)
index 0000000..413fd2e
--- /dev/null
@@ -0,0 +1,41 @@
+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
diff --git a/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.scalar.comp.out b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.scalar.comp.out
new file mode 100644 (file)
index 0000000..6a43e23
--- /dev/null
@@ -0,0 +1,84 @@
+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
diff --git a/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.std140.comp.out b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.std140.comp.out
new file mode 100644 (file)
index 0000000..df4b8ae
--- /dev/null
@@ -0,0 +1,83 @@
+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
diff --git a/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.std430.comp.out b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.std430.comp.out
new file mode 100644 (file)
index 0000000..e782784
--- /dev/null
@@ -0,0 +1,83 @@
+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
diff --git a/Test/spv.WorkgroupMemoryExplicitLayout.16BitAccess.comp b/Test/spv.WorkgroupMemoryExplicitLayout.16BitAccess.comp
new file mode 100644 (file)
index 0000000..e06555e
--- /dev/null
@@ -0,0 +1,18 @@
+#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);
+}
diff --git a/Test/spv.WorkgroupMemoryExplicitLayout.8BitAccess.comp b/Test/spv.WorkgroupMemoryExplicitLayout.8BitAccess.comp
new file mode 100644 (file)
index 0000000..aaa512c
--- /dev/null
@@ -0,0 +1,16 @@
+#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);
+}
diff --git a/Test/spv.WorkgroupMemoryExplicitLayout.MixBlockNonBlock_Errors.comp b/Test/spv.WorkgroupMemoryExplicitLayout.MixBlockNonBlock_Errors.comp
new file mode 100644 (file)
index 0000000..573d092
--- /dev/null
@@ -0,0 +1,20 @@
+#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;
+}
diff --git a/Test/spv.WorkgroupMemoryExplicitLayout.MultiBlock.comp b/Test/spv.WorkgroupMemoryExplicitLayout.MultiBlock.comp
new file mode 100644 (file)
index 0000000..675a443
--- /dev/null
@@ -0,0 +1,21 @@
+#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;
+}
diff --git a/Test/spv.WorkgroupMemoryExplicitLayout.NonBlock.comp b/Test/spv.WorkgroupMemoryExplicitLayout.NonBlock.comp
new file mode 100644 (file)
index 0000000..38316a5
--- /dev/null
@@ -0,0 +1,14 @@
+#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;
+}
diff --git a/Test/spv.WorkgroupMemoryExplicitLayout.SingleBlock.comp b/Test/spv.WorkgroupMemoryExplicitLayout.SingleBlock.comp
new file mode 100644 (file)
index 0000000..2a17c61
--- /dev/null
@@ -0,0 +1,15 @@
+#version 430 core
+
+#extension GL_EXT_shared_memory_block : enable
+
+layout(local_size_x = 8) in;
+
+shared first
+{
+    int a;
+};
+
+void main()
+{
+    a = 2;
+}
diff --git a/Test/spv.WorkgroupMemoryExplicitLayout.scalar.comp b/Test/spv.WorkgroupMemoryExplicitLayout.scalar.comp
new file mode 100644 (file)
index 0000000..38085b4
--- /dev/null
@@ -0,0 +1,39 @@
+#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()
+{
+}
diff --git a/Test/spv.WorkgroupMemoryExplicitLayout.std140.comp b/Test/spv.WorkgroupMemoryExplicitLayout.std140.comp
new file mode 100644 (file)
index 0000000..f4f2475
--- /dev/null
@@ -0,0 +1,35 @@
+#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()
+{
+}
diff --git a/Test/spv.WorkgroupMemoryExplicitLayout.std430.comp b/Test/spv.WorkgroupMemoryExplicitLayout.std430.comp
new file mode 100644 (file)
index 0000000..717593b
--- /dev/null
@@ -0,0 +1,35 @@
+#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()
+{
+}
index d4b360c..8927b82 100644 (file)
@@ -87,6 +87,10 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b
     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
@@ -6033,12 +6037,28 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
     }
 }
 
+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())
@@ -6121,7 +6141,7 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier
             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())
@@ -7667,6 +7687,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
     case EvqBuffer:     defaultQualification = globalBufferDefaults;     break;
     case EvqVaryingIn:  defaultQualification = globalInputDefaults;      break;
     case EvqVaryingOut: defaultQualification = globalOutputDefaults;     break;
+    case EvqShared:     defaultQualification = globalSharedDefaults;     break;
     default:            defaultQualification.clear();                    break;
     }
 
@@ -7930,6 +7951,12 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
             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");
@@ -8088,7 +8115,7 @@ void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
 //
 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;
@@ -8602,8 +8629,14 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
         }
 #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;
     }
 
index fe2b6fb..4093fbf 100644 (file)
@@ -485,6 +485,7 @@ protected:
     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
index 517ff9f..488c98c 100644 (file)
@@ -331,6 +331,7 @@ void TParseVersions::initializeExtensionBehavior()
     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;
@@ -472,6 +473,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#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"
index 6b5efbc..f377973 100644 (file)
@@ -202,6 +202,7 @@ const char* const E_GL_EXT_shader_implicit_conversions      = "GL_EXT_shader_imp
 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
 
index 4e84adb..2d14031 100644 (file)
@@ -653,6 +653,25 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
 #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).
@@ -778,6 +797,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
             error(infoSink, "post_depth_coverage requires early_fragment_tests");
         break;
     case EShLangCompute:
+        sharedBlockCheck(infoSink);
         break;
     case EShLangRayGen:
     case EShLangIntersect:
@@ -810,6 +830,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
     case EShLangTaskNV:
         if (numTaskNVBlocks > 1)
             error(infoSink, "Only one taskNV interface block is allowed per shader");
+        sharedBlockCheck(infoSink);
         break;
     default:
         error(infoSink, "Unknown Stage.");
index d581959..84d19d4 100644 (file)
@@ -954,6 +954,7 @@ protected:
     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;
index 83aac82..2ee292e 100644 (file)
@@ -582,6 +582,17 @@ INSTANTIATE_TEST_SUITE_P(
         "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
 );