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