summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-06-12 09:39:20 -0700
committerGitHub <noreply@github.com>2024-06-12 09:39:20 -0700
commit180d6b13c6794a0bbb209df023301701cda15158 (patch)
tree3a7ff1697c9b7fc71c6d44850659ea13013dcc69 /source
parentfa8c11ebe8f9b1bf2174a5a4dbe92a34c16811c8 (diff)
Fix duplicate SPIRV decorations. (#4346)
* Fix duplicate `DescriptorSet` decorations. * Fix duplicate `Block` decoration.
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-emit-spirv.cpp39
-rw-r--r--source/slang/slang-ir-insts.h9
-rw-r--r--source/slang/slang-ir-spirv-legalize.cpp10
3 files changed, 38 insertions, 20 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp
index 10c263793..df60feecf 100644
--- a/source/slang/slang-emit-spirv.cpp
+++ b/source/slang/slang-emit-spirv.cpp
@@ -2139,6 +2139,7 @@ struct SPIRVEmitContext
{
bool needDefaultSetBindingDecoration = false;
bool hasExplicitSetBinding = false;
+ bool isDescirptorSetDecorated = false;
for (auto rr : layout->getOffsetAttrs())
{
UInt index = rr->getOffset();
@@ -2200,32 +2201,40 @@ struct SPIRVEmitContext
nullptr,
varInst,
SpvLiteralInteger::from32(int32_t(index)));
- if (space)
+ if (!isDescirptorSetDecorated)
+ {
+ if (space)
+ {
+ emitOpDecorateDescriptorSet(
+ getSection(SpvLogicalSectionID::Annotations),
+ nullptr,
+ varInst,
+ SpvLiteralInteger::from32(int32_t(space)));
+ isDescirptorSetDecorated = true;
+ }
+ else
+ {
+ needDefaultSetBindingDecoration = true;
+ }
+ }
+ break;
+ case LayoutResourceKind::RegisterSpace:
+ if (!isDescirptorSetDecorated)
{
emitOpDecorateDescriptorSet(
getSection(SpvLogicalSectionID::Annotations),
nullptr,
varInst,
- SpvLiteralInteger::from32(int32_t(space)));
+ SpvLiteralInteger::from32(int32_t(index)));
+ hasExplicitSetBinding = true;
+ isDescirptorSetDecorated = true;
}
- else
- {
- needDefaultSetBindingDecoration = true;
- }
- break;
- case LayoutResourceKind::RegisterSpace:
- emitOpDecorateDescriptorSet(
- getSection(SpvLogicalSectionID::Annotations),
- nullptr,
- varInst,
- SpvLiteralInteger::from32(int32_t(index)));
- hasExplicitSetBinding = true;
break;
default:
break;
}
}
- if (needDefaultSetBindingDecoration && !hasExplicitSetBinding)
+ if (needDefaultSetBindingDecoration && !hasExplicitSetBinding && !isDescirptorSetDecorated)
{
emitOpDecorateDescriptorSet(
getSection(SpvLogicalSectionID::Annotations),
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index d63c6878e..bc86fa7ee 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -328,6 +328,8 @@ IR_SIMPLE_DECORATION(VulkanHitObjectAttributesDecoration)
IR_SIMPLE_DECORATION(PerVertexDecoration)
+IR_SIMPLE_DECORATION(SPIRVBlockDecoration)
+
struct IRRequireGLSLVersionDecoration : IRDecoration
{
enum { kOp = kIROp_RequireGLSLVersionDecoration };
@@ -4342,6 +4344,13 @@ public:
return addDecoration(value, op, (IRInst* const*) nullptr, 0);
}
+ IRDecoration* addDecorationIfNotExist(IRInst* value, IROp op)
+ {
+ if (auto decor = value->findDecorationImpl(op))
+ return decor;
+ return addDecoration(value, op);
+ }
+
IRDecoration* addDecoration(IRInst* value, IROp op, IRInst* operand)
{
return addDecoration(value, op, &operand, 1);
diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp
index 44c5bae7b..989790b13 100644
--- a/source/slang/slang-ir-spirv-legalize.cpp
+++ b/source/slang/slang-ir-spirv-legalize.cpp
@@ -137,9 +137,9 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
}
builder.addNameHintDecoration(structType, nameSb.getUnownedSlice());
if (m_sharedContext->isSpirv14OrLater())
- builder.addDecoration(structType, kIROp_SPIRVBlockDecoration);
+ builder.addDecorationIfNotExist(structType, kIROp_SPIRVBlockDecoration);
else
- builder.addDecoration(structType, kIROp_SPIRVBufferBlockDecoration);
+ builder.addDecorationIfNotExist(structType, kIROp_SPIRVBufferBlockDecoration);
result.structType = structType;
result.arrayKey = arrayKey;
@@ -594,7 +594,7 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
{
innerType = wrapConstantBufferElement(inst);
}
- builder.addDecoration(innerType, kIROp_SPIRVBlockDecoration);
+ builder.addDecorationIfNotExist(innerType, kIROp_SPIRVBlockDecoration);
auto varLayoutInst = inst->findDecoration<IRLayoutDecoration>();
if (paramBlockType)
@@ -650,12 +650,12 @@ struct SPIRVLegalizationContext : public SourceEmitterBase
innerType = glslShaderStorageBufferType->getElementType();
if (m_sharedContext->isSpirv14OrLater())
{
- builder.addDecoration(innerType, kIROp_SPIRVBlockDecoration);
+ builder.addDecorationIfNotExist(innerType, kIROp_SPIRVBlockDecoration);
storageClass = SpvStorageClassStorageBuffer;
}
else
{
- builder.addDecoration(innerType, kIROp_SPIRVBufferBlockDecoration);
+ builder.addDecorationIfNotExist(innerType, kIROp_SPIRVBufferBlockDecoration);
storageClass = SpvStorageClassUniform;
}
needLoad = false;