From a38df83d3ec985d2fd569a29aac69c074083b4b6 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Wed, 27 Jan 2021 00:30:59 -0800 Subject: [PATCH 1/3] Consider GL_EXT_scalar_block_layout when validating SPIR-V If GL_EXT_scalar_block_layout is requested by the shader, set the option to allow scalar blocks in the SPIR-V validator. Fix the existing tests using scalar layout to not expect "Validation failed". Fixes #2400. --- SPIRV/SpvTools.cpp | 1 + Test/baseResults/spv.scalarlayout.frag.out | 1 - Test/baseResults/spv.scalarlayoutfloat16.frag.out | 1 - glslang/MachineIndependent/localintermediate.h | 8 ++++++++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/SPIRV/SpvTools.cpp b/SPIRV/SpvTools.cpp index 16d051a9..56eb2484 100644 --- a/SPIRV/SpvTools.cpp +++ b/SPIRV/SpvTools.cpp @@ -153,6 +153,7 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector< spv_validator_options options = spvValidatorOptionsCreate(); spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets()); spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization); + spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout()); spvValidateWithOptions(context, options, &binary, &diagnostic); // report diff --git a/Test/baseResults/spv.scalarlayout.frag.out b/Test/baseResults/spv.scalarlayout.frag.out index 549efaa8..e08721f8 100644 --- a/Test/baseResults/spv.scalarlayout.frag.out +++ b/Test/baseResults/spv.scalarlayout.frag.out @@ -1,5 +1,4 @@ spv.scalarlayout.frag -Validation failed // Module Version 10000 // Generated by (magic number): 8000a // Id's are bound by 20 diff --git a/Test/baseResults/spv.scalarlayoutfloat16.frag.out b/Test/baseResults/spv.scalarlayoutfloat16.frag.out index fc0dca84..4f22730e 100644 --- a/Test/baseResults/spv.scalarlayoutfloat16.frag.out +++ b/Test/baseResults/spv.scalarlayoutfloat16.frag.out @@ -1,5 +1,4 @@ spv.scalarlayoutfloat16.frag -Validation failed // Module Version 10000 // Generated by (magic number): 8000a // Id's are bound by 18 diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index f8d8e801..d581959d 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -858,6 +858,14 @@ public: bool usingHlslIoMapping() { return false; } #endif + bool usingScalarBlockLayout() const { + for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt) { + if (*extIt == E_GL_EXT_scalar_block_layout) + return true; + } + return false; + }; + void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee); void merge(TInfoSink&, TIntermediate&); void finalCheck(TInfoSink&, bool keepUncalled); From 3785ddd59ae7a1e8fc854635c857455376a291f1 Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Tue, 12 May 2020 08:29:00 -0700 Subject: [PATCH 2/3] Update known_good.json to pick up SPV_KHR_workgroup_memory_explicit_layout Also update the test expectations regarding validation accordingly and the in-tree spirv.hpp copy. --- SPIRV/spirv.hpp | 94 ++++++++++++++++++- Test/baseResults/hlsl.load.2dms.dx10.frag.out | 1 + .../hlsl.load.offset.dx10.frag.out | 1 + .../hlsl.load.offsetarray.dx10.frag.out | 1 + Test/baseResults/spv.nullInit.comp.out | 1 - known_good.json | 4 +- 6 files changed, 97 insertions(+), 5 deletions(-) diff --git a/SPIRV/spirv.hpp b/SPIRV/spirv.hpp index 43dd2aae..af629efa 100644 --- a/SPIRV/spirv.hpp +++ b/SPIRV/spirv.hpp @@ -168,10 +168,16 @@ enum ExecutionMode { ExecutionModeSampleInterlockUnorderedEXT = 5369, ExecutionModeShadingRateInterlockOrderedEXT = 5370, ExecutionModeShadingRateInterlockUnorderedEXT = 5371, + ExecutionModeSharedLocalMemorySizeINTEL = 5618, + ExecutionModeRoundingModeRTPINTEL = 5620, + ExecutionModeRoundingModeRTNINTEL = 5621, + ExecutionModeFloatingPointModeALTINTEL = 5622, + ExecutionModeFloatingPointModeIEEEINTEL = 5623, ExecutionModeMaxWorkgroupSizeINTEL = 5893, ExecutionModeMaxWorkDimINTEL = 5894, ExecutionModeNoGlobalOffsetINTEL = 5895, ExecutionModeNumSIMDWorkitemsINTEL = 5896, + ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, ExecutionModeMax = 0x7fffffff, }; @@ -204,6 +210,8 @@ enum StorageClass { StorageClassPhysicalStorageBuffer = 5349, StorageClassPhysicalStorageBufferEXT = 5349, StorageClassCodeSectionINTEL = 5605, + StorageClassDeviceOnlyINTEL = 5936, + StorageClassHostOnlyINTEL = 5937, StorageClassMax = 0x7fffffff, }; @@ -374,6 +382,8 @@ enum FPFastMathModeShift { FPFastMathModeNSZShift = 2, FPFastMathModeAllowRecipShift = 3, FPFastMathModeFastShift = 4, + FPFastMathModeAllowContractFastINTELShift = 16, + FPFastMathModeAllowReassocINTELShift = 17, FPFastMathModeMax = 0x7fffffff, }; @@ -384,6 +394,8 @@ enum FPFastMathModeMask { FPFastMathModeNSZMask = 0x00000004, FPFastMathModeAllowRecipMask = 0x00000008, FPFastMathModeFastMask = 0x00000010, + FPFastMathModeAllowContractFastINTELMask = 0x00010000, + FPFastMathModeAllowReassocINTELMask = 0x00020000, }; enum FPRoundingMode { @@ -484,12 +496,22 @@ enum Decoration { DecorationRestrictPointerEXT = 5355, DecorationAliasedPointer = 5356, DecorationAliasedPointerEXT = 5356, + DecorationSIMTCallINTEL = 5599, DecorationReferencedIndirectlyINTEL = 5602, + DecorationClobberINTEL = 5607, + DecorationSideEffectsINTEL = 5608, + DecorationVectorComputeVariableINTEL = 5624, + DecorationFuncParamIOKindINTEL = 5625, + DecorationVectorComputeFunctionINTEL = 5626, + DecorationStackCallINTEL = 5627, + DecorationGlobalVariableOffsetINTEL = 5628, DecorationCounterBuffer = 5634, DecorationHlslCounterBufferGOOGLE = 5634, DecorationHlslSemanticGOOGLE = 5635, DecorationUserSemantic = 5635, DecorationUserTypeGOOGLE = 5636, + DecorationFunctionRoundingModeINTEL = 5822, + DecorationFunctionDenormModeINTEL = 5823, DecorationRegisterINTEL = 5825, DecorationMemoryINTEL = 5826, DecorationNumbanksINTEL = 5827, @@ -502,6 +524,17 @@ enum Decoration { DecorationMergeINTEL = 5834, DecorationBankBitsINTEL = 5835, DecorationForcePow2DepthINTEL = 5836, + DecorationBurstCoalesceINTEL = 5899, + DecorationCacheSizeINTEL = 5900, + DecorationDontStaticallyCoalesceINTEL = 5901, + DecorationPrefetchINTEL = 5902, + DecorationStallEnableINTEL = 5905, + DecorationFuseLoopsInFunctionINTEL = 5907, + DecorationBufferLocationINTEL = 5921, + DecorationIOPipeStorageINTEL = 5944, + DecorationFunctionFloatingPointModeINTEL = 6080, + DecorationSingleElementVectorINTEL = 6085, + DecorationVectorComputeCallableFunctionINTEL = 6087, DecorationMax = 0x7fffffff, }; @@ -656,6 +689,7 @@ enum LoopControlShift { LoopControlLoopCoalesceINTELShift = 20, LoopControlMaxInterleavingINTELShift = 21, LoopControlSpeculatedIterationsINTELShift = 22, + LoopControlNoFusionINTELShift = 23, LoopControlMax = 0x7fffffff, }; @@ -677,6 +711,7 @@ enum LoopControlMask { LoopControlLoopCoalesceINTELMask = 0x00100000, LoopControlMaxInterleavingINTELMask = 0x00200000, LoopControlSpeculatedIterationsINTELMask = 0x00400000, + LoopControlNoFusionINTELMask = 0x00800000, }; enum FunctionControlShift { @@ -876,6 +911,9 @@ enum Capability { CapabilityFragmentShadingRateKHR = 4422, CapabilitySubgroupBallotKHR = 4423, CapabilityDrawParameters = 4427, + CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, + CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, CapabilitySubgroupVoteKHR = 4431, CapabilityStorageBuffer16BitAccess = 4433, CapabilityStorageUniformBufferBlock16 = 4433, @@ -966,21 +1004,37 @@ enum Capability { CapabilitySubgroupBufferBlockIOINTEL = 5569, CapabilitySubgroupImageBlockIOINTEL = 5570, CapabilitySubgroupImageMediaBlockIOINTEL = 5579, + CapabilityRoundToInfinityINTEL = 5582, + CapabilityFloatingPointModeINTEL = 5583, CapabilityIntegerFunctions2INTEL = 5584, CapabilityFunctionPointersINTEL = 5603, CapabilityIndirectReferencesINTEL = 5604, + CapabilityAsmINTEL = 5606, + CapabilityVectorComputeINTEL = 5617, + CapabilityVectorAnyINTEL = 5619, CapabilitySubgroupAvcMotionEstimationINTEL = 5696, CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + CapabilityVariableLengthArrayINTEL = 5817, + CapabilityFunctionFloatControlINTEL = 5821, CapabilityFPGAMemoryAttributesINTEL = 5824, + CapabilityFPFastMathModeINTEL = 5837, + CapabilityArbitraryPrecisionIntegersINTEL = 5844, CapabilityUnstructuredLoopControlsINTEL = 5886, CapabilityFPGALoopControlsINTEL = 5888, CapabilityKernelAttributesINTEL = 5892, CapabilityFPGAKernelAttributesINTEL = 5897, + CapabilityFPGAMemoryAccessesINTEL = 5898, + CapabilityFPGAClusterAttributesINTEL = 5904, + CapabilityLoopFuseINTEL = 5906, + CapabilityFPGABufferLocationINTEL = 5920, + CapabilityUSMStorageClassesINTEL = 5935, + CapabilityIOPipesINTEL = 5943, CapabilityBlockingPipesINTEL = 5945, CapabilityFPGARegINTEL = 5948, CapabilityAtomicFloat32AddEXT = 6033, CapabilityAtomicFloat64AddEXT = 6034, + CapabilityLongConstantCompositeINTEL = 6089, CapabilityMax = 0x7fffffff, }; @@ -1047,6 +1101,18 @@ enum FragmentShadingRateMask { FragmentShadingRateHorizontal4PixelsMask = 0x00000008, }; +enum FPDenormMode { + FPDenormModePreserve = 0, + FPDenormModeFlushToZero = 1, + FPDenormModeMax = 0x7fffffff, +}; + +enum FPOperationMode { + FPOperationModeIEEE = 0, + FPOperationModeALT = 1, + FPOperationModeMax = 0x7fffffff, +}; + enum Op { OpNop = 0, OpUndef = 1, @@ -1466,8 +1532,11 @@ enum Op { OpUSubSatINTEL = 5596, OpIMul32x16INTEL = 5597, OpUMul32x16INTEL = 5598, - OpFunctionPointerINTEL = 5600, + OpConstFunctionPointerINTEL = 5600, OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, OpDecorateString = 5632, OpDecorateStringGOOGLE = 5632, OpMemberDecorateString = 5633, @@ -1590,7 +1659,12 @@ enum Op { OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, OpLoopControlINTEL = 5887, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, OpReadPipeBlockingINTEL = 5946, OpWritePipeBlockingINTEL = 5947, OpFPGARegINTEL = 5949, @@ -1612,6 +1686,10 @@ enum Op { OpRayQueryGetIntersectionObjectToWorldKHR = 6031, OpRayQueryGetIntersectionWorldToObjectKHR = 6032, OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, OpMax = 0x7fffffff, }; @@ -2036,8 +2114,11 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; - case OpFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case OpConstFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; case OpDecorateString: *hasResult = false; *hasResultType = false; break; case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; @@ -2158,7 +2239,12 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; @@ -2180,6 +2266,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; } } #endif /* SPV_ENABLE_UTILITY_CODE */ diff --git a/Test/baseResults/hlsl.load.2dms.dx10.frag.out b/Test/baseResults/hlsl.load.2dms.dx10.frag.out index 99860745..02365b8f 100644 --- a/Test/baseResults/hlsl.load.2dms.dx10.frag.out +++ b/Test/baseResults/hlsl.load.2dms.dx10.frag.out @@ -357,6 +357,7 @@ using depth_any 0:? '@entryPointOutput.Depth' ( out float FragDepth) 0:? '@entryPointOutput.Color' (layout( location=0) out 4-component vector of float) +Validation failed // Module Version 10000 // Generated by (magic number): 8000a // Id's are bound by 130 diff --git a/Test/baseResults/hlsl.load.offset.dx10.frag.out b/Test/baseResults/hlsl.load.offset.dx10.frag.out index d0fa5fd4..135b4afa 100644 --- a/Test/baseResults/hlsl.load.offset.dx10.frag.out +++ b/Test/baseResults/hlsl.load.offset.dx10.frag.out @@ -561,6 +561,7 @@ using depth_any 0:? '@entryPointOutput.Depth' ( out float FragDepth) 0:? '@entryPointOutput.Color' (layout( location=0) out 4-component vector of float) +Validation failed // Module Version 10000 // Generated by (magic number): 8000a // Id's are bound by 201 diff --git a/Test/baseResults/hlsl.load.offsetarray.dx10.frag.out b/Test/baseResults/hlsl.load.offsetarray.dx10.frag.out index a379068a..24aa3680 100644 --- a/Test/baseResults/hlsl.load.offsetarray.dx10.frag.out +++ b/Test/baseResults/hlsl.load.offsetarray.dx10.frag.out @@ -435,6 +435,7 @@ using depth_any 0:? '@entryPointOutput.Depth' ( out float FragDepth) 0:? '@entryPointOutput.Color' (layout( location=0) out 4-component vector of float) +Validation failed // Module Version 10000 // Generated by (magic number): 8000a // Id's are bound by 174 diff --git a/Test/baseResults/spv.nullInit.comp.out b/Test/baseResults/spv.nullInit.comp.out index a8e231b8..b7908b57 100755 --- a/Test/baseResults/spv.nullInit.comp.out +++ b/Test/baseResults/spv.nullInit.comp.out @@ -1,5 +1,4 @@ spv.nullInit.comp -Validation failed // Module Version 10000 // Generated by (magic number): 8000a // Id's are bound by 37 diff --git a/known_good.json b/known_good.json index a01735ba..90105383 100644 --- a/known_good.json +++ b/known_good.json @@ -5,14 +5,14 @@ "site" : "github", "subrepo" : "KhronosGroup/SPIRV-Tools", "subdir" : "External/spirv-tools", - "commit" : "ad898cb9498c65cac7c5b6f9ebddb610bd0852ad" + "commit" : "b812fd634ea5ff307c374fb2b6340169f7db8b16" }, { "name" : "spirv-tools/external/spirv-headers", "site" : "github", "subrepo" : "KhronosGroup/SPIRV-Headers", "subdir" : "External/spirv-tools/external/spirv-headers", - "commit" : "f027d53ded7e230e008d37c8b47ede7cd308e19d" + "commit" : "faa570afbc91ac73d594d787486bcf8f2df1ace0" } ] } From 4bfbf62794a037533a6d856184a93d499306508c Mon Sep 17 00:00:00 2001 From: Caio Marcelo de Oliveira Filho Date: Tue, 2 Jun 2020 16:58:51 -0700 Subject: [PATCH 3/3] Add support for GL_EXT_shared_memory_block Uses SPV_KHR_workgroup_memory_explicit_layout. Note that if GL_EXT_scalar_block_layout is enabled, Workgroup blocks can also use scalar layout. --- SPIRV/GLSL.ext.KHR.h | 1 + SPIRV/GlslangToSpv.cpp | 17 ++++ SPIRV/SpvPostProcess.cpp | 25 ++++++ SPIRV/SpvTools.cpp | 1 + SPIRV/doc.cpp | 4 + Test/baseResults/310.comp.out | 2 +- Test/baseResults/400.frag.out | 2 +- Test/baseResults/430.comp.out | 2 +- ...pMemoryExplicitLayout.16BitAccess.comp.out | 54 ++++++++++++ ...upMemoryExplicitLayout.8BitAccess.comp.out | 45 ++++++++++ ...citLayout.MixBlockNonBlock_Errors.comp.out | 4 + ...upMemoryExplicitLayout.MultiBlock.comp.out | 54 ++++++++++++ ...roupMemoryExplicitLayout.NonBlock.comp.out | 35 ++++++++ ...pMemoryExplicitLayout.SingleBlock.comp.out | 41 +++++++++ ...kgroupMemoryExplicitLayout.scalar.comp.out | 84 +++++++++++++++++++ ...kgroupMemoryExplicitLayout.std140.comp.out | 83 ++++++++++++++++++ ...kgroupMemoryExplicitLayout.std430.comp.out | 83 ++++++++++++++++++ ...groupMemoryExplicitLayout.16BitAccess.comp | 18 ++++ ...kgroupMemoryExplicitLayout.8BitAccess.comp | 16 ++++ ...xplicitLayout.MixBlockNonBlock_Errors.comp | 20 +++++ ...kgroupMemoryExplicitLayout.MultiBlock.comp | 21 +++++ ...orkgroupMemoryExplicitLayout.NonBlock.comp | 14 ++++ ...groupMemoryExplicitLayout.SingleBlock.comp | 15 ++++ ....WorkgroupMemoryExplicitLayout.scalar.comp | 39 +++++++++ ....WorkgroupMemoryExplicitLayout.std140.comp | 35 ++++++++ ....WorkgroupMemoryExplicitLayout.std430.comp | 35 ++++++++ glslang/MachineIndependent/ParseHelper.cpp | 43 ++++++++-- glslang/MachineIndependent/ParseHelper.h | 1 + glslang/MachineIndependent/Versions.cpp | 2 + glslang/MachineIndependent/Versions.h | 1 + glslang/MachineIndependent/linkValidate.cpp | 21 +++++ .../MachineIndependent/localintermediate.h | 1 + gtests/Spv.FromFile.cpp | 11 +++ 33 files changed, 822 insertions(+), 8 deletions(-) create mode 100644 Test/baseResults/spv.WorkgroupMemoryExplicitLayout.16BitAccess.comp.out create mode 100644 Test/baseResults/spv.WorkgroupMemoryExplicitLayout.8BitAccess.comp.out create mode 100644 Test/baseResults/spv.WorkgroupMemoryExplicitLayout.MixBlockNonBlock_Errors.comp.out create mode 100644 Test/baseResults/spv.WorkgroupMemoryExplicitLayout.MultiBlock.comp.out create mode 100644 Test/baseResults/spv.WorkgroupMemoryExplicitLayout.NonBlock.comp.out create mode 100644 Test/baseResults/spv.WorkgroupMemoryExplicitLayout.SingleBlock.comp.out create mode 100644 Test/baseResults/spv.WorkgroupMemoryExplicitLayout.scalar.comp.out create mode 100644 Test/baseResults/spv.WorkgroupMemoryExplicitLayout.std140.comp.out create mode 100644 Test/baseResults/spv.WorkgroupMemoryExplicitLayout.std430.comp.out create mode 100644 Test/spv.WorkgroupMemoryExplicitLayout.16BitAccess.comp create mode 100644 Test/spv.WorkgroupMemoryExplicitLayout.8BitAccess.comp create mode 100644 Test/spv.WorkgroupMemoryExplicitLayout.MixBlockNonBlock_Errors.comp create mode 100644 Test/spv.WorkgroupMemoryExplicitLayout.MultiBlock.comp create mode 100644 Test/spv.WorkgroupMemoryExplicitLayout.NonBlock.comp create mode 100644 Test/spv.WorkgroupMemoryExplicitLayout.SingleBlock.comp create mode 100644 Test/spv.WorkgroupMemoryExplicitLayout.scalar.comp create mode 100644 Test/spv.WorkgroupMemoryExplicitLayout.std140.comp create mode 100644 Test/spv.WorkgroupMemoryExplicitLayout.std430.comp diff --git a/SPIRV/GLSL.ext.KHR.h b/SPIRV/GLSL.ext.KHR.h index 9610c6ee..175fa8d5 100644 --- a/SPIRV/GLSL.ext.KHR.h +++ b/SPIRV/GLSL.ext.KHR.h @@ -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 diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 49baf978..5ad2d333 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -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; diff --git a/SPIRV/SpvPostProcess.cpp b/SPIRV/SpvPostProcess.cpp index 36d568f0..23d7b5a4 100644 --- a/SPIRV/SpvPostProcess.cpp +++ b/SPIRV/SpvPostProcess.cpp @@ -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 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 diff --git a/SPIRV/SpvTools.cpp b/SPIRV/SpvTools.cpp index 56eb2484..5cfc4262 100644 --- a/SPIRV/SpvTools.cpp +++ b/SPIRV/SpvTools.cpp @@ -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 diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp index 5327f221..6805c3a6 100644 --- a/SPIRV/doc.cpp +++ b/SPIRV/doc.cpp @@ -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"; } } diff --git a/Test/baseResults/310.comp.out b/Test/baseResults/310.comp.out index 8874e20b..85b01161 100644 --- a/Test/baseResults/310.comp.out +++ b/Test/baseResults/310.comp.out @@ -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' diff --git a/Test/baseResults/400.frag.out b/Test/baseResults/400.frag.out index 90f73dc7..b7e88df9 100644 --- a/Test/baseResults/400.frag.out +++ b/Test/baseResults/400.frag.out @@ -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 diff --git a/Test/baseResults/430.comp.out b/Test/baseResults/430.comp.out index ee126a0f..4d8495bc 100644 --- a/Test/baseResults/430.comp.out +++ b/Test/baseResults/430.comp.out @@ -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 index 00000000..31dd2dd1 --- /dev/null +++ b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.16BitAccess.comp.out @@ -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 index 00000000..3447791f --- /dev/null +++ b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.8BitAccess.comp.out @@ -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 index 00000000..82495d11 --- /dev/null +++ b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.MixBlockNonBlock_Errors.comp.out @@ -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 index 00000000..b578bd3a --- /dev/null +++ b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.MultiBlock.comp.out @@ -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 index 00000000..19bcff6b --- /dev/null +++ b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.NonBlock.comp.out @@ -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 index 00000000..413fd2e8 --- /dev/null +++ b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.SingleBlock.comp.out @@ -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 index 00000000..6a43e236 --- /dev/null +++ b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.scalar.comp.out @@ -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 index 00000000..df4b8aed --- /dev/null +++ b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.std140.comp.out @@ -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 index 00000000..e782784b --- /dev/null +++ b/Test/baseResults/spv.WorkgroupMemoryExplicitLayout.std430.comp.out @@ -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 index 00000000..e06555e4 --- /dev/null +++ b/Test/spv.WorkgroupMemoryExplicitLayout.16BitAccess.comp @@ -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 index 00000000..aaa512c2 --- /dev/null +++ b/Test/spv.WorkgroupMemoryExplicitLayout.8BitAccess.comp @@ -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 index 00000000..573d0922 --- /dev/null +++ b/Test/spv.WorkgroupMemoryExplicitLayout.MixBlockNonBlock_Errors.comp @@ -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 index 00000000..675a4433 --- /dev/null +++ b/Test/spv.WorkgroupMemoryExplicitLayout.MultiBlock.comp @@ -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 index 00000000..38316a50 --- /dev/null +++ b/Test/spv.WorkgroupMemoryExplicitLayout.NonBlock.comp @@ -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 index 00000000..2a17c61c --- /dev/null +++ b/Test/spv.WorkgroupMemoryExplicitLayout.SingleBlock.comp @@ -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 index 00000000..38085b4d --- /dev/null +++ b/Test/spv.WorkgroupMemoryExplicitLayout.scalar.comp @@ -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 index 00000000..f4f2475a --- /dev/null +++ b/Test/spv.WorkgroupMemoryExplicitLayout.std140.comp @@ -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 index 00000000..717593b6 --- /dev/null +++ b/Test/spv.WorkgroupMemoryExplicitLayout.std430.comp @@ -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() +{ +} diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index d4b360ce..8927b823 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -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; } diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index fe2b6fbb..4093fbfe 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -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 diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 517ff9f8..488c98c5 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -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" diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index 6b5efbce..f377973a 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -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 diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 4e84adbf..2d14031c 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -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."); diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index d581959d..84d19d45 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -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; diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 83aac827..2ee292e4 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -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 );