Fixes #1433. Validate binary version
* Validates SPIR-V binary version against target environment
diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h
index de5f16c..d6cb60c 100644
--- a/include/spirv-tools/libspirv.h
+++ b/include/spirv-tools/libspirv.h
@@ -411,7 +411,7 @@
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_ENV_VULKAN_1_1, // Vulkan 1.1 latest revision.
} spv_target_env;
// SPIR-V Validator can be parameterized with the following Universal Limits.
diff --git a/source/opcode.cpp b/source/opcode.cpp
index c8b0055..c73f14d 100644
--- a/source/opcode.cpp
+++ b/source/opcode.cpp
@@ -25,6 +25,7 @@
#include "spirv-tools/libspirv.h"
#include "spirv_constant.h"
#include "spirv_endian.h"
+#include "spirv_target_env.h"
namespace {
struct OpcodeDescPtrLen {
diff --git a/source/operand.cpp b/source/operand.cpp
index 38db2a5..4a2a2d6 100644
--- a/source/operand.cpp
+++ b/source/operand.cpp
@@ -20,6 +20,7 @@
#include "macro.h"
#include "spirv_constant.h"
+#include "spirv_target_env.h"
// For now, assume unified1 contains up to SPIR-V 1.3 and no later
// SPIR-V version.
diff --git a/source/spirv_constant.h b/source/spirv_constant.h
index 92ccd15..8eb6572 100644
--- a/source/spirv_constant.h
+++ b/source/spirv_constant.h
@@ -29,9 +29,6 @@
// Returns the minor version extracted from a version header word.
#define SPV_SPIRV_VERSION_MINOR_PART(WORD) ((uint32_t(WORD) >> 8) & 0xff)
-// Returns the version number for the given SPIR-V target environment.
-uint32_t spvVersionForTargetEnv(spv_target_env env);
-
// Header indices
#define SPV_INDEX_MAGIC_NUMBER 0u
diff --git a/source/spirv_target_env.cpp b/source/spirv_target_env.cpp
index efeff5a..cc99228 100644
--- a/source/spirv_target_env.cpp
+++ b/source/spirv_target_env.cpp
@@ -43,15 +43,15 @@
case SPV_ENV_OPENCL_EMBEDDED_2_2:
return "SPIR-V 1.2 (under OpenCL 2.2 Embedded Profile semantics)";
case SPV_ENV_OPENGL_4_0:
- return "SPIR-V 1.0 (under OpenCL 4.0 semantics)";
+ return "SPIR-V 1.0 (under OpenGL 4.0 semantics)";
case SPV_ENV_OPENGL_4_1:
- return "SPIR-V 1.0 (under OpenCL 4.1 semantics)";
+ return "SPIR-V 1.0 (under OpenGL 4.1 semantics)";
case SPV_ENV_OPENGL_4_2:
- return "SPIR-V 1.0 (under OpenCL 4.2 semantics)";
+ return "SPIR-V 1.0 (under OpenGL 4.2 semantics)";
case SPV_ENV_OPENGL_4_3:
- return "SPIR-V 1.0 (under OpenCL 4.3 semantics)";
+ return "SPIR-V 1.0 (under OpenGL 4.3 semantics)";
case SPV_ENV_OPENGL_4_5:
- return "SPIR-V 1.0 (under OpenCL 4.5 semantics)";
+ return "SPIR-V 1.0 (under OpenGL 4.5 semantics)";
case SPV_ENV_UNIVERSAL_1_2:
return "SPIR-V 1.2";
case SPV_ENV_UNIVERSAL_1_3:
diff --git a/source/spirv_target_env.h b/source/spirv_target_env.h
index 8ce1a04..315dbbe 100644
--- a/source/spirv_target_env.h
+++ b/source/spirv_target_env.h
@@ -24,4 +24,7 @@
// Returns true if |env| is a VULKAN environment, false otherwise.
bool spvIsVulkanEnv(spv_target_env env);
+// Returns the version number for the given SPIR-V target environment.
+uint32_t spvVersionForTargetEnv(spv_target_env env);
+
#endif // LIBSPIRV_SPIRV_TARGET_ENV_H_
diff --git a/source/text.cpp b/source/text.cpp
index bf18bcc..ac4f8a1 100644
--- a/source/text.cpp
+++ b/source/text.cpp
@@ -36,6 +36,7 @@
#include "operand.h"
#include "spirv-tools/libspirv.h"
#include "spirv_constant.h"
+#include "spirv_target_env.h"
#include "table.h"
#include "text_handler.h"
#include "util/bitutils.h"
diff --git a/source/validate.cpp b/source/validate.cpp
index aa8335c..2c3386c 100644
--- a/source/validate.cpp
+++ b/source/validate.cpp
@@ -35,6 +35,7 @@
#include "spirv-tools/libspirv.h"
#include "spirv_constant.h"
#include "spirv_endian.h"
+#include "spirv_target_env.h"
#include "spirv_validator_options.h"
#include "val/construct.h"
#include "val/function.h"
@@ -255,6 +256,16 @@
<< "Invalid SPIR-V header.";
}
+ if (header.version > spvVersionForTargetEnv(context.target_env)) {
+ return libspirv::DiagnosticStream(position, context.consumer,
+ SPV_ERROR_WRONG_VERSION)
+ << "Invalid SPIR-V binary version "
+ << SPV_SPIRV_VERSION_MAJOR_PART(header.version) << "."
+ << SPV_SPIRV_VERSION_MINOR_PART(header.version)
+ << " for target environment "
+ << spvTargetEnvDescription(context.target_env) << ".";
+ }
+
// Look for OpExtension instructions and register extensions.
// Diagnostics if any will be produced in the next pass (ProcessInstruction).
spvBinaryParse(&context, vstate, words, num_words,
diff --git a/test/val/CMakeLists.txt b/test/val/CMakeLists.txt
index 7e47bb6..093a04a 100644
--- a/test/val/CMakeLists.txt
+++ b/test/val/CMakeLists.txt
@@ -180,3 +180,9 @@
${VAL_TEST_COMMON_SRCS}
LIBS ${SPIRV_TOOLS}
)
+
+add_spvtools_unittest(TARGET val_version
+ SRCS val_version_test.cpp
+ ${VAL_TEST_COMMON_SRCS}
+ LIBS ${SPIRV_TOOLS}
+)
diff --git a/test/val/val_layout_test.cpp b/test/val/val_layout_test.cpp
index 06ecdc7..b91454c 100644
--- a/test/val/val_layout_test.cpp
+++ b/test/val/val_layout_test.cpp
@@ -504,11 +504,12 @@
)";
CompileSuccessfully(str, SPV_ENV_UNIVERSAL_1_1);
- ASSERT_EQ(SPV_ERROR_INVALID_BINARY,
+ ASSERT_EQ(SPV_ERROR_WRONG_VERSION,
ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
- // In a 1.0 environment the binary parse fails before we even get to
- // validation. This occurs no matter where the OpModuleProcessed is placed.
- EXPECT_THAT(getDiagnosticString(), HasSubstr("Invalid opcode: 330"));
+ // In a 1.0 environment the version check fails.
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Invalid SPIR-V binary version 1.1 for target "
+ "environment SPIR-V 1.0."));
}
TEST_F(ValidateLayout, ModuleProcessedValidIn11) {
diff --git a/test/val/val_version_test.cpp b/test/val/val_version_test.cpp
new file mode 100644
index 0000000..c9fbba7
--- /dev/null
+++ b/test/val/val_version_test.cpp
@@ -0,0 +1,207 @@
+// Copyright (c) 2018 Google LLC.
+//
+// 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 "gmock/gmock.h"
+#include "val_fixtures.h"
+
+using namespace spvtest;
+using ::testing::HasSubstr;
+using std::make_tuple;
+
+using ValidateVersion =
+ ValidateBase<std::tuple<spv_target_env, spv_target_env, std::string, bool>>;
+
+const std::string vulkan_spirv = R"(
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %func "func"
+%void = OpTypeVoid
+%functy = OpTypeFunction %void
+%func = OpFunction %void None %functy
+%1 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+const std::string opencl_spirv = R"(
+OpCapability Kernel
+OpCapability Linkage
+OpMemoryModel Logical OpenCL
+)";
+
+std::string version(spv_target_env env) {
+ switch (env) {
+ case SPV_ENV_UNIVERSAL_1_0:
+ case SPV_ENV_VULKAN_1_0:
+ case SPV_ENV_OPENGL_4_0:
+ case SPV_ENV_OPENGL_4_1:
+ case SPV_ENV_OPENGL_4_2:
+ case SPV_ENV_OPENGL_4_3:
+ case SPV_ENV_OPENGL_4_5:
+ case SPV_ENV_OPENCL_2_0:
+ case SPV_ENV_OPENCL_EMBEDDED_2_0:
+ return "1.0";
+ case SPV_ENV_UNIVERSAL_1_1:
+ case SPV_ENV_OPENCL_2_1:
+ case SPV_ENV_OPENCL_EMBEDDED_2_1:
+ return "1.1";
+ case SPV_ENV_UNIVERSAL_1_2:
+ case SPV_ENV_OPENCL_2_2:
+ case SPV_ENV_OPENCL_EMBEDDED_2_2:
+ return "1.2";
+ case SPV_ENV_UNIVERSAL_1_3:
+ case SPV_ENV_VULKAN_1_1:
+ return "1.3";
+ default:
+ return "0";
+ }
+}
+
+TEST_P(ValidateVersion, version) {
+ CompileSuccessfully(std::get<2>(GetParam()), std::get<0>(GetParam()));
+ spv_result_t res = ValidateInstructions(std::get<1>(GetParam()));
+ if (std::get<3>(GetParam())) {
+ ASSERT_EQ(SPV_SUCCESS, res);
+ } else {
+ ASSERT_EQ(SPV_ERROR_WRONG_VERSION, res);
+
+ std::string msg = "Invalid SPIR-V binary version ";
+ msg += version(std::get<0>(GetParam()));
+ msg += " for target environment ";
+ msg += spvTargetEnvDescription(std::get<1>(GetParam()));
+ EXPECT_THAT(getDiagnosticString(), HasSubstr(msg));
+ }
+}
+
+// clang-format off
+INSTANTIATE_TEST_CASE_P(Universal, ValidateVersion,
+ ::testing::Values(
+ // Binary version, Target environment
+ make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_0, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_2, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_3, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_VULKAN_1_0, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_VULKAN_1_1, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_OPENGL_4_0, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_OPENGL_4_1, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_OPENGL_4_2, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_OPENGL_4_3, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_OPENGL_4_5, vulkan_spirv, true),
+
+ make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_UNIVERSAL_1_0, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_UNIVERSAL_1_1, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_UNIVERSAL_1_2, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_UNIVERSAL_1_3, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_VULKAN_1_0, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_VULKAN_1_1, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_OPENGL_4_0, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_OPENGL_4_1, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_OPENGL_4_2, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_OPENGL_4_3, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_1, SPV_ENV_OPENGL_4_5, vulkan_spirv, false),
+
+ make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_0, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_1, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_2, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_0, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_1, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_OPENGL_4_0, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_OPENGL_4_1, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_OPENGL_4_2, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_OPENGL_4_3, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_2, SPV_ENV_OPENGL_4_5, vulkan_spirv, false),
+
+ make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_0, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_1, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_2, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_UNIVERSAL_1_3, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_0, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_1, vulkan_spirv, true),
+ make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_0, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_1, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_2, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_3, vulkan_spirv, false),
+ make_tuple(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_OPENGL_4_5, vulkan_spirv, false)
+ )
+);
+
+INSTANTIATE_TEST_CASE_P(Vulkan, ValidateVersion,
+ ::testing::Values(
+ // Binary version, Target environment
+ make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_UNIVERSAL_1_0, vulkan_spirv, true),
+ make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_UNIVERSAL_1_1, vulkan_spirv, true),
+ make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_UNIVERSAL_1_2, vulkan_spirv, true),
+ make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_UNIVERSAL_1_3, vulkan_spirv, true),
+ make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_0, vulkan_spirv, true),
+ make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1, vulkan_spirv, true),
+ make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_OPENGL_4_0, vulkan_spirv, true),
+ make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_OPENGL_4_1, vulkan_spirv, true),
+ make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_OPENGL_4_2, vulkan_spirv, true),
+ make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_OPENGL_4_3, vulkan_spirv, true),
+ make_tuple(SPV_ENV_VULKAN_1_0, SPV_ENV_OPENGL_4_5, vulkan_spirv, true),
+
+ make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_UNIVERSAL_1_0, vulkan_spirv, false),
+ make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_UNIVERSAL_1_1, vulkan_spirv, false),
+ make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_UNIVERSAL_1_2, vulkan_spirv, false),
+ make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_UNIVERSAL_1_3, vulkan_spirv, true),
+ make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_0, vulkan_spirv, false),
+ make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_1, vulkan_spirv, true),
+ make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_OPENGL_4_0, vulkan_spirv, false),
+ make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_OPENGL_4_1, vulkan_spirv, false),
+ make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_OPENGL_4_2, vulkan_spirv, false),
+ make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_OPENGL_4_3, vulkan_spirv, false),
+ make_tuple(SPV_ENV_VULKAN_1_1, SPV_ENV_OPENGL_4_5, vulkan_spirv, false)
+ )
+);
+
+INSTANTIATE_TEST_CASE_P(OpenCL, ValidateVersion,
+ ::testing::Values(
+ // Binary version, Target environment
+ make_tuple(SPV_ENV_OPENCL_2_0, SPV_ENV_UNIVERSAL_1_0, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_0, SPV_ENV_UNIVERSAL_1_1, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_0, SPV_ENV_UNIVERSAL_1_2, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_0, SPV_ENV_UNIVERSAL_1_3, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_0, SPV_ENV_OPENCL_2_0, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_0, SPV_ENV_OPENCL_2_1, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_0, SPV_ENV_OPENCL_2_2, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_0, SPV_ENV_OPENCL_EMBEDDED_2_0, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_0, SPV_ENV_OPENCL_EMBEDDED_2_1, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_0, SPV_ENV_OPENCL_EMBEDDED_2_2, opencl_spirv, true),
+
+ make_tuple(SPV_ENV_OPENCL_2_1, SPV_ENV_UNIVERSAL_1_0, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_1, SPV_ENV_UNIVERSAL_1_1, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_1, SPV_ENV_UNIVERSAL_1_2, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_1, SPV_ENV_UNIVERSAL_1_3, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_1, SPV_ENV_OPENCL_2_0, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_1, SPV_ENV_OPENCL_2_1, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_1, SPV_ENV_OPENCL_2_2, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_1, SPV_ENV_OPENCL_EMBEDDED_2_0, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_1, SPV_ENV_OPENCL_EMBEDDED_2_1, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_1, SPV_ENV_OPENCL_EMBEDDED_2_2, opencl_spirv, true),
+
+ make_tuple(SPV_ENV_OPENCL_2_2, SPV_ENV_UNIVERSAL_1_0, opencl_spirv, false),
+ make_tuple(SPV_ENV_OPENCL_2_2, SPV_ENV_UNIVERSAL_1_1, opencl_spirv, false),
+ make_tuple(SPV_ENV_OPENCL_2_2, SPV_ENV_UNIVERSAL_1_2, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_2, SPV_ENV_UNIVERSAL_1_3, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_2, SPV_ENV_OPENCL_2_0, opencl_spirv, false),
+ make_tuple(SPV_ENV_OPENCL_2_2, SPV_ENV_OPENCL_2_1, opencl_spirv, false),
+ make_tuple(SPV_ENV_OPENCL_2_2, SPV_ENV_OPENCL_2_2, opencl_spirv, true),
+ make_tuple(SPV_ENV_OPENCL_2_2, SPV_ENV_OPENCL_EMBEDDED_2_0, opencl_spirv, false),
+ make_tuple(SPV_ENV_OPENCL_2_2, SPV_ENV_OPENCL_EMBEDDED_2_1, opencl_spirv, false),
+ make_tuple(SPV_ENV_OPENCL_2_2, SPV_ENV_OPENCL_EMBEDDED_2_2, opencl_spirv, true)
+ )
+);
+// clang-format on