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
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
--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)))
// 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.
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")
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:
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};
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 {
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;
// 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;
#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),
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) {
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;
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 "";
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);
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;
} 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;
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;
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;
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);
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",
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.
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",
"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",
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",
{65535, 32767, "Unknown(65535); 32767"},
}), );
+// TODO(dneto): Test new instructions and enums in SPIR-V 1.3
+
} // anonymous namespace
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,
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);
}
{"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},
{"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},
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'"));
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(
// 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})},
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,
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,
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",
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})},
// 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.
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;
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;
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);
}
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);
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;
}
} 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")) {