Home | History | Annotate | Download | only in val
      1 // Copyright (c) 2015-2016 The Khronos Group Inc.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // Validation tests for Logical Layout
     16 
     17 #include <sstream>
     18 #include <string>
     19 #include <tuple>
     20 #include <utility>
     21 #include <vector>
     22 
     23 #include "gmock/gmock.h"
     24 #include "source/assembly_grammar.h"
     25 #include "source/spirv_target_env.h"
     26 #include "test/test_fixture.h"
     27 #include "test/unit_spirv.h"
     28 #include "test/val/val_fixtures.h"
     29 
     30 namespace spvtools {
     31 namespace val {
     32 namespace {
     33 
     34 using spvtest::ScopedContext;
     35 using testing::Combine;
     36 using testing::HasSubstr;
     37 using testing::Values;
     38 using testing::ValuesIn;
     39 
     40 // Parameter for validation test fixtures.  The first std::string is a
     41 // capability name that will begin the assembly under test, the second the
     42 // remainder assembly, and the std::vector at the end determines whether the
     43 // test expects success or failure.  See below for details and convenience
     44 // methods to access each one.
     45 //
     46 // The assembly to test is composed from a variable top line and a fixed
     47 // remainder.  The top line will be an OpCapability instruction, while the
     48 // remainder will be some assembly text that succeeds or fails to assemble
     49 // depending on which capability was chosen.  For instance, the following will
     50 // succeed:
     51 //
     52 // OpCapability Pipes ; implies Kernel
     53 // OpLifetimeStop %1 0 ; requires Kernel
     54 //
     55 // and the following will fail:
     56 //
     57 // OpCapability Kernel
     58 // %1 = OpTypeNamedBarrier ; requires NamedBarrier
     59 //
     60 // So how does the test parameter capture which capabilities should cause
     61 // success and which shouldn't?  The answer is in the last element: it's a
     62 // std::vector of capabilities that make the remainder assembly succeed.  So if
     63 // the first-line capability exists in that std::vector, success is expected;
     64 // otherwise, failure is expected in the tests.
     65 //
     66 // We will use testing::Combine() to vary the first line: when we combine
     67 // AllCapabilities() with a single remainder assembly, we generate enough test
     68 // cases to try the assembly with every possible capability that could be
     69 // declared. However, Combine() only produces tuples -- it cannot produce, say,
     70 // a struct.  Therefore, this type must be a tuple.
     71 using CapTestParameter =
     72     std::tuple<std::string, std::pair<std::string, std::vector<std::string>>>;
     73 
     74 const std::string& Capability(const CapTestParameter& p) {
     75   return std::get<0>(p);
     76 }
     77 const std::string& Remainder(const CapTestParameter& p) {
     78   return std::get<1>(p).first;
     79 }
     80 const std::vector<std::string>& MustSucceed(const CapTestParameter& p) {
     81   return std::get<1>(p).second;
     82 }
     83 
     84 // Creates assembly to test from p.
     85 std::string MakeAssembly(const CapTestParameter& p) {
     86   std::ostringstream ss;
     87   const std::string& capability = Capability(p);
     88   if (!capability.empty()) {
     89     ss << "OpCapability " << capability << "\n";
     90   }
     91   ss << Remainder(p);
     92   return ss.str();
     93 }
     94 
     95 // Expected validation result for p.
     96 spv_result_t ExpectedResult(const CapTestParameter& p) {
     97   const auto& caps = MustSucceed(p);
     98   auto found = find(begin(caps), end(caps), Capability(p));
     99   return (found == end(caps)) ? SPV_ERROR_INVALID_CAPABILITY : SPV_SUCCESS;
    100 }
    101 
    102 // Assembles using v1.0, unless the parameter's capability requires v1.1.
    103 using ValidateCapability = spvtest::ValidateBase<CapTestParameter>;
    104 
    105 // Always assembles using v1.1.
    106 using ValidateCapabilityV11 = spvtest::ValidateBase<CapTestParameter>;
    107 
    108 // Always assembles using Vulkan 1.0.
    109 // TODO(dneto): Refactor all these tests to scale better across environments.
    110 using ValidateCapabilityVulkan10 = spvtest::ValidateBase<CapTestParameter>;
    111 // Always assembles using OpenGL 4.0.
    112 using ValidateCapabilityOpenGL40 = spvtest::ValidateBase<CapTestParameter>;
    113 // Always assembles using Vulkan 1.1.
    114 using ValidateCapabilityVulkan11 = spvtest::ValidateBase<CapTestParameter>;
    115 // Always assembles using WebGPU.
    116 using ValidateCapabilityWebGPU = spvtest::ValidateBase<CapTestParameter>;
    117 
    118 TEST_F(ValidateCapability, Default) {
    119   const char str[] = R"(
    120             OpCapability Kernel
    121             OpCapability Linkage
    122             OpCapability Matrix
    123             OpMemoryModel Logical OpenCL
    124 %f32      = OpTypeFloat 32
    125 %vec3     = OpTypeVector %f32 3
    126 %mat33    = OpTypeMatrix %vec3 3
    127 )";
    128 
    129   CompileSuccessfully(str);
    130   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
    131 }
    132 
    133 // clang-format off
    134 const std::vector<std::string>& AllCapabilities() {
    135   static const auto r = new std::vector<std::string>{
    136     "",
    137     "Matrix",
    138     "Shader",
    139     "Geometry",
    140     "Tessellation",
    141     "Addresses",
    142     "Linkage",
    143     "Kernel",
    144     "Vector16",
    145     "Float16Buffer",
    146     "Float16",
    147     "Float64",
    148     "Int64",
    149     "Int64Atomics",
    150     "ImageBasic",
    151     "ImageReadWrite",
    152     "ImageMipmap",
    153     "Pipes",
    154     "Groups",
    155     "DeviceEnqueue",
    156     "LiteralSampler",
    157     "AtomicStorage",
    158     "Int16",
    159     "TessellationPointSize",
    160     "GeometryPointSize",
    161     "ImageGatherExtended",
    162     "StorageImageMultisample",
    163     "UniformBufferArrayDynamicIndexing",
    164     "SampledImageArrayDynamicIndexing",
    165     "StorageBufferArrayDynamicIndexing",
    166     "StorageImageArrayDynamicIndexing",
    167     "ClipDistance",
    168     "CullDistance",
    169     "ImageCubeArray",
    170     "SampleRateShading",
    171     "ImageRect",
    172     "SampledRect",
    173     "GenericPointer",
    174     "Int8",
    175     "InputAttachment",
    176     "SparseResidency",
    177     "MinLod",
    178     "Sampled1D",
    179     "Image1D",
    180     "SampledCubeArray",
    181     "SampledBuffer",
    182     "ImageBuffer",
    183     "ImageMSArray",
    184     "StorageImageExtendedFormats",
    185     "ImageQuery",
    186     "DerivativeControl",
    187     "InterpolationFunction",
    188     "TransformFeedback",
    189     "GeometryStreams",
    190     "StorageImageReadWithoutFormat",
    191     "StorageImageWriteWithoutFormat",
    192     "MultiViewport",
    193     "SubgroupDispatch",
    194     "NamedBarrier",
    195     "PipeStorage",
    196     "GroupNonUniform",
    197     "GroupNonUniformVote",
    198     "GroupNonUniformArithmetic",
    199     "GroupNonUniformBallot",
    200     "GroupNonUniformShuffle",
    201     "GroupNonUniformShuffleRelative",
    202     "GroupNonUniformClustered",
    203     "GroupNonUniformQuad",
    204     "DrawParameters",
    205     "StorageBuffer16BitAccess",
    206     "StorageUniformBufferBlock16",
    207     "UniformAndStorageBuffer16BitAccess",
    208     "StorageUniform16",
    209     "StoragePushConstant16",
    210     "StorageInputOutput16",
    211     "DeviceGroup",
    212     "MultiView",
    213     "VariablePointersStorageBuffer",
    214     "VariablePointers"};
    215   return *r;
    216 }
    217 
    218 const std::vector<std::string>& AllSpirV10Capabilities() {
    219   static const auto r = new std::vector<std::string>{
    220     "",
    221     "Matrix",
    222     "Shader",
    223     "Geometry",
    224     "Tessellation",
    225     "Addresses",
    226     "Linkage",
    227     "Kernel",
    228     "Vector16",
    229     "Float16Buffer",
    230     "Float16",
    231     "Float64",
    232     "Int64",
    233     "Int64Atomics",
    234     "ImageBasic",
    235     "ImageReadWrite",
    236     "ImageMipmap",
    237     "Pipes",
    238     "Groups",
    239     "DeviceEnqueue",
    240     "LiteralSampler",
    241     "AtomicStorage",
    242     "Int16",
    243     "TessellationPointSize",
    244     "GeometryPointSize",
    245     "ImageGatherExtended",
    246     "StorageImageMultisample",
    247     "UniformBufferArrayDynamicIndexing",
    248     "SampledImageArrayDynamicIndexing",
    249     "StorageBufferArrayDynamicIndexing",
    250     "StorageImageArrayDynamicIndexing",
    251     "ClipDistance",
    252     "CullDistance",
    253     "ImageCubeArray",
    254     "SampleRateShading",
    255     "ImageRect",
    256     "SampledRect",
    257     "GenericPointer",
    258     "Int8",
    259     "InputAttachment",
    260     "SparseResidency",
    261     "MinLod",
    262     "Sampled1D",
    263     "Image1D",
    264     "SampledCubeArray",
    265     "SampledBuffer",
    266     "ImageBuffer",
    267     "ImageMSArray",
    268     "StorageImageExtendedFormats",
    269     "ImageQuery",
    270     "DerivativeControl",
    271     "InterpolationFunction",
    272     "TransformFeedback",
    273     "GeometryStreams",
    274     "StorageImageReadWithoutFormat",
    275     "StorageImageWriteWithoutFormat",
    276     "MultiViewport"};
    277   return *r;
    278 }
    279 
    280 const std::vector<std::string>& AllVulkan10Capabilities() {
    281   static const auto r = new std::vector<std::string>{
    282     "",
    283     "Matrix",
    284     "Shader",
    285     "InputAttachment",
    286     "Sampled1D",
    287     "Image1D",
    288     "SampledBuffer",
    289     "ImageBuffer",
    290     "ImageQuery",
    291     "DerivativeControl",
    292     "Geometry",
    293     "Tessellation",
    294     "Float16",
    295     "Float64",
    296     "Int64",
    297     "Int64Atomics",
    298     "Int16",
    299     "TessellationPointSize",
    300     "GeometryPointSize",
    301     "ImageGatherExtended",
    302     "StorageImageMultisample",
    303     "UniformBufferArrayDynamicIndexing",
    304     "SampledImageArrayDynamicIndexing",
    305     "StorageBufferArrayDynamicIndexing",
    306     "StorageImageArrayDynamicIndexing",
    307     "ClipDistance",
    308     "CullDistance",
    309     "ImageCubeArray",
    310     "SampleRateShading",
    311     "Int8",
    312     "SparseResidency",
    313     "MinLod",
    314     "SampledCubeArray",
    315     "ImageMSArray",
    316     "StorageImageExtendedFormats",
    317     "InterpolationFunction",
    318     "StorageImageReadWithoutFormat",
    319     "StorageImageWriteWithoutFormat",
    320     "MultiViewport",
    321     "TransformFeedback",
    322     "GeometryStreams"};
    323   return *r;
    324 }
    325 
    326 const std::vector<std::string>& AllVulkan11Capabilities() {
    327   static const auto r = new std::vector<std::string>{
    328     "",
    329     "Matrix",
    330     "Shader",
    331     "InputAttachment",
    332     "Sampled1D",
    333     "Image1D",
    334     "SampledBuffer",
    335     "ImageBuffer",
    336     "ImageQuery",
    337     "DerivativeControl",
    338     "Geometry",
    339     "Tessellation",
    340     "Float16",
    341     "Float64",
    342     "Int64",
    343     "Int64Atomics",
    344     "Int16",
    345     "TessellationPointSize",
    346     "GeometryPointSize",
    347     "ImageGatherExtended",
    348     "StorageImageMultisample",
    349     "UniformBufferArrayDynamicIndexing",
    350     "SampledImageArrayDynamicIndexing",
    351     "StorageBufferArrayDynamicIndexing",
    352     "StorageImageArrayDynamicIndexing",
    353     "ClipDistance",
    354     "CullDistance",
    355     "ImageCubeArray",
    356     "SampleRateShading",
    357     "Int8",
    358     "SparseResidency",
    359     "MinLod",
    360     "SampledCubeArray",
    361     "ImageMSArray",
    362     "StorageImageExtendedFormats",
    363     "InterpolationFunction",
    364     "StorageImageReadWithoutFormat",
    365     "StorageImageWriteWithoutFormat",
    366     "MultiViewport",
    367     "GroupNonUniform",
    368     "GroupNonUniformVote",
    369     "GroupNonUniformArithmetic",
    370     "GroupNonUniformBallot",
    371     "GroupNonUniformShuffle",
    372     "GroupNonUniformShuffleRelative",
    373     "GroupNonUniformClustered",
    374     "GroupNonUniformQuad",
    375     "DrawParameters",
    376     "StorageBuffer16BitAccess",
    377     "StorageUniformBufferBlock16",
    378     "UniformAndStorageBuffer16BitAccess",
    379     "StorageUniform16",
    380     "StoragePushConstant16",
    381     "StorageInputOutput16",
    382     "DeviceGroup",
    383     "MultiView",
    384     "VariablePointersStorageBuffer",
    385     "VariablePointers",
    386     "TransformFeedback",
    387     "GeometryStreams"};
    388   return *r;
    389 }
    390 
    391 const std::vector<std::string>& AllWebGPUCapabilities() {
    392   static const auto r = new std::vector<std::string>{
    393     "",
    394     "Shader",
    395     "Matrix",
    396     "Sampled1D",
    397     "Image1D",
    398     "ImageQuery",
    399     "DerivativeControl"};
    400     return *r;
    401 }
    402 
    403 const std::vector<std::string>& MatrixDependencies() {
    404   static const auto r = new std::vector<std::string>{
    405   "Matrix",
    406   "Shader",
    407   "Geometry",
    408   "Tessellation",
    409   "AtomicStorage",
    410   "TessellationPointSize",
    411   "GeometryPointSize",
    412   "ImageGatherExtended",
    413   "StorageImageMultisample",
    414   "UniformBufferArrayDynamicIndexing",
    415   "SampledImageArrayDynamicIndexing",
    416   "StorageBufferArrayDynamicIndexing",
    417   "StorageImageArrayDynamicIndexing",
    418   "ClipDistance",
    419   "CullDistance",
    420   "ImageCubeArray",
    421   "SampleRateShading",
    422   "ImageRect",
    423   "SampledRect",
    424   "InputAttachment",
    425   "SparseResidency",
    426   "MinLod",
    427   "SampledCubeArray",
    428   "ImageMSArray",
    429   "StorageImageExtendedFormats",
    430   "ImageQuery",
    431   "DerivativeControl",
    432   "InterpolationFunction",
    433   "TransformFeedback",
    434   "GeometryStreams",
    435   "StorageImageReadWithoutFormat",
    436   "StorageImageWriteWithoutFormat",
    437   "MultiViewport",
    438   "DrawParameters",
    439   "MultiView",
    440   "VariablePointersStorageBuffer",
    441   "VariablePointers"};
    442   return *r;
    443 }
    444 
    445 const std::vector<std::string>& ShaderDependencies() {
    446   static const auto r = new std::vector<std::string>{
    447   "Shader",
    448   "Geometry",
    449   "Tessellation",
    450   "AtomicStorage",
    451   "TessellationPointSize",
    452   "GeometryPointSize",
    453   "ImageGatherExtended",
    454   "StorageImageMultisample",
    455   "UniformBufferArrayDynamicIndexing",
    456   "SampledImageArrayDynamicIndexing",
    457   "StorageBufferArrayDynamicIndexing",
    458   "StorageImageArrayDynamicIndexing",
    459   "ClipDistance",
    460   "CullDistance",
    461   "ImageCubeArray",
    462   "SampleRateShading",
    463   "ImageRect",
    464   "SampledRect",
    465   "InputAttachment",
    466   "SparseResidency",
    467   "MinLod",
    468   "SampledCubeArray",
    469   "ImageMSArray",
    470   "StorageImageExtendedFormats",
    471   "ImageQuery",
    472   "DerivativeControl",
    473   "InterpolationFunction",
    474   "TransformFeedback",
    475   "GeometryStreams",
    476   "StorageImageReadWithoutFormat",
    477   "StorageImageWriteWithoutFormat",
    478   "MultiViewport",
    479   "DrawParameters",
    480   "MultiView",
    481   "VariablePointersStorageBuffer",
    482   "VariablePointers"};
    483   return *r;
    484 }
    485 
    486 const std::vector<std::string>& TessellationDependencies() {
    487   static const auto r = new std::vector<std::string>{
    488   "Tessellation",
    489   "TessellationPointSize"};
    490   return *r;
    491 }
    492 
    493 const std::vector<std::string>& GeometryDependencies() {
    494   static const auto r = new std::vector<std::string>{
    495   "Geometry",
    496   "GeometryPointSize",
    497   "GeometryStreams",
    498   "MultiViewport"};
    499   return *r;
    500 }
    501 
    502 const std::vector<std::string>& GeometryTessellationDependencies() {
    503   static const auto r = new std::vector<std::string>{
    504   "Tessellation",
    505   "TessellationPointSize",
    506   "Geometry",
    507   "GeometryPointSize",
    508   "GeometryStreams",
    509   "MultiViewport"};
    510   return *r;
    511 }
    512 
    513 // Returns the names of capabilities that directly depend on Kernel,
    514 // plus itself.
    515 const std::vector<std::string>& KernelDependencies() {
    516   static const auto r = new std::vector<std::string>{
    517   "Kernel",
    518   "Vector16",
    519   "Float16Buffer",
    520   "ImageBasic",
    521   "ImageReadWrite",
    522   "ImageMipmap",
    523   "Pipes",
    524   "DeviceEnqueue",
    525   "LiteralSampler",
    526   "SubgroupDispatch",
    527   "NamedBarrier",
    528   "PipeStorage"};
    529   return *r;
    530 }
    531 
    532 const std::vector<std::string>& KernelAndGroupNonUniformDependencies() {
    533   static const auto r = new std::vector<std::string>{
    534   "Kernel",
    535   "Vector16",
    536   "Float16Buffer",
    537   "ImageBasic",
    538   "ImageReadWrite",
    539   "ImageMipmap",
    540   "Pipes",
    541   "DeviceEnqueue",
    542   "LiteralSampler",
    543   "SubgroupDispatch",
    544   "NamedBarrier",
    545   "PipeStorage",
    546   "GroupNonUniform",
    547   "GroupNonUniformVote",
    548   "GroupNonUniformArithmetic",
    549   "GroupNonUniformBallot",
    550   "GroupNonUniformShuffle",
    551   "GroupNonUniformShuffleRelative",
    552   "GroupNonUniformClustered",
    553   "GroupNonUniformQuad"};
    554   return *r;
    555 }
    556 
    557 const std::vector<std::string>& AddressesDependencies() {
    558   static const auto r = new std::vector<std::string>{
    559   "Addresses",
    560   "GenericPointer"};
    561   return *r;
    562 }
    563 
    564 const std::vector<std::string>& Sampled1DDependencies() {
    565   static const auto r = new std::vector<std::string>{
    566   "Sampled1D",
    567   "Image1D"};
    568   return *r;
    569 }
    570 
    571 const std::vector<std::string>& SampledRectDependencies() {
    572   static const auto r = new std::vector<std::string>{
    573   "SampledRect",
    574   "ImageRect"};
    575   return *r;
    576 }
    577 
    578 const std::vector<std::string>& SampledBufferDependencies() {
    579   static const auto r = new std::vector<std::string>{
    580   "SampledBuffer",
    581   "ImageBuffer"};
    582   return *r;
    583 }
    584 
    585 const char kOpenCLMemoryModel[] = \
    586   " OpCapability Kernel"
    587   " OpMemoryModel Logical OpenCL ";
    588 
    589 const char kGLSL450MemoryModel[] = \
    590   " OpCapability Shader"
    591   " OpMemoryModel Logical GLSL450 ";
    592 
    593 const char kVulkanMemoryModel[] = \
    594   " OpCapability Shader"
    595   " OpCapability VulkanMemoryModelKHR"
    596   " OpExtension \"SPV_KHR_vulkan_memory_model\""
    597   " OpMemoryModel Logical VulkanKHR ";
    598 
    599 const char kVoidFVoid[] = \
    600   " %void   = OpTypeVoid"
    601   " %void_f = OpTypeFunction %void"
    602   " %func   = OpFunction %void None %void_f"
    603   " %label  = OpLabel"
    604   "           OpReturn"
    605   "           OpFunctionEnd ";
    606 
    607 const char kVoidFVoid2[] = \
    608   " %void_f = OpTypeFunction %voidt"
    609   " %func   = OpFunction %voidt None %void_f"
    610   " %label  = OpLabel"
    611   "           OpReturn"
    612   "           OpFunctionEnd ";
    613 
    614 INSTANTIATE_TEST_CASE_P(ExecutionModel, ValidateCapability,
    615                         Combine(
    616                             ValuesIn(AllCapabilities()),
    617                             Values(
    618 std::make_pair(std::string(kOpenCLMemoryModel) +
    619           " OpEntryPoint Vertex %func \"shader\"" +
    620           std::string(kVoidFVoid), ShaderDependencies()),
    621 std::make_pair(std::string(kOpenCLMemoryModel) +
    622           " OpEntryPoint TessellationControl %func \"shader\"" +
    623           std::string(kVoidFVoid), TessellationDependencies()),
    624 std::make_pair(std::string(kOpenCLMemoryModel) +
    625           " OpEntryPoint TessellationEvaluation %func \"shader\"" +
    626           std::string(kVoidFVoid), TessellationDependencies()),
    627 std::make_pair(std::string(kOpenCLMemoryModel) +
    628           " OpEntryPoint Geometry %func \"shader\"" +
    629           " OpExecutionMode %func InputPoints" +
    630           " OpExecutionMode %func OutputPoints" +
    631           std::string(kVoidFVoid), GeometryDependencies()),
    632 std::make_pair(std::string(kOpenCLMemoryModel) +
    633           " OpEntryPoint Fragment %func \"shader\"" +
    634           " OpExecutionMode %func OriginUpperLeft" +
    635           std::string(kVoidFVoid), ShaderDependencies()),
    636 std::make_pair(std::string(kOpenCLMemoryModel) +
    637           " OpEntryPoint GLCompute %func \"shader\"" +
    638           std::string(kVoidFVoid), ShaderDependencies()),
    639 std::make_pair(std::string(kGLSL450MemoryModel) +
    640           " OpEntryPoint Kernel %func \"shader\"" +
    641           std::string(kVoidFVoid), KernelDependencies())
    642 )),);
    643 
    644 INSTANTIATE_TEST_CASE_P(AddressingAndMemoryModel, ValidateCapability,
    645                         Combine(
    646                             ValuesIn(AllCapabilities()),
    647                             Values(
    648 std::make_pair(" OpCapability Shader"
    649           " OpMemoryModel Logical Simple"
    650           " OpEntryPoint Vertex %func \"shader\"" +
    651           std::string(kVoidFVoid),     AllCapabilities()),
    652 std::make_pair(" OpCapability Shader"
    653           " OpMemoryModel Logical GLSL450"
    654           " OpEntryPoint Vertex %func \"shader\"" +
    655           std::string(kVoidFVoid),    AllCapabilities()),
    656 std::make_pair(" OpCapability Kernel"
    657           " OpMemoryModel Logical OpenCL"
    658           " OpEntryPoint Kernel %func \"compute\"" +
    659           std::string(kVoidFVoid),     AllCapabilities()),
    660 std::make_pair(" OpCapability Shader"
    661           " OpMemoryModel Physical32 Simple"
    662           " OpEntryPoint Vertex %func \"shader\"" +
    663           std::string(kVoidFVoid),  AddressesDependencies()),
    664 std::make_pair(" OpCapability Shader"
    665           " OpMemoryModel Physical32 GLSL450"
    666           " OpEntryPoint Vertex %func \"shader\"" +
    667           std::string(kVoidFVoid), AddressesDependencies()),
    668 std::make_pair(" OpCapability Kernel"
    669           " OpMemoryModel Physical32 OpenCL"
    670           " OpEntryPoint Kernel %func \"compute\"" +
    671           std::string(kVoidFVoid),  AddressesDependencies()),
    672 std::make_pair(" OpCapability Shader"
    673           " OpMemoryModel Physical64 Simple"
    674           " OpEntryPoint Vertex %func \"shader\"" +
    675           std::string(kVoidFVoid),  AddressesDependencies()),
    676 std::make_pair(" OpCapability Shader"
    677           " OpMemoryModel Physical64 GLSL450"
    678           " OpEntryPoint Vertex %func \"shader\"" +
    679           std::string(kVoidFVoid), AddressesDependencies()),
    680 std::make_pair(" OpCapability Kernel"
    681           " OpMemoryModel Physical64 OpenCL"
    682           " OpEntryPoint Kernel %func \"compute\"" +
    683           std::string(kVoidFVoid),  AddressesDependencies())
    684 )),);
    685 
    686 INSTANTIATE_TEST_CASE_P(ExecutionMode, ValidateCapability,
    687                         Combine(
    688                             ValuesIn(AllCapabilities()),
    689                             Values(
    690 std::make_pair(std::string(kOpenCLMemoryModel) +
    691           "OpEntryPoint Geometry %func \"shader\" "
    692           "OpExecutionMode %func Invocations 42" +
    693           " OpExecutionMode %func InputPoints" +
    694           " OpExecutionMode %func OutputPoints" +
    695           std::string(kVoidFVoid), GeometryDependencies()),
    696 std::make_pair(std::string(kOpenCLMemoryModel) +
    697           "OpEntryPoint TessellationControl %func \"shader\" "
    698           "OpExecutionMode %func SpacingEqual" +
    699           std::string(kVoidFVoid), TessellationDependencies()),
    700 std::make_pair(std::string(kOpenCLMemoryModel) +
    701           "OpEntryPoint TessellationControl %func \"shader\" "
    702           "OpExecutionMode %func SpacingFractionalEven" +
    703           std::string(kVoidFVoid), TessellationDependencies()),
    704 std::make_pair(std::string(kOpenCLMemoryModel) +
    705           "OpEntryPoint TessellationControl %func \"shader\" "
    706           "OpExecutionMode %func SpacingFractionalOdd" +
    707           std::string(kVoidFVoid), TessellationDependencies()),
    708 std::make_pair(std::string(kOpenCLMemoryModel) +
    709           "OpEntryPoint TessellationControl %func \"shader\" "
    710           "OpExecutionMode %func VertexOrderCw" +
    711           std::string(kVoidFVoid), TessellationDependencies()),
    712 std::make_pair(std::string(kOpenCLMemoryModel) +
    713           "OpEntryPoint TessellationControl %func \"shader\" "
    714           "OpExecutionMode %func VertexOrderCcw" +
    715           std::string(kVoidFVoid), TessellationDependencies()),
    716 std::make_pair(std::string(kOpenCLMemoryModel) +
    717           "OpEntryPoint Fragment %func \"shader\" "
    718           "OpExecutionMode %func PixelCenterInteger" +
    719           " OpExecutionMode %func OriginUpperLeft" +
    720           std::string(kVoidFVoid), ShaderDependencies()),
    721 std::make_pair(std::string(kOpenCLMemoryModel) +
    722           "OpEntryPoint Fragment %func \"shader\" "
    723           "OpExecutionMode %func OriginUpperLeft" +
    724           std::string(kVoidFVoid), ShaderDependencies()),
    725 std::make_pair(std::string(kOpenCLMemoryModel) +
    726           "OpEntryPoint Fragment %func \"shader\" "
    727           "OpExecutionMode %func OriginLowerLeft" +
    728           std::string(kVoidFVoid), ShaderDependencies()),
    729 std::make_pair(std::string(kOpenCLMemoryModel) +
    730           "OpEntryPoint Fragment %func \"shader\" "
    731           "OpExecutionMode %func EarlyFragmentTests" +
    732           " OpExecutionMode %func OriginUpperLeft" +
    733           std::string(kVoidFVoid), ShaderDependencies()),
    734 std::make_pair(std::string(kOpenCLMemoryModel) +
    735           "OpEntryPoint TessellationControl %func \"shader\" "
    736           "OpExecutionMode %func PointMode" +
    737           std::string(kVoidFVoid), TessellationDependencies()),
    738 std::make_pair(std::string(kOpenCLMemoryModel) +
    739           "OpEntryPoint Vertex %func \"shader\" "
    740           "OpExecutionMode %func Xfb" +
    741           std::string(kVoidFVoid), std::vector<std::string>{"TransformFeedback"}),
    742 std::make_pair(std::string(kOpenCLMemoryModel) +
    743           "OpEntryPoint Fragment %func \"shader\" "
    744           "OpExecutionMode %func DepthReplacing" +
    745           " OpExecutionMode %func OriginUpperLeft" +
    746           std::string(kVoidFVoid), ShaderDependencies()),
    747 std::make_pair(std::string(kOpenCLMemoryModel) +
    748           "OpEntryPoint Fragment %func \"shader\" "
    749           "OpExecutionMode %func DepthGreater" +
    750           " OpExecutionMode %func OriginUpperLeft" +
    751           std::string(kVoidFVoid), ShaderDependencies()),
    752 std::make_pair(std::string(kOpenCLMemoryModel) +
    753           "OpEntryPoint Fragment %func \"shader\" "
    754           "OpExecutionMode %func DepthLess" +
    755           " OpExecutionMode %func OriginUpperLeft" +
    756           std::string(kVoidFVoid), ShaderDependencies()),
    757 std::make_pair(std::string(kOpenCLMemoryModel) +
    758           "OpEntryPoint Fragment %func \"shader\" "
    759           "OpExecutionMode %func DepthUnchanged" +
    760           " OpExecutionMode %func OriginUpperLeft" +
    761           std::string(kVoidFVoid), ShaderDependencies()),
    762 std::make_pair(std::string(kOpenCLMemoryModel) +
    763           "OpEntryPoint Kernel %func \"shader\" "
    764           "OpExecutionMode %func LocalSize 42 42 42" +
    765           std::string(kVoidFVoid), AllCapabilities()),
    766 std::make_pair(std::string(kGLSL450MemoryModel) +
    767           "OpEntryPoint Kernel %func \"shader\" "
    768           "OpExecutionMode %func LocalSizeHint 42 42 42" +
    769           std::string(kVoidFVoid), KernelDependencies()),
    770 std::make_pair(std::string(kOpenCLMemoryModel) +
    771           "OpEntryPoint Geometry %func \"shader\" "
    772           "OpExecutionMode %func InputPoints" +
    773           " OpExecutionMode %func OutputPoints" +
    774           std::string(kVoidFVoid), GeometryDependencies()),
    775 std::make_pair(std::string(kOpenCLMemoryModel) +
    776           "OpEntryPoint Geometry %func \"shader\" "
    777           "OpExecutionMode %func InputLines" +
    778           " OpExecutionMode %func OutputLineStrip" +
    779           std::string(kVoidFVoid), GeometryDependencies()),
    780 std::make_pair(std::string(kOpenCLMemoryModel) +
    781           "OpEntryPoint Geometry %func \"shader\" "
    782           "OpExecutionMode %func InputLinesAdjacency" +
    783           " OpExecutionMode %func OutputLineStrip" +
    784           std::string(kVoidFVoid), GeometryDependencies()),
    785 std::make_pair(std::string(kOpenCLMemoryModel) +
    786           "OpEntryPoint Geometry %func \"shader\" "
    787           "OpExecutionMode %func Triangles" +
    788           " OpExecutionMode %func OutputTriangleStrip" +
    789           std::string(kVoidFVoid), GeometryDependencies()),
    790 std::make_pair(std::string(kOpenCLMemoryModel) +
    791           "OpEntryPoint TessellationControl %func \"shader\" "
    792           "OpExecutionMode %func Triangles" +
    793           std::string(kVoidFVoid), TessellationDependencies()),
    794 std::make_pair(std::string(kOpenCLMemoryModel) +
    795           "OpEntryPoint Geometry %func \"shader\" "
    796           "OpExecutionMode %func InputTrianglesAdjacency" +
    797           " OpExecutionMode %func OutputTriangleStrip" +
    798           std::string(kVoidFVoid), GeometryDependencies()),
    799 std::make_pair(std::string(kOpenCLMemoryModel) +
    800           "OpEntryPoint TessellationControl %func \"shader\" "
    801           "OpExecutionMode %func Quads" +
    802           std::string(kVoidFVoid), TessellationDependencies()),
    803 std::make_pair(std::string(kOpenCLMemoryModel) +
    804           "OpEntryPoint TessellationControl %func \"shader\" "
    805           "OpExecutionMode %func Isolines" +
    806           std::string(kVoidFVoid), TessellationDependencies()),
    807 std::make_pair(std::string(kOpenCLMemoryModel) +
    808           "OpEntryPoint Geometry %func \"shader\" "
    809           "OpExecutionMode %func OutputVertices 42" +
    810           " OpExecutionMode %func OutputPoints" +
    811           " OpExecutionMode %func InputPoints" +
    812           std::string(kVoidFVoid), GeometryDependencies()),
    813 std::make_pair(std::string(kOpenCLMemoryModel) +
    814           "OpEntryPoint TessellationControl %func \"shader\" "
    815           "OpExecutionMode %func OutputVertices 42" +
    816           std::string(kVoidFVoid), TessellationDependencies()),
    817 std::make_pair(std::string(kOpenCLMemoryModel) +
    818           "OpEntryPoint Geometry %func \"shader\" "
    819           "OpExecutionMode %func OutputPoints" +
    820           " OpExecutionMode %func InputPoints" +
    821           std::string(kVoidFVoid), GeometryDependencies()),
    822 std::make_pair(std::string(kOpenCLMemoryModel) +
    823           "OpEntryPoint Geometry %func \"shader\" "
    824           "OpExecutionMode %func OutputLineStrip" +
    825           " OpExecutionMode %func InputLines" +
    826           std::string(kVoidFVoid), GeometryDependencies()),
    827 std::make_pair(std::string(kOpenCLMemoryModel) +
    828           "OpEntryPoint Geometry %func \"shader\" "
    829           "OpExecutionMode %func OutputTriangleStrip" +
    830           " OpExecutionMode %func Triangles" +
    831           std::string(kVoidFVoid), GeometryDependencies()),
    832 std::make_pair(std::string(kGLSL450MemoryModel) +
    833           "OpEntryPoint Kernel %func \"shader\" "
    834           "OpExecutionMode %func VecTypeHint 2" +
    835           std::string(kVoidFVoid), KernelDependencies()),
    836 std::make_pair(std::string(kGLSL450MemoryModel) +
    837           "OpEntryPoint Kernel %func \"shader\" "
    838           "OpExecutionMode %func ContractionOff" +
    839           std::string(kVoidFVoid), KernelDependencies()))),);
    840 
    841 // clang-format on
    842 
    843 INSTANTIATE_TEST_CASE_P(
    844     ExecutionModeV11, ValidateCapabilityV11,
    845     Combine(ValuesIn(AllCapabilities()),
    846             Values(std::make_pair(std::string(kOpenCLMemoryModel) +
    847                                       "OpEntryPoint Kernel %func \"shader\" "
    848                                       "OpExecutionMode %func SubgroupSize 1" +
    849                                       std::string(kVoidFVoid),
    850                                   std::vector<std::string>{"SubgroupDispatch"}),
    851                    std::make_pair(
    852                        std::string(kOpenCLMemoryModel) +
    853                            "OpEntryPoint Kernel %func \"shader\" "
    854                            "OpExecutionMode %func SubgroupsPerWorkgroup 65535" +
    855                            std::string(kVoidFVoid),
    856                        std::vector<std::string>{"SubgroupDispatch"}))), );
    857 // clang-format off
    858 
    859 INSTANTIATE_TEST_CASE_P(StorageClass, ValidateCapability,
    860                         Combine(
    861                             ValuesIn(AllCapabilities()),
    862                             Values(
    863 std::make_pair(std::string(kGLSL450MemoryModel) +
    864           " OpEntryPoint Vertex %func \"shader\"" +
    865           " %intt = OpTypeInt 32 0\n"
    866           " %ptrt = OpTypePointer UniformConstant %intt\n"
    867           " %var = OpVariable %ptrt UniformConstant\n" + std::string(kVoidFVoid),
    868           AllCapabilities()),
    869 std::make_pair(std::string(kOpenCLMemoryModel) +
    870           " OpEntryPoint Kernel %func \"compute\"" +
    871           " %intt = OpTypeInt 32 0\n"
    872           " %ptrt = OpTypePointer Input %intt"
    873           " %var = OpVariable %ptrt Input\n" + std::string(kVoidFVoid),
    874           AllCapabilities()),
    875 std::make_pair(std::string(kOpenCLMemoryModel) +
    876           " OpEntryPoint Vertex %func \"shader\"" +
    877           " %intt = OpTypeInt 32 0\n"
    878           " %ptrt = OpTypePointer Uniform %intt\n"
    879           " %var = OpVariable %ptrt Uniform\n" + std::string(kVoidFVoid),
    880           ShaderDependencies()),
    881 std::make_pair(std::string(kOpenCLMemoryModel) +
    882           " OpEntryPoint Vertex %func \"shader\"" +
    883           " %intt = OpTypeInt 32 0\n"
    884           " %ptrt = OpTypePointer Output %intt\n"
    885           " %var = OpVariable %ptrt Output\n" + std::string(kVoidFVoid),
    886           ShaderDependencies()),
    887 std::make_pair(std::string(kGLSL450MemoryModel) +
    888           " OpEntryPoint Vertex %func \"shader\"" +
    889           " %intt = OpTypeInt 32 0\n"
    890           " %ptrt = OpTypePointer Workgroup %intt\n"
    891           " %var = OpVariable %ptrt Workgroup\n" + std::string(kVoidFVoid),
    892           AllCapabilities()),
    893 std::make_pair(std::string(kGLSL450MemoryModel) +
    894           " OpEntryPoint Vertex %func \"shader\"" +
    895           " %intt = OpTypeInt 32 0\n"
    896           " %ptrt = OpTypePointer CrossWorkgroup %intt\n"
    897           " %var = OpVariable %ptrt CrossWorkgroup\n" + std::string(kVoidFVoid),
    898           AllCapabilities()),
    899 std::make_pair(std::string(kOpenCLMemoryModel) +
    900           " OpEntryPoint Kernel %func \"compute\"" +
    901           " %intt = OpTypeInt 32 0\n"
    902           " %ptrt = OpTypePointer Private %intt\n"
    903           " %var = OpVariable %ptrt Private\n" + std::string(kVoidFVoid),
    904           ShaderDependencies()),
    905 std::make_pair(std::string(kOpenCLMemoryModel) +
    906           " OpEntryPoint Kernel %func \"compute\"" +
    907           " %intt = OpTypeInt 32 0\n"
    908           " %ptrt = OpTypePointer PushConstant %intt\n"
    909           " %var = OpVariable %ptrt PushConstant\n" + std::string(kVoidFVoid),
    910           ShaderDependencies()),
    911 std::make_pair(std::string(kGLSL450MemoryModel) +
    912           " OpEntryPoint Vertex %func \"shader\"" +
    913           " %intt = OpTypeInt 32 0\n"
    914           " %ptrt = OpTypePointer AtomicCounter %intt\n"
    915           " %var = OpVariable %ptrt AtomicCounter\n" + std::string(kVoidFVoid),
    916           std::vector<std::string>{"AtomicStorage"}),
    917 std::make_pair(std::string(kGLSL450MemoryModel) +
    918           " OpEntryPoint Vertex %func \"shader\"" +
    919           " %intt = OpTypeInt 32 0\n"
    920           " %ptrt = OpTypePointer Image %intt\n"
    921           " %var = OpVariable %ptrt Image\n" + std::string(kVoidFVoid),
    922           AllCapabilities())
    923 )),);
    924 
    925 INSTANTIATE_TEST_CASE_P(Dim, ValidateCapability,
    926                         Combine(
    927                             ValuesIn(AllCapabilities()),
    928                             Values(
    929 std::make_pair(" OpCapability ImageBasic" +
    930           std::string(kOpenCLMemoryModel) +
    931           std::string(" OpEntryPoint Kernel %func \"compute\"") +
    932           " %voidt = OpTypeVoid"
    933           " %imgt = OpTypeImage %voidt 1D 0 0 0 0 Unknown" + std::string(kVoidFVoid2),
    934           Sampled1DDependencies()),
    935 std::make_pair(" OpCapability ImageBasic" +
    936           std::string(kOpenCLMemoryModel) +
    937           std::string(" OpEntryPoint Kernel %func \"compute\"") +
    938           " %voidt = OpTypeVoid"
    939           " %imgt = OpTypeImage %voidt 2D 0 0 0 0 Unknown" + std::string(kVoidFVoid2),
    940           AllCapabilities()),
    941 std::make_pair(" OpCapability ImageBasic" +
    942           std::string(kOpenCLMemoryModel) +
    943           std::string(" OpEntryPoint Kernel %func \"compute\"") +
    944           " %voidt = OpTypeVoid"
    945           " %imgt = OpTypeImage %voidt 3D 0 0 0 0 Unknown" + std::string(kVoidFVoid2),
    946           AllCapabilities()),
    947 std::make_pair(" OpCapability ImageBasic" +
    948           std::string(kOpenCLMemoryModel) +
    949           std::string(" OpEntryPoint Kernel %func \"compute\"") +
    950           " %voidt = OpTypeVoid"
    951           " %imgt = OpTypeImage %voidt Cube 0 0 0 0 Unknown" + std::string(kVoidFVoid2),
    952           ShaderDependencies()),
    953 std::make_pair(" OpCapability ImageBasic" +
    954           std::string(kOpenCLMemoryModel) +
    955           std::string(" OpEntryPoint Kernel %func \"compute\"") +
    956           " %voidt = OpTypeVoid"
    957           " %imgt = OpTypeImage %voidt Rect 0 0 0 0 Unknown" + std::string(kVoidFVoid2),
    958           SampledRectDependencies()),
    959 std::make_pair(" OpCapability ImageBasic" +
    960           std::string(kOpenCLMemoryModel) +
    961           std::string(" OpEntryPoint Kernel %func \"compute\"") +
    962           " %voidt = OpTypeVoid"
    963           " %imgt = OpTypeImage %voidt Buffer 0 0 0 0 Unknown" + std::string(kVoidFVoid2),
    964           SampledBufferDependencies()),
    965 std::make_pair(" OpCapability ImageBasic" +
    966           std::string(kOpenCLMemoryModel) +
    967           std::string(" OpEntryPoint Kernel %func \"compute\"") +
    968           " %voidt = OpTypeVoid"
    969           " %imgt = OpTypeImage %voidt SubpassData 0 0 0 2 Unknown" + std::string(kVoidFVoid2),
    970           std::vector<std::string>{"InputAttachment"})
    971 )),);
    972 
    973 // NOTE: All Sampler Address Modes require kernel capabilities but the
    974 // OpConstantSampler requires LiteralSampler which depends on Kernel
    975 INSTANTIATE_TEST_CASE_P(SamplerAddressingMode, ValidateCapability,
    976                         Combine(
    977                             ValuesIn(AllCapabilities()),
    978                             Values(
    979 std::make_pair(std::string(kGLSL450MemoryModel) +
    980           " OpEntryPoint Vertex %func \"shader\""
    981           " %samplert = OpTypeSampler"
    982           " %sampler = OpConstantSampler %samplert None 1 Nearest" +
    983           std::string(kVoidFVoid),
    984           std::vector<std::string>{"LiteralSampler"}),
    985 std::make_pair(std::string(kGLSL450MemoryModel) +
    986           " OpEntryPoint Vertex %func \"shader\""
    987           " %samplert = OpTypeSampler"
    988           " %sampler = OpConstantSampler %samplert ClampToEdge 1 Nearest" +
    989           std::string(kVoidFVoid),
    990           std::vector<std::string>{"LiteralSampler"}),
    991 std::make_pair(std::string(kGLSL450MemoryModel) +
    992           " OpEntryPoint Vertex %func \"shader\""
    993           " %samplert = OpTypeSampler"
    994           " %sampler = OpConstantSampler %samplert Clamp 1 Nearest" +
    995           std::string(kVoidFVoid),
    996           std::vector<std::string>{"LiteralSampler"}),
    997 std::make_pair(std::string(kGLSL450MemoryModel) +
    998           " OpEntryPoint Vertex %func \"shader\""
    999           " %samplert = OpTypeSampler"
   1000           " %sampler = OpConstantSampler %samplert Repeat 1 Nearest" +
   1001           std::string(kVoidFVoid),
   1002           std::vector<std::string>{"LiteralSampler"}),
   1003 std::make_pair(std::string(kGLSL450MemoryModel) +
   1004           " OpEntryPoint Vertex %func \"shader\""
   1005           " %samplert = OpTypeSampler"
   1006           " %sampler = OpConstantSampler %samplert RepeatMirrored 1 Nearest" +
   1007           std::string(kVoidFVoid),
   1008           std::vector<std::string>{"LiteralSampler"})
   1009 )),);
   1010 
   1011 // TODO(umar): Sampler Filter Mode
   1012 // TODO(umar): Image Format
   1013 // TODO(umar): Image Channel Order
   1014 // TODO(umar): Image Channel Data Type
   1015 // TODO(umar): Image Operands
   1016 // TODO(umar): FP Fast Math Mode
   1017 // TODO(umar): FP Rounding Mode
   1018 // TODO(umar): Linkage Type
   1019 // TODO(umar): Access Qualifier
   1020 // TODO(umar): Function Parameter Attribute
   1021 
   1022 INSTANTIATE_TEST_CASE_P(Decoration, ValidateCapability,
   1023                         Combine(
   1024                             ValuesIn(AllCapabilities()),
   1025                             Values(
   1026 std::make_pair(std::string(kOpenCLMemoryModel) +
   1027           "OpEntryPoint Kernel %func \"compute\" \n"
   1028           "OpDecorate %intt RelaxedPrecision\n"
   1029           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1030           ShaderDependencies()),
   1031 std::make_pair(std::string(kOpenCLMemoryModel) +
   1032           "OpEntryPoint Kernel %func \"compute\" \n"
   1033           "OpDecorate %intt Block\n"
   1034           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1035           ShaderDependencies()),
   1036 std::make_pair(std::string(kOpenCLMemoryModel) +
   1037           "OpEntryPoint Kernel %func \"compute\" \n"
   1038           "OpDecorate %intt BufferBlock\n"
   1039           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1040           ShaderDependencies()),
   1041 std::make_pair(std::string(kOpenCLMemoryModel) +
   1042           "OpEntryPoint Kernel %func \"compute\" \n"
   1043           "OpDecorate %intt RowMajor\n"
   1044           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1045           MatrixDependencies()),
   1046 std::make_pair(std::string(kOpenCLMemoryModel) +
   1047           "OpEntryPoint Kernel %func \"compute\" \n"
   1048           "OpDecorate %intt ColMajor\n"
   1049           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1050           MatrixDependencies()),
   1051 std::make_pair(std::string(kOpenCLMemoryModel) +
   1052           "OpEntryPoint Kernel %func \"compute\" \n"
   1053           "OpDecorate %intt ArrayStride 1\n"
   1054           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1055           ShaderDependencies()),
   1056 std::make_pair(std::string(kOpenCLMemoryModel) +
   1057           "OpEntryPoint Kernel %func \"compute\" \n"
   1058           "OpDecorate %intt MatrixStride 1\n"
   1059           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1060           MatrixDependencies()),
   1061 std::make_pair(std::string(kOpenCLMemoryModel) +
   1062           "OpEntryPoint Kernel %func \"compute\" \n"
   1063           "OpDecorate %intt GLSLShared\n"
   1064           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1065           ShaderDependencies()),
   1066 std::make_pair(std::string(kOpenCLMemoryModel) +
   1067           "OpEntryPoint Kernel %func \"compute\" \n"
   1068           "OpDecorate %intt GLSLPacked\n"
   1069           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1070           ShaderDependencies()),
   1071 std::make_pair(std::string(kGLSL450MemoryModel) +
   1072           "OpEntryPoint Vertex %func \"shader\" \n"
   1073           "OpDecorate %intt CPacked\n"
   1074           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1075           KernelDependencies()),
   1076 std::make_pair(std::string(kOpenCLMemoryModel) +
   1077           "OpEntryPoint Kernel %func \"compute\" \n"
   1078           "OpDecorate %intt NoPerspective\n"
   1079           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1080           ShaderDependencies()),
   1081 std::make_pair(std::string(kOpenCLMemoryModel) +
   1082           "OpEntryPoint Kernel %func \"compute\" \n"
   1083           "OpDecorate %intt Flat\n"
   1084           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1085           ShaderDependencies()),
   1086 std::make_pair(std::string(kOpenCLMemoryModel) +
   1087           "OpEntryPoint Kernel %func \"compute\" \n"
   1088           "OpDecorate %intt Patch\n"
   1089           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1090           TessellationDependencies()),
   1091 std::make_pair(std::string(kOpenCLMemoryModel) +
   1092           "OpEntryPoint Kernel %func \"compute\" \n"
   1093           "OpDecorate %intt Centroid\n"
   1094           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1095           ShaderDependencies()),
   1096 std::make_pair(std::string(kOpenCLMemoryModel) +
   1097           "OpEntryPoint Kernel %func \"compute\" \n"
   1098           "OpDecorate %intt Sample\n"
   1099           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1100           std::vector<std::string>{"SampleRateShading"}),
   1101 std::make_pair(std::string(kOpenCLMemoryModel) +
   1102           "OpEntryPoint Kernel %func \"compute\" \n"
   1103           "OpDecorate %intt Invariant\n"
   1104           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1105           ShaderDependencies()),
   1106 std::make_pair(std::string(kOpenCLMemoryModel) +
   1107           "OpEntryPoint Kernel %func \"compute\" \n"
   1108           "OpDecorate %intt Restrict\n"
   1109           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1110           AllCapabilities()),
   1111 std::make_pair(std::string(kOpenCLMemoryModel) +
   1112           "OpEntryPoint Kernel %func \"compute\" \n"
   1113           "OpDecorate %intt Aliased\n"
   1114           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1115           AllCapabilities()),
   1116 std::make_pair(std::string(kOpenCLMemoryModel) +
   1117           "OpEntryPoint Kernel %func \"compute\" \n"
   1118           "OpDecorate %intt Volatile\n"
   1119           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1120           AllCapabilities()),
   1121 std::make_pair(std::string(kGLSL450MemoryModel) +
   1122           "OpEntryPoint Vertex %func \"shader\" \n"
   1123           "OpDecorate %intt Constant\n"
   1124           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1125           KernelDependencies()),
   1126 std::make_pair(std::string(kOpenCLMemoryModel) +
   1127           "OpEntryPoint Kernel %func \"compute\" \n"
   1128           "OpDecorate %intt Coherent\n"
   1129           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1130           AllCapabilities()),
   1131 std::make_pair(std::string(kOpenCLMemoryModel) +
   1132           "OpEntryPoint Kernel %func \"compute\" \n"
   1133           "OpDecorate %intt NonWritable\n"
   1134           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1135           AllCapabilities()),
   1136 std::make_pair(std::string(kOpenCLMemoryModel) +
   1137           "OpEntryPoint Kernel %func \"compute\" \n"
   1138           "OpDecorate %intt NonReadable\n"
   1139           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1140           AllCapabilities()),
   1141 std::make_pair(std::string(kOpenCLMemoryModel) +
   1142           // Uniform must target a non-void value.
   1143           "OpEntryPoint Kernel %func \"compute\" \n"
   1144           "OpDecorate %int0 Uniform\n"
   1145           "%intt = OpTypeInt 32 0\n" +
   1146           "%int0 = OpConstantNull %intt"
   1147           + std::string(kVoidFVoid),
   1148           ShaderDependencies()),
   1149 std::make_pair(std::string(kGLSL450MemoryModel) +
   1150           "OpEntryPoint Vertex %func \"shader\" \n"
   1151           "OpDecorate %intt SaturatedConversion\n"
   1152           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1153           KernelDependencies()),
   1154 std::make_pair(std::string(kOpenCLMemoryModel) +
   1155           "OpEntryPoint Kernel %func \"compute\" \n"
   1156           "OpDecorate %intt Stream 0\n"
   1157           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1158           std::vector<std::string>{"GeometryStreams"}),
   1159 std::make_pair(std::string(kOpenCLMemoryModel) +
   1160           "OpEntryPoint Kernel %func \"compute\" \n"
   1161           "OpDecorate %intt Location 0\n"
   1162           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1163           ShaderDependencies()),
   1164 std::make_pair(std::string(kOpenCLMemoryModel) +
   1165           "OpEntryPoint Kernel %func \"compute\" \n"
   1166           "OpDecorate %intt Component 0\n"
   1167           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1168           ShaderDependencies()),
   1169 std::make_pair(std::string(kOpenCLMemoryModel) +
   1170           "OpEntryPoint Kernel %func \"compute\" \n"
   1171           "OpDecorate %intt Index 0\n"
   1172           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1173           ShaderDependencies()),
   1174 std::make_pair(std::string(kOpenCLMemoryModel) +
   1175           "OpEntryPoint Kernel %func \"compute\" \n"
   1176           "OpDecorate %intt Binding 0\n"
   1177           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1178           ShaderDependencies()),
   1179 std::make_pair(std::string(kOpenCLMemoryModel) +
   1180           "OpEntryPoint Kernel %func \"compute\" \n"
   1181           "OpDecorate %intt DescriptorSet 0\n"
   1182           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1183           ShaderDependencies()),
   1184 std::make_pair(std::string(kOpenCLMemoryModel) +
   1185           "OpEntryPoint Kernel %func \"compute\" \n"
   1186           "OpDecorate %intt Offset 0\n"
   1187           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1188           ShaderDependencies()),
   1189 std::make_pair(std::string(kOpenCLMemoryModel) +
   1190           "OpEntryPoint Kernel %func \"compute\" \n"
   1191           "OpDecorate %intt XfbBuffer 0\n"
   1192           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1193           std::vector<std::string>{"TransformFeedback"}),
   1194 std::make_pair(std::string(kOpenCLMemoryModel) +
   1195           "OpEntryPoint Kernel %func \"compute\" \n"
   1196           "OpDecorate %intt XfbStride 0\n"
   1197           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1198           std::vector<std::string>{"TransformFeedback"}),
   1199 std::make_pair(std::string(kGLSL450MemoryModel) +
   1200           "OpEntryPoint Vertex %func \"shader\" \n"
   1201           "OpDecorate %intt FuncParamAttr Zext\n"
   1202           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1203           KernelDependencies()),
   1204 std::make_pair(std::string(kGLSL450MemoryModel) +
   1205           "OpEntryPoint Vertex %func \"shader\" \n"
   1206           "OpDecorate %intt FPFastMathMode Fast\n"
   1207           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1208           KernelDependencies()),
   1209 std::make_pair(std::string(kOpenCLMemoryModel) +
   1210           "OpEntryPoint Kernel %func \"compute\" \n"
   1211           "OpDecorate %intt LinkageAttributes \"other\" Import\n"
   1212           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1213           std::vector<std::string>{"Linkage"}),
   1214 std::make_pair(std::string(kOpenCLMemoryModel) +
   1215           "OpEntryPoint Kernel %func \"compute\" \n"
   1216           "OpDecorate %intt NoContraction\n"
   1217           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1218           ShaderDependencies()),
   1219 std::make_pair(std::string(kOpenCLMemoryModel) +
   1220           "OpEntryPoint Kernel %func \"compute\" \n"
   1221           "OpDecorate %intt InputAttachmentIndex 0\n"
   1222           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1223           std::vector<std::string>{"InputAttachment"}),
   1224 std::make_pair(std::string(kGLSL450MemoryModel) +
   1225           "OpEntryPoint Vertex %func \"shader\" \n"
   1226           "OpDecorate %intt Alignment 4\n"
   1227           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1228           KernelDependencies())
   1229 )),);
   1230 
   1231 // clang-format on
   1232 INSTANTIATE_TEST_CASE_P(
   1233     DecorationSpecId, ValidateCapability,
   1234     Combine(
   1235         ValuesIn(AllSpirV10Capabilities()),
   1236         Values(std::make_pair(std::string(kOpenCLMemoryModel) +
   1237                                   "OpEntryPoint Vertex %func \"shader\" \n" +
   1238                                   "OpDecorate %1 SpecId 1\n"
   1239                                   "%intt = OpTypeInt 32 0\n"
   1240                                   "%1 = OpSpecConstant %intt 0\n" +
   1241                                   std::string(kVoidFVoid),
   1242                               ShaderDependencies()))), );
   1243 
   1244 INSTANTIATE_TEST_CASE_P(
   1245     DecorationV11, ValidateCapabilityV11,
   1246     Combine(ValuesIn(AllCapabilities()),
   1247             Values(std::make_pair(std::string(kOpenCLMemoryModel) +
   1248                                       "OpEntryPoint Kernel %func \"compute\" \n"
   1249                                       "OpDecorate %p MaxByteOffset 0 "
   1250                                       "%i32 = OpTypeInt 32 0 "
   1251                                       "%pi32 = OpTypePointer Workgroup %i32 "
   1252                                       "%p = OpVariable %pi32 Workgroup " +
   1253                                       std::string(kVoidFVoid),
   1254                                   AddressesDependencies()),
   1255                    // Trying to test OpDecorate here, but if this fails due to
   1256                    // incorrect OpMemoryModel validation, that must also be
   1257                    // fixed.
   1258                    std::make_pair(
   1259                        std::string("OpMemoryModel Logical OpenCL "
   1260                                    "OpEntryPoint Kernel %func \"compute\" \n"
   1261                                    "OpDecorate %1 SpecId 1 "
   1262                                    "%intt = OpTypeInt 32 0 "
   1263                                    "%1 = OpSpecConstant %intt 0") +
   1264                            std::string(kVoidFVoid),
   1265                        KernelDependencies()),
   1266                    std::make_pair(
   1267                        std::string("OpMemoryModel Logical Simple "
   1268                                    "OpEntryPoint Vertex %func \"shader\" \n"
   1269                                    "OpDecorate %1 SpecId 1 "
   1270                                    "%intt = OpTypeInt 32 0 "
   1271                                    "%1 = OpSpecConstant %intt 0") +
   1272                            std::string(kVoidFVoid),
   1273                        ShaderDependencies()))), );
   1274 // clang-format off
   1275 
   1276 INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapability,
   1277                         Combine(
   1278                             ValuesIn(AllCapabilities()),
   1279                             Values(
   1280 std::make_pair(std::string(kOpenCLMemoryModel) +
   1281           "OpEntryPoint Kernel %func \"compute\" \n" +
   1282           "OpDecorate %intt BuiltIn Position\n"
   1283           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1284           ShaderDependencies()),
   1285 // Just mentioning PointSize, ClipDistance, or CullDistance as a BuiltIn does
   1286 // not trigger the requirement for the associated capability.
   1287 // See https://github.com/KhronosGroup/SPIRV-Tools/issues/365
   1288 std::make_pair(std::string(kOpenCLMemoryModel) +
   1289           "OpEntryPoint Kernel %func \"compute\" \n" +
   1290           "OpDecorate %intt BuiltIn PointSize\n"
   1291           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1292           AllCapabilities()),
   1293 std::make_pair(std::string(kOpenCLMemoryModel) +
   1294           "OpEntryPoint Kernel %func \"compute\" \n" +
   1295           "OpDecorate %intt BuiltIn ClipDistance\n"
   1296           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1297           AllCapabilities()),
   1298 std::make_pair(std::string(kOpenCLMemoryModel) +
   1299           "OpEntryPoint Kernel %func \"compute\" \n" +
   1300           "OpDecorate %intt BuiltIn CullDistance\n"
   1301           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1302           AllCapabilities()),
   1303 std::make_pair(std::string(kOpenCLMemoryModel) +
   1304           "OpEntryPoint Kernel %func \"compute\" \n" +
   1305           "OpDecorate %intt BuiltIn VertexId\n"
   1306           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1307           ShaderDependencies()),
   1308 std::make_pair(std::string(kOpenCLMemoryModel) +
   1309           "OpEntryPoint Kernel %func \"compute\" \n" +
   1310           "OpDecorate %intt BuiltIn InstanceId\n"
   1311           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1312           ShaderDependencies()),
   1313 std::make_pair(std::string(kOpenCLMemoryModel) +
   1314           "OpEntryPoint Kernel %func \"compute\" \n" +
   1315           "OpDecorate %intt BuiltIn PrimitiveId\n"
   1316           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1317           GeometryTessellationDependencies()),
   1318 std::make_pair(std::string(kOpenCLMemoryModel) +
   1319           "OpEntryPoint Kernel %func \"compute\" \n" +
   1320           "OpDecorate %intt BuiltIn InvocationId\n"
   1321           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1322           GeometryTessellationDependencies()),
   1323 std::make_pair(std::string(kOpenCLMemoryModel) +
   1324           "OpEntryPoint Kernel %func \"compute\" \n" +
   1325           "OpDecorate %intt BuiltIn Layer\n"
   1326           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1327           GeometryDependencies()),
   1328 std::make_pair(std::string(kOpenCLMemoryModel) +
   1329           "OpEntryPoint Kernel %func \"compute\" \n" +
   1330           "OpDecorate %intt BuiltIn ViewportIndex\n"
   1331           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1332           std::vector<std::string>{"MultiViewport"}),
   1333 std::make_pair(std::string(kOpenCLMemoryModel) +
   1334           "OpEntryPoint Kernel %func \"compute\" \n" +
   1335           "OpDecorate %intt BuiltIn TessLevelOuter\n"
   1336           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1337           TessellationDependencies()),
   1338 std::make_pair(std::string(kOpenCLMemoryModel) +
   1339           "OpEntryPoint Kernel %func \"compute\" \n" +
   1340           "OpDecorate %intt BuiltIn TessLevelInner\n"
   1341           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1342           TessellationDependencies()),
   1343 std::make_pair(std::string(kOpenCLMemoryModel) +
   1344           "OpEntryPoint Kernel %func \"compute\" \n" +
   1345           "OpDecorate %intt BuiltIn TessCoord\n"
   1346           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1347           TessellationDependencies()),
   1348 std::make_pair(std::string(kOpenCLMemoryModel) +
   1349           "OpEntryPoint Kernel %func \"compute\" \n" +
   1350           "OpDecorate %intt BuiltIn PatchVertices\n"
   1351           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1352           TessellationDependencies()),
   1353 std::make_pair(std::string(kOpenCLMemoryModel) +
   1354           "OpEntryPoint Kernel %func \"compute\" \n" +
   1355           "OpDecorate %intt BuiltIn FragCoord\n"
   1356           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1357           ShaderDependencies()),
   1358 std::make_pair(std::string(kOpenCLMemoryModel) +
   1359           "OpEntryPoint Kernel %func \"compute\" \n" +
   1360           "OpDecorate %intt BuiltIn PointCoord\n"
   1361           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1362           ShaderDependencies()),
   1363 std::make_pair(std::string(kOpenCLMemoryModel) +
   1364           "OpEntryPoint Kernel %func \"compute\" \n" +
   1365           "OpDecorate %intt BuiltIn FrontFacing\n"
   1366           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1367           ShaderDependencies()),
   1368 std::make_pair(std::string(kOpenCLMemoryModel) +
   1369           "OpEntryPoint Kernel %func \"compute\" \n" +
   1370           "OpDecorate %intt BuiltIn SampleId\n"
   1371           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1372           std::vector<std::string>{"SampleRateShading"}),
   1373 std::make_pair(std::string(kOpenCLMemoryModel) +
   1374           "OpEntryPoint Kernel %func \"compute\" \n" +
   1375           "OpDecorate %intt BuiltIn SamplePosition\n"
   1376           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1377           std::vector<std::string>{"SampleRateShading"}),
   1378 std::make_pair(std::string(kOpenCLMemoryModel) +
   1379           "OpEntryPoint Kernel %func \"compute\" \n" +
   1380           "OpDecorate %intt BuiltIn SampleMask\n"
   1381           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1382           ShaderDependencies()),
   1383 std::make_pair(std::string(kOpenCLMemoryModel) +
   1384           "OpEntryPoint Kernel %func \"compute\" \n" +
   1385           "OpDecorate %intt BuiltIn FragDepth\n"
   1386           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1387           ShaderDependencies()),
   1388 std::make_pair(std::string(kOpenCLMemoryModel) +
   1389           "OpEntryPoint Kernel %func \"compute\" \n" +
   1390           "OpDecorate %intt BuiltIn HelperInvocation\n"
   1391           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1392           ShaderDependencies()),
   1393 std::make_pair(std::string(kOpenCLMemoryModel) +
   1394           "OpEntryPoint Kernel %func \"compute\" \n" +
   1395           "OpDecorate %intt BuiltIn VertexIndex\n"
   1396           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1397           ShaderDependencies()),
   1398 std::make_pair(std::string(kOpenCLMemoryModel) +
   1399           "OpEntryPoint Kernel %func \"compute\" \n" +
   1400           "OpDecorate %intt BuiltIn InstanceIndex\n"
   1401           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1402           ShaderDependencies()),
   1403 std::make_pair(std::string(kOpenCLMemoryModel) +
   1404           "OpEntryPoint Kernel %func \"compute\" \n" +
   1405           "OpDecorate %intt BuiltIn NumWorkgroups\n"
   1406           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1407           AllCapabilities()),
   1408 std::make_pair(std::string(kOpenCLMemoryModel) +
   1409           "OpEntryPoint Kernel %func \"compute\" \n" +
   1410           "OpDecorate %intt BuiltIn WorkgroupSize\n"
   1411           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1412           AllCapabilities()),
   1413 std::make_pair(std::string(kOpenCLMemoryModel) +
   1414           "OpEntryPoint Kernel %func \"compute\" \n" +
   1415           "OpDecorate %intt BuiltIn WorkgroupId\n"
   1416           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1417           AllCapabilities()),
   1418 std::make_pair(std::string(kOpenCLMemoryModel) +
   1419           "OpEntryPoint Kernel %func \"compute\" \n" +
   1420           "OpDecorate %intt BuiltIn LocalInvocationId\n"
   1421           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1422           AllCapabilities()),
   1423 std::make_pair(std::string(kOpenCLMemoryModel) +
   1424           "OpEntryPoint Kernel %func \"compute\" \n" +
   1425           "OpDecorate %intt BuiltIn GlobalInvocationId\n"
   1426           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1427           AllCapabilities()),
   1428 std::make_pair(std::string(kOpenCLMemoryModel) +
   1429           "OpEntryPoint Kernel %func \"compute\" \n" +
   1430           "OpDecorate %intt BuiltIn LocalInvocationIndex\n"
   1431           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1432           AllCapabilities()),
   1433 std::make_pair(std::string(kGLSL450MemoryModel) +
   1434           "OpEntryPoint Vertex %func \"shader\" \n" +
   1435           "OpDecorate %intt BuiltIn WorkDim\n"
   1436           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1437           KernelDependencies()),
   1438 std::make_pair(std::string(kGLSL450MemoryModel) +
   1439           "OpEntryPoint Vertex %func \"shader\" \n" +
   1440           "OpDecorate %intt BuiltIn GlobalSize\n"
   1441           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1442           KernelDependencies()),
   1443 std::make_pair(std::string(kGLSL450MemoryModel) +
   1444           "OpEntryPoint Vertex %func \"shader\" \n" +
   1445           "OpDecorate %intt BuiltIn EnqueuedWorkgroupSize\n"
   1446           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1447           KernelDependencies()),
   1448 std::make_pair(std::string(kGLSL450MemoryModel) +
   1449           "OpEntryPoint Vertex %func \"shader\" \n" +
   1450           "OpDecorate %intt BuiltIn GlobalOffset\n"
   1451           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1452           KernelDependencies()),
   1453 std::make_pair(std::string(kGLSL450MemoryModel) +
   1454           "OpEntryPoint Vertex %func \"shader\" \n" +
   1455           "OpDecorate %intt BuiltIn GlobalLinearId\n"
   1456           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1457           KernelDependencies()),
   1458 std::make_pair(std::string(kGLSL450MemoryModel) +
   1459           "OpEntryPoint Vertex %func \"shader\" \n" +
   1460           "OpDecorate %intt BuiltIn SubgroupSize\n"
   1461           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1462           KernelAndGroupNonUniformDependencies()),
   1463 std::make_pair(std::string(kGLSL450MemoryModel) +
   1464           "OpEntryPoint Vertex %func \"shader\" \n" +
   1465           "OpDecorate %intt BuiltIn SubgroupMaxSize\n"
   1466           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1467           KernelDependencies()),
   1468 std::make_pair(std::string(kGLSL450MemoryModel) +
   1469           "OpEntryPoint Vertex %func \"shader\" \n" +
   1470           "OpDecorate %intt BuiltIn NumSubgroups\n"
   1471           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1472           KernelAndGroupNonUniformDependencies()),
   1473 std::make_pair(std::string(kGLSL450MemoryModel) +
   1474           "OpEntryPoint Vertex %func \"shader\" \n" +
   1475           "OpDecorate %intt BuiltIn NumEnqueuedSubgroups\n"
   1476           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1477           KernelDependencies()),
   1478 std::make_pair(std::string(kGLSL450MemoryModel) +
   1479           "OpEntryPoint Vertex %func \"shader\" \n" +
   1480           "OpDecorate %intt BuiltIn SubgroupId\n"
   1481           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1482           KernelAndGroupNonUniformDependencies()),
   1483 std::make_pair(std::string(kGLSL450MemoryModel) +
   1484           "OpEntryPoint Vertex %func \"shader\" \n" +
   1485           "OpDecorate %intt BuiltIn SubgroupLocalInvocationId\n"
   1486           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1487           KernelAndGroupNonUniformDependencies()),
   1488 std::make_pair(std::string(kOpenCLMemoryModel) +
   1489           "OpEntryPoint Kernel %func \"compute\" \n" +
   1490           "OpDecorate %intt BuiltIn VertexIndex\n"
   1491           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1492           ShaderDependencies()),
   1493 std::make_pair(std::string(kOpenCLMemoryModel) +
   1494           "OpEntryPoint Kernel %func \"compute\" \n" +
   1495           "OpDecorate %intt BuiltIn InstanceIndex\n"
   1496           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1497           ShaderDependencies())
   1498 )),);
   1499 
   1500 // Ensure that mere mention of PointSize, ClipDistance, or CullDistance as
   1501 // BuiltIns does not trigger the requirement for the associated
   1502 // capability.
   1503 // See https://github.com/KhronosGroup/SPIRV-Tools/issues/365
   1504 INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapabilityVulkan10,
   1505                         Combine(
   1506                             // All capabilities to try.
   1507                             ValuesIn(AllSpirV10Capabilities()),
   1508                             Values(
   1509 std::make_pair(std::string(kGLSL450MemoryModel) +
   1510           "OpEntryPoint Vertex %func \"shader\" \n"
   1511           "OpMemberDecorate %block 0 BuiltIn PointSize\n"
   1512           "%f32 = OpTypeFloat 32\n"
   1513           "%block = OpTypeStruct %f32\n"
   1514           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1515           // Capabilities which should succeed.
   1516           AllVulkan10Capabilities()),
   1517 std::make_pair(std::string(kGLSL450MemoryModel) +
   1518           "OpEntryPoint Vertex %func \"shader\" \n"
   1519           "OpMemberDecorate %block 0 BuiltIn ClipDistance\n"
   1520           "%f32 = OpTypeFloat 32\n"
   1521           "%intt = OpTypeInt 32 0\n"
   1522           "%intt_4 = OpConstant %intt 4\n"
   1523           "%f32arr4 = OpTypeArray %f32 %intt_4\n"
   1524           "%block = OpTypeStruct %f32arr4\n" + std::string(kVoidFVoid),
   1525           AllVulkan10Capabilities()),
   1526 std::make_pair(std::string(kGLSL450MemoryModel) +
   1527           "OpEntryPoint Vertex %func \"shader\" \n"
   1528           "OpMemberDecorate %block 0 BuiltIn CullDistance\n"
   1529           "%f32 = OpTypeFloat 32\n"
   1530           "%intt = OpTypeInt 32 0\n"
   1531           "%intt_4 = OpConstant %intt 4\n"
   1532           "%f32arr4 = OpTypeArray %f32 %intt_4\n"
   1533           "%block = OpTypeStruct %f32arr4\n" + std::string(kVoidFVoid),
   1534           AllVulkan10Capabilities())
   1535 )),);
   1536 
   1537 INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapabilityOpenGL40,
   1538                         Combine(
   1539                             // OpenGL 4.0 is based on SPIR-V 1.0
   1540                             ValuesIn(AllSpirV10Capabilities()),
   1541                             Values(
   1542 std::make_pair(std::string(kGLSL450MemoryModel) +
   1543           "OpEntryPoint Vertex %func \"shader\" \n" +
   1544           "OpDecorate %intt BuiltIn PointSize\n"
   1545           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1546           AllSpirV10Capabilities()),
   1547 std::make_pair(std::string(kGLSL450MemoryModel) +
   1548           "OpEntryPoint Vertex %func \"shader\" \n" +
   1549           "OpDecorate %intt BuiltIn ClipDistance\n"
   1550           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1551           AllSpirV10Capabilities()),
   1552 std::make_pair(std::string(kGLSL450MemoryModel) +
   1553           "OpEntryPoint Vertex %func \"shader\" \n" +
   1554           "OpDecorate %intt BuiltIn CullDistance\n"
   1555           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1556           AllSpirV10Capabilities())
   1557 )),);
   1558 
   1559 INSTANTIATE_TEST_CASE_P(Capabilities, ValidateCapabilityWebGPU,
   1560                         Combine(
   1561                             // All capabilities to try.
   1562                             ValuesIn(AllCapabilities()),
   1563                             Values(
   1564 std::make_pair(std::string(kVulkanMemoryModel) +
   1565           "OpEntryPoint Vertex %func \"shader\" \n" + std::string(kVoidFVoid),
   1566           AllWebGPUCapabilities())
   1567 )),);
   1568 
   1569 INSTANTIATE_TEST_CASE_P(Capabilities, ValidateCapabilityVulkan11,
   1570                         Combine(
   1571                             // All capabilities to try.
   1572                             ValuesIn(AllCapabilities()),
   1573                             Values(
   1574 std::make_pair(std::string(kGLSL450MemoryModel) +
   1575           "OpEntryPoint Vertex %func \"shader\" \n" +
   1576           "OpDecorate %intt BuiltIn PointSize\n"
   1577           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1578           AllVulkan11Capabilities()),
   1579 std::make_pair(std::string(kGLSL450MemoryModel) +
   1580           "OpEntryPoint Vertex %func \"shader\" \n" +
   1581           "OpDecorate %intt BuiltIn CullDistance\n"
   1582           "%intt = OpTypeInt 32 0\n" + std::string(kVoidFVoid),
   1583           AllVulkan11Capabilities())
   1584 )),);
   1585 
   1586 // TODO(umar): Selection Control
   1587 // TODO(umar): Loop Control
   1588 // TODO(umar): Function Control
   1589 // TODO(umar): Memory Semantics
   1590 // TODO(umar): Memory Access
   1591 // TODO(umar): Scope
   1592 // TODO(umar): Group Operation
   1593 // TODO(umar): Kernel Enqueue Flags
   1594 // TODO(umar): Kernel Profiling Flags
   1595 
   1596 INSTANTIATE_TEST_CASE_P(MatrixOp, ValidateCapability,
   1597                         Combine(
   1598                             ValuesIn(AllCapabilities()),
   1599                             Values(
   1600 std::make_pair(std::string(kOpenCLMemoryModel) +
   1601           "OpEntryPoint Kernel %func \"compute\" \n" +
   1602           "%f32      = OpTypeFloat 32\n"
   1603           "%vec3     = OpTypeVector %f32 3\n"
   1604           "%mat33    = OpTypeMatrix %vec3 3\n" + std::string(kVoidFVoid),
   1605           MatrixDependencies()))),);
   1606 // clang-format on
   1607 
   1608 #if 0
   1609 // TODO(atgoo (at) github.com) The following test is not valid as it generates
   1610 // invalid combinations of images, instructions and image operands.
   1611 //
   1612 // Creates assembly containing an OpImageFetch instruction using operands for
   1613 // the image-operands part.  The assembly defines constants %fzero and %izero
   1614 // that can be used for operands where IDs are required.  The assembly is valid,
   1615 // apart from not declaring any capabilities required by the operands.
   1616 string ImageOperandsTemplate(const std::string& operands) {
   1617   ostringstream ss;
   1618   // clang-format off
   1619   ss << R"(
   1620 OpCapability Kernel
   1621 OpCapability Linkage
   1622 OpMemoryModel Logical OpenCL
   1623 
   1624 %i32 = OpTypeInt 32 0
   1625 %f32 = OpTypeFloat 32
   1626 %v4i32 = OpTypeVector %i32 4
   1627 %timg = OpTypeImage %i32 2D 0 0 0 0 Unknown
   1628 %pimg = OpTypePointer UniformConstant %timg
   1629 %tfun = OpTypeFunction %i32
   1630 
   1631 %vimg = OpVariable %pimg UniformConstant
   1632 %izero = OpConstant %i32 0
   1633 %fzero = OpConstant %f32 0.
   1634 
   1635 %main = OpFunction %i32 None %tfun
   1636 %lbl = OpLabel
   1637 %img = OpLoad %timg %vimg
   1638 %r1 = OpImageFetch %v4i32 %img %izero )" << operands << R"(
   1639 OpReturnValue %izero
   1640 OpFunctionEnd
   1641 )";
   1642   // clang-format on
   1643   return ss.str();
   1644 }
   1645 
   1646 INSTANTIATE_TEST_CASE_P(
   1647     TwoImageOperandsMask, ValidateCapability,
   1648     Combine(
   1649         ValuesIn(AllCapabilities()),
   1650         Values(std::make_pair(ImageOperandsTemplate("Bias|Lod %fzero %fzero"),
   1651                          ShaderDependencies()),
   1652                std::make_pair(ImageOperandsTemplate("Lod|Offset %fzero %izero"),
   1653                          std::vector<std::string>{"ImageGatherExtended"}),
   1654                std::make_pair(ImageOperandsTemplate("Sample|MinLod %izero %fzero"),
   1655                          std::vector<std::string>{"MinLod"}),
   1656                std::make_pair(ImageOperandsTemplate("Lod|Sample %fzero %izero"),
   1657                          AllCapabilities()))), );
   1658 #endif
   1659 
   1660 // TODO(umar): Instruction capability checks
   1661 
   1662 spv_result_t spvCoreOperandTableNameLookup(spv_target_env env,
   1663                                            const spv_operand_table table,
   1664                                            const spv_operand_type_t type,
   1665                                            const char* name,
   1666                                            const size_t nameLength) {
   1667   if (!table) return SPV_ERROR_INVALID_TABLE;
   1668   if (!name) return SPV_ERROR_INVALID_POINTER;
   1669 
   1670   for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
   1671     const auto& group = table->types[typeIndex];
   1672     if (type != group.type) continue;
   1673     for (uint64_t index = 0; index < group.count; ++index) {
   1674       const auto& entry = group.entries[index];
   1675       // Check for min version only.
   1676       if (spvVersionForTargetEnv(env) >= entry.minVersion &&
   1677           nameLength == strlen(entry.name) &&
   1678           !strncmp(entry.name, name, nameLength)) {
   1679         return SPV_SUCCESS;
   1680       }
   1681     }
   1682   }
   1683 
   1684   return SPV_ERROR_INVALID_LOOKUP;
   1685 }
   1686 
   1687 // True if capability exists in core spec of env.
   1688 bool Exists(const std::string& capability, spv_target_env env) {
   1689   ScopedContext sc(env);
   1690   return SPV_SUCCESS ==
   1691          spvCoreOperandTableNameLookup(env, sc.context->operand_table,
   1692                                        SPV_OPERAND_TYPE_CAPABILITY,
   1693                                        capability.c_str(), capability.size());
   1694 }
   1695 
   1696 TEST_P(ValidateCapability, Capability) {
   1697   const std::string capability = Capability(GetParam());
   1698   spv_target_env env = SPV_ENV_UNIVERSAL_1_0;
   1699   if (!capability.empty()) {
   1700     if (Exists(capability, SPV_ENV_UNIVERSAL_1_0))
   1701       env = SPV_ENV_UNIVERSAL_1_0;
   1702     else if (Exists(capability, SPV_ENV_UNIVERSAL_1_1))
   1703       env = SPV_ENV_UNIVERSAL_1_1;
   1704     else if (Exists(capability, SPV_ENV_UNIVERSAL_1_2))
   1705       env = SPV_ENV_UNIVERSAL_1_2;
   1706     else
   1707       env = SPV_ENV_UNIVERSAL_1_3;
   1708   }
   1709   const std::string test_code = MakeAssembly(GetParam());
   1710   CompileSuccessfully(test_code, env);
   1711   ASSERT_EQ(ExpectedResult(GetParam()), ValidateInstructions(env))
   1712       << "target env: " << spvTargetEnvDescription(env) << "\ntest code:\n"
   1713       << test_code;
   1714 }
   1715 
   1716 TEST_P(ValidateCapabilityV11, Capability) {
   1717   const std::string capability = Capability(GetParam());
   1718   if (Exists(capability, SPV_ENV_UNIVERSAL_1_1)) {
   1719     const std::string test_code = MakeAssembly(GetParam());
   1720     CompileSuccessfully(test_code, SPV_ENV_UNIVERSAL_1_1);
   1721     ASSERT_EQ(ExpectedResult(GetParam()),
   1722               ValidateInstructions(SPV_ENV_UNIVERSAL_1_1))
   1723         << test_code;
   1724   }
   1725 }
   1726 
   1727 TEST_P(ValidateCapabilityVulkan10, Capability) {
   1728   const std::string capability = Capability(GetParam());
   1729   if (Exists(capability, SPV_ENV_VULKAN_1_0)) {
   1730     const std::string test_code = MakeAssembly(GetParam());
   1731     CompileSuccessfully(test_code, SPV_ENV_VULKAN_1_0);
   1732     ASSERT_EQ(ExpectedResult(GetParam()),
   1733               ValidateInstructions(SPV_ENV_VULKAN_1_0))
   1734         << test_code;
   1735   }
   1736 }
   1737 
   1738 TEST_P(ValidateCapabilityVulkan11, Capability) {
   1739   const std::string capability = Capability(GetParam());
   1740   if (Exists(capability, SPV_ENV_VULKAN_1_1)) {
   1741     const std::string test_code = MakeAssembly(GetParam());
   1742     CompileSuccessfully(test_code, SPV_ENV_VULKAN_1_1);
   1743     ASSERT_EQ(ExpectedResult(GetParam()),
   1744               ValidateInstructions(SPV_ENV_VULKAN_1_1))
   1745         << test_code;
   1746   }
   1747 }
   1748 
   1749 TEST_P(ValidateCapabilityOpenGL40, Capability) {
   1750   const std::string capability = Capability(GetParam());
   1751   if (Exists(capability, SPV_ENV_OPENGL_4_0)) {
   1752     const std::string test_code = MakeAssembly(GetParam());
   1753     CompileSuccessfully(test_code, SPV_ENV_OPENGL_4_0);
   1754     ASSERT_EQ(ExpectedResult(GetParam()),
   1755               ValidateInstructions(SPV_ENV_OPENGL_4_0))
   1756         << test_code;
   1757   }
   1758 }
   1759 
   1760 TEST_P(ValidateCapabilityWebGPU, Capability) {
   1761   const std::string capability = Capability(GetParam());
   1762   if (Exists(capability, SPV_ENV_WEBGPU_0)) {
   1763     const std::string test_code = MakeAssembly(GetParam());
   1764     CompileSuccessfully(test_code, SPV_ENV_WEBGPU_0);
   1765     ASSERT_EQ(ExpectedResult(GetParam()),
   1766               ValidateInstructions(SPV_ENV_WEBGPU_0))
   1767         << test_code;
   1768   }
   1769 }
   1770 
   1771 TEST_F(ValidateCapability, SemanticsIdIsAnIdNotALiteral) {
   1772   // From https://github.com/KhronosGroup/SPIRV-Tools/issues/248
   1773   // The validator was interpreting the memory semantics ID number
   1774   // as the value to be checked rather than an ID that references
   1775   // another value to be checked.
   1776   // In this case a raw ID of 64 was mistaken to mean a literal
   1777   // semantic value of UniformMemory, which would require the Shader
   1778   // capability.
   1779   const char str[] = R"(
   1780 OpCapability Kernel
   1781 OpCapability Linkage
   1782 OpMemoryModel Logical OpenCL
   1783 
   1784 ;  %i32 has ID 1
   1785 %i32    = OpTypeInt 32 0
   1786 %tf     = OpTypeFunction %i32
   1787 %pi32   = OpTypePointer CrossWorkgroup %i32
   1788 %var    = OpVariable %pi32 CrossWorkgroup
   1789 %c      = OpConstant %i32 100
   1790 %scope  = OpConstant %i32 1 ; Device scope
   1791 
   1792 ; Fake an instruction with 64 as the result id.
   1793 ; !64 = OpConstantNull %i32
   1794 !0x3002e !1 !64
   1795 
   1796 %f = OpFunction %i32 None %tf
   1797 %l = OpLabel
   1798 %result = OpAtomicIAdd %i32 %var %scope !64 %c
   1799 OpReturnValue %result
   1800 OpFunctionEnd
   1801 )";
   1802 
   1803   CompileSuccessfully(str);
   1804 
   1805   // Since we are forcing usage of <id> 64, the "id bound" in the binary header
   1806   // must be overwritten so that <id> 64 is considered within bound.
   1807   // ID Bound is at index 3 of the binary. Set it to 65.
   1808   OverwriteAssembledBinary(3, 65);
   1809 
   1810   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
   1811 }
   1812 
   1813 TEST_F(ValidateCapability, IntSignednessKernelGood) {
   1814   const std::string spirv = R"(
   1815 OpCapability Kernel
   1816 OpCapability Linkage
   1817 OpMemoryModel Logical OpenCL
   1818 %i32    = OpTypeInt 32 0
   1819 )";
   1820   CompileSuccessfully(spirv);
   1821   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
   1822 }
   1823 
   1824 TEST_F(ValidateCapability, IntSignednessKernelBad) {
   1825   const std::string spirv = R"(
   1826 OpCapability Kernel
   1827 OpCapability Linkage
   1828 OpMemoryModel Logical OpenCL
   1829 %i32    = OpTypeInt 32 1
   1830 )";
   1831   CompileSuccessfully(spirv);
   1832   EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
   1833   EXPECT_THAT(getDiagnosticString(),
   1834               HasSubstr("The Signedness in OpTypeInt must always be 0 when "
   1835                         "Kernel capability is used."));
   1836 }
   1837 
   1838 TEST_F(ValidateCapability, IntSignednessShaderGood) {
   1839   const std::string spirv = R"(
   1840 OpCapability Shader
   1841 OpCapability Linkage
   1842 OpMemoryModel Logical GLSL450
   1843 %u32    = OpTypeInt 32 0
   1844 %i32    = OpTypeInt 32 1
   1845 )";
   1846   CompileSuccessfully(spirv);
   1847   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
   1848 }
   1849 
   1850 TEST_F(ValidateCapability, NonVulkan10Capability) {
   1851   const std::string spirv = R"(
   1852 OpCapability Shader
   1853 OpCapability Linkage
   1854 OpMemoryModel Logical GLSL450
   1855 %u32    = OpTypeInt 32 0
   1856 %i32    = OpTypeInt 32 1
   1857 )";
   1858   CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
   1859   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   1860             ValidateInstructions(SPV_ENV_VULKAN_1_0));
   1861   EXPECT_THAT(getDiagnosticString(),
   1862               HasSubstr("Capability Linkage is not allowed by Vulkan 1.0"));
   1863 }
   1864 
   1865 TEST_F(ValidateCapability, Vulkan10EnabledByExtension) {
   1866   const std::string spirv = R"(
   1867 OpCapability Shader
   1868 OpCapability DrawParameters
   1869 OpExtension "SPV_KHR_shader_draw_parameters"
   1870 OpMemoryModel Logical GLSL450
   1871 OpEntryPoint Vertex %func "shader"
   1872 OpMemberDecorate %block 0 BuiltIn PointSize
   1873 %f32 = OpTypeFloat 32
   1874 %block = OpTypeStruct %f32
   1875 )" + std::string(kVoidFVoid);
   1876 
   1877   CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
   1878   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
   1879 }
   1880 
   1881 TEST_F(ValidateCapability, Vulkan10NotEnabledByExtension) {
   1882   const std::string spirv = R"(
   1883 OpCapability Shader
   1884 OpCapability DrawParameters
   1885 OpMemoryModel Logical GLSL450
   1886 OpEntryPoint Vertex %func "shader"
   1887 OpDecorate %intt BuiltIn PointSize
   1888 %intt = OpTypeInt 32 0
   1889 )" + std::string(kVoidFVoid);
   1890 
   1891   CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
   1892   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   1893             ValidateInstructions(SPV_ENV_VULKAN_1_0));
   1894   EXPECT_THAT(
   1895       getDiagnosticString(),
   1896       HasSubstr("Capability DrawParameters is not allowed by Vulkan 1.0"));
   1897 }
   1898 
   1899 TEST_F(ValidateCapability, NonOpenCL12FullCapability) {
   1900   const std::string spirv = R"(
   1901 OpCapability Kernel
   1902 OpCapability Addresses
   1903 OpCapability Linkage
   1904 OpCapability Pipes
   1905 OpMemoryModel Physical64 OpenCL
   1906 %u32    = OpTypeInt 32 0
   1907 )";
   1908   CompileSuccessfully(spirv, SPV_ENV_OPENCL_1_2);
   1909   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   1910             ValidateInstructions(SPV_ENV_OPENCL_1_2));
   1911   EXPECT_THAT(
   1912       getDiagnosticString(),
   1913       HasSubstr("Capability Pipes is not allowed by OpenCL 1.2 Full Profile"));
   1914 }
   1915 
   1916 TEST_F(ValidateCapability, OpenCL12FullEnabledByCapability) {
   1917   const std::string spirv = R"(
   1918 OpCapability Kernel
   1919 OpCapability Addresses
   1920 OpCapability Linkage
   1921 OpCapability ImageBasic
   1922 OpCapability Sampled1D
   1923 OpMemoryModel Physical64 OpenCL
   1924 %u32    = OpTypeInt 32 0
   1925 )" + std::string(kVoidFVoid);
   1926 
   1927   CompileSuccessfully(spirv, SPV_ENV_OPENCL_1_2);
   1928   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_1_2));
   1929 }
   1930 
   1931 TEST_F(ValidateCapability, OpenCL12FullNotEnabledByCapability) {
   1932   const std::string spirv = R"(
   1933 OpCapability Kernel
   1934 OpCapability Addresses
   1935 OpCapability Linkage
   1936 OpCapability Sampled1D
   1937 OpMemoryModel Physical64 OpenCL
   1938 %u32    = OpTypeInt 32 0
   1939 )" + std::string(kVoidFVoid);
   1940 
   1941   CompileSuccessfully(spirv, SPV_ENV_OPENCL_1_2);
   1942   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   1943             ValidateInstructions(SPV_ENV_OPENCL_1_2));
   1944   EXPECT_THAT(
   1945       getDiagnosticString(),
   1946       HasSubstr(
   1947           "Capability Sampled1D is not allowed by OpenCL 1.2 Full Profile"));
   1948 }
   1949 
   1950 TEST_F(ValidateCapability, NonOpenCL12EmbeddedCapability) {
   1951   const std::string spirv = R"(
   1952 OpCapability Kernel
   1953 OpCapability Addresses
   1954 OpCapability Linkage
   1955 OpCapability Int64
   1956 OpMemoryModel Physical64 OpenCL
   1957 %u32    = OpTypeInt 32 0
   1958 )";
   1959   CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_1_2);
   1960   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   1961             ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_1_2));
   1962   EXPECT_THAT(
   1963       getDiagnosticString(),
   1964       HasSubstr(
   1965           "Capability Int64 is not allowed by OpenCL 1.2 Embedded Profile"));
   1966 }
   1967 
   1968 TEST_F(ValidateCapability, OpenCL12EmbeddedEnabledByCapability) {
   1969   const std::string spirv = R"(
   1970 OpCapability Kernel
   1971 OpCapability Addresses
   1972 OpCapability Linkage
   1973 OpCapability ImageBasic
   1974 OpCapability Sampled1D
   1975 OpMemoryModel Physical64 OpenCL
   1976 %u32    = OpTypeInt 32 0
   1977 )" + std::string(kVoidFVoid);
   1978 
   1979   CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_1_2);
   1980   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_1_2));
   1981 }
   1982 
   1983 TEST_F(ValidateCapability, OpenCL12EmbeddedNotEnabledByCapability) {
   1984   const std::string spirv = R"(
   1985 OpCapability Kernel
   1986 OpCapability Addresses
   1987 OpCapability Linkage
   1988 OpCapability Sampled1D
   1989 OpMemoryModel Physical64 OpenCL
   1990 %u32    = OpTypeInt 32 0
   1991 )" + std::string(kVoidFVoid);
   1992 
   1993   CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_1_2);
   1994   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   1995             ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_1_2));
   1996   EXPECT_THAT(getDiagnosticString(),
   1997               HasSubstr("Capability Sampled1D is not allowed by OpenCL 1.2 "
   1998                         "Embedded Profile"));
   1999 }
   2000 
   2001 TEST_F(ValidateCapability, OpenCL20FullCapability) {
   2002   const std::string spirv = R"(
   2003 OpCapability Kernel
   2004 OpCapability Addresses
   2005 OpCapability Linkage
   2006 OpCapability Pipes
   2007 OpMemoryModel Physical64 OpenCL
   2008 %u32    = OpTypeInt 32 0
   2009 )";
   2010   CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_0);
   2011   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_0));
   2012 }
   2013 
   2014 TEST_F(ValidateCapability, NonOpenCL20FullCapability) {
   2015   const std::string spirv = R"(
   2016 OpCapability Kernel
   2017 OpCapability Addresses
   2018 OpCapability Linkage
   2019 OpCapability Matrix
   2020 OpMemoryModel Physical64 OpenCL
   2021 %u32    = OpTypeInt 32 0
   2022 )";
   2023   CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_0);
   2024   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   2025             ValidateInstructions(SPV_ENV_OPENCL_2_0));
   2026   EXPECT_THAT(
   2027       getDiagnosticString(),
   2028       HasSubstr(
   2029           "Capability Matrix is not allowed by OpenCL 2.0/2.1 Full Profile"));
   2030 }
   2031 
   2032 TEST_F(ValidateCapability, OpenCL20FullEnabledByCapability) {
   2033   const std::string spirv = R"(
   2034 OpCapability Kernel
   2035 OpCapability Addresses
   2036 OpCapability Linkage
   2037 OpCapability ImageBasic
   2038 OpCapability Sampled1D
   2039 OpMemoryModel Physical64 OpenCL
   2040 %u32    = OpTypeInt 32 0
   2041 )" + std::string(kVoidFVoid);
   2042 
   2043   CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_0);
   2044   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_0));
   2045 }
   2046 
   2047 TEST_F(ValidateCapability, OpenCL20FullNotEnabledByCapability) {
   2048   const std::string spirv = R"(
   2049 OpCapability Kernel
   2050 OpCapability Addresses
   2051 OpCapability Linkage
   2052 OpCapability Sampled1D
   2053 OpMemoryModel Physical64 OpenCL
   2054 %u32    = OpTypeInt 32 0
   2055 )" + std::string(kVoidFVoid);
   2056 
   2057   CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_0);
   2058   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   2059             ValidateInstructions(SPV_ENV_OPENCL_2_0));
   2060   EXPECT_THAT(getDiagnosticString(),
   2061               HasSubstr("Capability Sampled1D is not allowed by OpenCL 2.0/2.1 "
   2062                         "Full Profile"));
   2063 }
   2064 
   2065 TEST_F(ValidateCapability, NonOpenCL20EmbeddedCapability) {
   2066   const std::string spirv = R"(
   2067 OpCapability Kernel
   2068 OpCapability Addresses
   2069 OpCapability Linkage
   2070 OpCapability Int64
   2071 OpMemoryModel Physical64 OpenCL
   2072 %u32    = OpTypeInt 32 0
   2073 )";
   2074   CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_2_0);
   2075   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   2076             ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_2_0));
   2077   EXPECT_THAT(getDiagnosticString(),
   2078               HasSubstr("Capability Int64 is not allowed by OpenCL 2.0/2.1 "
   2079                         "Embedded Profile"));
   2080 }
   2081 
   2082 TEST_F(ValidateCapability, OpenCL20EmbeddedEnabledByCapability) {
   2083   const std::string spirv = R"(
   2084 OpCapability Kernel
   2085 OpCapability Addresses
   2086 OpCapability Linkage
   2087 OpCapability ImageBasic
   2088 OpCapability Sampled1D
   2089 OpMemoryModel Physical64 OpenCL
   2090 %u32    = OpTypeInt 32 0
   2091 )" + std::string(kVoidFVoid);
   2092 
   2093   CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_2_0);
   2094   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_2_0));
   2095 }
   2096 
   2097 TEST_F(ValidateCapability, OpenCL20EmbeddedNotEnabledByCapability) {
   2098   const std::string spirv = R"(
   2099 OpCapability Kernel
   2100 OpCapability Addresses
   2101 OpCapability Linkage
   2102 OpCapability Sampled1D
   2103 OpMemoryModel Physical64 OpenCL
   2104 %u32    = OpTypeInt 32 0
   2105 )" + std::string(kVoidFVoid);
   2106 
   2107   CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_2_0);
   2108   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   2109             ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_2_0));
   2110   EXPECT_THAT(getDiagnosticString(),
   2111               HasSubstr("Capability Sampled1D is not allowed by OpenCL 2.0/2.1 "
   2112                         "Embedded Profile"));
   2113 }
   2114 
   2115 TEST_F(ValidateCapability, OpenCL22FullCapability) {
   2116   const std::string spirv = R"(
   2117 OpCapability Kernel
   2118 OpCapability Addresses
   2119 OpCapability Linkage
   2120 OpCapability PipeStorage
   2121 OpMemoryModel Physical64 OpenCL
   2122 %u32    = OpTypeInt 32 0
   2123 )";
   2124   CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_2);
   2125   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_2));
   2126 }
   2127 
   2128 TEST_F(ValidateCapability, NonOpenCL22FullCapability) {
   2129   const std::string spirv = R"(
   2130 OpCapability Kernel
   2131 OpCapability Addresses
   2132 OpCapability Linkage
   2133 OpCapability Matrix
   2134 OpMemoryModel Physical64 OpenCL
   2135 %u32    = OpTypeInt 32 0
   2136 )";
   2137   CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_2);
   2138   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   2139             ValidateInstructions(SPV_ENV_OPENCL_2_2));
   2140   EXPECT_THAT(
   2141       getDiagnosticString(),
   2142       HasSubstr("Capability Matrix is not allowed by OpenCL 2.2 Full Profile"));
   2143 }
   2144 
   2145 TEST_F(ValidateCapability, OpenCL22FullEnabledByCapability) {
   2146   const std::string spirv = R"(
   2147 OpCapability Kernel
   2148 OpCapability Addresses
   2149 OpCapability Linkage
   2150 OpCapability ImageBasic
   2151 OpCapability Sampled1D
   2152 OpMemoryModel Physical64 OpenCL
   2153 %u32    = OpTypeInt 32 0
   2154 )" + std::string(kVoidFVoid);
   2155 
   2156   CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_2);
   2157   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_2_2));
   2158 }
   2159 
   2160 TEST_F(ValidateCapability, OpenCL22FullNotEnabledByCapability) {
   2161   const std::string spirv = R"(
   2162 OpCapability Kernel
   2163 OpCapability Addresses
   2164 OpCapability Linkage
   2165 OpCapability Sampled1D
   2166 OpMemoryModel Physical64 OpenCL
   2167 %u32    = OpTypeInt 32 0
   2168 )" + std::string(kVoidFVoid);
   2169 
   2170   CompileSuccessfully(spirv, SPV_ENV_OPENCL_2_2);
   2171   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   2172             ValidateInstructions(SPV_ENV_OPENCL_2_2));
   2173   EXPECT_THAT(
   2174       getDiagnosticString(),
   2175       HasSubstr(
   2176           "Capability Sampled1D is not allowed by OpenCL 2.2 Full Profile"));
   2177 }
   2178 
   2179 TEST_F(ValidateCapability, NonOpenCL22EmbeddedCapability) {
   2180   const std::string spirv = R"(
   2181 OpCapability Kernel
   2182 OpCapability Addresses
   2183 OpCapability Linkage
   2184 OpCapability Int64
   2185 OpMemoryModel Physical64 OpenCL
   2186 %u32    = OpTypeInt 32 0
   2187 )";
   2188   CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_2_2);
   2189   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   2190             ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_2_2));
   2191   EXPECT_THAT(
   2192       getDiagnosticString(),
   2193       HasSubstr(
   2194           "Capability Int64 is not allowed by OpenCL 2.2 Embedded Profile"));
   2195 }
   2196 
   2197 TEST_F(ValidateCapability, OpenCL22EmbeddedEnabledByCapability) {
   2198   const std::string spirv = R"(
   2199 OpCapability Kernel
   2200 OpCapability Addresses
   2201 OpCapability Linkage
   2202 OpCapability ImageBasic
   2203 OpCapability Sampled1D
   2204 OpMemoryModel Physical64 OpenCL
   2205 %u32    = OpTypeInt 32 0
   2206 )" + std::string(kVoidFVoid);
   2207 
   2208   CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_2_2);
   2209   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_2_2));
   2210 }
   2211 
   2212 TEST_F(ValidateCapability, OpenCL22EmbeddedNotEnabledByCapability) {
   2213   const std::string spirv = R"(
   2214 OpCapability Kernel
   2215 OpCapability Addresses
   2216 OpCapability Linkage
   2217 OpCapability Sampled1D
   2218 OpMemoryModel Physical64 OpenCL
   2219 %u32    = OpTypeInt 32 0
   2220 )" + std::string(kVoidFVoid);
   2221 
   2222   CompileSuccessfully(spirv, SPV_ENV_OPENCL_EMBEDDED_2_2);
   2223   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   2224             ValidateInstructions(SPV_ENV_OPENCL_EMBEDDED_2_2));
   2225   EXPECT_THAT(getDiagnosticString(),
   2226               HasSubstr("Capability Sampled1D is not allowed by OpenCL 2.2 "
   2227                         "Embedded Profile"));
   2228 }
   2229 
   2230 // Three tests to check enablement of an enum (a decoration) which is not
   2231 // in core, and is directly enabled by a capability, but not directly enabled
   2232 // by an extension.  See https://github.com/KhronosGroup/SPIRV-Tools/issues/1596
   2233 
   2234 TEST_F(ValidateCapability, DecorationFromExtensionMissingEnabledByCapability) {
   2235   // Decoration ViewportRelativeNV is enabled by ShaderViewportMaskNV, which in
   2236   // turn is enabled by SPV_NV_viewport_array2.
   2237   const std::string spirv = R"(
   2238 OpCapability Shader
   2239 OpMemoryModel Logical Simple
   2240 OpDecorate %void ViewportRelativeNV
   2241 )" + std::string(kVoidFVoid);
   2242 
   2243   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_0);
   2244   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   2245             ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
   2246   EXPECT_THAT(getDiagnosticString(),
   2247               HasSubstr("Operand 2 of Decorate requires one of these "
   2248                         "capabilities: ShaderViewportMaskNV"));
   2249 }
   2250 
   2251 TEST_F(ValidateCapability, CapabilityEnabledByMissingExtension) {
   2252   // Capability ShaderViewportMaskNV is enabled by SPV_NV_viewport_array2.
   2253   const std::string spirv = R"(
   2254 OpCapability Shader
   2255 OpCapability ShaderViewportMaskNV
   2256 OpMemoryModel Logical Simple
   2257 )" + std::string(kVoidFVoid);
   2258 
   2259   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_0);
   2260   EXPECT_EQ(SPV_ERROR_MISSING_EXTENSION,
   2261             ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
   2262   EXPECT_THAT(getDiagnosticString(),
   2263               HasSubstr("operand 5255 requires one of these extensions: "
   2264                         "SPV_NV_viewport_array2"));
   2265 }
   2266 
   2267 TEST_F(ValidateCapability,
   2268        DecorationEnabledByCapabilityEnabledByPresentExtension) {
   2269   // Decoration ViewportRelativeNV is enabled by ShaderViewportMaskNV, which in
   2270   // turn is enabled by SPV_NV_viewport_array2.
   2271   const std::string spirv = R"(
   2272 OpCapability Shader
   2273 OpCapability Linkage
   2274 OpCapability ShaderViewportMaskNV
   2275 OpExtension "SPV_NV_viewport_array2"
   2276 OpMemoryModel Logical Simple
   2277 OpDecorate %void ViewportRelativeNV
   2278 %void = OpTypeVoid
   2279 )";
   2280 
   2281   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_0);
   2282   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0))
   2283       << getDiagnosticString();
   2284 }
   2285 
   2286 // Three tests to check enablement of an instruction  which is not in core, and
   2287 // is directly enabled by a capability, but not directly enabled by an
   2288 // extension. See https://github.com/KhronosGroup/SPIRV-Tools/issues/1624
   2289 // Instruction OpSubgroupShuffleINTEL is enabled by SubgroupShuffleINTEL, which
   2290 // in turn is enabled by SPV_INTEL_subgroups.
   2291 
   2292 TEST_F(ValidateCapability, InstructionFromExtensionMissingEnabledByCapability) {
   2293   // Decoration ViewportRelativeNV is enabled by ShaderViewportMaskNV, which in
   2294   // turn is enabled by SPV_NV_viewport_array2.
   2295   const std::string spirv = R"(
   2296 OpCapability Kernel
   2297 OpCapability Addresses
   2298 ; OpCapability SubgroupShuffleINTEL
   2299 OpExtension "SPV_INTEL_subgroups"
   2300 OpMemoryModel Physical32 OpenCL
   2301 OpEntryPoint Kernel %main "main"
   2302 %void = OpTypeVoid
   2303 %uint = OpTypeInt 32 0
   2304 %voidfn = OpTypeFunction %void
   2305 %zero = OpConstant %uint 0
   2306 %main = OpFunction %void None %voidfn
   2307 %entry = OpLabel
   2308 %foo = OpSubgroupShuffleINTEL %uint %zero %zero
   2309 OpReturn
   2310 OpFunctionEnd
   2311 )";
   2312 
   2313   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_0);
   2314   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
   2315             ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
   2316   EXPECT_THAT(getDiagnosticString(),
   2317               HasSubstr("Opcode SubgroupShuffleINTEL requires one of these "
   2318                         "capabilities: SubgroupShuffleINTEL"));
   2319 }
   2320 
   2321 TEST_F(ValidateCapability,
   2322        InstructionEnablingCapabilityEnabledByMissingExtension) {
   2323   const std::string spirv = R"(
   2324 OpCapability Kernel
   2325 OpCapability Addresses
   2326 OpCapability SubgroupShuffleINTEL
   2327 ; OpExtension "SPV_INTEL_subgroups"
   2328 OpMemoryModel Physical32 OpenCL
   2329 OpEntryPoint Kernel %main "main"
   2330 %void = OpTypeVoid
   2331 %uint = OpTypeInt 32 0
   2332 %voidfn = OpTypeFunction %void
   2333 %zero = OpConstant %uint 0
   2334 %main = OpFunction %void None %voidfn
   2335 %entry = OpLabel
   2336 %foo = OpSubgroupShuffleINTEL %uint %zero %zero
   2337 OpReturn
   2338 OpFunctionEnd
   2339 )";
   2340 
   2341   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_0);
   2342   EXPECT_EQ(SPV_ERROR_MISSING_EXTENSION,
   2343             ValidateInstructions(SPV_ENV_UNIVERSAL_1_0));
   2344   EXPECT_THAT(getDiagnosticString(),
   2345               HasSubstr("operand 5568 requires one of these extensions: "
   2346                         "SPV_INTEL_subgroups"));
   2347 }
   2348 
   2349 TEST_F(ValidateCapability,
   2350        InstructionEnabledByCapabilityEnabledByPresentExtension) {
   2351   const std::string spirv = R"(
   2352 OpCapability Kernel
   2353 OpCapability Addresses
   2354 OpCapability SubgroupShuffleINTEL
   2355 OpExtension "SPV_INTEL_subgroups"
   2356 OpMemoryModel Physical32 OpenCL
   2357 OpEntryPoint Kernel %main "main"
   2358 %void = OpTypeVoid
   2359 %uint = OpTypeInt 32 0
   2360 %voidfn = OpTypeFunction %void
   2361 %zero = OpConstant %uint 0
   2362 %main = OpFunction %void None %voidfn
   2363 %entry = OpLabel
   2364 %foo = OpSubgroupShuffleINTEL %uint %zero %zero
   2365 OpReturn
   2366 OpFunctionEnd
   2367 )";
   2368 
   2369   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_0);
   2370   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_0))
   2371       << getDiagnosticString();
   2372 }
   2373 
   2374 TEST_F(ValidateCapability, VulkanMemoryModelWithVulkanKHR) {
   2375   const std::string spirv = R"(
   2376 OpCapability Shader
   2377 OpCapability VulkanMemoryModelKHR
   2378 OpCapability Linkage
   2379 OpExtension "SPV_KHR_vulkan_memory_model"
   2380 OpMemoryModel Logical VulkanKHR
   2381 )";
   2382 
   2383   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
   2384   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3))
   2385       << getDiagnosticString();
   2386 }
   2387 
   2388 TEST_F(ValidateCapability, VulkanMemoryModelWithGLSL450) {
   2389   const std::string spirv = R"(
   2390 OpCapability Shader
   2391 OpCapability VulkanMemoryModelKHR
   2392 OpCapability Linkage
   2393 OpExtension "SPV_KHR_vulkan_memory_model"
   2394 OpMemoryModel Logical GLSL450
   2395 )";
   2396 
   2397   CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
   2398   EXPECT_EQ(SPV_ERROR_INVALID_DATA,
   2399             ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
   2400   EXPECT_THAT(getDiagnosticString(),
   2401               HasSubstr("VulkanMemoryModelKHR capability must only be "
   2402                         "specified if the VulkanKHR memory model is used"));
   2403 }
   2404 
   2405 }  // namespace
   2406 }  // namespace val
   2407 }  // namespace spvtools
   2408