Generator word now has two 16-bit components
The high 16-bits are a registered generator tool. These are registered at https://www.khronos.org/registry/spir-v/api/spir-v.xml The low 16-bits are tool-specific. It might be a version number, for example, but is not constrained by the spec or by the registration process. The disassembler prints the tool name when we know it. If we don't, print "Unknown" and then the numeric tool number in parentheses. In all cases, the disassembler prints lower 16-bit number on the same line but after the tool name. Also add newly registered generators: 6: Khronos LLVM/SPIR-V Translator 7: Khronos SPIR-V Tools Assembler
This commit is contained in:
Родитель
5f7ed91e18
Коммит
14b93e49ed
|
@ -39,6 +39,7 @@
|
|||
#include "libspirv/libspirv.h"
|
||||
#include "opcode.h"
|
||||
#include "print.h"
|
||||
#include "spirv_constant.h"
|
||||
#include "util/hex_float.h"
|
||||
|
||||
namespace {
|
||||
|
@ -131,9 +132,18 @@ spv_result_t Disassembler::HandleHeader(spv_endianness_t endian,
|
|||
endian_ = endian;
|
||||
|
||||
SetGrey();
|
||||
const char* generator_tool =
|
||||
spvGeneratorStr(SPV_GENERATOR_TOOL_PART(generator));
|
||||
stream_ << "; SPIR-V\n"
|
||||
<< "; Version: " << version << "\n"
|
||||
<< "; Generator: " << spvGeneratorStr(generator) << "\n"
|
||||
<< "; Generator: " << generator_tool;
|
||||
// For unknown tools, print the numeric tool value.
|
||||
if (0 == strcmp("Unknown", generator_tool)) {
|
||||
stream_ << "(" << SPV_GENERATOR_TOOL_PART(generator) << ")";
|
||||
}
|
||||
// Print the miscellaneous part of the generator word on the same
|
||||
// line as the tool name.
|
||||
stream_ << "; " << SPV_GENERATOR_MISC_PART(generator) << "\n"
|
||||
<< "; Bound: " << id_bound << "\n"
|
||||
<< "; Schema: " << schema << "\n";
|
||||
ResetColor();
|
||||
|
|
|
@ -298,6 +298,10 @@ const char* spvGeneratorStr(uint32_t generator) {
|
|||
return "NVIDIA";
|
||||
case SPV_GENERATOR_ARM:
|
||||
return "ARM";
|
||||
case SPV_GENERATOR_KHRONOS_LLVM_TRANSLATOR:
|
||||
return "Khronos LLVM/SPIR-V Translator";
|
||||
case SPV_GENERATOR_KHRONOS_ASSEMBLER:
|
||||
return "Khronos SPIR-V Tools Assembler";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
|
|
|
@ -69,16 +69,31 @@
|
|||
|
||||
// Enumerations
|
||||
|
||||
// Values mapping to registered vendors. See the registry at
|
||||
// Values mapping to registered tools. See the registry at
|
||||
// https://www.khronos.org/registry/spir-v/api/spir-v.xml
|
||||
// These values occupy the higher order 16 bits of the generator magic word.
|
||||
typedef enum spv_generator_t {
|
||||
// TODO(dneto) Values 0 through 5 were registered only as vendor.
|
||||
SPV_GENERATOR_KHRONOS = 0,
|
||||
SPV_GENERATOR_LUNARG = 1,
|
||||
SPV_GENERATOR_VALVE = 2,
|
||||
SPV_GENERATOR_CODEPLAY = 3,
|
||||
SPV_GENERATOR_NVIDIA = 4,
|
||||
SPV_GENERATOR_ARM = 5,
|
||||
SPV_FORCE_32_BIT_ENUM(spv_generator_t)
|
||||
// These are vendor and tool.
|
||||
SPV_GENERATOR_KHRONOS_LLVM_TRANSLATOR = 6,
|
||||
SPV_GENERATOR_KHRONOS_ASSEMBLER = 7,
|
||||
SPV_GENERATOR_NUM_ENTRIES,
|
||||
SPV_FORCE_16_BIT_ENUM(spv_generator_t)
|
||||
} spv_generator_t;
|
||||
|
||||
// Evaluates to a well-formed generator magic word from a tool value and
|
||||
// miscellaneous 16-bit value.
|
||||
#define SPV_GENERATOR_WORD(TOOL, MISC) \
|
||||
((uint32_t(uint16_t(TOOL)) << 16) | uint16_t(MISC))
|
||||
// Returns the tool component of the generator word.
|
||||
#define SPV_GENERATOR_TOOL_PART(WORD) (uint32_t(WORD) >> 16)
|
||||
// Returns the misc part of the generator word.
|
||||
#define SPV_GENERATOR_MISC_PART(WORD) (uint32_t(WORD) & 0xFFFF)
|
||||
|
||||
#endif // LIBSPIRV_SPIRV_CONSTANT_H_
|
||||
|
|
|
@ -652,18 +652,24 @@ spv_result_t spvTextEncodeOpcode(const libspirv::AssemblyGrammar& grammar,
|
|||
|
||||
namespace {
|
||||
|
||||
enum {
|
||||
kAssemblerVersion = 0
|
||||
};
|
||||
|
||||
/// @brief Populate a binary stream's words with this generator's header.
|
||||
///
|
||||
/// @param[in,out] words the array of words
|
||||
/// @param[in] bound the upper ID bound
|
||||
///
|
||||
/// @return result code
|
||||
spv_result_t SetHeader(uint32_t* words, const uint32_t bound) {
|
||||
spv_result_t
|
||||
SetHeader(uint32_t* words, const uint32_t bound) {
|
||||
if (!words) return SPV_ERROR_INVALID_BINARY;
|
||||
|
||||
words[SPV_INDEX_MAGIC_NUMBER] = SpvMagicNumber;
|
||||
words[SPV_INDEX_VERSION_NUMBER] = SpvVersion;
|
||||
words[SPV_INDEX_GENERATOR_NUMBER] = SPV_GENERATOR_KHRONOS;
|
||||
words[SPV_INDEX_GENERATOR_NUMBER] =
|
||||
SPV_GENERATOR_WORD(SPV_GENERATOR_KHRONOS_ASSEMBLER, kAssemblerVersion);
|
||||
words[SPV_INDEX_BOUND] = bound;
|
||||
words[SPV_INDEX_SCHEMA] = 0; // NOTE: Reserved
|
||||
|
||||
|
|
|
@ -30,10 +30,11 @@
|
|||
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
#include "TestFixture.h"
|
||||
#include "../source/spirv_constant.h"
|
||||
#include "TestFixture.h"
|
||||
|
||||
using ::testing::Eq;
|
||||
using ::testing::HasSubstr;
|
||||
using spvtest::AutoText;
|
||||
using spvtest::TextToBinaryTest;
|
||||
|
||||
|
@ -394,4 +395,51 @@ OpStore %2 %3 Aligned|Volatile 4 ; bogus, but not indented
|
|||
expected);
|
||||
}
|
||||
|
||||
// Test generator string.
|
||||
|
||||
// A test case for the generator string. This allows us to
|
||||
// test both of the 16-bit components of the generator word.
|
||||
struct GeneratorStringCase {
|
||||
uint16_t generator;
|
||||
uint16_t misc;
|
||||
std::string expected;
|
||||
};
|
||||
|
||||
using GeneratorStringTest = spvtest::TextToBinaryTestBase<
|
||||
::testing::TestWithParam<GeneratorStringCase>>;
|
||||
|
||||
TEST_P(GeneratorStringTest, Sample) {
|
||||
auto words = CompileSuccessfully("");
|
||||
EXPECT_EQ(SPV_INDEX_GENERATOR_NUMBER, 2);
|
||||
words[SPV_INDEX_GENERATOR_NUMBER] =
|
||||
SPV_GENERATOR_WORD(GetParam().generator, GetParam().misc);
|
||||
|
||||
spv_text decoded_text = nullptr;
|
||||
spv_diagnostic diagnostic = nullptr;
|
||||
EXPECT_THAT(spvBinaryToText(context, words.data(), words.size(),
|
||||
SPV_BINARY_TO_TEXT_OPTION_NONE, &decoded_text,
|
||||
&diagnostic),
|
||||
Eq(SPV_SUCCESS));
|
||||
EXPECT_THAT(diagnostic, Eq(nullptr));
|
||||
EXPECT_THAT(std::string(decoded_text->str), HasSubstr(GetParam().expected));
|
||||
spvTextDestroy(decoded_text);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(GeneratorStrings, GeneratorStringTest,
|
||||
::testing::ValuesIn(std::vector<GeneratorStringCase>{
|
||||
{SPV_GENERATOR_KHRONOS, 12, "Khronos; 12"},
|
||||
{SPV_GENERATOR_LUNARG, 99, "LunarG; 99"},
|
||||
{SPV_GENERATOR_VALVE, 1, "Valve; 1"},
|
||||
{SPV_GENERATOR_CODEPLAY, 65535,
|
||||
"Codeplay Software Ltd.; 65535"},
|
||||
{SPV_GENERATOR_NVIDIA, 19, "NVIDIA; 19"},
|
||||
{SPV_GENERATOR_ARM, 1000, "ARM; 1000"},
|
||||
{SPV_GENERATOR_KHRONOS_LLVM_TRANSLATOR, 38,
|
||||
"Khronos LLVM/SPIR-V Translator; 38"},
|
||||
{SPV_GENERATOR_KHRONOS_ASSEMBLER, 2,
|
||||
"Khronos SPIR-V Tools Assembler; 2"},
|
||||
{9, 18, "Unknown(9); 18"},
|
||||
{65535, 32767, "Unknown(65535); 32767"},
|
||||
}));
|
||||
|
||||
} // anonymous namespace
|
||||
|
|
|
@ -67,7 +67,7 @@ OpFunctionEnd
|
|||
const std::string spirv_header =
|
||||
R"(; SPIR-V
|
||||
; Version: 100
|
||||
; Generator: Khronos
|
||||
; Generator: Khronos SPIR-V Tools Assembler; 0
|
||||
; Bound: 9
|
||||
; Schema: 0)";
|
||||
spv_binary binary;
|
||||
|
|
|
@ -52,13 +52,16 @@ INSTANTIATE_TEST_CASE_P(
|
|||
{SPV_GENERATOR_CODEPLAY, "Codeplay Software Ltd."},
|
||||
{SPV_GENERATOR_NVIDIA, "NVIDIA"},
|
||||
{SPV_GENERATOR_ARM, "ARM"},
|
||||
{SPV_GENERATOR_KHRONOS_LLVM_TRANSLATOR,
|
||||
"Khronos LLVM/SPIR-V Translator"},
|
||||
{SPV_GENERATOR_KHRONOS_ASSEMBLER, "Khronos SPIR-V Tools Assembler"},
|
||||
}));
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(
|
||||
Unregistered, GeneratorMagicNumberTest,
|
||||
::testing::ValuesIn(std::vector<EnumCase<spv_generator_t>>{
|
||||
// Currently value 6 and beyond are unregiestered.
|
||||
{spv_generator_t(6), "Unknown"},
|
||||
{spv_generator_t(8), "Unknown"},
|
||||
{spv_generator_t(9999), "Unknown"},
|
||||
}));
|
||||
} // anonymous namespace
|
||||
|
|
Загрузка…
Ссылка в новой задаче