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