Autogenererating enum-string mappings from grammar

Autogenerating the following code:
- extension enum
- extension-to-string
- string-to-extension
- capability-to-string

Capability mapping table will not compile if incomplete.
TODO: Use "spirv-latest-version.h" instead of 1.1.

Added function to generate capability tables for tests.
This commit is contained in:
Andrey Tuganov 2017-03-15 17:28:24 -04:00 коммит произвёл David Neto
Родитель b011633171
Коммит c804c125c5
13 изменённых файлов: 480 добавлений и 91 удалений

Просмотреть файл

@ -35,6 +35,22 @@ macro(spvtools_core_tables VERSION)
list(APPEND OPERAND_CPP_DEPENDS ${GRAMMAR_KINDS_INC_FILE})
endmacro(spvtools_core_tables)
macro(spvtools_enum_string_mapping VERSION)
set(GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${VERSION}/spirv.core.grammar.json")
set(GRAMMAR_EXTENSION_ENUM_INC_FILE "${spirv-tools_BINARY_DIR}/extension_enum.inc")
set(GRAMMAR_ENUM_STRING_MAPPING_INC_FILE "${spirv-tools_BINARY_DIR}/enum_string_mapping.inc")
add_custom_command(OUTPUT ${GRAMMAR_EXTENSION_ENUM_INC_FILE}
${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE}
COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
--spirv-core-grammar=${GRAMMAR_JSON_FILE}
--extension-enum-output=${GRAMMAR_EXTENSION_ENUM_INC_FILE}
--enum-string-mapping-output=${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE}
DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${GRAMMAR_JSON_FILE}
COMMENT "Generate enum-string mapping for SPIR-V v${VERSION}.")
list(APPEND EXTENSION_H_DEPENDS ${GRAMMAR_EXTENSION_ENUM_INC_FILE})
list(APPEND ENUM_STRING_MAPPING_CPP_DEPENDS ${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE})
endmacro(spvtools_enum_string_mapping)
macro(spvtools_vimsyntax VERSION CLVERSION)
set(GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${VERSION}/spirv.core.grammar.json")
set(GLSL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${VERSION}/extinst.glsl.std.450.grammar.json")
@ -81,6 +97,7 @@ endmacro(spvtools_opencl_tables)
spvtools_core_tables("1.0")
spvtools_core_tables("1.1")
spvtools_enum_string_mapping("1.1")
spvtools_opencl_tables("1.0")
spvtools_glsl_tables("1.0")
@ -122,6 +139,16 @@ set_source_files_properties(
set_source_files_properties(
${CMAKE_CURRENT_SOURCE_DIR}/ext_inst.cpp
PROPERTIES OBJECT_DEPENDS "${EXTINST_CPP_DEPENDS}")
set_source_files_properties(
${CMAKE_CURRENT_SOURCE_DIR}/enum_string_mapping.cpp
PROPERTIES OBJECT_DEPENDS "${ENUM_STRING_MAPPING_CPP_DEPENDS}")
set_source_files_properties(
${CMAKE_CURRENT_SOURCE_DIR}/extension.h
PROPERTIES HEADER_FILE_ONLY TRUE)
set_source_files_properties(
${CMAKE_CURRENT_SOURCE_DIR}/extension.h
PROPERTIES OBJECT_DEPENDS "${EXTENSION_H_DEPENDS}")
set(SPIRV_TOOLS_BUILD_VERSION_INC
${spirv-tools_BINARY_DIR}/build-version.inc)
@ -154,6 +181,7 @@ set(SPIRV_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/binary.h
${CMAKE_CURRENT_SOURCE_DIR}/diagnostic.h
${CMAKE_CURRENT_SOURCE_DIR}/enum_set.h
${CMAKE_CURRENT_SOURCE_DIR}/enum_string_mapping.h
${CMAKE_CURRENT_SOURCE_DIR}/ext_inst.h
${CMAKE_CURRENT_SOURCE_DIR}/extensions.h
${CMAKE_CURRENT_SOURCE_DIR}/instruction.h
@ -179,6 +207,7 @@ set(SPIRV_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/binary.cpp
${CMAKE_CURRENT_SOURCE_DIR}/diagnostic.cpp
${CMAKE_CURRENT_SOURCE_DIR}/disassemble.cpp
${CMAKE_CURRENT_SOURCE_DIR}/enum_string_mapping.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ext_inst.cpp
${CMAKE_CURRENT_SOURCE_DIR}/extensions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/libspirv.cpp

Просмотреть файл

@ -0,0 +1,27 @@
// Copyright (c) 2017 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.
#include "enum_string_mapping.h"
#include <cassert>
#include <string>
#include <unordered_map>
#include "extensions.h"
namespace libspirv {
#include "enum_string_mapping.inc"
} // namespace libspirv

Просмотреть файл

@ -0,0 +1,37 @@
// Copyright (c) 2017 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.
#ifndef LIBSPIRV_ENUM_STRING_MAPPING_H_
#define LIBSPIRV_ENUM_STRING_MAPPING_H_
#include <string>
#include "spirv/1.1/spirv.h"
namespace libspirv {
enum class Extension;
// Finds Extension enum corresponding to |str|. Returns false if not found.
bool GetExtensionFromString(const std::string& str, Extension* extension);
// Returns text string corresponding to |extension|.
std::string ExtensionToString(Extension extension);
// Returns text string corresponding to |capability|.
std::string CapabilityToString(SpvCapability capability);
} // namespace libspirv
#endif // LIBSPIRV_ENUM_STRING_MAPPING_H_

Просмотреть файл

@ -18,6 +18,8 @@
#include <sstream>
#include <string>
#include "enum_string_mapping.h"
namespace libspirv {
std::string GetExtensionString(const spv_parsed_instruction_t* inst) {
@ -33,65 +35,6 @@ std::string GetExtensionString(const spv_parsed_instruction_t* inst) {
return reinterpret_cast<const char*>(inst->words + operand.offset);
}
bool ParseSpvExtensionFromString(const std::string& str, Extension* extension) {
if (str == "SPV_KHR_shader_ballot") {
*extension = Extension::kSPV_KHR_shader_ballot;
} else if (str == "SPV_KHR_shader_draw_parameters") {
*extension = Extension::kSPV_KHR_shader_draw_parameters;
} else if (str == "SPV_KHR_subgroup_vote") {
*extension = Extension::kSPV_KHR_subgroup_vote;
} else if (str == "SPV_KHR_16bit_storage") {
*extension = Extension::kSPV_KHR_16bit_storage;
} else if (str == "SPV_KHR_device_group") {
*extension = Extension::kSPV_KHR_device_group;
} else if (str == "SPV_KHR_multiview") {
*extension = Extension::kSPV_KHR_multiview;
} else if (str == "SPV_NV_sample_mask_override_coverage") {
*extension = Extension::kSPV_NV_sample_mask_override_coverage;
} else if (str == "SPV_NV_geometry_shader_passthrough") {
*extension = Extension::kSPV_NV_geometry_shader_passthrough;
} else if (str == "SPV_NV_viewport_array2") {
*extension = Extension::kSPV_NV_viewport_array2;
} else if (str == "SPV_NV_stereo_view_rendering") {
*extension = Extension::kSPV_NV_stereo_view_rendering;
} else if (str == "SPV_NVX_multiview_per_view_attributes") {
*extension = Extension::kSPV_NVX_multiview_per_view_attributes;
} else {
return false;
}
return true;
}
std::string ExtensionToString(Extension extension) {
switch (extension) {
case Extension::kSPV_KHR_shader_ballot:
return "SPV_KHR_shader_ballot";
case Extension::kSPV_KHR_shader_draw_parameters:
return "SPV_KHR_shader_draw_parameters";
case Extension::kSPV_KHR_subgroup_vote:
return "SPV_KHR_subgroup_vote";
case Extension::kSPV_KHR_16bit_storage:
return "SPV_KHR_16bit_storage";
case Extension::kSPV_KHR_device_group:
return "SPV_KHR_device_group";
case Extension::kSPV_KHR_multiview:
return "SPV_KHR_multiview";
case Extension::kSPV_NV_sample_mask_override_coverage:
return "SPV_NV_sample_mask_override_coverage";
case Extension::kSPV_NV_geometry_shader_passthrough:
return "SPV_NV_geometry_shader_passthrough";
case Extension::kSPV_NV_viewport_array2:
return "SPV_NV_viewport_array2";
case Extension::kSPV_NV_stereo_view_rendering:
return "SPV_NV_stereo_view_rendering";
case Extension::kSPV_NVX_multiview_per_view_attributes:
return "SPV_NVX_multiview_per_view_attributes";
}
return "ERROR_unknown_extension";
}
std::string ExtensionSetToString(const ExtensionSet& extensions) {
std::stringstream ss;
extensions.ForEach([&ss](Extension ext) {

Просмотреть файл

@ -23,21 +23,8 @@
namespace libspirv {
// The known SPIR-V extensions.
// TODO(dneto): Consider auto-generating this list?
// When updating this list, consider also updating ParseSpvExtensionFromString
// and SpvExtensionToString.
enum class Extension {
kSPV_KHR_shader_ballot,
kSPV_KHR_shader_draw_parameters,
kSPV_KHR_subgroup_vote,
kSPV_KHR_16bit_storage,
kSPV_KHR_device_group,
kSPV_KHR_multiview,
kSPV_NV_sample_mask_override_coverage,
kSPV_NV_geometry_shader_passthrough,
kSPV_NV_viewport_array2,
kSPV_NV_stereo_view_rendering,
kSPV_NVX_multiview_per_view_attributes,
#include "extension_enum.inc"
};
using ExtensionSet = EnumSet<Extension>;
@ -45,12 +32,6 @@ using ExtensionSet = EnumSet<Extension>;
// Returns literal string operand of OpExtension instruction.
std::string GetExtensionString(const spv_parsed_instruction_t* inst);
// Finds Extension enum corresponding to |str|. Returns false if not found.
bool ParseSpvExtensionFromString(const std::string& str, Extension* extension);
// Returns text string corresponding to |extension|.
std::string ExtensionToString(Extension extension);
// Returns text string listing |extensions| separated by whitespace.
std::string ExtensionSetToString(const ExtensionSet& extensions);

Просмотреть файл

@ -57,6 +57,7 @@ spvtools_default_compile_options(SPIRV-Tools-opt)
target_include_directories(SPIRV-Tools-opt
PUBLIC ${spirv-tools_SOURCE_DIR}/include
PUBLIC ${SPIRV_HEADER_INCLUDE_DIR}
PRIVATE ${spirv-tools_BINARY_DIR}
)
# We need the assembling and disassembling functionalities in the main library.
target_link_libraries(SPIRV-Tools-opt

Просмотреть файл

@ -26,6 +26,7 @@
#include "binary.h"
#include "diagnostic.h"
#include "enum_string_mapping.h"
#include "extensions.h"
#include "instruction.h"
#include "opcode.h"
@ -124,7 +125,7 @@ void RegisterExtension(ValidationState_t& _,
const spv_parsed_instruction_t* inst) {
const std::string extension_str = libspirv::GetExtensionString(inst);
Extension extension;
if (!ParseSpvExtensionFromString(extension_str, &extension)) {
if (!GetExtensionFromString(extension_str, &extension)) {
// The error will be logged in the ProcessInstruction pass.
return;
}

Просмотреть файл

@ -25,6 +25,7 @@
#include "binary.h"
#include "diagnostic.h"
#include "enum_set.h"
#include "enum_string_mapping.h"
#include "extensions.h"
#include "opcode.h"
#include "operand.h"
@ -383,7 +384,7 @@ void CheckIfKnownExtension(ValidationState_t& _,
const spv_parsed_instruction_t* inst) {
const std::string extension_str = GetExtensionString(inst);
Extension extension;
if (!ParseSpvExtensionFromString(extension_str, &extension)) {
if (!GetExtensionFromString(extension_str, &extension)) {
_.diag(SPV_SUCCESS) << "Found unrecognized extension " << extension_str;
return;
}

Просмотреть файл

@ -52,6 +52,7 @@ function(add_spvtools_unittest)
${spirv-tools_SOURCE_DIR}
${spirv-tools_SOURCE_DIR}/include
${spirv-tools_SOURCE_DIR}/test
${spirv-tools_BINARY_DIR}
${gtest_SOURCE_DIR}/include
${gmock_SOURCE_DIR}/include
)
@ -75,6 +76,7 @@ set(TEST_SOURCES
binary_to_text_test.cpp
binary_to_text.literal_test.cpp
comment_test.cpp
enum_string_mapping_test.cpp
enum_set_test.cpp
ext_inst.glsl_test.cpp
ext_inst.opencl_test.cpp

Просмотреть файл

@ -0,0 +1,249 @@
// Copyright (c) 2017 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.
// Tests for OpExtension validator rules.
#include <string>
#include "enum_string_mapping.h"
#include "extensions.h"
#include "gtest/gtest.h"
namespace {
using ::libspirv::Extension;
using ::testing::Values;
using ::testing::ValuesIn;
using ExtensionTest = ::testing::TestWithParam<std::pair<Extension, std::string>>;
using UnknownExtensionTest = ::testing::TestWithParam<std::string>;
using CapabilityTest = ::testing::TestWithParam<std::pair<SpvCapability, std::string>>;
TEST_P(ExtensionTest, TestExtensionFromString) {
const std::pair<Extension, std::string>& param = GetParam();
const Extension extension = param.first;
const std::string extension_str = param.second;
Extension result_extension;
ASSERT_TRUE(libspirv::GetExtensionFromString(extension_str, &result_extension));
EXPECT_EQ(extension, result_extension);
}
TEST_P(ExtensionTest, TestExtensionToString) {
const std::pair<Extension, std::string>& param = GetParam();
const Extension extension = param.first;
const std::string extension_str = param.second;
const std::string result_str = libspirv::ExtensionToString(extension);
EXPECT_EQ(extension_str, result_str);
}
TEST_P(UnknownExtensionTest, TestExtensionFromStringFails) {
Extension result_extension;
ASSERT_FALSE(libspirv::GetExtensionFromString(GetParam(), &result_extension));
}
TEST_P(CapabilityTest, TestCapabilityToString) {
const std::pair<SpvCapability, std::string>& param = GetParam();
const SpvCapability capability = param.first;
const std::string capability_str = param.second;
const std::string result_str = libspirv::CapabilityToString(capability);
EXPECT_EQ(capability_str, result_str);
}
INSTANTIATE_TEST_CASE_P(AllExtensions, ExtensionTest,
ValuesIn(std::vector<std::pair<Extension, std::string>>({
{Extension::kSPV_KHR_16bit_storage,
"SPV_KHR_16bit_storage"},
{Extension::kSPV_KHR_device_group,
"SPV_KHR_device_group"},
{Extension::kSPV_KHR_multiview,
"SPV_KHR_multiview"},
{Extension::kSPV_KHR_shader_ballot,
"SPV_KHR_shader_ballot"},
{Extension::kSPV_KHR_shader_draw_parameters,
"SPV_KHR_shader_draw_parameters"},
{Extension::kSPV_KHR_subgroup_vote,
"SPV_KHR_subgroup_vote"},
{Extension::kSPV_NVX_multiview_per_view_attributes,
"SPV_NVX_multiview_per_view_attributes"},
{Extension::kSPV_NV_geometry_shader_passthrough,
"SPV_NV_geometry_shader_passthrough"},
{Extension::kSPV_NV_sample_mask_override_coverage,
"SPV_NV_sample_mask_override_coverage"},
{Extension::kSPV_NV_stereo_view_rendering,
"SPV_NV_stereo_view_rendering"},
{Extension::kSPV_NV_viewport_array2,
"SPV_NV_viewport_array2"}
})));
INSTANTIATE_TEST_CASE_P(UnknownExtensions, UnknownExtensionTest, Values(
"",
"SPV_KHR_",
"SPV_KHR_device_group_ERROR",
"SPV_ERROR_random_string_hfsdklhlktherh"
));
INSTANTIATE_TEST_CASE_P(AllCapabilities, CapabilityTest,
ValuesIn(std::vector<std::pair<SpvCapability, std::string>>({
{SpvCapabilityMatrix,
"Matrix"},
{SpvCapabilityShader,
"Shader"},
{SpvCapabilityGeometry,
"Geometry"},
{SpvCapabilityTessellation,
"Tessellation"},
{SpvCapabilityAddresses,
"Addresses"},
{SpvCapabilityLinkage,
"Linkage"},
{SpvCapabilityKernel,
"Kernel"},
{SpvCapabilityVector16,
"Vector16"},
{SpvCapabilityFloat16Buffer,
"Float16Buffer"},
{SpvCapabilityFloat16,
"Float16"},
{SpvCapabilityFloat64,
"Float64"},
{SpvCapabilityInt64,
"Int64"},
{SpvCapabilityInt64Atomics,
"Int64Atomics"},
{SpvCapabilityImageBasic,
"ImageBasic"},
{SpvCapabilityImageReadWrite,
"ImageReadWrite"},
{SpvCapabilityImageMipmap,
"ImageMipmap"},
{SpvCapabilityPipes,
"Pipes"},
{SpvCapabilityGroups,
"Groups"},
{SpvCapabilityDeviceEnqueue,
"DeviceEnqueue"},
{SpvCapabilityLiteralSampler,
"LiteralSampler"},
{SpvCapabilityAtomicStorage,
"AtomicStorage"},
{SpvCapabilityInt16,
"Int16"},
{SpvCapabilityTessellationPointSize,
"TessellationPointSize"},
{SpvCapabilityGeometryPointSize,
"GeometryPointSize"},
{SpvCapabilityImageGatherExtended,
"ImageGatherExtended"},
{SpvCapabilityStorageImageMultisample,
"StorageImageMultisample"},
{SpvCapabilityUniformBufferArrayDynamicIndexing,
"UniformBufferArrayDynamicIndexing"},
{SpvCapabilitySampledImageArrayDynamicIndexing,
"SampledImageArrayDynamicIndexing"},
{SpvCapabilityStorageBufferArrayDynamicIndexing,
"StorageBufferArrayDynamicIndexing"},
{SpvCapabilityStorageImageArrayDynamicIndexing,
"StorageImageArrayDynamicIndexing"},
{SpvCapabilityClipDistance,
"ClipDistance"},
{SpvCapabilityCullDistance,
"CullDistance"},
{SpvCapabilityImageCubeArray,
"ImageCubeArray"},
{SpvCapabilitySampleRateShading,
"SampleRateShading"},
{SpvCapabilityImageRect,
"ImageRect"},
{SpvCapabilitySampledRect,
"SampledRect"},
{SpvCapabilityGenericPointer,
"GenericPointer"},
{SpvCapabilityInt8,
"Int8"},
{SpvCapabilityInputAttachment,
"InputAttachment"},
{SpvCapabilitySparseResidency,
"SparseResidency"},
{SpvCapabilityMinLod,
"MinLod"},
{SpvCapabilitySampled1D,
"Sampled1D"},
{SpvCapabilityImage1D,
"Image1D"},
{SpvCapabilitySampledCubeArray,
"SampledCubeArray"},
{SpvCapabilitySampledBuffer,
"SampledBuffer"},
{SpvCapabilityImageBuffer,
"ImageBuffer"},
{SpvCapabilityImageMSArray,
"ImageMSArray"},
{SpvCapabilityStorageImageExtendedFormats,
"StorageImageExtendedFormats"},
{SpvCapabilityImageQuery,
"ImageQuery"},
{SpvCapabilityDerivativeControl,
"DerivativeControl"},
{SpvCapabilityInterpolationFunction,
"InterpolationFunction"},
{SpvCapabilityTransformFeedback,
"TransformFeedback"},
{SpvCapabilityGeometryStreams,
"GeometryStreams"},
{SpvCapabilityStorageImageReadWithoutFormat,
"StorageImageReadWithoutFormat"},
{SpvCapabilityStorageImageWriteWithoutFormat,
"StorageImageWriteWithoutFormat"},
{SpvCapabilityMultiViewport,
"MultiViewport"},
{SpvCapabilitySubgroupDispatch,
"SubgroupDispatch"},
{SpvCapabilityNamedBarrier,
"NamedBarrier"},
{SpvCapabilityPipeStorage,
"PipeStorage"},
{SpvCapabilitySubgroupBallotKHR,
"SubgroupBallotKHR"},
{SpvCapabilityDrawParameters,
"DrawParameters"},
{SpvCapabilitySubgroupVoteKHR,
"SubgroupVoteKHR"},
{SpvCapabilityStorageUniformBufferBlock16,
"StorageUniformBufferBlock16"},
{SpvCapabilityStorageUniform16,
"StorageUniform16"},
{SpvCapabilityStoragePushConstant16,
"StoragePushConstant16"},
{SpvCapabilityStorageInputOutput16,
"StorageInputOutput16"},
{SpvCapabilityDeviceGroup,
"DeviceGroup"},
{SpvCapabilityMultiView,
"MultiView"},
{SpvCapabilitySampleMaskOverrideCoverageNV,
"SampleMaskOverrideCoverageNV"},
{SpvCapabilityGeometryShaderPassthroughNV,
"GeometryShaderPassthroughNV"},
{SpvCapabilityShaderViewportIndexLayerNV,
"ShaderViewportIndexLayerNV"},
{SpvCapabilityShaderViewportMaskNV,
"ShaderViewportMaskNV"},
{SpvCapabilityShaderStereoViewNV,
"ShaderStereoViewNV"},
{SpvCapabilityPerViewAttributesNV,
"PerViewAttributesNV"}
})));
} // anonymous namespace

Просмотреть файл

@ -16,6 +16,7 @@
#include <string>
#include "enum_string_mapping.h"
#include "extensions.h"
#include "gmock/gmock.h"
#include "test_fixture.h"
@ -81,14 +82,6 @@ TEST_P(ValidateUnknownExtensions, FailSilently) {
EXPECT_THAT(getDiagnosticString(), HasSubstr(GetErrorString(extension)));
}
TEST_P(ValidateKnownExtensions, ToAndFromString) {
const std::string extension_str = GetParam();
Extension extension;
ASSERT_TRUE(ParseSpvExtensionFromString(extension_str, &extension));
const std::string result_str = ExtensionToString(extension);
EXPECT_EQ(extension_str, result_str);
}
TEST_F(ValidateExtensionCapabilities, DeclCapabilitySuccess) {
const string str =
"OpCapability Shader\nOpCapability Linkage\nOpCapability DeviceGroup\n"

Просмотреть файл

@ -30,7 +30,10 @@ function(add_spvtools_tool)
add_executable(${ARG_TARGET} ${ARG_SRCS})
spvtools_default_compile_options(${ARG_TARGET})
target_link_libraries(${ARG_TARGET} PRIVATE ${ARG_LIBS})
target_include_directories(${ARG_TARGET} PRIVATE ${spirv-tools_SOURCE_DIR})
target_include_directories(${ARG_TARGET} PRIVATE
${spirv-tools_SOURCE_DIR}
${spirv-tools_BINARY_DIR}
)
endfunction()
if (NOT ${SPIRV_SKIP_EXECUTABLES})

Просмотреть файл

@ -348,6 +348,111 @@ def generate_operand_kind_table(enums):
return '\n\n'.join(enum_entries + (table,))
def get_extension_list(operands):
"""Returns extensions as an alphabetically sorted list of strings."""
enumerants = sum([item.get('enumerants', []) for item in operands
if item.get('category') in ['ValueEnum']], [])
extensions = sum([item.get('extensions', []) for item in enumerants
if item.get('extensions')], [])
return sorted(set(extensions))
def get_capability_list(operands):
"""Returns capabilities as a list of strings in the order of appearance."""
enumerants = sum([item.get('enumerants', []) for item in operands
if item.get('kind') in ['Capability']], [])
return [item.get('enumerant') for item in enumerants]
def generate_extension_enum(operands):
"""Returns enumeration containing extensions declared in the grammar."""
extensions = get_extension_list(operands)
return ',\n'.join(['k' + extension for extension in extensions])
def generate_extension_to_string_table(operands):
"""Returns extension to string mapping table."""
extensions = get_extension_list(operands)
entry_template = ' {{Extension::k{extension},\n "{extension}"}}'
table_entries = [entry_template.format(extension=extension)
for extension in extensions]
table_template = '{{\n{enums}\n}}'
return table_template.format(enums=',\n'.join(table_entries))
def generate_string_to_extension_table(operands):
"""Returns string to extension mapping table."""
extensions = get_extension_list(operands)
entry_template = ' {{"{extension}",\n Extension::k{extension}}}'
table_entries = [entry_template.format(extension=extension)
for extension in extensions]
table_template = '{{\n{enums}\n}}'
return table_template.format(enums=',\n'.join(table_entries))
def generate_capability_to_string_table(operands):
"""Returns capability to string mapping table."""
capabilities = get_capability_list(operands)
entry_template = ' {{SpvCapability{capability},\n "{capability}"}}'
table_entries = [entry_template.format(capability=capability)
for capability in capabilities]
table_template = '{{\n{enums}\n}}'
return table_template.format(enums=',\n'.join(table_entries))
def generate_extension_to_string_mapping(operands):
"""Returns mapping function from extensions to corresponding strings."""
extensions = get_extension_list(operands)
function = 'std::string ExtensionToString(Extension extension) {\n'
function += ' switch (extension) {\n'
template = ' case Extension::k{extension}:\n' \
' return "{extension}";\n'
function += ''.join([template.format(extension=extension)
for extension in extensions])
function += ' };\n\n return "";\n}'
return function
def generate_string_to_extension_mapping(operands):
"""Returns mapping function from strings to corresponding extensions."""
function = 'bool GetExtensionFromString(' \
'const std::string& str, Extension* extension) {\n ' \
'static const std::unordered_map<std::string, Extension> mapping =\n'
function += generate_string_to_extension_table(operands)
function += ';\n\n'
function += ' const auto it = mapping.find(str);\n\n' \
' if (it == mapping.end()) return false;\n\n' \
' *extension = it->second;\n return true;\n}'
return function
def generate_capability_to_string_mapping(operands):
"""Returns mapping function from capabilities to corresponding strings."""
capabilities = get_capability_list(operands)
function = 'std::string CapabilityToString(SpvCapability capability) {\n'
function += ' switch (capability) {\n'
template = ' case SpvCapability{capability}:\n' \
' return "{capability}";\n'
function += ''.join([template.format(capability=capability)
for capability in capabilities])
function += ' case SpvCapabilityMax:\n' \
' assert(0 && "Attempting to convert SpvCapabilityMax to string");\n' \
' return "";\n'
function += ' };\n\n return "";\n}'
return function
def generate_all_string_enum_mappings(operands):
"""Returns all string-to-enum / enum-to-string mapping tables."""
tables = []
tables.append(generate_extension_to_string_mapping(operands))
tables.append(generate_string_to_extension_mapping(operands))
tables.append(generate_capability_to_string_mapping(operands))
return '\n\n'.join(tables)
def main():
import argparse
parser = argparse.ArgumentParser(description='Generate SPIR-V info tables')
@ -375,6 +480,12 @@ def main():
parser.add_argument('--operand-kinds-output', metavar='<path>',
type=str, required=False, default=None,
help='output file for operand kinds')
parser.add_argument('--extension-enum-output', metavar='<path>',
type=str, required=False, default=None,
help='output file for extension enumeration')
parser.add_argument('--enum-string-mapping-output', metavar='<path>',
type=str, required=False, default=None,
help='output file for enum-string mappings')
args = parser.parse_args()
if (args.core_insts_output is None) != \
@ -394,7 +505,9 @@ def main():
exit(1)
if all([args.core_insts_output is None,
args.glsl_insts_output is None,
args.opencl_insts_output is None]):
args.opencl_insts_output is None,
args.extension_enum_output is None,
args.enum_string_mapping_output is None]):
print('error: at least one output should be specified.')
exit(1)
@ -407,6 +520,15 @@ def main():
file=open(args.core_insts_output, 'w'))
print(generate_operand_kind_table(grammar['operand_kinds']),
file=open(args.operand_kinds_output, 'w'))
if args.extension_enum_output is not None:
make_path_to_file(args.extension_enum_output)
print(generate_extension_enum(grammar['operand_kinds']),
file=open(args.extension_enum_output, 'w'))
if args.enum_string_mapping_output is not None:
make_path_to_file(args.enum_string_mapping_output)
print(generate_all_string_enum_mappings(
grammar['operand_kinds']),
file=open(args.enum_string_mapping_output, 'w'))
if args.extinst_glsl_grammar is not None:
with open(args.extinst_glsl_grammar) as json_file: