From 180d6b13c6794a0bbb209df023301701cda15158 Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 12 Jun 2024 09:39:20 -0700 Subject: Fix duplicate SPIRV decorations. (#4346) * Fix duplicate `DescriptorSet` decorations. * Fix duplicate `Block` decoration. --- source/slang/slang-emit-spirv.cpp | 39 ++++++++++++++++++++------------ source/slang/slang-ir-insts.h | 9 ++++++++ source/slang/slang-ir-spirv-legalize.cpp | 10 ++++---- 3 files changed, 38 insertions(+), 20 deletions(-) (limited to 'source') 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(); 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; -- cgit v1.2.3