• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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