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