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