mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-26 17:51:02 +00:00
Make friendly names for built-in variables.
Handles only OpDecorate Does not handle: - decorations on struct members - decoration via OpGroupDecorate
This commit is contained in:
parent
247e024c72
commit
e0dd033414
1
CHANGES
1
CHANGES
@ -1,6 +1,7 @@
|
||||
Revision history for SPIRV-Tools
|
||||
|
||||
v2016.5-dev 2016-09-12
|
||||
- Disassembler: Generate friendly names for built-in variables.
|
||||
- Partial fixes:
|
||||
#359: Add Emacs helper for automatically diassembling/assembling a SPIR-V
|
||||
binary on file load/save.
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "name_mapper.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
@ -95,6 +96,70 @@ void FriendlyNameMapper::SaveName(uint32_t id,
|
||||
name_for_id_[id] = name;
|
||||
}
|
||||
|
||||
void FriendlyNameMapper::SaveBuiltInName(uint32_t target_id,
|
||||
uint32_t built_in) {
|
||||
#define GLCASE(name) \
|
||||
case SpvBuiltIn##name: \
|
||||
SaveName(target_id, "gl_" #name); \
|
||||
return;
|
||||
#define GLCASE2(name, suggested) \
|
||||
case SpvBuiltIn##name: \
|
||||
SaveName(target_id, "gl_" #suggested); \
|
||||
return;
|
||||
#define CASE(name) \
|
||||
case SpvBuiltIn##name: \
|
||||
SaveName(target_id, #name); \
|
||||
return;
|
||||
switch (built_in) {
|
||||
GLCASE(Position)
|
||||
GLCASE(PointSize)
|
||||
GLCASE(ClipDistance)
|
||||
GLCASE(CullDistance)
|
||||
GLCASE2(VertexId, VertexID)
|
||||
GLCASE2(InstanceId, InstanceID)
|
||||
GLCASE2(PrimitiveId, PrimitiveID)
|
||||
GLCASE2(InvocationId, InvocationID)
|
||||
GLCASE(Layer)
|
||||
GLCASE(ViewportIndex)
|
||||
GLCASE(TessLevelOuter)
|
||||
GLCASE(TessLevelInner)
|
||||
GLCASE(TessCoord)
|
||||
GLCASE(PatchVertices)
|
||||
GLCASE(FragCoord)
|
||||
GLCASE(PointCoord)
|
||||
GLCASE(FrontFacing)
|
||||
GLCASE2(SampleId, SampleID)
|
||||
GLCASE(SamplePosition)
|
||||
GLCASE(SampleMask)
|
||||
GLCASE(FragDepth)
|
||||
GLCASE(HelperInvocation)
|
||||
GLCASE2(NumWorkgroups, NumWorkGroups)
|
||||
GLCASE2(WorkgroupSize, WorkGroupSize)
|
||||
GLCASE2(WorkgroupId, WorkGroupID)
|
||||
GLCASE2(LocalInvocationId, LocalInvocationID)
|
||||
GLCASE2(GlobalInvocationId, GlobalInvocationID)
|
||||
GLCASE(LocalInvocationIndex)
|
||||
CASE(WorkDim)
|
||||
CASE(GlobalSize)
|
||||
CASE(EnqueuedWorkgroupSize)
|
||||
CASE(GlobalOffset)
|
||||
CASE(GlobalLinearId)
|
||||
CASE(SubgroupSize)
|
||||
CASE(SubgroupMaxSize)
|
||||
CASE(NumSubgroups)
|
||||
CASE(NumEnqueuedSubgroups)
|
||||
CASE(SubgroupId)
|
||||
CASE(SubgroupLocalInvocationId)
|
||||
GLCASE(VertexIndex)
|
||||
GLCASE(InstanceIndex)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#undef GLCASE
|
||||
#undef GLCASE2
|
||||
#undef CASE
|
||||
}
|
||||
|
||||
spv_result_t FriendlyNameMapper::ParseInstruction(
|
||||
const spv_parsed_instruction_t& inst) {
|
||||
const auto result_id = inst.result_id;
|
||||
@ -102,6 +167,17 @@ spv_result_t FriendlyNameMapper::ParseInstruction(
|
||||
case SpvOpName:
|
||||
SaveName(inst.words[1], reinterpret_cast<const char*>(inst.words + 2));
|
||||
break;
|
||||
case SpvOpDecorate:
|
||||
// Decorations come after OpName. So OpName will take precedence over
|
||||
// decorations.
|
||||
//
|
||||
// In theory, we should also handle OpGroupDecorate. But that's unlikely
|
||||
// to occur.
|
||||
if (inst.words[2] == SpvDecorationBuiltIn) {
|
||||
assert(inst.num_words > 3);
|
||||
SaveBuiltInName(inst.words[1], inst.words[3]);
|
||||
}
|
||||
break;
|
||||
case SpvOpTypeVoid:
|
||||
SaveName(result_id, "void");
|
||||
break;
|
||||
|
@ -56,6 +56,7 @@ NameMapper GetTrivialNameMapper();
|
||||
// human readable names.
|
||||
// - A struct type maps to "_struct_" followed by the raw Id number. That's
|
||||
// pretty simplistic, but workable.
|
||||
// - A built-in variable maps to its GLSL variable name.
|
||||
class FriendlyNameMapper {
|
||||
public:
|
||||
// Construct a friendly name mapper, and determine friendly names for each
|
||||
@ -80,11 +81,16 @@ class FriendlyNameMapper {
|
||||
// assembly language. Two distinct inputs can map to the same output.
|
||||
std::string Sanitize(const std::string& suggested_name);
|
||||
|
||||
// Records a name for the given id. Use the given suggested_name if it
|
||||
// hasn't already been taken, and otherwise generate a new (unused) name
|
||||
// based on the suggested name.
|
||||
// Records a name for the given id. If this id already has a name, then
|
||||
// this is a no-op. If the id doesn't have a name, use the given
|
||||
// suggested_name if it hasn't already been taken, and otherwise generate
|
||||
// a new (unused) name based on the suggested name.
|
||||
void SaveName(uint32_t id, const std::string& suggested_name);
|
||||
|
||||
// Records a built-in variable name for target_id. If target_id already
|
||||
// has a name then this is a no-op.
|
||||
void SaveBuiltInName(uint32_t target_id, uint32_t built_in);
|
||||
|
||||
// Collects information from the given parsed instruction to populate
|
||||
// name_for_id_. Returns SPV_SUCCESS;
|
||||
spv_result_t ParseInstruction(const spv_parsed_instruction_t& inst);
|
||||
|
@ -205,4 +205,76 @@ INSTANTIATE_TEST_CASE_P(ExoticTypes, FriendlyNameTest,
|
||||
{"%1 = OpTypeNamedBarrier", 1, "NamedBarrier"},
|
||||
}), );
|
||||
|
||||
// Makes a test case for a BuiltIn variable declaration.
|
||||
NameIdCase BuiltInCase(std::string assembly_name, std::string expected) {
|
||||
return NameIdCase{std::string("OpDecorate %1 BuiltIn ") + assembly_name +
|
||||
" %1 = OpVariable %2 Input",
|
||||
1, expected};
|
||||
}
|
||||
|
||||
// Makes a test case for a BuiltIn variable declaration. In this overload,
|
||||
// the expected result is the same as the assembly name.
|
||||
NameIdCase BuiltInCase(std::string assembly_name) {
|
||||
return BuiltInCase(assembly_name, assembly_name);
|
||||
}
|
||||
|
||||
// Makes a test case for a BuiltIn variable declaration. In this overload,
|
||||
// the expected result is the same as the assembly name, but with a "gl_"
|
||||
// prefix.
|
||||
NameIdCase BuiltInGLCase(std::string assembly_name) {
|
||||
return BuiltInCase(assembly_name, std::string("gl_") + assembly_name);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
BuiltIns, FriendlyNameTest,
|
||||
::testing::ValuesIn(std::vector<NameIdCase>{
|
||||
BuiltInGLCase("Position"),
|
||||
BuiltInGLCase("PointSize"),
|
||||
BuiltInGLCase("ClipDistance"),
|
||||
BuiltInGLCase("CullDistance"),
|
||||
BuiltInCase("VertexId", "gl_VertexID"),
|
||||
BuiltInCase("InstanceId", "gl_InstanceID"),
|
||||
BuiltInCase("PrimitiveId", "gl_PrimitiveID"),
|
||||
BuiltInCase("InvocationId", "gl_InvocationID"),
|
||||
BuiltInGLCase("Layer"),
|
||||
BuiltInGLCase("ViewportIndex"),
|
||||
BuiltInGLCase("TessLevelOuter"),
|
||||
BuiltInGLCase("TessLevelInner"),
|
||||
BuiltInGLCase("TessCoord"),
|
||||
BuiltInGLCase("PatchVertices"),
|
||||
BuiltInGLCase("FragCoord"),
|
||||
BuiltInGLCase("PointCoord"),
|
||||
BuiltInGLCase("FrontFacing"),
|
||||
BuiltInCase("SampleId", "gl_SampleID"),
|
||||
BuiltInGLCase("SamplePosition"),
|
||||
BuiltInGLCase("SampleMask"),
|
||||
BuiltInGLCase("FragDepth"),
|
||||
BuiltInGLCase("HelperInvocation"),
|
||||
BuiltInCase("NumWorkgroups", "gl_NumWorkGroups"),
|
||||
BuiltInCase("WorkgroupSize", "gl_WorkGroupSize"),
|
||||
BuiltInCase("WorkgroupId", "gl_WorkGroupID"),
|
||||
BuiltInCase("LocalInvocationId", "gl_LocalInvocationID"),
|
||||
BuiltInCase("GlobalInvocationId", "gl_GlobalInvocationID"),
|
||||
BuiltInGLCase("LocalInvocationIndex"),
|
||||
BuiltInCase("WorkDim"),
|
||||
BuiltInCase("GlobalSize"),
|
||||
BuiltInCase("EnqueuedWorkgroupSize"),
|
||||
BuiltInCase("GlobalOffset"),
|
||||
BuiltInCase("GlobalLinearId"),
|
||||
BuiltInCase("SubgroupSize"),
|
||||
BuiltInCase("SubgroupMaxSize"),
|
||||
BuiltInCase("NumSubgroups"),
|
||||
BuiltInCase("NumEnqueuedSubgroups"),
|
||||
BuiltInCase("SubgroupId"),
|
||||
BuiltInCase("SubgroupLocalInvocationId"),
|
||||
BuiltInGLCase("VertexIndex"),
|
||||
BuiltInGLCase("InstanceIndex"),
|
||||
}), );
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(DebugNameOverridesBuiltin, FriendlyNameTest,
|
||||
::testing::ValuesIn(std::vector<NameIdCase>{
|
||||
{"OpName %1 \"foo\" OpDecorate %1 BuiltIn WorkDim "
|
||||
"%1 = OpVariable %2 Input",
|
||||
1, "foo"}}), );
|
||||
|
||||
} // anonymous namespace
|
||||
|
Loading…
Reference in New Issue
Block a user