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