diff --git a/Android.mk b/Android.mk index 9585d50a..a0cf5e84 100644 --- a/Android.mk +++ b/Android.mk @@ -126,6 +126,10 @@ SPVTOOLS_OPT_SRC_FILES := \ source/opt/workaround1209.cpp # Locations of grammar files. +# +# TODO(dneto): Build a single set of tables that embeds versioning differences on +# a per-item basis. That must happen before SPIR-V 1.4, etc. +# https://github.com/KhronosGroup/SPIRV-Tools/issues/1195 SPV_CORE10_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.0/spirv.core.grammar.json SPV_CORE11_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.1/spirv.core.grammar.json SPV_CORE12_GRAMMAR=$(SPVHEADERS_LOCAL_PATH)/include/spirv/1.2/spirv.core.grammar.json @@ -174,9 +178,26 @@ $(1)/core.insts-1.2.inc $(1)/operand.kinds-1.2.inc: \ --core-insts-output=$(1)/core.insts-1.2.inc \ --operand-kinds-output=$(1)/operand.kinds-1.2.inc @echo "[$(TARGET_ARCH_ABI)] Grammar v1.2 : instructions & operands <= grammar JSON files" -$(LOCAL_PATH)/source/opcode.cpp: $(1)/core.insts-1.0.inc $(1)/core.insts-1.1.inc $(1)/core.insts-1.2.inc -$(LOCAL_PATH)/source/operand.cpp: $(1)/operand.kinds-1.0.inc $(1)/operand.kinds-1.1.inc $(1)/operand.kinds-1.2.inc -$(LOCAL_PATH)/source/ext_inst.cpp: $(1)/glsl.std.450.insts.inc $(1)/opencl.std.insts.inc +$(1)/core.insts-unified1.inc $(1)/operand.kinds-unified1.inc: \ + $(LOCAL_PATH)/utils/generate_grammar_tables.py \ + $(SPV_COREUNIFIED1_GRAMMAR) \ + $(SPV_DEBUGINFO_GRAMMAR) + @$(HOST_PYTHON) $(LOCAL_PATH)/utils/generate_grammar_tables.py \ + --spirv-core-grammar=$(SPV_COREUNIFIED1_GRAMMAR) \ + --extinst-debuginfo-grammar=$(SPV_DEBUGINFO_GRAMMAR) \ + --core-insts-output=$(1)/core.insts-unified1.inc \ + --operand-kinds-output=$(1)/operand.kinds-unified1.inc + @echo "[$(TARGET_ARCH_ABI)] Grammar v1.3 (from unified1) : instructions & operands <= grammar JSON files" +$(LOCAL_PATH)/source/opcode.cpp: $(1)/core.insts-1.0.inc $(1)/core.insts-1.1.inc $(1)/core.insts-1.2.inc $(1)/core.insts-unified1.inc +$(LOCAL_PATH)/source/operand.cpp: $(1)/operand.kinds-1.0.inc $(1)/operand.kinds-1.1.inc $(1)/operand.kinds-1.2.inc $(1)/operand.kinds-unified1.inc +$(LOCAL_PATH)/source/ext_inst.cpp: \ + $(1)/glsl.std.450.insts.inc \ + $(1)/opencl.std.insts.inc \ + $(1)/debuginfo.insts.inc \ + $(1)/spv-amd-gcn-shader.insts.inc \ + $(1)/spv-amd-shader-ballot.insts.inc \ + $(1)/spv-amd-shader-explicit-vertex-parameter.insts.inc \ + $(1)/spv-amd-shader-trinary-minmax.insts.inc endef $(eval $(call gen_spvtools_grammar_tables,$(SPVTOOLS_OUT_PATH))) diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h index 7f1ebba7..948a6722 100644 --- a/include/spirv-tools/libspirv.h +++ b/include/spirv-tools/libspirv.h @@ -409,6 +409,8 @@ typedef enum { // cl_khr_il_program, latest revision. SPV_ENV_OPENCL_EMBEDDED_2_1, // OpenCL Embedded Profile 2.1 latest revision. SPV_ENV_OPENCL_EMBEDDED_2_2, // OpenCL Embedded Profile 2.2 latest revision. + SPV_ENV_UNIVERSAL_1_3, // SPIR-V 1.3 latest revision, no other restrictions. + SPV_ENV_VULKAN_1_1, // Vulkan 1.0 latest revision. } spv_target_env; // SPIR-V Validator can be parameterized with the following Universal Limits. diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 2d7d7caa..f29a0d4f 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -131,9 +131,15 @@ macro(spvtools_extinst_lang_headers NAME GRAMMAR_FILE) endmacro(spvtools_extinst_lang_headers) +# SPIR-V 1.3 support is in SPIRV-Headers include/spirv/unified1 +# Temporarily assume that's the last SPIR-V version in 'unified1'. +# TODO(dneto): Build a single set of tables that embeds versioning +# differences on a per-item basis. That must happen before SPIR-V 1.4, etc. +# https://github.com/KhronosGroup/SPIRV-Tools/issues/1195 spvtools_core_tables("1.0") spvtools_core_tables("1.1") spvtools_core_tables("1.2") +spvtools_core_tables("unified1") spvtools_enum_string_mapping("unified1") spvtools_opencl_tables("unified1") spvtools_glsl_tables("unified1") diff --git a/source/ext_inst.cpp b/source/ext_inst.cpp index 19122a25..6218eb11 100644 --- a/source/ext_inst.cpp +++ b/source/ext_inst.cpp @@ -79,6 +79,8 @@ spv_result_t spvExtInstTableGet(spv_ext_inst_table* pExtInstTable, case SPV_ENV_OPENGL_4_2: case SPV_ENV_OPENGL_4_3: case SPV_ENV_OPENGL_4_5: + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_VULKAN_1_1: *pExtInstTable = &kTable_1_0; return SPV_SUCCESS; default: diff --git a/source/opcode.cpp b/source/opcode.cpp index ae9d0240..871c3372 100644 --- a/source/opcode.cpp +++ b/source/opcode.cpp @@ -32,9 +32,15 @@ struct OpcodeDescPtrLen { uint32_t len; }; -#include "core.insts-1.0.inc" // defines kOpcodeTableEntries_1_0 -#include "core.insts-1.1.inc" // defines kOpcodeTableEntries_1_1 -#include "core.insts-1.2.inc" // defines kOpcodeTableEntries_1_2 +// For now, assume unified1 contains up to SPIR-V 1.3 and no later +// SPIR-V version. +// TODO(dneto): Make one set of tables, but with version tags on a +// per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195 + +#include "core.insts-1.0.inc" // defines kOpcodeTableEntries_1_0 +#include "core.insts-1.1.inc" // defines kOpcodeTableEntries_1_1 +#include "core.insts-1.2.inc" // defines kOpcodeTableEntries_1_2 +#include "core.insts-unified1.inc" // defines kOpcodeTableEntries_1_3 static const spv_opcode_table_t kTable_1_0 = { ARRAY_SIZE(kOpcodeTableEntries_1_0), kOpcodeTableEntries_1_0}; @@ -42,6 +48,8 @@ static const spv_opcode_table_t kTable_1_1 = { ARRAY_SIZE(kOpcodeTableEntries_1_1), kOpcodeTableEntries_1_1}; static const spv_opcode_table_t kTable_1_2 = { ARRAY_SIZE(kOpcodeTableEntries_1_2), kOpcodeTableEntries_1_2}; +static const spv_opcode_table_t kTable_1_3 = { + ARRAY_SIZE(kOpcodeTableEntries_1_3), kOpcodeTableEntries_1_3}; // Represents a vendor tool entry in the SPIR-V XML Regsitry. struct VendorTool { @@ -112,6 +120,10 @@ spv_result_t spvOpcodeTableGet(spv_opcode_table* pInstTable, case SPV_ENV_OPENCL_EMBEDDED_2_2: *pInstTable = &kTable_1_2; return SPV_SUCCESS; + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_VULKAN_1_1: + *pInstTable = &kTable_1_3; + return SPV_SUCCESS; } assert(0 && "Unknown spv_target_env in spvOpcodeTableGet()"); return SPV_ERROR_INVALID_TABLE; @@ -182,9 +194,9 @@ const char* spvOpcodeString(const SpvOp opcode) { // Use the latest SPIR-V version, which should be backward-compatible with all // previous ones. - const auto beg = kOpcodeTableEntries_1_2; + const auto beg = kOpcodeTableEntries_1_3; const auto end = - kOpcodeTableEntries_1_2 + ARRAY_SIZE(kOpcodeTableEntries_1_2); + kOpcodeTableEntries_1_3 + ARRAY_SIZE(kOpcodeTableEntries_1_3); spv_opcode_desc_t value{"", opcode, 0, nullptr, 0, {}, 0, 0}; auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) { return lhs.opcode < rhs.opcode; diff --git a/source/operand.cpp b/source/operand.cpp index 180cb7ff..cdb99a7a 100644 --- a/source/operand.cpp +++ b/source/operand.cpp @@ -20,9 +20,15 @@ #include "macro.h" +// For now, assume unified1 contains up to SPIR-V 1.3 and no later +// SPIR-V version. +// TODO(dneto): Make one set of tables, but with version tags on a +// per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195 + #include "operand.kinds-1.0.inc" #include "operand.kinds-1.1.inc" #include "operand.kinds-1.2.inc" +#include "operand.kinds-unified1.inc" static const spv_operand_table_t kTable_1_0 = { ARRAY_SIZE(pygen_variable_OperandInfoTable_1_0), @@ -33,6 +39,9 @@ static const spv_operand_table_t kTable_1_1 = { static const spv_operand_table_t kTable_1_2 = { ARRAY_SIZE(pygen_variable_OperandInfoTable_1_2), pygen_variable_OperandInfoTable_1_2}; +static const spv_operand_table_t kTable_1_3 = { + ARRAY_SIZE(pygen_variable_OperandInfoTable_1_3), + pygen_variable_OperandInfoTable_1_3}; spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable, spv_target_env env) { @@ -62,6 +71,10 @@ spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable, case SPV_ENV_OPENCL_EMBEDDED_2_2: *pOperandTable = &kTable_1_2; return SPV_SUCCESS; + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_VULKAN_1_1: + *pOperandTable = &kTable_1_3; + return SPV_SUCCESS; } assert(0 && "Unknown spv_target_env in spvOperandTableGet()"); return SPV_ERROR_INVALID_TABLE; diff --git a/source/spirv_target_env.cpp b/source/spirv_target_env.cpp index 9d777bc4..d3fe4b42 100644 --- a/source/spirv_target_env.cpp +++ b/source/spirv_target_env.cpp @@ -54,6 +54,10 @@ const char* spvTargetEnvDescription(spv_target_env env) { return "SPIR-V 1.0 (under OpenCL 4.5 semantics)"; case SPV_ENV_UNIVERSAL_1_2: return "SPIR-V 1.2"; + case SPV_ENV_UNIVERSAL_1_3: + return "SPIR-V 1.3"; + case SPV_ENV_VULKAN_1_1: + return "SPIR-V 1.3 (under Vulkan 1.1 semantics)"; } assert(0 && "Unhandled SPIR-V target environment"); return ""; @@ -81,6 +85,9 @@ uint32_t spvVersionForTargetEnv(spv_target_env env) { case SPV_ENV_OPENCL_2_2: case SPV_ENV_OPENCL_EMBEDDED_2_2: return SPV_SPIRV_VERSION_WORD(1, 2); + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_VULKAN_1_1: + return SPV_SPIRV_VERSION_WORD(1, 3); } assert(0 && "Unhandled SPIR-V target environment"); return SPV_SPIRV_VERSION_WORD(0, 0); @@ -93,6 +100,9 @@ bool spvParseTargetEnv(const char* s, spv_target_env* env) { if (match("vulkan1.0")) { if (env) *env = SPV_ENV_VULKAN_1_0; return true; + } else if (match("vulkan1.1")) { + if (env) *env = SPV_ENV_VULKAN_1_1; + return true; } else if (match("spv1.0")) { if (env) *env = SPV_ENV_UNIVERSAL_1_0; return true; @@ -102,6 +112,9 @@ bool spvParseTargetEnv(const char* s, spv_target_env* env) { } else if (match("spv1.2")) { if (env) *env = SPV_ENV_UNIVERSAL_1_2; return true; + } else if (match("spv1.3")) { + if (env) *env = SPV_ENV_UNIVERSAL_1_3; + return true; } else if (match("opencl1.2embedded")) { if (env) *env = SPV_ENV_OPENCL_EMBEDDED_1_2; return true; @@ -165,8 +178,10 @@ bool spvIsVulkanEnv(spv_target_env env) { case SPV_ENV_UNIVERSAL_1_2: case SPV_ENV_OPENCL_2_2: case SPV_ENV_OPENCL_EMBEDDED_2_2: + case SPV_ENV_UNIVERSAL_1_3: return false; case SPV_ENV_VULKAN_1_0: + case SPV_ENV_VULKAN_1_1: return true; } return false; diff --git a/source/table.cpp b/source/table.cpp index 92296ec2..1a40e27c 100644 --- a/source/table.cpp +++ b/source/table.cpp @@ -35,6 +35,8 @@ spv_context spvContextCreate(spv_target_env env) { case SPV_ENV_OPENGL_4_3: case SPV_ENV_OPENGL_4_5: case SPV_ENV_UNIVERSAL_1_2: + case SPV_ENV_UNIVERSAL_1_3: + case SPV_ENV_VULKAN_1_1: break; default: return nullptr; diff --git a/test/binary_header_get_test.cpp b/test/binary_header_get_test.cpp index 9ccd0a95..d6efe5af 100644 --- a/test/binary_header_get_test.cpp +++ b/test/binary_header_get_test.cpp @@ -50,7 +50,7 @@ TEST_F(BinaryHeaderGet, Default) { ASSERT_EQ(SPV_SUCCESS, spvBinaryHeaderGet(&const_bin, endian, &header)); ASSERT_EQ(static_cast(SpvMagicNumber), header.magic); - ASSERT_EQ(0x00010200u, header.version); + ASSERT_EQ(0x00010300u, header.version); ASSERT_EQ(static_cast(SPV_GENERATOR_CODEPLAY), header.generator); ASSERT_EQ(1u, header.bound); ASSERT_EQ(0u, header.schema); diff --git a/test/binary_to_text_test.cpp b/test/binary_to_text_test.cpp index d7adae34..148e025d 100644 --- a/test/binary_to_text_test.cpp +++ b/test/binary_to_text_test.cpp @@ -240,7 +240,7 @@ INSTANTIATE_TEST_CASE_P( NumericLiterals, RoundTripInstructionsTest, // This test is independent of environment, so just test the one. Combine(::testing::Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_UNIVERSAL_1_2), + SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3), ::testing::ValuesIn(std::vector{ "%1 = OpTypeInt 12 0\n%2 = OpConstant %1 1867\n", "%1 = OpTypeInt 12 1\n%2 = OpConstant %1 1867\n", @@ -274,7 +274,7 @@ INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P( MemoryAccessMasks, RoundTripInstructionsTest, Combine(::testing::Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_UNIVERSAL_1_2), + SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3), ::testing::ValuesIn(std::vector{ "OpStore %1 %2\n", // 3 words long. "OpStore %1 %2 None\n", // 4 words long, explicit final 0. @@ -291,7 +291,7 @@ INSTANTIATE_TEST_CASE_P( FPFastMathModeMasks, RoundTripInstructionsTest, Combine( ::testing::Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_UNIVERSAL_1_2), + SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3), ::testing::ValuesIn(std::vector{ "OpDecorate %1 FPFastMathMode None\n", "OpDecorate %1 FPFastMathMode NotNaN\n", @@ -305,54 +305,55 @@ INSTANTIATE_TEST_CASE_P( "OpDecorate %1 FPFastMathMode NotNaN|NotInf|NSZ|AllowRecip|Fast\n", })), ); -INSTANTIATE_TEST_CASE_P(LoopControlMasks, RoundTripInstructionsTest, - Combine(::testing::Values(SPV_ENV_UNIVERSAL_1_0, - SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_UNIVERSAL_1_2), - ::testing::ValuesIn(std::vector{ - "OpLoopMerge %1 %2 None\n", - "OpLoopMerge %1 %2 Unroll\n", - "OpLoopMerge %1 %2 DontUnroll\n", - "OpLoopMerge %1 %2 Unroll|DontUnroll\n", - })), ); +INSTANTIATE_TEST_CASE_P( + LoopControlMasks, RoundTripInstructionsTest, + Combine(::testing::Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, + SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_2), + ::testing::ValuesIn(std::vector{ + "OpLoopMerge %1 %2 None\n", + "OpLoopMerge %1 %2 Unroll\n", + "OpLoopMerge %1 %2 DontUnroll\n", + "OpLoopMerge %1 %2 Unroll|DontUnroll\n", + })), ); INSTANTIATE_TEST_CASE_P(LoopControlMasksV11, RoundTripInstructionsTest, Combine(::testing::Values(SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_UNIVERSAL_1_2), + SPV_ENV_UNIVERSAL_1_2, + SPV_ENV_UNIVERSAL_1_3), ::testing::ValuesIn(std::vector{ "OpLoopMerge %1 %2 DependencyInfinite\n", "OpLoopMerge %1 %2 DependencyLength 8\n", })), ); -INSTANTIATE_TEST_CASE_P(SelectionControlMasks, RoundTripInstructionsTest, - Combine(::testing::Values(SPV_ENV_UNIVERSAL_1_0, - SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_UNIVERSAL_1_2), - ::testing::ValuesIn(std::vector{ - "OpSelectionMerge %1 None\n", - "OpSelectionMerge %1 Flatten\n", - "OpSelectionMerge %1 DontFlatten\n", - "OpSelectionMerge %1 Flatten|DontFlatten\n", - })), ); +INSTANTIATE_TEST_CASE_P( + SelectionControlMasks, RoundTripInstructionsTest, + Combine(::testing::Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, + SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_2), + ::testing::ValuesIn(std::vector{ + "OpSelectionMerge %1 None\n", + "OpSelectionMerge %1 Flatten\n", + "OpSelectionMerge %1 DontFlatten\n", + "OpSelectionMerge %1 Flatten|DontFlatten\n", + })), ); -INSTANTIATE_TEST_CASE_P(FunctionControlMasks, RoundTripInstructionsTest, - Combine(::testing::Values(SPV_ENV_UNIVERSAL_1_0, - SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_UNIVERSAL_1_2), - ::testing::ValuesIn(std::vector{ - "%2 = OpFunction %1 None %3\n", - "%2 = OpFunction %1 Inline %3\n", - "%2 = OpFunction %1 DontInline %3\n", - "%2 = OpFunction %1 Pure %3\n", - "%2 = OpFunction %1 Const %3\n", - "%2 = OpFunction %1 Inline|Pure|Const %3\n", - "%2 = OpFunction %1 DontInline|Const %3\n", - })), ); +INSTANTIATE_TEST_CASE_P( + FunctionControlMasks, RoundTripInstructionsTest, + Combine(::testing::Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, + SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3), + ::testing::ValuesIn(std::vector{ + "%2 = OpFunction %1 None %3\n", + "%2 = OpFunction %1 Inline %3\n", + "%2 = OpFunction %1 DontInline %3\n", + "%2 = OpFunction %1 Pure %3\n", + "%2 = OpFunction %1 Const %3\n", + "%2 = OpFunction %1 Inline|Pure|Const %3\n", + "%2 = OpFunction %1 DontInline|Const %3\n", + })), ); INSTANTIATE_TEST_CASE_P( ImageMasks, RoundTripInstructionsTest, Combine(::testing::Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_UNIVERSAL_1_2), + SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3), ::testing::ValuesIn(std::vector{ "%2 = OpImageFetch %1 %3 %4\n", "%2 = OpImageFetch %1 %3 %4 None\n", @@ -374,7 +375,7 @@ INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P( NewInstructionsInSPIRV1_2, RoundTripInstructionsTest, - Combine(::testing::Values(SPV_ENV_UNIVERSAL_1_2), + Combine(::testing::Values(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3), ::testing::ValuesIn(std::vector{ "OpExecutionModeId %1 SubgroupsPerWorkgroupId %2\n", "OpExecutionModeId %1 LocalSizeId %2 %3 %4\n", @@ -547,4 +548,6 @@ INSTANTIATE_TEST_CASE_P(GeneratorStrings, GeneratorStringTest, {65535, 32767, "Unknown(65535); 32767"}, }), ); +// TODO(dneto): Test new instructions and enums in SPIR-V 1.3 + } // anonymous namespace diff --git a/test/target_env_test.cpp b/test/target_env_test.cpp index f67a461c..0c706215 100644 --- a/test/target_env_test.cpp +++ b/test/target_env_test.cpp @@ -41,7 +41,7 @@ TEST_P(TargetEnvTest, ValidDescription) { TEST_P(TargetEnvTest, ValidSpirvVersion) { auto spirv_version = spvVersionForTargetEnv(GetParam()); - ASSERT_THAT(spirv_version, AnyOf(0x10000, 0x10100, 0x10200)); + ASSERT_THAT(spirv_version, AnyOf(0x10000, 0x10100, 0x10200, 0x10300)); } INSTANTIATE_TEST_CASE_P(AllTargetEnvs, TargetEnvTest, @@ -49,7 +49,7 @@ INSTANTIATE_TEST_CASE_P(AllTargetEnvs, TargetEnvTest, TEST(GetContextTest, InvalidTargetEnvProducesNull) { // Use a value beyond the last valid enum value. - spv_context context = spvContextCreate(static_cast(17)); + spv_context context = spvContextCreate(static_cast(30)); EXPECT_EQ(context, nullptr); } @@ -75,7 +75,9 @@ INSTANTIATE_TEST_CASE_P( {"spv1.0", true, SPV_ENV_UNIVERSAL_1_0}, {"spv1.1", true, SPV_ENV_UNIVERSAL_1_1}, {"spv1.2", true, SPV_ENV_UNIVERSAL_1_2}, + {"spv1.3", true, SPV_ENV_UNIVERSAL_1_3}, {"vulkan1.0", true, SPV_ENV_VULKAN_1_0}, + {"vulkan1.1", true, SPV_ENV_VULKAN_1_1}, {"opencl2.1", true, SPV_ENV_OPENCL_2_1}, {"opencl2.2", true, SPV_ENV_OPENCL_2_2}, {"opengl4.0", true, SPV_ENV_OPENGL_4_0}, @@ -89,6 +91,10 @@ INSTANTIATE_TEST_CASE_P( {"opencl2.0embedded", true, SPV_ENV_OPENCL_EMBEDDED_2_0}, {"opencl2.1embedded", true, SPV_ENV_OPENCL_EMBEDDED_2_1}, {"opencl2.2embedded", true, SPV_ENV_OPENCL_EMBEDDED_2_2}, + {"opencl2.3", false, SPV_ENV_UNIVERSAL_1_0}, + {"opencl3.0", false, SPV_ENV_UNIVERSAL_1_0}, + {"vulkan1.2", false, SPV_ENV_UNIVERSAL_1_0}, + {"vulkan2.0", false, SPV_ENV_UNIVERSAL_1_0}, {nullptr, false, SPV_ENV_UNIVERSAL_1_0}, {"", false, SPV_ENV_UNIVERSAL_1_0}, {"abc", false, SPV_ENV_UNIVERSAL_1_0}, diff --git a/test/text_to_binary.extension_test.cpp b/test/text_to_binary.extension_test.cpp index 6689beea..4db76491 100644 --- a/test/text_to_binary.extension_test.cpp +++ b/test/text_to_binary.extension_test.cpp @@ -33,6 +33,12 @@ using spvtest::MakeInstruction; using spvtest::MakeVector; using spvtest::TextToBinaryTest; +// Returns a generator of common Vulkan environment values to be tested. +std::vector CommonVulkanEnvs() { + return {SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, SPV_ENV_UNIVERSAL_1_2, + SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1}; +} + TEST_F(TextToBinaryTest, InvalidExtInstImportName) { EXPECT_THAT(CompileFailure("%1 = OpExtInstImport \"Haskell.std\""), Eq("Invalid extended instruction import 'Haskell.std'")); @@ -155,6 +161,61 @@ INSTANTIATE_TEST_CASE_P( SpvBuiltInSubgroupLtMaskKHR})}, })), ); +INSTANTIATE_TEST_CASE_P( + SPV_KHR_shader_ballot_vulkan_1_1, ExtensionRoundTripTest, + // In SPIR-V 1.3 and Vulkan 1.1 we can drop the KHR suffix on the + // builtin enums. + Combine(Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_1), + ValuesIn(std::vector{ + {"OpCapability SubgroupBallotKHR\n", + MakeInstruction(SpvOpCapability, + {SpvCapabilitySubgroupBallotKHR})}, + {"%2 = OpSubgroupBallotKHR %1 %3\n", + MakeInstruction(SpvOpSubgroupBallotKHR, {1, 2, 3})}, + {"%2 = OpSubgroupFirstInvocationKHR %1 %3\n", + MakeInstruction(SpvOpSubgroupFirstInvocationKHR, {1, 2, 3})}, + {"OpDecorate %1 BuiltIn SubgroupEqMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupEqMask})}, + {"OpDecorate %1 BuiltIn SubgroupGeMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupGeMask})}, + {"OpDecorate %1 BuiltIn SubgroupGtMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupGtMask})}, + {"OpDecorate %1 BuiltIn SubgroupLeMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupLeMask})}, + {"OpDecorate %1 BuiltIn SubgroupLtMask\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupLtMask})}, + })), ); + +// The old builtin names (with KHR suffix) still work in the assmebler, and +// map to the enums without the KHR. +INSTANTIATE_TEST_CASE_P( + SPV_KHR_shader_ballot_vulkan_1_1_alias_check, ExtensionAssemblyTest, + // In SPIR-V 1.3 and Vulkan 1.1 we can drop the KHR suffix on the + // builtin enums. + Combine(Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_1), + ValuesIn(std::vector{ + {"OpDecorate %1 BuiltIn SubgroupEqMaskKHR\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupEqMask})}, + {"OpDecorate %1 BuiltIn SubgroupGeMaskKHR\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupGeMask})}, + {"OpDecorate %1 BuiltIn SubgroupGtMaskKHR\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupGtMask})}, + {"OpDecorate %1 BuiltIn SubgroupLeMaskKHR\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupLeMask})}, + {"OpDecorate %1 BuiltIn SubgroupLtMaskKHR\n", + MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn, + SpvBuiltInSubgroupLtMask})}, + })), ); + // SPV_KHR_shader_draw_parameters INSTANTIATE_TEST_CASE_P( @@ -162,8 +223,7 @@ INSTANTIATE_TEST_CASE_P( // We'll get coverage over operand tables by trying the universal // environments, and at least one specific environment. Combine( - Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_VULKAN_1_0), + ValuesIn(CommonVulkanEnvs()), ValuesIn(std::vector{ {"OpCapability DrawParameters\n", MakeInstruction(SpvOpCapability, {SpvCapabilityDrawParameters})}, @@ -184,8 +244,7 @@ INSTANTIATE_TEST_CASE_P( SPV_KHR_subgroup_vote, ExtensionRoundTripTest, // We'll get coverage over operand tables by trying the universal // environments, and at least one specific environment. - Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_VULKAN_1_0), + Combine(ValuesIn(CommonVulkanEnvs()), ValuesIn(std::vector{ {"OpCapability SubgroupVoteKHR\n", MakeInstruction(SpvOpCapability, @@ -204,8 +263,7 @@ INSTANTIATE_TEST_CASE_P( SPV_KHR_16bit_storage, ExtensionRoundTripTest, // We'll get coverage over operand tables by trying the universal // environments, and at least one specific environment. - Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_VULKAN_1_0), + Combine(ValuesIn(CommonVulkanEnvs()), ValuesIn(std::vector{ {"OpCapability StorageBuffer16BitAccess\n", MakeInstruction(SpvOpCapability, @@ -230,8 +288,7 @@ INSTANTIATE_TEST_CASE_P( INSTANTIATE_TEST_CASE_P( SPV_KHR_16bit_storage_alias_check, ExtensionAssemblyTest, - Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_VULKAN_1_0), + Combine(ValuesIn(CommonVulkanEnvs()), ValuesIn(std::vector{ // The old name maps to the new enum. {"OpCapability StorageUniformBufferBlock16\n", @@ -250,8 +307,7 @@ INSTANTIATE_TEST_CASE_P( SPV_KHR_device_group, ExtensionRoundTripTest, // We'll get coverage over operand tables by trying the universal // environments, and at least one specific environment. - Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_VULKAN_1_0), + Combine(ValuesIn(CommonVulkanEnvs()), ValuesIn(std::vector{ {"OpCapability DeviceGroup\n", MakeInstruction(SpvOpCapability, {SpvCapabilityDeviceGroup})}, diff --git a/test/unit_spirv.h b/test/unit_spirv.h index c848fe90..45e8c237 100644 --- a/test/unit_spirv.h +++ b/test/unit_spirv.h @@ -208,15 +208,18 @@ inline std::string MakeLongUTF8String(size_t num_4_byte_chars) { // Returns a vector of all valid target environment enums. inline std::vector AllTargetEnvironments() { - return {SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, - SPV_ENV_OPENCL_1_2, SPV_ENV_OPENCL_EMBEDDED_1_2, - SPV_ENV_OPENCL_2_0, SPV_ENV_OPENCL_EMBEDDED_2_0, - SPV_ENV_OPENCL_2_1, SPV_ENV_OPENCL_EMBEDDED_2_1, - SPV_ENV_OPENCL_2_2, SPV_ENV_OPENCL_EMBEDDED_2_2, - SPV_ENV_VULKAN_1_0, SPV_ENV_OPENGL_4_0, - SPV_ENV_OPENGL_4_1, SPV_ENV_OPENGL_4_2, - SPV_ENV_OPENGL_4_3, SPV_ENV_OPENGL_4_5, - SPV_ENV_UNIVERSAL_1_2}; + return { + SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, + SPV_ENV_OPENCL_1_2, SPV_ENV_OPENCL_EMBEDDED_1_2, + SPV_ENV_OPENCL_2_0, SPV_ENV_OPENCL_EMBEDDED_2_0, + SPV_ENV_OPENCL_2_1, SPV_ENV_OPENCL_EMBEDDED_2_1, + SPV_ENV_OPENCL_2_2, SPV_ENV_OPENCL_EMBEDDED_2_2, + SPV_ENV_VULKAN_1_0, SPV_ENV_OPENGL_4_0, + SPV_ENV_OPENGL_4_1, SPV_ENV_OPENGL_4_2, + SPV_ENV_OPENGL_4_3, SPV_ENV_OPENGL_4_5, + SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3, + SPV_ENV_VULKAN_1_1, + }; } // Returns the capabilities in a CapabilitySet as an ordered vector. diff --git a/tools/as/as.cpp b/tools/as/as.cpp index 475d44da..0d9363f7 100644 --- a/tools/as/as.cpp +++ b/tools/as/as.cpp @@ -41,13 +41,14 @@ Options: Numeric IDs in the binary will have the same values as in the source. Non-numeric IDs are allocated by filling in the gaps, starting with 1 and going up. - --target-env {vulkan1.0|spv1.0|spv1.1|spv1.2} - Use Vulkan1.0/SPIR-V1.0/SPIR-V1.1/SPIR-V1.2 + --target-env {vulkan1.0|vulkan1.1|spv1.0|spv1.1|spv1.2|spv1.3} + Use Vulkan 1.0, Vulkan 1.1, SPIR-V 1.0, SPIR-V 1.1, + SPIR-V 1.2, or SPIR-V 1.3 )", argv0, argv0); } -static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_2; +static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_3; int main(int argc, char** argv) { const char* inFile = nullptr; diff --git a/tools/dis/dis.cpp b/tools/dis/dis.cpp index c1dc189c..6a2e2693 100644 --- a/tools/dis/dis.cpp +++ b/tools/dis/dis.cpp @@ -60,7 +60,7 @@ Options: argv0, argv0); } -static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_2; +static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_3; int main(int argc, char** argv) { const char* inFile = nullptr; diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 9c9a2710..ca63c196 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -48,20 +48,22 @@ std::string GetListOfPassesAsString(const spvtools::Optimizer& optimizer) { return ss.str(); } +const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_3; + std::string GetLegalizationPasses() { - spvtools::Optimizer optimizer(SPV_ENV_UNIVERSAL_1_2); + spvtools::Optimizer optimizer(kDefaultEnvironment); optimizer.RegisterLegalizationPasses(); return GetListOfPassesAsString(optimizer); } std::string GetOptimizationPasses() { - spvtools::Optimizer optimizer(SPV_ENV_UNIVERSAL_1_2); + spvtools::Optimizer optimizer(kDefaultEnvironment); optimizer.RegisterPerformancePasses(); return GetListOfPassesAsString(optimizer); } std::string GetSizePasses() { - spvtools::Optimizer optimizer(SPV_ENV_UNIVERSAL_1_2); + spvtools::Optimizer optimizer(kDefaultEnvironment); optimizer.RegisterSizePasses(); return GetListOfPassesAsString(optimizer); } @@ -561,7 +563,7 @@ int main(int argc, const char** argv) { const char* out_file = nullptr; bool skip_validator = false; - spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2; + spv_target_env target_env = kDefaultEnvironment; spv_validator_options options = spvValidatorOptionsCreate(); spvtools::Optimizer optimizer(target_env); diff --git a/tools/val/val.cpp b/tools/val/val.cpp index 633d2f6e..fc1fb53a 100644 --- a/tools/val/val.cpp +++ b/tools/val/val.cpp @@ -58,7 +58,7 @@ Options: int main(int argc, char** argv) { const char* inFile = nullptr; - spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2; + spv_target_env target_env = SPV_ENV_UNIVERSAL_1_3; spvtools::ValidatorOptions options; bool continue_processing = true; int return_code = 0; @@ -90,11 +90,14 @@ int main(int argc, char** argv) { } } else if (0 == strcmp(cur_arg, "--version")) { printf("%s\n", spvSoftwareVersionDetailsString()); - // TODO(dneto): Add OpenCL 2.2 at least. - printf("Targets:\n %s\n %s\n %s\n", + printf("Targets:\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n", + spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_0), spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_1), + spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_2), + spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_3), + spvTargetEnvDescription(SPV_ENV_OPENCL_2_2), spvTargetEnvDescription(SPV_ENV_VULKAN_1_0), - spvTargetEnvDescription(SPV_ENV_UNIVERSAL_1_2)); + spvTargetEnvDescription(SPV_ENV_VULKAN_1_1)); continue_processing = false; return_code = 0; } else if (0 == strcmp(cur_arg, "--help") || 0 == strcmp(cur_arg, "-h")) {