• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 #include <gmock/gmock.h>
23 
24 #include "source/assembly_grammar.h"
25 #include "test_fixture.h"
26 #include "unit_spirv.h"
27 #include "val_fixtures.h"
28 
29 namespace {
30 
31 using spvtest::ScopedContext;
32 using std::get;
33 using std::make_pair;
34 using std::ostringstream;
35 using std::pair;
36 using std::string;
37 using std::tuple;
38 using std::vector;
39 using testing::Combine;
40 using testing::HasSubstr;
41 using testing::Values;
42 using testing::ValuesIn;
43 
44 // Parameter for validation test fixtures.  The first string is a capability
45 // name that will begin the assembly under test, the second the remainder
46 // assembly, and the vector at the end determines whether the test expects
47 // success or failure.  See below for details and convenience methods to access
48 // each one.
49 //
50 // The assembly to test is composed from a variable top line and a fixed
51 // remainder.  The top line will be an OpCapability instruction, while the
52 // remainder will be some assembly text that succeeds or fails to assemble
53 // depending on which capability was chosen.  For instance, the following will
54 // succeed:
55 //
56 // OpCapability Pipes ; implies Kernel
57 // OpLifetimeStop %1 0 ; requires Kernel
58 //
59 // and the following will fail:
60 //
61 // OpCapability Kernel
62 // %1 = OpTypeNamedBarrier ; requires NamedBarrier
63 //
64 // So how does the test parameter capture which capabilities should cause
65 // success and which shouldn't?  The answer is in the last element: it's a
66 // vector of capabilities that make the remainder assembly succeed.  So if the
67 // first-line capability exists in that vector, success is expected; otherwise,
68 // failure is expected in the tests.
69 //
70 // We will use testing::Combine() to vary the first line: when we combine
71 // AllCapabilities() with a single remainder assembly, we generate enough test
72 // cases to try the assembly with every possible capability that could be
73 // declared. However, Combine() only produces tuples -- it cannot produce, say,
74 // a struct.  Therefore, this type must be a tuple.
75 using CapTestParameter = tuple<string, pair<string, vector<string>>>;
76 
Capability(const CapTestParameter & p)77 const string& Capability(const CapTestParameter& p) { return get<0>(p); }
Remainder(const CapTestParameter & p)78 const string& Remainder(const CapTestParameter& p) { return get<1>(p).first; }
MustSucceed(const CapTestParameter & p)79 const vector<string>& MustSucceed(const CapTestParameter& p) {
80   return get<1>(p).second;
81 }
82 
83 // Creates assembly to test from p.
MakeAssembly(const CapTestParameter & p)84 string MakeAssembly(const CapTestParameter& p) {
85   ostringstream ss;
86   const string& capability = Capability(p);
87   if (!capability.empty()) {
88     ss << "OpCapability " << capability << "\n";
89   }
90   ss << Remainder(p);
91   return ss.str();
92 }
93 
94 // Expected validation result for p.
ExpectedResult(const CapTestParameter & p)95 spv_result_t ExpectedResult(const CapTestParameter& p) {
96   const auto& caps = MustSucceed(p);
97   auto found = find(begin(caps), end(caps), Capability(p));
98   return (found == end(caps)) ? SPV_ERROR_INVALID_CAPABILITY : SPV_SUCCESS;
99 }
100 
101 // Assembles using v1.0, unless the parameter's capability requires v1.1.
102 using ValidateCapability = spvtest::ValidateBase<CapTestParameter>;
103 
104 // Always assembles using v1.1.
105 using ValidateCapabilityV11 = spvtest::ValidateBase<CapTestParameter>;
106 
107 // Always assembles using Vulkan 1.0.
108 // TODO(dneto): Refactor all these tests to scale better across environments.
109 using ValidateCapabilityVulkan10 = spvtest::ValidateBase<CapTestParameter>;
110 // Always assembles using OpenGL 4.0.
111 using ValidateCapabilityOpenGL40 = spvtest::ValidateBase<CapTestParameter>;
112 
TEST_F(ValidateCapability,Default)113 TEST_F(ValidateCapability, Default) {
114   const char str[] = R"(
115             OpCapability Kernel
116             OpCapability Linkage
117             OpCapability Matrix
118             OpMemoryModel Logical OpenCL
119 %f32      = OpTypeFloat 32
120 %vec3     = OpTypeVector %f32 3
121 %mat33    = OpTypeMatrix %vec3 3
122 )";
123 
124   CompileSuccessfully(str);
125   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
126 }
127 
128 // clang-format off
AllCapabilities()129 const vector<string>& AllCapabilities() {
130   static const auto r = new vector<string>{
131     "",
132     "Matrix",
133     "Shader",
134     "Geometry",
135     "Tessellation",
136     "Addresses",
137     "Linkage",
138     "Kernel",
139     "Vector16",
140     "Float16Buffer",
141     "Float16",
142     "Float64",
143     "Int64",
144     "Int64Atomics",
145     "ImageBasic",
146     "ImageReadWrite",
147     "ImageMipmap",
148     "Pipes",
149     "Groups",
150     "DeviceEnqueue",
151     "LiteralSampler",
152     "AtomicStorage",
153     "Int16",
154     "TessellationPointSize",
155     "GeometryPointSize",
156     "ImageGatherExtended",
157     "StorageImageMultisample",
158     "UniformBufferArrayDynamicIndexing",
159     "SampledImageArrayDynamicIndexing",
160     "StorageBufferArrayDynamicIndexing",
161     "StorageImageArrayDynamicIndexing",
162     "ClipDistance",
163     "CullDistance",
164     "ImageCubeArray",
165     "SampleRateShading",
166     "ImageRect",
167     "SampledRect",
168     "GenericPointer",
169     "Int8",
170     "InputAttachment",
171     "SparseResidency",
172     "MinLod",
173     "Sampled1D",
174     "Image1D",
175     "SampledCubeArray",
176     "SampledBuffer",
177     "ImageBuffer",
178     "ImageMSArray",
179     "StorageImageExtendedFormats",
180     "ImageQuery",
181     "DerivativeControl",
182     "InterpolationFunction",
183     "TransformFeedback",
184     "GeometryStreams",
185     "StorageImageReadWithoutFormat",
186     "StorageImageWriteWithoutFormat",
187     "MultiViewport",
188     "SubgroupDispatch",
189     "NamedBarrier",
190     "PipeStorage"};
191   return *r;
192 }
193 
AllSpirV10Capabilities()194 const vector<string>& AllSpirV10Capabilities() {
195   static const auto r = new vector<string>{
196     "",
197     "Matrix",
198     "Shader",
199     "Geometry",
200     "Tessellation",
201     "Addresses",
202     "Linkage",
203     "Kernel",
204     "Vector16",
205     "Float16Buffer",
206     "Float16",
207     "Float64",
208     "Int64",
209     "Int64Atomics",
210     "ImageBasic",
211     "ImageReadWrite",
212     "ImageMipmap",
213     "Pipes",
214     "Groups",
215     "DeviceEnqueue",
216     "LiteralSampler",
217     "AtomicStorage",
218     "Int16",
219     "TessellationPointSize",
220     "GeometryPointSize",
221     "ImageGatherExtended",
222     "StorageImageMultisample",
223     "UniformBufferArrayDynamicIndexing",
224     "SampledImageArrayDynamicIndexing",
225     "StorageBufferArrayDynamicIndexing",
226     "StorageImageArrayDynamicIndexing",
227     "ClipDistance",
228     "CullDistance",
229     "ImageCubeArray",
230     "SampleRateShading",
231     "ImageRect",
232     "SampledRect",
233     "GenericPointer",
234     "Int8",
235     "InputAttachment",
236     "SparseResidency",
237     "MinLod",
238     "Sampled1D",
239     "Image1D",
240     "SampledCubeArray",
241     "SampledBuffer",
242     "ImageBuffer",
243     "ImageMSArray",
244     "StorageImageExtendedFormats",
245     "ImageQuery",
246     "DerivativeControl",
247     "InterpolationFunction",
248     "TransformFeedback",
249     "GeometryStreams",
250     "StorageImageReadWithoutFormat",
251     "StorageImageWriteWithoutFormat",
252     "MultiViewport"};
253   return *r;
254 }
255 
AllVulkan10Capabilities()256 const vector<string>& AllVulkan10Capabilities() {
257   static const auto r = new vector<string>{
258     "",
259     "Matrix",
260     "Shader",
261     "InputAttachment",
262     "Sampled1D",
263     "Image1D",
264     "SampledBuffer",
265     "ImageBuffer",
266     "ImageQuery",
267     "DerivativeControl",
268     "Geometry",
269     "Tessellation",
270     "Float64",
271     "Int64",
272     "Int16",
273     "TessellationPointSize",
274     "GeometryPointSize",
275     "ImageGatherExtended",
276     "StorageImageMultisample",
277     "UniformBufferArrayDynamicIndexing",
278     "SampledImageArrayDynamicIndexing",
279     "StorageBufferArrayDynamicIndexing",
280     "StorageImageArrayDynamicIndexing",
281     "ClipDistance",
282     "CullDistance",
283     "ImageCubeArray",
284     "SampleRateShading",
285     "SparseResidency",
286     "MinLod",
287     "SampledCubeArray",
288     "ImageMSArray",
289     "StorageImageExtendedFormats",
290     "InterpolationFunction",
291     "StorageImageReadWithoutFormat",
292     "StorageImageWriteWithoutFormat",
293     "MultiViewport"};
294   return *r;
295 }
296 
MatrixDependencies()297 const vector<string>& MatrixDependencies() {
298   static const auto r = new vector<string>{
299   "Matrix",
300   "Shader",
301   "Geometry",
302   "Tessellation",
303   "AtomicStorage",
304   "TessellationPointSize",
305   "GeometryPointSize",
306   "ImageGatherExtended",
307   "StorageImageMultisample",
308   "UniformBufferArrayDynamicIndexing",
309   "SampledImageArrayDynamicIndexing",
310   "StorageBufferArrayDynamicIndexing",
311   "StorageImageArrayDynamicIndexing",
312   "ClipDistance",
313   "CullDistance",
314   "ImageCubeArray",
315   "SampleRateShading",
316   "ImageRect",
317   "SampledRect",
318   "InputAttachment",
319   "SparseResidency",
320   "MinLod",
321   "SampledCubeArray",
322   "ImageMSArray",
323   "StorageImageExtendedFormats",
324   "ImageQuery",
325   "DerivativeControl",
326   "InterpolationFunction",
327   "TransformFeedback",
328   "GeometryStreams",
329   "StorageImageReadWithoutFormat",
330   "StorageImageWriteWithoutFormat",
331   "MultiViewport"};
332   return *r;
333 }
334 
ShaderDependencies()335 const vector<string>& ShaderDependencies() {
336   static const auto r = new vector<string>{
337   "Shader",
338   "Geometry",
339   "Tessellation",
340   "AtomicStorage",
341   "TessellationPointSize",
342   "GeometryPointSize",
343   "ImageGatherExtended",
344   "StorageImageMultisample",
345   "UniformBufferArrayDynamicIndexing",
346   "SampledImageArrayDynamicIndexing",
347   "StorageBufferArrayDynamicIndexing",
348   "StorageImageArrayDynamicIndexing",
349   "ClipDistance",
350   "CullDistance",
351   "ImageCubeArray",
352   "SampleRateShading",
353   "ImageRect",
354   "SampledRect",
355   "InputAttachment",
356   "SparseResidency",
357   "MinLod",
358   "SampledCubeArray",
359   "ImageMSArray",
360   "StorageImageExtendedFormats",
361   "ImageQuery",
362   "DerivativeControl",
363   "InterpolationFunction",
364   "TransformFeedback",
365   "GeometryStreams",
366   "StorageImageReadWithoutFormat",
367   "StorageImageWriteWithoutFormat",
368   "MultiViewport"};
369   return *r;
370 }
371 
TessellationDependencies()372 const vector<string>& TessellationDependencies() {
373   static const auto r = new vector<string>{
374   "Tessellation",
375   "TessellationPointSize"};
376   return *r;
377 }
378 
GeometryDependencies()379 const vector<string>& GeometryDependencies() {
380   static const auto r = new vector<string>{
381   "Geometry",
382   "GeometryPointSize",
383   "GeometryStreams",
384   "MultiViewport"};
385   return *r;
386 }
387 
GeometryTessellationDependencies()388 const vector<string>& GeometryTessellationDependencies() {
389   static const auto r = new vector<string>{
390   "Tessellation",
391   "TessellationPointSize",
392   "Geometry",
393   "GeometryPointSize",
394   "GeometryStreams",
395   "MultiViewport"};
396   return *r;
397 }
398 
399 // Returns the names of capabilities that directly depend on Kernel,
400 // plus itself.
KernelDependencies()401 const vector<string>& KernelDependencies() {
402   static const auto r = new vector<string>{
403   "Kernel",
404   "Vector16",
405   "Float16Buffer",
406   "ImageBasic",
407   "ImageReadWrite",
408   "ImageMipmap",
409   "Pipes",
410   "DeviceEnqueue",
411   "LiteralSampler",
412   "Int8",
413   "SubgroupDispatch",
414   "NamedBarrier",
415   "PipeStorage"};
416   return *r;
417 }
418 
AddressesDependencies()419 const vector<string>& AddressesDependencies() {
420   static const auto r = new vector<string>{
421   "Addresses",
422   "GenericPointer"};
423   return *r;
424 }
425 
Sampled1DDependencies()426 const vector<string>& Sampled1DDependencies() {
427   static const auto r = new vector<string>{
428   "Sampled1D",
429   "Image1D"};
430   return *r;
431 }
432 
SampledRectDependencies()433 const vector<string>& SampledRectDependencies() {
434   static const auto r = new vector<string>{
435   "SampledRect",
436   "ImageRect"};
437   return *r;
438 }
439 
SampledBufferDependencies()440 const vector<string>& SampledBufferDependencies() {
441   static const auto r = new vector<string>{
442   "SampledBuffer",
443   "ImageBuffer"};
444   return *r;
445 }
446 
447 const char kOpenCLMemoryModel[] = \
448   " OpCapability Kernel"
449   " OpMemoryModel Logical OpenCL ";
450 
451 const char kGLSL450MemoryModel[] = \
452   " OpCapability Shader"
453   " OpMemoryModel Logical GLSL450 ";
454 
455 const char kVoidFVoid[] = \
456   " %void   = OpTypeVoid"
457   " %void_f = OpTypeFunction %void"
458   " %func   = OpFunction %void None %void_f"
459   " %label  = OpLabel"
460   "           OpReturn"
461   "           OpFunctionEnd ";
462 
463 const char kVoidFVoid2[] = \
464   " %void_f = OpTypeFunction %voidt"
465   " %func   = OpFunction %voidt None %void_f"
466   " %label  = OpLabel"
467   "           OpReturn"
468   "           OpFunctionEnd ";
469 
470 INSTANTIATE_TEST_CASE_P(ExecutionModel, ValidateCapability,
471                         Combine(
472                             ValuesIn(AllCapabilities()),
473                             Values(
474 make_pair(string(kOpenCLMemoryModel) +
475           " OpEntryPoint Vertex %func \"shader\"" +
476           string(kVoidFVoid), ShaderDependencies()),
477 make_pair(string(kOpenCLMemoryModel) +
478           " OpEntryPoint TessellationControl %func \"shader\"" +
479           string(kVoidFVoid), TessellationDependencies()),
480 make_pair(string(kOpenCLMemoryModel) +
481           " OpEntryPoint TessellationEvaluation %func \"shader\"" +
482           string(kVoidFVoid), TessellationDependencies()),
483 make_pair(string(kOpenCLMemoryModel) +
484           " OpEntryPoint Geometry %func \"shader\"" +
485           string(kVoidFVoid), GeometryDependencies()),
486 make_pair(string(kOpenCLMemoryModel) +
487           " OpEntryPoint Fragment %func \"shader\"" +
488           string(kVoidFVoid), ShaderDependencies()),
489 make_pair(string(kOpenCLMemoryModel) +
490           " OpEntryPoint GLCompute %func \"shader\"" +
491           string(kVoidFVoid), ShaderDependencies()),
492 make_pair(string(kGLSL450MemoryModel) +
493           " OpEntryPoint Kernel %func \"shader\"" +
494           string(kVoidFVoid), KernelDependencies())
495 )),);
496 
497 INSTANTIATE_TEST_CASE_P(AddressingAndMemoryModel, ValidateCapability,
498                         Combine(
499                             ValuesIn(AllCapabilities()),
500                             Values(
501 make_pair(" OpCapability Shader"
502           " OpMemoryModel Logical Simple"
503           " OpEntryPoint Vertex %func \"shader\"" +
504           string(kVoidFVoid),     AllCapabilities()),
505 make_pair(" OpCapability Shader"
506           " OpMemoryModel Logical GLSL450"
507           " OpEntryPoint Vertex %func \"shader\"" +
508           string(kVoidFVoid),    AllCapabilities()),
509 make_pair(" OpCapability Kernel"
510           " OpMemoryModel Logical OpenCL"
511           " OpEntryPoint Kernel %func \"compute\"" +
512           string(kVoidFVoid),     AllCapabilities()),
513 make_pair(" OpCapability Shader"
514           " OpMemoryModel Physical32 Simple"
515           " OpEntryPoint Vertex %func \"shader\"" +
516           string(kVoidFVoid),  AddressesDependencies()),
517 make_pair(" OpCapability Shader"
518           " OpMemoryModel Physical32 GLSL450"
519           " OpEntryPoint Vertex %func \"shader\"" +
520           string(kVoidFVoid), AddressesDependencies()),
521 make_pair(" OpCapability Kernel"
522           " OpMemoryModel Physical32 OpenCL"
523           " OpEntryPoint Kernel %func \"compute\"" +
524           string(kVoidFVoid),  AddressesDependencies()),
525 make_pair(" OpCapability Shader"
526           " OpMemoryModel Physical64 Simple"
527           " OpEntryPoint Vertex %func \"shader\"" +
528           string(kVoidFVoid),  AddressesDependencies()),
529 make_pair(" OpCapability Shader"
530           " OpMemoryModel Physical64 GLSL450"
531           " OpEntryPoint Vertex %func \"shader\"" +
532           string(kVoidFVoid), AddressesDependencies()),
533 make_pair(" OpCapability Kernel"
534           " OpMemoryModel Physical64 OpenCL"
535           " OpEntryPoint Kernel %func \"compute\"" +
536           string(kVoidFVoid),  AddressesDependencies())
537 )),);
538 
539 INSTANTIATE_TEST_CASE_P(ExecutionMode, ValidateCapability,
540                         Combine(
541                             ValuesIn(AllCapabilities()),
542                             Values(
543 make_pair(string(kOpenCLMemoryModel) +
544           "OpEntryPoint Geometry %func \"shader\" "
545           "OpExecutionMode %func Invocations 42" +
546           string(kVoidFVoid), GeometryDependencies()),
547 make_pair(string(kOpenCLMemoryModel) +
548           "OpEntryPoint TessellationControl %func \"shader\" "
549           "OpExecutionMode %func SpacingEqual" +
550           string(kVoidFVoid), TessellationDependencies()),
551 make_pair(string(kOpenCLMemoryModel) +
552           "OpEntryPoint TessellationControl %func \"shader\" "
553           "OpExecutionMode %func SpacingFractionalEven" +
554           string(kVoidFVoid), TessellationDependencies()),
555 make_pair(string(kOpenCLMemoryModel) +
556           "OpEntryPoint TessellationControl %func \"shader\" "
557           "OpExecutionMode %func SpacingFractionalOdd" +
558           string(kVoidFVoid), TessellationDependencies()),
559 make_pair(string(kOpenCLMemoryModel) +
560           "OpEntryPoint TessellationControl %func \"shader\" "
561           "OpExecutionMode %func VertexOrderCw" +
562           string(kVoidFVoid), TessellationDependencies()),
563 make_pair(string(kOpenCLMemoryModel) +
564           "OpEntryPoint TessellationControl %func \"shader\" "
565           "OpExecutionMode %func VertexOrderCcw" +
566           string(kVoidFVoid), TessellationDependencies()),
567 make_pair(string(kOpenCLMemoryModel) +
568           "OpEntryPoint Vertex %func \"shader\" "
569           "OpExecutionMode %func PixelCenterInteger" +
570           string(kVoidFVoid), ShaderDependencies()),
571 make_pair(string(kOpenCLMemoryModel) +
572           "OpEntryPoint Vertex %func \"shader\" "
573           "OpExecutionMode %func OriginUpperLeft" +
574           string(kVoidFVoid), ShaderDependencies()),
575 make_pair(string(kOpenCLMemoryModel) +
576           "OpEntryPoint Vertex %func \"shader\" "
577           "OpExecutionMode %func OriginLowerLeft" +
578           string(kVoidFVoid), ShaderDependencies()),
579 make_pair(string(kOpenCLMemoryModel) +
580           "OpEntryPoint Vertex %func \"shader\" "
581           "OpExecutionMode %func EarlyFragmentTests" +
582           string(kVoidFVoid), ShaderDependencies()),
583 make_pair(string(kOpenCLMemoryModel) +
584           "OpEntryPoint TessellationControl %func \"shader\" "
585           "OpExecutionMode %func PointMode" +
586           string(kVoidFVoid), TessellationDependencies()),
587 make_pair(string(kOpenCLMemoryModel) +
588           "OpEntryPoint Vertex %func \"shader\" "
589           "OpExecutionMode %func Xfb" +
590           string(kVoidFVoid), vector<string>{"TransformFeedback"}),
591 make_pair(string(kOpenCLMemoryModel) +
592           "OpEntryPoint Vertex %func \"shader\" "
593           "OpExecutionMode %func DepthReplacing" +
594           string(kVoidFVoid), ShaderDependencies()),
595 make_pair(string(kOpenCLMemoryModel) +
596           "OpEntryPoint Vertex %func \"shader\" "
597           "OpExecutionMode %func DepthGreater" +
598           string(kVoidFVoid), ShaderDependencies()),
599 make_pair(string(kOpenCLMemoryModel) +
600           "OpEntryPoint Vertex %func \"shader\" "
601           "OpExecutionMode %func DepthLess" +
602           string(kVoidFVoid), ShaderDependencies()),
603 make_pair(string(kOpenCLMemoryModel) +
604           "OpEntryPoint Vertex %func \"shader\" "
605           "OpExecutionMode %func DepthUnchanged" +
606           string(kVoidFVoid), ShaderDependencies()),
607 make_pair(string(kOpenCLMemoryModel) +
608           "OpEntryPoint Kernel %func \"shader\" "
609           "OpExecutionMode %func LocalSize 42 42 42" +
610           string(kVoidFVoid), AllCapabilities()),
611 make_pair(string(kGLSL450MemoryModel) +
612           "OpEntryPoint Kernel %func \"shader\" "
613           "OpExecutionMode %func LocalSizeHint 42 42 42" +
614           string(kVoidFVoid), KernelDependencies()),
615 make_pair(string(kOpenCLMemoryModel) +
616           "OpEntryPoint Geometry %func \"shader\" "
617           "OpExecutionMode %func InputPoints" +
618           string(kVoidFVoid), GeometryDependencies()),
619 make_pair(string(kOpenCLMemoryModel) +
620           "OpEntryPoint Geometry %func \"shader\" "
621           "OpExecutionMode %func InputLines" +
622           string(kVoidFVoid), GeometryDependencies()),
623 make_pair(string(kOpenCLMemoryModel) +
624           "OpEntryPoint Geometry %func \"shader\" "
625           "OpExecutionMode %func InputLinesAdjacency" +
626           string(kVoidFVoid), GeometryDependencies()),
627 make_pair(string(kOpenCLMemoryModel) +
628           "OpEntryPoint Geometry %func \"shader\" "
629           "OpExecutionMode %func Triangles" +
630           string(kVoidFVoid), GeometryDependencies()),
631 make_pair(string(kOpenCLMemoryModel) +
632           "OpEntryPoint TessellationControl %func \"shader\" "
633           "OpExecutionMode %func Triangles" +
634           string(kVoidFVoid), TessellationDependencies()),
635 make_pair(string(kOpenCLMemoryModel) +
636           "OpEntryPoint Geometry %func \"shader\" "
637           "OpExecutionMode %func InputTrianglesAdjacency" +
638           string(kVoidFVoid), GeometryDependencies()),
639 make_pair(string(kOpenCLMemoryModel) +
640           "OpEntryPoint TessellationControl %func \"shader\" "
641           "OpExecutionMode %func Quads" +
642           string(kVoidFVoid), TessellationDependencies()),
643 make_pair(string(kOpenCLMemoryModel) +
644           "OpEntryPoint TessellationControl %func \"shader\" "
645           "OpExecutionMode %func Isolines" +
646           string(kVoidFVoid), TessellationDependencies()),
647 make_pair(string(kOpenCLMemoryModel) +
648           "OpEntryPoint Geometry %func \"shader\" "
649           "OpExecutionMode %func OutputVertices 42" +
650           string(kVoidFVoid), GeometryDependencies()),
651 make_pair(string(kOpenCLMemoryModel) +
652           "OpEntryPoint TessellationControl %func \"shader\" "
653           "OpExecutionMode %func OutputVertices 42" +
654           string(kVoidFVoid), TessellationDependencies()),
655 make_pair(string(kOpenCLMemoryModel) +
656           "OpEntryPoint Geometry %func \"shader\" "
657           "OpExecutionMode %func OutputPoints" +
658           string(kVoidFVoid), GeometryDependencies()),
659 make_pair(string(kOpenCLMemoryModel) +
660           "OpEntryPoint Geometry %func \"shader\" "
661           "OpExecutionMode %func OutputLineStrip" +
662           string(kVoidFVoid), GeometryDependencies()),
663 make_pair(string(kOpenCLMemoryModel) +
664           "OpEntryPoint Geometry %func \"shader\" "
665           "OpExecutionMode %func OutputTriangleStrip" +
666           string(kVoidFVoid), GeometryDependencies()),
667 make_pair(string(kGLSL450MemoryModel) +
668           "OpEntryPoint Kernel %func \"shader\" "
669           "OpExecutionMode %func VecTypeHint 2" +
670           string(kVoidFVoid), KernelDependencies()),
671 make_pair(string(kGLSL450MemoryModel) +
672           "OpEntryPoint Kernel %func \"shader\" "
673           "OpExecutionMode %func ContractionOff" +
674           string(kVoidFVoid), KernelDependencies()))),);
675 
676 // clang-format on
677 
678 INSTANTIATE_TEST_CASE_P(
679     ExecutionModeV11, ValidateCapabilityV11,
680     Combine(ValuesIn(AllCapabilities()),
681             Values(make_pair(string(kOpenCLMemoryModel) +
682                                  "OpEntryPoint Kernel %func \"shader\" "
683                                  "OpExecutionMode %func SubgroupSize 1" +
684                                  string(kVoidFVoid),
685                              vector<string>{"SubgroupDispatch"}),
686                    make_pair(
687                        string(kOpenCLMemoryModel) +
688                            "OpEntryPoint Kernel %func \"shader\" "
689                            "OpExecutionMode %func SubgroupsPerWorkgroup 65535" +
690                            string(kVoidFVoid),
691                        vector<string>{"SubgroupDispatch"}))), );
692 // clang-format off
693 
694 INSTANTIATE_TEST_CASE_P(StorageClass, ValidateCapability,
695                         Combine(
696                             ValuesIn(AllCapabilities()),
697                             Values(
698 make_pair(string(kGLSL450MemoryModel) +
699           " OpEntryPoint Vertex %func \"shader\"" +
700           " %intt = OpTypeInt 32 0\n"
701           " %ptrt = OpTypePointer UniformConstant %intt\n"
702           " %var = OpVariable %ptrt UniformConstant\n" + string(kVoidFVoid),
703           AllCapabilities()),
704 make_pair(string(kOpenCLMemoryModel) +
705           " OpEntryPoint Kernel %func \"compute\"" +
706           " %intt = OpTypeInt 32 0\n"
707           " %ptrt = OpTypePointer Input %intt"
708           " %var = OpVariable %ptrt Input\n" + string(kVoidFVoid),
709           AllCapabilities()),
710 make_pair(string(kOpenCLMemoryModel) +
711           " OpEntryPoint Vertex %func \"shader\"" +
712           " %intt = OpTypeInt 32 0\n"
713           " %ptrt = OpTypePointer Uniform %intt\n"
714           " %var = OpVariable %ptrt Uniform\n" + string(kVoidFVoid),
715           ShaderDependencies()),
716 make_pair(string(kOpenCLMemoryModel) +
717           " OpEntryPoint Vertex %func \"shader\"" +
718           " %intt = OpTypeInt 32 0\n"
719           " %ptrt = OpTypePointer Output %intt\n"
720           " %var = OpVariable %ptrt Output\n" + string(kVoidFVoid),
721           ShaderDependencies()),
722 make_pair(string(kGLSL450MemoryModel) +
723           " OpEntryPoint Vertex %func \"shader\"" +
724           " %intt = OpTypeInt 32 0\n"
725           " %ptrt = OpTypePointer Workgroup %intt\n"
726           " %var = OpVariable %ptrt Workgroup\n" + string(kVoidFVoid),
727           AllCapabilities()),
728 make_pair(string(kGLSL450MemoryModel) +
729           " OpEntryPoint Vertex %func \"shader\"" +
730           " %intt = OpTypeInt 32 0\n"
731           " %ptrt = OpTypePointer CrossWorkgroup %intt\n"
732           " %var = OpVariable %ptrt CrossWorkgroup\n" + string(kVoidFVoid),
733           AllCapabilities()),
734 make_pair(string(kOpenCLMemoryModel) +
735           " OpEntryPoint Kernel %func \"compute\"" +
736           " %intt = OpTypeInt 32 0\n"
737           " %ptrt = OpTypePointer Private %intt\n"
738           " %var = OpVariable %ptrt Private\n" + string(kVoidFVoid),
739           ShaderDependencies()),
740 make_pair(string(kOpenCLMemoryModel) +
741           " OpEntryPoint Kernel %func \"compute\"" +
742           " %intt = OpTypeInt 32 0\n"
743           " %ptrt = OpTypePointer PushConstant %intt\n"
744           " %var = OpVariable %ptrt PushConstant\n" + string(kVoidFVoid),
745           ShaderDependencies()),
746 make_pair(string(kGLSL450MemoryModel) +
747           " OpEntryPoint Vertex %func \"shader\"" +
748           " %intt = OpTypeInt 32 0\n"
749           " %ptrt = OpTypePointer AtomicCounter %intt\n"
750           " %var = OpVariable %ptrt AtomicCounter\n" + string(kVoidFVoid),
751           vector<string>{"AtomicStorage"}),
752 make_pair(string(kGLSL450MemoryModel) +
753           " OpEntryPoint Vertex %func \"shader\"" +
754           " %intt = OpTypeInt 32 0\n"
755           " %ptrt = OpTypePointer Image %intt\n"
756           " %var = OpVariable %ptrt Image\n" + string(kVoidFVoid),
757           AllCapabilities())
758 )),);
759 
760 INSTANTIATE_TEST_CASE_P(Dim, ValidateCapability,
761                         Combine(
762                             ValuesIn(AllCapabilities()),
763                             Values(
764 make_pair(" OpCapability ImageBasic" +
765           string(kOpenCLMemoryModel) +
766           string(" OpEntryPoint Kernel %func \"compute\"") +
767           " %voidt = OpTypeVoid"
768           " %imgt = OpTypeImage %voidt 1D 0 0 0 0 Unknown" + string(kVoidFVoid2),
769           Sampled1DDependencies()),
770 make_pair(" OpCapability ImageBasic" +
771           string(kOpenCLMemoryModel) +
772           string(" OpEntryPoint Kernel %func \"compute\"") +
773           " %voidt = OpTypeVoid"
774           " %imgt = OpTypeImage %voidt 2D 0 0 0 0 Unknown" + string(kVoidFVoid2),
775           AllCapabilities()),
776 make_pair(" OpCapability ImageBasic" +
777           string(kOpenCLMemoryModel) +
778           string(" OpEntryPoint Kernel %func \"compute\"") +
779           " %voidt = OpTypeVoid"
780           " %imgt = OpTypeImage %voidt 3D 0 0 0 0 Unknown" + string(kVoidFVoid2),
781           AllCapabilities()),
782 make_pair(" OpCapability ImageBasic" +
783           string(kOpenCLMemoryModel) +
784           string(" OpEntryPoint Kernel %func \"compute\"") +
785           " %voidt = OpTypeVoid"
786           " %imgt = OpTypeImage %voidt Cube 0 0 0 0 Unknown" + string(kVoidFVoid2),
787           ShaderDependencies()),
788 make_pair(" OpCapability ImageBasic" +
789           string(kOpenCLMemoryModel) +
790           string(" OpEntryPoint Kernel %func \"compute\"") +
791           " %voidt = OpTypeVoid"
792           " %imgt = OpTypeImage %voidt Rect 0 0 0 0 Unknown" + string(kVoidFVoid2),
793           SampledRectDependencies()),
794 make_pair(" OpCapability ImageBasic" +
795           string(kOpenCLMemoryModel) +
796           string(" OpEntryPoint Kernel %func \"compute\"") +
797           " %voidt = OpTypeVoid"
798           " %imgt = OpTypeImage %voidt Buffer 0 0 0 0 Unknown" + string(kVoidFVoid2),
799           SampledBufferDependencies()),
800 make_pair(" OpCapability ImageBasic" +
801           string(kOpenCLMemoryModel) +
802           string(" OpEntryPoint Kernel %func \"compute\"") +
803           " %voidt = OpTypeVoid"
804           " %imgt = OpTypeImage %voidt SubpassData 0 0 0 2 Unknown" + string(kVoidFVoid2),
805           vector<string>{"InputAttachment"})
806 )),);
807 
808 // NOTE: All Sampler Address Modes require kernel capabilities but the
809 // OpConstantSampler requires LiteralSampler which depends on Kernel
810 INSTANTIATE_TEST_CASE_P(SamplerAddressingMode, ValidateCapability,
811                         Combine(
812                             ValuesIn(AllCapabilities()),
813                             Values(
814 make_pair(string(kGLSL450MemoryModel) +
815           " OpEntryPoint Vertex %func \"shader\""
816           " %samplert = OpTypeSampler"
817           " %sampler = OpConstantSampler %samplert None 1 Nearest" +
818           string(kVoidFVoid),
819           vector<string>{"LiteralSampler"}),
820 make_pair(string(kGLSL450MemoryModel) +
821           " OpEntryPoint Vertex %func \"shader\""
822           " %samplert = OpTypeSampler"
823           " %sampler = OpConstantSampler %samplert ClampToEdge 1 Nearest" +
824           string(kVoidFVoid),
825           vector<string>{"LiteralSampler"}),
826 make_pair(string(kGLSL450MemoryModel) +
827           " OpEntryPoint Vertex %func \"shader\""
828           " %samplert = OpTypeSampler"
829           " %sampler = OpConstantSampler %samplert Clamp 1 Nearest" +
830           string(kVoidFVoid),
831           vector<string>{"LiteralSampler"}),
832 make_pair(string(kGLSL450MemoryModel) +
833           " OpEntryPoint Vertex %func \"shader\""
834           " %samplert = OpTypeSampler"
835           " %sampler = OpConstantSampler %samplert Repeat 1 Nearest" +
836           string(kVoidFVoid),
837           vector<string>{"LiteralSampler"}),
838 make_pair(string(kGLSL450MemoryModel) +
839           " OpEntryPoint Vertex %func \"shader\""
840           " %samplert = OpTypeSampler"
841           " %sampler = OpConstantSampler %samplert RepeatMirrored 1 Nearest" +
842           string(kVoidFVoid),
843           vector<string>{"LiteralSampler"})
844 )),);
845 
846 //TODO(umar): Sampler Filter Mode
847 //TODO(umar): Image Format
848 //TODO(umar): Image Channel Order
849 //TODO(umar): Image Channel Data Type
850 //TODO(umar): Image Operands
851 //TODO(umar): FP Fast Math Mode
852 //TODO(umar): FP Rounding Mode
853 //TODO(umar): Linkage Type
854 //TODO(umar): Access Qualifier
855 //TODO(umar): Function Parameter Attribute
856 
857 INSTANTIATE_TEST_CASE_P(Decoration, ValidateCapability,
858                         Combine(
859                             ValuesIn(AllCapabilities()),
860                             Values(
861 make_pair(string(kOpenCLMemoryModel) +
862           "OpEntryPoint Kernel %func \"compute\" \n"
863           "OpDecorate %intt RelaxedPrecision\n"
864           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
865           ShaderDependencies()),
866 make_pair(string(kOpenCLMemoryModel) +
867           "OpEntryPoint Kernel %func \"compute\" \n"
868           "OpDecorate %intt Block\n"
869           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
870           ShaderDependencies()),
871 make_pair(string(kOpenCLMemoryModel) +
872           "OpEntryPoint Kernel %func \"compute\" \n"
873           "OpDecorate %intt BufferBlock\n"
874           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
875           ShaderDependencies()),
876 make_pair(string(kOpenCLMemoryModel) +
877           "OpEntryPoint Kernel %func \"compute\" \n"
878           "OpDecorate %intt RowMajor\n"
879           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
880           MatrixDependencies()),
881 make_pair(string(kOpenCLMemoryModel) +
882           "OpEntryPoint Kernel %func \"compute\" \n"
883           "OpDecorate %intt ColMajor\n"
884           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
885           MatrixDependencies()),
886 make_pair(string(kOpenCLMemoryModel) +
887           "OpEntryPoint Kernel %func \"compute\" \n"
888           "OpDecorate %intt ArrayStride 1\n"
889           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
890           ShaderDependencies()),
891 make_pair(string(kOpenCLMemoryModel) +
892           "OpEntryPoint Kernel %func \"compute\" \n"
893           "OpDecorate %intt MatrixStride 1\n"
894           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
895           MatrixDependencies()),
896 make_pair(string(kOpenCLMemoryModel) +
897           "OpEntryPoint Kernel %func \"compute\" \n"
898           "OpDecorate %intt GLSLShared\n"
899           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
900           ShaderDependencies()),
901 make_pair(string(kOpenCLMemoryModel) +
902           "OpEntryPoint Kernel %func \"compute\" \n"
903           "OpDecorate %intt GLSLPacked\n"
904           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
905           ShaderDependencies()),
906 make_pair(string(kGLSL450MemoryModel) +
907           "OpEntryPoint Vertex %func \"shader\" \n"
908           "OpDecorate %intt CPacked\n"
909           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
910           KernelDependencies()),
911 make_pair(string(kOpenCLMemoryModel) +
912           "OpEntryPoint Kernel %func \"compute\" \n"
913           "OpDecorate %intt NoPerspective\n"
914           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
915           ShaderDependencies()),
916 make_pair(string(kOpenCLMemoryModel) +
917           "OpEntryPoint Kernel %func \"compute\" \n"
918           "OpDecorate %intt Flat\n"
919           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
920           ShaderDependencies()),
921 make_pair(string(kOpenCLMemoryModel) +
922           "OpEntryPoint Kernel %func \"compute\" \n"
923           "OpDecorate %intt Patch\n"
924           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
925           TessellationDependencies()),
926 make_pair(string(kOpenCLMemoryModel) +
927           "OpEntryPoint Kernel %func \"compute\" \n"
928           "OpDecorate %intt Centroid\n"
929           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
930           ShaderDependencies()),
931 make_pair(string(kOpenCLMemoryModel) +
932           "OpEntryPoint Kernel %func \"compute\" \n"
933           "OpDecorate %intt Sample\n"
934           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
935           vector<string>{"SampleRateShading"}),
936 make_pair(string(kOpenCLMemoryModel) +
937           "OpEntryPoint Kernel %func \"compute\" \n"
938           "OpDecorate %intt Invariant\n"
939           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
940           ShaderDependencies()),
941 make_pair(string(kOpenCLMemoryModel) +
942           "OpEntryPoint Kernel %func \"compute\" \n"
943           "OpDecorate %intt Restrict\n"
944           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
945           AllCapabilities()),
946 make_pair(string(kOpenCLMemoryModel) +
947           "OpEntryPoint Kernel %func \"compute\" \n"
948           "OpDecorate %intt Aliased\n"
949           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
950           AllCapabilities()),
951 make_pair(string(kOpenCLMemoryModel) +
952           "OpEntryPoint Kernel %func \"compute\" \n"
953           "OpDecorate %intt Volatile\n"
954           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
955           AllCapabilities()),
956 make_pair(string(kGLSL450MemoryModel) +
957           "OpEntryPoint Vertex %func \"shader\" \n"
958           "OpDecorate %intt Constant\n"
959           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
960           KernelDependencies()),
961 make_pair(string(kOpenCLMemoryModel) +
962           "OpEntryPoint Kernel %func \"compute\" \n"
963           "OpDecorate %intt Coherent\n"
964           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
965           AllCapabilities()),
966 make_pair(string(kOpenCLMemoryModel) +
967           "OpEntryPoint Kernel %func \"compute\" \n"
968           "OpDecorate %intt NonWritable\n"
969           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
970           AllCapabilities()),
971 make_pair(string(kOpenCLMemoryModel) +
972           "OpEntryPoint Kernel %func \"compute\" \n"
973           "OpDecorate %intt NonReadable\n"
974           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
975           AllCapabilities()),
976 make_pair(string(kOpenCLMemoryModel) +
977           "OpEntryPoint Kernel %func \"compute\" \n"
978           "OpDecorate %intt Uniform\n"
979           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
980           ShaderDependencies()),
981 make_pair(string(kGLSL450MemoryModel) +
982           "OpEntryPoint Vertex %func \"shader\" \n"
983           "OpDecorate %intt SaturatedConversion\n"
984           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
985           KernelDependencies()),
986 make_pair(string(kOpenCLMemoryModel) +
987           "OpEntryPoint Kernel %func \"compute\" \n"
988           "OpDecorate %intt Stream 0\n"
989           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
990           vector<string>{"GeometryStreams"}),
991 make_pair(string(kOpenCLMemoryModel) +
992           "OpEntryPoint Kernel %func \"compute\" \n"
993           "OpDecorate %intt Location 0\n"
994           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
995           ShaderDependencies()),
996 make_pair(string(kOpenCLMemoryModel) +
997           "OpEntryPoint Kernel %func \"compute\" \n"
998           "OpDecorate %intt Component 0\n"
999           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1000           ShaderDependencies()),
1001 make_pair(string(kOpenCLMemoryModel) +
1002           "OpEntryPoint Kernel %func \"compute\" \n"
1003           "OpDecorate %intt Index 0\n"
1004           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1005           ShaderDependencies()),
1006 make_pair(string(kOpenCLMemoryModel) +
1007           "OpEntryPoint Kernel %func \"compute\" \n"
1008           "OpDecorate %intt Binding 0\n"
1009           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1010           ShaderDependencies()),
1011 make_pair(string(kOpenCLMemoryModel) +
1012           "OpEntryPoint Kernel %func \"compute\" \n"
1013           "OpDecorate %intt DescriptorSet 0\n"
1014           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1015           ShaderDependencies()),
1016 make_pair(string(kOpenCLMemoryModel) +
1017           "OpEntryPoint Kernel %func \"compute\" \n"
1018           "OpDecorate %intt Offset 0\n"
1019           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1020           ShaderDependencies()),
1021 make_pair(string(kOpenCLMemoryModel) +
1022           "OpEntryPoint Kernel %func \"compute\" \n"
1023           "OpDecorate %intt XfbBuffer 0\n"
1024           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1025           vector<string>{"TransformFeedback"}),
1026 make_pair(string(kOpenCLMemoryModel) +
1027           "OpEntryPoint Kernel %func \"compute\" \n"
1028           "OpDecorate %intt XfbStride 0\n"
1029           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1030           vector<string>{"TransformFeedback"}),
1031 make_pair(string(kGLSL450MemoryModel) +
1032           "OpEntryPoint Vertex %func \"shader\" \n"
1033           "OpDecorate %intt FuncParamAttr Zext\n"
1034           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1035           KernelDependencies()),
1036 make_pair(string(kGLSL450MemoryModel) +
1037           "OpEntryPoint Vertex %func \"shader\" \n"
1038           "OpDecorate %intt FPRoundingMode RTE\n"
1039           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1040           KernelDependencies()),
1041 make_pair(string(kGLSL450MemoryModel) +
1042           "OpEntryPoint Vertex %func \"shader\" \n"
1043           "OpDecorate %intt FPFastMathMode Fast\n"
1044           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1045           KernelDependencies()),
1046 make_pair(string(kOpenCLMemoryModel) +
1047           "OpEntryPoint Kernel %func \"compute\" \n"
1048           "OpDecorate %intt LinkageAttributes \"other\" Import\n"
1049           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1050           vector<string>{"Linkage"}),
1051 make_pair(string(kOpenCLMemoryModel) +
1052           "OpEntryPoint Kernel %func \"compute\" \n"
1053           "OpDecorate %intt NoContraction\n"
1054           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1055           ShaderDependencies()),
1056 make_pair(string(kOpenCLMemoryModel) +
1057           "OpEntryPoint Kernel %func \"compute\" \n"
1058           "OpDecorate %intt InputAttachmentIndex 0\n"
1059           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1060           vector<string>{"InputAttachment"}),
1061 make_pair(string(kGLSL450MemoryModel) +
1062           "OpEntryPoint Vertex %func \"shader\" \n"
1063           "OpDecorate %intt Alignment 4\n"
1064           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1065           KernelDependencies())
1066 )),);
1067 
1068 // clang-format on
1069 INSTANTIATE_TEST_CASE_P(
1070     DecorationSpecId, ValidateCapability,
1071     Combine(ValuesIn(AllSpirV10Capabilities()),
1072             Values(make_pair(string(kOpenCLMemoryModel) +
1073                                  "OpEntryPoint Vertex %func \"shader\" \n" +
1074                                  "OpDecorate %1 SpecId 1\n"
1075                                  "%intt = OpTypeInt 32 0\n"
1076                                  "%1 = OpSpecConstant %intt 0\n" +
1077                                  string(kVoidFVoid),
1078                              ShaderDependencies()))), );
1079 
1080 INSTANTIATE_TEST_CASE_P(
1081     DecorationV11, ValidateCapabilityV11,
1082     Combine(ValuesIn(AllCapabilities()),
1083             Values(make_pair(string(kOpenCLMemoryModel) +
1084                                  "OpEntryPoint Kernel %func \"compute\" \n"
1085                                  "OpDecorate %p MaxByteOffset 0 "
1086                                  "%i32 = OpTypeInt 32 0 "
1087                                  "%pi32 = OpTypePointer Workgroup %i32 "
1088                                  "%p = OpVariable %pi32 Workgroup " +
1089                                  string(kVoidFVoid),
1090                              AddressesDependencies()),
1091                    // Trying to test OpDecorate here, but if this fails due to
1092                    // incorrect OpMemoryModel validation, that must also be
1093                    // fixed.
1094                    make_pair(string("OpMemoryModel Logical OpenCL "
1095                                     "OpEntryPoint Kernel %func \"compute\" \n"
1096                                     "OpDecorate %1 SpecId 1 "
1097                                     "%intt = OpTypeInt 32 0 "
1098                                     "%1 = OpSpecConstant %intt 0") +
1099                                  string(kVoidFVoid),
1100                              KernelDependencies()),
1101                    make_pair(string("OpMemoryModel Logical Simple "
1102                                     "OpEntryPoint Vertex %func \"shader\" \n"
1103                                     "OpDecorate %1 SpecId 1 "
1104                                     "%intt = OpTypeInt 32 0 "
1105                                     "%1 = OpSpecConstant %intt 0") +
1106                                  string(kVoidFVoid),
1107                              ShaderDependencies()))), );
1108 // clang-format off
1109 
1110 INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapability,
1111                         Combine(
1112                             ValuesIn(AllCapabilities()),
1113                             Values(
1114 make_pair(string(kOpenCLMemoryModel) +
1115           "OpEntryPoint Kernel %func \"compute\" \n" +
1116           "OpDecorate %intt BuiltIn Position\n"
1117           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1118           ShaderDependencies()),
1119 // Just mentioning PointSize, ClipDistance, or CullDistance as a BuiltIn does
1120 // not trigger the requirement for the associated capability.
1121 // See https://github.com/KhronosGroup/SPIRV-Tools/issues/365
1122 make_pair(string(kOpenCLMemoryModel) +
1123           "OpEntryPoint Kernel %func \"compute\" \n" +
1124           "OpDecorate %intt BuiltIn PointSize\n"
1125           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1126           AllCapabilities()),
1127 make_pair(string(kOpenCLMemoryModel) +
1128           "OpEntryPoint Kernel %func \"compute\" \n" +
1129           "OpDecorate %intt BuiltIn ClipDistance\n"
1130           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1131           AllCapabilities()),
1132 make_pair(string(kOpenCLMemoryModel) +
1133           "OpEntryPoint Kernel %func \"compute\" \n" +
1134           "OpDecorate %intt BuiltIn CullDistance\n"
1135           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1136           AllCapabilities()),
1137 make_pair(string(kOpenCLMemoryModel) +
1138           "OpEntryPoint Kernel %func \"compute\" \n" +
1139           "OpDecorate %intt BuiltIn VertexId\n"
1140           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1141           ShaderDependencies()),
1142 make_pair(string(kOpenCLMemoryModel) +
1143           "OpEntryPoint Kernel %func \"compute\" \n" +
1144           "OpDecorate %intt BuiltIn InstanceId\n"
1145           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1146           ShaderDependencies()),
1147 make_pair(string(kOpenCLMemoryModel) +
1148           "OpEntryPoint Kernel %func \"compute\" \n" +
1149           "OpDecorate %intt BuiltIn PrimitiveId\n"
1150           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1151           GeometryTessellationDependencies()),
1152 make_pair(string(kOpenCLMemoryModel) +
1153           "OpEntryPoint Kernel %func \"compute\" \n" +
1154           "OpDecorate %intt BuiltIn InvocationId\n"
1155           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1156           GeometryTessellationDependencies()),
1157 make_pair(string(kOpenCLMemoryModel) +
1158           "OpEntryPoint Kernel %func \"compute\" \n" +
1159           "OpDecorate %intt BuiltIn Layer\n"
1160           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1161           GeometryDependencies()),
1162 make_pair(string(kOpenCLMemoryModel) +
1163           "OpEntryPoint Kernel %func \"compute\" \n" +
1164           "OpDecorate %intt BuiltIn ViewportIndex\n"
1165           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1166           vector<string>{"MultiViewport"}),
1167 make_pair(string(kOpenCLMemoryModel) +
1168           "OpEntryPoint Kernel %func \"compute\" \n" +
1169           "OpDecorate %intt BuiltIn TessLevelOuter\n"
1170           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1171           TessellationDependencies()),
1172 make_pair(string(kOpenCLMemoryModel) +
1173           "OpEntryPoint Kernel %func \"compute\" \n" +
1174           "OpDecorate %intt BuiltIn TessLevelInner\n"
1175           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1176           TessellationDependencies()),
1177 make_pair(string(kOpenCLMemoryModel) +
1178           "OpEntryPoint Kernel %func \"compute\" \n" +
1179           "OpDecorate %intt BuiltIn TessCoord\n"
1180           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1181           TessellationDependencies()),
1182 make_pair(string(kOpenCLMemoryModel) +
1183           "OpEntryPoint Kernel %func \"compute\" \n" +
1184           "OpDecorate %intt BuiltIn PatchVertices\n"
1185           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1186           TessellationDependencies()),
1187 make_pair(string(kOpenCLMemoryModel) +
1188           "OpEntryPoint Kernel %func \"compute\" \n" +
1189           "OpDecorate %intt BuiltIn FragCoord\n"
1190           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1191           ShaderDependencies()),
1192 make_pair(string(kOpenCLMemoryModel) +
1193           "OpEntryPoint Kernel %func \"compute\" \n" +
1194           "OpDecorate %intt BuiltIn PointCoord\n"
1195           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1196           ShaderDependencies()),
1197 make_pair(string(kOpenCLMemoryModel) +
1198           "OpEntryPoint Kernel %func \"compute\" \n" +
1199           "OpDecorate %intt BuiltIn FrontFacing\n"
1200           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1201           ShaderDependencies()),
1202 make_pair(string(kOpenCLMemoryModel) +
1203           "OpEntryPoint Kernel %func \"compute\" \n" +
1204           "OpDecorate %intt BuiltIn SampleId\n"
1205           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1206           vector<string>{"SampleRateShading"}),
1207 make_pair(string(kOpenCLMemoryModel) +
1208           "OpEntryPoint Kernel %func \"compute\" \n" +
1209           "OpDecorate %intt BuiltIn SamplePosition\n"
1210           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1211           vector<string>{"SampleRateShading"}),
1212 make_pair(string(kOpenCLMemoryModel) +
1213           "OpEntryPoint Kernel %func \"compute\" \n" +
1214           "OpDecorate %intt BuiltIn SampleMask\n"
1215           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1216           vector<string>{"SampleRateShading"}),
1217 make_pair(string(kOpenCLMemoryModel) +
1218           "OpEntryPoint Kernel %func \"compute\" \n" +
1219           "OpDecorate %intt BuiltIn FragDepth\n"
1220           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1221           ShaderDependencies()),
1222 make_pair(string(kOpenCLMemoryModel) +
1223           "OpEntryPoint Kernel %func \"compute\" \n" +
1224           "OpDecorate %intt BuiltIn HelperInvocation\n"
1225           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1226           ShaderDependencies()),
1227 make_pair(string(kOpenCLMemoryModel) +
1228           "OpEntryPoint Kernel %func \"compute\" \n" +
1229           "OpDecorate %intt BuiltIn VertexIndex\n"
1230           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1231           ShaderDependencies()),
1232 make_pair(string(kOpenCLMemoryModel) +
1233           "OpEntryPoint Kernel %func \"compute\" \n" +
1234           "OpDecorate %intt BuiltIn InstanceIndex\n"
1235           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1236           ShaderDependencies()),
1237 make_pair(string(kOpenCLMemoryModel) +
1238           "OpEntryPoint Kernel %func \"compute\" \n" +
1239           "OpDecorate %intt BuiltIn NumWorkgroups\n"
1240           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1241           AllCapabilities()),
1242 make_pair(string(kOpenCLMemoryModel) +
1243           "OpEntryPoint Kernel %func \"compute\" \n" +
1244           "OpDecorate %intt BuiltIn WorkgroupSize\n"
1245           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1246           AllCapabilities()),
1247 make_pair(string(kOpenCLMemoryModel) +
1248           "OpEntryPoint Kernel %func \"compute\" \n" +
1249           "OpDecorate %intt BuiltIn WorkgroupId\n"
1250           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1251           AllCapabilities()),
1252 make_pair(string(kOpenCLMemoryModel) +
1253           "OpEntryPoint Kernel %func \"compute\" \n" +
1254           "OpDecorate %intt BuiltIn LocalInvocationId\n"
1255           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1256           AllCapabilities()),
1257 make_pair(string(kOpenCLMemoryModel) +
1258           "OpEntryPoint Kernel %func \"compute\" \n" +
1259           "OpDecorate %intt BuiltIn GlobalInvocationId\n"
1260           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1261           AllCapabilities()),
1262 make_pair(string(kOpenCLMemoryModel) +
1263           "OpEntryPoint Kernel %func \"compute\" \n" +
1264           "OpDecorate %intt BuiltIn LocalInvocationIndex\n"
1265           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1266           AllCapabilities()),
1267 make_pair(string(kGLSL450MemoryModel) +
1268           "OpEntryPoint Vertex %func \"shader\" \n" +
1269           "OpDecorate %intt BuiltIn WorkDim\n"
1270           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1271           KernelDependencies()),
1272 make_pair(string(kGLSL450MemoryModel) +
1273           "OpEntryPoint Vertex %func \"shader\" \n" +
1274           "OpDecorate %intt BuiltIn GlobalSize\n"
1275           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1276           KernelDependencies()),
1277 make_pair(string(kGLSL450MemoryModel) +
1278           "OpEntryPoint Vertex %func \"shader\" \n" +
1279           "OpDecorate %intt BuiltIn EnqueuedWorkgroupSize\n"
1280           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1281           KernelDependencies()),
1282 make_pair(string(kGLSL450MemoryModel) +
1283           "OpEntryPoint Vertex %func \"shader\" \n" +
1284           "OpDecorate %intt BuiltIn GlobalOffset\n"
1285           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1286           KernelDependencies()),
1287 make_pair(string(kGLSL450MemoryModel) +
1288           "OpEntryPoint Vertex %func \"shader\" \n" +
1289           "OpDecorate %intt BuiltIn GlobalLinearId\n"
1290           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1291           KernelDependencies()),
1292 make_pair(string(kGLSL450MemoryModel) +
1293           "OpEntryPoint Vertex %func \"shader\" \n" +
1294           "OpDecorate %intt BuiltIn SubgroupSize\n"
1295           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1296           KernelDependencies()),
1297 make_pair(string(kGLSL450MemoryModel) +
1298           "OpEntryPoint Vertex %func \"shader\" \n" +
1299           "OpDecorate %intt BuiltIn SubgroupMaxSize\n"
1300           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1301           KernelDependencies()),
1302 make_pair(string(kGLSL450MemoryModel) +
1303           "OpEntryPoint Vertex %func \"shader\" \n" +
1304           "OpDecorate %intt BuiltIn NumSubgroups\n"
1305           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1306           KernelDependencies()),
1307 make_pair(string(kGLSL450MemoryModel) +
1308           "OpEntryPoint Vertex %func \"shader\" \n" +
1309           "OpDecorate %intt BuiltIn NumEnqueuedSubgroups\n"
1310           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1311           KernelDependencies()),
1312 make_pair(string(kGLSL450MemoryModel) +
1313           "OpEntryPoint Vertex %func \"shader\" \n" +
1314           "OpDecorate %intt BuiltIn SubgroupId\n"
1315           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1316           KernelDependencies()),
1317 make_pair(string(kGLSL450MemoryModel) +
1318           "OpEntryPoint Vertex %func \"shader\" \n" +
1319           "OpDecorate %intt BuiltIn SubgroupLocalInvocationId\n"
1320           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1321           KernelDependencies()),
1322 make_pair(string(kOpenCLMemoryModel) +
1323           "OpEntryPoint Kernel %func \"compute\" \n" +
1324           "OpDecorate %intt BuiltIn VertexIndex\n"
1325           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1326           ShaderDependencies()),
1327 make_pair(string(kOpenCLMemoryModel) +
1328           "OpEntryPoint Kernel %func \"compute\" \n" +
1329           "OpDecorate %intt BuiltIn InstanceIndex\n"
1330           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1331           ShaderDependencies())
1332 )),);
1333 
1334 // Ensure that mere mention of PointSize, ClipDistance, or CullDistance as
1335 // BuiltIns does not trigger the requirement for the associated
1336 // capability.
1337 // See https://github.com/KhronosGroup/SPIRV-Tools/issues/365
1338 INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapabilityVulkan10,
1339                         Combine(
1340                             // All capabilities to try.
1341                             ValuesIn(AllSpirV10Capabilities()),
1342                             Values(
1343 make_pair(string(kGLSL450MemoryModel) +
1344           "OpEntryPoint Vertex %func \"shader\" \n" +
1345           "OpDecorate %intt BuiltIn PointSize\n"
1346           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1347           // Capabilities which should succeed.
1348           AllVulkan10Capabilities()),
1349 make_pair(string(kGLSL450MemoryModel) +
1350           "OpEntryPoint Vertex %func \"shader\" \n" +
1351           "OpDecorate %intt BuiltIn ClipDistance\n"
1352           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1353           AllVulkan10Capabilities()),
1354 make_pair(string(kGLSL450MemoryModel) +
1355           "OpEntryPoint Vertex %func \"shader\" \n" +
1356           "OpDecorate %intt BuiltIn CullDistance\n"
1357           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1358           AllVulkan10Capabilities())
1359 )),);
1360 
1361 INSTANTIATE_TEST_CASE_P(BuiltIn, ValidateCapabilityOpenGL40,
1362                         Combine(
1363                             // OpenGL 4.0 is based on SPIR-V 1.0
1364                             ValuesIn(AllSpirV10Capabilities()),
1365                             Values(
1366 make_pair(string(kGLSL450MemoryModel) +
1367           "OpEntryPoint Vertex %func \"shader\" \n" +
1368           "OpDecorate %intt BuiltIn PointSize\n"
1369           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1370           AllSpirV10Capabilities()),
1371 make_pair(string(kGLSL450MemoryModel) +
1372           "OpEntryPoint Vertex %func \"shader\" \n" +
1373           "OpDecorate %intt BuiltIn ClipDistance\n"
1374           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1375           AllSpirV10Capabilities()),
1376 make_pair(string(kGLSL450MemoryModel) +
1377           "OpEntryPoint Vertex %func \"shader\" \n" +
1378           "OpDecorate %intt BuiltIn CullDistance\n"
1379           "%intt = OpTypeInt 32 0\n" + string(kVoidFVoid),
1380           AllSpirV10Capabilities())
1381 )),);
1382 
1383 // TODO(umar): Selection Control
1384 // TODO(umar): Loop Control
1385 // TODO(umar): Function Control
1386 // TODO(umar): Memory Semantics
1387 // TODO(umar): Memory Access
1388 // TODO(umar): Scope
1389 // TODO(umar): Group Operation
1390 // TODO(umar): Kernel Enqueue Flags
1391 // TODO(umar): Kernel Profiling Flags
1392 
1393 INSTANTIATE_TEST_CASE_P(MatrixOp, ValidateCapability,
1394                         Combine(
1395                             ValuesIn(AllCapabilities()),
1396                             Values(
1397 make_pair(string(kOpenCLMemoryModel) +
1398           "OpEntryPoint Kernel %func \"compute\" \n" +
1399           "%f32      = OpTypeFloat 32\n"
1400           "%vec3     = OpTypeVector %f32 3\n"
1401           "%mat33    = OpTypeMatrix %vec3 3\n" + string(kVoidFVoid),
1402           MatrixDependencies()))),);
1403 // clang-format on
1404 
1405 // Creates assembly containing an OpImageFetch instruction using operands for
1406 // the image-operands part.  The assembly defines constants %fzero and %izero
1407 // that can be used for operands where IDs are required.  The assembly is valid,
1408 // apart from not declaring any capabilities required by the operands.
ImageOperandsTemplate(const string & operands)1409 string ImageOperandsTemplate(const string& operands) {
1410   ostringstream ss;
1411   // clang-format off
1412   ss << R"(
1413 OpCapability Kernel
1414 OpCapability Linkage
1415 OpMemoryModel Logical OpenCL
1416 
1417 %i32 = OpTypeInt 32 0
1418 %f32 = OpTypeFloat 32
1419 %v4i32 = OpTypeVector %i32 4
1420 %timg = OpTypeImage %i32 2D 0 0 0 0 Unknown
1421 %pimg = OpTypePointer UniformConstant %timg
1422 %tfun = OpTypeFunction %i32
1423 
1424 %vimg = OpVariable %pimg UniformConstant
1425 %izero = OpConstant %i32 0
1426 %fzero = OpConstant %f32 0.
1427 
1428 %main = OpFunction %i32 None %tfun
1429 %lbl = OpLabel
1430 %img = OpLoad %timg %vimg
1431 %r1 = OpImageFetch %v4i32 %img %izero )" << operands << R"(
1432 OpReturnValue %izero
1433 OpFunctionEnd
1434 )";
1435   // clang-format on
1436   return ss.str();
1437 }
1438 
1439 INSTANTIATE_TEST_CASE_P(
1440     TwoImageOperandsMask, ValidateCapability,
1441     Combine(
1442         ValuesIn(AllCapabilities()),
1443         Values(make_pair(ImageOperandsTemplate("Bias|Lod %fzero %fzero"),
1444                          ShaderDependencies()),
1445                make_pair(ImageOperandsTemplate("Lod|Offset %fzero %izero"),
1446                          vector<string>{"ImageGatherExtended"}),
1447                make_pair(ImageOperandsTemplate("Sample|MinLod %izero %fzero"),
1448                          vector<string>{"MinLod"}),
1449                make_pair(ImageOperandsTemplate("Lod|Sample %fzero %izero"),
1450                          AllCapabilities()))), );
1451 
1452 // TODO(umar): Instruction capability checks
1453 
1454 // True if capability exists in env.
Exists(const std::string & capability,spv_target_env env)1455 bool Exists(const std::string& capability, spv_target_env env) {
1456   spv_operand_desc dummy;
1457   return SPV_SUCCESS ==
1458          libspirv::AssemblyGrammar(ScopedContext(env).context)
1459              .lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, capability.c_str(),
1460                             capability.size(), &dummy);
1461 }
1462 
TEST_P(ValidateCapability,Capability)1463 TEST_P(ValidateCapability, Capability) {
1464   const string capability = Capability(GetParam());
1465   spv_target_env env =
1466       (capability.empty() || Exists(capability, SPV_ENV_UNIVERSAL_1_0))
1467           ? SPV_ENV_UNIVERSAL_1_0
1468           : SPV_ENV_UNIVERSAL_1_1;
1469   const string test_code = MakeAssembly(GetParam());
1470   CompileSuccessfully(test_code, env);
1471   ASSERT_EQ(ExpectedResult(GetParam()), ValidateInstructions(env)) << test_code;
1472 }
1473 
TEST_P(ValidateCapabilityV11,Capability)1474 TEST_P(ValidateCapabilityV11, Capability) {
1475   const string test_code = MakeAssembly(GetParam());
1476   CompileSuccessfully(test_code, SPV_ENV_UNIVERSAL_1_1);
1477   ASSERT_EQ(ExpectedResult(GetParam()),
1478             ValidateInstructions(SPV_ENV_UNIVERSAL_1_1))
1479       << test_code;
1480 }
1481 
TEST_P(ValidateCapabilityVulkan10,Capability)1482 TEST_P(ValidateCapabilityVulkan10, Capability) {
1483   const string test_code = MakeAssembly(GetParam());
1484   CompileSuccessfully(test_code, SPV_ENV_VULKAN_1_0);
1485   ASSERT_EQ(ExpectedResult(GetParam()),
1486             ValidateInstructions(SPV_ENV_VULKAN_1_0))
1487       << test_code;
1488 }
1489 
TEST_P(ValidateCapabilityOpenGL40,Capability)1490 TEST_P(ValidateCapabilityOpenGL40, Capability) {
1491   const string test_code = MakeAssembly(GetParam());
1492   CompileSuccessfully(test_code, SPV_ENV_OPENGL_4_0);
1493   ASSERT_EQ(ExpectedResult(GetParam()),
1494             ValidateInstructions(SPV_ENV_OPENGL_4_0))
1495       << test_code;
1496 }
1497 
TEST_F(ValidateCapability,SemanticsIdIsAnIdNotALiteral)1498 TEST_F(ValidateCapability, SemanticsIdIsAnIdNotALiteral) {
1499   // From https://github.com/KhronosGroup/SPIRV-Tools/issues/248
1500   // The validator was interpreting the memory semantics ID number
1501   // as the value to be checked rather than an ID that references
1502   // another value to be checked.
1503   // In this case a raw ID of 64 was mistaken to mean a literal
1504   // semantic value of UniformMemory, which would require the Shader
1505   // capability.
1506   const char str[] = R"(
1507 OpCapability Kernel
1508 OpCapability Linkage
1509 OpMemoryModel Logical OpenCL
1510 
1511 ;  %i32 has ID 1
1512 %i32    = OpTypeInt 32 0
1513 %tf     = OpTypeFunction %i32
1514 %pi32   = OpTypePointer CrossWorkgroup %i32
1515 %var    = OpVariable %pi32 CrossWorkgroup
1516 %c      = OpConstant %i32 100
1517 %scope  = OpConstant %i32 1 ; Device scope
1518 
1519 ; Fake an instruction with 64 as the result id.
1520 ; !64 = OpConstantNull %i32
1521 !0x3002e !1 !64
1522 
1523 %f = OpFunction %i32 None %tf
1524 %l = OpLabel
1525 %result = OpAtomicIAdd %i32 %var %scope !64 %c
1526 OpReturnValue %result
1527 OpFunctionEnd
1528 )";
1529 
1530   CompileSuccessfully(str);
1531 
1532   // Since we are forcing usage of <id> 64, the "id bound" in the binary header
1533   // must be overwritten so that <id> 64 is considered within bound.
1534   // ID Bound is at index 3 of the binary. Set it to 65.
1535   OverwriteAssembledBinary(3, 65);
1536 
1537   ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1538 }
1539 
TEST_F(ValidateCapability,IntSignednessKernelGood)1540 TEST_F(ValidateCapability, IntSignednessKernelGood) {
1541   const std::string spirv = R"(
1542 OpCapability Kernel
1543 OpCapability Linkage
1544 OpMemoryModel Logical OpenCL
1545 %i32    = OpTypeInt 32 0
1546 )";
1547   CompileSuccessfully(spirv);
1548   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
1549 }
1550 
TEST_F(ValidateCapability,IntSignednessKernelBad)1551 TEST_F(ValidateCapability, IntSignednessKernelBad) {
1552   const std::string spirv = R"(
1553 OpCapability Kernel
1554 OpCapability Linkage
1555 OpMemoryModel Logical OpenCL
1556 %i32    = OpTypeInt 32 1
1557 )";
1558   CompileSuccessfully(spirv);
1559   EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
1560   EXPECT_THAT(getDiagnosticString(),
1561               HasSubstr("The Signedness in OpTypeInt must always be 0 when "
1562                         "Kernel capability is used."));
1563 }
1564 
TEST_F(ValidateCapability,IntSignednessShaderGood)1565 TEST_F(ValidateCapability, IntSignednessShaderGood) {
1566   const std::string spirv = R"(
1567 OpCapability Shader
1568 OpCapability Linkage
1569 OpMemoryModel Logical GLSL450
1570 %u32    = OpTypeInt 32 0
1571 %i32    = OpTypeInt 32 1
1572 )";
1573   CompileSuccessfully(spirv);
1574   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
1575 }
1576 
TEST_F(ValidateCapability,NonVulkan10Capability)1577 TEST_F(ValidateCapability, NonVulkan10Capability) {
1578   const std::string spirv = R"(
1579 OpCapability Shader
1580 OpCapability Linkage
1581 OpMemoryModel Logical GLSL450
1582 %u32    = OpTypeInt 32 0
1583 %i32    = OpTypeInt 32 1
1584 )";
1585   CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
1586   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
1587             ValidateInstructions(SPV_ENV_VULKAN_1_0));
1588   EXPECT_THAT(getDiagnosticString(),
1589               HasSubstr("Capability value 5 is not allowed by Vulkan 1.0"));
1590 }
1591 
TEST_F(ValidateCapability,Vulkan10EnabledByExtension)1592 TEST_F(ValidateCapability, Vulkan10EnabledByExtension) {
1593   const std::string spirv = R"(
1594 OpCapability Shader
1595 OpCapability DrawParameters
1596 OpExtension "SPV_KHR_shader_draw_parameters"
1597 OpMemoryModel Logical GLSL450
1598 OpEntryPoint Vertex %func "shader"
1599 OpDecorate %intt BuiltIn PointSize
1600 %intt = OpTypeInt 32 0
1601 )" + string(kVoidFVoid);
1602 
1603   CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
1604   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
1605 }
1606 
TEST_F(ValidateCapability,Vulkan10NotEnabledByExtension)1607 TEST_F(ValidateCapability, Vulkan10NotEnabledByExtension) {
1608   const std::string spirv = R"(
1609 OpCapability Shader
1610 OpCapability DrawParameters
1611 OpMemoryModel Logical GLSL450
1612 OpEntryPoint Vertex %func "shader"
1613 OpDecorate %intt BuiltIn PointSize
1614 %intt = OpTypeInt 32 0
1615 )" + string(kVoidFVoid);
1616 
1617   CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
1618   EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY,
1619             ValidateInstructions(SPV_ENV_VULKAN_1_0));
1620   EXPECT_THAT(getDiagnosticString(),
1621               HasSubstr("Capability value 4427 is not allowed by Vulkan 1.0"));
1622 }
1623 
1624 }  // namespace anonymous
1625