From 38a52fca935f9b4036b17957a25d023dfb521947 Mon Sep 17 00:00:00 2001 From: Jeff Bolz Date: Fri, 14 Jun 2019 09:56:28 -0500 Subject: [PATCH] Add gl_SemanticsVolatile to GL_KHR_memory_scope_semantics, and make volatile-qualified atomics generate MemorySemanticsVolatile when using the Vulkan memory model --- SPIRV/GlslangToSpv.cpp | 74 ++-- SPIRV/spirv.hpp | 4 +- Test/baseResults/spv.memoryScopeSemantics.comp.out | 378 +++++++++++---------- .../spv.memoryScopeSemantics_Error.comp.out | 4 +- Test/spv.memoryScopeSemantics.comp | 6 + Test/spv.memoryScopeSemantics_Error.comp | 2 + glslang/MachineIndependent/Initialize.cpp | 2 + glslang/MachineIndependent/ParseHelper.cpp | 15 +- 8 files changed, 278 insertions(+), 207 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 312e06a..9ad19b5 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -169,7 +169,7 @@ protected: void makeGlobalInitializers(const glslang::TIntermSequence&); void visitFunctions(const glslang::TIntermSequence&); void handleFunctionEntry(const glslang::TIntermAggregate* node); - void translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments); + void translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); void translateArguments(glslang::TIntermUnary& node, std::vector& arguments); spv::Id createImageTextureFunctionCall(glslang::TIntermOperator* node); spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*); @@ -178,14 +178,14 @@ protected: glslang::TBasicType typeProxy, bool reduceComparison = true); spv::Id createBinaryMatrixOperation(spv::Op, OpDecorations&, spv::Id typeId, spv::Id left, spv::Id right); spv::Id createUnaryOperation(glslang::TOperator op, OpDecorations&, spv::Id typeId, spv::Id operand, - glslang::TBasicType typeProxy); + glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); spv::Id createUnaryMatrixOperation(spv::Op op, OpDecorations&, spv::Id typeId, spv::Id operand, glslang::TBasicType typeProxy); spv::Id createConversion(glslang::TOperator op, OpDecorations&, spv::Id destTypeId, spv::Id operand, glslang::TBasicType typeProxy); spv::Id createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize); spv::Id makeSmearedConstant(spv::Id constant, int vectorSize); - spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); + spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags); spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, std::vector& operands); spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy); @@ -1981,19 +1981,26 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI invertedType = getInvertedSwizzleType(*node->getOperand()); builder.clearAccessChain(); + TIntermNode *operandNode; if (invertedType != spv::NoType) - node->getOperand()->getAsBinaryNode()->getLeft()->traverse(this); + operandNode = node->getOperand()->getAsBinaryNode()->getLeft(); else - node->getOperand()->traverse(this); + operandNode = node->getOperand(); + + operandNode->traverse(this); spv::Id operand = spv::NoResult; + spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags; + if (node->getOp() == glslang::EOpAtomicCounterIncrement || node->getOp() == glslang::EOpAtomicCounterDecrement || node->getOp() == glslang::EOpAtomicCounter || - node->getOp() == glslang::EOpInterpolateAtCentroid) + node->getOp() == glslang::EOpInterpolateAtCentroid) { operand = builder.accessChainGetLValue(); // Special case l-value operands - else + lvalueCoherentFlags = builder.getAccessChain().coherentFlags; + lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType()); + } else operand = accessChainLoad(node->getOperand()->getType()); OpDecorations decorations = { TranslatePrecisionDecoration(node->getOperationPrecision()), @@ -2006,7 +2013,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI // if not, then possibly an operation if (! result) - result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType()); + result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType(), lvalueCoherentFlags); if (result) { if (invertedType) { @@ -2113,6 +2120,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt bool noReturnValue = false; bool atomic = false; + spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags; + assert(node->getOp()); spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision()); @@ -2310,7 +2319,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt { builder.setLine(node->getLoc().line, node->getLoc().getFilename()); std::vector arguments; - translateArguments(*node, arguments); + translateArguments(*node, arguments, lvalueCoherentFlags); spv::Id constructed; if (node->getOp() == glslang::EOpConstructTextureSampler) constructed = builder.createOp(spv::OpSampledImage, resultType(), arguments); @@ -2602,9 +2611,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt } } - if (lvalue) + if (lvalue) { operands.push_back(builder.accessChainGetLValue()); - else { + lvalueCoherentFlags = builder.getAccessChain().coherentFlags; + lvalueCoherentFlags |= TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType()); + } else { builder.setLine(node->getLoc().line, node->getLoc().getFilename()); operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType())); } @@ -2639,7 +2650,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt result = 0; } else if (atomic) { // Handle all atomics - result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType()); + result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags); } else { // Pass through to generic operations. switch (glslangOperands.size()) { @@ -2654,7 +2665,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt result = createUnaryOperation( node->getOp(), decorations, resultType(), operands.front(), - glslangOperands[0]->getAsTyped()->getBasicType()); + glslangOperands[0]->getAsTyped()->getBasicType(), lvalueCoherentFlags); } break; default: @@ -4052,7 +4063,7 @@ void TGlslangToSpvTraverser::handleFunctionEntry(const glslang::TIntermAggregate builder.setBuildPoint(functionBlock); } -void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments) +void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) { const glslang::TIntermSequence& glslangArguments = node.getSequence(); @@ -4210,9 +4221,11 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& break; } - if (lvalue) + if (lvalue) { arguments.push_back(builder.accessChainGetLValue()); - else + lvalueCoherentFlags = builder.getAccessChain().coherentFlags; + lvalueCoherentFlags |= TranslateCoherent(glslangArguments[i]->getAsTyped()->getType()); + } else arguments.push_back(accessChainLoad(glslangArguments[i]->getAsTyped()->getType())); } } @@ -4253,9 +4266,11 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO return spv::ImageOperandsMaskNone; }; + spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags; + std::vector arguments; if (node->getAsAggregate()) - translateArguments(*node->getAsAggregate(), arguments); + translateArguments(*node->getAsAggregate(), arguments, lvalueCoherentFlags); else translateArguments(*node->getAsUnaryNode(), arguments); spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision()); @@ -4536,7 +4551,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO for (; opIt != arguments.end(); ++opIt) operands.push_back(*opIt); - return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType()); + return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags); } } @@ -5292,7 +5307,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora } spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDecorations& decorations, spv::Id typeId, - spv::Id operand, glslang::TBasicType typeProxy) + spv::Id operand, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) { spv::Op unaryOp = spv::OpNop; int extBuiltins = -1; @@ -5563,7 +5578,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe // Handle all of the atomics in one place, in createAtomicOperation() std::vector operands; operands.push_back(operand); - return createAtomicOperation(op, decorations.precision, typeId, operands, typeProxy); + return createAtomicOperation(op, decorations.precision, typeId, operands, typeProxy, lvalueCoherentFlags); } case glslang::EOpBitFieldReverse: @@ -6171,7 +6186,7 @@ spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vector } // For glslang ops that map to SPV atomic opCodes -spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy) +spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv::Decoration /*precision*/, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy, const spv::Builder::AccessChain::CoherentFlags &lvalueCoherentFlags) { spv::Op opCode = spv::OpNop; @@ -6257,7 +6272,7 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv scopeId = builder.makeUintConstant(spv::ScopeDevice); } // semantics default to relaxed - spv::Id semanticsId = builder.makeUintConstant(spv::MemorySemanticsMaskNone); + spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.volatil ? spv::MemorySemanticsVolatileMask : spv::MemorySemanticsMaskNone); spv::Id semanticsId2 = semanticsId; pointerId = operands[0]; @@ -6287,7 +6302,10 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv // Check for capabilities unsigned semanticsImmediate = builder.getConstantScalar(semanticsId) | builder.getConstantScalar(semanticsId2); - if (semanticsImmediate & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) { + if (semanticsImmediate & (spv::MemorySemanticsMakeAvailableKHRMask | + spv::MemorySemanticsMakeVisibleKHRMask | + spv::MemorySemanticsOutputMemoryKHRMask | + spv::MemorySemanticsVolatileMask)) { builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); } @@ -7229,7 +7247,10 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: unsigned int memoryScope = builder.getConstantScalar(operands[1]); unsigned int semantics = builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]); builder.createControlBarrier((spv::Scope)executionScope, (spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics); - if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) { + if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | + spv::MemorySemanticsMakeVisibleKHRMask | + spv::MemorySemanticsOutputMemoryKHRMask | + spv::MemorySemanticsVolatileMask)) { builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); } if (glslangIntermediate->usingVulkanMemoryModel() && (executionScope == spv::ScopeDevice || memoryScope == spv::ScopeDevice)) { @@ -7246,7 +7267,10 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: unsigned int memoryScope = builder.getConstantScalar(operands[0]); unsigned int semantics = builder.getConstantScalar(operands[1]) | builder.getConstantScalar(operands[2]); builder.createMemoryBarrier((spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics); - if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) { + if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | + spv::MemorySemanticsMakeVisibleKHRMask | + spv::MemorySemanticsOutputMemoryKHRMask | + spv::MemorySemanticsVolatileMask)) { builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); } if (glslangIntermediate->usingVulkanMemoryModel() && memoryScope == spv::ScopeDevice) { diff --git a/SPIRV/spirv.hpp b/SPIRV/spirv.hpp index 03ba767..bbaf47c 100644 --- a/SPIRV/spirv.hpp +++ b/SPIRV/spirv.hpp @@ -632,6 +632,7 @@ enum MemorySemanticsShift { MemorySemanticsOutputMemoryKHRShift = 12, MemorySemanticsMakeAvailableKHRShift = 13, MemorySemanticsMakeVisibleKHRShift = 14, + MemorySemanticsVolatileShift = 15, MemorySemanticsMax = 0x7fffffff, }; @@ -649,7 +650,8 @@ enum MemorySemanticsMask { MemorySemanticsImageMemoryMask = 0x00000800, MemorySemanticsOutputMemoryKHRMask = 0x00001000, MemorySemanticsMakeAvailableKHRMask = 0x00002000, - MemorySemanticsMakeVisibleKHRMask = 0x00004000, + MemorySemanticsMakeVisibleKHRMask = 0x00004000, + MemorySemanticsVolatileMask = 0x00008000, }; enum MemoryAccessShift { diff --git a/Test/baseResults/spv.memoryScopeSemantics.comp.out b/Test/baseResults/spv.memoryScopeSemantics.comp.out index 9361e76..8c4e576 100644 --- a/Test/baseResults/spv.memoryScopeSemantics.comp.out +++ b/Test/baseResults/spv.memoryScopeSemantics.comp.out @@ -1,7 +1,7 @@ spv.memoryScopeSemantics.comp // Module Version 10300 // Generated by (magic number): 80007 -// Id's are bound by 148 +// Id's are bound by 163 Capability Shader Capability Int64 @@ -23,59 +23,66 @@ spv.memoryScopeSemantics.comp Name 23 "atomu" Name 24 "value" Name 36 "imagei" - Name 45 "imageu" - Name 65 "BufferU" - MemberName 65(BufferU) 0 "x" - Name 67 "bufferu" - Name 72 "y" - Name 77 "BufferI" - MemberName 77(BufferI) 0 "x" - Name 79 "bufferi" - Name 83 "A" - MemberName 83(A) 0 "x" - Name 84 "BufferJ" - MemberName 84(BufferJ) 0 "a" - Name 87 "bufferj" - Name 98 "BufferK" - MemberName 98(BufferK) 0 "x" - Name 100 "bufferk" - Name 110 "imagej" - Name 122 "samp" - Name 133 "atomu64" - Name 138 "atomi64" - Name 143 "BufferL" - MemberName 143(BufferL) 0 "x" - Name 145 "bufferl" + Name 46 "imageu" + Name 66 "BufferU" + MemberName 66(BufferU) 0 "x" + Name 68 "bufferu" + Name 73 "y" + Name 78 "BufferI" + MemberName 78(BufferI) 0 "x" + Name 80 "bufferi" + Name 84 "A" + MemberName 84(A) 0 "x" + Name 85 "BufferJ" + MemberName 85(BufferJ) 0 "a" + Name 88 "bufferj" + Name 99 "BufferK" + MemberName 99(BufferK) 0 "x" + Name 101 "bufferk" + Name 111 "imagej" + Name 123 "samp" + Name 134 "atomu64" + Name 139 "atomi64" + Name 144 "BufferL" + MemberName 144(BufferL) 0 "x" + Name 146 "bufferl" + Name 151 "BufferM" + MemberName 151(BufferM) 0 "x" + Name 153 "bufferm" Decorate 36(imagei) DescriptorSet 0 Decorate 36(imagei) Binding 1 - Decorate 45(imageu) DescriptorSet 0 - Decorate 45(imageu) Binding 0 - MemberDecorate 65(BufferU) 0 Offset 0 - Decorate 65(BufferU) Block - Decorate 67(bufferu) DescriptorSet 0 - Decorate 67(bufferu) Binding 2 - MemberDecorate 77(BufferI) 0 Offset 0 - Decorate 77(BufferI) Block - Decorate 79(bufferi) DescriptorSet 0 - Decorate 79(bufferi) Binding 3 - Decorate 82 ArrayStride 4 - MemberDecorate 83(A) 0 Offset 0 - MemberDecorate 84(BufferJ) 0 Offset 0 - Decorate 84(BufferJ) Block - Decorate 87(bufferj) DescriptorSet 0 - Decorate 87(bufferj) Binding 4 - MemberDecorate 98(BufferK) 0 Offset 0 - Decorate 98(BufferK) Block - Decorate 100(bufferk) DescriptorSet 0 - Decorate 100(bufferk) Binding 7 - Decorate 110(imagej) DescriptorSet 0 - Decorate 110(imagej) Binding 5 - Decorate 122(samp) DescriptorSet 0 - Decorate 122(samp) Binding 6 - MemberDecorate 143(BufferL) 0 Offset 0 - Decorate 143(BufferL) Block - Decorate 145(bufferl) DescriptorSet 0 - Decorate 145(bufferl) Binding 8 + Decorate 46(imageu) DescriptorSet 0 + Decorate 46(imageu) Binding 0 + MemberDecorate 66(BufferU) 0 Offset 0 + Decorate 66(BufferU) Block + Decorate 68(bufferu) DescriptorSet 0 + Decorate 68(bufferu) Binding 2 + MemberDecorate 78(BufferI) 0 Offset 0 + Decorate 78(BufferI) Block + Decorate 80(bufferi) DescriptorSet 0 + Decorate 80(bufferi) Binding 3 + Decorate 83 ArrayStride 4 + MemberDecorate 84(A) 0 Offset 0 + MemberDecorate 85(BufferJ) 0 Offset 0 + Decorate 85(BufferJ) Block + Decorate 88(bufferj) DescriptorSet 0 + Decorate 88(bufferj) Binding 4 + MemberDecorate 99(BufferK) 0 Offset 0 + Decorate 99(BufferK) Block + Decorate 101(bufferk) DescriptorSet 0 + Decorate 101(bufferk) Binding 7 + Decorate 111(imagej) DescriptorSet 0 + Decorate 111(imagej) Binding 5 + Decorate 123(samp) DescriptorSet 0 + Decorate 123(samp) Binding 6 + MemberDecorate 144(BufferL) 0 Offset 0 + Decorate 144(BufferL) Block + Decorate 146(bufferl) DescriptorSet 0 + Decorate 146(bufferl) Binding 8 + MemberDecorate 151(BufferM) 0 Offset 0 + Decorate 151(BufferM) Block + Decorate 153(bufferm) DescriptorSet 0 + Decorate 153(bufferm) Binding 9 2: TypeVoid 3: TypeFunction 2 6: TypeInt 32 1 @@ -106,67 +113,72 @@ spv.memoryScopeSemantics.comp 38: 6(int) Constant 0 39: 37(ivec2) ConstantComposite 38 38 40: TypePointer Image 6(int) - 43: TypeImage 15(int) 2D nonsampled format:R32ui - 44: TypePointer UniformConstant 43 - 45(imageu): 44(ptr) Variable UniformConstant - 46: 15(int) Constant 3 - 47: TypePointer Image 15(int) - 50: 15(int) Constant 4 - 52: 15(int) Constant 7 - 57: 6(int) Constant 7 - 61: 15(int) Constant 10 - 63: 15(int) Constant 322 - 65(BufferU): TypeStruct 15(int) - 66: TypePointer StorageBuffer 65(BufferU) - 67(bufferu): 66(ptr) Variable StorageBuffer - 68: TypePointer StorageBuffer 15(int) - 70: 15(int) Constant 1 - 77(BufferI): TypeStruct 15(int) - 78: TypePointer StorageBuffer 77(BufferI) - 79(bufferi): 78(ptr) Variable StorageBuffer - 82: TypeArray 15(int) 26 - 83(A): TypeStruct 82 - 84(BufferJ): TypeStruct 83(A) - 85: TypeArray 84(BufferJ) 26 - 86: TypePointer StorageBuffer 85 - 87(bufferj): 86(ptr) Variable StorageBuffer - 94: TypePointer StorageBuffer 83(A) - 98(BufferK): TypeStruct 15(int) - 99: TypePointer Uniform 98(BufferK) - 100(bufferk): 99(ptr) Variable Uniform - 101: TypePointer Uniform 15(int) - 106: TypeVector 6(int) 4 - 108: TypeArray 34 26 - 109: TypePointer UniformConstant 108 - 110(imagej): 109(ptr) Variable UniformConstant - 116: 106(ivec4) ConstantComposite 38 38 38 38 - 117: TypeFloat 32 - 118: TypeImage 117(float) 2D sampled format:Unknown - 119: TypeSampledImage 118 - 120: TypeArray 119 26 - 121: TypePointer UniformConstant 120 - 122(samp): 121(ptr) Variable UniformConstant - 123: TypePointer UniformConstant 119 - 126: TypeVector 117(float) 2 - 127: 117(float) Constant 0 - 128: 126(fvec2) ConstantComposite 127 127 - 129: TypeVector 117(float) 4 - 131: TypeInt 64 0 - 132: TypePointer Workgroup 131(int64_t) - 133(atomu64): 132(ptr) Variable Workgroup - 134:131(int64_t) Constant 7 0 - 136: TypeInt 64 1 - 137: TypePointer Workgroup 136(int64_t) - 138(atomi64): 137(ptr) Variable Workgroup - 139:136(int64_t) Constant 10 0 - 143(BufferL): TypeStruct 15(int) - 144: TypePointer StorageBuffer 143(BufferL) - 145(bufferl): 144(ptr) Variable StorageBuffer + 42: 15(int) Constant 32768 + 44: TypeImage 15(int) 2D nonsampled format:R32ui + 45: TypePointer UniformConstant 44 + 46(imageu): 45(ptr) Variable UniformConstant + 47: 15(int) Constant 3 + 48: TypePointer Image 15(int) + 51: 15(int) Constant 4 + 53: 15(int) Constant 7 + 58: 6(int) Constant 7 + 62: 15(int) Constant 10 + 64: 15(int) Constant 322 + 66(BufferU): TypeStruct 15(int) + 67: TypePointer StorageBuffer 66(BufferU) + 68(bufferu): 67(ptr) Variable StorageBuffer + 69: TypePointer StorageBuffer 15(int) + 71: 15(int) Constant 1 + 78(BufferI): TypeStruct 15(int) + 79: TypePointer StorageBuffer 78(BufferI) + 80(bufferi): 79(ptr) Variable StorageBuffer + 83: TypeArray 15(int) 26 + 84(A): TypeStruct 83 + 85(BufferJ): TypeStruct 84(A) + 86: TypeArray 85(BufferJ) 26 + 87: TypePointer StorageBuffer 86 + 88(bufferj): 87(ptr) Variable StorageBuffer + 95: TypePointer StorageBuffer 84(A) + 99(BufferK): TypeStruct 15(int) + 100: TypePointer Uniform 99(BufferK) + 101(bufferk): 100(ptr) Variable Uniform + 102: TypePointer Uniform 15(int) + 107: TypeVector 6(int) 4 + 109: TypeArray 34 26 + 110: TypePointer UniformConstant 109 + 111(imagej): 110(ptr) Variable UniformConstant + 117: 107(ivec4) ConstantComposite 38 38 38 38 + 118: TypeFloat 32 + 119: TypeImage 118(float) 2D sampled format:Unknown + 120: TypeSampledImage 119 + 121: TypeArray 120 26 + 122: TypePointer UniformConstant 121 + 123(samp): 122(ptr) Variable UniformConstant + 124: TypePointer UniformConstant 120 + 127: TypeVector 118(float) 2 + 128: 118(float) Constant 0 + 129: 127(fvec2) ConstantComposite 128 128 + 130: TypeVector 118(float) 4 + 132: TypeInt 64 0 + 133: TypePointer Workgroup 132(int64_t) + 134(atomu64): 133(ptr) Variable Workgroup + 135:132(int64_t) Constant 7 0 + 137: TypeInt 64 1 + 138: TypePointer Workgroup 137(int64_t) + 139(atomi64): 138(ptr) Variable Workgroup + 140:137(int64_t) Constant 10 0 + 144(BufferL): TypeStruct 15(int) + 145: TypePointer StorageBuffer 144(BufferL) + 146(bufferl): 145(ptr) Variable StorageBuffer + 151(BufferM): TypeStruct 15(int) + 152: TypePointer StorageBuffer 151(BufferM) + 153(bufferm): 152(ptr) Variable StorageBuffer + 161: 6(int) Constant 32768 4(main): 2 Function None 3 5: Label 8(origi): 7(ptr) Variable Function 21(origu): 20(ptr) Variable Function - 72(y): 20(ptr) Variable Function + 73(y): 20(ptr) Variable Function 19: 6(int) AtomicIAdd 10(atomi) 12 18 11 Store 8(origi) 19 25: 15(int) Load 24(value) MakePointerVisibleKHR NonPrivatePointerKHR 26 @@ -177,77 +189,87 @@ spv.memoryScopeSemantics.comp 32: 15(int) Load 24(value) MakePointerVisibleKHR NonPrivatePointerKHR 26 AtomicStore 23(atomu) 12 33 32 41: 40(ptr) ImageTexelPointer 36(imagei) 39 17 - 42: 6(int) AtomicLoad 41 12 30 - Store 8(origi) 42 - 48: 47(ptr) ImageTexelPointer 45(imageu) 39 17 - 49: 15(int) AtomicIAdd 48 12 30 46 - Store 21(origu) 49 - 51: 47(ptr) ImageTexelPointer 45(imageu) 39 17 - AtomicStore 51 12 33 50 - 53: 15(int) AtomicOr 23(atomu) 12 17 52 - Store 21(origu) 53 - 54: 15(int) AtomicXor 23(atomu) 12 17 52 + 43: 6(int) AtomicLoad 41 12 30 + Store 8(origi) 43 + 49: 48(ptr) ImageTexelPointer 46(imageu) 39 17 + 50: 15(int) AtomicIAdd 49 12 30 47 + Store 21(origu) 50 + 52: 48(ptr) ImageTexelPointer 46(imageu) 39 17 + AtomicStore 52 12 33 51 + 54: 15(int) AtomicOr 23(atomu) 12 17 53 Store 21(origu) 54 - 55: 15(int) Load 24(value) MakePointerVisibleKHR NonPrivatePointerKHR 26 - 56: 15(int) AtomicUMin 23(atomu) 12 17 55 - Store 21(origu) 56 - 58: 6(int) AtomicSMax 10(atomi) 12 17 57 - Store 8(origi) 58 - 59: 6(int) Load 8(origi) - 60: 6(int) AtomicExchange 10(atomi) 12 17 59 - Store 8(origi) 60 - 62: 15(int) Load 24(value) MakePointerVisibleKHR NonPrivatePointerKHR 26 - 64: 15(int) AtomicCompareExchange 23(atomu) 12 63 63 62 61 - Store 21(origu) 64 - 69: 68(ptr) AccessChain 67(bufferu) 38 - 71: 15(int) AtomicIAdd 69 12 18 70 + 55: 15(int) AtomicXor 23(atomu) 12 17 53 + Store 21(origu) 55 + 56: 15(int) Load 24(value) MakePointerVisibleKHR NonPrivatePointerKHR 26 + 57: 15(int) AtomicUMin 23(atomu) 12 17 56 + Store 21(origu) 57 + 59: 6(int) AtomicSMax 10(atomi) 12 17 58 + Store 8(origi) 59 + 60: 6(int) Load 8(origi) + 61: 6(int) AtomicExchange 10(atomi) 12 17 60 + Store 8(origi) 61 + 63: 15(int) Load 24(value) MakePointerVisibleKHR NonPrivatePointerKHR 26 + 65: 15(int) AtomicCompareExchange 23(atomu) 12 64 64 63 62 + Store 21(origu) 65 + 70: 69(ptr) AccessChain 68(bufferu) 38 + 72: 15(int) AtomicIAdd 70 12 18 71 MemoryBarrier 26 18 - ControlBarrier 26 26 63 + ControlBarrier 26 26 64 ControlBarrier 26 26 17 - 73: 68(ptr) AccessChain 67(bufferu) 38 - 74: 15(int) Load 73 MakePointerVisibleKHR NonPrivatePointerKHR 26 - Store 72(y) 74 - 75: 15(int) Load 72(y) - 76: 68(ptr) AccessChain 67(bufferu) 38 - Store 76 75 MakePointerAvailableKHR NonPrivatePointerKHR 26 - 80: 68(ptr) AccessChain 79(bufferi) 38 - 81: 15(int) Load 80 MakePointerVisibleKHR NonPrivatePointerKHR 16 - Store 72(y) 81 - 88: 68(ptr) AccessChain 87(bufferj) 38 38 38 12 - 89: 15(int) Load 88 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16 - Store 72(y) 89 - 90: 15(int) Load 72(y) - 91: 68(ptr) AccessChain 79(bufferi) 38 - Store 91 90 MakePointerAvailableKHR NonPrivatePointerKHR 16 - 92: 15(int) Load 72(y) - 93: 68(ptr) AccessChain 87(bufferj) 38 38 38 12 - Store 93 92 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 16 - 95: 94(ptr) AccessChain 87(bufferj) 12 38 - 96: 83(A) Load 95 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16 - 97: 94(ptr) AccessChain 87(bufferj) 38 38 - Store 97 96 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 16 - 102: 101(ptr) AccessChain 100(bufferk) 38 - 103: 15(int) Load 102 NonPrivatePointerKHR - 104: 68(ptr) AccessChain 79(bufferi) 38 - Store 104 103 MakePointerAvailableKHR NonPrivatePointerKHR 16 - 105: 34 Load 36(imagei) - 107: 106(ivec4) ImageRead 105 39 MakeTexelVisibleKHR NonPrivateTexelKHR VolatileTexelKHR 16 - 111: 35(ptr) AccessChain 110(imagej) 38 - 112: 34 Load 111 - 113: 106(ivec4) ImageRead 112 39 NonPrivateTexelKHR - 114: 35(ptr) AccessChain 110(imagej) 12 - 115: 34 Load 114 - ImageWrite 115 39 116 NonPrivateTexelKHR - 124: 123(ptr) AccessChain 122(samp) 38 - 125: 119 Load 124 - 130: 129(fvec4) ImageSampleExplicitLod 125 128 Lod NonPrivateTexelKHR 127 - 135:131(int64_t) AtomicUMax 133(atomu64) 12 17 134 - Store 133(atomu64) 135 MakePointerAvailableKHR NonPrivatePointerKHR 26 - 140:131(int64_t) Load 133(atomu64) MakePointerVisibleKHR NonPrivatePointerKHR 26 - 141:136(int64_t) Bitcast 140 - 142:136(int64_t) AtomicCompareExchange 138(atomi64) 12 63 63 141 139 - 146: 68(ptr) AccessChain 145(bufferl) 38 - 147: 15(int) Load 146 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16 - Store 72(y) 147 + 74: 69(ptr) AccessChain 68(bufferu) 38 + 75: 15(int) Load 74 MakePointerVisibleKHR NonPrivatePointerKHR 26 + Store 73(y) 75 + 76: 15(int) Load 73(y) + 77: 69(ptr) AccessChain 68(bufferu) 38 + Store 77 76 MakePointerAvailableKHR NonPrivatePointerKHR 26 + 81: 69(ptr) AccessChain 80(bufferi) 38 + 82: 15(int) Load 81 MakePointerVisibleKHR NonPrivatePointerKHR 16 + Store 73(y) 82 + 89: 69(ptr) AccessChain 88(bufferj) 38 38 38 12 + 90: 15(int) Load 89 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16 + Store 73(y) 90 + 91: 15(int) Load 73(y) + 92: 69(ptr) AccessChain 80(bufferi) 38 + Store 92 91 MakePointerAvailableKHR NonPrivatePointerKHR 16 + 93: 15(int) Load 73(y) + 94: 69(ptr) AccessChain 88(bufferj) 38 38 38 12 + Store 94 93 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 16 + 96: 95(ptr) AccessChain 88(bufferj) 12 38 + 97: 84(A) Load 96 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16 + 98: 95(ptr) AccessChain 88(bufferj) 38 38 + Store 98 97 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 16 + 103: 102(ptr) AccessChain 101(bufferk) 38 + 104: 15(int) Load 103 NonPrivatePointerKHR + 105: 69(ptr) AccessChain 80(bufferi) 38 + Store 105 104 MakePointerAvailableKHR NonPrivatePointerKHR 16 + 106: 34 Load 36(imagei) + 108: 107(ivec4) ImageRead 106 39 MakeTexelVisibleKHR NonPrivateTexelKHR VolatileTexelKHR 16 + 112: 35(ptr) AccessChain 111(imagej) 38 + 113: 34 Load 112 + 114: 107(ivec4) ImageRead 113 39 NonPrivateTexelKHR + 115: 35(ptr) AccessChain 111(imagej) 12 + 116: 34 Load 115 + ImageWrite 116 39 117 NonPrivateTexelKHR + 125: 124(ptr) AccessChain 123(samp) 38 + 126: 120 Load 125 + 131: 130(fvec4) ImageSampleExplicitLod 126 129 Lod NonPrivateTexelKHR 128 + 136:132(int64_t) AtomicUMax 134(atomu64) 12 17 135 + Store 134(atomu64) 136 MakePointerAvailableKHR NonPrivatePointerKHR 26 + 141:132(int64_t) Load 134(atomu64) MakePointerVisibleKHR NonPrivatePointerKHR 26 + 142:137(int64_t) Bitcast 141 + 143:137(int64_t) AtomicCompareExchange 139(atomi64) 12 64 64 142 140 + 147: 69(ptr) AccessChain 146(bufferl) 38 + 148: 15(int) Load 147 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 16 + Store 73(y) 148 + 149: 69(ptr) AccessChain 146(bufferl) 38 + 150: 15(int) AtomicIAdd 149 16 42 71 + 154: 69(ptr) AccessChain 153(bufferm) 38 + 155: 15(int) AtomicOr 154 16 42 26 + 156: 40(ptr) ImageTexelPointer 36(imagei) 39 17 + 157: 6(int) AtomicIAdd 156 16 42 11 + 158: 69(ptr) AccessChain 68(bufferu) 38 + 159: 15(int) AtomicIAdd 158 12 17 51 + 160: 69(ptr) AccessChain 68(bufferu) 38 + 162: 15(int) AtomicIAdd 160 12 42 16 Return FunctionEnd diff --git a/Test/baseResults/spv.memoryScopeSemantics_Error.comp.out b/Test/baseResults/spv.memoryScopeSemantics_Error.comp.out index c4149d8..6de93fd 100644 --- a/Test/baseResults/spv.memoryScopeSemantics_Error.comp.out +++ b/Test/baseResults/spv.memoryScopeSemantics_Error.comp.out @@ -11,7 +11,9 @@ ERROR: 0:23: 'atomicAdd' : Semantics must not include multiple of gl_SemanticsRe ERROR: 0:24: 'atomicCompSwap' : semUnequal must not be gl_SemanticsRelease or gl_SemanticsAcquireRelease ERROR: 0:25: 'memoryBarrier' : gl_SemanticsMakeVisible requires gl_SemanticsAcquire or gl_SemanticsAcquireRelease ERROR: 0:26: 'memoryBarrier' : gl_SemanticsMakeAvailable requires gl_SemanticsRelease or gl_SemanticsAcquireRelease -ERROR: 12 compilation errors. No code generated. +ERROR: 0:27: 'memoryBarrier' : gl_SemanticsVolatile must not be used with memoryBarrier or controlBarrier +ERROR: 0:28: 'atomicCompSwap' : semEqual and semUnequal must either both include gl_SemanticsVolatile or neither +ERROR: 14 compilation errors. No code generated. SPIR-V is not generated for failed compile or link diff --git a/Test/spv.memoryScopeSemantics.comp b/Test/spv.memoryScopeSemantics.comp index 88f5481..037e6d7 100644 --- a/Test/spv.memoryScopeSemantics.comp +++ b/Test/spv.memoryScopeSemantics.comp @@ -19,6 +19,7 @@ layout (binding = 7) nonprivate uniform BufferK { uint x; } bufferk; shared uint64_t atomu64; shared int64_t atomi64; layout (binding = 8) volatile buffer BufferL { uint x; } bufferl; +layout (binding = 9) buffer BufferM { volatile uint x; } bufferm; void main() @@ -60,5 +61,10 @@ void main() atomicCompSwap(atomi64, int64_t(10), int64_t(atomu64), gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire); y = bufferl.x; + atomicAdd(bufferl.x, 1); + atomicOr(bufferm.x, 2); + imageAtomicAdd(imagei, ivec2(0,0), 3); + atomicAdd(bufferu.x, 4u, gl_ScopeDevice, 0, 0); + atomicAdd(bufferu.x, 5u, gl_ScopeDevice, 0, gl_SemanticsVolatile); } diff --git a/Test/spv.memoryScopeSemantics_Error.comp b/Test/spv.memoryScopeSemantics_Error.comp index 4e18b2e..1b85671 100644 --- a/Test/spv.memoryScopeSemantics_Error.comp +++ b/Test/spv.memoryScopeSemantics_Error.comp @@ -24,5 +24,7 @@ void main() uint origu = atomicCompSwap(atomu, 10u, value, gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquireRelease); memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer, gl_SemanticsRelease | gl_SemanticsMakeVisible); memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer, gl_SemanticsAcquire | gl_SemanticsMakeAvailable); + memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer, gl_SemanticsRelease | gl_SemanticsVolatile); + atomicCompSwap(bufferi.x, 10u, 10u, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquire | gl_SemanticsVolatile, gl_StorageSemanticsBuffer, gl_SemanticsAcquire); } diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index afaf2d6..169fef0 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -6309,6 +6309,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV commonBuiltins.append("const int gl_SemanticsAcquireRelease = 0x8;\n"); commonBuiltins.append("const int gl_SemanticsMakeAvailable = 0x2000;\n"); commonBuiltins.append("const int gl_SemanticsMakeVisible = 0x4000;\n"); + commonBuiltins.append("const int gl_SemanticsVolatile = 0x8000;\n"); commonBuiltins.append("const int gl_StorageSemanticsNone = 0x0;\n"); commonBuiltins.append("const int gl_StorageSemanticsBuffer = 0x40;\n"); @@ -8630,6 +8631,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_SemanticsAcquireRelease", 1, &E_GL_KHR_memory_scope_semantics); symbolTable.setVariableExtensions("gl_SemanticsMakeAvailable", 1, &E_GL_KHR_memory_scope_semantics); symbolTable.setVariableExtensions("gl_SemanticsMakeVisible", 1, &E_GL_KHR_memory_scope_semantics); + symbolTable.setVariableExtensions("gl_SemanticsVolatile", 1, &E_GL_KHR_memory_scope_semantics); symbolTable.setVariableExtensions("gl_StorageSemanticsNone", 1, &E_GL_KHR_memory_scope_semantics); symbolTable.setVariableExtensions("gl_StorageSemanticsBuffer", 1, &E_GL_KHR_memory_scope_semantics); diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 8e570ae..57cc5f9 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -1641,6 +1641,7 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& const int gl_SemanticsAcquireRelease = 0x8; const int gl_SemanticsMakeAvailable = 0x2000; const int gl_SemanticsMakeVisible = 0x4000; + const int gl_SemanticsVolatile = 0x8000; //const int gl_StorageSemanticsNone = 0x0; const int gl_StorageSemanticsBuffer = 0x40; @@ -1730,7 +1731,8 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& gl_SemanticsRelease | gl_SemanticsAcquireRelease | gl_SemanticsMakeAvailable | - gl_SemanticsMakeVisible))) { + gl_SemanticsMakeVisible | + gl_SemanticsVolatile))) { error(loc, "Invalid semantics value", fnCandidate.getName().c_str(), ""); } if (((storageClassSemantics | storageClassSemantics2) & ~(gl_StorageSemanticsBuffer | @@ -1782,7 +1784,16 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& error(loc, "gl_SemanticsMakeVisible requires gl_SemanticsAcquire or gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), ""); } - + if ((semantics & gl_SemanticsVolatile) && + (callNode.getOp() == EOpMemoryBarrier || callNode.getOp() == EOpBarrier)) { + error(loc, "gl_SemanticsVolatile must not be used with memoryBarrier or controlBarrier", + fnCandidate.getName().c_str(), ""); + } + if ((callNode.getOp() == EOpAtomicCompSwap || callNode.getOp() == EOpImageAtomicCompSwap) && + ((semantics ^ semantics2) & gl_SemanticsVolatile)) { + error(loc, "semEqual and semUnequal must either both include gl_SemanticsVolatile or neither", + fnCandidate.getName().c_str(), ""); + } } -- 2.7.4