Add support for new HLSL semantic/counter buffer decorations.
This commit is contained in:
parent
7f84537350
commit
215d3ca0a4
@ -1185,6 +1185,7 @@ struct Meta
|
||||
{
|
||||
std::string alias;
|
||||
std::string qualified_alias;
|
||||
std::string hlsl_semantic;
|
||||
Bitset decoration_flags;
|
||||
spv::BuiltIn builtin_type;
|
||||
uint32_t location = 0;
|
||||
@ -1212,6 +1213,11 @@ struct Meta
|
||||
// is not a valid identifier in any high-level language.
|
||||
std::string hlsl_magic_counter_buffer_name;
|
||||
bool hlsl_magic_counter_buffer_candidate = false;
|
||||
|
||||
// For SPV_GOOGLE_hlsl_functionality1, this avoids the workaround.
|
||||
bool hlsl_is_magic_counter_buffer = false;
|
||||
// ID for the sibling counter buffer.
|
||||
uint32_t hlsl_magic_counter_buffer = 0;
|
||||
};
|
||||
|
||||
// A user callback that remaps the type of any variable.
|
||||
|
112
spirv_cross.cpp
112
spirv_cross.cpp
@ -1012,6 +1012,7 @@ void Compiler::set_name(uint32_t id, const std::string &name)
|
||||
|
||||
// glslang uses identifiers to pass along meaningful information
|
||||
// about HLSL reflection.
|
||||
// FIXME: This should be deprecated eventually.
|
||||
auto &m = meta.at(id);
|
||||
if (source.hlsl && name.size() >= 6 && name.find("@count") == name.size() - 6)
|
||||
{
|
||||
@ -1041,6 +1042,24 @@ const SPIRType &Compiler::get_type_from_variable(uint32_t id) const
|
||||
return get<SPIRType>(get<SPIRVariable>(id).basetype);
|
||||
}
|
||||
|
||||
void Compiler::set_member_decoration_string(uint32_t id, uint32_t index, spv::Decoration decoration,
|
||||
const std::string &argument)
|
||||
{
|
||||
meta.at(id).members.resize(max(meta[id].members.size(), size_t(index) + 1));
|
||||
auto &dec = meta.at(id).members[index];
|
||||
dec.decoration_flags.set(decoration);
|
||||
|
||||
switch (decoration)
|
||||
{
|
||||
case DecorationHlslSemanticGOOGLE:
|
||||
dec.hlsl_semantic = argument;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::set_member_decoration(uint32_t id, uint32_t index, Decoration decoration, uint32_t argument)
|
||||
{
|
||||
meta.at(id).members.resize(max(meta[id].members.size(), size_t(index) + 1));
|
||||
@ -1206,6 +1225,26 @@ void Compiler::unset_member_decoration(uint32_t id, uint32_t index, Decoration d
|
||||
dec.spec_id = 0;
|
||||
break;
|
||||
|
||||
case DecorationHlslSemanticGOOGLE:
|
||||
dec.hlsl_semantic.clear();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::set_decoration_string(uint32_t id, spv::Decoration decoration, const std::string &argument)
|
||||
{
|
||||
auto &dec = meta.at(id).decoration;
|
||||
dec.decoration_flags.set(decoration);
|
||||
|
||||
switch (decoration)
|
||||
{
|
||||
case DecorationHlslSemanticGOOGLE:
|
||||
dec.hlsl_semantic = argument;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1259,6 +1298,11 @@ void Compiler::set_decoration(uint32_t id, Decoration decoration, uint32_t argum
|
||||
dec.index = argument;
|
||||
break;
|
||||
|
||||
case DecorationHlslCounterBufferGOOGLE:
|
||||
meta.at(id).hlsl_magic_counter_buffer = argument;
|
||||
meta.at(argument).hlsl_is_magic_counter_buffer = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1304,6 +1348,24 @@ bool Compiler::has_decoration(uint32_t id, Decoration decoration) const
|
||||
return get_decoration_bitset(id).get(decoration);
|
||||
}
|
||||
|
||||
const string &Compiler::get_decoration_string(uint32_t id, spv::Decoration decoration) const
|
||||
{
|
||||
auto &dec = meta.at(id).decoration;
|
||||
static const string empty;
|
||||
|
||||
if (!dec.decoration_flags.get(decoration))
|
||||
return empty;
|
||||
|
||||
switch (decoration)
|
||||
{
|
||||
case DecorationHlslSemanticGOOGLE:
|
||||
return dec.hlsl_semantic;
|
||||
|
||||
default:
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Compiler::get_decoration(uint32_t id, Decoration decoration) const
|
||||
{
|
||||
auto &dec = meta.at(id).decoration;
|
||||
@ -1371,6 +1433,21 @@ void Compiler::unset_decoration(uint32_t id, Decoration decoration)
|
||||
dec.spec_id = 0;
|
||||
break;
|
||||
|
||||
case DecorationHlslSemanticGOOGLE:
|
||||
dec.hlsl_semantic.clear();
|
||||
break;
|
||||
|
||||
case DecorationHlslCounterBufferGOOGLE:
|
||||
{
|
||||
auto &counter = meta.at(id).hlsl_magic_counter_buffer;
|
||||
if (counter)
|
||||
{
|
||||
meta.at(counter).hlsl_is_magic_counter_buffer = false;
|
||||
counter = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1548,6 +1625,7 @@ void Compiler::parse(const Instruction &instruction)
|
||||
}
|
||||
|
||||
case OpDecorate:
|
||||
case OpDecorateId:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
|
||||
@ -1563,6 +1641,14 @@ void Compiler::parse(const Instruction &instruction)
|
||||
break;
|
||||
}
|
||||
|
||||
case OpDecorateStringGOOGLE:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
auto decoration = static_cast<Decoration>(ops[1]);
|
||||
set_decoration_string(id, decoration, extract_string(spirv, instruction.offset + 2));
|
||||
break;
|
||||
}
|
||||
|
||||
case OpMemberDecorate:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
@ -1575,6 +1661,15 @@ void Compiler::parse(const Instruction &instruction)
|
||||
break;
|
||||
}
|
||||
|
||||
case OpMemberDecorateStringGOOGLE:
|
||||
{
|
||||
uint32_t id = ops[0];
|
||||
uint32_t member = ops[1];
|
||||
auto decoration = static_cast<Decoration>(ops[2]);
|
||||
set_member_decoration_string(id, member, decoration, extract_string(spirv, instruction.offset + 3));
|
||||
break;
|
||||
}
|
||||
|
||||
// Build up basic types.
|
||||
case OpTypeVoid:
|
||||
{
|
||||
@ -4239,6 +4334,13 @@ bool Compiler::CombinedImageSamplerUsageHandler::handle(Op opcode, const uint32_
|
||||
|
||||
bool Compiler::buffer_is_hlsl_counter_buffer(uint32_t id) const
|
||||
{
|
||||
// First, check for the proper decoration.
|
||||
if (meta.at(id).hlsl_is_magic_counter_buffer)
|
||||
return true;
|
||||
|
||||
// Check for legacy fallback method.
|
||||
// FIXME: This should be deprecated eventually.
|
||||
|
||||
if (meta.at(id).hlsl_magic_counter_buffer_candidate)
|
||||
{
|
||||
auto *var = maybe_get<SPIRVariable>(id);
|
||||
@ -4252,6 +4354,16 @@ bool Compiler::buffer_is_hlsl_counter_buffer(uint32_t id) const
|
||||
|
||||
bool Compiler::buffer_get_hlsl_counter_buffer(uint32_t id, uint32_t &counter_id) const
|
||||
{
|
||||
// First, check for the proper decoration.
|
||||
if (meta[id].hlsl_magic_counter_buffer != 0)
|
||||
{
|
||||
counter_id = meta[id].hlsl_magic_counter_buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for legacy fallback method.
|
||||
// FIXME: This should be deprecated eventually.
|
||||
|
||||
auto &name = get_name(id);
|
||||
uint32_t id_bound = get_current_id_bound();
|
||||
for (uint32_t i = 0; i < id_bound; i++)
|
||||
|
@ -136,6 +136,7 @@ public:
|
||||
|
||||
// Applies a decoration to an ID. Effectively injects OpDecorate.
|
||||
void set_decoration(uint32_t id, spv::Decoration decoration, uint32_t argument = 0);
|
||||
void set_decoration_string(uint32_t id, spv::Decoration decoration, const std::string &argument);
|
||||
|
||||
// Overrides the identifier OpName of an ID.
|
||||
// Identifiers beginning with underscores or identifiers which contain double underscores
|
||||
@ -157,6 +158,7 @@ public:
|
||||
// If decoration doesn't exist or decoration is not recognized,
|
||||
// 0 will be returned.
|
||||
uint32_t get_decoration(uint32_t id, spv::Decoration decoration) const;
|
||||
const std::string &get_decoration_string(uint32_t id, spv::Decoration decoration) const;
|
||||
|
||||
// Removes the decoration for a an ID.
|
||||
void unset_decoration(uint32_t id, spv::Decoration decoration);
|
||||
@ -185,6 +187,7 @@ public:
|
||||
|
||||
// Given an OpTypeStruct in ID, obtain the OpMemberDecoration for member number "index".
|
||||
uint32_t get_member_decoration(uint32_t id, uint32_t index, spv::Decoration decoration) const;
|
||||
const std::string &get_member_decoration_string(uint32_t id, uint32_t index, spv::Decoration decoration) const;
|
||||
|
||||
// Sets the member identifier for OpTypeStruct ID, member number "index".
|
||||
void set_member_name(uint32_t id, uint32_t index, const std::string &name);
|
||||
@ -206,6 +209,8 @@ public:
|
||||
|
||||
// Similar to set_decoration, but for struct members.
|
||||
void set_member_decoration(uint32_t id, uint32_t index, spv::Decoration decoration, uint32_t argument = 0);
|
||||
void set_member_decoration_string(uint32_t id, uint32_t index, spv::Decoration decoration,
|
||||
const std::string &argument);
|
||||
|
||||
// Unsets a member decoration, similar to unset_decoration.
|
||||
void unset_member_decoration(uint32_t id, uint32_t index, spv::Decoration decoration);
|
||||
@ -441,14 +446,18 @@ public:
|
||||
// which lets us link the two buffers together.
|
||||
|
||||
// Queries if a variable ID is a counter buffer which "belongs" to a regular buffer object.
|
||||
// NOTE: This query is purely based on OpName identifiers as found in the SPIR-V module, and will
|
||||
|
||||
// If SPV_GOOGLE_hlsl_functionality1 is used, this can be used even with a stripped SPIR-V module.
|
||||
// Otherwise, this query is purely based on OpName identifiers as found in the SPIR-V module, and will
|
||||
// only return true if OpSource was reported HLSL.
|
||||
// To rely on this functionality, ensure that the SPIR-V module is not stripped.
|
||||
|
||||
bool buffer_is_hlsl_counter_buffer(uint32_t id) const;
|
||||
|
||||
// Queries if a buffer object has a neighbor "counter" buffer.
|
||||
// If so, the ID of that counter buffer will be returned in counter_id.
|
||||
// NOTE: This query is purely based on OpName identifiers as found in the SPIR-V module, and will
|
||||
// If SPV_GOOGLE_hlsl_functionality1 is used, this can be used even with a stripped SPIR-V module.
|
||||
// Otherwise, this query is purely based on OpName identifiers as found in the SPIR-V module, and will
|
||||
// only return true if OpSource was reported HLSL.
|
||||
// To rely on this functionality, ensure that the SPIR-V module is not stripped.
|
||||
bool buffer_get_hlsl_counter_buffer(uint32_t id, uint32_t &counter_id) const;
|
||||
|
Loading…
Reference in New Issue
Block a user