Add a helper applySpirvDecorate to handle spirv_decorate_xxx directives
Some code paths could be shared.
This commit is contained in:
parent
091b9fd979
commit
a8d39f97cd
1 changed files with 65 additions and 71 deletions
|
|
@ -66,6 +66,7 @@ namespace spv {
|
|||
#include <iomanip>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
|
@ -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<int> 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<int> 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<unsigned> literals;
|
||||
TranslateLiterals(decorate.second, literals);
|
||||
if (member.has_value())
|
||||
builder.addMemberDecoration(id, *member, static_cast<spv::Decoration>(decorate.first), literals);
|
||||
else
|
||||
builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first), literals);
|
||||
} else {
|
||||
if (member.has_value())
|
||||
builder.addMemberDecoration(id, *member, static_cast<spv::Decoration>(decorate.first));
|
||||
else
|
||||
builder.addDecoration(id, static_cast<spv::Decoration>(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<spv::Id> 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<spv::Decoration>(decorateId.first), operandIds);
|
||||
}
|
||||
}
|
||||
|
||||
// Add spirv_decorate_string
|
||||
for (auto& decorateString : spirvDecorate.decorateStrings) {
|
||||
std::vector<const char*> 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<spv::Decoration>(decorateString.first), strings);
|
||||
else
|
||||
builder.addDecoration(id, static_cast<spv::Decoration>(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<unsigned> literals;
|
||||
TranslateLiterals(decorate.second, literals);
|
||||
builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first), literals);
|
||||
}
|
||||
else
|
||||
builder.addMemberDecoration(spvType, member, static_cast<spv::Decoration>(decorate.first));
|
||||
}
|
||||
|
||||
// spirv_decorate_id not applied to members
|
||||
assert(spirvDecorate.decorateIds.empty());
|
||||
|
||||
// Add spirv_decorate_string
|
||||
for (auto& decorateString : spirvDecorate.decorateStrings) {
|
||||
std::vector<const char*> 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<spv::Decoration>(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<unsigned> literals;
|
||||
TranslateLiterals(decorate.second, literals);
|
||||
builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first), literals);
|
||||
}
|
||||
else
|
||||
builder.addDecoration(id, static_cast<spv::Decoration>(decorate.first));
|
||||
}
|
||||
|
||||
// Add spirv_decorate_id
|
||||
for (auto& decorateId : spirvDecorate.decorateIds) {
|
||||
std::vector<spv::Id> 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<spv::Decoration>(decorateId.first), operandIds);
|
||||
}
|
||||
|
||||
// Add spirv_decorate_string
|
||||
for (auto& decorateString : spirvDecorate.decorateStrings) {
|
||||
std::vector<const char*> 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<spv::Decoration>(decorateString.first), strings);
|
||||
}
|
||||
}
|
||||
if (symbol->getType().getQualifier().hasSpirvDecorate())
|
||||
applySpirvDecorate(symbol->getType(), id, {});
|
||||
|
||||
return id;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue