Support SPIR-V 1.3 and Vulkan 1.1
authorDavid Neto <dneto@google.com>
Fri, 9 Feb 2018 19:29:02 +0000 (14:29 -0500)
committerDavid Neto <dneto@google.com>
Tue, 6 Mar 2018 20:17:31 +0000 (15:17 -0500)
The default target is SPIR-V 1.3.

For example, spirv-as will generate a SPIR-V 1.3 binary by default.
Use command line option "--target-env spv1.0" if you want to make a SPIR-V
1.0 binary or validate against SPIR-V 1.0 rules.

Example:
        # Generate a SPIR-V 1.0 binary instead of SPIR-V 1.3
spirv-as --target-env spv1.0 a.spvasm -o a.spv
spirv-as --target-env vulkan1.0 a.spvasm -o a.spv

        # Validate as SPIR-V 1.0.
spirv-val --target-env spv1.0 a.spv
        # Validate as Vulkan 1.0
spirv-val --target-env vulkan1.0 a.spv

17 files changed:
Android.mk
include/spirv-tools/libspirv.h
source/CMakeLists.txt
source/ext_inst.cpp
source/opcode.cpp
source/operand.cpp
source/spirv_target_env.cpp
source/table.cpp
test/binary_header_get_test.cpp
test/binary_to_text_test.cpp
test/target_env_test.cpp
test/text_to_binary.extension_test.cpp
test/unit_spirv.h
tools/as/as.cpp
tools/dis/dis.cpp
tools/opt/opt.cpp
tools/val/val.cpp

index 9585d50..a0cf5e8 100644 (file)
@@ -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)))
 
index 7f1ebba..948a672 100644 (file)
@@ -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.
index 2d7d7ca..f29a0d4 100644 (file)
@@ -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")
index 19122a2..6218eb1 100644 (file)
@@ -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:
index ae9d024..871c337 100644 (file)
@@ -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;
index 180cb7f..cdb99a7 100644 (file)
 
 #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;
index 9d777bc..d3fe4b4 100644 (file)
@@ -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;
index 92296ec..1a40e27 100644 (file)
@@ -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;
index 9ccd0a9..d6efe5a 100644 (file)
@@ -50,7 +50,7 @@ TEST_F(BinaryHeaderGet, Default) {
   ASSERT_EQ(SPV_SUCCESS, spvBinaryHeaderGet(&const_bin, endian, &header));
 
   ASSERT_EQ(static_cast<uint32_t>(SpvMagicNumber), header.magic);
-  ASSERT_EQ(0x00010200u, header.version);
+  ASSERT_EQ(0x00010300u, header.version);
   ASSERT_EQ(static_cast<uint32_t>(SPV_GENERATOR_CODEPLAY), header.generator);
   ASSERT_EQ(1u, header.bound);
   ASSERT_EQ(0u, header.schema);
index d7adae3..148e025 100644 (file)
@@ -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<std::string>{
                 "%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<std::string>{
                 "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<std::string>{
             "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<std::string>{
-                                    "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<std::string>{
+                "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<std::string>{
                                     "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<std::string>{
-                                    "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<std::string>{
+                "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<std::string>{
-                                    "%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<std::string>{
+                "%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<std::string>{
                 "%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<std::string>{
                 "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
index f67a461..0c70621 100644 (file)
@@ -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<spv_target_env>(17));
+  spv_context context = spvContextCreate(static_cast<spv_target_env>(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},
index 6689bee..4db7649 100644 (file)
@@ -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<spv_target_env> 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<AssemblyCase>{
+                {"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<AssemblyCase>{
+                {"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<AssemblyCase>{
             {"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<AssemblyCase>{
                 {"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<AssemblyCase>{
                 {"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<AssemblyCase>{
                 // 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<AssemblyCase>{
                 {"OpCapability DeviceGroup\n",
                  MakeInstruction(SpvOpCapability, {SpvCapabilityDeviceGroup})},
index c848fe9..45e8c23 100644 (file)
@@ -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<spv_target_env> 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.
index 475d44d..0d9363f 100644 (file)
@@ -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;
index c1dc189..6a2e269 100644 (file)
@@ -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;
index 9c9a271..ca63c19 100644 (file)
@@ -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);
index 633d2f6..fc1fb53 100644 (file)
@@ -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")) {