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