From 1c11c8690f6b8dd3a396447bca8a180e468156a7 Mon Sep 17 00:00:00 2001 From: Ehsan Nasiri Date: Mon, 9 Jan 2017 11:10:52 -0500 Subject: [PATCH] Validation of OpEntryPoint usage. According to the SPIRV Spec (2.16.1): * There is at least one OpEntryPoint instruction, unless the Linkage capability is being used. * No function can be targeted by both an OpEntryPoint instruction and an OpFunctionCall instruction. Also updated unit tests to includ OpEntryPoint. --- source/val/validation_state.h | 13 + source/validate.cpp | 27 ++- test/c_interface_test.cpp | 4 +- test/cpp_interface_test.cpp | 12 +- test/val/val_capability_test.cpp | 501 +++++++++++++++++++++++++++++---------- test/val/val_cfg_test.cpp | 6 +- test/val/val_data_test.cpp | 9 + test/val/val_id_test.cpp | 1 + test/val/val_layout_test.cpp | 64 ++++- test/val/val_limits_test.cpp | 5 +- test/val/val_ssa_test.cpp | 28 +++ test/val/val_storage_test.cpp | 6 + 12 files changed, 538 insertions(+), 138 deletions(-) diff --git a/source/val/validation_state.h b/source/val/validation_state.h index 5abf9c3..a4a4140 100644 --- a/source/val/validation_state.h +++ b/source/val/validation_state.h @@ -129,6 +129,16 @@ class ValidationState_t { std::vector& entry_points() { return entry_points_; } const std::vector& entry_points() const { return entry_points_; } + /// Inserts an to the set of functions that are target of OpFunctionCall. + void AddFunctionCallTarget(const uint32_t id) { + function_call_targets_.insert(id); + } + + /// Returns whether or not a function is the target of OpFunctionCall. + bool IsFunctionCallTarget(const uint32_t id) { + return (function_call_targets_.find(id) != function_call_targets_.end()); + } + /// Registers the capability and its dependent capabilities void RegisterCapability(SpvCapability cap); @@ -255,6 +265,9 @@ class ValidationState_t { /// IDs that are entry points, ie, arguments to OpEntryPoint. std::vector entry_points_; + /// Functions IDs that are target of OpFunctionCall. + std::unordered_set function_call_targets_; + /// ID Bound from the Header uint32_t id_bound_; diff --git a/source/validate.cpp b/source/validate.cpp index fe6c4c4..c3a7c9e 100644 --- a/source/validate.cpp +++ b/source/validate.cpp @@ -120,8 +120,12 @@ spv_result_t ProcessInstruction(void* user_data, const spv_parsed_instruction_t* inst) { ValidationState_t& _ = *(reinterpret_cast(user_data)); _.increment_instruction_count(); - if (static_cast(inst->opcode) == SpvOpEntryPoint) + if (static_cast(inst->opcode) == SpvOpEntryPoint) { _.entry_points().push_back(inst->words[2]); + } + if (static_cast(inst->opcode) == SpvOpFunctionCall) { + _.AddFunctionCallTarget(inst->words[3]); + } DebugInstructionPass(_, inst); if (auto error = DataRulesPass(_, inst)) return error; @@ -235,6 +239,27 @@ spv_result_t ValidateBinaryUsingContextAndValidationState( if (auto error = UpdateIdUse(*vstate)) return error; if (auto error = CheckIdDefinitionDominateUse(*vstate)) return error; + // Entry point validation. Based on 2.16.1 (Universal Validation Rules) of the + // SPIRV spec: + // * There is at least one OpEntryPoint instruction, unless the Linkage + // capability is being used. + // * No function can be targeted by both an OpEntryPoint instruction and an + // OpFunctionCall instruction. + if (vstate->entry_points().empty() && + !vstate->HasCapability(SpvCapabilityLinkage)) { + return vstate->diag(SPV_ERROR_INVALID_BINARY) + << "No OpEntryPoint instruction was found. This is only allowed if " + "the Linkage capability is being used."; + } + for (const auto& entry_point : vstate->entry_points()) { + if (vstate->IsFunctionCallTarget(entry_point)) { + return vstate->diag(SPV_ERROR_INVALID_BINARY) + << "A function (" << entry_point + << ") may not be targeted by both an OpEntryPoint instruction and " + "an OpFunctionCall instruction."; + } + } + // NOTE: Copy each instruction for easier processing std::vector instructions; uint64_t index = SPV_INDEX_INSTRUCTION; diff --git a/test/c_interface_test.cpp b/test/c_interface_test.cpp index 6defbec..168ff13 100644 --- a/test/c_interface_test.cpp +++ b/test/c_interface_test.cpp @@ -26,7 +26,9 @@ using namespace spvtools; TEST(CInterface, DefaultConsumerNullDiagnosticForValidInput) { auto context = spvContextCreate(SPV_ENV_UNIVERSAL_1_1); const char input_text[] = - "OpCapability Shader\nOpMemoryModel Logical GLSL450"; + "OpCapability Shader\n" + "OpCapability Linkage\n" + "OpMemoryModel Logical GLSL450"; spv_binary binary = nullptr; EXPECT_EQ(SPV_SUCCESS, spvTextToBinary(context, input_text, diff --git a/test/cpp_interface_test.cpp b/test/cpp_interface_test.cpp index e492a63..307ee93 100644 --- a/test/cpp_interface_test.cpp +++ b/test/cpp_interface_test.cpp @@ -173,8 +173,10 @@ TEST(CppInterface, DisassembleWithWrongTargetEnv) { } TEST(CppInterface, SuccessfulValidation) { - const std::string input_text = - "OpCapability Shader\nOpMemoryModel Logical GLSL450"; + const std::string input_text = R"( + OpCapability Shader + OpCapability Linkage + OpMemoryModel Logical GLSL450)"; SpirvTools t(SPV_ENV_UNIVERSAL_1_1); int invocation_count = 0; t.SetMessageConsumer([&invocation_count](spv_message_level_t, const char*, @@ -189,8 +191,10 @@ TEST(CppInterface, SuccessfulValidation) { } TEST(CppInterface, ValidateOverloads) { - const std::string input_text = - "OpCapability Shader\nOpMemoryModel Logical GLSL450"; + const std::string input_text = R"( + OpCapability Shader + OpCapability Linkage + OpMemoryModel Logical GLSL450)"; SpirvTools t(SPV_ENV_UNIVERSAL_1_1); std::vector binary; EXPECT_TRUE(t.Assemble(input_text, &binary)); diff --git a/test/val/val_capability_test.cpp b/test/val/val_capability_test.cpp index 2604187..65345d6 100644 --- a/test/val/val_capability_test.cpp +++ b/test/val/val_capability_test.cpp @@ -112,6 +112,7 @@ using ValidateCapabilityOpenGL40 = spvtest::ValidateBase; TEST_F(ValidateCapability, Default) { const char str[] = R"( OpCapability Kernel + OpCapability Linkage OpCapability Matrix OpMemoryModel Logical OpenCL %f32 = OpTypeFloat 32 @@ -449,23 +450,41 @@ INSTANTIATE_TEST_CASE_P(AddressingAndMemoryModel, ValidateCapability, ValuesIn(AllCapabilities()), Values( make_pair(" OpCapability Shader" - " OpMemoryModel Logical Simple", AllCapabilities()), + " OpMemoryModel Logical Simple" + " OpEntryPoint Vertex %func \"shader\"" + + string(kVoidFVoid), AllCapabilities()), make_pair(" OpCapability Shader" - " OpMemoryModel Logical GLSL450", AllCapabilities()), + " OpMemoryModel Logical GLSL450" + " OpEntryPoint Vertex %func \"shader\"" + + string(kVoidFVoid), AllCapabilities()), make_pair(" OpCapability Kernel" - " OpMemoryModel Logical OpenCL", AllCapabilities()), + " OpMemoryModel Logical OpenCL" + " OpEntryPoint Kernel %func \"compute\"" + + string(kVoidFVoid), AllCapabilities()), make_pair(" OpCapability Shader" - " OpMemoryModel Physical32 Simple", AddressesDependencies()), + " OpMemoryModel Physical32 Simple" + " OpEntryPoint Vertex %func \"shader\"" + + string(kVoidFVoid), AddressesDependencies()), make_pair(" OpCapability Shader" - " OpMemoryModel Physical32 GLSL450", AddressesDependencies()), + " OpMemoryModel Physical32 GLSL450" + " OpEntryPoint Vertex %func \"shader\"" + + string(kVoidFVoid), AddressesDependencies()), make_pair(" OpCapability Kernel" - " OpMemoryModel Physical32 OpenCL", AddressesDependencies()), + " OpMemoryModel Physical32 OpenCL" + " OpEntryPoint Kernel %func \"compute\"" + + string(kVoidFVoid), AddressesDependencies()), make_pair(" OpCapability Shader" - " OpMemoryModel Physical64 Simple", AddressesDependencies()), + " OpMemoryModel Physical64 Simple" + " OpEntryPoint Vertex %func \"shader\"" + + string(kVoidFVoid), AddressesDependencies()), make_pair(" OpCapability Shader" - " OpMemoryModel Physical64 GLSL450", AddressesDependencies()), + " OpMemoryModel Physical64 GLSL450" + " OpEntryPoint Vertex %func \"shader\"" + + string(kVoidFVoid), AddressesDependencies()), make_pair(" OpCapability Kernel" - " OpMemoryModel Physical64 OpenCL", AddressesDependencies()) + " OpMemoryModel Physical64 OpenCL" + " OpEntryPoint Kernel %func \"compute\"" + + string(kVoidFVoid), AddressesDependencies()) )),); INSTANTIATE_TEST_CASE_P(ExecutionMode, ValidateCapability, @@ -628,45 +647,65 @@ INSTANTIATE_TEST_CASE_P(StorageClass, ValidateCapability, ValuesIn(AllCapabilities()), Values( make_pair(string(kGLSL450MemoryModel) + + " OpEntryPoint Vertex %func \"shader\"" + " %intt = OpTypeInt 32 0\n" " %ptrt = OpTypePointer UniformConstant %intt\n" - " %var = OpVariable %ptrt UniformConstant\n", AllCapabilities()), + " %var = OpVariable %ptrt UniformConstant\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + " OpEntryPoint Kernel %func \"compute\"" + " %intt = OpTypeInt 32 0\n" " %ptrt = OpTypePointer Input %intt" - " %var = OpVariable %ptrt Input\n", AllCapabilities()), + " %var = OpVariable %ptrt Input\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + " OpEntryPoint Vertex %func \"shader\"" + " %intt = OpTypeInt 32 0\n" " %ptrt = OpTypePointer Uniform %intt\n" - " %var = OpVariable %ptrt Uniform\n", ShaderDependencies()), + " %var = OpVariable %ptrt Uniform\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + " OpEntryPoint Vertex %func \"shader\"" + " %intt = OpTypeInt 32 0\n" " %ptrt = OpTypePointer Output %intt\n" - " %var = OpVariable %ptrt Output\n", ShaderDependencies()), + " %var = OpVariable %ptrt Output\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kGLSL450MemoryModel) + + " OpEntryPoint Vertex %func \"shader\"" + " %intt = OpTypeInt 32 0\n" " %ptrt = OpTypePointer Workgroup %intt\n" - " %var = OpVariable %ptrt Workgroup\n", AllCapabilities()), + " %var = OpVariable %ptrt Workgroup\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kGLSL450MemoryModel) + + " OpEntryPoint Vertex %func \"shader\"" + " %intt = OpTypeInt 32 0\n" " %ptrt = OpTypePointer CrossWorkgroup %intt\n" - " %var = OpVariable %ptrt CrossWorkgroup\n", AllCapabilities()), + " %var = OpVariable %ptrt CrossWorkgroup\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + " OpEntryPoint Kernel %func \"compute\"" + " %intt = OpTypeInt 32 0\n" " %ptrt = OpTypePointer Private %intt\n" - " %var = OpVariable %ptrt Private\n", ShaderDependencies()), + " %var = OpVariable %ptrt Private\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + " OpEntryPoint Kernel %func \"compute\"" + " %intt = OpTypeInt 32 0\n" " %ptrt = OpTypePointer PushConstant %intt\n" - " %var = OpVariable %ptrt PushConstant\n", ShaderDependencies()), + " %var = OpVariable %ptrt PushConstant\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kGLSL450MemoryModel) + + " OpEntryPoint Vertex %func \"shader\"" + " %intt = OpTypeInt 32 0\n" " %ptrt = OpTypePointer AtomicCounter %intt\n" - " %var = OpVariable %ptrt AtomicCounter\n", vector{"AtomicStorage"}), + " %var = OpVariable %ptrt AtomicCounter\n" + string(kVoidFVoid), + vector{"AtomicStorage"}), make_pair(string(kGLSL450MemoryModel) + + " OpEntryPoint Vertex %func \"shader\"" + " %intt = OpTypeInt 32 0\n" " %ptrt = OpTypePointer Image %intt\n" - " %var = OpVariable %ptrt Image\n", AllCapabilities()) + " %var = OpVariable %ptrt Image\n" + string(kVoidFVoid), + AllCapabilities()) )),); INSTANTIATE_TEST_CASE_P(Dim, ValidateCapability, @@ -675,38 +714,45 @@ INSTANTIATE_TEST_CASE_P(Dim, ValidateCapability, Values( make_pair(" OpCapability ImageBasic" + string(kOpenCLMemoryModel) + + string(" OpEntryPoint Kernel %func \"compute\"") + " %voidt = OpTypeVoid" - " %imgt = OpTypeImage %voidt 1D 0 0 0 0 Unknown", + " %imgt = OpTypeImage %voidt 1D 0 0 0 0 Unknown" + string(kVoidFVoid), Sampled1DDependencies()), make_pair(" OpCapability ImageBasic" + string(kOpenCLMemoryModel) + + string(" OpEntryPoint Kernel %func \"compute\"") + " %voidt = OpTypeVoid" - " %imgt = OpTypeImage %voidt 2D 0 0 0 0 Unknown", + " %imgt = OpTypeImage %voidt 2D 0 0 0 0 Unknown" + string(kVoidFVoid), AllCapabilities()), make_pair(" OpCapability ImageBasic" + string(kOpenCLMemoryModel) + + string(" OpEntryPoint Kernel %func \"compute\"") + " %voidt = OpTypeVoid" - " %imgt = OpTypeImage %voidt 3D 0 0 0 0 Unknown", + " %imgt = OpTypeImage %voidt 3D 0 0 0 0 Unknown" + string(kVoidFVoid), AllCapabilities()), make_pair(" OpCapability ImageBasic" + string(kOpenCLMemoryModel) + + string(" OpEntryPoint Kernel %func \"compute\"") + " %voidt = OpTypeVoid" - " %imgt = OpTypeImage %voidt Cube 0 0 0 0 Unknown", + " %imgt = OpTypeImage %voidt Cube 0 0 0 0 Unknown" + string(kVoidFVoid), ShaderDependencies()), make_pair(" OpCapability ImageBasic" + string(kOpenCLMemoryModel) + + string(" OpEntryPoint Kernel %func \"compute\"") + " %voidt = OpTypeVoid" - " %imgt = OpTypeImage %voidt Rect 0 0 0 0 Unknown", + " %imgt = OpTypeImage %voidt Rect 0 0 0 0 Unknown" + string(kVoidFVoid), SampledRectDependencies()), make_pair(" OpCapability ImageBasic" + string(kOpenCLMemoryModel) + + string(" OpEntryPoint Kernel %func \"compute\"") + " %voidt = OpTypeVoid" - " %imgt = OpTypeImage %voidt Buffer 0 0 0 0 Unknown", + " %imgt = OpTypeImage %voidt Buffer 0 0 0 0 Unknown" + string(kVoidFVoid), SampledBufferDependencies()), make_pair(" OpCapability ImageBasic" + string(kOpenCLMemoryModel) + + string(" OpEntryPoint Kernel %func \"compute\"") + " %voidt = OpTypeVoid" - " %imgt = OpTypeImage %voidt SubpassData 0 0 0 2 Unknown", + " %imgt = OpTypeImage %voidt SubpassData 0 0 0 2 Unknown" + string(kVoidFVoid), vector{"InputAttachment"}) )),); @@ -717,24 +763,34 @@ INSTANTIATE_TEST_CASE_P(SamplerAddressingMode, ValidateCapability, ValuesIn(AllCapabilities()), Values( make_pair(string(kGLSL450MemoryModel) + + " OpEntryPoint Vertex %func \"shader\"" " %samplert = OpTypeSampler" - " %sampler = OpConstantSampler %samplert None 1 Nearest", + " %sampler = OpConstantSampler %samplert None 1 Nearest" + + string(kVoidFVoid), vector{"LiteralSampler"}), make_pair(string(kGLSL450MemoryModel) + + " OpEntryPoint Vertex %func \"shader\"" " %samplert = OpTypeSampler" - " %sampler = OpConstantSampler %samplert ClampToEdge 1 Nearest", + " %sampler = OpConstantSampler %samplert ClampToEdge 1 Nearest" + + string(kVoidFVoid), vector{"LiteralSampler"}), make_pair(string(kGLSL450MemoryModel) + + " OpEntryPoint Vertex %func \"shader\"" " %samplert = OpTypeSampler" - " %sampler = OpConstantSampler %samplert Clamp 1 Nearest", + " %sampler = OpConstantSampler %samplert Clamp 1 Nearest" + + string(kVoidFVoid), vector{"LiteralSampler"}), make_pair(string(kGLSL450MemoryModel) + + " OpEntryPoint Vertex %func \"shader\"" " %samplert = OpTypeSampler" - " %sampler = OpConstantSampler %samplert Repeat 1 Nearest", + " %sampler = OpConstantSampler %samplert Repeat 1 Nearest" + + string(kVoidFVoid), vector{"LiteralSampler"}), make_pair(string(kGLSL450MemoryModel) + + " OpEntryPoint Vertex %func \"shader\"" " %samplert = OpTypeSampler" - " %sampler = OpConstantSampler %samplert RepeatMirrored 1 Nearest", + " %sampler = OpConstantSampler %samplert RepeatMirrored 1 Nearest" + + string(kVoidFVoid), vector{"LiteralSampler"}) )),); @@ -754,128 +810,210 @@ INSTANTIATE_TEST_CASE_P(Decoration, ValidateCapability, ValuesIn(AllCapabilities()), Values( make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt RelaxedPrecision\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Block\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt BufferBlock\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt RowMajor\n" - "%intt = OpTypeInt 32 1\n", MatrixDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + MatrixDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt ColMajor\n" - "%intt = OpTypeInt 32 1\n", MatrixDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + MatrixDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt ArrayStride 1\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt MatrixStride 1\n" - "%intt = OpTypeInt 32 1\n", MatrixDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + MatrixDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt GLSLShared\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt GLSLPacked\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" "OpDecorate %intt CPacked\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt NoPerspective\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Flat\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Patch\n" - "%intt = OpTypeInt 32 1\n", TessellationDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + TessellationDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Centroid\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Sample\n" - "%intt = OpTypeInt 32 1\n", vector{"SampleRateShading"}), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + vector{"SampleRateShading"}), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Invariant\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Restrict\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Aliased\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Volatile\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" "OpDecorate %intt Constant\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Coherent\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt NonWritable\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt NonReadable\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Uniform\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" "OpDecorate %intt SaturatedConversion\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Stream 0\n" - "%intt = OpTypeInt 32 1\n", vector{"GeometryStreams"}), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + vector{"GeometryStreams"}), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Location 0\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Component 0\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Index 0\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Binding 0\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt DescriptorSet 0\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt Offset 0\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt XfbBuffer 0\n" - "%intt = OpTypeInt 32 1\n", vector{"TransformFeedback"}), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + vector{"TransformFeedback"}), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt XfbStride 0\n" - "%intt = OpTypeInt 32 1\n", vector{"TransformFeedback"}), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + vector{"TransformFeedback"}), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" "OpDecorate %intt FuncParamAttr Zext\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" "OpDecorate %intt FPRoundingMode RTE\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" "OpDecorate %intt FPFastMathMode Fast\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt LinkageAttributes \"other\" Import\n" - "%intt = OpTypeInt 32 1\n", vector{"Linkage"}), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + vector{"Linkage"}), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt NoContraction\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt InputAttachmentIndex 0\n" - "%intt = OpTypeInt 32 1\n", vector{"InputAttachment"}), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + vector{"InputAttachment"}), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" "OpDecorate %intt Alignment 4\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()) + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()) )),); // clang-format on @@ -883,29 +1021,36 @@ INSTANTIATE_TEST_CASE_P( DecorationSpecId, ValidateCapability, Combine(ValuesIn(AllV10Capabilities()), Values(make_pair(string(kOpenCLMemoryModel) + - "OpDecorate %intt SpecId 1\n" - "%intt = OpTypeInt 32 1\n", + "OpEntryPoint Vertex %func \"shader\" \n" + + "OpDecorate %intt SpecId 1\n" + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), ShaderDependencies()))), ); INSTANTIATE_TEST_CASE_P( DecorationV11, ValidateCapabilityV11, Combine(ValuesIn(AllCapabilities()), Values(make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %p MaxByteOffset 0 " "%i32 = OpTypeInt 32 1 " "%pi32 = OpTypePointer Workgroup %i32 " - "%p = OpVariable %pi32 Workgroup ", + "%p = OpVariable %pi32 Workgroup " + + string(kVoidFVoid), AddressesDependencies()), // Trying to test OpDecorate here, but if this fails due to // incorrect OpMemoryModel validation, that must also be // fixed. make_pair(string("OpMemoryModel Logical OpenCL " + "OpEntryPoint Kernel %func \"compute\" \n" "OpDecorate %intt SpecId 1 " - "%intt = OpTypeInt 32 1 "), + "%intt = OpTypeInt 32 1 ") + + string(kVoidFVoid), KernelDependencies()), make_pair(string("OpMemoryModel Logical Simple " + "OpEntryPoint Vertex %func \"shader\" \n" "OpDecorate %intt SpecId 1 " - "%intt = OpTypeInt 32 1 "), + "%intt = OpTypeInt 32 1 ") + + string(kVoidFVoid), ShaderDependencies()))), ); // clang-format off @@ -914,137 +1059,223 @@ INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapability, ValuesIn(AllCapabilities()), Values( make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn Position\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), // Just mentioning PointSize, ClipDistance, or CullDistance as a BuiltIn does // not trigger the requirement for the associated capability. // See https://github.com/KhronosGroup/SPIRV-Tools/issues/365 make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn PointSize\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn ClipDistance\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn CullDistance\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn VertexId\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn InstanceId\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn PrimitiveId\n" - "%intt = OpTypeInt 32 1\n", GeometryTessellationDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + GeometryTessellationDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn InvocationId\n" - "%intt = OpTypeInt 32 1\n", GeometryTessellationDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + GeometryTessellationDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn Layer\n" - "%intt = OpTypeInt 32 1\n", GeometryDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + GeometryDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn ViewportIndex\n" - "%intt = OpTypeInt 32 1\n", vector{"MultiViewport"}), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + vector{"MultiViewport"}), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn TessLevelOuter\n" - "%intt = OpTypeInt 32 1\n", TessellationDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + TessellationDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn TessLevelInner\n" - "%intt = OpTypeInt 32 1\n", TessellationDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + TessellationDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn TessCoord\n" - "%intt = OpTypeInt 32 1\n", TessellationDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + TessellationDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn PatchVertices\n" - "%intt = OpTypeInt 32 1\n", TessellationDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + TessellationDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn FragCoord\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn PointCoord\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn FrontFacing\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn SampleId\n" - "%intt = OpTypeInt 32 1\n", vector{"SampleRateShading"}), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + vector{"SampleRateShading"}), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn SamplePosition\n" - "%intt = OpTypeInt 32 1\n", vector{"SampleRateShading"}), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + vector{"SampleRateShading"}), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn SampleMask\n" - "%intt = OpTypeInt 32 1\n", vector{"SampleRateShading"}), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + vector{"SampleRateShading"}), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn FragDepth\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn HelperInvocation\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn VertexIndex\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn InstanceIndex\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn NumWorkgroups\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn WorkgroupSize\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn WorkgroupId\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn LocalInvocationId\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn GlobalInvocationId\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn LocalInvocationIndex\n" - "%intt = OpTypeInt 32 1\n", AllCapabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllCapabilities()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn WorkDim\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn GlobalSize\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn EnqueuedWorkgroupSize\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn GlobalOffset\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn GlobalLinearId\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn SubgroupSize\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn SubgroupMaxSize\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn NumSubgroups\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn NumEnqueuedSubgroups\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn SubgroupId\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn SubgroupLocalInvocationId\n" - "%intt = OpTypeInt 32 1\n", KernelDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + KernelDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn VertexIndex\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()), make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "OpDecorate %intt BuiltIn InstanceIndex\n" - "%intt = OpTypeInt 32 1\n", ShaderDependencies()) + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + ShaderDependencies()) )),); // Ensure that mere mention of PointSize, ClipDistance, or CullDistance as @@ -1057,14 +1288,20 @@ INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapabilityVulkan10, ValuesIn(AllV10Capabilities()), Values( make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn PointSize\n" - "%intt = OpTypeInt 32 1\n", AllV10Capabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllV10Capabilities()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn ClipDistance\n" - "%intt = OpTypeInt 32 1\n", AllV10Capabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllV10Capabilities()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn CullDistance\n" - "%intt = OpTypeInt 32 1\n", AllV10Capabilities()) + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllV10Capabilities()) )),); INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapabilityOpenGL40, @@ -1073,14 +1310,20 @@ INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapabilityOpenGL40, ValuesIn(AllV10Capabilities()), Values( make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn PointSize\n" - "%intt = OpTypeInt 32 1\n", AllV10Capabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllV10Capabilities()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn ClipDistance\n" - "%intt = OpTypeInt 32 1\n", AllV10Capabilities()), + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllV10Capabilities()), make_pair(string(kGLSL450MemoryModel) + + "OpEntryPoint Vertex %func \"shader\" \n" + "OpDecorate %intt BuiltIn CullDistance\n" - "%intt = OpTypeInt 32 1\n", AllV10Capabilities()) + "%intt = OpTypeInt 32 1\n" + string(kVoidFVoid), + AllV10Capabilities()) )),); // TODO(umar): Selection Control @@ -1098,9 +1341,11 @@ INSTANTIATE_TEST_CASE_P(MatrixOp, ValidateCapability, ValuesIn(AllCapabilities()), Values( make_pair(string(kOpenCLMemoryModel) + + "OpEntryPoint Kernel %func \"compute\" \n" + "%f32 = OpTypeFloat 32\n" "%vec3 = OpTypeVector %f32 3\n" - "%mat33 = OpTypeMatrix %vec3 3\n", MatrixDependencies()))),); + "%mat33 = OpTypeMatrix %vec3 3\n" + string(kVoidFVoid), + MatrixDependencies()))),); // clang-format on // Creates assembly containing an OpImageFetch instruction using operands for @@ -1112,6 +1357,7 @@ string ImageOperandsTemplate(const string& operands) { // clang-format off ss << R"( OpCapability Kernel +OpCapability Linkage OpMemoryModel Logical OpenCL %i32 = OpTypeInt 32 1 @@ -1205,6 +1451,7 @@ TEST_F(ValidateCapability, SemanticsIdIsAnIdNotALiteral) { // capability. const char str[] = R"( OpCapability Kernel +OpCapability Linkage OpMemoryModel Logical OpenCL ; %i32 has ID 1 diff --git a/test/val/val_cfg_test.cpp b/test/val/val_cfg_test.cpp index 81c8274..069d019 100644 --- a/test/val/val_cfg_test.cpp +++ b/test/val/val_cfg_test.cpp @@ -1,4 +1,3 @@ - // Copyright (c) 2015-2016 The Khronos Group Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -156,10 +155,12 @@ Block& operator>>(Block& lhs, Block& successor) { const char* header(SpvCapability cap) { static const char* shader_header = "OpCapability Shader\n" + "OpCapability Linkage\n" "OpMemoryModel Logical GLSL450\n"; static const char* kernel_header = "OpCapability Kernel\n" + "OpCapability Linkage\n" "OpMemoryModel Logical OpenCL\n"; return (cap == SpvCapabilityShader) ? shader_header : kernel_header; @@ -194,6 +195,7 @@ TEST_P(ValidateCFG, LoopReachableFromEntryButNeverLeadingToReturn) { // https://github.com/KhronosGroup/SPIRV-Tools/issues/279 string str = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %entry "entry" @@ -231,6 +233,7 @@ TEST_P(ValidateCFG, LoopUnreachableFromEntryButLeadingToReturn) { // post-dominators. string str = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %entry "entry" @@ -1303,6 +1306,7 @@ TEST_P(ValidateCFG, SingleLatchBlockHeaderContinueTargetIsItselfGood) { TEST_F(ValidateCFG, BasicBlockIsEntryBlockOfTwoConstructsGood) { std::string spirv = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 %void = OpTypeVoid %bool = OpTypeBool diff --git a/test/val/val_data_test.cpp b/test/val/val_data_test.cpp index 656abce..82d5d00 100644 --- a/test/val/val_data_test.cpp +++ b/test/val/val_data_test.cpp @@ -33,6 +33,7 @@ using ValidateData = spvtest::ValidateBase>; string header = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 %1 = OpTypeFloat 32 )"; @@ -40,41 +41,49 @@ string header_with_addresses = R"( OpCapability Addresses OpCapability Kernel OpCapability GenericPointer + OpCapability Linkage OpMemoryModel Physical32 OpenCL )"; string header_with_vec16_cap = R"( OpCapability Shader OpCapability Vector16 + OpCapability Linkage OpMemoryModel Logical GLSL450 %1 = OpTypeFloat 32 )"; string header_with_int8 = R"( OpCapability Shader + OpCapability Linkage OpCapability Int8 OpMemoryModel Logical GLSL450 )"; string header_with_int16 = R"( OpCapability Shader + OpCapability Linkage OpCapability Int16 OpMemoryModel Logical GLSL450 )"; string header_with_int64 = R"( OpCapability Shader + OpCapability Linkage OpCapability Int64 OpMemoryModel Logical GLSL450 )"; string header_with_float16 = R"( OpCapability Shader + OpCapability Linkage OpCapability Float16 OpMemoryModel Logical GLSL450 )"; string header_with_float16_buffer = R"( OpCapability Shader + OpCapability Linkage OpCapability Float16Buffer OpMemoryModel Logical GLSL450 )"; string header_with_float64 = R"( OpCapability Shader + OpCapability Linkage OpCapability Float64 OpMemoryModel Logical GLSL450 )"; diff --git a/test/val/val_id_test.cpp b/test/val/val_id_test.cpp index fa58ea5..9d58374 100644 --- a/test/val/val_id_test.cpp +++ b/test/val/val_id_test.cpp @@ -39,6 +39,7 @@ using ValidateIdWithMessage = spvtest::ValidateBase; string kGLSL450MemoryModel = R"( OpCapability Shader + OpCapability Linkage OpCapability Addresses OpCapability Pipes OpCapability LiteralSampler diff --git a/test/val/val_layout_test.cpp b/test/val/val_layout_test.cpp index bc49075..e8b4247 100644 --- a/test/val/val_layout_test.cpp +++ b/test/val/val_layout_test.cpp @@ -35,7 +35,7 @@ using std::tuple; using std::vector; using ::testing::StrEq; - +using ::testing::HasSubstr; using libspirv::spvResultToString; using pred_type = function; @@ -303,6 +303,7 @@ TEST_F(ValidateLayout, FuncParameterNotImmediatlyAfterFuncBad) { TEST_F(ValidateLayout, OpUndefCanAppearInTypeDeclarationSection) { string str = R"( OpCapability Kernel + OpCapability Linkage OpMemoryModel Logical OpenCL %voidt = OpTypeVoid %uintt = OpTypeInt 32 0 @@ -321,6 +322,7 @@ TEST_F(ValidateLayout, OpUndefCanAppearInTypeDeclarationSection) { TEST_F(ValidateLayout, OpUndefCanAppearInBlock) { string str = R"( OpCapability Kernel + OpCapability Linkage OpMemoryModel Logical OpenCL %voidt = OpTypeVoid %uintt = OpTypeInt 32 0 @@ -339,6 +341,7 @@ TEST_F(ValidateLayout, OpUndefCanAppearInBlock) { TEST_F(ValidateLayout, MissingFunctionEndForFunctionWithBody) { const auto s = R"( OpCapability Shader +OpCapability Linkage OpMemoryModel Logical GLSL450 %void = OpTypeVoid %tf = OpTypeFunction %void @@ -356,6 +359,7 @@ OpReturn TEST_F(ValidateLayout, MissingFunctionEndForFunctionPrototype) { const auto s = R"( OpCapability Shader +OpCapability Linkage OpMemoryModel Logical GLSL450 %void = OpTypeVoid %tf = OpTypeFunction %void @@ -373,6 +377,7 @@ using ValidateOpFunctionParameter = spvtest::ValidateBase; TEST_F(ValidateOpFunctionParameter, OpLineBetweenParameters) { const auto s = R"( OpCapability Shader +OpCapability Linkage OpMemoryModel Logical GLSL450 %foo_frag = OpString "foo.frag" %i32 = OpTypeInt 32 1 @@ -394,6 +399,7 @@ OpFunctionEnd TEST_F(ValidateOpFunctionParameter, TooManyParameters) { const auto s = R"( OpCapability Shader +OpCapability Linkage OpMemoryModel Logical GLSL450 %i32 = OpTypeInt 32 1 %tf = OpTypeFunction %i32 %i32 %i32 @@ -413,5 +419,61 @@ OpFunctionEnd CompileSuccessfully(s); ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions()); } + +using ValidateEntryPoint = spvtest::ValidateBase; + +// Tests that not having OpEntryPoint causes an error. +TEST_F(ValidateEntryPoint, NoEntryPointBad) { + std::string spirv = R"( + OpCapability Shader + OpMemoryModel Logical GLSL450)"; + CompileSuccessfully(spirv); + EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions()); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("No OpEntryPoint instruction was found. This is only " + "allowed if the Linkage capability is being used.")); +} + +// Invalid. A function may not be a target of both OpEntryPoint and +// OpFunctionCall. +TEST_F(ValidateEntryPoint, FunctionIsTargetOfEntryPointAndFunctionCallBad) { + std::string spirv = R"( + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %foo "foo" +%voidt = OpTypeVoid +%funct = OpTypeFunction %voidt +%foo = OpFunction %voidt None %funct +%entry = OpLabel +%recurse = OpFunctionCall %voidt %foo + OpReturn + OpFunctionEnd + )"; + CompileSuccessfully(spirv); + EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions()); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("A function (1) may not be targeted by both an OpEntryPoint " + "instruction and an OpFunctionCall instruction.")); +} + +// Valid. Module with a function but no entry point is valid when Linkage +// Capability is used. +TEST_F(ValidateEntryPoint, NoEntryPointWithLinkageCapGood) { + std::string spirv = R"( + OpCapability Shader + OpCapability Linkage + OpMemoryModel Logical GLSL450 +%voidt = OpTypeVoid +%funct = OpTypeFunction %voidt +%foo = OpFunction %voidt None %funct +%entry = OpLabel + OpReturn + OpFunctionEnd + )"; + CompileSuccessfully(spirv); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); +} + // TODO(umar): Test optional instructions } diff --git a/test/val/val_limits_test.cpp b/test/val/val_limits_test.cpp index c402e34..5fd336a 100644 --- a/test/val/val_limits_test.cpp +++ b/test/val/val_limits_test.cpp @@ -32,6 +32,7 @@ using ValidateLimits = spvtest::ValidateBase; string header = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 )"; @@ -392,9 +393,7 @@ TEST_F(ValidateLimits, ControlFlowDepthBad) { // continue target is the loop iteself. It also exercises the case where a loop // is unreachable. TEST_F(ValidateLimits, ControlFlowNoEntryToLoopGood) { - string str = R"( - OpCapability Shader - OpMemoryModel Logical GLSL450 + string str = header + R"( OpName %entry "entry" OpName %loop "loop" OpName %exit "exit" diff --git a/test/val/val_ssa_test.cpp b/test/val/val_ssa_test.cpp index 09bb9bc..affc5a4 100644 --- a/test/val/val_ssa_test.cpp +++ b/test/val/val_ssa_test.cpp @@ -35,6 +35,7 @@ using ValidateSSA = spvtest::ValidateBase>; TEST_F(ValidateSSA, Default) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpEntryPoint GLCompute %3 "" OpExecutionMode %3 LocalSize 1 1 1 @@ -52,6 +53,7 @@ TEST_F(ValidateSSA, Default) { TEST_F(ValidateSSA, IdUndefinedBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %missing "missing" %voidt = OpTypeVoid @@ -69,6 +71,7 @@ TEST_F(ValidateSSA, IdUndefinedBad) { TEST_F(ValidateSSA, IdRedefinedBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %2 "redefined" %1 = OpTypeVoid @@ -85,6 +88,7 @@ TEST_F(ValidateSSA, IdRedefinedBad) { TEST_F(ValidateSSA, DominateUsageBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %1 "not_dominant" %2 = OpTypeFunction %1 ; uses %1 before it's definition @@ -98,6 +102,7 @@ TEST_F(ValidateSSA, DominateUsageBad) { TEST_F(ValidateSSA, DominateUsageWithinBlockBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %bad "bad" %voidt = OpTypeVoid @@ -120,6 +125,7 @@ TEST_F(ValidateSSA, DominateUsageWithinBlockBad) { TEST_F(ValidateSSA, DominateUsageSameInstructionBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %sum "sum" %voidt = OpTypeVoid @@ -141,6 +147,7 @@ TEST_F(ValidateSSA, DominateUsageSameInstructionBad) { TEST_F(ValidateSSA, ForwardNameGood) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %3 "main" %1 = OpTypeVoid @@ -157,6 +164,7 @@ TEST_F(ValidateSSA, ForwardNameGood) { TEST_F(ValidateSSA, ForwardNameMissingTargetBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %5 "main" ; Target never defined )"; @@ -168,6 +176,7 @@ TEST_F(ValidateSSA, ForwardNameMissingTargetBad) { TEST_F(ValidateSSA, ForwardMemberNameGood) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpMemberName %struct 0 "value" OpMemberName %struct 1 "size" @@ -182,6 +191,7 @@ TEST_F(ValidateSSA, ForwardMemberNameGood) { TEST_F(ValidateSSA, ForwardMemberNameMissingTargetBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpMemberName %struct 0 "value" OpMemberName %bad 1 "size" ; Target is not defined @@ -197,6 +207,7 @@ TEST_F(ValidateSSA, ForwardMemberNameMissingTargetBad) { TEST_F(ValidateSSA, ForwardDecorateGood) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %var Restrict %intt = OpTypeInt 32 1 @@ -210,6 +221,7 @@ TEST_F(ValidateSSA, ForwardDecorateGood) { TEST_F(ValidateSSA, ForwardDecorateInvalidIDBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %missing "missing" OpDecorate %missing Restrict ;Missing ID @@ -231,6 +243,7 @@ TEST_F(ValidateSSA, ForwardDecorateInvalidIDBad) { TEST_F(ValidateSSA, ForwardMemberDecorateGood) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpMemberDecorate %struct 1 RowMajor %intt = OpTypeInt 32 1 @@ -246,6 +259,7 @@ TEST_F(ValidateSSA, ForwardMemberDecorateGood) { TEST_F(ValidateSSA, ForwardMemberDecorateInvalidIdBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %missing "missing" OpMemberDecorate %missing 1 RowMajor ; Target not defined @@ -263,6 +277,7 @@ TEST_F(ValidateSSA, ForwardMemberDecorateInvalidIdBad) { TEST_F(ValidateSSA, ForwardGroupDecorateGood) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpDecorate %dgrp RowMajor %dgrp = OpDecorationGroup @@ -280,6 +295,7 @@ TEST_F(ValidateSSA, ForwardGroupDecorateGood) { TEST_F(ValidateSSA, ForwardGroupDecorateMissingGroupBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %missing "missing" OpDecorate %dgrp RowMajor @@ -299,6 +315,7 @@ TEST_F(ValidateSSA, ForwardGroupDecorateMissingGroupBad) { TEST_F(ValidateSSA, ForwardGroupDecorateMissingTargetBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %missing "missing" OpDecorate %dgrp RowMajor @@ -318,6 +335,7 @@ TEST_F(ValidateSSA, ForwardGroupDecorateMissingTargetBad) { TEST_F(ValidateSSA, ForwardGroupDecorateDecorationGroupDominateBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %dgrp "group" OpDecorate %dgrp RowMajor @@ -337,6 +355,7 @@ TEST_F(ValidateSSA, ForwardGroupDecorateDecorationGroupDominateBad) { TEST_F(ValidateSSA, ForwardDecorateInvalidIdBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %missing "missing" OpDecorate %missing Restrict ; Missing target @@ -358,6 +377,7 @@ TEST_F(ValidateSSA, ForwardDecorateInvalidIdBad) { TEST_F(ValidateSSA, FunctionCallGood) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 %1 = OpTypeVoid %2 = OpTypeInt 32 1 @@ -385,6 +405,7 @@ TEST_F(ValidateSSA, FunctionCallGood) { TEST_F(ValidateSSA, ForwardFunctionCallGood) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 %1 = OpTypeVoid %2 = OpTypeInt 32 1 @@ -412,6 +433,7 @@ TEST_F(ValidateSSA, ForwardFunctionCallGood) { TEST_F(ValidateSSA, ForwardBranchConditionalGood) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 %voidt = OpTypeVoid %boolt = OpTypeBool @@ -438,6 +460,7 @@ TEST_F(ValidateSSA, ForwardBranchConditionalGood) { TEST_F(ValidateSSA, ForwardBranchConditionalWithWeightsGood) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 %voidt = OpTypeVoid %boolt = OpTypeBool @@ -464,6 +487,7 @@ TEST_F(ValidateSSA, ForwardBranchConditionalWithWeightsGood) { TEST_F(ValidateSSA, ForwardBranchConditionalNonDominantConditionBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %tcpy "conditional" %voidt = OpTypeVoid @@ -493,6 +517,7 @@ TEST_F(ValidateSSA, ForwardBranchConditionalNonDominantConditionBad) { TEST_F(ValidateSSA, ForwardBranchConditionalMissingTargetBad) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 OpName %missing "missing" %voidt = OpTypeVoid @@ -521,6 +546,7 @@ TEST_F(ValidateSSA, ForwardBranchConditionalMissingTargetBad) { const string kHeader = R"( OpCapability Int8 OpCapability DeviceEnqueue +OpCapability Linkage OpMemoryModel Logical OpenCL )"; @@ -1346,6 +1372,7 @@ TEST_F(ValidateSSA, TypeForwardPointerForwardReference) { string str = R"( OpCapability Kernel OpCapability Addresses + OpCapability Linkage OpMemoryModel Logical OpenCL OpName %intptrt "intptrt" OpTypeForwardPointer %intptrt UniformConstant @@ -1361,6 +1388,7 @@ TEST_F(ValidateSSA, TypeStructForwardReference) { string str = R"( OpCapability Kernel OpCapability Addresses + OpCapability Linkage OpMemoryModel Logical OpenCL OpName %structptr "structptr" OpTypeForwardPointer %structptr UniformConstant diff --git a/test/val/val_storage_test.cpp b/test/val/val_storage_test.cpp index 653429f..d26a860 100644 --- a/test/val/val_storage_test.cpp +++ b/test/val/val_storage_test.cpp @@ -28,6 +28,7 @@ namespace { TEST_F(ValidateStorage, FunctionStorageInsideFunction) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 %intt = OpTypeInt 32 1 %voidt = OpTypeVoid @@ -47,6 +48,7 @@ TEST_F(ValidateStorage, FunctionStorageInsideFunction) { TEST_F(ValidateStorage, FunctionStorageOutsideFunction) { char str[] = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 %intt = OpTypeInt 32 1 %voidt = OpTypeVoid @@ -68,6 +70,7 @@ TEST_F(ValidateStorage, OtherStorageOutsideFunction) { OpCapability Shader OpCapability Kernel OpCapability AtomicStorage + OpCapability Linkage OpMemoryModel Logical GLSL450 %intt = OpTypeInt 32 1 %voidt = OpTypeVoid @@ -100,6 +103,7 @@ TEST_P(ValidateStorage, OtherStorageInsideFunction) { OpCapability Shader OpCapability Kernel OpCapability AtomicStorage + OpCapability Linkage OpMemoryModel Logical GLSL450 %intt = OpTypeInt 32 1 %voidt = OpTypeVoid @@ -132,6 +136,7 @@ INSTANTIATE_TEST_CASE_P(MatrixOp, ValidateStorage, TEST_F(ValidateStorage, GenericVariableOutsideFunction) { const auto str = R"( OpCapability Kernel + OpCapability Linkage OpMemoryModel Logical OpenCL %intt = OpTypeInt 32 1 %ptrt = OpTypePointer Function %intt @@ -144,6 +149,7 @@ TEST_F(ValidateStorage, GenericVariableOutsideFunction) { TEST_F(ValidateStorage, GenericVariableInsideFunction) { const auto str = R"( OpCapability Shader + OpCapability Linkage OpMemoryModel Logical GLSL450 %intt = OpTypeInt 32 1 %voidt = OpTypeVoid -- 2.7.4