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