1 // Copyright (c) 2018 Google LLC.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <sstream>
16 #include <string>
17 #include <tuple>
18
19 #include "gmock/gmock.h"
20 #include "test/unit_spirv.h"
21 #include "test/val/val_fixtures.h"
22
23 namespace spvtools {
24 namespace val {
25 namespace {
26
27 using ::testing::Combine;
28 using ::testing::HasSubstr;
29 using ::testing::Values;
30 using ::testing::ValuesIn;
31
GenerateShaderCode(const std::string & body,const std::string & capabilities_and_extensions="",const std::string & execution_model="GLCompute")32 std::string GenerateShaderCode(
33 const std::string& body,
34 const std::string& capabilities_and_extensions = "",
35 const std::string& execution_model = "GLCompute") {
36 std::ostringstream ss;
37 ss << R"(
38 OpCapability Shader
39 OpCapability GroupNonUniform
40 OpCapability GroupNonUniformVote
41 OpCapability GroupNonUniformBallot
42 OpCapability GroupNonUniformShuffle
43 OpCapability GroupNonUniformShuffleRelative
44 OpCapability GroupNonUniformArithmetic
45 OpCapability GroupNonUniformClustered
46 OpCapability GroupNonUniformQuad
47 OpCapability GroupNonUniformPartitionedNV
48 OpCapability QuadControlKHR
49 OpExtension "SPV_NV_shader_subgroup_partitioned"
50 OpExtension "SPV_KHR_quad_control"
51 )";
52
53 ss << capabilities_and_extensions;
54 ss << "OpMemoryModel Logical GLSL450\n";
55 ss << "OpEntryPoint " << execution_model << " %main \"main\"\n";
56 if (execution_model == "GLCompute") {
57 ss << "OpExecutionMode %main LocalSize 1 1 1\n";
58 }
59
60 ss << R"(
61 %void = OpTypeVoid
62 %func = OpTypeFunction %void
63 %bool = OpTypeBool
64 %u32 = OpTypeInt 32 0
65 %int = OpTypeInt 32 1
66 %float = OpTypeFloat 32
67 %u32vec4 = OpTypeVector %u32 4
68 %u32vec3 = OpTypeVector %u32 3
69 %v2bool = OpTypeVector %bool 2
70 %v4float = OpTypeVector %float 4
71 %struct = OpTypeStruct %int
72 %v4int = OpTypeVector %int 4
73
74 %true = OpConstantTrue %bool
75 %false = OpConstantFalse %bool
76
77 %u32_0 = OpConstant %u32 0
78 %int_0 = OpConstant %int 0
79
80 %float_0 = OpConstant %float 0
81
82 %u32vec4_null = OpConstantComposite %u32vec4 %u32_0 %u32_0 %u32_0 %u32_0
83 %u32vec3_null = OpConstantComposite %u32vec3 %u32_0 %u32_0 %u32_0
84 %v2bool_false = OpConstantNull %v2bool
85 %v4float_null = OpConstantNull %v4float
86 %struct_null = OpConstantNull %struct
87 %v4int_null = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
88
89 %u32_undef = OpUndef %u32
90
91 %cross_device = OpConstant %u32 0
92 %device = OpConstant %u32 1
93 %workgroup = OpConstant %u32 2
94 %subgroup = OpConstant %u32 3
95 %invocation = OpConstant %u32 4
96
97 %reduce = OpConstant %u32 0
98 %inclusive_scan = OpConstant %u32 1
99 %exclusive_scan = OpConstant %u32 2
100 %clustered_reduce = OpConstant %u32 3
101
102 %main = OpFunction %void None %func
103 %main_entry = OpLabel
104 )";
105
106 ss << body;
107
108 ss << R"(
109 OpReturn
110 OpFunctionEnd)";
111
112 return ss.str();
113 }
114
115 spv::Scope scopes[] = {spv::Scope::CrossDevice, spv::Scope::Device,
116 spv::Scope::Workgroup, spv::Scope::Subgroup,
117 spv::Scope::Invocation};
118
119 using ValidateGroupNonUniform = spvtest::ValidateBase<bool>;
120 using GroupNonUniform = spvtest::ValidateBase<
121 std::tuple<std::string, std::string, spv::Scope, std::string, std::string>>;
122
ConvertScope(spv::Scope scope)123 std::string ConvertScope(spv::Scope scope) {
124 switch (scope) {
125 case spv::Scope::CrossDevice:
126 return "%cross_device";
127 case spv::Scope::Device:
128 return "%device";
129 case spv::Scope::Workgroup:
130 return "%workgroup";
131 case spv::Scope::Subgroup:
132 return "%subgroup";
133 case spv::Scope::Invocation:
134 return "%invocation";
135 default:
136 return "";
137 }
138 }
139
ConvertMatch(const std::string & type)140 std::string ConvertMatch(const std::string& type) {
141 if (type == "%bool") {
142 return "%true";
143 } else if (type == "%u32") {
144 return "%u32_0";
145 } else if (type == "%int") {
146 return "%int_0";
147 } else if (type == "%float") {
148 return "%float_0";
149 } else if (type == "%u32vec4") {
150 return "%u32vec4_null";
151 } else if (type == "%u32vec3") {
152 return "%u32vec3_null";
153 } else if (type == "%v2bool") {
154 return "%v2bool_false";
155 } else if (type == "%v4float") {
156 return "%v4float_null";
157 } else if (type == "%struct") {
158 return "%struct_null";
159 } else if (type == "%v4int") {
160 return "%v4int_null";
161 }
162
163 return "INVALID";
164 }
165
TEST_P(GroupNonUniform,Vulkan1p1)166 TEST_P(GroupNonUniform, Vulkan1p1) {
167 std::string opcode = std::get<0>(GetParam());
168 std::string type = std::get<1>(GetParam());
169 spv::Scope execution_scope = std::get<2>(GetParam());
170 std::string args = std::get<3>(GetParam());
171 std::string error = std::get<4>(GetParam());
172
173 const std::string match = "match_res";
174 size_t pos = std::string::npos;
175 while ((pos = args.find(match)) != std::string::npos) {
176 const std::string replace = ConvertMatch(type);
177 args = args.substr(0, pos) + replace + args.substr(pos + match.size());
178 }
179
180 std::ostringstream sstr;
181 sstr << "%result = " << opcode << " ";
182 sstr << type << " ";
183 if (opcode != "OpGroupNonUniformQuadAllKHR" &&
184 opcode != "OpGroupNonUniformQuadAnyKHR") {
185 sstr << ConvertScope(execution_scope) << " ";
186 }
187 sstr << args << "\n";
188
189 CompileSuccessfully(GenerateShaderCode(sstr.str()), SPV_ENV_VULKAN_1_1);
190 spv_result_t result = ValidateInstructions(SPV_ENV_VULKAN_1_1);
191 if (error == "") {
192 if (execution_scope == spv::Scope::Subgroup) {
193 EXPECT_EQ(SPV_SUCCESS, result);
194 } else {
195 EXPECT_EQ(SPV_ERROR_INVALID_DATA, result);
196 EXPECT_THAT(getDiagnosticString(),
197 AnyVUID("VUID-StandaloneSpirv-None-04642"));
198 EXPECT_THAT(
199 getDiagnosticString(),
200 HasSubstr(
201 "in Vulkan environment Execution scope is limited to Subgroup"));
202 }
203 } else {
204 EXPECT_EQ(SPV_ERROR_INVALID_DATA, result);
205 EXPECT_THAT(getDiagnosticString(), HasSubstr(error));
206 }
207 }
208
TEST_P(GroupNonUniform,Spirv1p3)209 TEST_P(GroupNonUniform, Spirv1p3) {
210 std::string opcode = std::get<0>(GetParam());
211 std::string type = std::get<1>(GetParam());
212 spv::Scope execution_scope = std::get<2>(GetParam());
213 std::string args = std::get<3>(GetParam());
214 std::string error = std::get<4>(GetParam());
215
216 const std::string match = "match_res";
217 size_t pos = std::string::npos;
218 while ((pos = args.find(match)) != std::string::npos) {
219 const std::string replace = ConvertMatch(type);
220 args = args.substr(0, pos) + replace + args.substr(pos + match.size());
221 }
222
223 std::ostringstream sstr;
224 sstr << "%result = " << opcode << " ";
225 sstr << type << " ";
226 if (opcode != "OpGroupNonUniformQuadAllKHR" &&
227 opcode != "OpGroupNonUniformQuadAnyKHR") {
228 sstr << ConvertScope(execution_scope) << " ";
229 }
230 sstr << args << "\n";
231
232 CompileSuccessfully(GenerateShaderCode(sstr.str()), SPV_ENV_UNIVERSAL_1_3);
233 spv_result_t result = ValidateInstructions(SPV_ENV_UNIVERSAL_1_3);
234 if (error == "") {
235 if (execution_scope == spv::Scope::Subgroup ||
236 execution_scope == spv::Scope::Workgroup) {
237 EXPECT_EQ(SPV_SUCCESS, result);
238 } else {
239 EXPECT_EQ(SPV_ERROR_INVALID_DATA, result);
240 EXPECT_THAT(
241 getDiagnosticString(),
242 HasSubstr("Execution scope is limited to Subgroup or Workgroup"));
243 }
244 } else {
245 EXPECT_EQ(SPV_ERROR_INVALID_DATA, result);
246 EXPECT_THAT(getDiagnosticString(), HasSubstr(error));
247 }
248 }
249
250 INSTANTIATE_TEST_SUITE_P(GroupNonUniformElect, GroupNonUniform,
251 Combine(Values("OpGroupNonUniformElect"),
252 Values("%bool"), ValuesIn(scopes), Values(""),
253 Values("")));
254
255 INSTANTIATE_TEST_SUITE_P(GroupNonUniformVote, GroupNonUniform,
256 Combine(Values("OpGroupNonUniformAll",
257 "OpGroupNonUniformAny",
258 "OpGroupNonUniformAllEqual"),
259 Values("%bool"), ValuesIn(scopes),
260 Values("%true"), Values("")));
261
262 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBroadcast, GroupNonUniform,
263 Combine(Values("OpGroupNonUniformBroadcast"),
264 Values("%bool"), ValuesIn(scopes),
265 Values("%true %u32_0"), Values("")));
266
267 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBroadcastFirst, GroupNonUniform,
268 Combine(Values("OpGroupNonUniformBroadcastFirst"),
269 Values("%bool"), ValuesIn(scopes),
270 Values("%true"), Values("")));
271
272 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallot, GroupNonUniform,
273 Combine(Values("OpGroupNonUniformBallot"),
274 Values("%u32vec4"), ValuesIn(scopes),
275 Values("%true"), Values("")));
276
277 INSTANTIATE_TEST_SUITE_P(GroupNonUniformInverseBallot, GroupNonUniform,
278 Combine(Values("OpGroupNonUniformInverseBallot"),
279 Values("%bool"), ValuesIn(scopes),
280 Values("%u32vec4_null"), Values("")));
281
282 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotBitExtract, GroupNonUniform,
283 Combine(Values("OpGroupNonUniformBallotBitExtract"),
284 Values("%bool"), ValuesIn(scopes),
285 Values("%u32vec4_null %u32_0"), Values("")));
286
287 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotBitCount, GroupNonUniform,
288 Combine(Values("OpGroupNonUniformBallotBitCount"),
289 Values("%u32"), ValuesIn(scopes),
290 Values("Reduce %u32vec4_null"), Values("")));
291
292 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotFind, GroupNonUniform,
293 Combine(Values("OpGroupNonUniformBallotFindLSB",
294 "OpGroupNonUniformBallotFindMSB"),
295 Values("%u32"), ValuesIn(scopes),
296 Values("%u32vec4_null"), Values("")));
297
298 INSTANTIATE_TEST_SUITE_P(GroupNonUniformShuffle, GroupNonUniform,
299 Combine(Values("OpGroupNonUniformShuffle",
300 "OpGroupNonUniformShuffleXor",
301 "OpGroupNonUniformShuffleUp",
302 "OpGroupNonUniformShuffleDown"),
303 Values("%u32"), ValuesIn(scopes),
304 Values("%u32_0 %u32_0"), Values("")));
305
306 INSTANTIATE_TEST_SUITE_P(
307 GroupNonUniformIntegerArithmetic, GroupNonUniform,
308 Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
309 "OpGroupNonUniformSMin", "OpGroupNonUniformUMin",
310 "OpGroupNonUniformSMax", "OpGroupNonUniformUMax",
311 "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
312 "OpGroupNonUniformBitwiseXor"),
313 Values("%u32"), ValuesIn(scopes), Values("Reduce %u32_0"),
314 Values("")));
315
316 INSTANTIATE_TEST_SUITE_P(
317 GroupNonUniformFloatArithmetic, GroupNonUniform,
318 Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
319 "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
320 Values("%float"), ValuesIn(scopes), Values("Reduce %float_0"),
321 Values("")));
322
323 INSTANTIATE_TEST_SUITE_P(GroupNonUniformLogicalArithmetic, GroupNonUniform,
324 Combine(Values("OpGroupNonUniformLogicalAnd",
325 "OpGroupNonUniformLogicalOr",
326 "OpGroupNonUniformLogicalXor"),
327 Values("%bool"), ValuesIn(scopes),
328 Values("Reduce %true"), Values("")));
329
330 INSTANTIATE_TEST_SUITE_P(GroupNonUniformQuad, GroupNonUniform,
331 Combine(Values("OpGroupNonUniformQuadBroadcast",
332 "OpGroupNonUniformQuadSwap"),
333 Values("%u32"), ValuesIn(scopes),
334 Values("%u32_0 %u32_0"), Values("")));
335
336 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotBitCountScope, GroupNonUniform,
337 Combine(Values("OpGroupNonUniformBallotBitCount"),
338 Values("%u32"), ValuesIn(scopes),
339 Values("Reduce %u32vec4_null"), Values("")));
340
341 INSTANTIATE_TEST_SUITE_P(
342 GroupNonUniformBallotBitCountBadResultType, GroupNonUniform,
343 Combine(
344 Values("OpGroupNonUniformBallotBitCount"), Values("%float", "%int"),
345 Values(spv::Scope::Subgroup), Values("Reduce %u32vec4_null"),
346 Values("Expected Result Type to be an unsigned integer type scalar.")));
347
348 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotBitCountBadValue, GroupNonUniform,
349 Combine(Values("OpGroupNonUniformBallotBitCount"),
350 Values("%u32"), Values(spv::Scope::Subgroup),
351 Values("Reduce %u32vec3_null", "Reduce %u32_0",
352 "Reduce %float_0"),
353 Values("Expected Value to be a vector of four "
354 "components of integer type scalar")));
355
356 INSTANTIATE_TEST_SUITE_P(GroupNonUniformElectGood, GroupNonUniform,
357 Combine(Values("OpGroupNonUniformElect"),
358 Values("%bool"), Values(spv::Scope::Subgroup),
359 Values(""), Values("")));
360
361 INSTANTIATE_TEST_SUITE_P(
362 GroupNonUniformElectBadResultType, GroupNonUniform,
363 Combine(Values("OpGroupNonUniformElect"),
364 Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3",
365 "%v2bool", "%v4float", "%struct"),
366 Values(spv::Scope::Subgroup), Values(""),
367 Values("Result must be a boolean scalar type")));
368
369 INSTANTIATE_TEST_SUITE_P(GroupNonUniformAnyAllGood, GroupNonUniform,
370 Combine(Values("OpGroupNonUniformAny",
371 "OpGroupNonUniformAll"),
372 Values("%bool"), Values(spv::Scope::Subgroup),
373 Values("%true", "%false"), Values("")));
374
375 INSTANTIATE_TEST_SUITE_P(
376 GroupNonUniformAnyAllBadResultType, GroupNonUniform,
377 Combine(Values("OpGroupNonUniformAny", "OpGroupNonUniformAll"),
378 Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3",
379 "%v2bool", "%v4float", "%struct"),
380 Values(spv::Scope::Subgroup), Values("%true"),
381 Values("Result must be a boolean scalar type")));
382
383 INSTANTIATE_TEST_SUITE_P(
384 GroupNonUniformAnyAllBadOperand, GroupNonUniform,
385 Combine(Values("OpGroupNonUniformAny", "OpGroupNonUniformAll"),
386 Values("%bool"), Values(spv::Scope::Subgroup),
387 Values("%u32_0", "%int_0", "%float_0", "%u32vec4_null",
388 "%u32vec3_null", "%v2bool_false", "%v4float_null",
389 "%struct_null"),
390 Values("Predicate must be a boolean scalar type")));
391
392 INSTANTIATE_TEST_SUITE_P(GroupNonUniformAllEqualGood, GroupNonUniform,
393 Combine(Values("OpGroupNonUniformAllEqual"),
394 Values("%bool"), Values(spv::Scope::Subgroup),
395 Values("%true", "%false"), Values("")));
396
397 INSTANTIATE_TEST_SUITE_P(
398 GroupNonUniformAllEqualBadResultType, GroupNonUniform,
399 Combine(Values("OpGroupNonUniformAllEqual"),
400 Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3",
401 "%v2bool", "%v4float", "%struct"),
402 Values(spv::Scope::Subgroup), Values("%true"),
403 Values("Result must be a boolean scalar type")));
404
405 INSTANTIATE_TEST_SUITE_P(
406 GroupNonUniformAllEqualBadOperand, GroupNonUniform,
407 Combine(Values("OpGroupNonUniformAllEqual"), Values("%bool"),
408 Values(spv::Scope::Subgroup), Values("%struct_null"),
409 Values("Value must be a scalar or vector of integer, "
410 "floating-point, or boolean type")));
411
412 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBroadcastGood, GroupNonUniform,
413 Combine(Values("OpGroupNonUniformBroadcast",
414 "OpGroupNonUniformQuadBroadcast",
415 "OpGroupNonUniformQuadSwap"),
416 Values("%bool", "%u32", "%int", "%float",
417 "%u32vec4", "%u32vec3", "%v2bool",
418 "%v4float", "%v4int"),
419 Values(spv::Scope::Subgroup),
420 Values("match_res %u32_0"), Values("")));
421
422 INSTANTIATE_TEST_SUITE_P(
423 GroupNonUniformBroadcastShuffleBadResultType, GroupNonUniform,
424 Combine(Values("OpGroupNonUniformBroadcast", "OpGroupNonUniformShuffle",
425 "OpGroupNonUniformShuffleXor", "OpGroupNonUniformShuffleUp",
426 "OpGroupNonUniformShuffleDown",
427 "OpGroupNonUniformQuadBroadcast",
428 "OpGroupNonUniformQuadSwap"),
429 Values("%void", "%struct"), Values(spv::Scope::Subgroup),
430 Values("%u32_0 %u32_0"),
431 Values("Result must be a scalar or vector of integer, "
432 "floating-point, or boolean type")));
433
434 INSTANTIATE_TEST_SUITE_P(
435 GroupNonUniformBroadcastShuffleBadOperand1, GroupNonUniform,
436 Combine(Values("OpGroupNonUniformBroadcast", "OpGroupNonUniformShuffle",
437 "OpGroupNonUniformShuffleXor", "OpGroupNonUniformShuffleUp",
438 "OpGroupNonUniformShuffleDown",
439 "OpGroupNonUniformQuadBroadcast",
440 "OpGroupNonUniformQuadSwap"),
441 Values("%bool"), Values(spv::Scope::Subgroup),
442 Values("%u32_0 %u32_0", "%int_0 %u32_0", "%float_0 %u32_0",
443 "%u32vec4_null %u32_0", "%u32vec3_null %u32_0",
444 "%v2bool_false %u32_0", "%v4float_null %u32_0",
445 "%struct_null %u32_0", "%v4int_null %u32_0"),
446 Values("The type of Value must match the Result type")));
447
448 INSTANTIATE_TEST_SUITE_P(
449 GroupNonUniformBroadcastShuffleBadOperand2, GroupNonUniform,
450 Combine(Values("OpGroupNonUniformBroadcast", "OpGroupNonUniformShuffle",
451 "OpGroupNonUniformShuffleXor", "OpGroupNonUniformShuffleUp",
452 "OpGroupNonUniformShuffleDown",
453 "OpGroupNonUniformQuadBroadcast",
454 "OpGroupNonUniformQuadSwap"),
455 Values("%bool"), Values(spv::Scope::Subgroup),
456 Values("%true %true", "%true %int_0", "%true %float_0",
457 "%true %u32vec4_null", "%true %u32vec3_null",
458 "%true %v4float_null", "%true %v2bool_false",
459 "%true %struct_null", "%true %v4int_null"),
460 Values("must be an unsigned integer scalar")));
461
462 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBroadcastShuffleOperand2NotConstant,
463 GroupNonUniform,
464 Combine(Values("OpGroupNonUniformBroadcast",
465 "OpGroupNonUniformQuadBroadcast",
466 "OpGroupNonUniformQuadSwap"),
467 Values("%bool"), Values(spv::Scope::Subgroup),
468 Values("%true %u32_undef"),
469 Values("must be a constant instruction")));
470
471 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBroadcastFirstGood, GroupNonUniform,
472 Combine(Values("OpGroupNonUniformBroadcastFirst"),
473 Values("%bool", "%u32", "%int", "%float",
474 "%u32vec4", "%u32vec3", "%v2bool",
475 "%v4float", "%v4int"),
476 Values(spv::Scope::Subgroup),
477 Values("match_res"), Values("")));
478
479 INSTANTIATE_TEST_SUITE_P(
480 GroupNonUniformBroadcasFirsttBadResultType, GroupNonUniform,
481 Combine(Values("OpGroupNonUniformBroadcastFirst"),
482 Values("%void", "%struct"), Values(spv::Scope::Subgroup),
483 Values("%u32_0"),
484 Values("Result must be a scalar or vector of integer, "
485 "floating-point, or boolean type")));
486
487 INSTANTIATE_TEST_SUITE_P(
488 GroupNonUniformBroadcastBadOperand, GroupNonUniform,
489 Combine(Values("OpGroupNonUniformBroadcastFirst"), Values("%bool"),
490 Values(spv::Scope::Subgroup),
491 Values("%u32_0", "%int_0", "%float_0", "%u32vec4_null",
492 "%u32vec3_null", "%v2bool_false", "%v4float_null",
493 "%struct_null", "%v4int_null"),
494 Values("The type of Value must match the Result type")));
495
496 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotGood, GroupNonUniform,
497 Combine(Values("OpGroupNonUniformBallot"),
498 Values("%u32vec4"),
499 Values(spv::Scope::Subgroup),
500 Values("%true", "%false"), Values("")));
501
502 INSTANTIATE_TEST_SUITE_P(
503 GroupNonUniformBallotBadResultType, GroupNonUniform,
504 Combine(Values("OpGroupNonUniformBallot"),
505 Values("%void", "%bool", "%u32", "%int", "%float", "%u32vec3",
506 "%v2bool", "%v4float", "%struct", "%v4int"),
507 Values(spv::Scope::Subgroup), Values("%true", "%false"),
508 Values("Result must be a 4-component unsigned integer vector")));
509
510 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotBadOperand, GroupNonUniform,
511 Combine(Values("OpGroupNonUniformBallot"),
512 Values("%u32vec4"),
513 Values(spv::Scope::Subgroup),
514 Values("%u32_0", "%int_0", "%float_0",
515 "%u32vec4_null", "%u32vec3_null",
516 "%v2bool_false", "%v4float_null",
517 "%struct_null", "%v4int_null"),
518 Values("Predicate must be a boolean scalar")));
519
520 INSTANTIATE_TEST_SUITE_P(GroupNonUniformInverseBallotGood, GroupNonUniform,
521 Combine(Values("OpGroupNonUniformInverseBallot"),
522 Values("%bool"), Values(spv::Scope::Subgroup),
523 Values("%u32vec4_null"), Values("")));
524
525 INSTANTIATE_TEST_SUITE_P(
526 GroupNonUniformInverseBallotBadResultType, GroupNonUniform,
527 Combine(Values("OpGroupNonUniformInverseBallot"),
528 Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3",
529 "%v2bool", "%v4float", "%struct", "%v4int"),
530 Values(spv::Scope::Subgroup), Values("%u32vec4_null"),
531 Values("Result must be a boolean scalar")));
532
533 INSTANTIATE_TEST_SUITE_P(
534 GroupNonUniformInverseBallotBadOperand, GroupNonUniform,
535 Combine(Values("OpGroupNonUniformInverseBallot"), Values("%bool"),
536 Values(spv::Scope::Subgroup),
537 Values("%true", "%false", "%u32_0", "%int_0", "%float_0",
538 "%u32vec3_null", "%v2bool_false", "%v4float_null",
539 "%struct_null", "%v4int_null"),
540 Values("Value must be a 4-component unsigned integer vector")));
541
542 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotBitExtractGood, GroupNonUniform,
543 Combine(Values("OpGroupNonUniformBallotBitExtract"),
544 Values("%bool"), Values(spv::Scope::Subgroup),
545 Values("%u32vec4_null %u32_0"), Values("")));
546
547 INSTANTIATE_TEST_SUITE_P(
548 GroupNonUniformBallotBitExtractBadResultType, GroupNonUniform,
549 Combine(Values("OpGroupNonUniformBallotBitExtract"),
550 Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3",
551 "%v2bool", "%v4float", "%struct", "%v4int"),
552 Values(spv::Scope::Subgroup), Values("%u32vec4_null %u32_0"),
553 Values("Result must be a boolean scalar")));
554
555 INSTANTIATE_TEST_SUITE_P(
556 GroupNonUniformBallotBitExtractBadOperand1, GroupNonUniform,
557 Combine(Values("OpGroupNonUniformBallotBitExtract"), Values("%bool"),
558 Values(spv::Scope::Subgroup),
559 Values("%true %u32_0", "%false %u32_0", "%u32_0 %u32_0",
560 "%int_0 %u32_0", "%float_0 %u32_0", "%u32vec3_null %u32_0",
561 "%v2bool_false %u32_0", "%v4float_null %u32_0",
562 "%struct_null %u32_0", "%v4int_null %u32_0"),
563 Values("Value must be a 4-component unsigned integer vector")));
564
565 INSTANTIATE_TEST_SUITE_P(
566 GroupNonUniformBallotBitExtractBadOperand2, GroupNonUniform,
567 Combine(Values("OpGroupNonUniformBallotBitExtract"), Values("%bool"),
568 Values(spv::Scope::Subgroup),
569 Values("%u32vec4_null %true", "%u32vec4_null %false",
570 "%u32vec4_null %int_0", "%u32vec4_null %float_0",
571 "%u32vec4_null %u32vec3_null", "%u32vec4_null %v2bool_false",
572 "%u32vec4_null %v4float_null", "%u32vec4_null %struct_null",
573 "%u32vec4_null %v4int_null"),
574 Values("Id must be an unsigned integer scalar")));
575
576 INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotFindGood, GroupNonUniform,
577 Combine(Values("OpGroupNonUniformBallotFindLSB",
578 "OpGroupNonUniformBallotFindMSB"),
579 Values("%u32"), Values(spv::Scope::Subgroup),
580 Values("%u32vec4_null"), Values("")));
581
582 INSTANTIATE_TEST_SUITE_P(
583 GroupNonUniformBallotFindBadResultType, GroupNonUniform,
584 Combine(Values("OpGroupNonUniformBallotFindLSB",
585 "OpGroupNonUniformBallotFindMSB"),
586 Values("%void", "%bool", "%int", "%float", "%u32vec4", "%u32vec3",
587 "%v2bool", "%v4float", "%struct", "%v4int"),
588 Values(spv::Scope::Subgroup), Values("%u32vec4_null"),
589 Values("Result must be an unsigned integer scalar")));
590
591 INSTANTIATE_TEST_SUITE_P(
592 GroupNonUniformBallotFindBadOperand, GroupNonUniform,
593 Combine(Values("OpGroupNonUniformBallotFindLSB",
594 "OpGroupNonUniformBallotFindMSB"),
595 Values("%u32"), Values(spv::Scope::Subgroup),
596 Values("%true", "%false", "%u32_0", "%int_0", "%float_0",
597 "%u32vec3_null", "%v2bool_false", "%v4float_null",
598 "%struct_null", "%v4int_null"),
599 Values("Value must be a 4-component unsigned integer vector")));
600
601 INSTANTIATE_TEST_SUITE_P(
602 GroupNonUniformIntegerArithmeticGood, GroupNonUniform,
603 Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
604 "OpGroupNonUniformSMin", "OpGroupNonUniformSMax",
605 "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
606 "OpGroupNonUniformBitwiseXor"),
607 Values("%u32", "%int", "%u32vec4", "%u32vec3", "%v4int"),
608 Values(spv::Scope::Subgroup),
609 Values("Reduce match_res", "InclusiveScan match_res",
610 "ExclusiveScan match_res",
611 "ClusteredReduce match_res %u32_0",
612 "PartitionedReduceNV match_res %u32vec4_null",
613 "PartitionedInclusiveScanNV match_res %u32vec4_null",
614 "PartitionedExclusiveScanNV match_res %v4int_null"),
615 Values("")));
616
617 INSTANTIATE_TEST_SUITE_P(
618 GroupNonUniformIntegerArithmeticBadResultType, GroupNonUniform,
619 Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
620 "OpGroupNonUniformSMin", "OpGroupNonUniformSMax",
621 "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
622 "OpGroupNonUniformBitwiseXor"),
623 Values("%bool", "%float", "%v4float", "%struct"),
624 Values(spv::Scope::Subgroup),
625 Values("Reduce match_res", "InclusiveScan match_res",
626 "ExclusiveScan match_res",
627 "ClusteredReduce match_res %u32_0"),
628 Values("Result must be an integer scalar or vector")));
629
630 INSTANTIATE_TEST_SUITE_P(
631 GroupNonUniformIntegerArithmeticBadValue, GroupNonUniform,
632 Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
633 "OpGroupNonUniformSMin", "OpGroupNonUniformSMax",
634 "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
635 "OpGroupNonUniformBitwiseXor"),
636 Values("%int", "%u32vec4", "%u32vec3", "%v4int"),
637 Values(spv::Scope::Subgroup),
638 Values("Reduce %u32_0", "InclusiveScan %u32_0",
639 "ExclusiveScan %u32_0", "ClusteredReduce %u32_0 %u32_0"),
640 Values("The type of Value must match the Result type")));
641
642 INSTANTIATE_TEST_SUITE_P(
643 GroupNonUniformIntegerArithmeticMissingClusterSize, GroupNonUniform,
644 Combine(
645 Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
646 "OpGroupNonUniformSMin", "OpGroupNonUniformUMin",
647 "OpGroupNonUniformSMax", "OpGroupNonUniformUMax",
648 "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
649 "OpGroupNonUniformBitwiseXor"),
650 Values("%u32"), Values(spv::Scope::Subgroup),
651 Values("ClusteredReduce match_res"),
652 Values(
653 "ClusterSize must be present when Operation is ClusteredReduce")));
654
655 INSTANTIATE_TEST_SUITE_P(
656 GroupNonUniformIntegerArithmeticMissingBallot, GroupNonUniform,
657 Combine(
658 Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
659 "OpGroupNonUniformSMin", "OpGroupNonUniformUMin",
660 "OpGroupNonUniformSMax", "OpGroupNonUniformUMax",
661 "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
662 "OpGroupNonUniformBitwiseXor"),
663 Values("%u32"), Values(spv::Scope::Subgroup),
664 Values("PartitionedReduceNV match_res",
665 "PartitionedInclusiveScanNV match_res",
666 "PartitionedExclusiveScanNV match_res"),
667 Values("Ballot must be present when Operation is PartitionedReduceNV, "
668 "PartitionedInclusiveScanNV, or PartitionedExclusiveScanNV")));
669
670 INSTANTIATE_TEST_SUITE_P(
671 GroupNonUniformIntegerArithmeticBadClusterSizeType, GroupNonUniform,
672 Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
673 "OpGroupNonUniformSMin", "OpGroupNonUniformUMin",
674 "OpGroupNonUniformSMax", "OpGroupNonUniformUMax",
675 "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
676 "OpGroupNonUniformBitwiseXor"),
677 Values("%u32"), Values(spv::Scope::Subgroup),
678 Values("ClusteredReduce match_res %true",
679 "ClusteredReduce match_res %false",
680 "ClusteredReduce match_res %int_0",
681 "ClusteredReduce match_res %float_0",
682 "ClusteredReduce match_res %u32vec4_null",
683 "ClusteredReduce match_res %u32vec3_null",
684 "ClusteredReduce match_res %v2bool_false",
685 "ClusteredReduce match_res %v4float_null",
686 "ClusteredReduce match_res %struct_null",
687 "ClusteredReduce match_res %v4int_null"),
688 Values("ClusterSize must be an unsigned integer scalar")));
689
690 INSTANTIATE_TEST_SUITE_P(
691 GroupNonUniformIntegerArithmeticBadBallotType, GroupNonUniform,
692 Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
693 "OpGroupNonUniformSMin", "OpGroupNonUniformUMin",
694 "OpGroupNonUniformSMax", "OpGroupNonUniformUMax",
695 "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
696 "OpGroupNonUniformBitwiseXor"),
697 Values("%u32"), Values(spv::Scope::Subgroup),
698 Values("PartitionedReduceNV match_res %true",
699 "PartitionedReduceNV match_res %false",
700 "PartitionedReduceNV match_res %int_0",
701 "PartitionedReduceNV match_res %float_0",
702 "PartitionedReduceNV match_res %u32_0",
703 "PartitionedReduceNV match_res %u32vec3_null",
704 "PartitionedReduceNV match_res %v2bool_false",
705 "PartitionedReduceNV match_res %v4float_null",
706 "PartitionedReduceNV match_res %struct_null"),
707 Values("Ballot must be a 4-component integer vector")));
708
709 INSTANTIATE_TEST_SUITE_P(
710 GroupNonUniformIntegerArithmeticClusterSizeNotConstant, GroupNonUniform,
711 Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
712 "OpGroupNonUniformSMin", "OpGroupNonUniformUMin",
713 "OpGroupNonUniformSMax", "OpGroupNonUniformUMax",
714 "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
715 "OpGroupNonUniformBitwiseXor"),
716 Values("%u32"), Values(spv::Scope::Subgroup),
717 Values("ClusteredReduce match_res %u32_undef"),
718 Values("ClusterSize must be a constant instruction")));
719
720 INSTANTIATE_TEST_SUITE_P(
721 GroupNonUniformUnsignedIntegerArithmeticGood, GroupNonUniform,
722 Combine(Values("OpGroupNonUniformUMin", "OpGroupNonUniformUMax"),
723 Values("%u32", "%u32vec4", "%u32vec3"),
724 Values(spv::Scope::Subgroup),
725 Values("Reduce match_res", "InclusiveScan match_res",
726 "ExclusiveScan match_res",
727 "ClusteredReduce match_res %u32_0"),
728 Values("")));
729
730 INSTANTIATE_TEST_SUITE_P(
731 GroupNonUniformUnsignedIntegerArithmeticBadResultType, GroupNonUniform,
732 Combine(Values("OpGroupNonUniformUMin", "OpGroupNonUniformUMax"),
733 Values("%bool", "%int", "%float", "%v4float", "%struct", "%v4int"),
734 Values(spv::Scope::Subgroup),
735 Values("Reduce match_res", "InclusiveScan match_res",
736 "ExclusiveScan match_res",
737 "ClusteredReduce match_res %u32_0"),
738 Values("Result must be an unsigned integer scalar or vector")));
739
740 INSTANTIATE_TEST_SUITE_P(
741 GroupNonUniformUnsignedIntegerArithmeticBadValue, GroupNonUniform,
742 Combine(Values("OpGroupNonUniformUMin", "OpGroupNonUniformUMax"),
743 Values("%u32vec4", "%u32vec3"), Values(spv::Scope::Subgroup),
744 Values("Reduce %u32_0", "InclusiveScan %u32_0",
745 "ExclusiveScan %u32_0", "ClusteredReduce %u32_0 %u32_0"),
746 Values("The type of Value must match the Result type")));
747
748 INSTANTIATE_TEST_SUITE_P(
749 GroupNonUniformFloatArithmeticGood, GroupNonUniform,
750 Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
751 "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
752 Values("%float", "%v4float"), Values(spv::Scope::Subgroup),
753 Values("Reduce match_res", "InclusiveScan match_res",
754 "ExclusiveScan match_res",
755 "ClusteredReduce match_res %u32_0"),
756 Values("")));
757
758 INSTANTIATE_TEST_SUITE_P(
759 GroupNonUniformFloatArithmeticBadResultType, GroupNonUniform,
760 Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
761 "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
762 Values("%bool", "%u32", "%int", "%u32vec4", "%u32vec3", "%struct",
763 "%v4int"),
764 Values(spv::Scope::Subgroup),
765 Values("Reduce match_res", "InclusiveScan match_res",
766 "ExclusiveScan match_res",
767 "ClusteredReduce match_res %u32_0"),
768 Values("Result must be a floating-point scalar or vector")));
769
770 INSTANTIATE_TEST_SUITE_P(
771 GroupNonUniformFloatArithmeticBadValue, GroupNonUniform,
772 Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
773 "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
774 Values("%v4float"), Values(spv::Scope::Subgroup),
775 Values("Reduce %float_0", "InclusiveScan %float_0",
776 "ExclusiveScan %float_0", "ClusteredReduce %float_0 %u32_0"),
777 Values("The type of Value must match the Result type")));
778
779 INSTANTIATE_TEST_SUITE_P(
780 GroupNonUniformFloatArithmeticMissingClusterSize, GroupNonUniform,
781 Combine(
782 Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
783 "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
784 Values("%float"), Values(spv::Scope::Subgroup),
785 Values("ClusteredReduce match_res"),
786 Values(
787 "ClusterSize must be present when Operation is ClusteredReduce")));
788
789 INSTANTIATE_TEST_SUITE_P(
790 GroupNonUniformFloatArithmeticBadClusterSizeType, GroupNonUniform,
791 Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
792 "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
793 Values("%float"), Values(spv::Scope::Subgroup),
794 Values("ClusteredReduce match_res %true",
795 "ClusteredReduce match_res %false",
796 "ClusteredReduce match_res %int_0",
797 "ClusteredReduce match_res %float_0",
798 "ClusteredReduce match_res %u32vec4_null",
799 "ClusteredReduce match_res %u32vec3_null",
800 "ClusteredReduce match_res %v2bool_false",
801 "ClusteredReduce match_res %v4float_null",
802 "ClusteredReduce match_res %struct_null",
803 "ClusteredReduce match_res %v4int_null"),
804 Values("ClusterSize must be an unsigned integer scalar")));
805
806 INSTANTIATE_TEST_SUITE_P(
807 GroupNonUniformFloatArithmeticClusterSizeNotConstant, GroupNonUniform,
808 Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
809 "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
810 Values("%float"), Values(spv::Scope::Subgroup),
811 Values("ClusteredReduce match_res %u32_undef"),
812 Values("ClusterSize must be a constant instruction")));
813
814 INSTANTIATE_TEST_SUITE_P(
815 GroupNonUniformBooleanArithmeticGood, GroupNonUniform,
816 Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr",
817 "OpGroupNonUniformLogicalXor"),
818 Values("%bool", "%v2bool"), Values(spv::Scope::Subgroup),
819 Values("Reduce match_res", "InclusiveScan match_res",
820 "ExclusiveScan match_res",
821 "ClusteredReduce match_res %u32_0"),
822 Values("")));
823
824 INSTANTIATE_TEST_SUITE_P(
825 GroupNonUniformBooleanArithmeticBadResultType, GroupNonUniform,
826 Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr",
827 "OpGroupNonUniformLogicalXor"),
828 Values("%u32", "%int", "%float", "%u32vec4", "%u32vec3", "%struct",
829 "%v4float", "%v4int"),
830 Values(spv::Scope::Subgroup),
831 Values("Reduce match_res", "InclusiveScan match_res",
832 "ExclusiveScan match_res",
833 "ClusteredReduce match_res %u32_0"),
834 Values("Result must be a boolean scalar or vector")));
835
836 INSTANTIATE_TEST_SUITE_P(
837 GroupNonUniformBooleanArithmeticBadValue, GroupNonUniform,
838 Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr",
839 "OpGroupNonUniformLogicalXor"),
840 Values("%v2bool"), Values(spv::Scope::Subgroup),
841 Values("Reduce %true", "InclusiveScan %true",
842 "ExclusiveScan %false", "ClusteredReduce %false %u32_0"),
843 Values("The type of Value must match the Result type")));
844
845 INSTANTIATE_TEST_SUITE_P(
846 GroupNonUniformBooleanArithmeticMissingClusterSize, GroupNonUniform,
847 Combine(
848 Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr",
849 "OpGroupNonUniformLogicalXor"),
850 Values("%bool"), Values(spv::Scope::Subgroup),
851 Values("ClusteredReduce match_res"),
852 Values(
853 "ClusterSize must be present when Operation is ClusteredReduce")));
854
855 INSTANTIATE_TEST_SUITE_P(
856 GroupNonUniformBooleanArithmeticBadClusterSizeType, GroupNonUniform,
857 Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr",
858 "OpGroupNonUniformLogicalXor"),
859 Values("%bool"), Values(spv::Scope::Subgroup),
860 Values("ClusteredReduce match_res %true",
861 "ClusteredReduce match_res %false",
862 "ClusteredReduce match_res %int_0",
863 "ClusteredReduce match_res %float_0",
864 "ClusteredReduce match_res %u32vec4_null",
865 "ClusteredReduce match_res %u32vec3_null",
866 "ClusteredReduce match_res %v2bool_false",
867 "ClusteredReduce match_res %v4float_null",
868 "ClusteredReduce match_res %struct_null",
869 "ClusteredReduce match_res %v4int_null"),
870 Values("ClusterSize must be an unsigned integer scalar")));
871
872 INSTANTIATE_TEST_SUITE_P(
873 GroupNonUniformBooleanArithmeticClusterSizeNotConstant, GroupNonUniform,
874 Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr",
875 "OpGroupNonUniformLogicalXor"),
876 Values("%bool"), Values(spv::Scope::Subgroup),
877 Values("ClusteredReduce match_res %u32_undef"),
878 Values("ClusterSize must be a constant instruction")));
879
880 // Subgroup scope is not actual parameter, but used for test expectations,
881 INSTANTIATE_TEST_SUITE_P(GroupNonUniformQuadAllKHR, GroupNonUniform,
882 Combine(Values("OpGroupNonUniformQuadAllKHR"),
883 Values("%bool"), Values(spv::Scope::Subgroup),
884 Values("%true"), Values("")));
885
886 // Subgroup scope is not actual parameter, but used for test expectations,
887 INSTANTIATE_TEST_SUITE_P(GroupNonUniformQuadAnyKHR, GroupNonUniform,
888 Combine(Values("OpGroupNonUniformQuadAnyKHR"),
889 Values("%bool"), Values(spv::Scope::Subgroup),
890 Values("%true"), Values("")));
891
TEST_F(ValidateGroupNonUniform,VulkanGroupNonUniformBallotBitCountOperation)892 TEST_F(ValidateGroupNonUniform, VulkanGroupNonUniformBallotBitCountOperation) {
893 std::string test = R"(
894 OpCapability Shader
895 OpCapability GroupNonUniform
896 OpCapability GroupNonUniformBallot
897 OpCapability GroupNonUniformClustered
898 OpMemoryModel Logical GLSL450
899 OpEntryPoint GLCompute %main "main"
900 OpExecutionMode %main LocalSize 1 1 1
901 %void = OpTypeVoid
902 %func = OpTypeFunction %void
903 %u32 = OpTypeInt 32 0
904 %u32vec4 = OpTypeVector %u32 4
905 %u32_0 = OpConstant %u32 0
906 %u32vec4_null = OpConstantComposite %u32vec4 %u32_0 %u32_0 %u32_0 %u32_0
907 %subgroup = OpConstant %u32 3
908 %main = OpFunction %void None %func
909 %main_entry = OpLabel
910 %result = OpGroupNonUniformBallotBitCount %u32 %subgroup ClusteredReduce %u32vec4_null
911 OpReturn
912 OpFunctionEnd
913 )";
914
915 CompileSuccessfully(test, SPV_ENV_VULKAN_1_1);
916 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1));
917 EXPECT_THAT(
918 getDiagnosticString(),
919 AnyVUID("VUID-StandaloneSpirv-OpGroupNonUniformBallotBitCount-04685"));
920 EXPECT_THAT(
921 getDiagnosticString(),
922 HasSubstr(
923 "In Vulkan: The OpGroupNonUniformBallotBitCount group operation must "
924 "be only: Reduce, InclusiveScan, or ExclusiveScan."));
925 }
926
TEST_F(ValidateGroupNonUniform,BroadcastNonConstantSpv1p4)927 TEST_F(ValidateGroupNonUniform, BroadcastNonConstantSpv1p4) {
928 const std::string text = R"(
929 OpCapability Shader
930 OpCapability GroupNonUniformBallot
931 OpMemoryModel Logical GLSL450
932 OpEntryPoint GLCompute %main "main" %var
933 OpExecutionMode %main LocalSize 1 1 1
934 OpDecorate %var DescriptorSet 0
935 OpDecorate %var Binding 0
936 OpDecorate %struct Block
937 OpMemberDecorate %struct 0 Offset 0
938 %void = OpTypeVoid
939 %int = OpTypeInt 32 0
940 %int_0 = OpConstant %int 0
941 %subgroup = OpConstant %int 3
942 %struct = OpTypeStruct %int
943 %ptr_struct = OpTypePointer StorageBuffer %struct
944 %ptr_int = OpTypePointer StorageBuffer %int
945 %var = OpVariable %ptr_struct StorageBuffer
946 %void_fn = OpTypeFunction %void
947 %main = OpFunction %void None %void_fn
948 %entry = OpLabel
949 %gep = OpAccessChain %ptr_int %var %int_0
950 %ld = OpLoad %int %gep
951 %broadcast = OpGroupNonUniformBroadcast %int %subgroup %int_0 %ld
952 OpReturn
953 OpFunctionEnd
954 )";
955
956 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
957 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
958 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
959 EXPECT_THAT(
960 getDiagnosticString(),
961 HasSubstr("Before SPIR-V 1.5, Id must be a constant instruction"));
962 }
963
TEST_F(ValidateGroupNonUniform,BroadcastNonConstantSpv1p5)964 TEST_F(ValidateGroupNonUniform, BroadcastNonConstantSpv1p5) {
965 const std::string text = R"(
966 OpCapability Shader
967 OpCapability GroupNonUniformBallot
968 OpMemoryModel Logical GLSL450
969 OpEntryPoint GLCompute %main "main" %var
970 OpExecutionMode %main LocalSize 1 1 1
971 OpDecorate %var DescriptorSet 0
972 OpDecorate %var Binding 0
973 OpDecorate %struct Block
974 OpMemberDecorate %struct 0 Offset 0
975 %void = OpTypeVoid
976 %int = OpTypeInt 32 0
977 %int_0 = OpConstant %int 0
978 %subgroup = OpConstant %int 3
979 %struct = OpTypeStruct %int
980 %ptr_struct = OpTypePointer StorageBuffer %struct
981 %ptr_int = OpTypePointer StorageBuffer %int
982 %var = OpVariable %ptr_struct StorageBuffer
983 %void_fn = OpTypeFunction %void
984 %main = OpFunction %void None %void_fn
985 %entry = OpLabel
986 %gep = OpAccessChain %ptr_int %var %int_0
987 %ld = OpLoad %int %gep
988 %broadcast = OpGroupNonUniformBroadcast %int %subgroup %int_0 %ld
989 OpReturn
990 OpFunctionEnd
991 )";
992
993 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_5);
994 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
995 }
996
TEST_F(ValidateGroupNonUniform,QuadBroadcastNonConstantSpv1p4)997 TEST_F(ValidateGroupNonUniform, QuadBroadcastNonConstantSpv1p4) {
998 const std::string text = R"(
999 OpCapability Shader
1000 OpCapability GroupNonUniformQuad
1001 OpMemoryModel Logical GLSL450
1002 OpEntryPoint GLCompute %main "main" %var
1003 OpExecutionMode %main LocalSize 1 1 1
1004 OpDecorate %var DescriptorSet 0
1005 OpDecorate %var Binding 0
1006 OpDecorate %struct Block
1007 OpMemberDecorate %struct 0 Offset 0
1008 %void = OpTypeVoid
1009 %int = OpTypeInt 32 0
1010 %int_0 = OpConstant %int 0
1011 %subgroup = OpConstant %int 3
1012 %struct = OpTypeStruct %int
1013 %ptr_struct = OpTypePointer StorageBuffer %struct
1014 %ptr_int = OpTypePointer StorageBuffer %int
1015 %var = OpVariable %ptr_struct StorageBuffer
1016 %void_fn = OpTypeFunction %void
1017 %main = OpFunction %void None %void_fn
1018 %entry = OpLabel
1019 %gep = OpAccessChain %ptr_int %var %int_0
1020 %ld = OpLoad %int %gep
1021 %broadcast = OpGroupNonUniformQuadBroadcast %int %subgroup %int_0 %ld
1022 OpReturn
1023 OpFunctionEnd
1024 )";
1025
1026 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
1027 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1028 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
1029 EXPECT_THAT(
1030 getDiagnosticString(),
1031 HasSubstr("Before SPIR-V 1.5, Index must be a constant instruction"));
1032 }
1033
TEST_F(ValidateGroupNonUniform,QuadBroadcastNonConstantSpv1p5)1034 TEST_F(ValidateGroupNonUniform, QuadBroadcastNonConstantSpv1p5) {
1035 const std::string text = R"(
1036 OpCapability Shader
1037 OpCapability GroupNonUniformQuad
1038 OpMemoryModel Logical GLSL450
1039 OpEntryPoint GLCompute %main "main" %var
1040 OpExecutionMode %main LocalSize 1 1 1
1041 OpDecorate %var DescriptorSet 0
1042 OpDecorate %var Binding 0
1043 OpDecorate %struct Block
1044 OpMemberDecorate %struct 0 Offset 0
1045 %void = OpTypeVoid
1046 %int = OpTypeInt 32 0
1047 %int_0 = OpConstant %int 0
1048 %subgroup = OpConstant %int 3
1049 %struct = OpTypeStruct %int
1050 %ptr_struct = OpTypePointer StorageBuffer %struct
1051 %ptr_int = OpTypePointer StorageBuffer %int
1052 %var = OpVariable %ptr_struct StorageBuffer
1053 %void_fn = OpTypeFunction %void
1054 %main = OpFunction %void None %void_fn
1055 %entry = OpLabel
1056 %gep = OpAccessChain %ptr_int %var %int_0
1057 %ld = OpLoad %int %gep
1058 %broadcast = OpGroupNonUniformQuadBroadcast %int %subgroup %int_0 %ld
1059 OpReturn
1060 OpFunctionEnd
1061 )";
1062
1063 CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_5);
1064 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
1065 }
1066
1067 } // namespace
1068 } // namespace val
1069 } // namespace spvtools
1070