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