1 // Copyright (c) 2018 Google LLC.
2 // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
3 // reserved.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16
17 // Tests validation rules of GLSL.450.std and OpenCL.std extended instructions.
18 // Doesn't test OpenCL.std vector size 2, 3, 4, 8 or 16 rules (not supported
19 // by standard SPIR-V).
20
21 #include <cstring>
22 #include <sstream>
23 #include <string>
24 #include <tuple>
25 #include <utility>
26 #include <vector>
27
28 #include "gmock/gmock.h"
29 #include "source/spirv_target_env.h"
30 #include "test/unit_spirv.h"
31 #include "test/val/val_code_generator.h"
32 #include "test/val/val_fixtures.h"
33
34 namespace spvtools {
35 namespace val {
36 namespace {
37
38 struct TestResult {
TestResultspvtools::val::__anonaed621760111::TestResult39 TestResult(spv_result_t in_validation_result = SPV_SUCCESS,
40 const char* in_error_str = nullptr,
41 const char* in_error_str2 = nullptr)
42 : validation_result(in_validation_result),
43 error_str(in_error_str),
44 error_str2(in_error_str2) {}
45 spv_result_t validation_result;
46 const char* error_str;
47 const char* error_str2;
48 };
49
50 using ::testing::Combine;
51 using ::testing::HasSubstr;
52 using ::testing::Not;
53 using ::testing::Values;
54 using ::testing::ValuesIn;
55
56 using ValidateBuiltIns = spvtest::ValidateBase<bool>;
57 using ValidateVulkanSubgroupBuiltIns =
58 spvtest::ValidateBase<std::tuple<const char*, const char*, const char*,
59 const char*, const char*, TestResult>>;
60 using ValidateVulkanCombineBuiltInExecutionModelDataTypeResult =
61 spvtest::ValidateBase<std::tuple<const char*, const char*, const char*,
62 const char*, const char*, TestResult>>;
63 using ValidateVulkanCombineBuiltInArrayedVariable = spvtest::ValidateBase<
64 std::tuple<const char*, const char*, const char*, const char*, TestResult>>;
65 using ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult =
66 spvtest::ValidateBase<
67 std::tuple<const char*, const char*, const char*, const char*,
68 const char*, const char*, const char*, TestResult>>;
69
70 using ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult =
71 spvtest::ValidateBase<std::tuple<spv_target_env, const char*, const char*,
72 const char*, const char*, const char*,
73 const char*, const char*, TestResult>>;
74
InitializerRequired(const char * const storage_class)75 bool InitializerRequired(const char* const storage_class) {
76 return (strncmp(storage_class, "Output", 6) == 0 ||
77 strncmp(storage_class, "Private", 7) == 0 ||
78 strncmp(storage_class, "Function", 8) == 0);
79 }
80
GetInMainCodeGenerator(const char * const built_in,const char * const execution_model,const char * const storage_class,const char * const capabilities,const char * const extensions,const char * const data_type)81 CodeGenerator GetInMainCodeGenerator(const char* const built_in,
82 const char* const execution_model,
83 const char* const storage_class,
84 const char* const capabilities,
85 const char* const extensions,
86 const char* const data_type) {
87 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
88
89 if (capabilities) {
90 generator.capabilities_ += capabilities;
91 }
92 if (extensions) {
93 generator.extensions_ += extensions;
94 }
95
96 generator.before_types_ = "OpMemberDecorate %built_in_type 0 BuiltIn ";
97 generator.before_types_ += built_in;
98 generator.before_types_ += "\n";
99
100 std::ostringstream after_types;
101
102 after_types << "%built_in_type = OpTypeStruct " << data_type << "\n";
103 if (InitializerRequired(storage_class)) {
104 after_types << "%built_in_null = OpConstantNull %built_in_type\n";
105 }
106 after_types << "%built_in_ptr = OpTypePointer " << storage_class
107 << " %built_in_type\n";
108 after_types << "%built_in_var = OpVariable %built_in_ptr " << storage_class;
109 if (InitializerRequired(storage_class)) {
110 after_types << " %built_in_null";
111 }
112 after_types << "\n";
113 after_types << "%data_ptr = OpTypePointer " << storage_class << " "
114 << data_type << "\n";
115 generator.after_types_ = after_types.str();
116
117 EntryPoint entry_point;
118 entry_point.name = "main";
119 entry_point.execution_model = execution_model;
120 if (strncmp(storage_class, "Input", 5) == 0 ||
121 strncmp(storage_class, "Output", 6) == 0) {
122 entry_point.interfaces = "%built_in_var";
123 }
124
125 std::ostringstream execution_modes;
126 if (0 == std::strcmp(execution_model, "Fragment")) {
127 execution_modes << "OpExecutionMode %" << entry_point.name
128 << " OriginUpperLeft\n";
129 if (0 == std::strcmp(built_in, "FragDepth")) {
130 execution_modes << "OpExecutionMode %" << entry_point.name
131 << " DepthReplacing\n";
132 }
133 }
134 if (0 == std::strcmp(execution_model, "Geometry")) {
135 execution_modes << "OpExecutionMode %" << entry_point.name
136 << " InputPoints\n";
137 execution_modes << "OpExecutionMode %" << entry_point.name
138 << " OutputPoints\n";
139 }
140 if (0 == std::strcmp(execution_model, "GLCompute")) {
141 execution_modes << "OpExecutionMode %" << entry_point.name
142 << " LocalSize 1 1 1\n";
143 }
144 entry_point.execution_modes = execution_modes.str();
145
146 entry_point.body = R"(
147 %ptr = OpAccessChain %data_ptr %built_in_var %u32_0
148 )";
149 generator.entry_points_.push_back(std::move(entry_point));
150
151 return generator;
152 }
153
TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,InMain)154 TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, InMain) {
155 const char* const built_in = std::get<0>(GetParam());
156 const char* const execution_model = std::get<1>(GetParam());
157 const char* const storage_class = std::get<2>(GetParam());
158 const char* const data_type = std::get<3>(GetParam());
159 const char* const vuid = std::get<4>(GetParam());
160 const TestResult& test_result = std::get<5>(GetParam());
161
162 CodeGenerator generator = GetInMainCodeGenerator(
163 built_in, execution_model, storage_class, NULL, NULL, data_type);
164
165 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
166 ASSERT_EQ(test_result.validation_result,
167 ValidateInstructions(SPV_ENV_VULKAN_1_0));
168 if (test_result.error_str) {
169 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str));
170 }
171 if (test_result.error_str2) {
172 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2));
173 }
174 if (vuid) {
175 EXPECT_THAT(getDiagnosticString(), AnyVUID(vuid));
176 }
177 }
178
TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,InMain)179 TEST_P(
180 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
181 InMain) {
182 const char* const built_in = std::get<0>(GetParam());
183 const char* const execution_model = std::get<1>(GetParam());
184 const char* const storage_class = std::get<2>(GetParam());
185 const char* const data_type = std::get<3>(GetParam());
186 const char* const capabilities = std::get<4>(GetParam());
187 const char* const extensions = std::get<5>(GetParam());
188 const char* const vuid = std::get<6>(GetParam());
189 const TestResult& test_result = std::get<7>(GetParam());
190
191 CodeGenerator generator =
192 GetInMainCodeGenerator(built_in, execution_model, storage_class,
193 capabilities, extensions, data_type);
194
195 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
196 ASSERT_EQ(test_result.validation_result,
197 ValidateInstructions(SPV_ENV_VULKAN_1_0));
198 if (test_result.error_str) {
199 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str));
200 }
201 if (test_result.error_str2) {
202 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2));
203 }
204 if (vuid) {
205 EXPECT_THAT(getDiagnosticString(), AnyVUID(vuid));
206 }
207 }
208
TEST_P(ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,InMain)209 TEST_P(
210 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
211 InMain) {
212 const spv_target_env env = std::get<0>(GetParam());
213 const char* const built_in = std::get<1>(GetParam());
214 const char* const execution_model = std::get<2>(GetParam());
215 const char* const storage_class = std::get<3>(GetParam());
216 const char* const data_type = std::get<4>(GetParam());
217 const char* const capabilities = std::get<5>(GetParam());
218 const char* const extensions = std::get<6>(GetParam());
219 const char* const vuid = std::get<7>(GetParam());
220 const TestResult& test_result = std::get<8>(GetParam());
221
222 CodeGenerator generator =
223 GetInMainCodeGenerator(built_in, execution_model, storage_class,
224 capabilities, extensions, data_type);
225
226 CompileSuccessfully(generator.Build(), env);
227 ASSERT_EQ(test_result.validation_result, ValidateInstructions(env));
228 if (test_result.error_str) {
229 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str));
230 }
231 if (test_result.error_str2) {
232 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2));
233 }
234 if (vuid) {
235 EXPECT_THAT(getDiagnosticString(), AnyVUID(vuid));
236 }
237 }
238
GetInFunctionCodeGenerator(const char * const built_in,const char * const execution_model,const char * const storage_class,const char * const capabilities,const char * const extensions,const char * const data_type)239 CodeGenerator GetInFunctionCodeGenerator(const char* const built_in,
240 const char* const execution_model,
241 const char* const storage_class,
242 const char* const capabilities,
243 const char* const extensions,
244 const char* const data_type) {
245 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
246
247 if (capabilities) {
248 generator.capabilities_ += capabilities;
249 }
250 if (extensions) {
251 generator.extensions_ += extensions;
252 }
253
254 generator.before_types_ = "OpMemberDecorate %built_in_type 0 BuiltIn ";
255 generator.before_types_ += built_in;
256 generator.before_types_ += "\n";
257
258 std::ostringstream after_types;
259 after_types << "%built_in_type = OpTypeStruct " << data_type << "\n";
260 if (InitializerRequired(storage_class)) {
261 after_types << "%built_in_null = OpConstantNull %built_in_type\n";
262 }
263 after_types << "%built_in_ptr = OpTypePointer " << storage_class
264 << " %built_in_type\n";
265 after_types << "%built_in_var = OpVariable %built_in_ptr " << storage_class;
266 if (InitializerRequired(storage_class)) {
267 after_types << " %built_in_null";
268 }
269 after_types << "\n";
270 after_types << "%data_ptr = OpTypePointer " << storage_class << " "
271 << data_type << "\n";
272 generator.after_types_ = after_types.str();
273
274 EntryPoint entry_point;
275 entry_point.name = "main";
276 entry_point.execution_model = execution_model;
277 if (strncmp(storage_class, "Input", 5) == 0 ||
278 strncmp(storage_class, "Output", 6) == 0) {
279 entry_point.interfaces = "%built_in_var";
280 }
281
282 std::ostringstream execution_modes;
283 if (0 == std::strcmp(execution_model, "Fragment")) {
284 execution_modes << "OpExecutionMode %" << entry_point.name
285 << " OriginUpperLeft\n";
286 if (0 == std::strcmp(built_in, "FragDepth")) {
287 execution_modes << "OpExecutionMode %" << entry_point.name
288 << " DepthReplacing\n";
289 }
290 }
291 if (0 == std::strcmp(execution_model, "Geometry")) {
292 execution_modes << "OpExecutionMode %" << entry_point.name
293 << " InputPoints\n";
294 execution_modes << "OpExecutionMode %" << entry_point.name
295 << " OutputPoints\n";
296 }
297 if (0 == std::strcmp(execution_model, "GLCompute")) {
298 execution_modes << "OpExecutionMode %" << entry_point.name
299 << " LocalSize 1 1 1\n";
300 }
301 entry_point.execution_modes = execution_modes.str();
302
303 entry_point.body = R"(
304 %val2 = OpFunctionCall %void %foo
305 )";
306
307 std::string function_body = R"(
308 %foo = OpFunction %void None %func
309 %foo_entry = OpLabel
310 %ptr = OpAccessChain %data_ptr %built_in_var %u32_0
311 OpReturn
312 OpFunctionEnd
313 )";
314
315 generator.add_at_the_end_ = function_body;
316
317 generator.entry_points_.push_back(std::move(entry_point));
318
319 return generator;
320 }
321
TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,InFunction)322 TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, InFunction) {
323 const char* const built_in = std::get<0>(GetParam());
324 const char* const execution_model = std::get<1>(GetParam());
325 const char* const storage_class = std::get<2>(GetParam());
326 const char* const data_type = std::get<3>(GetParam());
327 const char* const vuid = std::get<4>(GetParam());
328 const TestResult& test_result = std::get<5>(GetParam());
329
330 CodeGenerator generator = GetInFunctionCodeGenerator(
331 built_in, execution_model, storage_class, NULL, NULL, data_type);
332
333 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
334 ASSERT_EQ(test_result.validation_result,
335 ValidateInstructions(SPV_ENV_VULKAN_1_0));
336 if (test_result.error_str) {
337 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str));
338 }
339 if (test_result.error_str2) {
340 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2));
341 }
342 if (vuid) {
343 EXPECT_THAT(getDiagnosticString(), AnyVUID(vuid));
344 }
345 }
346
TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,InFunction)347 TEST_P(
348 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
349 InFunction) {
350 const char* const built_in = std::get<0>(GetParam());
351 const char* const execution_model = std::get<1>(GetParam());
352 const char* const storage_class = std::get<2>(GetParam());
353 const char* const data_type = std::get<3>(GetParam());
354 const char* const capabilities = std::get<4>(GetParam());
355 const char* const extensions = std::get<5>(GetParam());
356 const char* const vuid = std::get<6>(GetParam());
357 const TestResult& test_result = std::get<7>(GetParam());
358
359 CodeGenerator generator =
360 GetInFunctionCodeGenerator(built_in, execution_model, storage_class,
361 capabilities, extensions, data_type);
362
363 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
364 ASSERT_EQ(test_result.validation_result,
365 ValidateInstructions(SPV_ENV_VULKAN_1_0));
366 if (test_result.error_str) {
367 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str));
368 }
369 if (test_result.error_str2) {
370 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2));
371 }
372 if (vuid) {
373 EXPECT_THAT(getDiagnosticString(), AnyVUID(vuid));
374 }
375 }
376
GetVariableCodeGenerator(const char * const built_in,const char * const execution_model,const char * const storage_class,const char * const capabilities,const char * const extensions,const char * const data_type)377 CodeGenerator GetVariableCodeGenerator(const char* const built_in,
378 const char* const execution_model,
379 const char* const storage_class,
380 const char* const capabilities,
381 const char* const extensions,
382 const char* const data_type) {
383 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
384
385 if (capabilities) {
386 generator.capabilities_ += capabilities;
387 }
388 if (extensions) {
389 generator.extensions_ += extensions;
390 }
391
392 generator.before_types_ = "OpDecorate %built_in_var BuiltIn ";
393 generator.before_types_ += built_in;
394 generator.before_types_ += "\n";
395
396 std::ostringstream after_types;
397 if (InitializerRequired(storage_class)) {
398 after_types << "%built_in_null = OpConstantNull " << data_type << "\n";
399 }
400 after_types << "%built_in_ptr = OpTypePointer " << storage_class << " "
401 << data_type << "\n";
402 after_types << "%built_in_var = OpVariable %built_in_ptr " << storage_class;
403 if (InitializerRequired(storage_class)) {
404 after_types << " %built_in_null";
405 }
406 after_types << "\n";
407 generator.after_types_ = after_types.str();
408
409 EntryPoint entry_point;
410 entry_point.name = "main";
411 entry_point.execution_model = execution_model;
412 if (strncmp(storage_class, "Input", 5) == 0 ||
413 strncmp(storage_class, "Output", 6) == 0) {
414 entry_point.interfaces = "%built_in_var";
415 }
416 // Any kind of reference would do.
417 entry_point.body = R"(
418 %val = OpBitcast %u32 %built_in_var
419 )";
420
421 std::ostringstream execution_modes;
422 if (0 == std::strcmp(execution_model, "Fragment")) {
423 execution_modes << "OpExecutionMode %" << entry_point.name
424 << " OriginUpperLeft\n";
425 if (0 == std::strcmp(built_in, "FragDepth")) {
426 execution_modes << "OpExecutionMode %" << entry_point.name
427 << " DepthReplacing\n";
428 }
429 }
430 if (0 == std::strcmp(execution_model, "Geometry")) {
431 execution_modes << "OpExecutionMode %" << entry_point.name
432 << " InputPoints\n";
433 execution_modes << "OpExecutionMode %" << entry_point.name
434 << " OutputPoints\n";
435 }
436 if (0 == std::strcmp(execution_model, "GLCompute")) {
437 execution_modes << "OpExecutionMode %" << entry_point.name
438 << " LocalSize 1 1 1\n";
439 }
440 entry_point.execution_modes = execution_modes.str();
441
442 generator.entry_points_.push_back(std::move(entry_point));
443
444 return generator;
445 }
446
TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,Variable)447 TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeResult, Variable) {
448 const char* const built_in = std::get<0>(GetParam());
449 const char* const execution_model = std::get<1>(GetParam());
450 const char* const storage_class = std::get<2>(GetParam());
451 const char* const data_type = std::get<3>(GetParam());
452 const char* const vuid = std::get<4>(GetParam());
453 const TestResult& test_result = std::get<5>(GetParam());
454
455 CodeGenerator generator = GetVariableCodeGenerator(
456 built_in, execution_model, storage_class, NULL, NULL, data_type);
457
458 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
459 ASSERT_EQ(test_result.validation_result,
460 ValidateInstructions(SPV_ENV_VULKAN_1_0));
461 if (test_result.error_str) {
462 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str));
463 }
464 if (test_result.error_str2) {
465 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2));
466 }
467 if (vuid) {
468 EXPECT_THAT(getDiagnosticString(), AnyVUID(vuid));
469 }
470 }
471
TEST_P(ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,Variable)472 TEST_P(
473 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
474 Variable) {
475 const char* const built_in = std::get<0>(GetParam());
476 const char* const execution_model = std::get<1>(GetParam());
477 const char* const storage_class = std::get<2>(GetParam());
478 const char* const data_type = std::get<3>(GetParam());
479 const char* const capabilities = std::get<4>(GetParam());
480 const char* const extensions = std::get<5>(GetParam());
481 const char* const vuid = std::get<6>(GetParam());
482 const TestResult& test_result = std::get<7>(GetParam());
483
484 CodeGenerator generator =
485 GetVariableCodeGenerator(built_in, execution_model, storage_class,
486 capabilities, extensions, data_type);
487
488 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
489 ASSERT_EQ(test_result.validation_result,
490 ValidateInstructions(SPV_ENV_VULKAN_1_0));
491 if (test_result.error_str) {
492 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str));
493 }
494 if (test_result.error_str2) {
495 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2));
496 }
497 if (vuid) {
498 EXPECT_THAT(getDiagnosticString(), AnyVUID(vuid));
499 }
500 }
501
502 INSTANTIATE_TEST_SUITE_P(
503 ClipAndCullDistanceOutputSuccess,
504 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
505 Combine(Values("ClipDistance", "CullDistance"),
506 Values("Vertex", "Geometry", "TessellationControl",
507 "TessellationEvaluation"),
508 Values("Output"), Values("%f32arr2", "%f32arr4"), Values(nullptr),
509 Values(TestResult())));
510
511 INSTANTIATE_TEST_SUITE_P(
512 ClipAndCullDistanceInputSuccess,
513 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
514 Combine(Values("ClipDistance", "CullDistance"),
515 Values("Fragment", "Geometry", "TessellationControl",
516 "TessellationEvaluation"),
517 Values("Input"), Values("%f32arr2", "%f32arr4"), Values(nullptr),
518 Values(TestResult())));
519
520 INSTANTIATE_TEST_SUITE_P(
521 ClipAndCullDistanceInvalidStorageClass,
522 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
523 Combine(Values("ClipDistance", "CullDistance"),
524 Values("Vertex", "Geometry", "TessellationControl",
525 "TessellationEvaluation"),
526 Values("Private"), Values("%f32arr2", "%f32arr4"),
527 Values("VUID-ClipDistance-ClipDistance-04190 "
528 "VUID-CullDistance-CullDistance-04199"),
529 Values(TestResult(
530 SPV_ERROR_INVALID_DATA,
531 "to be only used for variables with Input or Output storage "
532 "class."))));
533
534 INSTANTIATE_TEST_SUITE_P(
535 ClipAndCullDistanceFragmentOutput,
536 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
537 Combine(Values("ClipDistance", "CullDistance"), Values("Fragment"),
538 Values("Output"), Values("%f32arr4"),
539 Values("VUID-ClipDistance-ClipDistance-04189 "
540 "VUID-CullDistance-CullDistance-04198"),
541 Values(TestResult(
542 SPV_ERROR_INVALID_DATA,
543 "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance "
544 "to be used for variables with Output storage class if "
545 "execution model is Fragment.",
546 "which is called with execution model Fragment."))));
547
548 INSTANTIATE_TEST_SUITE_P(
549 VertexIdVertexInput,
550 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
551 Combine(
552 Values("VertexId"), Values("Vertex"), Values("Input"), Values("%u32"),
553 Values(nullptr),
554 Values(TestResult(SPV_ERROR_INVALID_DATA,
555 "Vulkan spec doesn't allow BuiltIn VertexId to be "
556 "used."))));
557
558 INSTANTIATE_TEST_SUITE_P(
559 ClipAndCullDistanceVertexInput,
560 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
561 Combine(Values("ClipDistance", "CullDistance"), Values("Vertex"),
562 Values("Input"), Values("%f32arr4"),
563 Values("VUID-ClipDistance-ClipDistance-04188 "
564 "VUID-CullDistance-CullDistance-04197"),
565 Values(TestResult(
566 SPV_ERROR_INVALID_DATA,
567 "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance "
568 "to be used for variables with Input storage class if "
569 "execution model is Vertex.",
570 "which is called with execution model Vertex."))));
571
572 INSTANTIATE_TEST_SUITE_P(
573 ClipAndCullInvalidExecutionModel,
574 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
575 Combine(Values("ClipDistance", "CullDistance"), Values("GLCompute"),
576 Values("Input", "Output"), Values("%f32arr4"),
577 Values("VUID-ClipDistance-ClipDistance-04187 "
578 "VUID-CullDistance-CullDistance-04196"),
579 Values(TestResult(
580 SPV_ERROR_INVALID_DATA,
581 "to be used only with Fragment, Vertex, TessellationControl, "
582 "TessellationEvaluation or Geometry execution models"))));
583
584 INSTANTIATE_TEST_SUITE_P(
585 ClipAndCullDistanceNotArray,
586 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
587 Combine(Values("ClipDistance", "CullDistance"), Values("Fragment"),
588 Values("Input"), Values("%f32vec2", "%f32vec4", "%f32"),
589 Values("VUID-ClipDistance-ClipDistance-04191 "
590 "VUID-CullDistance-CullDistance-04200"),
591 Values(TestResult(SPV_ERROR_INVALID_DATA,
592 "needs to be a 32-bit float array",
593 "is not an array"))));
594
595 INSTANTIATE_TEST_SUITE_P(
596 ClipAndCullDistanceNotFloatArray,
597 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
598 Combine(Values("ClipDistance", "CullDistance"), Values("Fragment"),
599 Values("Input"), Values("%u32arr2", "%u64arr4"),
600 Values("VUID-ClipDistance-ClipDistance-04191 "
601 "VUID-CullDistance-CullDistance-04200"),
602 Values(TestResult(SPV_ERROR_INVALID_DATA,
603 "needs to be a 32-bit float array",
604 "components are not float scalar"))));
605
606 INSTANTIATE_TEST_SUITE_P(
607 ClipAndCullDistanceNotF32Array,
608 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
609 Combine(Values("ClipDistance", "CullDistance"), Values("Fragment"),
610 Values("Input"), Values("%f64arr2", "%f64arr4"),
611 Values("VUID-ClipDistance-ClipDistance-04191 "
612 "VUID-CullDistance-CullDistance-04200"),
613 Values(TestResult(SPV_ERROR_INVALID_DATA,
614 "needs to be a 32-bit float array",
615 "has components with bit width 64"))));
616
617 INSTANTIATE_TEST_SUITE_P(
618 FragCoordSuccess, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
619 Combine(Values("FragCoord"), Values("Fragment"), Values("Input"),
620 Values("%f32vec4"), Values(nullptr), Values(TestResult())));
621
622 INSTANTIATE_TEST_SUITE_P(
623 FragCoordNotFragment,
624 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
625 Combine(
626 Values("FragCoord"),
627 Values("Vertex", "GLCompute", "Geometry", "TessellationControl",
628 "TessellationEvaluation"),
629 Values("Input"), Values("%f32vec4"),
630 Values("VUID-FragCoord-FragCoord-04210"),
631 Values(TestResult(SPV_ERROR_INVALID_DATA,
632 "to be used only with Fragment execution model"))));
633
634 INSTANTIATE_TEST_SUITE_P(
635 FragCoordNotInput, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
636 Combine(Values("FragCoord"), Values("Fragment"), Values("Output"),
637 Values("%f32vec4"), Values("VUID-FragCoord-FragCoord-04211"),
638 Values(TestResult(
639 SPV_ERROR_INVALID_DATA,
640 "to be only used for variables with Input storage class",
641 "uses storage class Output"))));
642
643 INSTANTIATE_TEST_SUITE_P(
644 FragCoordNotFloatVector,
645 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
646 Combine(Values("FragCoord"), Values("Fragment"), Values("Input"),
647 Values("%f32arr4", "%u32vec4"),
648 Values("VUID-FragCoord-FragCoord-04212"),
649 Values(TestResult(SPV_ERROR_INVALID_DATA,
650 "needs to be a 4-component 32-bit float vector",
651 "is not a float vector"))));
652
653 INSTANTIATE_TEST_SUITE_P(
654 FragCoordNotFloatVec4,
655 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
656 Combine(Values("FragCoord"), Values("Fragment"), Values("Input"),
657 Values("%f32vec3"), Values("VUID-FragCoord-FragCoord-04212"),
658 Values(TestResult(SPV_ERROR_INVALID_DATA,
659 "needs to be a 4-component 32-bit float vector",
660 "has 3 components"))));
661
662 INSTANTIATE_TEST_SUITE_P(
663 FragCoordNotF32Vec4,
664 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
665 Combine(Values("FragCoord"), Values("Fragment"), Values("Input"),
666 Values("%f64vec4"), Values("VUID-FragCoord-FragCoord-04212"),
667 Values(TestResult(SPV_ERROR_INVALID_DATA,
668 "needs to be a 4-component 32-bit float vector",
669 "has components with bit width 64"))));
670
671 INSTANTIATE_TEST_SUITE_P(
672 FragDepthSuccess, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
673 Combine(Values("FragDepth"), Values("Fragment"), Values("Output"),
674 Values("%f32"), Values(nullptr), Values(TestResult())));
675
676 INSTANTIATE_TEST_SUITE_P(
677 FragDepthNotFragment,
678 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
679 Combine(
680 Values("FragDepth"),
681 Values("Vertex", "GLCompute", "Geometry", "TessellationControl",
682 "TessellationEvaluation"),
683 Values("Output"), Values("%f32"),
684 Values("VUID-FragDepth-FragDepth-04213"),
685 Values(TestResult(SPV_ERROR_INVALID_DATA,
686 "to be used only with Fragment execution model"))));
687
688 INSTANTIATE_TEST_SUITE_P(
689 FragDepthNotOutput,
690 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
691 Combine(Values("FragDepth"), Values("Fragment"), Values("Input"),
692 Values("%f32"), Values("VUID-FragDepth-FragDepth-04214"),
693 Values(TestResult(
694 SPV_ERROR_INVALID_DATA,
695 "to be only used for variables with Output storage class",
696 "uses storage class Input"))));
697
698 INSTANTIATE_TEST_SUITE_P(
699 FragDepthNotFloatScalar,
700 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
701 Combine(Values("FragDepth"), Values("Fragment"), Values("Output"),
702 Values("%f32vec4", "%u32"),
703 Values("VUID-FragDepth-FragDepth-04215"),
704 Values(TestResult(SPV_ERROR_INVALID_DATA,
705 "needs to be a 32-bit float scalar",
706 "is not a float scalar"))));
707
708 INSTANTIATE_TEST_SUITE_P(
709 FragDepthNotF32, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
710 Combine(Values("FragDepth"), Values("Fragment"), Values("Output"),
711 Values("%f64"), Values("VUID-FragDepth-FragDepth-04215"),
712 Values(TestResult(SPV_ERROR_INVALID_DATA,
713 "needs to be a 32-bit float scalar",
714 "has bit width 64"))));
715
716 INSTANTIATE_TEST_SUITE_P(
717 FrontFacingAndHelperInvocationSuccess,
718 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
719 Combine(Values("FrontFacing", "HelperInvocation"), Values("Fragment"),
720 Values("Input"), Values("%bool"), Values(nullptr),
721 Values(TestResult())));
722
723 INSTANTIATE_TEST_SUITE_P(
724 FrontFacingAndHelperInvocationNotFragment,
725 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
726 Combine(
727 Values("FrontFacing", "HelperInvocation"),
728 Values("Vertex", "GLCompute", "Geometry", "TessellationControl",
729 "TessellationEvaluation"),
730 Values("Input"), Values("%bool"),
731 Values("VUID-FrontFacing-FrontFacing-04229 "
732 "VUID-HelperInvocation-HelperInvocation-04239"),
733 Values(TestResult(SPV_ERROR_INVALID_DATA,
734 "to be used only with Fragment execution model"))));
735
736 INSTANTIATE_TEST_SUITE_P(
737 FrontFacingAndHelperInvocationNotInput,
738 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
739 Combine(Values("FrontFacing", "HelperInvocation"), Values("Fragment"),
740 Values("Output"), Values("%bool"),
741 Values("VUID-FrontFacing-FrontFacing-04230 "
742 "VUID-HelperInvocation-HelperInvocation-04240"),
743 Values(TestResult(
744 SPV_ERROR_INVALID_DATA,
745 "to be only used for variables with Input storage class",
746 "uses storage class Output"))));
747
748 INSTANTIATE_TEST_SUITE_P(
749 FrontFacingAndHelperInvocationNotBool,
750 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
751 Combine(Values("FrontFacing", "HelperInvocation"), Values("Fragment"),
752 Values("Input"), Values("%f32", "%u32"),
753 Values("VUID-FrontFacing-FrontFacing-04231 "
754 "VUID-HelperInvocation-HelperInvocation-04241"),
755 Values(TestResult(SPV_ERROR_INVALID_DATA,
756 "needs to be a bool scalar",
757 "is not a bool scalar"))));
758
759 INSTANTIATE_TEST_SUITE_P(
760 ComputeShaderInputInt32Vec3Success,
761 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
762 Combine(Values("GlobalInvocationId", "LocalInvocationId", "NumWorkgroups",
763 "WorkgroupId"),
764 Values("GLCompute"), Values("Input"), Values("%u32vec3"),
765 Values(nullptr), Values(TestResult())));
766
767 INSTANTIATE_TEST_SUITE_P(
768 ComputeShaderInputInt32Vec3NotGLCompute,
769 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
770 Combine(Values("GlobalInvocationId", "LocalInvocationId", "NumWorkgroups",
771 "WorkgroupId"),
772 Values("Vertex", "Fragment", "Geometry", "TessellationControl",
773 "TessellationEvaluation"),
774 Values("Input"), Values("%u32vec3"),
775 Values("VUID-GlobalInvocationId-GlobalInvocationId-04236 "
776 "VUID-LocalInvocationId-LocalInvocationId-04281 "
777 "VUID-NumWorkgroups-NumWorkgroups-04296 "
778 "VUID-WorkgroupId-WorkgroupId-04422"),
779 Values(TestResult(SPV_ERROR_INVALID_DATA,
780 "to be used only with GLCompute, MeshNV, or "
781 "TaskNV execution model"))));
782
783 INSTANTIATE_TEST_SUITE_P(
784 ComputeShaderInputInt32Vec3NotInput,
785 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
786 Combine(Values("GlobalInvocationId", "LocalInvocationId", "NumWorkgroups",
787 "WorkgroupId"),
788 Values("GLCompute"), Values("Output"), Values("%u32vec3"),
789 Values("VUID-GlobalInvocationId-GlobalInvocationId-04237 "
790 "VUID-LocalInvocationId-LocalInvocationId-04282 "
791 "VUID-NumWorkgroups-NumWorkgroups-04297 "
792 "VUID-WorkgroupId-WorkgroupId-04423"),
793 Values(TestResult(
794 SPV_ERROR_INVALID_DATA,
795 "to be only used for variables with Input storage class",
796 "uses storage class Output"))));
797
798 INSTANTIATE_TEST_SUITE_P(
799 ComputeShaderInputInt32Vec3NotIntVector,
800 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
801 Combine(Values("GlobalInvocationId", "LocalInvocationId", "NumWorkgroups",
802 "WorkgroupId"),
803 Values("GLCompute"), Values("Input"),
804 Values("%u32arr3", "%f32vec3"),
805 Values("VUID-GlobalInvocationId-GlobalInvocationId-04238 "
806 "VUID-LocalInvocationId-LocalInvocationId-04283 "
807 "VUID-NumWorkgroups-NumWorkgroups-04298 "
808 "VUID-WorkgroupId-WorkgroupId-04424"),
809 Values(TestResult(SPV_ERROR_INVALID_DATA,
810 "needs to be a 3-component 32-bit int vector",
811 "is not an int vector"))));
812
813 INSTANTIATE_TEST_SUITE_P(
814 ComputeShaderInputInt32Vec3NotIntVec3,
815 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
816 Combine(Values("GlobalInvocationId", "LocalInvocationId", "NumWorkgroups",
817 "WorkgroupId"),
818 Values("GLCompute"), Values("Input"), Values("%u32vec4"),
819 Values("VUID-GlobalInvocationId-GlobalInvocationId-04238 "
820 "VUID-LocalInvocationId-LocalInvocationId-04283 "
821 "VUID-NumWorkgroups-NumWorkgroups-04298 "
822 "VUID-WorkgroupId-WorkgroupId-04424"),
823 Values(TestResult(SPV_ERROR_INVALID_DATA,
824 "needs to be a 3-component 32-bit int vector",
825 "has 4 components"))));
826
827 INSTANTIATE_TEST_SUITE_P(
828 ComputeShaderInputInt32Vec3NotInt32Vec,
829 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
830 Combine(Values("GlobalInvocationId", "LocalInvocationId", "NumWorkgroups",
831 "WorkgroupId"),
832 Values("GLCompute"), Values("Input"), Values("%u64vec3"),
833 Values("VUID-GlobalInvocationId-GlobalInvocationId-04238 "
834 "VUID-LocalInvocationId-LocalInvocationId-04283 "
835 "VUID-NumWorkgroups-NumWorkgroups-04298 "
836 "VUID-WorkgroupId-WorkgroupId-04424"),
837 Values(TestResult(SPV_ERROR_INVALID_DATA,
838 "needs to be a 3-component 32-bit int vector",
839 "has components with bit width 64"))));
840
841 INSTANTIATE_TEST_SUITE_P(
842 InvocationIdSuccess,
843 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
844 Combine(Values("InvocationId"), Values("Geometry", "TessellationControl"),
845 Values("Input"), Values("%u32"), Values(nullptr),
846 Values(TestResult())));
847
848 INSTANTIATE_TEST_SUITE_P(
849 InvocationIdInvalidExecutionModel,
850 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
851 Combine(Values("InvocationId"),
852 Values("Vertex", "Fragment", "GLCompute", "TessellationEvaluation"),
853 Values("Input"), Values("%u32"),
854 Values("VUID-InvocationId-InvocationId-04257"),
855 Values(TestResult(SPV_ERROR_INVALID_DATA,
856 "to be used only with TessellationControl or "
857 "Geometry execution models"))));
858
859 INSTANTIATE_TEST_SUITE_P(
860 InvocationIdNotInput,
861 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
862 Combine(Values("InvocationId"), Values("Geometry", "TessellationControl"),
863 Values("Output"), Values("%u32"),
864 Values("VUID-InvocationId-InvocationId-04258"),
865 Values(TestResult(
866 SPV_ERROR_INVALID_DATA,
867 "to be only used for variables with Input storage class",
868 "uses storage class Output"))));
869
870 INSTANTIATE_TEST_SUITE_P(
871 InvocationIdNotIntScalar,
872 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
873 Combine(Values("InvocationId"), Values("Geometry", "TessellationControl"),
874 Values("Input"), Values("%f32", "%u32vec3"),
875 Values("VUID-InvocationId-InvocationId-04259"),
876 Values(TestResult(SPV_ERROR_INVALID_DATA,
877 "needs to be a 32-bit int scalar",
878 "is not an int scalar"))));
879
880 INSTANTIATE_TEST_SUITE_P(
881 InvocationIdNotInt32,
882 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
883 Combine(Values("InvocationId"), Values("Geometry", "TessellationControl"),
884 Values("Input"), Values("%u64"),
885 Values("VUID-InvocationId-InvocationId-04259"),
886 Values(TestResult(SPV_ERROR_INVALID_DATA,
887 "needs to be a 32-bit int scalar",
888 "has bit width 64"))));
889
890 INSTANTIATE_TEST_SUITE_P(
891 InstanceIndexSuccess,
892 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
893 Combine(Values("InstanceIndex"), Values("Vertex"), Values("Input"),
894 Values("%u32"), Values(nullptr), Values(TestResult())));
895
896 INSTANTIATE_TEST_SUITE_P(
897 InstanceIndexInvalidExecutionModel,
898 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
899 Combine(Values("InstanceIndex"),
900 Values("Geometry", "Fragment", "GLCompute", "TessellationControl",
901 "TessellationEvaluation"),
902 Values("Input"), Values("%u32"),
903 Values("VUID-InstanceIndex-InstanceIndex-04263"),
904 Values(TestResult(SPV_ERROR_INVALID_DATA,
905 "to be used only with Vertex execution model"))));
906
907 INSTANTIATE_TEST_SUITE_P(
908 InstanceIndexNotInput,
909 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
910 Combine(Values("InstanceIndex"), Values("Vertex"), Values("Output"),
911 Values("%u32"), Values("VUID-InstanceIndex-InstanceIndex-04264"),
912 Values(TestResult(
913 SPV_ERROR_INVALID_DATA,
914 "to be only used for variables with Input storage class",
915 "uses storage class Output"))));
916
917 INSTANTIATE_TEST_SUITE_P(
918 InstanceIndexNotIntScalar,
919 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
920 Combine(Values("InstanceIndex"), Values("Vertex"), Values("Input"),
921 Values("%f32", "%u32vec3"),
922 Values("VUID-InstanceIndex-InstanceIndex-04265"),
923 Values(TestResult(SPV_ERROR_INVALID_DATA,
924 "needs to be a 32-bit int scalar",
925 "is not an int scalar"))));
926
927 INSTANTIATE_TEST_SUITE_P(
928 InstanceIndexNotInt32,
929 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
930 Combine(Values("InstanceIndex"), Values("Vertex"), Values("Input"),
931 Values("%u64"), Values("VUID-InstanceIndex-InstanceIndex-04265"),
932 Values(TestResult(SPV_ERROR_INVALID_DATA,
933 "needs to be a 32-bit int scalar",
934 "has bit width 64"))));
935
936 INSTANTIATE_TEST_SUITE_P(
937 LayerAndViewportIndexInputSuccess,
938 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
939 Combine(Values("Layer", "ViewportIndex"), Values("Fragment"),
940 Values("Input"), Values("%u32"), Values(nullptr),
941 Values(TestResult())));
942
943 INSTANTIATE_TEST_SUITE_P(
944 LayerAndViewportIndexOutputSuccess,
945 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
946 Combine(Values("Layer", "ViewportIndex"), Values("Geometry"),
947 Values("Output"), Values("%u32"), Values(nullptr),
948 Values(TestResult())));
949
950 INSTANTIATE_TEST_SUITE_P(
951 LayerAndViewportIndexInvalidExecutionModel,
952 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
953 Combine(
954 Values("Layer", "ViewportIndex"),
955 Values("TessellationControl", "GLCompute"), Values("Input"),
956 Values("%u32"),
957 Values("VUID-Layer-Layer-04272 VUID-ViewportIndex-ViewportIndex-04404"),
958 Values(
959 TestResult(SPV_ERROR_INVALID_DATA,
960 "to be used only with Vertex, TessellationEvaluation, "
961 "Geometry, or Fragment execution models"))));
962
963 INSTANTIATE_TEST_SUITE_P(
964 ViewportIndexExecutionModelEnabledByCapability,
965 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
966 Combine(Values("ViewportIndex"), Values("Vertex", "TessellationEvaluation"),
967 Values("Output"), Values("%u32"),
968 Values("VUID-ViewportIndex-ViewportIndex-04405"),
969 Values(TestResult(
970 SPV_ERROR_INVALID_DATA,
971 "ShaderViewportIndexLayerEXT or ShaderViewportIndex"))));
972
973 INSTANTIATE_TEST_SUITE_P(
974 LayerExecutionModelEnabledByCapability,
975 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
976 Combine(Values("Layer"), Values("Vertex", "TessellationEvaluation"),
977 Values("Output"), Values("%u32"), Values("VUID-Layer-Layer-04273"),
978 Values(TestResult(SPV_ERROR_INVALID_DATA,
979 "ShaderViewportIndexLayerEXT or ShaderLayer"))));
980
981 INSTANTIATE_TEST_SUITE_P(
982 LayerAndViewportIndexFragmentNotInput,
983 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
984 Combine(
985 Values("Layer", "ViewportIndex"), Values("Fragment"), Values("Output"),
986 Values("%u32"),
987 Values("VUID-Layer-Layer-04275 VUID-ViewportIndex-ViewportIndex-04407"),
988 Values(TestResult(SPV_ERROR_INVALID_DATA,
989 "Output storage class if execution model is Fragment",
990 "which is called with execution model Fragment"))));
991
992 INSTANTIATE_TEST_SUITE_P(
993 LayerAndViewportIndexGeometryNotOutput,
994 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
995 Combine(
996 Values("Layer", "ViewportIndex"),
997 Values("Vertex", "TessellationEvaluation", "Geometry"), Values("Input"),
998 Values("%u32"),
999 Values("VUID-Layer-Layer-04274 VUID-ViewportIndex-ViewportIndex-04406"),
1000 Values(TestResult(SPV_ERROR_INVALID_DATA,
1001 "Input storage class if execution model is Vertex, "
1002 "TessellationEvaluation, Geometry, or MeshNV",
1003 "which is called with execution model"))));
1004
1005 INSTANTIATE_TEST_SUITE_P(
1006 LayerAndViewportIndexNotIntScalar,
1007 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1008 Combine(
1009 Values("Layer", "ViewportIndex"), Values("Fragment"), Values("Input"),
1010 Values("%f32", "%u32vec3"),
1011 Values("VUID-Layer-Layer-04276 VUID-ViewportIndex-ViewportIndex-04408"),
1012 Values(TestResult(SPV_ERROR_INVALID_DATA,
1013 "needs to be a 32-bit int scalar",
1014 "is not an int scalar"))));
1015
1016 INSTANTIATE_TEST_SUITE_P(
1017 LayerAndViewportIndexNotInt32,
1018 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1019 Combine(
1020 Values("Layer", "ViewportIndex"), Values("Fragment"), Values("Input"),
1021 Values("%u64"),
1022 Values("VUID-Layer-Layer-04276 VUID-ViewportIndex-ViewportIndex-04408"),
1023 Values(TestResult(SPV_ERROR_INVALID_DATA,
1024 "needs to be a 32-bit int scalar",
1025 "has bit width 64"))));
1026
1027 INSTANTIATE_TEST_SUITE_P(
1028 LayerCapability,
1029 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1030 Combine(Values(SPV_ENV_VULKAN_1_2), Values("Layer"), Values("Vertex"),
1031 Values("Output"), Values("%u32"),
1032 Values("OpCapability ShaderLayer\n"), Values(nullptr),
1033 Values(nullptr), Values(TestResult())));
1034
1035 INSTANTIATE_TEST_SUITE_P(
1036 ViewportIndexCapability,
1037 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1038 Combine(Values(SPV_ENV_VULKAN_1_2), Values("ViewportIndex"),
1039 Values("Vertex"), Values("Output"), Values("%u32"),
1040 Values("OpCapability ShaderViewportIndex\n"), Values(nullptr),
1041 Values(nullptr), Values(TestResult())));
1042
1043 INSTANTIATE_TEST_SUITE_P(
1044 PatchVerticesSuccess,
1045 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1046 Combine(Values("PatchVertices"),
1047 Values("TessellationEvaluation", "TessellationControl"),
1048 Values("Input"), Values("%u32"), Values(nullptr),
1049 Values(TestResult())));
1050
1051 INSTANTIATE_TEST_SUITE_P(
1052 PatchVerticesInvalidExecutionModel,
1053 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1054 Combine(Values("PatchVertices"),
1055 Values("Vertex", "Fragment", "GLCompute", "Geometry"),
1056 Values("Input"), Values("%u32"),
1057 Values("VUID-PatchVertices-PatchVertices-04308"),
1058 Values(TestResult(SPV_ERROR_INVALID_DATA,
1059 "to be used only with TessellationControl or "
1060 "TessellationEvaluation execution models"))));
1061
1062 INSTANTIATE_TEST_SUITE_P(
1063 PatchVerticesNotInput,
1064 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1065 Combine(Values("PatchVertices"),
1066 Values("TessellationEvaluation", "TessellationControl"),
1067 Values("Output"), Values("%u32"),
1068 Values("VUID-PatchVertices-PatchVertices-04309"),
1069 Values(TestResult(
1070 SPV_ERROR_INVALID_DATA,
1071 "to be only used for variables with Input storage class",
1072 "uses storage class Output"))));
1073
1074 INSTANTIATE_TEST_SUITE_P(
1075 PatchVerticesNotIntScalar,
1076 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1077 Combine(Values("PatchVertices"),
1078 Values("TessellationEvaluation", "TessellationControl"),
1079 Values("Input"), Values("%f32", "%u32vec3"),
1080 Values("VUID-PatchVertices-PatchVertices-04310"),
1081 Values(TestResult(SPV_ERROR_INVALID_DATA,
1082 "needs to be a 32-bit int scalar",
1083 "is not an int scalar"))));
1084
1085 INSTANTIATE_TEST_SUITE_P(
1086 PatchVerticesNotInt32,
1087 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1088 Combine(Values("PatchVertices"),
1089 Values("TessellationEvaluation", "TessellationControl"),
1090 Values("Input"), Values("%u64"),
1091 Values("VUID-PatchVertices-PatchVertices-04310"),
1092 Values(TestResult(SPV_ERROR_INVALID_DATA,
1093 "needs to be a 32-bit int scalar",
1094 "has bit width 64"))));
1095
1096 INSTANTIATE_TEST_SUITE_P(
1097 PointCoordSuccess, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1098 Combine(Values("PointCoord"), Values("Fragment"), Values("Input"),
1099 Values("%f32vec2"), Values(nullptr), Values(TestResult())));
1100
1101 INSTANTIATE_TEST_SUITE_P(
1102 PointCoordNotFragment,
1103 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1104 Combine(
1105 Values("PointCoord"),
1106 Values("Vertex", "GLCompute", "Geometry", "TessellationControl",
1107 "TessellationEvaluation"),
1108 Values("Input"), Values("%f32vec2"),
1109 Values("VUID-PointCoord-PointCoord-04311"),
1110 Values(TestResult(SPV_ERROR_INVALID_DATA,
1111 "to be used only with Fragment execution model"))));
1112
1113 INSTANTIATE_TEST_SUITE_P(
1114 PointCoordNotInput,
1115 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1116 Combine(Values("PointCoord"), Values("Fragment"), Values("Output"),
1117 Values("%f32vec2"), Values("VUID-PointCoord-PointCoord-04312"),
1118 Values(TestResult(
1119 SPV_ERROR_INVALID_DATA,
1120 "to be only used for variables with Input storage class",
1121 "uses storage class Output"))));
1122
1123 INSTANTIATE_TEST_SUITE_P(
1124 PointCoordNotFloatVector,
1125 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1126 Combine(Values("PointCoord"), Values("Fragment"), Values("Input"),
1127 Values("%f32arr2", "%u32vec2"),
1128 Values("VUID-PointCoord-PointCoord-04313"),
1129 Values(TestResult(SPV_ERROR_INVALID_DATA,
1130 "needs to be a 2-component 32-bit float vector",
1131 "is not a float vector"))));
1132
1133 INSTANTIATE_TEST_SUITE_P(
1134 PointCoordNotFloatVec3,
1135 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1136 Combine(Values("PointCoord"), Values("Fragment"), Values("Input"),
1137 Values("%f32vec3"), Values("VUID-PointCoord-PointCoord-04313"),
1138 Values(TestResult(SPV_ERROR_INVALID_DATA,
1139 "needs to be a 2-component 32-bit float vector",
1140 "has 3 components"))));
1141
1142 INSTANTIATE_TEST_SUITE_P(
1143 PointCoordNotF32Vec4,
1144 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1145 Combine(Values("PointCoord"), Values("Fragment"), Values("Input"),
1146 Values("%f64vec2"), Values("VUID-PointCoord-PointCoord-04313"),
1147 Values(TestResult(SPV_ERROR_INVALID_DATA,
1148 "needs to be a 2-component 32-bit float vector",
1149 "has components with bit width 64"))));
1150
1151 INSTANTIATE_TEST_SUITE_P(
1152 PointSizeOutputSuccess,
1153 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1154 Combine(Values("PointSize"),
1155 Values("Vertex", "Geometry", "TessellationControl",
1156 "TessellationEvaluation"),
1157 Values("Output"), Values("%f32"), Values(nullptr),
1158 Values(TestResult())));
1159
1160 INSTANTIATE_TEST_SUITE_P(
1161 PointSizeInputSuccess,
1162 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1163 Combine(Values("PointSize"),
1164 Values("Geometry", "TessellationControl", "TessellationEvaluation"),
1165 Values("Input"), Values("%f32"), Values(nullptr),
1166 Values(TestResult())));
1167
1168 INSTANTIATE_TEST_SUITE_P(
1169 PointSizeVertexInput,
1170 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1171 Combine(Values("PointSize"), Values("Vertex"), Values("Input"),
1172 Values("%f32"), Values("VUID-PointSize-PointSize-04315"),
1173 Values(TestResult(
1174 SPV_ERROR_INVALID_DATA,
1175 "Vulkan spec doesn't allow BuiltIn PointSize "
1176 "to be used for variables with Input storage class if "
1177 "execution model is Vertex.",
1178 "which is called with execution model Vertex."))));
1179
1180 INSTANTIATE_TEST_SUITE_P(
1181 PointSizeInvalidExecutionModel,
1182 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1183 Combine(Values("PointSize"), Values("GLCompute", "Fragment"),
1184 Values("Input", "Output"), Values("%f32"),
1185 Values("VUID-PointSize-PointSize-04314"),
1186 Values(TestResult(
1187 SPV_ERROR_INVALID_DATA,
1188 "to be used only with Vertex, TessellationControl, "
1189 "TessellationEvaluation or Geometry execution models"))));
1190
1191 INSTANTIATE_TEST_SUITE_P(
1192 PointSizeNotFloatScalar,
1193 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1194 Combine(Values("PointSize"), Values("Vertex"), Values("Output"),
1195 Values("%f32vec4", "%u32"),
1196 Values("VUID-PointSize-PointSize-04317"),
1197 Values(TestResult(SPV_ERROR_INVALID_DATA,
1198 "needs to be a 32-bit float scalar",
1199 "is not a float scalar"))));
1200
1201 INSTANTIATE_TEST_SUITE_P(
1202 PointSizeNotF32, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1203 Combine(Values("PointSize"), Values("Vertex"), Values("Output"),
1204 Values("%f64"), Values("VUID-PointSize-PointSize-04317"),
1205 Values(TestResult(SPV_ERROR_INVALID_DATA,
1206 "needs to be a 32-bit float scalar",
1207 "has bit width 64"))));
1208
1209 INSTANTIATE_TEST_SUITE_P(
1210 PositionOutputSuccess,
1211 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1212 Combine(Values("Position"),
1213 Values("Vertex", "Geometry", "TessellationControl",
1214 "TessellationEvaluation"),
1215 Values("Output"), Values("%f32vec4"), Values(nullptr),
1216 Values(TestResult())));
1217
1218 INSTANTIATE_TEST_SUITE_P(
1219 PositionInputSuccess,
1220 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1221 Combine(Values("Position"),
1222 Values("Geometry", "TessellationControl", "TessellationEvaluation"),
1223 Values("Input"), Values("%f32vec4"), Values(nullptr),
1224 Values(TestResult())));
1225
1226 INSTANTIATE_TEST_SUITE_P(
1227 PositionInvalidStorageClass,
1228 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1229 Combine(Values("Position"),
1230 Values("Geometry", "TessellationControl", "TessellationEvaluation"),
1231 Values("Private"), Values("%f32vec4"),
1232 Values("VUID-Position-Position-04320"),
1233 Values(TestResult(
1234 SPV_ERROR_INVALID_DATA,
1235 "Vulkan spec allows BuiltIn Position to be only used for "
1236 "variables with Input or Output storage class."))));
1237
1238 INSTANTIATE_TEST_SUITE_P(
1239 PositionVertexInput,
1240 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1241 Combine(Values("Position"), Values("Vertex"), Values("Input"),
1242 Values("%f32vec4"), Values("VUID-Position-Position-04319"),
1243 Values(TestResult(
1244 SPV_ERROR_INVALID_DATA,
1245 "Vulkan spec doesn't allow BuiltIn Position "
1246 "to be used for variables with Input storage class if "
1247 "execution model is Vertex.",
1248 "which is called with execution model Vertex."))));
1249
1250 INSTANTIATE_TEST_SUITE_P(
1251 PositionInvalidExecutionModel,
1252 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1253 Combine(Values("Position"), Values("GLCompute", "Fragment"),
1254 Values("Input", "Output"), Values("%f32vec4"),
1255 Values("VUID-Position-Position-04318"),
1256 Values(TestResult(
1257 SPV_ERROR_INVALID_DATA,
1258 "to be used only with Vertex, TessellationControl, "
1259 "TessellationEvaluation or Geometry execution models"))));
1260
1261 INSTANTIATE_TEST_SUITE_P(
1262 PositionNotFloatVector,
1263 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1264 Combine(Values("Position"), Values("Geometry"), Values("Input"),
1265 Values("%f32arr4", "%u32vec4"),
1266 Values("VUID-Position-Position-04321"),
1267 Values(TestResult(SPV_ERROR_INVALID_DATA,
1268 "needs to be a 4-component 32-bit float vector",
1269 "is not a float vector"))));
1270
1271 INSTANTIATE_TEST_SUITE_P(
1272 PositionNotFloatVec4,
1273 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1274 Combine(Values("Position"), Values("Geometry"), Values("Input"),
1275 Values("%f32vec3"), Values("VUID-Position-Position-04321"),
1276 Values(TestResult(SPV_ERROR_INVALID_DATA,
1277 "needs to be a 4-component 32-bit float vector",
1278 "has 3 components"))));
1279
1280 INSTANTIATE_TEST_SUITE_P(
1281 PositionNotF32Vec4,
1282 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1283 Combine(Values("Position"), Values("Geometry"), Values("Input"),
1284 Values("%f64vec4"), Values("VUID-Position-Position-04321"),
1285 Values(TestResult(SPV_ERROR_INVALID_DATA,
1286 "needs to be a 4-component 32-bit float vector",
1287 "has components with bit width 64"))));
1288
1289 INSTANTIATE_TEST_SUITE_P(
1290 PrimitiveIdInputSuccess,
1291 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1292 Combine(Values("PrimitiveId"),
1293 Values("Fragment", "TessellationControl", "TessellationEvaluation",
1294 "Geometry"),
1295 Values("Input"), Values("%u32"), Values(nullptr),
1296 Values(TestResult())));
1297
1298 INSTANTIATE_TEST_SUITE_P(
1299 PrimitiveIdOutputSuccess,
1300 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1301 Combine(Values("PrimitiveId"), Values("Geometry"), Values("Output"),
1302 Values("%u32"), Values(nullptr), Values(TestResult())));
1303
1304 INSTANTIATE_TEST_SUITE_P(
1305 PrimitiveIdInvalidExecutionModel,
1306 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1307 Combine(Values("PrimitiveId"), Values("Vertex", "GLCompute"),
1308 Values("Input"), Values("%u32"),
1309 Values("VUID-PrimitiveId-PrimitiveId-04330"),
1310 Values(TestResult(
1311 SPV_ERROR_INVALID_DATA,
1312 "to be used only with Fragment, TessellationControl, "
1313 "TessellationEvaluation, Geometry, MeshNV, IntersectionKHR, "
1314 "AnyHitKHR, and ClosestHitKHR execution models"))));
1315
1316 INSTANTIATE_TEST_SUITE_P(
1317 PrimitiveIdFragmentNotInput,
1318 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1319 Combine(
1320 Values("PrimitiveId"), Values("Fragment"), Values("Output"),
1321 Values("%u32"), Values("VUID-PrimitiveId-PrimitiveId-04334"),
1322 Values(TestResult(SPV_ERROR_INVALID_DATA,
1323 "Output storage class if execution model is Fragment",
1324 "which is called with execution model Fragment"))));
1325
1326 INSTANTIATE_TEST_SUITE_P(
1327 PrimitiveIdTessellationNotInput,
1328 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1329 Combine(Values("PrimitiveId"),
1330 Values("TessellationControl", "TessellationEvaluation"),
1331 Values("Output"), Values("%u32"),
1332 Values("VUID-PrimitiveId-PrimitiveId-04334"),
1333 Values(TestResult(
1334 SPV_ERROR_INVALID_DATA,
1335 "Output storage class if execution model is Tessellation",
1336 "which is called with execution model Tessellation"))));
1337
1338 INSTANTIATE_TEST_SUITE_P(
1339 PrimitiveIdNotIntScalar,
1340 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1341 Combine(Values("PrimitiveId"), Values("Fragment"), Values("Input"),
1342 Values("%f32", "%u32vec3"),
1343 Values("VUID-PrimitiveId-PrimitiveId-04337"),
1344 Values(TestResult(SPV_ERROR_INVALID_DATA,
1345 "needs to be a 32-bit int scalar",
1346 "is not an int scalar"))));
1347
1348 INSTANTIATE_TEST_SUITE_P(
1349 PrimitiveIdNotInt32,
1350 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1351 Combine(Values("PrimitiveId"), Values("Fragment"), Values("Input"),
1352 Values("%u64"), Values("VUID-PrimitiveId-PrimitiveId-04337"),
1353 Values(TestResult(SPV_ERROR_INVALID_DATA,
1354 "needs to be a 32-bit int scalar",
1355 "has bit width 64"))));
1356
1357 INSTANTIATE_TEST_SUITE_P(
1358 SampleIdSuccess, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1359 Combine(Values("SampleId"), Values("Fragment"), Values("Input"),
1360 Values("%u32"), Values(nullptr), Values(TestResult())));
1361
1362 INSTANTIATE_TEST_SUITE_P(
1363 SampleIdInvalidExecutionModel,
1364 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1365 Combine(
1366 Values("SampleId"),
1367 Values("Vertex", "GLCompute", "Geometry", "TessellationControl",
1368 "TessellationEvaluation"),
1369 Values("Input"), Values("%u32"), Values("VUID-SampleId-SampleId-04354"),
1370 Values(TestResult(SPV_ERROR_INVALID_DATA,
1371 "to be used only with Fragment execution model"))));
1372
1373 INSTANTIATE_TEST_SUITE_P(
1374 SampleIdNotInput, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1375 Combine(
1376 Values("SampleId"), Values("Fragment"), Values("Output"),
1377 Values("%u32"), Values("VUID-SampleId-SampleId-04355"),
1378 Values(TestResult(SPV_ERROR_INVALID_DATA,
1379 "Vulkan spec allows BuiltIn SampleId to be only used "
1380 "for variables with Input storage class"))));
1381
1382 INSTANTIATE_TEST_SUITE_P(
1383 SampleIdNotIntScalar,
1384 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1385 Combine(Values("SampleId"), Values("Fragment"), Values("Input"),
1386 Values("%f32", "%u32vec3"), Values("VUID-SampleId-SampleId-04356"),
1387 Values(TestResult(SPV_ERROR_INVALID_DATA,
1388 "needs to be a 32-bit int scalar",
1389 "is not an int scalar"))));
1390
1391 INSTANTIATE_TEST_SUITE_P(
1392 SampleIdNotInt32, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1393 Combine(Values("SampleId"), Values("Fragment"), Values("Input"),
1394 Values("%u64"), Values("VUID-SampleId-SampleId-04356"),
1395 Values(TestResult(SPV_ERROR_INVALID_DATA,
1396 "needs to be a 32-bit int scalar",
1397 "has bit width 64"))));
1398
1399 INSTANTIATE_TEST_SUITE_P(
1400 SampleMaskSuccess, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1401 Combine(Values("SampleMask"), Values("Fragment"), Values("Input", "Output"),
1402 Values("%u32arr2", "%u32arr4"), Values(nullptr),
1403 Values(TestResult())));
1404
1405 INSTANTIATE_TEST_SUITE_P(
1406 SampleMaskInvalidExecutionModel,
1407 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1408 Combine(
1409 Values("SampleMask"),
1410 Values("Vertex", "GLCompute", "Geometry", "TessellationControl",
1411 "TessellationEvaluation"),
1412 Values("Input"), Values("%u32arr2"),
1413 Values("VUID-SampleMask-SampleMask-04357"),
1414 Values(TestResult(SPV_ERROR_INVALID_DATA,
1415 "to be used only with Fragment execution model"))));
1416
1417 INSTANTIATE_TEST_SUITE_P(
1418 SampleMaskWrongStorageClass,
1419 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1420 Combine(Values("SampleMask"), Values("Fragment"), Values("Workgroup"),
1421 Values("%u32arr2"), Values("VUID-SampleMask-SampleMask-04358"),
1422 Values(TestResult(
1423 SPV_ERROR_INVALID_DATA,
1424 "Vulkan spec allows BuiltIn SampleMask to be only used for "
1425 "variables with Input or Output storage class"))));
1426
1427 INSTANTIATE_TEST_SUITE_P(
1428 SampleMaskNotArray,
1429 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1430 Combine(Values("SampleMask"), Values("Fragment"), Values("Input"),
1431 Values("%f32", "%u32vec3"),
1432 Values("VUID-SampleMask-SampleMask-04359"),
1433 Values(TestResult(SPV_ERROR_INVALID_DATA,
1434 "needs to be a 32-bit int array",
1435 "is not an array"))));
1436
1437 INSTANTIATE_TEST_SUITE_P(
1438 SampleMaskNotIntArray,
1439 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1440 Combine(Values("SampleMask"), Values("Fragment"), Values("Input"),
1441 Values("%f32arr2"), Values("VUID-SampleMask-SampleMask-04359"),
1442 Values(TestResult(SPV_ERROR_INVALID_DATA,
1443 "needs to be a 32-bit int array",
1444 "components are not int scalar"))));
1445
1446 INSTANTIATE_TEST_SUITE_P(
1447 SampleMaskNotInt32Array,
1448 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1449 Combine(Values("SampleMask"), Values("Fragment"), Values("Input"),
1450 Values("%u64arr2"), Values("VUID-SampleMask-SampleMask-04359"),
1451 Values(TestResult(SPV_ERROR_INVALID_DATA,
1452 "needs to be a 32-bit int array",
1453 "has components with bit width 64"))));
1454
1455 INSTANTIATE_TEST_SUITE_P(
1456 SamplePositionSuccess,
1457 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1458 Combine(Values("SamplePosition"), Values("Fragment"), Values("Input"),
1459 Values("%f32vec2"), Values(nullptr), Values(TestResult())));
1460
1461 INSTANTIATE_TEST_SUITE_P(
1462 SamplePositionNotFragment,
1463 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1464 Combine(
1465 Values("SamplePosition"),
1466 Values("Vertex", "GLCompute", "Geometry", "TessellationControl",
1467 "TessellationEvaluation"),
1468 Values("Input"), Values("%f32vec2"),
1469 Values("VUID-SamplePosition-SamplePosition-04360"),
1470 Values(TestResult(SPV_ERROR_INVALID_DATA,
1471 "to be used only with Fragment execution model"))));
1472
1473 INSTANTIATE_TEST_SUITE_P(
1474 SamplePositionNotInput,
1475 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1476 Combine(Values("SamplePosition"), Values("Fragment"), Values("Output"),
1477 Values("%f32vec2"),
1478 Values("VUID-SamplePosition-SamplePosition-04361"),
1479 Values(TestResult(
1480 SPV_ERROR_INVALID_DATA,
1481 "to be only used for variables with Input storage class",
1482 "uses storage class Output"))));
1483
1484 INSTANTIATE_TEST_SUITE_P(
1485 SamplePositionNotFloatVector,
1486 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1487 Combine(Values("SamplePosition"), Values("Fragment"), Values("Input"),
1488 Values("%f32arr2", "%u32vec4"),
1489 Values("VUID-SamplePosition-SamplePosition-04362"),
1490 Values(TestResult(SPV_ERROR_INVALID_DATA,
1491 "needs to be a 2-component 32-bit float vector",
1492 "is not a float vector"))));
1493
1494 INSTANTIATE_TEST_SUITE_P(
1495 SamplePositionNotFloatVec2,
1496 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1497 Combine(Values("SamplePosition"), Values("Fragment"), Values("Input"),
1498 Values("%f32vec3"),
1499 Values("VUID-SamplePosition-SamplePosition-04362"),
1500 Values(TestResult(SPV_ERROR_INVALID_DATA,
1501 "needs to be a 2-component 32-bit float vector",
1502 "has 3 components"))));
1503
1504 INSTANTIATE_TEST_SUITE_P(
1505 SamplePositionNotF32Vec2,
1506 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1507 Combine(Values("SamplePosition"), Values("Fragment"), Values("Input"),
1508 Values("%f64vec2"),
1509 Values("VUID-SamplePosition-SamplePosition-04362"),
1510 Values(TestResult(SPV_ERROR_INVALID_DATA,
1511 "needs to be a 2-component 32-bit float vector",
1512 "has components with bit width 64"))));
1513
1514 INSTANTIATE_TEST_SUITE_P(
1515 TessCoordSuccess, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1516 Combine(Values("TessCoord"), Values("TessellationEvaluation"),
1517 Values("Input"), Values("%f32vec3"), Values(nullptr),
1518 Values(TestResult())));
1519
1520 INSTANTIATE_TEST_SUITE_P(
1521 TessCoordNotFragment,
1522 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1523 Combine(
1524 Values("TessCoord"),
1525 Values("Vertex", "GLCompute", "Geometry", "TessellationControl",
1526 "Fragment"),
1527 Values("Input"), Values("%f32vec3"),
1528 Values("VUID-TessCoord-TessCoord-04387"),
1529 Values(TestResult(
1530 SPV_ERROR_INVALID_DATA,
1531 "to be used only with TessellationEvaluation execution model"))));
1532
1533 INSTANTIATE_TEST_SUITE_P(
1534 TessCoordNotInput, ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1535 Combine(Values("TessCoord"), Values("Fragment"), Values("Output"),
1536 Values("%f32vec3"), Values("VUID-TessCoord-TessCoord-04388"),
1537 Values(TestResult(
1538 SPV_ERROR_INVALID_DATA,
1539 "to be only used for variables with Input storage class",
1540 "uses storage class Output"))));
1541
1542 INSTANTIATE_TEST_SUITE_P(
1543 TessCoordNotFloatVector,
1544 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1545 Combine(Values("TessCoord"), Values("Fragment"), Values("Input"),
1546 Values("%f32arr3", "%u32vec4"),
1547 Values("VUID-TessCoord-TessCoord-04389"),
1548 Values(TestResult(SPV_ERROR_INVALID_DATA,
1549 "needs to be a 3-component 32-bit float vector",
1550 "is not a float vector"))));
1551
1552 INSTANTIATE_TEST_SUITE_P(
1553 TessCoordNotFloatVec3,
1554 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1555 Combine(Values("TessCoord"), Values("Fragment"), Values("Input"),
1556 Values("%f32vec2"), Values("VUID-TessCoord-TessCoord-04389"),
1557 Values(TestResult(SPV_ERROR_INVALID_DATA,
1558 "needs to be a 3-component 32-bit float vector",
1559 "has 2 components"))));
1560
1561 INSTANTIATE_TEST_SUITE_P(
1562 TessCoordNotF32Vec3,
1563 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1564 Combine(Values("TessCoord"), Values("Fragment"), Values("Input"),
1565 Values("%f64vec3"), Values("VUID-TessCoord-TessCoord-04389"),
1566 Values(TestResult(SPV_ERROR_INVALID_DATA,
1567 "needs to be a 3-component 32-bit float vector",
1568 "has components with bit width 64"))));
1569
1570 INSTANTIATE_TEST_SUITE_P(
1571 TessLevelOuterTeseInputSuccess,
1572 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1573 Combine(Values("TessLevelOuter"), Values("TessellationEvaluation"),
1574 Values("Input"), Values("%f32arr4"), Values(nullptr),
1575 Values(TestResult())));
1576
1577 INSTANTIATE_TEST_SUITE_P(
1578 TessLevelOuterTescOutputSuccess,
1579 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1580 Combine(Values("TessLevelOuter"), Values("TessellationControl"),
1581 Values("Output"), Values("%f32arr4"), Values(nullptr),
1582 Values(TestResult())));
1583
1584 INSTANTIATE_TEST_SUITE_P(
1585 TessLevelOuterInvalidExecutionModel,
1586 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1587 Combine(Values("TessLevelOuter"),
1588 Values("Vertex", "GLCompute", "Geometry", "Fragment"),
1589 Values("Input"), Values("%f32arr4"),
1590 Values("VUID-TessLevelOuter-TessLevelOuter-04390"),
1591 Values(TestResult(SPV_ERROR_INVALID_DATA,
1592 "to be used only with TessellationControl or "
1593 "TessellationEvaluation execution models."))));
1594
1595 INSTANTIATE_TEST_SUITE_P(
1596 TessLevelOuterOutputTese,
1597 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1598 Combine(Values("TessLevelOuter"), Values("TessellationEvaluation"),
1599 Values("Output"), Values("%f32arr4"),
1600 Values("VUID-TessLevelOuter-TessLevelOuter-04392"),
1601 Values(TestResult(
1602 SPV_ERROR_INVALID_DATA,
1603 "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be "
1604 "used for variables with Output storage class if execution "
1605 "model is TessellationEvaluation."))));
1606
1607 INSTANTIATE_TEST_SUITE_P(
1608 TessLevelOuterInputTesc,
1609 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1610 Combine(Values("TessLevelOuter"), Values("TessellationControl"),
1611 Values("Input"), Values("%f32arr4"),
1612 Values("VUID-TessLevelOuter-TessLevelOuter-04391"),
1613 Values(TestResult(
1614 SPV_ERROR_INVALID_DATA,
1615 "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be "
1616 "used for variables with Input storage class if execution "
1617 "model is TessellationControl."))));
1618
1619 INSTANTIATE_TEST_SUITE_P(
1620 TessLevelOuterNotArray,
1621 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1622 Combine(Values("TessLevelOuter"), Values("TessellationEvaluation"),
1623 Values("Input"), Values("%f32vec4", "%f32"),
1624 Values("VUID-TessLevelOuter-TessLevelOuter-04393"),
1625 Values(TestResult(SPV_ERROR_INVALID_DATA,
1626 "needs to be a 4-component 32-bit float array",
1627 "is not an array"))));
1628
1629 INSTANTIATE_TEST_SUITE_P(
1630 TessLevelOuterNotFloatArray,
1631 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1632 Combine(Values("TessLevelOuter"), Values("TessellationEvaluation"),
1633 Values("Input"), Values("%u32arr4"),
1634 Values("VUID-TessLevelOuter-TessLevelOuter-04393"),
1635 Values(TestResult(SPV_ERROR_INVALID_DATA,
1636 "needs to be a 4-component 32-bit float array",
1637 "components are not float scalar"))));
1638
1639 INSTANTIATE_TEST_SUITE_P(
1640 TessLevelOuterNotFloatArr4,
1641 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1642 Combine(Values("TessLevelOuter"), Values("TessellationEvaluation"),
1643 Values("Input"), Values("%f32arr3"),
1644 Values("VUID-TessLevelOuter-TessLevelOuter-04393"),
1645 Values(TestResult(SPV_ERROR_INVALID_DATA,
1646 "needs to be a 4-component 32-bit float array",
1647 "has 3 components"))));
1648
1649 INSTANTIATE_TEST_SUITE_P(
1650 TessLevelOuterNotF32Arr4,
1651 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1652 Combine(Values("TessLevelOuter"), Values("TessellationEvaluation"),
1653 Values("Input"), Values("%f64arr4"),
1654 Values("VUID-TessLevelOuter-TessLevelOuter-04393"),
1655 Values(TestResult(SPV_ERROR_INVALID_DATA,
1656 "needs to be a 4-component 32-bit float array",
1657 "has components with bit width 64"))));
1658
1659 INSTANTIATE_TEST_SUITE_P(
1660 TessLevelInnerTeseInputSuccess,
1661 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1662 Combine(Values("TessLevelInner"), Values("TessellationEvaluation"),
1663 Values("Input"), Values("%f32arr2"), Values(nullptr),
1664 Values(TestResult())));
1665
1666 INSTANTIATE_TEST_SUITE_P(
1667 TessLevelInnerTescOutputSuccess,
1668 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1669 Combine(Values("TessLevelInner"), Values("TessellationControl"),
1670 Values("Output"), Values("%f32arr2"), Values(nullptr),
1671 Values(TestResult())));
1672
1673 INSTANTIATE_TEST_SUITE_P(
1674 TessLevelInnerInvalidExecutionModel,
1675 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1676 Combine(Values("TessLevelInner"),
1677 Values("Vertex", "GLCompute", "Geometry", "Fragment"),
1678 Values("Input"), Values("%f32arr2"),
1679 Values("VUID-TessLevelInner-TessLevelInner-04394"),
1680 Values(TestResult(SPV_ERROR_INVALID_DATA,
1681 "to be used only with TessellationControl or "
1682 "TessellationEvaluation execution models."))));
1683
1684 INSTANTIATE_TEST_SUITE_P(
1685 TessLevelInnerOutputTese,
1686 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1687 Combine(Values("TessLevelInner"), Values("TessellationEvaluation"),
1688 Values("Output"), Values("%f32arr2"),
1689 Values("VUID-TessLevelInner-TessLevelInner-04396"),
1690 Values(TestResult(
1691 SPV_ERROR_INVALID_DATA,
1692 "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be "
1693 "used for variables with Output storage class if execution "
1694 "model is TessellationEvaluation."))));
1695
1696 INSTANTIATE_TEST_SUITE_P(
1697 TessLevelInnerInputTesc,
1698 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1699 Combine(Values("TessLevelInner"), Values("TessellationControl"),
1700 Values("Input"), Values("%f32arr2"),
1701 Values("VUID-TessLevelInner-TessLevelInner-04395"),
1702 Values(TestResult(
1703 SPV_ERROR_INVALID_DATA,
1704 "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be "
1705 "used for variables with Input storage class if execution "
1706 "model is TessellationControl."))));
1707
1708 INSTANTIATE_TEST_SUITE_P(
1709 TessLevelInnerNotArray,
1710 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1711 Combine(Values("TessLevelInner"), Values("TessellationEvaluation"),
1712 Values("Input"), Values("%f32vec2", "%f32"),
1713 Values("VUID-TessLevelInner-TessLevelInner-04397"),
1714 Values(TestResult(SPV_ERROR_INVALID_DATA,
1715 "needs to be a 2-component 32-bit float array",
1716 "is not an array"))));
1717
1718 INSTANTIATE_TEST_SUITE_P(
1719 TessLevelInnerNotFloatArray,
1720 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1721 Combine(Values("TessLevelInner"), Values("TessellationEvaluation"),
1722 Values("Input"), Values("%u32arr2"),
1723 Values("VUID-TessLevelInner-TessLevelInner-04397"),
1724 Values(TestResult(SPV_ERROR_INVALID_DATA,
1725 "needs to be a 2-component 32-bit float array",
1726 "components are not float scalar"))));
1727
1728 INSTANTIATE_TEST_SUITE_P(
1729 TessLevelInnerNotFloatArr2,
1730 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1731 Combine(Values("TessLevelInner"), Values("TessellationEvaluation"),
1732 Values("Input"), Values("%f32arr3"),
1733 Values("VUID-TessLevelInner-TessLevelInner-04397"),
1734 Values(TestResult(SPV_ERROR_INVALID_DATA,
1735 "needs to be a 2-component 32-bit float array",
1736 "has 3 components"))));
1737
1738 INSTANTIATE_TEST_SUITE_P(
1739 TessLevelInnerNotF32Arr2,
1740 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1741 Combine(Values("TessLevelInner"), Values("TessellationEvaluation"),
1742 Values("Input"), Values("%f64arr2"),
1743 Values("VUID-TessLevelInner-TessLevelInner-04397"),
1744 Values(TestResult(SPV_ERROR_INVALID_DATA,
1745 "needs to be a 2-component 32-bit float array",
1746 "has components with bit width 64"))));
1747
1748 INSTANTIATE_TEST_SUITE_P(
1749 VertexIndexSuccess,
1750 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1751 Combine(Values("VertexIndex"), Values("Vertex"), Values("Input"),
1752 Values("%u32"), Values(nullptr), Values(TestResult())));
1753
1754 INSTANTIATE_TEST_SUITE_P(
1755 VertexIndexInvalidExecutionModel,
1756 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1757 Combine(Values("VertexIndex"),
1758 Values("Fragment", "GLCompute", "Geometry", "TessellationControl",
1759 "TessellationEvaluation"),
1760 Values("Input"), Values("%u32"),
1761 Values("VUID-VertexIndex-VertexIndex-04398"),
1762 Values(TestResult(SPV_ERROR_INVALID_DATA,
1763 "to be used only with Vertex execution model"))));
1764
1765 INSTANTIATE_TEST_SUITE_P(
1766 VertexIndexNotInput,
1767 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1768 Combine(
1769 Values("VertexIndex"), Values("Vertex"), Values("Output"),
1770 Values("%u32"), Values("VUID-VertexIndex-VertexIndex-04399"),
1771 Values(TestResult(SPV_ERROR_INVALID_DATA,
1772 "Vulkan spec allows BuiltIn VertexIndex to be only "
1773 "used for variables with Input storage class"))));
1774
1775 INSTANTIATE_TEST_SUITE_P(
1776 VertexIndexNotIntScalar,
1777 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1778 Combine(Values("VertexIndex"), Values("Vertex"), Values("Input"),
1779 Values("%f32", "%u32vec3"),
1780 Values("VUID-VertexIndex-VertexIndex-04400"),
1781 Values(TestResult(SPV_ERROR_INVALID_DATA,
1782 "needs to be a 32-bit int scalar",
1783 "is not an int scalar"))));
1784
1785 INSTANTIATE_TEST_SUITE_P(
1786 VertexIndexNotInt32,
1787 ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
1788 Combine(Values("VertexIndex"), Values("Vertex"), Values("Input"),
1789 Values("%u64"), Values("VUID-VertexIndex-VertexIndex-04400"),
1790 Values(TestResult(SPV_ERROR_INVALID_DATA,
1791 "needs to be a 32-bit int scalar",
1792 "has bit width 64"))));
1793
1794 INSTANTIATE_TEST_SUITE_P(
1795 BaseInstanceOrVertexSuccess,
1796 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1797 Combine(Values("BaseInstance", "BaseVertex"), Values("Vertex"),
1798 Values("Input"), Values("%u32"),
1799 Values("OpCapability DrawParameters\n"),
1800 Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\n"),
1801 Values(nullptr), Values(TestResult())));
1802
1803 INSTANTIATE_TEST_SUITE_P(
1804 BaseInstanceOrVertexInvalidExecutionModel,
1805 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1806 Combine(Values("BaseInstance", "BaseVertex"),
1807 Values("Fragment", "GLCompute", "Geometry", "TessellationControl",
1808 "TessellationEvaluation"),
1809 Values("Input"), Values("%u32"),
1810 Values("OpCapability DrawParameters\n"),
1811 Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\n"),
1812 Values("VUID-BaseInstance-BaseInstance-04181 "
1813 "VUID-BaseVertex-BaseVertex-04184"),
1814 Values(TestResult(SPV_ERROR_INVALID_DATA,
1815 "to be used only with Vertex execution model"))));
1816
1817 INSTANTIATE_TEST_SUITE_P(
1818 BaseInstanceOrVertexNotInput,
1819 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1820 Combine(Values("BaseInstance", "BaseVertex"), Values("Vertex"),
1821 Values("Output"), Values("%u32"),
1822 Values("OpCapability DrawParameters\n"),
1823 Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\n"),
1824 Values("VUID-BaseInstance-BaseInstance-04182 "
1825 "VUID-BaseVertex-BaseVertex-04185"),
1826 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
1827 "used for variables with Input storage class"))));
1828
1829 INSTANTIATE_TEST_SUITE_P(
1830 BaseInstanceOrVertexNotIntScalar,
1831 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1832 Combine(Values("BaseInstance", "BaseVertex"), Values("Vertex"),
1833 Values("Input"), Values("%f32", "%u32vec3"),
1834 Values("OpCapability DrawParameters\n"),
1835 Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\n"),
1836 Values("VUID-BaseInstance-BaseInstance-04183 "
1837 "VUID-BaseVertex-BaseVertex-04186"),
1838 Values(TestResult(SPV_ERROR_INVALID_DATA,
1839 "needs to be a 32-bit int scalar",
1840 "is not an int scalar"))));
1841
1842 INSTANTIATE_TEST_SUITE_P(
1843 DrawIndexSuccess,
1844 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1845 Combine(Values("DrawIndex"), Values("Vertex"), Values("Input"),
1846 Values("%u32"), Values("OpCapability DrawParameters\n"),
1847 Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\n"),
1848 Values(nullptr), Values(TestResult())));
1849
1850 INSTANTIATE_TEST_SUITE_P(
1851 DrawIndexMeshSuccess,
1852 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1853 Combine(
1854 Values("DrawIndex"), Values("MeshNV", "TaskNV"), Values("Input"),
1855 Values("%u32"), Values("OpCapability MeshShadingNV\n"),
1856 Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\nOpExtension "
1857 "\"SPV_NV_mesh_shader\"\n"),
1858 Values(nullptr), Values(TestResult())));
1859
1860 INSTANTIATE_TEST_SUITE_P(
1861 DrawIndexInvalidExecutionModel,
1862 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1863 Combine(Values("DrawIndex"),
1864 Values("Fragment", "GLCompute", "Geometry", "TessellationControl",
1865 "TessellationEvaluation"),
1866 Values("Input"), Values("%u32"),
1867 Values("OpCapability DrawParameters\n"),
1868 Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\n"),
1869 Values("VUID-DrawIndex-DrawIndex-04207"),
1870 Values(TestResult(SPV_ERROR_INVALID_DATA,
1871 "to be used only with Vertex, MeshNV, or TaskNV "
1872 "execution model"))));
1873
1874 INSTANTIATE_TEST_SUITE_P(
1875 DrawIndexNotInput,
1876 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1877 Combine(Values("DrawIndex"), Values("Vertex"), Values("Output"),
1878 Values("%u32"), Values("OpCapability DrawParameters\n"),
1879 Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\n"),
1880 Values("VUID-DrawIndex-DrawIndex-04208"),
1881 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
1882 "used for variables with Input storage class"))));
1883
1884 INSTANTIATE_TEST_SUITE_P(
1885 DrawIndexNotIntScalar,
1886 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1887 Combine(Values("DrawIndex"), Values("Vertex"), Values("Input"),
1888 Values("%f32", "%u32vec3"), Values("OpCapability DrawParameters\n"),
1889 Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\n"),
1890 Values("VUID-DrawIndex-DrawIndex-04209"),
1891 Values(TestResult(SPV_ERROR_INVALID_DATA,
1892 "needs to be a 32-bit int scalar",
1893 "is not an int scalar"))));
1894
1895 INSTANTIATE_TEST_SUITE_P(
1896 ViewIndexSuccess,
1897 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1898 Combine(Values("ViewIndex"),
1899 Values("Fragment", "Vertex", "Geometry", "TessellationControl",
1900 "TessellationEvaluation"),
1901 Values("Input"), Values("%u32"), Values("OpCapability MultiView\n"),
1902 Values("OpExtension \"SPV_KHR_multiview\"\n"), Values(nullptr),
1903 Values(TestResult())));
1904
1905 INSTANTIATE_TEST_SUITE_P(
1906 ViewIndexInvalidExecutionModel,
1907 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1908 Combine(Values("ViewIndex"), Values("GLCompute"), Values("Input"),
1909 Values("%u32"), Values("OpCapability MultiView\n"),
1910 Values("OpExtension \"SPV_KHR_multiview\"\n"),
1911 Values("VUID-ViewIndex-ViewIndex-04401"),
1912 Values(TestResult(
1913 SPV_ERROR_INVALID_DATA,
1914 "to be not be used with GLCompute execution model"))));
1915
1916 INSTANTIATE_TEST_SUITE_P(
1917 ViewIndexNotInput,
1918 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1919 Combine(Values("ViewIndex"), Values("Vertex"), Values("Output"),
1920 Values("%u32"), Values("OpCapability MultiView\n"),
1921 Values("OpExtension \"SPV_KHR_multiview\"\n"),
1922 Values("VUID-ViewIndex-ViewIndex-04402"),
1923 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
1924 "used for variables with Input storage class"))));
1925
1926 INSTANTIATE_TEST_SUITE_P(
1927 ViewIndexNotIntScalar,
1928 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1929 Combine(Values("ViewIndex"), Values("Vertex"), Values("Input"),
1930 Values("%f32", "%u32vec3"), Values("OpCapability MultiView\n"),
1931 Values("OpExtension \"SPV_KHR_multiview\"\n"),
1932 Values("VUID-ViewIndex-ViewIndex-04403"),
1933 Values(TestResult(SPV_ERROR_INVALID_DATA,
1934 "needs to be a 32-bit int scalar",
1935 "is not an int scalar"))));
1936
1937 INSTANTIATE_TEST_SUITE_P(
1938 DeviceIndexSuccess,
1939 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1940 Combine(Values("DeviceIndex"),
1941 Values("Fragment", "Vertex", "Geometry", "TessellationControl",
1942 "TessellationEvaluation", "GLCompute"),
1943 Values("Input"), Values("%u32"),
1944 Values("OpCapability DeviceGroup\n"),
1945 Values("OpExtension \"SPV_KHR_device_group\"\n"), Values(nullptr),
1946 Values(TestResult())));
1947
1948 INSTANTIATE_TEST_SUITE_P(
1949 DeviceIndexNotInput,
1950 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1951 Combine(Values("DeviceIndex"), Values("Fragment", "Vertex", "GLCompute"),
1952 Values("Output"), Values("%u32"),
1953 Values("OpCapability DeviceGroup\n"),
1954 Values("OpExtension \"SPV_KHR_device_group\"\n"),
1955 Values("VUID-DeviceIndex-DeviceIndex-04205"),
1956 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
1957 "used for variables with Input storage class"))));
1958
1959 INSTANTIATE_TEST_SUITE_P(
1960 DeviceIndexNotIntScalar,
1961 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1962 Combine(Values("DeviceIndex"), Values("Fragment", "Vertex", "GLCompute"),
1963 Values("Input"), Values("%f32", "%u32vec3"),
1964 Values("OpCapability DeviceGroup\n"),
1965 Values("OpExtension \"SPV_KHR_device_group\"\n"),
1966 Values("VUID-DeviceIndex-DeviceIndex-04206"),
1967 Values(TestResult(SPV_ERROR_INVALID_DATA,
1968 "needs to be a 32-bit int scalar",
1969 "is not an int scalar"))));
1970
1971 // Test HitKind in NV RT shaders
1972 INSTANTIATE_TEST_SUITE_P(
1973 HitKindNVSuccess,
1974 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1975 Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitKindNV"),
1976 Values("AnyHitNV", "ClosestHitNV"), Values("Input"), Values("%u32"),
1977 Values("OpCapability RayTracingNV\n"),
1978 Values("OpExtension \"SPV_NV_ray_tracing\"\n"), Values(nullptr),
1979 Values(TestResult())));
1980
1981 // HitKind is valid in AH, CH shaders as input i32 scalar
1982 INSTANTIATE_TEST_SUITE_P(
1983 HitKindSuccess,
1984 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1985 Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitKindKHR"),
1986 Values("AnyHitKHR", "ClosestHitKHR"), Values("Input"),
1987 Values("%u32"), Values("OpCapability RayTracingKHR\n"),
1988 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
1989 Values(TestResult())));
1990
1991 INSTANTIATE_TEST_SUITE_P(
1992 HitKindNotExecutionMode,
1993 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
1994 Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitKindKHR"),
1995 Values("Vertex", "Fragment", "TessellationControl",
1996 "TessellationEvaluation", "Geometry", "Fragment",
1997 "GLCompute", "RayGenerationKHR", "IntersectionKHR",
1998 "MissKHR", "CallableKHR"),
1999 Values("Input"), Values("%u32"),
2000 Values("OpCapability RayTracingKHR\n"),
2001 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2002 Values("VUID-HitKindKHR-HitKindKHR-04242"),
2003 Values(TestResult(SPV_ERROR_INVALID_DATA,
2004 "Vulkan spec does not allow BuiltIn",
2005 "to be used with the execution model"))));
2006
2007 INSTANTIATE_TEST_SUITE_P(
2008 HitKindNotInput,
2009 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2010 Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitKindKHR"),
2011 Values("AnyHitKHR", "ClosestHitKHR"), Values("Output"),
2012 Values("%u32"), Values("OpCapability RayTracingKHR\n"),
2013 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2014 Values("VUID-HitKindKHR-HitKindKHR-04243"),
2015 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
2016 "used for variables with Input storage class"))));
2017
2018 INSTANTIATE_TEST_SUITE_P(
2019 HitKindNotIntScalar,
2020 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2021 Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitKindKHR"),
2022 Values("AnyHitKHR", "ClosestHitKHR"), Values("Input"),
2023 Values("%f32", "%u32vec3"), Values("OpCapability RayTracingKHR\n"),
2024 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2025 Values("VUID-HitKindKHR-HitKindKHR-04244"),
2026 Values(TestResult(SPV_ERROR_INVALID_DATA,
2027 "needs to be a 32-bit int scalar",
2028 "is not an int scalar"))));
2029
2030 // Ensure HitT is not supported in KHR RT shaders
2031 INSTANTIATE_TEST_SUITE_P(
2032 HitTNVNotSupportedInKHR,
2033 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2034 Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitTNV"),
2035 Values("AnyHitKHR", "ClosestHitKHR"), Values("Input"),
2036 Values("%u32"), Values("OpCapability RayTracingKHR\n"),
2037 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
2038 Values(TestResult(
2039 SPV_ERROR_INVALID_CAPABILITY,
2040 "of MemberDecorate requires one of these capabilities"))));
2041
2042 // HitT is valid in AH, CH shaders as input f32 scalar (NV RT only)
2043 INSTANTIATE_TEST_SUITE_P(
2044 HitTNVSuccess,
2045 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2046 Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitTNV"),
2047 Values("AnyHitNV", "ClosestHitNV"), Values("Input"), Values("%f32"),
2048 Values("OpCapability RayTracingNV\n"),
2049 Values("OpExtension \"SPV_NV_ray_tracing\"\n"), Values(nullptr),
2050 Values(TestResult())));
2051
2052 INSTANTIATE_TEST_SUITE_P(
2053 HitTNVNotExecutionMode,
2054 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2055 Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitTNV"),
2056 Values("Vertex", "Fragment", "TessellationControl",
2057 "TessellationEvaluation", "Geometry", "Fragment",
2058 "GLCompute", "RayGenerationNV", "IntersectionNV", "MissNV",
2059 "CallableNV"),
2060 Values("Input"), Values("%f32"),
2061 Values("OpCapability RayTracingNV\n"),
2062 Values("OpExtension \"SPV_NV_ray_tracing\"\n"),
2063 Values("VUID-HitTNV-HitTNV-04245"),
2064 Values(TestResult(SPV_ERROR_INVALID_DATA,
2065 "Vulkan spec does not allow BuiltIn",
2066 "to be used with the execution model"))));
2067
2068 INSTANTIATE_TEST_SUITE_P(
2069 HitTNVNotInput,
2070 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2071 Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitTNV"),
2072 Values("AnyHitNV", "ClosestHitNV"), Values("Output"),
2073 Values("%f32"), Values("OpCapability RayTracingNV\n"),
2074 Values("OpExtension \"SPV_NV_ray_tracing\"\n"),
2075 Values("VUID-HitTNV-HitTNV-04246"),
2076 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
2077 "used for variables with Input storage class"))));
2078 INSTANTIATE_TEST_SUITE_P(
2079 HitTNVNotIntScalar,
2080 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2081 Combine(Values(SPV_ENV_VULKAN_1_2), Values("HitTNV"),
2082 Values("AnyHitNV", "ClosestHitNV"), Values("Input"),
2083 Values("%u32", "%f32vec3"), Values("OpCapability RayTracingNV\n"),
2084 Values("OpExtension \"SPV_NV_ray_tracing\"\n"),
2085 Values("VUID-HitTNV-HitTNV-04247"),
2086 Values(TestResult(SPV_ERROR_INVALID_DATA,
2087 "needs to be a 32-bit float scalar",
2088 "is not a float scalar"))));
2089
2090 // InstanceCustomIndexKHR, InstanceId, PrimitiveId, RayGeometryIndexKHR are
2091 // valid in IS, AH, CH shaders as input i32 scalars
2092 INSTANTIATE_TEST_SUITE_P(
2093 RTBuiltIn3StageI32Success,
2094 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2095 Combine(Values(SPV_ENV_VULKAN_1_2),
2096 Values("InstanceCustomIndexKHR", "RayGeometryIndexKHR",
2097 "InstanceId", "PrimitiveId"),
2098 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
2099 Values("Input"), Values("%u32"),
2100 Values("OpCapability RayTracingKHR\n"),
2101 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
2102 Values(TestResult())));
2103
2104 INSTANTIATE_TEST_SUITE_P(
2105 RTBuiltIn3StageI32NotExecutionMode,
2106 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2107 Combine(Values(SPV_ENV_VULKAN_1_2),
2108 Values("InstanceCustomIndexKHR", "RayGeometryIndexKHR",
2109 "InstanceId"),
2110 Values("Vertex", "Fragment", "TessellationControl",
2111 "TessellationEvaluation", "Geometry", "Fragment",
2112 "GLCompute", "RayGenerationKHR", "MissKHR", "CallableKHR"),
2113 Values("Input"), Values("%u32"),
2114 Values("OpCapability RayTracingKHR\n"),
2115 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2116 Values("VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04251 "
2117 "VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04345 "
2118 "VUID-InstanceId-InstanceId-04254 "),
2119 Values(TestResult(SPV_ERROR_INVALID_DATA,
2120 "Vulkan spec does not allow BuiltIn",
2121 "to be used with the execution model"))));
2122
2123 INSTANTIATE_TEST_SUITE_P(
2124 RTBuiltIn3StageI32NotInput,
2125 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2126 Combine(Values(SPV_ENV_VULKAN_1_2),
2127 Values("InstanceCustomIndexKHR", "RayGeometryIndexKHR",
2128 "InstanceId"),
2129 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
2130 Values("Output"), Values("%u32"),
2131 Values("OpCapability RayTracingKHR\n"),
2132 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2133 Values("VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04252 "
2134 "VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04346 "
2135 "VUID-InstanceId-InstanceId-04255 "),
2136 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
2137 "used for variables with Input storage class"))));
2138
2139 INSTANTIATE_TEST_SUITE_P(
2140 RTBuiltIn3StageI32NotIntScalar,
2141 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2142 Combine(Values(SPV_ENV_VULKAN_1_2),
2143 Values("InstanceCustomIndexKHR", "RayGeometryIndexKHR",
2144 "InstanceId"),
2145 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
2146 Values("Input"), Values("%f32", "%u32vec3"),
2147 Values("OpCapability RayTracingKHR\n"),
2148 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2149 Values("VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04253 "
2150 "VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04347 "
2151 "VUID-InstanceId-InstanceId-04256 "),
2152 Values(TestResult(SPV_ERROR_INVALID_DATA,
2153 "needs to be a 32-bit int scalar",
2154 "is not an int scalar"))));
2155
2156 // PrimitiveId needs special negative testing because it has non-RT uses
2157 INSTANTIATE_TEST_SUITE_P(
2158 PrimitiveIdRTNotExecutionMode,
2159 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2160 Combine(Values(SPV_ENV_VULKAN_1_2), Values("PrimitiveId"),
2161 Values("RayGenerationKHR", "MissKHR", "CallableKHR"),
2162 Values("Input"), Values("%u32"),
2163 Values("OpCapability RayTracingKHR\n"),
2164 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2165 Values("VUID-PrimitiveId-PrimitiveId-04330"),
2166 Values(TestResult(
2167 SPV_ERROR_INVALID_DATA,
2168 "to be used only with Fragment, TessellationControl, "
2169 "TessellationEvaluation, Geometry, MeshNV, IntersectionKHR, "
2170 "AnyHitKHR, and ClosestHitKHR execution models"))));
2171
2172 INSTANTIATE_TEST_SUITE_P(
2173 PrimitiveIdRTNotInput,
2174 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2175 Combine(Values(SPV_ENV_VULKAN_1_2), Values("PrimitiveId"),
2176 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
2177 Values("Output"), Values("%u32"),
2178 Values("OpCapability RayTracingKHR\n"),
2179 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2180 Values("VUID-PrimitiveId-PrimitiveId-04334"),
2181 Values(TestResult(SPV_ERROR_INVALID_DATA,
2182 "Output storage class if execution model is "))));
2183
2184 INSTANTIATE_TEST_SUITE_P(
2185 PrimitiveIdRTNotIntScalar,
2186 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2187 Combine(Values(SPV_ENV_VULKAN_1_2), Values("PrimitiveId"),
2188 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
2189 Values("Input"), Values("%f32", "%u32vec3"),
2190 Values("OpCapability RayTracingKHR\n"),
2191 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2192 Values("VUID-PrimitiveId-PrimitiveId-04337"),
2193 Values(TestResult(SPV_ERROR_INVALID_DATA,
2194 "needs to be a 32-bit int scalar",
2195 "is not an int scalar"))));
2196
2197 // ObjectRayDirectionKHR and ObjectRayOriginKHR valid
2198 // in IS, AH, CH shaders as input 32-bit float vec3
2199 INSTANTIATE_TEST_SUITE_P(
2200 ObjectRayDirectionAndOriginSuccess,
2201 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2202 Combine(Values(SPV_ENV_VULKAN_1_2),
2203 Values("ObjectRayDirectionKHR", "ObjectRayOriginKHR"),
2204 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
2205 Values("Input"), Values("%f32vec3"),
2206 Values("OpCapability RayTracingKHR\n"),
2207 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
2208 Values(TestResult())));
2209
2210 INSTANTIATE_TEST_SUITE_P(
2211 ObjectRayDirectionAndOriginNotExecutionMode,
2212 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2213 Combine(Values(SPV_ENV_VULKAN_1_2),
2214 Values("ObjectRayDirectionKHR", "ObjectRayOriginKHR"),
2215 Values("Vertex", "Fragment", "TessellationControl",
2216 "TessellationEvaluation", "Geometry", "Fragment",
2217 "GLCompute", "RayGenerationKHR", "MissKHR", "CallableKHR"),
2218 Values("Input"), Values("%f32vec3"),
2219 Values("OpCapability RayTracingKHR\n"),
2220 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2221 Values("VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04299 "
2222 "VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04302 "),
2223 Values(TestResult(SPV_ERROR_INVALID_DATA,
2224 "Vulkan spec does not allow BuiltIn",
2225 "to be used with the execution model"))));
2226
2227 INSTANTIATE_TEST_SUITE_P(
2228 ObjectRayDirectionAndOriginNotInput,
2229 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2230 Combine(Values(SPV_ENV_VULKAN_1_2),
2231 Values("ObjectRayDirectionKHR", "ObjectRayOriginKHR"),
2232 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
2233 Values("Output"), Values("%f32vec3"),
2234 Values("OpCapability RayTracingKHR\n"),
2235 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2236 Values("VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04300 "
2237 "VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04303 "),
2238 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
2239 "used for variables with Input storage class"))));
2240
2241 INSTANTIATE_TEST_SUITE_P(
2242 ObjectRayDirectionAndOriginNotFloatVec3,
2243 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2244 Combine(
2245 Values(SPV_ENV_VULKAN_1_2),
2246 Values("ObjectRayDirectionKHR", "ObjectRayOriginKHR"),
2247 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
2248 Values("Input"), Values("%u32vec3", "%f32", "%f32vec2", "%f32vec4"),
2249 Values("OpCapability RayTracingKHR\n"),
2250 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2251 Values("VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04301 "
2252 "VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04304 "),
2253 Values(TestResult(SPV_ERROR_INVALID_DATA,
2254 "needs to be a 3-component 32-bit float vector"))));
2255
2256 // ObjectToWorldKHR and WorldToObjectKHR valid
2257 // in IS, AH, CH shaders as input mat4x3
2258 INSTANTIATE_TEST_SUITE_P(
2259 RTObjectMatrixSuccess,
2260 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2261 Combine(Values(SPV_ENV_VULKAN_1_2),
2262 Values("ObjectToWorldKHR", "WorldToObjectKHR"),
2263 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
2264 Values("Input"), Values("%f32mat34"),
2265 Values("OpCapability RayTracingKHR\n"),
2266 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
2267 Values(TestResult())));
2268
2269 INSTANTIATE_TEST_SUITE_P(
2270 RTObjectMatrixNotExecutionMode,
2271 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2272 Combine(Values(SPV_ENV_VULKAN_1_2),
2273 Values("ObjectToWorldKHR", "WorldToObjectKHR"),
2274 Values("Vertex", "Fragment", "TessellationControl",
2275 "TessellationEvaluation", "Geometry", "Fragment",
2276 "GLCompute", "RayGenerationKHR", "MissKHR", "CallableKHR"),
2277 Values("Input"), Values("%f32mat34"),
2278 Values("OpCapability RayTracingKHR\n"),
2279 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2280 Values("VUID-ObjectToWorldKHR-ObjectToWorldKHR-04305 "
2281 "VUID-WorldToObjectKHR-WorldToObjectKHR-04434 "),
2282 Values(TestResult(SPV_ERROR_INVALID_DATA,
2283 "Vulkan spec does not allow BuiltIn",
2284 "to be used with the execution model"))));
2285
2286 INSTANTIATE_TEST_SUITE_P(
2287 RTObjectMatrixNotInput,
2288 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2289 Combine(Values(SPV_ENV_VULKAN_1_2),
2290 Values("ObjectToWorldKHR", "WorldToObjectKHR"),
2291 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
2292 Values("Output"), Values("%f32mat34"),
2293 Values("OpCapability RayTracingKHR\n"),
2294 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2295 Values("VUID-ObjectToWorldKHR-ObjectToWorldKHR-04306 "
2296 "VUID-WorldToObjectKHR-WorldToObjectKHR-04435 "),
2297 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
2298 "used for variables with Input storage class"))));
2299
2300 INSTANTIATE_TEST_SUITE_P(
2301 RTObjectMatrixNotMat4x3,
2302 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2303 Combine(Values(SPV_ENV_VULKAN_1_2),
2304 Values("ObjectToWorldKHR", "WorldToObjectKHR"),
2305 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR"),
2306 Values("Input"), Values("%f32mat43", "%f32mat44", "%f32vec4"),
2307 Values("OpCapability RayTracingKHR\n"),
2308 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2309 Values("VUID-ObjectToWorldKHR-ObjectToWorldKHR-04307 "
2310 "VUID-WorldToObjectKHR-WorldToObjectKHR-04436 "),
2311 Values(TestResult(
2312 SPV_ERROR_INVALID_DATA,
2313 "variable needs to be a matrix with "
2314 "4 columns of 3-component vectors of 32-bit floats"))));
2315
2316 // IncomingRayFlagsKHR is valid
2317 // in IS, AH, CH, MS shaders as an input i32 scalar
2318 INSTANTIATE_TEST_SUITE_P(
2319 IncomingRayFlagsSuccess,
2320 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2321 Combine(Values(SPV_ENV_VULKAN_1_2), Values("IncomingRayFlagsKHR"),
2322 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
2323 Values("Input"), Values("%u32"),
2324 Values("OpCapability RayTracingKHR\n"),
2325 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
2326 Values(TestResult())));
2327
2328 INSTANTIATE_TEST_SUITE_P(
2329 IncomingRayFlagsNotExecutionMode,
2330 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2331 Combine(Values(SPV_ENV_VULKAN_1_2), Values("IncomingRayFlagsKHR"),
2332 Values("Vertex", "Fragment", "TessellationControl",
2333 "TessellationEvaluation", "Geometry", "Fragment",
2334 "GLCompute", "RayGenerationKHR", "CallableKHR"),
2335 Values("Input"), Values("%u32"),
2336 Values("OpCapability RayTracingKHR\n"),
2337 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2338 Values("VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04248 "
2339 "VUID-RayTmaxKHR-RayTmaxKHR-04348 "
2340 "VUID-RayTminKHR-RayTminKHR-04351 "),
2341 Values(TestResult(SPV_ERROR_INVALID_DATA,
2342 "Vulkan spec does not allow BuiltIn",
2343 "to be used with the execution model"))));
2344
2345 INSTANTIATE_TEST_SUITE_P(
2346 IncomingRayFlagsNotInput,
2347 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2348 Combine(Values(SPV_ENV_VULKAN_1_2), Values("IncomingRayFlagsKHR"),
2349 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
2350 Values("Output"), Values("%u32"),
2351 Values("OpCapability RayTracingKHR\n"),
2352 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2353 Values("VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04249 "
2354 "VUID-RayTmaxKHR-RayTmaxKHR-04349 "
2355 "VUID-RayTminKHR-RayTminKHR-04352 "),
2356 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
2357 "used for variables with Input storage class"))));
2358 INSTANTIATE_TEST_SUITE_P(
2359 IncomingRayFlagsNotIntScalar,
2360 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2361 Combine(Values(SPV_ENV_VULKAN_1_2), Values("IncomingRayFlagsKHR"),
2362 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
2363 Values("Input"), Values("%f32", "%u32vec3"),
2364 Values("OpCapability RayTracingKHR\n"),
2365 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2366 Values("VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04250 "
2367 "VUID-RayTmaxKHR-RayTmaxKHR-04350 "
2368 "VUID-RayTminKHR-RayTminKHR-04353 "),
2369 Values(TestResult(SPV_ERROR_INVALID_DATA,
2370 "needs to be a 32-bit int scalar",
2371 "is not an int scalar"))));
2372
2373 // RayTmaxKHR, RayTminKHR are all valid
2374 // in IS, AH, CH, MS shaders as input f32 scalars
2375 INSTANTIATE_TEST_SUITE_P(
2376 RayTSuccess,
2377 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2378 Combine(Values(SPV_ENV_VULKAN_1_2), Values("RayTmaxKHR", "RayTminKHR"),
2379 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
2380 Values("Input"), Values("%f32"),
2381 Values("OpCapability RayTracingKHR\n"),
2382 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
2383 Values(TestResult())));
2384
2385 INSTANTIATE_TEST_SUITE_P(
2386 RayTNotExecutionMode,
2387 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2388 Combine(Values(SPV_ENV_VULKAN_1_2), Values("RayTmaxKHR", "RayTminKHR"),
2389 Values("Vertex", "Fragment", "TessellationControl",
2390 "TessellationEvaluation", "Geometry", "Fragment",
2391 "GLCompute", "RayGenerationKHR", "CallableKHR"),
2392 Values("Input"), Values("%f32"),
2393 Values("OpCapability RayTracingKHR\n"),
2394 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2395 Values("VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04248 "
2396 "VUID-RayTmaxKHR-RayTmaxKHR-04348 "
2397 "VUID-RayTminKHR-RayTminKHR-04351 "),
2398 Values(TestResult(SPV_ERROR_INVALID_DATA,
2399 "Vulkan spec does not allow BuiltIn",
2400 "to be used with the execution model"))));
2401
2402 INSTANTIATE_TEST_SUITE_P(
2403 RayTNotInput,
2404 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2405 Combine(Values(SPV_ENV_VULKAN_1_2), Values("RayTmaxKHR", "RayTminKHR"),
2406 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
2407 Values("Output"), Values("%f32"),
2408 Values("OpCapability RayTracingKHR\n"),
2409 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2410 Values("VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04249 "
2411 "VUID-RayTmaxKHR-RayTmaxKHR-04349 "
2412 "VUID-RayTminKHR-RayTminKHR-04352 "),
2413 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
2414 "used for variables with Input storage class"))));
2415 INSTANTIATE_TEST_SUITE_P(
2416 RayTNotFloatScalar,
2417 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2418 Combine(Values(SPV_ENV_VULKAN_1_2), Values("RayTmaxKHR", "RayTminKHR"),
2419 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
2420 Values("Input"), Values("%u32", "%f32vec3"),
2421 Values("OpCapability RayTracingKHR\n"),
2422 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2423 Values("VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04250 "
2424 "VUID-RayTmaxKHR-RayTmaxKHR-04350 "
2425 "VUID-RayTminKHR-RayTminKHR-04353 "),
2426 Values(TestResult(SPV_ERROR_INVALID_DATA,
2427 "needs to be a 32-bit float scalar",
2428 "is not a float scalar"))));
2429
2430 // WorldRayDirectionKHR and WorldRayOriginKHR are valid
2431 // in IS, AH, CH, MS shaders as input 32-bit float vec3
2432 INSTANTIATE_TEST_SUITE_P(
2433 WorldRayDirectionAndOriginSuccess,
2434 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2435 Combine(Values(SPV_ENV_VULKAN_1_2),
2436 Values("WorldRayDirectionKHR", "WorldRayOriginKHR"),
2437 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
2438 Values("Input"), Values("%f32vec3"),
2439 Values("OpCapability RayTracingKHR\n"),
2440 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
2441 Values(TestResult())));
2442
2443 INSTANTIATE_TEST_SUITE_P(
2444 WorldRayDirectionAndOriginNotExecutionMode,
2445 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2446 Combine(Values(SPV_ENV_VULKAN_1_2),
2447 Values("WorldRayDirectionKHR", "WorldRayOriginKHR"),
2448 Values("Vertex", "Fragment", "TessellationControl",
2449 "TessellationEvaluation", "Geometry", "Fragment",
2450 "GLCompute", "RayGenerationKHR", "CallableKHR"),
2451 Values("Input"), Values("%f32vec3"),
2452 Values("OpCapability RayTracingKHR\n"),
2453 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2454 Values("VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04428 "
2455 "VUID-WorldRayOriginKHR-WorldRayOriginKHR-04431 "),
2456 Values(TestResult(SPV_ERROR_INVALID_DATA,
2457 "Vulkan spec does not allow BuiltIn",
2458 "to be used with the execution model"))));
2459
2460 INSTANTIATE_TEST_SUITE_P(
2461 WorldRayDirectionAndOriginNotInput,
2462 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2463 Combine(Values(SPV_ENV_VULKAN_1_2),
2464 Values("WorldRayDirectionKHR", "WorldRayOriginKHR"),
2465 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
2466 Values("Output"), Values("%f32vec3"),
2467 Values("OpCapability RayTracingKHR\n"),
2468 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2469 Values("VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04429 "
2470 "VUID-WorldRayOriginKHR-WorldRayOriginKHR-04432 "),
2471 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
2472 "used for variables with Input storage class"))));
2473
2474 INSTANTIATE_TEST_SUITE_P(
2475 WorldRayDirectionAndOriginNotFloatVec3,
2476 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2477 Combine(
2478 Values(SPV_ENV_VULKAN_1_2),
2479 Values("WorldRayDirectionKHR", "WorldRayOriginKHR"),
2480 Values("AnyHitKHR", "ClosestHitKHR", "IntersectionKHR", "MissKHR"),
2481 Values("Input"), Values("%u32vec3", "%f32", "%f32vec2", "%f32vec4"),
2482 Values("OpCapability RayTracingKHR\n"),
2483 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2484 Values("VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04430 "
2485 "VUID-WorldRayOriginKHR-WorldRayOriginKHR-04433 "),
2486 Values(TestResult(SPV_ERROR_INVALID_DATA,
2487 "needs to be a 3-component 32-bit float vector"))));
2488
2489 // LaunchIdKHR and LaunchSizeKHR are valid
2490 // in RG, IS, AH, CH, MS shaders as input 32-bit ivec3
2491 INSTANTIATE_TEST_SUITE_P(
2492 LaunchRTSuccess,
2493 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2494 Combine(Values(SPV_ENV_VULKAN_1_2), Values("LaunchIdKHR", "LaunchSizeKHR"),
2495 Values("RayGenerationKHR", "AnyHitKHR", "ClosestHitKHR",
2496 "IntersectionKHR", "MissKHR", "CallableKHR"),
2497 Values("Input"), Values("%u32vec3"),
2498 Values("OpCapability RayTracingKHR\n"),
2499 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"), Values(nullptr),
2500 Values(TestResult())));
2501
2502 INSTANTIATE_TEST_SUITE_P(
2503 LaunchRTNotExecutionMode,
2504 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2505 Combine(Values(SPV_ENV_VULKAN_1_2), Values("LaunchIdKHR", "LaunchSizeKHR"),
2506 Values("Vertex", "Fragment", "TessellationControl",
2507 "TessellationEvaluation", "Geometry", "Fragment",
2508 "GLCompute"),
2509 Values("Input"), Values("%u32vec3"),
2510 Values("OpCapability RayTracingKHR\n"),
2511 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2512 Values("VUID-LaunchIdKHR-LaunchIdKHR-04266 "
2513 "VUID-LaunchSizeKHR-LaunchSizeKHR-04269 "),
2514 Values(TestResult(SPV_ERROR_INVALID_DATA,
2515 "Vulkan spec does not allow BuiltIn",
2516 "to be used with the execution model"))));
2517
2518 INSTANTIATE_TEST_SUITE_P(
2519 LaunchRTNotInput,
2520 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2521 Combine(Values(SPV_ENV_VULKAN_1_2), Values("LaunchIdKHR", "LaunchSizeKHR"),
2522 Values("RayGenerationKHR", "AnyHitKHR", "ClosestHitKHR",
2523 "IntersectionKHR", "MissKHR", "CallableKHR"),
2524 Values("Output"), Values("%u32vec3"),
2525 Values("OpCapability RayTracingKHR\n"),
2526 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2527 Values("VUID-LaunchIdKHR-LaunchIdKHR-04267 "
2528 "VUID-LaunchSizeKHR-LaunchSizeKHR-04270 "),
2529 Values(TestResult(SPV_ERROR_INVALID_DATA, "Vulkan spec allows",
2530 "used for variables with Input storage class"))));
2531
2532 INSTANTIATE_TEST_SUITE_P(
2533 LaunchRTNotIntVec3,
2534 ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2535 Combine(Values(SPV_ENV_VULKAN_1_2), Values("LaunchIdKHR", "LaunchSizeKHR"),
2536 Values("RayGenerationKHR", "AnyHitKHR", "ClosestHitKHR",
2537 "IntersectionKHR", "MissKHR", "CallableKHR"),
2538 Values("Input"), Values("%f32vec3", "%u32", "%u32vec2", "%u32vec4"),
2539 Values("OpCapability RayTracingKHR\n"),
2540 Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
2541 Values("VUID-LaunchIdKHR-LaunchIdKHR-04268 "
2542 "VUID-LaunchSizeKHR-LaunchSizeKHR-04271 "),
2543 Values(TestResult(SPV_ERROR_INVALID_DATA,
2544 "needs to be a 3-component 32-bit int vector"))));
2545
GetArrayedVariableCodeGenerator(const char * const built_in,const char * const execution_model,const char * const storage_class,const char * const data_type)2546 CodeGenerator GetArrayedVariableCodeGenerator(const char* const built_in,
2547 const char* const execution_model,
2548 const char* const storage_class,
2549 const char* const data_type) {
2550 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
2551
2552 generator.before_types_ = "OpDecorate %built_in_var BuiltIn ";
2553 generator.before_types_ += built_in;
2554 generator.before_types_ += "\n";
2555
2556 std::ostringstream after_types;
2557 after_types << "%built_in_array = OpTypeArray " << data_type << " %u32_3\n";
2558 if (InitializerRequired(storage_class)) {
2559 after_types << "%built_in_array_null = OpConstantNull %built_in_array\n";
2560 }
2561
2562 after_types << "%built_in_ptr = OpTypePointer " << storage_class
2563 << " %built_in_array\n";
2564 after_types << "%built_in_var = OpVariable %built_in_ptr " << storage_class;
2565 if (InitializerRequired(storage_class)) {
2566 after_types << " %built_in_array_null";
2567 }
2568 after_types << "\n";
2569 generator.after_types_ = after_types.str();
2570
2571 EntryPoint entry_point;
2572 entry_point.name = "main";
2573 entry_point.execution_model = execution_model;
2574 entry_point.interfaces = "%built_in_var";
2575 // Any kind of reference would do.
2576 entry_point.body = R"(
2577 %val = OpBitcast %u32 %built_in_var
2578 )";
2579
2580 std::ostringstream execution_modes;
2581 if (0 == std::strcmp(execution_model, "Fragment")) {
2582 execution_modes << "OpExecutionMode %" << entry_point.name
2583 << " OriginUpperLeft\n";
2584 if (0 == std::strcmp(built_in, "FragDepth")) {
2585 execution_modes << "OpExecutionMode %" << entry_point.name
2586 << " DepthReplacing\n";
2587 }
2588 }
2589 if (0 == std::strcmp(execution_model, "Geometry")) {
2590 execution_modes << "OpExecutionMode %" << entry_point.name
2591 << " InputPoints\n";
2592 execution_modes << "OpExecutionMode %" << entry_point.name
2593 << " OutputPoints\n";
2594 }
2595 if (0 == std::strcmp(execution_model, "GLCompute")) {
2596 execution_modes << "OpExecutionMode %" << entry_point.name
2597 << " LocalSize 1 1 1\n";
2598 }
2599 entry_point.execution_modes = execution_modes.str();
2600
2601 generator.entry_points_.push_back(std::move(entry_point));
2602
2603 return generator;
2604 }
2605
TEST_P(ValidateVulkanCombineBuiltInArrayedVariable,Variable)2606 TEST_P(ValidateVulkanCombineBuiltInArrayedVariable, Variable) {
2607 const char* const built_in = std::get<0>(GetParam());
2608 const char* const execution_model = std::get<1>(GetParam());
2609 const char* const storage_class = std::get<2>(GetParam());
2610 const char* const data_type = std::get<3>(GetParam());
2611 const TestResult& test_result = std::get<4>(GetParam());
2612
2613 CodeGenerator generator = GetArrayedVariableCodeGenerator(
2614 built_in, execution_model, storage_class, data_type);
2615
2616 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
2617 ASSERT_EQ(test_result.validation_result,
2618 ValidateInstructions(SPV_ENV_VULKAN_1_0));
2619 if (test_result.error_str) {
2620 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str));
2621 }
2622 if (test_result.error_str2) {
2623 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2));
2624 }
2625 }
2626
2627 INSTANTIATE_TEST_SUITE_P(PointSizeArrayedF32TessControl,
2628 ValidateVulkanCombineBuiltInArrayedVariable,
2629 Combine(Values("PointSize"),
2630 Values("TessellationControl"), Values("Input"),
2631 Values("%f32"), Values(TestResult())));
2632
2633 INSTANTIATE_TEST_SUITE_P(
2634 PointSizeArrayedF64TessControl, ValidateVulkanCombineBuiltInArrayedVariable,
2635 Combine(Values("PointSize"), Values("TessellationControl"), Values("Input"),
2636 Values("%f64"),
2637 Values(TestResult(SPV_ERROR_INVALID_DATA,
2638 "needs to be a 32-bit float scalar",
2639 "has bit width 64"))));
2640
2641 INSTANTIATE_TEST_SUITE_P(
2642 PointSizeArrayedF32Vertex, ValidateVulkanCombineBuiltInArrayedVariable,
2643 Combine(Values("PointSize"), Values("Vertex"), Values("Output"),
2644 Values("%f32"),
2645 Values(TestResult(SPV_ERROR_INVALID_DATA,
2646 "needs to be a 32-bit float scalar",
2647 "is not a float scalar"))));
2648
2649 INSTANTIATE_TEST_SUITE_P(PositionArrayedF32Vec4TessControl,
2650 ValidateVulkanCombineBuiltInArrayedVariable,
2651 Combine(Values("Position"),
2652 Values("TessellationControl"), Values("Input"),
2653 Values("%f32vec4"), Values(TestResult())));
2654
2655 INSTANTIATE_TEST_SUITE_P(
2656 PositionArrayedF32Vec3TessControl,
2657 ValidateVulkanCombineBuiltInArrayedVariable,
2658 Combine(Values("Position"), Values("TessellationControl"), Values("Input"),
2659 Values("%f32vec3"),
2660 Values(TestResult(SPV_ERROR_INVALID_DATA,
2661 "needs to be a 4-component 32-bit float vector",
2662 "has 3 components"))));
2663
2664 INSTANTIATE_TEST_SUITE_P(
2665 PositionArrayedF32Vec4Vertex, ValidateVulkanCombineBuiltInArrayedVariable,
2666 Combine(Values("Position"), Values("Vertex"), Values("Output"),
2667 Values("%f32vec4"),
2668 Values(TestResult(SPV_ERROR_INVALID_DATA,
2669 "needs to be a 4-component 32-bit float vector",
2670 "is not a float vector"))));
2671
2672 INSTANTIATE_TEST_SUITE_P(
2673 ClipAndCullDistanceOutputSuccess,
2674 ValidateVulkanCombineBuiltInArrayedVariable,
2675 Combine(Values("ClipDistance", "CullDistance"),
2676 Values("Geometry", "TessellationControl", "TessellationEvaluation"),
2677 Values("Output"), Values("%f32arr2", "%f32arr4"),
2678 Values(TestResult())));
2679
2680 INSTANTIATE_TEST_SUITE_P(
2681 ClipAndCullDistanceVertexInput, ValidateVulkanCombineBuiltInArrayedVariable,
2682 Combine(Values("ClipDistance", "CullDistance"), Values("Fragment"),
2683 Values("Input"), Values("%f32arr4"),
2684 Values(TestResult(SPV_ERROR_INVALID_DATA,
2685 "needs to be a 32-bit float array",
2686 "components are not float scalar"))));
2687
2688 INSTANTIATE_TEST_SUITE_P(
2689 ClipAndCullDistanceNotArray, ValidateVulkanCombineBuiltInArrayedVariable,
2690 Combine(Values("ClipDistance", "CullDistance"),
2691 Values("Geometry", "TessellationControl", "TessellationEvaluation"),
2692 Values("Input"), Values("%f32vec2", "%f32vec4"),
2693 Values(TestResult(SPV_ERROR_INVALID_DATA,
2694 "needs to be a 32-bit float array",
2695 "components are not float scalar"))));
2696
2697 INSTANTIATE_TEST_SUITE_P(
2698 SMBuiltinsInputSuccess,
2699 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2700 Combine(Values("SMCountNV", "SMIDNV", "WarpsPerSMNV", "WarpIDNV"),
2701 Values("Vertex", "Fragment", "TessellationControl",
2702 "TessellationEvaluation", "Geometry", "GLCompute"),
2703 Values("Input"), Values("%u32"),
2704 Values("OpCapability ShaderSMBuiltinsNV\n"),
2705 Values("OpExtension \"SPV_NV_shader_sm_builtins\"\n"),
2706 Values(nullptr), Values(TestResult())));
2707
2708 INSTANTIATE_TEST_SUITE_P(
2709 SMBuiltinsInputMeshSuccess,
2710 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2711 Combine(
2712 Values("SMCountNV", "SMIDNV", "WarpsPerSMNV", "WarpIDNV"),
2713 Values("MeshNV", "TaskNV"), Values("Input"), Values("%u32"),
2714 Values("OpCapability ShaderSMBuiltinsNV\nOpCapability MeshShadingNV\n"),
2715 Values("OpExtension \"SPV_NV_shader_sm_builtins\"\nOpExtension "
2716 "\"SPV_NV_mesh_shader\"\n"),
2717 Values(nullptr), Values(TestResult())));
2718
2719 INSTANTIATE_TEST_SUITE_P(
2720 SMBuiltinsInputRaySuccess,
2721 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2722 Combine(
2723 Values("SMCountNV", "SMIDNV", "WarpsPerSMNV", "WarpIDNV"),
2724 Values("RayGenerationNV", "IntersectionNV", "AnyHitNV", "ClosestHitNV",
2725 "MissNV", "CallableNV"),
2726 Values("Input"), Values("%u32"),
2727 Values("OpCapability ShaderSMBuiltinsNV\nOpCapability RayTracingNV\n"),
2728 Values("OpExtension \"SPV_NV_shader_sm_builtins\"\nOpExtension "
2729 "\"SPV_NV_ray_tracing\"\n"),
2730 Values(nullptr), Values(TestResult())));
2731
2732 INSTANTIATE_TEST_SUITE_P(
2733 SMBuiltinsNotInput,
2734 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2735 Combine(Values("SMCountNV", "SMIDNV", "WarpsPerSMNV", "WarpIDNV"),
2736 Values("Vertex", "Fragment", "TessellationControl",
2737 "TessellationEvaluation", "Geometry", "GLCompute"),
2738 Values("Output"), Values("%u32"),
2739 Values("OpCapability ShaderSMBuiltinsNV\n"),
2740 Values("OpExtension \"SPV_NV_shader_sm_builtins\"\n"),
2741 Values(nullptr),
2742 Values(TestResult(
2743 SPV_ERROR_INVALID_DATA,
2744 "to be only used for variables with Input storage class",
2745 "uses storage class Output"))));
2746
2747 INSTANTIATE_TEST_SUITE_P(
2748 SMBuiltinsNotIntScalar,
2749 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2750 Combine(Values("SMCountNV", "SMIDNV", "WarpsPerSMNV", "WarpIDNV"),
2751 Values("Vertex", "Fragment", "TessellationControl",
2752 "TessellationEvaluation", "Geometry", "GLCompute"),
2753 Values("Input"), Values("%f32", "%u32vec3"),
2754 Values("OpCapability ShaderSMBuiltinsNV\n"),
2755 Values("OpExtension \"SPV_NV_shader_sm_builtins\"\n"),
2756 Values(nullptr),
2757 Values(TestResult(SPV_ERROR_INVALID_DATA,
2758 "needs to be a 32-bit int scalar",
2759 "is not an int scalar"))));
2760
2761 INSTANTIATE_TEST_SUITE_P(
2762 SMBuiltinsNotInt32,
2763 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
2764 Combine(Values("SMCountNV", "SMIDNV", "WarpsPerSMNV", "WarpIDNV"),
2765 Values("Vertex", "Fragment", "TessellationControl",
2766 "TessellationEvaluation", "Geometry", "GLCompute"),
2767 Values("Input"), Values("%u64"),
2768 Values("OpCapability ShaderSMBuiltinsNV\n"),
2769 Values("OpExtension \"SPV_NV_shader_sm_builtins\"\n"),
2770 Values(nullptr),
2771 Values(TestResult(SPV_ERROR_INVALID_DATA,
2772 "needs to be a 32-bit int scalar",
2773 "has bit width 64"))));
2774
GetWorkgroupSizeSuccessGenerator()2775 CodeGenerator GetWorkgroupSizeSuccessGenerator() {
2776 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
2777
2778 generator.before_types_ = R"(
2779 OpDecorate %workgroup_size BuiltIn WorkgroupSize
2780 )";
2781
2782 generator.after_types_ = R"(
2783 %workgroup_size = OpConstantComposite %u32vec3 %u32_1 %u32_1 %u32_1
2784 )";
2785
2786 EntryPoint entry_point;
2787 entry_point.name = "main";
2788 entry_point.execution_model = "GLCompute";
2789 entry_point.body = R"(
2790 %copy = OpCopyObject %u32vec3 %workgroup_size
2791 )";
2792 generator.entry_points_.push_back(std::move(entry_point));
2793
2794 return generator;
2795 }
2796
TEST_F(ValidateBuiltIns,VulkanWorkgroupSizeSuccess)2797 TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeSuccess) {
2798 CodeGenerator generator = GetWorkgroupSizeSuccessGenerator();
2799 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
2800 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2801 }
2802
GetWorkgroupSizeFragmentGenerator()2803 CodeGenerator GetWorkgroupSizeFragmentGenerator() {
2804 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
2805
2806 generator.before_types_ = R"(
2807 OpDecorate %workgroup_size BuiltIn WorkgroupSize
2808 )";
2809
2810 generator.after_types_ = R"(
2811 %workgroup_size = OpConstantComposite %u32vec3 %u32_1 %u32_1 %u32_1
2812 )";
2813
2814 EntryPoint entry_point;
2815 entry_point.name = "main";
2816 entry_point.execution_model = "Fragment";
2817 entry_point.execution_modes = "OpExecutionMode %main OriginUpperLeft";
2818 entry_point.body = R"(
2819 %copy = OpCopyObject %u32vec3 %workgroup_size
2820 )";
2821 generator.entry_points_.push_back(std::move(entry_point));
2822
2823 return generator;
2824 }
2825
TEST_F(ValidateBuiltIns,VulkanWorkgroupSizeFragment)2826 TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeFragment) {
2827 CodeGenerator generator = GetWorkgroupSizeFragmentGenerator();
2828
2829 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
2830 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2831 EXPECT_THAT(
2832 getDiagnosticString(),
2833 HasSubstr("Vulkan spec allows BuiltIn WorkgroupSize to be used "
2834 "only with GLCompute, MeshNV, or TaskNV execution model"));
2835 EXPECT_THAT(getDiagnosticString(),
2836 HasSubstr("is referencing ID <2> (OpConstantComposite) which is "
2837 "decorated with BuiltIn WorkgroupSize in function <1> "
2838 "called with execution model Fragment"));
2839 EXPECT_THAT(getDiagnosticString(),
2840 AnyVUID("VUID-WorkgroupSize-WorkgroupSize-04425 "
2841 "VUID-WorkgroupSize-WorkgroupSize-04427"));
2842 }
2843
TEST_F(ValidateBuiltIns,WorkgroupSizeNotConstant)2844 TEST_F(ValidateBuiltIns, WorkgroupSizeNotConstant) {
2845 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
2846 generator.before_types_ = R"(
2847 OpDecorate %copy BuiltIn WorkgroupSize
2848 )";
2849
2850 generator.after_types_ = R"(
2851 %workgroup_size = OpConstantComposite %u32vec3 %u32_1 %u32_1 %u32_1
2852 )";
2853
2854 EntryPoint entry_point;
2855 entry_point.name = "main";
2856 entry_point.execution_model = "GLCompute";
2857 entry_point.body = R"(
2858 %copy = OpCopyObject %u32vec3 %workgroup_size
2859 )";
2860 generator.entry_points_.push_back(std::move(entry_point));
2861
2862 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
2863 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2864 EXPECT_THAT(getDiagnosticString(),
2865 HasSubstr("BuiltIns can only target variables, structure "
2866 "members or constants"));
2867 }
2868
GetWorkgroupSizeNotVectorGenerator()2869 CodeGenerator GetWorkgroupSizeNotVectorGenerator() {
2870 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
2871
2872 generator.before_types_ = R"(
2873 OpDecorate %workgroup_size BuiltIn WorkgroupSize
2874 )";
2875
2876 generator.after_types_ = R"(
2877 %workgroup_size = OpConstant %u32 16
2878 )";
2879
2880 EntryPoint entry_point;
2881 entry_point.name = "main";
2882 entry_point.execution_model = "GLCompute";
2883 entry_point.body = R"(
2884 %copy = OpCopyObject %u32 %workgroup_size
2885 )";
2886 generator.entry_points_.push_back(std::move(entry_point));
2887
2888 return generator;
2889 }
2890
TEST_F(ValidateBuiltIns,VulkanWorkgroupSizeNotVector)2891 TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeNotVector) {
2892 CodeGenerator generator = GetWorkgroupSizeNotVectorGenerator();
2893
2894 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
2895 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2896 EXPECT_THAT(getDiagnosticString(),
2897 HasSubstr("According to the Vulkan spec BuiltIn WorkgroupSize "
2898 "variable needs to be a 3-component 32-bit int vector. "
2899 "ID <2> (OpConstant) is not an int vector."));
2900 EXPECT_THAT(getDiagnosticString(),
2901 AnyVUID("VUID-WorkgroupSize-WorkgroupSize-04427"));
2902 }
2903
GetWorkgroupSizeNotIntVectorGenerator()2904 CodeGenerator GetWorkgroupSizeNotIntVectorGenerator() {
2905 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
2906
2907 generator.before_types_ = R"(
2908 OpDecorate %workgroup_size BuiltIn WorkgroupSize
2909 )";
2910
2911 generator.after_types_ = R"(
2912 %workgroup_size = OpConstantComposite %f32vec3 %f32_1 %f32_1 %f32_1
2913 )";
2914
2915 EntryPoint entry_point;
2916 entry_point.name = "main";
2917 entry_point.execution_model = "GLCompute";
2918 entry_point.body = R"(
2919 %copy = OpCopyObject %f32vec3 %workgroup_size
2920 )";
2921 generator.entry_points_.push_back(std::move(entry_point));
2922
2923 return generator;
2924 }
2925
TEST_F(ValidateBuiltIns,VulkanWorkgroupSizeNotIntVector)2926 TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeNotIntVector) {
2927 CodeGenerator generator = GetWorkgroupSizeNotIntVectorGenerator();
2928
2929 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
2930 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2931 EXPECT_THAT(getDiagnosticString(),
2932 HasSubstr("According to the Vulkan spec BuiltIn WorkgroupSize "
2933 "variable needs to be a 3-component 32-bit int vector. "
2934 "ID <2> (OpConstantComposite) is not an int vector."));
2935 EXPECT_THAT(getDiagnosticString(),
2936 AnyVUID("VUID-WorkgroupSize-WorkgroupSize-04427"));
2937 }
2938
GetWorkgroupSizeNotVec3Generator()2939 CodeGenerator GetWorkgroupSizeNotVec3Generator() {
2940 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
2941
2942 generator.before_types_ = R"(
2943 OpDecorate %workgroup_size BuiltIn WorkgroupSize
2944 )";
2945
2946 generator.after_types_ = R"(
2947 %workgroup_size = OpConstantComposite %u32vec2 %u32_1 %u32_1
2948 )";
2949
2950 EntryPoint entry_point;
2951 entry_point.name = "main";
2952 entry_point.execution_model = "GLCompute";
2953 entry_point.body = R"(
2954 %copy = OpCopyObject %u32vec2 %workgroup_size
2955 )";
2956 generator.entry_points_.push_back(std::move(entry_point));
2957
2958 return generator;
2959 }
2960
TEST_F(ValidateBuiltIns,VulkanWorkgroupSizeNotVec3)2961 TEST_F(ValidateBuiltIns, VulkanWorkgroupSizeNotVec3) {
2962 CodeGenerator generator = GetWorkgroupSizeNotVec3Generator();
2963
2964 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
2965 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2966 EXPECT_THAT(getDiagnosticString(),
2967 HasSubstr("According to the Vulkan spec BuiltIn WorkgroupSize "
2968 "variable needs to be a 3-component 32-bit int vector. "
2969 "ID <2> (OpConstantComposite) has 2 components."));
2970 EXPECT_THAT(getDiagnosticString(),
2971 AnyVUID("VUID-WorkgroupSize-WorkgroupSize-04427"));
2972 }
2973
TEST_F(ValidateBuiltIns,WorkgroupSizeNotInt32Vec)2974 TEST_F(ValidateBuiltIns, WorkgroupSizeNotInt32Vec) {
2975 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
2976 generator.before_types_ = R"(
2977 OpDecorate %workgroup_size BuiltIn WorkgroupSize
2978 )";
2979
2980 generator.after_types_ = R"(
2981 %workgroup_size = OpConstantComposite %u64vec3 %u64_1 %u64_1 %u64_1
2982 )";
2983
2984 EntryPoint entry_point;
2985 entry_point.name = "main";
2986 entry_point.execution_model = "GLCompute";
2987 entry_point.body = R"(
2988 %copy = OpCopyObject %u64vec3 %workgroup_size
2989 )";
2990 generator.entry_points_.push_back(std::move(entry_point));
2991
2992 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
2993 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
2994 EXPECT_THAT(
2995 getDiagnosticString(),
2996 HasSubstr("According to the Vulkan spec BuiltIn WorkgroupSize variable "
2997 "needs to be a 3-component 32-bit int vector. ID <2> "
2998 "(OpConstantComposite) has components with bit width 64."));
2999 EXPECT_THAT(getDiagnosticString(),
3000 AnyVUID("VUID-WorkgroupSize-WorkgroupSize-04427"));
3001 }
3002
TEST_F(ValidateBuiltIns,WorkgroupSizePrivateVar)3003 TEST_F(ValidateBuiltIns, WorkgroupSizePrivateVar) {
3004 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3005 generator.before_types_ = R"(
3006 OpDecorate %workgroup_size BuiltIn WorkgroupSize
3007 )";
3008
3009 generator.after_types_ = R"(
3010 %workgroup_size = OpConstantComposite %u32vec3 %u32_1 %u32_1 %u32_1
3011 %private_ptr_u32vec3 = OpTypePointer Private %u32vec3
3012 %var = OpVariable %private_ptr_u32vec3 Private %workgroup_size
3013 )";
3014
3015 EntryPoint entry_point;
3016 entry_point.name = "main";
3017 entry_point.execution_model = "GLCompute";
3018 entry_point.body = R"(
3019 )";
3020 generator.entry_points_.push_back(std::move(entry_point));
3021
3022 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
3023 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3024 }
3025
TEST_F(ValidateBuiltIns,GeometryPositionInOutSuccess)3026 TEST_F(ValidateBuiltIns, GeometryPositionInOutSuccess) {
3027 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3028
3029 generator.before_types_ = R"(
3030 OpDecorate %input_type Block
3031 OpMemberDecorate %input_type 0 BuiltIn Position
3032 OpDecorate %output_type Block
3033 OpMemberDecorate %output_type 0 BuiltIn Position
3034 )";
3035
3036 generator.after_types_ = R"(
3037 %input_type = OpTypeStruct %f32vec4
3038 %arrayed_input_type = OpTypeArray %input_type %u32_3
3039 %input_ptr = OpTypePointer Input %arrayed_input_type
3040 %input = OpVariable %input_ptr Input
3041 %input_f32vec4_ptr = OpTypePointer Input %f32vec4
3042 %output_type = OpTypeStruct %f32vec4
3043 %output_ptr = OpTypePointer Output %output_type
3044 %output = OpVariable %output_ptr Output
3045 %output_f32vec4_ptr = OpTypePointer Output %f32vec4
3046 )";
3047
3048 EntryPoint entry_point;
3049 entry_point.name = "main";
3050 entry_point.execution_model = "Geometry";
3051 entry_point.interfaces = "%input %output";
3052 entry_point.body = R"(
3053 %input_pos = OpAccessChain %input_f32vec4_ptr %input %u32_0 %u32_0
3054 %output_pos = OpAccessChain %output_f32vec4_ptr %output %u32_0
3055 %pos = OpLoad %f32vec4 %input_pos
3056 OpStore %output_pos %pos
3057 )";
3058 generator.entry_points_.push_back(std::move(entry_point));
3059 generator.entry_points_[0].execution_modes =
3060 "OpExecutionMode %main InputPoints\nOpExecutionMode %main OutputPoints\n";
3061
3062 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
3063 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3064 }
3065
TEST_F(ValidateBuiltIns,WorkgroupIdNotVec3)3066 TEST_F(ValidateBuiltIns, WorkgroupIdNotVec3) {
3067 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3068 generator.before_types_ = R"(
3069 OpDecorate %workgroup_size BuiltIn WorkgroupSize
3070 OpDecorate %workgroup_id BuiltIn WorkgroupId
3071 )";
3072
3073 generator.after_types_ = R"(
3074 %workgroup_size = OpConstantComposite %u32vec3 %u32_1 %u32_1 %u32_1
3075 %input_ptr = OpTypePointer Input %u32vec2
3076 %workgroup_id = OpVariable %input_ptr Input
3077 )";
3078
3079 EntryPoint entry_point;
3080 entry_point.name = "main";
3081 entry_point.execution_model = "GLCompute";
3082 entry_point.interfaces = "%workgroup_id";
3083 entry_point.body = R"(
3084 %copy_size = OpCopyObject %u32vec3 %workgroup_size
3085 %load_id = OpLoad %u32vec2 %workgroup_id
3086 )";
3087 generator.entry_points_.push_back(std::move(entry_point));
3088
3089 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
3090 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3091 EXPECT_THAT(getDiagnosticString(),
3092 HasSubstr("According to the Vulkan spec BuiltIn WorkgroupId "
3093 "variable needs to be a 3-component 32-bit int vector. "
3094 "ID <2> (OpVariable) has 2 components."));
3095 }
3096
TEST_F(ValidateBuiltIns,TwoBuiltInsFirstFails)3097 TEST_F(ValidateBuiltIns, TwoBuiltInsFirstFails) {
3098 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3099
3100 generator.before_types_ = R"(
3101 OpMemberDecorate %input_type 0 BuiltIn FragCoord
3102 OpMemberDecorate %output_type 0 BuiltIn Position
3103 )";
3104
3105 generator.after_types_ = R"(
3106 %input_type = OpTypeStruct %f32vec4
3107 %input_ptr = OpTypePointer Input %input_type
3108 %input = OpVariable %input_ptr Input
3109 %input_f32vec4_ptr = OpTypePointer Input %f32vec4
3110 %output_type = OpTypeStruct %f32vec4
3111 %output_ptr = OpTypePointer Output %output_type
3112 %output = OpVariable %output_ptr Output
3113 %output_f32vec4_ptr = OpTypePointer Output %f32vec4
3114 )";
3115
3116 EntryPoint entry_point;
3117 entry_point.name = "main";
3118 entry_point.execution_model = "Geometry";
3119 entry_point.interfaces = "%input %output";
3120 entry_point.body = R"(
3121 %input_pos = OpAccessChain %input_f32vec4_ptr %input %u32_0
3122 %output_pos = OpAccessChain %output_f32vec4_ptr %output %u32_0
3123 %pos = OpLoad %f32vec4 %input_pos
3124 OpStore %output_pos %pos
3125 )";
3126 generator.entry_points_.push_back(std::move(entry_point));
3127 generator.entry_points_[0].execution_modes =
3128 "OpExecutionMode %main InputPoints\nOpExecutionMode %main OutputPoints\n";
3129
3130 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
3131 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3132 EXPECT_THAT(getDiagnosticString(),
3133 HasSubstr("Vulkan spec allows BuiltIn FragCoord to be used only "
3134 "with Fragment execution model"));
3135 }
3136
TEST_F(ValidateBuiltIns,TwoBuiltInsSecondFails)3137 TEST_F(ValidateBuiltIns, TwoBuiltInsSecondFails) {
3138 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3139
3140 generator.before_types_ = R"(
3141 OpMemberDecorate %input_type 0 BuiltIn Position
3142 OpMemberDecorate %output_type 0 BuiltIn FragCoord
3143 )";
3144
3145 generator.after_types_ = R"(
3146 %input_type = OpTypeStruct %f32vec4
3147 %input_ptr = OpTypePointer Input %input_type
3148 %input = OpVariable %input_ptr Input
3149 %input_f32vec4_ptr = OpTypePointer Input %f32vec4
3150 %output_type = OpTypeStruct %f32vec4
3151 %output_ptr = OpTypePointer Output %output_type
3152 %output = OpVariable %output_ptr Output
3153 %output_f32vec4_ptr = OpTypePointer Output %f32vec4
3154 )";
3155
3156 EntryPoint entry_point;
3157 entry_point.name = "main";
3158 entry_point.execution_model = "Geometry";
3159 entry_point.interfaces = "%input %output";
3160 entry_point.body = R"(
3161 %input_pos = OpAccessChain %input_f32vec4_ptr %input %u32_0
3162 %output_pos = OpAccessChain %output_f32vec4_ptr %output %u32_0
3163 %pos = OpLoad %f32vec4 %input_pos
3164 OpStore %output_pos %pos
3165 )";
3166 generator.entry_points_.push_back(std::move(entry_point));
3167 generator.entry_points_[0].execution_modes =
3168 "OpExecutionMode %main InputPoints\nOpExecutionMode %main OutputPoints\n";
3169
3170 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
3171 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3172 EXPECT_THAT(getDiagnosticString(),
3173 HasSubstr("Vulkan spec allows BuiltIn FragCoord to be only used "
3174 "for variables with Input storage class"));
3175 }
3176
TEST_F(ValidateBuiltIns,VertexPositionVariableSuccess)3177 TEST_F(ValidateBuiltIns, VertexPositionVariableSuccess) {
3178 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3179 generator.before_types_ = R"(
3180 OpDecorate %position BuiltIn Position
3181 )";
3182
3183 generator.after_types_ = R"(
3184 %f32vec4_ptr_output = OpTypePointer Output %f32vec4
3185 %position = OpVariable %f32vec4_ptr_output Output
3186 )";
3187
3188 EntryPoint entry_point;
3189 entry_point.name = "main";
3190 entry_point.execution_model = "Vertex";
3191 entry_point.interfaces = "%position";
3192 entry_point.body = R"(
3193 OpStore %position %f32vec4_0123
3194 )";
3195 generator.entry_points_.push_back(std::move(entry_point));
3196
3197 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
3198 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3199 }
3200
TEST_F(ValidateBuiltIns,FragmentPositionTwoEntryPoints)3201 TEST_F(ValidateBuiltIns, FragmentPositionTwoEntryPoints) {
3202 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3203 generator.before_types_ = R"(
3204 OpMemberDecorate %output_type 0 BuiltIn Position
3205 )";
3206
3207 generator.after_types_ = R"(
3208 %output_type = OpTypeStruct %f32vec4
3209 %output_ptr = OpTypePointer Output %output_type
3210 %output = OpVariable %output_ptr Output
3211 %output_f32vec4_ptr = OpTypePointer Output %f32vec4
3212 )";
3213
3214 EntryPoint entry_point;
3215 entry_point.name = "vmain";
3216 entry_point.execution_model = "Vertex";
3217 entry_point.interfaces = "%output";
3218 entry_point.body = R"(
3219 %val1 = OpFunctionCall %void %foo
3220 )";
3221 generator.entry_points_.push_back(std::move(entry_point));
3222
3223 entry_point.name = "fmain";
3224 entry_point.execution_model = "Fragment";
3225 entry_point.interfaces = "%output";
3226 entry_point.execution_modes = "OpExecutionMode %fmain OriginUpperLeft";
3227 entry_point.body = R"(
3228 %val2 = OpFunctionCall %void %foo
3229 )";
3230 generator.entry_points_.push_back(std::move(entry_point));
3231
3232 generator.add_at_the_end_ = R"(
3233 %foo = OpFunction %void None %func
3234 %foo_entry = OpLabel
3235 %position = OpAccessChain %output_f32vec4_ptr %output %u32_0
3236 OpStore %position %f32vec4_0123
3237 OpReturn
3238 OpFunctionEnd
3239 )";
3240
3241 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
3242 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3243 EXPECT_THAT(getDiagnosticString(),
3244 HasSubstr("Vulkan spec allows BuiltIn Position to be used only "
3245 "with Vertex, TessellationControl, "
3246 "TessellationEvaluation or Geometry execution models"));
3247 EXPECT_THAT(getDiagnosticString(),
3248 HasSubstr("called with execution model Fragment"));
3249 }
3250
GetNoDepthReplacingGenerator()3251 CodeGenerator GetNoDepthReplacingGenerator() {
3252 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3253
3254 generator.before_types_ = R"(
3255 OpMemberDecorate %output_type 0 BuiltIn FragDepth
3256 )";
3257
3258 generator.after_types_ = R"(
3259 %output_type = OpTypeStruct %f32
3260 %output_null = OpConstantNull %output_type
3261 %output_ptr = OpTypePointer Output %output_type
3262 %output = OpVariable %output_ptr Output %output_null
3263 %output_f32_ptr = OpTypePointer Output %f32
3264 )";
3265
3266 EntryPoint entry_point;
3267 entry_point.name = "main";
3268 entry_point.execution_model = "Fragment";
3269 entry_point.interfaces = "%output";
3270 entry_point.execution_modes = "OpExecutionMode %main OriginUpperLeft";
3271 entry_point.body = R"(
3272 %val2 = OpFunctionCall %void %foo
3273 )";
3274 generator.entry_points_.push_back(std::move(entry_point));
3275
3276 const std::string function_body = R"(
3277 %foo = OpFunction %void None %func
3278 %foo_entry = OpLabel
3279 %frag_depth = OpAccessChain %output_f32_ptr %output %u32_0
3280 OpStore %frag_depth %f32_1
3281 OpReturn
3282 OpFunctionEnd
3283 )";
3284
3285 generator.add_at_the_end_ = function_body;
3286
3287 return generator;
3288 }
3289
TEST_F(ValidateBuiltIns,VulkanFragmentFragDepthNoDepthReplacing)3290 TEST_F(ValidateBuiltIns, VulkanFragmentFragDepthNoDepthReplacing) {
3291 CodeGenerator generator = GetNoDepthReplacingGenerator();
3292
3293 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
3294 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3295 EXPECT_THAT(getDiagnosticString(),
3296 HasSubstr("Vulkan spec requires DepthReplacing execution mode to "
3297 "be declared when using BuiltIn FragDepth"));
3298 EXPECT_THAT(getDiagnosticString(),
3299 HasSubstr("VUID-FragDepth-FragDepth-04216"));
3300 }
3301
GetOneMainHasDepthReplacingOtherHasntGenerator()3302 CodeGenerator GetOneMainHasDepthReplacingOtherHasntGenerator() {
3303 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3304
3305 generator.before_types_ = R"(
3306 OpMemberDecorate %output_type 0 BuiltIn FragDepth
3307 )";
3308
3309 generator.after_types_ = R"(
3310 %output_type = OpTypeStruct %f32
3311 %output_null = OpConstantNull %output_type
3312 %output_ptr = OpTypePointer Output %output_type
3313 %output = OpVariable %output_ptr Output %output_null
3314 %output_f32_ptr = OpTypePointer Output %f32
3315 )";
3316
3317 EntryPoint entry_point;
3318 entry_point.name = "main_d_r";
3319 entry_point.execution_model = "Fragment";
3320 entry_point.interfaces = "%output";
3321 entry_point.execution_modes =
3322 "OpExecutionMode %main_d_r OriginUpperLeft\n"
3323 "OpExecutionMode %main_d_r DepthReplacing";
3324 entry_point.body = R"(
3325 %val2 = OpFunctionCall %void %foo
3326 )";
3327 generator.entry_points_.push_back(std::move(entry_point));
3328
3329 entry_point.name = "main_no_d_r";
3330 entry_point.execution_model = "Fragment";
3331 entry_point.interfaces = "%output";
3332 entry_point.execution_modes = "OpExecutionMode %main_no_d_r OriginUpperLeft";
3333 entry_point.body = R"(
3334 %val3 = OpFunctionCall %void %foo
3335 )";
3336 generator.entry_points_.push_back(std::move(entry_point));
3337
3338 const std::string function_body = R"(
3339 %foo = OpFunction %void None %func
3340 %foo_entry = OpLabel
3341 %frag_depth = OpAccessChain %output_f32_ptr %output %u32_0
3342 OpStore %frag_depth %f32_1
3343 OpReturn
3344 OpFunctionEnd
3345 )";
3346
3347 generator.add_at_the_end_ = function_body;
3348
3349 return generator;
3350 }
3351
TEST_F(ValidateBuiltIns,VulkanFragmentFragDepthOneMainHasDepthReplacingOtherHasnt)3352 TEST_F(ValidateBuiltIns,
3353 VulkanFragmentFragDepthOneMainHasDepthReplacingOtherHasnt) {
3354 CodeGenerator generator = GetOneMainHasDepthReplacingOtherHasntGenerator();
3355
3356 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
3357 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3358 EXPECT_THAT(getDiagnosticString(),
3359 HasSubstr("Vulkan spec requires DepthReplacing execution mode to "
3360 "be declared when using BuiltIn FragDepth"));
3361 EXPECT_THAT(getDiagnosticString(),
3362 HasSubstr("VUID-FragDepth-FragDepth-04216"));
3363 }
3364
3365
TEST_F(ValidateBuiltIns,AllowInstanceIdWithIntersectionShader)3366 TEST_F(ValidateBuiltIns, AllowInstanceIdWithIntersectionShader) {
3367 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3368 generator.capabilities_ += R"(
3369 OpCapability RayTracingNV
3370 )";
3371
3372 generator.extensions_ = R"(
3373 OpExtension "SPV_NV_ray_tracing"
3374 )";
3375
3376 generator.before_types_ = R"(
3377 OpMemberDecorate %input_type 0 BuiltIn InstanceId
3378 )";
3379
3380 generator.after_types_ = R"(
3381 %input_type = OpTypeStruct %u32
3382 %input_ptr = OpTypePointer Input %input_type
3383 %input = OpVariable %input_ptr Input
3384 )";
3385
3386 EntryPoint entry_point;
3387 entry_point.name = "main_d_r";
3388 entry_point.execution_model = "IntersectionNV";
3389 entry_point.interfaces = "%input";
3390 entry_point.body = R"(
3391 %val2 = OpFunctionCall %void %foo
3392 )";
3393 generator.entry_points_.push_back(std::move(entry_point));
3394
3395 generator.add_at_the_end_ = R"(
3396 %foo = OpFunction %void None %func
3397 %foo_entry = OpLabel
3398 OpReturn
3399 OpFunctionEnd
3400 )";
3401
3402 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
3403 EXPECT_THAT(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
3404 }
3405
TEST_F(ValidateBuiltIns,ValidBuiltinsForMeshShader)3406 TEST_F(ValidateBuiltIns, ValidBuiltinsForMeshShader) {
3407 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3408 generator.capabilities_ += R"(
3409 OpCapability MeshShadingNV
3410 )";
3411
3412 generator.extensions_ = R"(
3413 OpExtension "SPV_NV_mesh_shader"
3414 )";
3415
3416 generator.before_types_ = R"(
3417 OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId
3418 OpDecorate %gl_PrimitiveID PerPrimitiveNV
3419 OpDecorate %gl_Layer BuiltIn Layer
3420 OpDecorate %gl_Layer PerPrimitiveNV
3421 OpDecorate %gl_ViewportIndex BuiltIn ViewportIndex
3422 OpDecorate %gl_ViewportIndex PerPrimitiveNV
3423 )";
3424
3425 generator.after_types_ = R"(
3426 %u32_81 = OpConstant %u32 81
3427 %_arr_int_uint_81 = OpTypeArray %i32 %u32_81
3428 %_ptr_Output__arr_int_uint_81 = OpTypePointer Output %_arr_int_uint_81
3429 %gl_PrimitiveID = OpVariable %_ptr_Output__arr_int_uint_81 Output
3430 %gl_Layer = OpVariable %_ptr_Output__arr_int_uint_81 Output
3431 %gl_ViewportIndex = OpVariable %_ptr_Output__arr_int_uint_81 Output
3432 )";
3433
3434 EntryPoint entry_point;
3435 entry_point.name = "main_d_r";
3436 entry_point.execution_model = "MeshNV";
3437 entry_point.interfaces = "%gl_PrimitiveID %gl_Layer %gl_ViewportIndex";
3438 generator.entry_points_.push_back(std::move(entry_point));
3439
3440 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_1);
3441 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3442 }
3443
TEST_F(ValidateBuiltIns,InvalidBuiltinsForMeshShader)3444 TEST_F(ValidateBuiltIns, InvalidBuiltinsForMeshShader) {
3445 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3446 generator.capabilities_ += R"(
3447 OpCapability MeshShadingNV
3448 )";
3449
3450 generator.extensions_ = R"(
3451 OpExtension "SPV_NV_mesh_shader"
3452 )";
3453
3454 generator.before_types_ = R"(
3455 OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId
3456 OpDecorate %gl_PrimitiveID PerPrimitiveNV
3457 OpDecorate %gl_Layer BuiltIn Layer
3458 OpDecorate %gl_Layer PerPrimitiveNV
3459 OpDecorate %gl_ViewportIndex BuiltIn ViewportIndex
3460 OpDecorate %gl_ViewportIndex PerPrimitiveNV
3461 )";
3462
3463 generator.after_types_ = R"(
3464 %u32_81 = OpConstant %u32 81
3465 %_arr_float_uint_81 = OpTypeArray %f32 %u32_81
3466 %_ptr_Output__arr_float_uint_81 = OpTypePointer Output %_arr_float_uint_81
3467 %gl_PrimitiveID = OpVariable %_ptr_Output__arr_float_uint_81 Output
3468 %gl_Layer = OpVariable %_ptr_Output__arr_float_uint_81 Output
3469 %gl_ViewportIndex = OpVariable %_ptr_Output__arr_float_uint_81 Output
3470 )";
3471
3472 EntryPoint entry_point;
3473 entry_point.name = "main_d_r";
3474 entry_point.execution_model = "MeshNV";
3475 entry_point.interfaces = "%gl_PrimitiveID %gl_Layer %gl_ViewportIndex";
3476 generator.entry_points_.push_back(std::move(entry_point));
3477
3478 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_1);
3479 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3480 EXPECT_THAT(getDiagnosticString(),
3481 HasSubstr("needs to be a 32-bit int scalar"));
3482 EXPECT_THAT(getDiagnosticString(), HasSubstr("is not an int scalar"));
3483 }
3484
TEST_P(ValidateVulkanSubgroupBuiltIns,InMain)3485 TEST_P(ValidateVulkanSubgroupBuiltIns, InMain) {
3486 const char* const built_in = std::get<0>(GetParam());
3487 const char* const execution_model = std::get<1>(GetParam());
3488 const char* const storage_class = std::get<2>(GetParam());
3489 const char* const data_type = std::get<3>(GetParam());
3490 const char* const vuid = std::get<4>(GetParam());
3491 const TestResult& test_result = std::get<5>(GetParam());
3492
3493 CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
3494 generator.capabilities_ += R"(
3495 OpCapability GroupNonUniformBallot
3496 )";
3497
3498 generator.before_types_ = "OpDecorate %built_in_var BuiltIn ";
3499 generator.before_types_ += built_in;
3500 generator.before_types_ += "\n";
3501
3502 std::ostringstream after_types;
3503 after_types << "%built_in_ptr = OpTypePointer " << storage_class << " "
3504 << data_type << "\n";
3505 after_types << "%built_in_var = OpVariable %built_in_ptr " << storage_class;
3506 after_types << "\n";
3507 generator.after_types_ = after_types.str();
3508
3509 EntryPoint entry_point;
3510 entry_point.name = "main";
3511 entry_point.execution_model = execution_model;
3512 if (strncmp(storage_class, "Input", 5) == 0 ||
3513 strncmp(storage_class, "Output", 6) == 0) {
3514 entry_point.interfaces = "%built_in_var";
3515 }
3516 entry_point.body =
3517 std::string("%ld = OpLoad ") + data_type + " %built_in_var\n";
3518
3519 std::ostringstream execution_modes;
3520 if (0 == std::strcmp(execution_model, "Fragment")) {
3521 execution_modes << "OpExecutionMode %" << entry_point.name
3522 << " OriginUpperLeft\n";
3523 if (0 == std::strcmp(built_in, "FragDepth")) {
3524 execution_modes << "OpExecutionMode %" << entry_point.name
3525 << " DepthReplacing\n";
3526 }
3527 }
3528 if (0 == std::strcmp(execution_model, "Geometry")) {
3529 execution_modes << "OpExecutionMode %" << entry_point.name
3530 << " InputPoints\n";
3531 execution_modes << "OpExecutionMode %" << entry_point.name
3532 << " OutputPoints\n";
3533 }
3534 if (0 == std::strcmp(execution_model, "GLCompute")) {
3535 execution_modes << "OpExecutionMode %" << entry_point.name
3536 << " LocalSize 1 1 1\n";
3537 }
3538 entry_point.execution_modes = execution_modes.str();
3539
3540 generator.entry_points_.push_back(std::move(entry_point));
3541
3542 CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_1);
3543 ASSERT_EQ(test_result.validation_result,
3544 ValidateInstructions(SPV_ENV_VULKAN_1_1));
3545 if (test_result.error_str) {
3546 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str));
3547 }
3548 if (test_result.error_str2) {
3549 EXPECT_THAT(getDiagnosticString(), HasSubstr(test_result.error_str2));
3550 }
3551 if (vuid) {
3552 EXPECT_THAT(getDiagnosticString(), AnyVUID(vuid));
3553 }
3554 }
3555
3556 INSTANTIATE_TEST_SUITE_P(
3557 SubgroupMaskNotVec4, ValidateVulkanSubgroupBuiltIns,
3558 Combine(Values("SubgroupEqMask", "SubgroupGeMask", "SubgroupGtMask",
3559 "SubgroupLeMask", "SubgroupLtMask"),
3560 Values("GLCompute"), Values("Input"), Values("%u32vec3"),
3561 Values("VUID-SubgroupEqMask-SubgroupEqMask-04371 "
3562 "VUID-SubgroupGeMask-SubgroupGeMask-04373 "
3563 "VUID-SubgroupGtMask-SubgroupGtMask-04375 "
3564 "VUID-SubgroupLeMask-SubgroupLeMask-04377 "
3565 "VUID-SubgroupLtMask-SubgroupLtMask-04379"),
3566 Values(TestResult(SPV_ERROR_INVALID_DATA,
3567 "needs to be a 4-component 32-bit int vector"))));
3568
3569 INSTANTIATE_TEST_SUITE_P(
3570 SubgroupMaskNotU32, ValidateVulkanSubgroupBuiltIns,
3571 Combine(Values("SubgroupEqMask", "SubgroupGeMask", "SubgroupGtMask",
3572 "SubgroupLeMask", "SubgroupLtMask"),
3573 Values("GLCompute"), Values("Input"), Values("%f32vec4"),
3574 Values("VUID-SubgroupEqMask-SubgroupEqMask-04371 "
3575 "VUID-SubgroupGeMask-SubgroupGeMask-04373 "
3576 "VUID-SubgroupGtMask-SubgroupGtMask-04375 "
3577 "VUID-SubgroupLeMask-SubgroupLeMask-04377 "
3578 "VUID-SubgroupLtMask-SubgroupLtMask-04379"),
3579 Values(TestResult(SPV_ERROR_INVALID_DATA,
3580 "needs to be a 4-component 32-bit int vector"))));
3581
3582 INSTANTIATE_TEST_SUITE_P(
3583 SubgroupMaskNotInput, ValidateVulkanSubgroupBuiltIns,
3584 Combine(Values("SubgroupEqMask", "SubgroupGeMask", "SubgroupGtMask",
3585 "SubgroupLeMask", "SubgroupLtMask"),
3586 Values("GLCompute"), Values("Output", "Workgroup", "Private"),
3587 Values("%u32vec4"),
3588 Values("VUID-SubgroupEqMask-SubgroupEqMask-04370 "
3589 "VUID-SubgroupGeMask-SubgroupGeMask-04372 "
3590 "VUID-SubgroupGtMask-SubgroupGtMask-04374 "
3591 "VUID-SubgroupLeMask-SubgroupLeMask-04376 "
3592 "VUID-SubgroupLtMask-SubgroupLtMask-04378"),
3593 Values(TestResult(
3594 SPV_ERROR_INVALID_DATA,
3595 "to be only used for variables with Input storage class"))));
3596
3597 INSTANTIATE_TEST_SUITE_P(SubgroupMaskOk, ValidateVulkanSubgroupBuiltIns,
3598 Combine(Values("SubgroupEqMask", "SubgroupGeMask",
3599 "SubgroupGtMask", "SubgroupLeMask",
3600 "SubgroupLtMask"),
3601 Values("GLCompute"), Values("Input"),
3602 Values("%u32vec4"), Values(nullptr),
3603 Values(TestResult(SPV_SUCCESS, ""))));
3604
TEST_F(ValidateBuiltIns,SubgroupMaskMemberDecorate)3605 TEST_F(ValidateBuiltIns, SubgroupMaskMemberDecorate) {
3606 const std::string text = R"(
3607 OpCapability Shader
3608 OpCapability GroupNonUniformBallot
3609 OpMemoryModel Logical GLSL450
3610 OpEntryPoint GLCompute %foo "foo"
3611 OpExecutionMode %foo LocalSize 1 1 1
3612 OpMemberDecorate %struct 0 BuiltIn SubgroupEqMask
3613 %void = OpTypeVoid
3614 %int = OpTypeInt 32 0
3615 %struct = OpTypeStruct %int
3616 %void_fn = OpTypeFunction %void
3617 %foo = OpFunction %void None %void_fn
3618 %entry = OpLabel
3619 OpReturn
3620 OpFunctionEnd
3621 )";
3622
3623 CompileSuccessfully(text, SPV_ENV_VULKAN_1_1);
3624 EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3625 EXPECT_THAT(
3626 getDiagnosticString(),
3627 HasSubstr(
3628 "BuiltIn SubgroupEqMask cannot be used as a member decoration"));
3629 }
3630
3631 INSTANTIATE_TEST_SUITE_P(
3632 SubgroupInvocationIdAndSizeNotU32, ValidateVulkanSubgroupBuiltIns,
3633 Combine(
3634 Values("SubgroupLocalInvocationId", "SubgroupSize"),
3635 Values("GLCompute"), Values("Input"), Values("%f32"),
3636 Values("VUID-SubgroupLocalInvocationId-SubgroupLocalInvocationId-04381 "
3637 "VUID-SubgroupSize-SubgroupSize-04383"),
3638 Values(TestResult(SPV_ERROR_INVALID_DATA,
3639 "needs to be a 32-bit int"))));
3640
3641 INSTANTIATE_TEST_SUITE_P(
3642 SubgroupInvocationIdAndSizeNotInput, ValidateVulkanSubgroupBuiltIns,
3643 Combine(
3644 Values("SubgroupLocalInvocationId", "SubgroupSize"),
3645 Values("GLCompute"), Values("Output", "Workgroup", "Private"),
3646 Values("%u32"),
3647 Values("VUID-SubgroupLocalInvocationId-SubgroupLocalInvocationId-04380 "
3648 "VUID-SubgroupSize-SubgroupSize-04382"),
3649 Values(TestResult(
3650 SPV_ERROR_INVALID_DATA,
3651 "to be only used for variables with Input storage class"))));
3652
3653 INSTANTIATE_TEST_SUITE_P(
3654 SubgroupInvocationIdAndSizeOk, ValidateVulkanSubgroupBuiltIns,
3655 Combine(Values("SubgroupLocalInvocationId", "SubgroupSize"),
3656 Values("GLCompute"), Values("Input"), Values("%u32"),
3657 Values(nullptr), Values(TestResult(SPV_SUCCESS, ""))));
3658
TEST_F(ValidateBuiltIns,SubgroupSizeMemberDecorate)3659 TEST_F(ValidateBuiltIns, SubgroupSizeMemberDecorate) {
3660 const std::string text = R"(
3661 OpCapability Shader
3662 OpCapability GroupNonUniform
3663 OpMemoryModel Logical GLSL450
3664 OpEntryPoint GLCompute %foo "foo"
3665 OpExecutionMode %foo LocalSize 1 1 1
3666 OpMemberDecorate %struct 0 BuiltIn SubgroupSize
3667 %void = OpTypeVoid
3668 %int = OpTypeInt 32 0
3669 %struct = OpTypeStruct %int
3670 %void_fn = OpTypeFunction %void
3671 %foo = OpFunction %void None %void_fn
3672 %entry = OpLabel
3673 OpReturn
3674 OpFunctionEnd
3675 )";
3676
3677 CompileSuccessfully(text, SPV_ENV_VULKAN_1_1);
3678 EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3679 EXPECT_THAT(
3680 getDiagnosticString(),
3681 HasSubstr("BuiltIn SubgroupSize cannot be used as a member decoration"));
3682 }
3683
3684 INSTANTIATE_TEST_SUITE_P(
3685 SubgroupNumAndIdNotCompute, ValidateVulkanSubgroupBuiltIns,
3686 Combine(Values("SubgroupId", "NumSubgroups"), Values("Vertex"),
3687 Values("Input"), Values("%u32"),
3688 Values("VUID-SubgroupId-SubgroupId-04367 "
3689 "VUID-NumSubgroups-NumSubgroups-04293"),
3690 Values(TestResult(SPV_ERROR_INVALID_DATA,
3691 "to be used only with GLCompute, MeshNV, or "
3692 "TaskNV execution model"))));
3693
3694 INSTANTIATE_TEST_SUITE_P(
3695 SubgroupNumAndIdNotU32, ValidateVulkanSubgroupBuiltIns,
3696 Combine(Values("SubgroupId", "NumSubgroups"), Values("GLCompute"),
3697 Values("Input"), Values("%f32"),
3698 Values("VUID-SubgroupId-SubgroupId-04369 "
3699 "VUID-NumSubgroups-NumSubgroups-04295"),
3700 Values(TestResult(SPV_ERROR_INVALID_DATA,
3701 "needs to be a 32-bit int"))));
3702
3703 INSTANTIATE_TEST_SUITE_P(
3704 SubgroupNumAndIdNotInput, ValidateVulkanSubgroupBuiltIns,
3705 Combine(Values("SubgroupId", "NumSubgroups"), Values("GLCompute"),
3706 Values("Output", "Workgroup", "Private"), Values("%u32"),
3707 Values("VUID-SubgroupId-SubgroupId-04368 "
3708 "VUID-NumSubgroups-NumSubgroups-04294"),
3709 Values(TestResult(
3710 SPV_ERROR_INVALID_DATA,
3711 "to be only used for variables with Input storage class"))));
3712
3713 INSTANTIATE_TEST_SUITE_P(SubgroupNumAndIdOk, ValidateVulkanSubgroupBuiltIns,
3714 Combine(Values("SubgroupId", "NumSubgroups"),
3715 Values("GLCompute"), Values("Input"),
3716 Values("%u32"), Values(nullptr),
3717 Values(TestResult(SPV_SUCCESS, ""))));
3718
TEST_F(ValidateBuiltIns,SubgroupIdMemberDecorate)3719 TEST_F(ValidateBuiltIns, SubgroupIdMemberDecorate) {
3720 const std::string text = R"(
3721 OpCapability Shader
3722 OpCapability GroupNonUniform
3723 OpMemoryModel Logical GLSL450
3724 OpEntryPoint GLCompute %foo "foo"
3725 OpExecutionMode %foo LocalSize 1 1 1
3726 OpMemberDecorate %struct 0 BuiltIn SubgroupId
3727 %void = OpTypeVoid
3728 %int = OpTypeInt 32 0
3729 %struct = OpTypeStruct %int
3730 %void_fn = OpTypeFunction %void
3731 %foo = OpFunction %void None %void_fn
3732 %entry = OpLabel
3733 OpReturn
3734 OpFunctionEnd
3735 )";
3736
3737 CompileSuccessfully(text, SPV_ENV_VULKAN_1_1);
3738 EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1));
3739 EXPECT_THAT(
3740 getDiagnosticString(),
3741 HasSubstr("BuiltIn SubgroupId cannot be used as a member decoration"));
3742 }
3743
TEST_F(ValidateBuiltIns,TargetIsType)3744 TEST_F(ValidateBuiltIns, TargetIsType) {
3745 const std::string text = R"(
3746 OpCapability Shader
3747 OpCapability Linkage
3748 OpMemoryModel Logical GLSL450
3749 OpDecorate %void BuiltIn Position
3750 %void = OpTypeVoid
3751 )";
3752
3753 CompileSuccessfully(text);
3754 EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3755 EXPECT_THAT(getDiagnosticString(),
3756 HasSubstr("BuiltIns can only target variables, structure members "
3757 "or constants"));
3758 }
3759
TEST_F(ValidateBuiltIns,TargetIsVariable)3760 TEST_F(ValidateBuiltIns, TargetIsVariable) {
3761 const std::string text = R"(
3762 OpCapability Shader
3763 OpCapability Linkage
3764 OpMemoryModel Logical GLSL450
3765 OpDecorate %wg_var BuiltIn Position
3766 %int = OpTypeInt 32 0
3767 %int_wg_ptr = OpTypePointer Workgroup %int
3768 %wg_var = OpVariable %int_wg_ptr Workgroup
3769 )";
3770
3771 CompileSuccessfully(text);
3772 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
3773 }
3774
3775 INSTANTIATE_TEST_SUITE_P(
3776 PrimitiveShadingRateOutputSuccess,
3777 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3778 Combine(Values("PrimitiveShadingRateKHR"), Values("Vertex", "Geometry"),
3779 Values("Output"), Values("%u32"),
3780 Values("OpCapability FragmentShadingRateKHR\n"),
3781 Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
3782 Values(nullptr), Values(TestResult())));
3783
3784 INSTANTIATE_TEST_SUITE_P(
3785 PrimitiveShadingRateMeshOutputSuccess,
3786 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3787 Combine(Values("PrimitiveShadingRateKHR"), Values("MeshNV"),
3788 Values("Output"), Values("%u32"),
3789 Values("OpCapability FragmentShadingRateKHR\nOpCapability "
3790 "MeshShadingNV\n"),
3791 Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\nOpExtension "
3792 "\"SPV_NV_mesh_shader\"\n"),
3793 Values(nullptr), Values(TestResult())));
3794
3795 INSTANTIATE_TEST_SUITE_P(
3796 PrimitiveShadingRateInvalidExecutionModel,
3797 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3798 Combine(
3799 Values("PrimitiveShadingRateKHR"), Values("Fragment"), Values("Output"),
3800 Values("%u32"), Values("OpCapability FragmentShadingRateKHR\n"),
3801 Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
3802 Values("VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04484 "),
3803 Values(TestResult(
3804 SPV_ERROR_INVALID_DATA,
3805 "Vulkan spec allows BuiltIn PrimitiveShadingRateKHR to be used "
3806 "only with Vertex, Geometry, or MeshNV execution models."))));
3807
3808 INSTANTIATE_TEST_SUITE_P(
3809 PrimitiveShadingRateInvalidStorageClass,
3810 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3811 Combine(
3812 Values("PrimitiveShadingRateKHR"), Values("Vertex"), Values("Input"),
3813 Values("%u32"), Values("OpCapability FragmentShadingRateKHR\n"),
3814 Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
3815 Values("VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04485 "),
3816 Values(TestResult(
3817 SPV_ERROR_INVALID_DATA,
3818 "Vulkan spec allows BuiltIn PrimitiveShadingRateKHR to be only "
3819 "used for variables with Output storage class."))));
3820
3821 INSTANTIATE_TEST_SUITE_P(
3822 PrimitiveShadingRateInvalidType,
3823 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3824 Combine(
3825 Values("PrimitiveShadingRateKHR"), Values("Vertex"), Values("Output"),
3826 Values("%f32"), Values("OpCapability FragmentShadingRateKHR\n"),
3827 Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
3828 Values("VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04486 "),
3829 Values(TestResult(
3830 SPV_ERROR_INVALID_DATA,
3831 "According to the Vulkan spec BuiltIn PrimitiveShadingRateKHR "
3832 "variable needs to be a 32-bit int scalar."))));
3833
3834 INSTANTIATE_TEST_SUITE_P(
3835 ShadingRateInputSuccess,
3836 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3837 Combine(Values("ShadingRateKHR"), Values("Fragment"), Values("Input"),
3838 Values("%u32"), Values("OpCapability FragmentShadingRateKHR\n"),
3839 Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
3840 Values(nullptr), Values(TestResult())));
3841
3842 INSTANTIATE_TEST_SUITE_P(
3843 ShadingRateInvalidExecutionModel,
3844 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3845 Combine(Values("ShadingRateKHR"), Values("Vertex"), Values("Input"),
3846 Values("%u32"), Values("OpCapability FragmentShadingRateKHR\n"),
3847 Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
3848 Values("VUID-ShadingRateKHR-ShadingRateKHR-04490 "),
3849 Values(TestResult(
3850 SPV_ERROR_INVALID_DATA,
3851 "Vulkan spec allows BuiltIn ShadingRateKHR to be used "
3852 "only with the Fragment execution model."))));
3853
3854 INSTANTIATE_TEST_SUITE_P(
3855 ShadingRateInvalidStorageClass,
3856 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3857 Combine(Values("ShadingRateKHR"), Values("Fragment"), Values("Output"),
3858 Values("%u32"), Values("OpCapability FragmentShadingRateKHR\n"),
3859 Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
3860 Values("VUID-ShadingRateKHR-ShadingRateKHR-04491 "),
3861 Values(TestResult(
3862 SPV_ERROR_INVALID_DATA,
3863 "Vulkan spec allows BuiltIn ShadingRateKHR to be only "
3864 "used for variables with Input storage class."))));
3865
3866 INSTANTIATE_TEST_SUITE_P(
3867 ShadingRateInvalidType,
3868 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3869 Combine(
3870 Values("ShadingRateKHR"), Values("Fragment"), Values("Input"),
3871 Values("%f32"), Values("OpCapability FragmentShadingRateKHR\n"),
3872 Values("OpExtension \"SPV_KHR_fragment_shading_rate\"\n"),
3873 Values("VUID-ShadingRateKHR-ShadingRateKHR-04492 "),
3874 Values(TestResult(SPV_ERROR_INVALID_DATA,
3875 "According to the Vulkan spec BuiltIn ShadingRateKHR "
3876 "variable needs to be a 32-bit int scalar."))));
3877
3878 INSTANTIATE_TEST_SUITE_P(
3879 FragInvocationCountInputSuccess,
3880 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3881 Combine(Values("FragInvocationCountEXT"), Values("Fragment"),
3882 Values("Input"), Values("%u32"),
3883 Values("OpCapability FragmentDensityEXT\n"),
3884 Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
3885 Values(nullptr), Values(TestResult())));
3886
3887 INSTANTIATE_TEST_SUITE_P(
3888 FragInvocationCountInvalidExecutionModel,
3889 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3890 Combine(
3891 Values("FragInvocationCountEXT"), Values("Vertex"), Values("Input"),
3892 Values("%u32"), Values("OpCapability FragmentDensityEXT\n"),
3893 Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
3894 Values("VUID-FragInvocationCountEXT-FragInvocationCountEXT-04217"),
3895 Values(TestResult(SPV_ERROR_INVALID_DATA,
3896 "Vulkan spec allows BuiltIn FragInvocationCountEXT "
3897 "to be used only with Fragment execution model."))));
3898
3899 INSTANTIATE_TEST_SUITE_P(
3900 FragInvocationCountInvalidStorageClass,
3901 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3902 Combine(Values("FragInvocationCountEXT"), Values("Fragment"),
3903 Values("Output"), Values("%u32"),
3904 Values("OpCapability FragmentDensityEXT\n"),
3905 Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
3906 Values("VUID-FragInvocationCountEXT-FragInvocationCountEXT-04218"),
3907 Values(TestResult(
3908 SPV_ERROR_INVALID_DATA,
3909 "Vulkan spec allows BuiltIn FragInvocationCountEXT to be only "
3910 "used for variables with Input storage class."))));
3911
3912 INSTANTIATE_TEST_SUITE_P(
3913 FragInvocationCountInvalidType,
3914 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3915 Combine(Values("FragInvocationCountEXT"), Values("Fragment"),
3916 Values("Input"), Values("%f32"),
3917 Values("OpCapability FragmentDensityEXT\n"),
3918 Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
3919 Values("VUID-FragInvocationCountEXT-FragInvocationCountEXT-04219"),
3920 Values(TestResult(
3921 SPV_ERROR_INVALID_DATA,
3922 "According to the Vulkan spec BuiltIn FragInvocationCountEXT "
3923 "variable needs to be a 32-bit int scalar."))));
3924
3925 INSTANTIATE_TEST_SUITE_P(
3926 FragSizeInputSuccess,
3927 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3928 Combine(Values("FragSizeEXT"), Values("Fragment"), Values("Input"),
3929 Values("%u32vec2"), Values("OpCapability FragmentDensityEXT\n"),
3930 Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
3931 Values(nullptr), Values(TestResult())));
3932
3933 INSTANTIATE_TEST_SUITE_P(
3934 FragSizeInvalidExecutionModel,
3935 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3936 Combine(Values("FragSizeEXT"), Values("Vertex"), Values("Input"),
3937 Values("%u32vec2"), Values("OpCapability FragmentDensityEXT\n"),
3938 Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
3939 Values("VUID-FragSizeEXT-FragSizeEXT-04220"),
3940 Values(TestResult(SPV_ERROR_INVALID_DATA,
3941 "Vulkan spec allows BuiltIn FragSizeEXT to be "
3942 "used only with Fragment execution model."))));
3943
3944 INSTANTIATE_TEST_SUITE_P(
3945 FragSizeInvalidStorageClass,
3946 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3947 Combine(
3948 Values("FragSizeEXT"), Values("Fragment"), Values("Output"),
3949 Values("%u32vec2"), Values("OpCapability FragmentDensityEXT\n"),
3950 Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
3951 Values("VUID-FragSizeEXT-FragSizeEXT-04221"),
3952 Values(TestResult(SPV_ERROR_INVALID_DATA,
3953 "Vulkan spec allows BuiltIn FragSizeEXT to be only "
3954 "used for variables with Input storage class."))));
3955
3956 INSTANTIATE_TEST_SUITE_P(
3957 FragSizeInvalidType,
3958 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3959 Combine(Values("FragSizeEXT"), Values("Fragment"), Values("Input"),
3960 Values("%u32vec3"), Values("OpCapability FragmentDensityEXT\n"),
3961 Values("OpExtension \"SPV_EXT_fragment_invocation_density\"\n"),
3962 Values("VUID-FragSizeEXT-FragSizeEXT-04222"),
3963 Values(TestResult(
3964 SPV_ERROR_INVALID_DATA,
3965 "According to the Vulkan spec BuiltIn FragSizeEXT variable "
3966 "needs to be a 2-component 32-bit int vector."))));
3967
3968 INSTANTIATE_TEST_SUITE_P(
3969 FragStencilRefOutputSuccess,
3970 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3971 Combine(Values("FragStencilRefEXT"), Values("Fragment"), Values("Output"),
3972 Values("%u32", "%u64"), Values("OpCapability StencilExportEXT\n"),
3973 Values("OpExtension \"SPV_EXT_shader_stencil_export\"\n"),
3974 Values(nullptr), Values(TestResult())));
3975
3976 INSTANTIATE_TEST_SUITE_P(
3977 FragStencilRefInvalidExecutionModel,
3978 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3979 Combine(Values("FragStencilRefEXT"), Values("Vertex"), Values("Output"),
3980 Values("%u32", "%u64"), Values("OpCapability StencilExportEXT\n"),
3981 Values("OpExtension \"SPV_EXT_shader_stencil_export\"\n"),
3982 Values("VUID-FragStencilRefEXT-FragStencilRefEXT-04223"),
3983 Values(TestResult(SPV_ERROR_INVALID_DATA,
3984 "Vulkan spec allows BuiltIn FragStencilRefEXT to "
3985 "be used only with Fragment execution model."))));
3986
3987 INSTANTIATE_TEST_SUITE_P(
3988 FragStencilRefInvalidStorageClass,
3989 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
3990 Combine(Values("FragStencilRefEXT"), Values("Fragment"), Values("Input"),
3991 Values("%u32", "%u64"), Values("OpCapability StencilExportEXT\n"),
3992 Values("OpExtension \"SPV_EXT_shader_stencil_export\"\n"),
3993 Values("VUID-FragStencilRefEXT-FragStencilRefEXT-04224"),
3994 Values(TestResult(
3995 SPV_ERROR_INVALID_DATA,
3996 "Vulkan spec allows BuiltIn FragStencilRefEXT to be only used "
3997 "for variables with Output storage class."))));
3998
3999 INSTANTIATE_TEST_SUITE_P(
4000 FragStencilRefInvalidType,
4001 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
4002 Combine(Values("FragStencilRefEXT"), Values("Fragment"), Values("Output"),
4003 Values("%f32", "%f64", "%u32vec2"),
4004 Values("OpCapability StencilExportEXT\n"),
4005 Values("OpExtension \"SPV_EXT_shader_stencil_export\"\n"),
4006 Values("VUID-FragStencilRefEXT-FragStencilRefEXT-04225"),
4007 Values(TestResult(
4008 SPV_ERROR_INVALID_DATA,
4009 "According to the Vulkan spec BuiltIn FragStencilRefEXT "
4010 "variable needs to be a int scalar."))));
4011
4012 INSTANTIATE_TEST_SUITE_P(
4013 FullyCoveredEXTInputSuccess,
4014 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
4015 Combine(Values("FullyCoveredEXT"), Values("Fragment"), Values("Input"),
4016 Values("%bool"), Values("OpCapability FragmentFullyCoveredEXT\n"),
4017 Values("OpExtension \"SPV_EXT_fragment_fully_covered\"\n"),
4018 Values(nullptr), Values(TestResult())));
4019
4020 INSTANTIATE_TEST_SUITE_P(
4021 FullyCoveredEXTInvalidExecutionModel,
4022 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
4023 Combine(Values("FullyCoveredEXT"), Values("Vertex"), Values("Input"),
4024 Values("%bool"), Values("OpCapability FragmentFullyCoveredEXT\n"),
4025 Values("OpExtension \"SPV_EXT_fragment_fully_covered\"\n"),
4026 Values("VUID-FullyCoveredEXT-FullyCoveredEXT-04232"),
4027 Values(TestResult(SPV_ERROR_INVALID_DATA,
4028 "Vulkan spec allows BuiltIn FullyCoveredEXT to "
4029 "be used only with Fragment execution model."))));
4030
4031 INSTANTIATE_TEST_SUITE_P(
4032 FullyCoveredEXTInvalidStorageClass,
4033 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
4034 Combine(Values("FullyCoveredEXT"), Values("Fragment"), Values("Output"),
4035 Values("%bool"), Values("OpCapability FragmentFullyCoveredEXT\n"),
4036 Values("OpExtension \"SPV_EXT_fragment_fully_covered\"\n"),
4037 Values("VUID-FullyCoveredEXT-FullyCoveredEXT-04233"),
4038 Values(TestResult(
4039 SPV_ERROR_INVALID_DATA,
4040 "Vulkan spec allows BuiltIn FullyCoveredEXT to be only used "
4041 "for variables with Input storage class."))));
4042
4043 INSTANTIATE_TEST_SUITE_P(
4044 FullyCoveredEXTInvalidType,
4045 ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
4046 Combine(Values("FullyCoveredEXT"), Values("Fragment"), Values("Input"),
4047 Values("%f32"), Values("OpCapability FragmentFullyCoveredEXT\n"),
4048 Values("OpExtension \"SPV_EXT_fragment_fully_covered\"\n"),
4049 Values("VUID-FullyCoveredEXT-FullyCoveredEXT-04234"),
4050 Values(TestResult(
4051 SPV_ERROR_INVALID_DATA,
4052 "According to the Vulkan spec BuiltIn FullyCoveredEXT variable "
4053 "needs to be a bool scalar."))));
4054
4055 } // namespace
4056 } // namespace val
4057 } // namespace spvtools
4058