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