diff options
| author | ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> | 2024-04-03 14:19:15 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-03 11:19:15 -0700 |
| commit | e0de98e9aabbe118f0eeca7821518c8fb4e1f6c4 (patch) | |
| tree | a310629cd025372c6d554705ba7f42251f400ac5 /source | |
| parent | a697b2c6707ee699cb734a03fa529dd214ac66cc (diff) | |
Refactor memory qualifier decorators to be a bit-flag set, resolves #3841 (#3881)
* Refactor memory qualifier decorators to be a bit-flag set.
replace GloballyCoherent, ReadOnly, WriteOnly, Volatile, and Restrict memory modifiers and decorations with a bit flag set to more efficiently manage memory qualifiers.
added `restrict` modifier to test to ensure the code works when dropping a `restrict` memory qualifier
* Refine tests & add SSBO memory qualifer support
add CHECK's to tests to ensure memory qualifiers emit as intended
added tests and changed code to ensure memory qualifiers work on SSBO objects (SPIR-V & GLSL)
* add memory qualifiers & fixes.
Add to StructuredBuffer & ByteAddressBuffer `ReadOnly`/NonWritable qualifier.
* Memory qualifiers must be decorated on a variable inst. Due to this the qualifier is added after `lowerStructuredBufferType`
Fixed an error where ReadOnly->NonReadable & WriteOnly->NonWritable
* Adjusted tests accordingly
Added back the removed `globallycoherent` memory qualifier emit'ing code in hlsl-emit (was incorrectly removed).
undo hlsl.meta changes
cleanup
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-ast-modifier.h | 4 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 24 | ||||
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 23 | ||||
| -rw-r--r-- | source/slang/slang-check-modifier.cpp | 27 | ||||
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 18 | ||||
| -rw-r--r-- | source/slang/slang-emit-hlsl.cpp | 14 | ||||
| -rw-r--r-- | source/slang/slang-emit-spirv.cpp | 129 | ||||
| -rw-r--r-- | source/slang/slang-ir-byte-address-legalize.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 8 | ||||
| -rw-r--r-- | source/slang/slang-ir-insts.h | 17 | ||||
| -rw-r--r-- | source/slang/slang-ir-spirv-legalize.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-ir.cpp | 1 | ||||
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 20 |
14 files changed, 168 insertions, 128 deletions
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h index c9b6c6376..21661939c 100644 --- a/source/slang/slang-ast-modifier.h +++ b/source/slang/slang-ast-modifier.h @@ -1585,9 +1585,9 @@ class DynamicUniformModifier : public Modifier SLANG_AST_CLASS(DynamicUniformModifier) }; -class MemoryQualifierCollectionModifier : public Modifier +class MemoryQualifierSetModifier : public Modifier { - SLANG_AST_CLASS(MemoryQualifierCollectionModifier); + SLANG_AST_CLASS(MemoryQualifierSetModifier); List<Modifier*> memoryModifiers; diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index aec3b463b..5190f8c0e 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -946,21 +946,15 @@ namespace Slang // Ensures child of struct is set read-only or not bool isWriteOnly = false; + if(auto collection = varDeclRef.getDecl()->findModifier<MemoryQualifierSetModifier>()) { - for (auto mod : varDeclRef.getDecl()->modifiers) + if(collection->getMemoryQualifierBit() & MemoryQualifierSetModifier::Flags::kReadOnly) { - if (as<GLSLReadOnlyModifier>(mod)) - { - isLValue = false; - qualType.hasReadOnlyOnTarget = true; - if (isLValue == false && isWriteOnly) break; - } - if (as<GLSLWriteOnlyModifier>(mod)) - { - isWriteOnly = true; - if (isLValue == false && isWriteOnly) break; - } + isLValue = false; + qualType.hasReadOnlyOnTarget = true; } + if(collection->getMemoryQualifierBit() & MemoryQualifierSetModifier::Flags::kWriteOnly) + isWriteOnly = true; } qualType.isLeftValue = isLValue; @@ -7162,10 +7156,10 @@ namespace Slang // Only texture types are allowed to have memory qualifiers on parameters if(!paramDecl->type || paramDecl->type->astNodeType != ASTNodeType::TextureType) { - auto memoryQualifierCollection = paramDecl->findModifier<MemoryQualifierCollectionModifier>(); - if(!memoryQualifierCollection) + auto MemoryQualifierSet = paramDecl->findModifier<MemoryQualifierSetModifier>(); + if(!MemoryQualifierSet) return; - for(auto mod : memoryQualifierCollection->getModifiers()) + for(auto mod : MemoryQualifierSet->getModifiers()) getSink()->diagnose(paramDecl, Diagnostics::memoryQualifierNotAllowedOnANonImageTypeParameter, mod); } } diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index ff5dd4af5..e88db59f8 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -314,7 +314,8 @@ namespace Slang // Check the modifiers on the declaration const auto d = varExpr->declRef.getDecl(); - if(d->hasModifier<GLSLReadOnlyModifier>()) + auto collection = d->findModifier<MemoryQualifierSetModifier>(); + if(collection && collection->getMemoryQualifierBit() & MemoryQualifierSetModifier::Flags::kReadOnly) return false; return true; @@ -2201,27 +2202,27 @@ namespace Slang if (!argDeclRef) return; auto argDecl = argDeclRef.getDecl(); - auto argMemMods = argDecl->findModifier<MemoryQualifierCollectionModifier>(); + auto argMemMods = argDecl->findModifier<MemoryQualifierSetModifier>(); if(!argMemMods) return; uint32_t argQualifiers = argMemMods->getMemoryQualifierBit(); uint32_t paramQualifiers = 0; - auto paramMemMods = paramIn->findModifier<MemoryQualifierCollectionModifier>(); + auto paramMemMods = paramIn->findModifier<MemoryQualifierSetModifier>(); if(paramMemMods) paramQualifiers = paramMemMods->getMemoryQualifierBit(); - if(argQualifiers & MemoryQualifierCollectionModifier::Flags::kCoherent - && !(paramQualifiers & MemoryQualifierCollectionModifier::Flags::kCoherent)) + if(argQualifiers & MemoryQualifierSetModifier::Flags::kCoherent + && !(paramQualifiers & MemoryQualifierSetModifier::Flags::kCoherent)) getSink()->diagnose(arg, Diagnostics::argumentHasMoreMemoryQualifiersThanParam, "coherent"); - if(argQualifiers & MemoryQualifierCollectionModifier::Flags::kReadOnly - && !(paramQualifiers & MemoryQualifierCollectionModifier::Flags::kReadOnly)) + if(argQualifiers & MemoryQualifierSetModifier::Flags::kReadOnly + && !(paramQualifiers & MemoryQualifierSetModifier::Flags::kReadOnly)) getSink()->diagnose(arg, Diagnostics::argumentHasMoreMemoryQualifiersThanParam, "readonly"); - if(argQualifiers & MemoryQualifierCollectionModifier::Flags::kWriteOnly - && !(paramQualifiers & MemoryQualifierCollectionModifier::Flags::kWriteOnly)) + if(argQualifiers & MemoryQualifierSetModifier::Flags::kWriteOnly + && !(paramQualifiers & MemoryQualifierSetModifier::Flags::kWriteOnly)) getSink()->diagnose(arg, Diagnostics::argumentHasMoreMemoryQualifiersThanParam, "writeonly"); - if(argQualifiers & MemoryQualifierCollectionModifier::Flags::kVolatile - && !(paramQualifiers & MemoryQualifierCollectionModifier::Flags::kVolatile)) + if(argQualifiers & MemoryQualifierSetModifier::Flags::kVolatile + && !(paramQualifiers & MemoryQualifierSetModifier::Flags::kVolatile)) getSink()->diagnose(arg, Diagnostics::argumentHasMoreMemoryQualifiersThanParam, "volatile"); // dropping a `restrict` qualifier from arguments is allowed in GLSL with memory qualifiers } diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp index 718de86cc..af47eaedb 100644 --- a/source/slang/slang-check-modifier.cpp +++ b/source/slang/slang-check-modifier.cpp @@ -1096,6 +1096,7 @@ namespace Slang case ASTNodeType::GLSLLayoutModifierGroupBegin: case ASTNodeType::GLSLLayoutModifierGroupEnd: case ASTNodeType::GLSLBufferModifier: + case ASTNodeType::MemoryQualifierSetModifier: case ASTNodeType::GLSLWriteOnlyModifier: case ASTNodeType::GLSLReadOnlyModifier: case ASTNodeType::GLSLVolatileModifier: @@ -1317,38 +1318,34 @@ namespace Slang } } - MemoryQualifierCollectionModifier::Flags::MemoryQualifiersBit memoryQualifierBit = - MemoryQualifierCollectionModifier::Flags::kNone; + MemoryQualifierSetModifier::Flags::MemoryQualifiersBit memoryQualifierBit = MemoryQualifierSetModifier::Flags::kNone; if(as<GloballyCoherentModifier>(m)) - memoryQualifierBit = MemoryQualifierCollectionModifier::Flags::kCoherent; + memoryQualifierBit = MemoryQualifierSetModifier::Flags::kCoherent; else if(as<GLSLReadOnlyModifier>(m)) - memoryQualifierBit = MemoryQualifierCollectionModifier::Flags::kReadOnly; + memoryQualifierBit = MemoryQualifierSetModifier::Flags::kReadOnly; else if(as<GLSLWriteOnlyModifier>(m)) - memoryQualifierBit = MemoryQualifierCollectionModifier::Flags::kWriteOnly; + memoryQualifierBit = MemoryQualifierSetModifier::Flags::kWriteOnly; else if(as<GLSLVolatileModifier>(m)) - memoryQualifierBit = MemoryQualifierCollectionModifier::Flags::kVolatile; + memoryQualifierBit = MemoryQualifierSetModifier::Flags::kVolatile; else if(as<GLSLRestrictModifier>(m)) - memoryQualifierBit = MemoryQualifierCollectionModifier::Flags::kRestrict; - if(memoryQualifierBit != MemoryQualifierCollectionModifier::Flags::kNone) + memoryQualifierBit = MemoryQualifierSetModifier::Flags::kRestrict; + if(memoryQualifierBit != MemoryQualifierSetModifier::Flags::kNone) { bool newModifier = false; - MemoryQualifierCollectionModifier* memoryQualifiers = syntaxNode->findModifier<MemoryQualifierCollectionModifier>(); + MemoryQualifierSetModifier* memoryQualifiers = syntaxNode->findModifier<MemoryQualifierSetModifier>(); if(!memoryQualifiers) { newModifier = true; - memoryQualifiers = getASTBuilder()->create<MemoryQualifierCollectionModifier>(); + memoryQualifiers = getASTBuilder()->create<MemoryQualifierSetModifier>(); } memoryQualifiers->addQualifier(m, memoryQualifierBit); if (newModifier) { - // insert in modifiers list the memoryQualifierCollection - Modifier* mod = m->next; m->next = memoryQualifiers; - memoryQualifiers->next = mod; - return m; + return memoryQualifiers; } - return m; + return nullptr; } if (auto hlslSemantic = as<HLSLSimpleSemantic>(m)) diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 58ca39b69..ceb4e6de0 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -3978,6 +3978,8 @@ void CLikeSourceEmitter::emitGlobalParam(IRGlobalParam* varDecl) if (as<IRVoidType>(varType)) return; + emitMemoryQualifiers(varDecl); + // When a global shader parameter represents a "parameter group" // (either a constant buffer or a parameter block with non-resource // data in it), we will prefer to emit it as an ordinary `cbuffer` diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index 2347d086b..1ae178aa8 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -116,25 +116,26 @@ void GLSLSourceEmitter::_requireGLSLVersion(int version) void GLSLSourceEmitter::_emitMemoryQualifierDecorations(IRInst* varDecl) { - for (auto decoration : varDecl->getDecorations()) + if(auto collection = varDecl->findDecoration<IRMemoryQualifierSetDecoration>()) { - if (as<IRGloballyCoherentDecoration>(decoration)) + IRIntegerValue flags = collection->getMemoryQualifierBit(); + if (flags & MemoryQualifierSetModifier::Flags::kCoherent) { m_writer->emit("coherent "); } - else if (as<IRGLSLVolatileDecoration>(decoration)) + if (flags & MemoryQualifierSetModifier::Flags::kVolatile) { m_writer->emit("volatile "); } - else if (as<IRGLSLRestrictDecoration>(decoration)) + if (flags & MemoryQualifierSetModifier::Flags::kRestrict) { m_writer->emit("restrict "); } - else if (as<IRGLSLReadOnlyDecoration>(decoration)) + if (flags & MemoryQualifierSetModifier::Flags::kReadOnly) { m_writer->emit("readonly "); } - else if (as<IRGLSLWriteOnlyDecoration>(decoration)) + if (flags & MemoryQualifierSetModifier::Flags::kWriteOnly) { m_writer->emit("writeonly "); } @@ -2749,11 +2750,6 @@ void GLSLSourceEmitter::emitVarDecorationsImpl(IRInst* varDecl) m_writer->emit(toSlice(")\n")); } } - - if (varDecl->findDecoration<IRGloballyCoherentDecoration>()) - { - m_writer->emit("coherent\n"); - } } void GLSLSourceEmitter::emitMatrixLayoutModifiersImpl(IRVarLayout* layout) diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp index 120e37f09..03de2108b 100644 --- a/source/slang/slang-emit-hlsl.cpp +++ b/source/slang/slang-emit-hlsl.cpp @@ -1266,18 +1266,20 @@ void HLSLSourceEmitter::emitVarDecorationsImpl(IRInst* varDecl) { for(auto decoration : varDecl->getDecorations()) { - if (as<IRGloballyCoherentDecoration>(decoration)) - { - m_writer->emit("globallycoherent\n"); - continue; - } - else if(auto glslInputAttachmentIndex = as<IRGLSLInputAttachmentIndexDecoration>(decoration)) + if(auto glslInputAttachmentIndex = as<IRGLSLInputAttachmentIndexDecoration>(decoration)) { m_writer->emit("[[vk::input_attachment_index("); m_writer->emit(glslInputAttachmentIndex->getIndex()->getValue()); m_writer->emit(")]]\n"); continue; } + if (auto collection = as<IRMemoryQualifierSetDecoration>(decoration)) + { + auto flags = collection->getMemoryQualifierBit(); + if(flags & MemoryQualifierSetModifier::Flags::kCoherent) + m_writer->emit("globallycoherent\n"); + continue; + } } } diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 91078e1fa..8bc3b9a44 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -3344,36 +3344,47 @@ struct SPIRVEmitContext requireSPIRVCapability(SpvCapabilityRayQueryKHR); isRayTracingObject = true; break; - case kIROp_GloballyCoherentDecoration: - emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), - decoration, - dstID, - SpvDecorationCoherent); - break; - case kIROp_GLSLVolatileDecoration: - emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), - decoration, - dstID, - SpvDecorationVolatile); - break; - case kIROp_GLSLRestrictDecoration: - emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), - decoration, - dstID, - SpvDecorationRestrict); - break; - case kIROp_GLSLReadOnlyDecoration: - emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), - decoration, - dstID, - SpvDecorationNonWritable); - break; - case kIROp_GLSLWriteOnlyDecoration: - emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), - decoration, - dstID, - SpvDecorationNonReadable); + case kIROp_MemoryQualifierSetDecoration: + { + auto collection = as<IRMemoryQualifierSetDecoration>(decoration); + IRIntegerValue flags = collection->getMemoryQualifierBit(); + if (flags & MemoryQualifierSetModifier::Flags::kCoherent) + { + emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), + nullptr, + dstID, + SpvDecorationCoherent); + } + if (flags & MemoryQualifierSetModifier::Flags::kVolatile) + { + emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), + nullptr, + dstID, + SpvDecorationVolatile); + } + if (flags & MemoryQualifierSetModifier::Flags::kRestrict) + { + emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), + nullptr, + dstID, + SpvDecorationRestrict); + } + if (flags & MemoryQualifierSetModifier::Flags::kReadOnly) + { + emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), + nullptr, + dstID, + SpvDecorationNonWritable); + } + if (flags & MemoryQualifierSetModifier::Flags::kWriteOnly) + { + emitOpDecorate(getSection(SpvLogicalSectionID::Annotations), + nullptr, + dstID, + SpvDecorationNonReadable); + } break; + } // ... } @@ -3466,15 +3477,59 @@ struct SPIRVEmitContext id, fieldNameDecor->getName()); } - else if (as<IRGloballyCoherentDecoration>(decor)) + else if (auto collection = as<IRMemoryQualifierSetDecoration>(decor)) { - emitOpMemberDecorate( - getSection(SpvLogicalSectionID::Annotations), - decor, - spvStructID, - SpvLiteralInteger::from32(id), - SpvDecorationCoherent - ); + IRIntegerValue flags = collection->getMemoryQualifierBit(); + if (flags & MemoryQualifierSetModifier::Flags::kCoherent) + { + emitOpMemberDecorate( + getSection(SpvLogicalSectionID::Annotations), + nullptr, + spvStructID, + SpvLiteralInteger::from32(id), + SpvDecorationCoherent + ); + } + if (flags & MemoryQualifierSetModifier::Flags::kVolatile) + { + emitOpMemberDecorate( + getSection(SpvLogicalSectionID::Annotations), + nullptr, + spvStructID, + SpvLiteralInteger::from32(id), + SpvDecorationVolatile + ); + } + if (flags & MemoryQualifierSetModifier::Flags::kRestrict) + { + emitOpMemberDecorate( + getSection(SpvLogicalSectionID::Annotations), + nullptr, + spvStructID, + SpvLiteralInteger::from32(id), + SpvDecorationRestrict + ); + } + if (flags & MemoryQualifierSetModifier::Flags::kReadOnly) + { + emitOpMemberDecorate( + getSection(SpvLogicalSectionID::Annotations), + nullptr, + spvStructID, + SpvLiteralInteger::from32(id), + SpvDecorationNonWritable + ); + } + if (flags & MemoryQualifierSetModifier::Flags::kWriteOnly) + { + emitOpMemberDecorate( + getSection(SpvLogicalSectionID::Annotations), + nullptr, + spvStructID, + SpvLiteralInteger::from32(id), + SpvDecorationNonReadable + ); + } } else if (auto semanticDecor = field->getKey()->findDecoration<IRSemanticDecoration>()) { diff --git a/source/slang/slang-ir-byte-address-legalize.cpp b/source/slang/slang-ir-byte-address-legalize.cpp index d5fc7ed5c..a089ca8ff 100644 --- a/source/slang/slang-ir-byte-address-legalize.cpp +++ b/source/slang/slang-ir-byte-address-legalize.cpp @@ -724,8 +724,9 @@ struct ByteAddressBufferLegalizationContext { switch (decoration->getOp()) { - case kIROp_GloballyCoherentDecoration: - builder.addDecoration(dest, decoration->getOp()); + case kIROp_MemoryQualifierSetDecoration: + builder.addMemoryQualifierSetDecoration(dest, + as<IRMemoryQualifierSetDecoration>(decoration)->getMemoryQualifierBit()); break; default: break; diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index 62283a7d6..e51f6dc95 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -728,7 +728,6 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0) INST(VulkanCallablePayloadDecoration, vulkanCallablePayload, 0, 0) INST(VulkanCallablePayloadInDecoration, vulkanCallablePayloadIn, 0, 0) INST(EarlyDepthStencilDecoration, earlyDepthStencil, 0, 0) - INST(GloballyCoherentDecoration, globallyCoherent, 0, 0) INST(PreciseDecoration, precise, 0, 0) INST(PublicDecoration, public, 0, 0) INST(HLSLExportDecoration, hlslExport, 0, 0) @@ -866,10 +865,6 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0) INST(GLSLLocationDecoration, glslLocation, 1, 0) INST(GLSLInputAttachmentIndexDecoration, glslInputAttachmentIndex, 1, 0) INST(GLSLOffsetDecoration, glslOffset, 1, 0) - INST(GLSLVolatileDecoration, glslVolatile, 1, 0) - INST(GLSLRestrictDecoration, glslRestrict, 1, 0) - INST(GLSLReadOnlyDecoration, glslReadonly, 1, 0) - INST(GLSLWriteOnlyDecoration, glslWriteonly, 1, 0) INST(PayloadDecoration, payload, 0, 0) /* Mesh Shader outputs */ @@ -1002,6 +997,9 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0) /// Recognized by SPIRV-emit pass so we can emit a SPIRV `Block` decoration. INST(SPIRVBlockDecoration, spvBlock, 0, 0) + // Stores flag bits of which memory qualifiers an object has + INST(MemoryQualifierSetDecoration, MemoryQualifierSetDecoration, 1, 0) + /// Marks a function as one which access a bitfield with the specified /// backing value key, width and offset INST(BitFieldAccessorDecoration, BitFieldAccessorDecoration, 3, 0) diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 8151622ae..60730f135 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -364,15 +364,17 @@ struct IRRequireGLSLExtensionDecoration : IRDecoration } }; +struct IRMemoryQualifierSetDecoration : IRDecoration +{ + enum { kOp = kIROp_MemoryQualifierSetDecoration }; + IR_LEAF_ISA(MemoryQualifierSetDecoration) + IRIntegerValue getMemoryQualifierBit() { return cast<IRIntLit>(getOperand(0))->getValue(); } +}; + IR_SIMPLE_DECORATION(HasExplicitHLSLBindingDecoration) IR_SIMPLE_DECORATION(ReadNoneDecoration) IR_SIMPLE_DECORATION(NoSideEffectDecoration) IR_SIMPLE_DECORATION(EarlyDepthStencilDecoration) -IR_SIMPLE_DECORATION(GloballyCoherentDecoration) -IR_SIMPLE_DECORATION(GLSLVolatileDecoration) -IR_SIMPLE_DECORATION(GLSLRestrictDecoration) -IR_SIMPLE_DECORATION(GLSLReadOnlyDecoration) -IR_SIMPLE_DECORATION(GLSLWriteOnlyDecoration) IR_SIMPLE_DECORATION(PreciseDecoration) IR_SIMPLE_DECORATION(PublicDecoration) IR_SIMPLE_DECORATION(HLSLExportDecoration) @@ -4830,6 +4832,11 @@ public: { addDecoration(value, kIROp_KnownBuiltinDecoration, getStringValue(name)); } + + void addMemoryQualifierSetDecoration(IRInst* inst, IRIntegerValue flags) + { + addDecoration(inst, kIROp_MemoryQualifierSetDecoration, getIntValue(getIntType(), flags)); + } }; // Helper to establish the source location that will be used diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp index f6370ca37..a1126104a 100644 --- a/source/slang/slang-ir-spirv-legalize.cpp +++ b/source/slang/slang-ir-spirv-legalize.cpp @@ -623,6 +623,10 @@ struct SPIRVLegalizationContext : public SourceEmitterBase innerType = lowerStructuredBufferType(structuredBufferType).structType; storageClass = SpvStorageClassStorageBuffer; needLoad = false; + + // structured buffers in GLSL should be annotated as ReadOnly + if (as<IRHLSLStructuredBufferType>(structuredBufferType)) + builder.addMemoryQualifierSetDecoration(inst, MemoryQualifierSetModifier::Flags::kReadOnly); } else if (auto glslShaderStorageBufferType = as<IRGLSLShaderStorageBufferType>(innerType)) { diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index 85464446d..2dfbde2cc 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -56,7 +56,6 @@ namespace Slang switch (op) { case kIROp_EarlyDepthStencilDecoration: - case kIROp_GloballyCoherentDecoration: case kIROp_KeepAliveDecoration: case kIROp_LineAdjInputPrimitiveTypeDecoration: case kIROp_LineInputPrimitiveTypeDecoration: diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 2d9ecf574..6a6ca7c64 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -2175,10 +2175,6 @@ void addVarDecorations( // may not be referenced; adding HLSL export modifier force emits builder->addHLSLExportDecoration(inst); } - else if(as<GloballyCoherentModifier>(mod)) - { - builder->addSimpleDecoration<IRGloballyCoherentDecoration>(inst); - } else if(as<PreciseModifier>(mod)) { builder->addSimpleDecoration<IRPreciseDecoration>(inst); @@ -2227,21 +2223,9 @@ void addVarDecorations( { builder->addDynamicUniformDecoration(inst); } - else if (as<GLSLVolatileModifier>(mod)) - { - builder->addSimpleDecoration<IRGLSLVolatileDecoration>(inst); - } - else if (as<GLSLRestrictModifier>(mod)) - { - builder->addSimpleDecoration<IRGLSLRestrictDecoration>(inst); - } - else if (as<GLSLReadOnlyModifier>(mod)) - { - builder->addSimpleDecoration<IRGLSLReadOnlyDecoration>(inst); - } - else if (as<GLSLWriteOnlyModifier>(mod)) + else if (auto collection = as<MemoryQualifierSetModifier>(mod)) { - builder->addSimpleDecoration<IRGLSLWriteOnlyDecoration>(inst); + builder->addMemoryQualifierSetDecoration(inst, IRIntegerValue(collection->getMemoryQualifierBit())); } // TODO: what are other modifiers we need to propagate through? } |
