summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorArielG-NV <159081215+ArielG-NV@users.noreply.github.com>2024-04-03 14:19:15 -0400
committerGitHub <noreply@github.com>2024-04-03 11:19:15 -0700
commite0de98e9aabbe118f0eeca7821518c8fb4e1f6c4 (patch)
treea310629cd025372c6d554705ba7f42251f400ac5 /source
parenta697b2c6707ee699cb734a03fa529dd214ac66cc (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.h4
-rw-r--r--source/slang/slang-check-decl.cpp24
-rw-r--r--source/slang/slang-check-expr.cpp23
-rw-r--r--source/slang/slang-check-modifier.cpp27
-rw-r--r--source/slang/slang-emit-c-like.cpp2
-rw-r--r--source/slang/slang-emit-glsl.cpp18
-rw-r--r--source/slang/slang-emit-hlsl.cpp14
-rw-r--r--source/slang/slang-emit-spirv.cpp129
-rw-r--r--source/slang/slang-ir-byte-address-legalize.cpp5
-rw-r--r--source/slang/slang-ir-inst-defs.h8
-rw-r--r--source/slang/slang-ir-insts.h17
-rw-r--r--source/slang/slang-ir-spirv-legalize.cpp4
-rw-r--r--source/slang/slang-ir.cpp1
-rw-r--r--source/slang/slang-lower-to-ir.cpp20
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?
}