diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index ace58ec0..25a39777 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -66,6 +66,7 @@ namespace spv { #include #include #include +#include #include #include #include @@ -164,6 +165,7 @@ protected: spv::Id convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly = false); spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&, bool lastBufferBlockMember, bool forwardReferenceOnly = false); + void applySpirvDecorate(const glslang::TType& type, spv::Id id, std::optional member); bool filterMember(const glslang::TType& member); spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct, glslang::TLayoutPacking, const glslang::TQualifier&); @@ -4705,6 +4707,64 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty return spvType; } +// Apply SPIR-V decorations to the SPIR-V object (provided by SPIR-V ID). If member index is provided, the +// decorations are applied to this member. +void TGlslangToSpvTraverser::applySpirvDecorate(const glslang::TType& type, spv::Id id, std::optional member) +{ + assert(type.getQualifier().hasSpirvDecorate()); + + const glslang::TSpirvDecorate& spirvDecorate = type.getQualifier().getSpirvDecorate(); + + // Add spirv_decorate + for (auto& decorate : spirvDecorate.decorates) { + if (!decorate.second.empty()) { + std::vector literals; + TranslateLiterals(decorate.second, literals); + if (member.has_value()) + builder.addMemberDecoration(id, *member, static_cast(decorate.first), literals); + else + builder.addDecoration(id, static_cast(decorate.first), literals); + } else { + if (member.has_value()) + builder.addMemberDecoration(id, *member, static_cast(decorate.first)); + else + builder.addDecoration(id, static_cast(decorate.first)); + } + } + + // Add spirv_decorate_id + if (member.has_value()) { + // spirv_decorate_id not applied to members + assert(spirvDecorate.decorateIds.empty()); + } else { + for (auto& decorateId : spirvDecorate.decorateIds) { + std::vector operandIds; + assert(!decorateId.second.empty()); + for (auto extraOperand : decorateId.second) { + if (extraOperand->getQualifier().isFrontEndConstant()) + operandIds.push_back(createSpvConstant(*extraOperand)); + else + operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode())); + } + builder.addDecorationId(id, static_cast(decorateId.first), operandIds); + } + } + + // Add spirv_decorate_string + for (auto& decorateString : spirvDecorate.decorateStrings) { + std::vector strings; + assert(!decorateString.second.empty()); + for (auto extraOperand : decorateString.second) { + const char* string = extraOperand->getConstArray()[0].getSConst()->c_str(); + strings.push_back(string); + } + if (member.has_value()) + builder.addMemberDecoration(id, *member, static_cast(decorateString.first), strings); + else + builder.addDecoration(id, static_cast(decorateString.first), strings); + } +} + // TODO: this functionality should exist at a higher level, in creating the AST // // Identify interface members that don't have their required extension turned on. @@ -4943,37 +5003,9 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough); } - // - // Add SPIR-V decorations for members (GL_EXT_spirv_intrinsics) - // - if (glslangMember.getQualifier().hasSpirvDecorate()) { - const glslang::TSpirvDecorate& spirvDecorate = glslangMember.getQualifier().getSpirvDecorate(); - - // Add spirv_decorate - for (auto& decorate : spirvDecorate.decorates) { - if (!decorate.second.empty()) { - std::vector literals; - TranslateLiterals(decorate.second, literals); - builder.addMemberDecoration(spvType, member, static_cast(decorate.first), literals); - } - else - builder.addMemberDecoration(spvType, member, static_cast(decorate.first)); - } - - // spirv_decorate_id not applied to members - assert(spirvDecorate.decorateIds.empty()); - - // Add spirv_decorate_string - for (auto& decorateString : spirvDecorate.decorateStrings) { - std::vector strings; - assert(!decorateString.second.empty()); - for (auto extraOperand : decorateString.second) { - const char* string = extraOperand->getConstArray()[0].getSConst()->c_str(); - strings.push_back(string); - } - builder.addDecoration(spvType, static_cast(decorateString.first), strings); - } - } + // Add SPIR-V decorations (GL_EXT_spirv_intrinsics) + if (glslangMember.getQualifier().hasSpirvDecorate()) + applySpirvDecorate(glslangMember, spvType, member); } // Decorate the structure @@ -9598,47 +9630,9 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT); } - // // Add SPIR-V decorations (GL_EXT_spirv_intrinsics) - // - if (symbol->getType().getQualifier().hasSpirvDecorate()) { - const glslang::TSpirvDecorate& spirvDecorate = symbol->getType().getQualifier().getSpirvDecorate(); - - // Add spirv_decorate - for (auto& decorate : spirvDecorate.decorates) { - if (!decorate.second.empty()) { - std::vector literals; - TranslateLiterals(decorate.second, literals); - builder.addDecoration(id, static_cast(decorate.first), literals); - } - else - builder.addDecoration(id, static_cast(decorate.first)); - } - - // Add spirv_decorate_id - for (auto& decorateId : spirvDecorate.decorateIds) { - std::vector operandIds; - assert(!decorateId.second.empty()); - for (auto extraOperand : decorateId.second) { - if (extraOperand->getQualifier().isFrontEndConstant()) - operandIds.push_back(createSpvConstant(*extraOperand)); - else - operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode())); - } - builder.addDecorationId(id, static_cast(decorateId.first), operandIds); - } - - // Add spirv_decorate_string - for (auto& decorateString : spirvDecorate.decorateStrings) { - std::vector strings; - assert(!decorateString.second.empty()); - for (auto extraOperand : decorateString.second) { - const char* string = extraOperand->getConstArray()[0].getSConst()->c_str(); - strings.push_back(string); - } - builder.addDecoration(id, static_cast(decorateString.first), strings); - } - } + if (symbol->getType().getQualifier().hasSpirvDecorate()) + applySpirvDecorate(symbol->getType(), id, {}); return id; }