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