From 5a0b5ca4a71d8ee91d4548fc0f0295349cfa7607 Mon Sep 17 00:00:00 2001 From: David Neto Date: Fri, 9 Dec 2016 14:01:43 -0500 Subject: [PATCH] Get vendor tool info from the SPIR-V registry file Update old tests to use officially registered vendor names; this affected "Codeplay". --- source/CMakeLists.txt | 13 +++++ source/opcode.cpp | 42 ++++++++-------- test/binary_to_text_test.cpp | 4 +- test/generator_magic_number_test.cpp | 7 +-- utils/generate_registry_tables.py | 72 ++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 27 deletions(-) create mode 100755 utils/generate_registry_tables.py diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 78202d3a..3a6b9a24 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -13,6 +13,7 @@ # limitations under the License. set(GRAMMAR_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_grammar_tables.py") +set(XML_REGISTRY_PROCESSING_SCRIPT "${spirv-tools_SOURCE_DIR}/utils/generate_registry_tables.py") # macro() definitions are used in the following because we need to append .inc # file paths into some global lists (*_CPP_DEPENDS). And those global lists are @@ -66,6 +67,18 @@ spvtools_core_tables("1.1") spvtools_opencl_tables("1.0") spvtools_glsl_tables("1.0") + +# Extract the list of known generators from the SPIR-V XML registry file. +set(GENERATOR_INC_FILE ${spirv-tools_BINARY_DIR}/generators.inc) +set(SPIRV_XML_REGISTRY_FILE ${SPIRV_HEADER_INCLUDE_DIR}/spirv/spir-v.xml) +add_custom_command(OUTPUT ${GENERATOR_INC_FILE} + COMMAND ${PYTHON_EXECUTABLE} ${XML_REGISTRY_PROCESSING_SCRIPT} + --xml=${SPIRV_XML_REGISTRY_FILE} + --generator-output=${GENERATOR_INC_FILE} + DEPENDS ${XML_REGISTRY_PROCESSING_SCRIPT} ${SPIRV_XML_REGISTRY_FILE} + COMMENT "Generate tables based on the SPIR-V XML registry.") +list(APPEND OPCODE_CPP_DEPENDS ${GENERATOR_INC_FILE}) + # The following .cpp files include the above generated .inc files. # Add those .inc files as their dependencies. # diff --git a/source/opcode.cpp b/source/opcode.cpp index 48c47cc2..ac87c707 100644 --- a/source/opcode.cpp +++ b/source/opcode.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "instruction.h" @@ -36,31 +37,28 @@ const spv_opcode_desc_t opcodeTableEntries_1_1[] = { #include "core.insts-1.1.inc" }; +// Represents a vendor tool entry in the SPIR-V XML Regsitry. +struct VendorTool { + uint32_t value; + const char* vendor; + const char* tool; // Might be empty string. + const char* vendor_tool; // Combiantion of vendor and tool. +}; + +const VendorTool vendor_tools[] = { +#include "generators.inc" +}; + } // anonymous namespace +// TODO(dneto): Move this to another file. It doesn't belong with opcode +// processing. const char* spvGeneratorStr(uint32_t generator) { - switch (generator) { - case SPV_GENERATOR_KHRONOS: - return "Khronos"; - case SPV_GENERATOR_LUNARG: - return "LunarG"; - case SPV_GENERATOR_VALVE: - return "Valve"; - case SPV_GENERATOR_CODEPLAY: - return "Codeplay Software Ltd."; - case SPV_GENERATOR_NVIDIA: - 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"; - case SPV_GENERATOR_KHRONOS_GLSLANG: - return "Khronos Glslang Reference Front End"; - default: - return "Unknown"; - } + auto where = std::find_if( + std::begin(vendor_tools), std::end(vendor_tools), + [generator](const VendorTool& vt) { return generator == vt.value; }); + if (where != std::end(vendor_tools)) return where->vendor_tool; + return "Unknown"; } uint32_t spvOpcodeMake(uint16_t wordCount, SpvOp opcode) { diff --git a/test/binary_to_text_test.cpp b/test/binary_to_text_test.cpp index 09d1abd3..ed1bee56 100644 --- a/test/binary_to_text_test.cpp +++ b/test/binary_to_text_test.cpp @@ -510,7 +510,7 @@ INSTANTIATE_TEST_CASE_P(GeneratorStrings, GeneratorStringTest, {SPV_GENERATOR_LUNARG, 99, "LunarG; 99"}, {SPV_GENERATOR_VALVE, 1, "Valve; 1"}, {SPV_GENERATOR_CODEPLAY, 65535, - "Codeplay Software Ltd.; 65535"}, + "Codeplay; 65535"}, {SPV_GENERATOR_NVIDIA, 19, "NVIDIA; 19"}, {SPV_GENERATOR_ARM, 1000, "ARM; 1000"}, {SPV_GENERATOR_KHRONOS_LLVM_TRANSLATOR, 38, @@ -519,7 +519,7 @@ INSTANTIATE_TEST_CASE_P(GeneratorStrings, GeneratorStringTest, "Khronos SPIR-V Tools Assembler; 2"}, {SPV_GENERATOR_KHRONOS_GLSLANG, 1, "Khronos Glslang Reference Front End; 1"}, - {9, 18, "Unknown(9); 18"}, + {1000, 18, "Unknown(1000); 18"}, {65535, 32767, "Unknown(65535); 32767"}, }), ); diff --git a/test/generator_magic_number_test.cpp b/test/generator_magic_number_test.cpp index c3f30f63..c78c7b0e 100644 --- a/test/generator_magic_number_test.cpp +++ b/test/generator_magic_number_test.cpp @@ -37,7 +37,7 @@ INSTANTIATE_TEST_CASE_P( {SPV_GENERATOR_KHRONOS, "Khronos"}, {SPV_GENERATOR_LUNARG, "LunarG"}, {SPV_GENERATOR_VALVE, "Valve"}, - {SPV_GENERATOR_CODEPLAY, "Codeplay Software Ltd."}, + {SPV_GENERATOR_CODEPLAY, "Codeplay"}, {SPV_GENERATOR_NVIDIA, "NVIDIA"}, {SPV_GENERATOR_ARM, "ARM"}, {SPV_GENERATOR_KHRONOS_LLVM_TRANSLATOR, @@ -49,8 +49,9 @@ INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P( Unregistered, GeneratorMagicNumberTest, ::testing::ValuesIn(std::vector>{ - // Currently value 6 and beyond are unregiestered. - {spv_generator_t(9), "Unknown"}, + // We read registered entries from the SPIR-V XML Registry file + // which can change over time. + {spv_generator_t(1000), "Unknown"}, {spv_generator_t(9999), "Unknown"}, }),); } // anonymous namespace diff --git a/utils/generate_registry_tables.py b/utils/generate_registry_tables.py new file mode 100755 index 00000000..8b1c3572 --- /dev/null +++ b/utils/generate_registry_tables.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python +# Copyright (c) 2016 Google Inc. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Generates the vendor tool table from the SPIR-V XML registry.""" + +from __future__ import print_function + +import distutils.dir_util +import os.path +import xml.etree.ElementTree + + +def generate_vendor_table(registry): + """Returns a list of C style initializers for the registered vendors + and their tools. + + Args: + registry: The SPIR-V XMLregistry as an xml.ElementTree + """ + + lines = [] + for ids in registry.iter('ids'): + if 'vendor' == ids.attrib['type']: + for an_id in ids.iter('id'): + value = an_id.attrib['value'] + vendor = an_id.attrib['vendor'] + if 'tool' in an_id.attrib: + tool = an_id.attrib['tool'] + vendor_tool = vendor + ' ' + tool + else: + tool = '' + vendor_tool = vendor + line = '{' + '{}, "{}", "{}", "{}"'.format(value, + vendor, + tool, + vendor_tool) + '},' + lines.append(line) + return '\n'.join(lines) + + +def main(): + import argparse + parser = argparse.ArgumentParser(description= + 'Generate tables from SPIR-V XML registry') + parser.add_argument('--xml', metavar='', + type=str, required=True, + help='SPIR-V XML Registry file') + parser.add_argument('--generator-output', metavar='', + type=str, required=True, + help='output file for SPIR-V generators table') + args = parser.parse_args() + + with open(args.xml) as xml_in: + registry = xml.etree.ElementTree.fromstring(xml_in.read()) + + distutils.dir_util.mkpath(os.path.dirname(args.generator_output)) + print(generate_vendor_table(registry), file=open(args.generator_output, 'w')) + + +if __name__ == '__main__': + main()