1 // Copyright (c) 2017 Google Inc.
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 // Tests validation rules of GLSL.450.std and OpenCL.std extended instructions.
16 // Doesn't test OpenCL.std vector size 2, 3, 4, 8 or 16 rules (not supported
17 // by standard SPIR-V).
18
19 #include <sstream>
20 #include <string>
21 #include <vector>
22
23 #include "gmock/gmock.h"
24 #include "test/unit_spirv.h"
25 #include "test/val/val_fixtures.h"
26
27 namespace spvtools {
28 namespace val {
29 namespace {
30
31 using ::testing::Eq;
32 using ::testing::HasSubstr;
33 using ::testing::Not;
34
35 using ValidateExtInst = spvtest::ValidateBase<bool>;
36 using ValidateOldDebugInfo = spvtest::ValidateBase<std::string>;
37 using ValidateOpenCL100DebugInfo = spvtest::ValidateBase<std::string>;
38 using ValidateLocalDebugInfoOutOfFunction = spvtest::ValidateBase<std::string>;
39 using ValidateOpenCL100DebugInfoDebugTypedef =
40 spvtest::ValidateBase<std::pair<std::string, std::string>>;
41 using ValidateOpenCL100DebugInfoDebugTypeEnum =
42 spvtest::ValidateBase<std::pair<std::string, std::string>>;
43 using ValidateOpenCL100DebugInfoDebugTypeComposite =
44 spvtest::ValidateBase<std::pair<std::string, std::string>>;
45 using ValidateOpenCL100DebugInfoDebugTypeMember =
46 spvtest::ValidateBase<std::pair<std::string, std::string>>;
47 using ValidateOpenCL100DebugInfoDebugTypeInheritance =
48 spvtest::ValidateBase<std::pair<std::string, std::string>>;
49 using ValidateOpenCL100DebugInfoDebugFunction =
50 spvtest::ValidateBase<std::pair<std::string, std::string>>;
51 using ValidateOpenCL100DebugInfoDebugFunctionDeclaration =
52 spvtest::ValidateBase<std::pair<std::string, std::string>>;
53 using ValidateOpenCL100DebugInfoDebugLexicalBlock =
54 spvtest::ValidateBase<std::pair<std::string, std::string>>;
55 using ValidateOpenCL100DebugInfoDebugLocalVariable =
56 spvtest::ValidateBase<std::pair<std::string, std::string>>;
57 using ValidateOpenCL100DebugInfoDebugGlobalVariable =
58 spvtest::ValidateBase<std::pair<std::string, std::string>>;
59 using ValidateOpenCL100DebugInfoDebugDeclare =
60 spvtest::ValidateBase<std::pair<std::string, std::string>>;
61 using ValidateOpenCL100DebugInfoDebugValue =
62 spvtest::ValidateBase<std::pair<std::string, std::string>>;
63 using ValidateGlslStd450SqrtLike = spvtest::ValidateBase<std::string>;
64 using ValidateGlslStd450FMinLike = spvtest::ValidateBase<std::string>;
65 using ValidateGlslStd450FClampLike = spvtest::ValidateBase<std::string>;
66 using ValidateGlslStd450SAbsLike = spvtest::ValidateBase<std::string>;
67 using ValidateGlslStd450UMinLike = spvtest::ValidateBase<std::string>;
68 using ValidateGlslStd450UClampLike = spvtest::ValidateBase<std::string>;
69 using ValidateGlslStd450SinLike = spvtest::ValidateBase<std::string>;
70 using ValidateGlslStd450PowLike = spvtest::ValidateBase<std::string>;
71 using ValidateGlslStd450Pack = spvtest::ValidateBase<std::string>;
72 using ValidateGlslStd450Unpack = spvtest::ValidateBase<std::string>;
73 using ValidateOpenCLStdSqrtLike = spvtest::ValidateBase<std::string>;
74 using ValidateOpenCLStdFMinLike = spvtest::ValidateBase<std::string>;
75 using ValidateOpenCLStdFClampLike = spvtest::ValidateBase<std::string>;
76 using ValidateOpenCLStdSAbsLike = spvtest::ValidateBase<std::string>;
77 using ValidateOpenCLStdUMinLike = spvtest::ValidateBase<std::string>;
78 using ValidateOpenCLStdUClampLike = spvtest::ValidateBase<std::string>;
79 using ValidateOpenCLStdUMul24Like = spvtest::ValidateBase<std::string>;
80 using ValidateOpenCLStdUMad24Like = spvtest::ValidateBase<std::string>;
81 using ValidateOpenCLStdLengthLike = spvtest::ValidateBase<std::string>;
82 using ValidateOpenCLStdDistanceLike = spvtest::ValidateBase<std::string>;
83 using ValidateOpenCLStdNormalizeLike = spvtest::ValidateBase<std::string>;
84 using ValidateOpenCLStdVStoreHalfLike = spvtest::ValidateBase<std::string>;
85 using ValidateOpenCLStdVLoadHalfLike = spvtest::ValidateBase<std::string>;
86 using ValidateOpenCLStdFractLike = spvtest::ValidateBase<std::string>;
87 using ValidateOpenCLStdFrexpLike = spvtest::ValidateBase<std::string>;
88 using ValidateOpenCLStdLdexpLike = spvtest::ValidateBase<std::string>;
89 using ValidateOpenCLStdUpsampleLike = spvtest::ValidateBase<std::string>;
90 using ValidateClspvReflection = spvtest::ValidateBase<bool>;
91
92 // Returns number of components in Pack/Unpack extended instructions.
93 // |ext_inst_name| is expected to be of the format "PackHalf2x16".
94 // Number of components is assumed to be single-digit.
GetPackedNumComponents(const std::string & ext_inst_name)95 uint32_t GetPackedNumComponents(const std::string& ext_inst_name) {
96 const size_t x_index = ext_inst_name.find_last_of('x');
97 const std::string num_components_str =
98 ext_inst_name.substr(x_index - 1, x_index);
99 return uint32_t(std::stoul(num_components_str));
100 }
101
102 // Returns packed bit width in Pack/Unpack extended instructions.
103 // |ext_inst_name| is expected to be of the format "PackHalf2x16".
GetPackedBitWidth(const std::string & ext_inst_name)104 uint32_t GetPackedBitWidth(const std::string& ext_inst_name) {
105 const size_t x_index = ext_inst_name.find_last_of('x');
106 const std::string packed_bit_width_str = ext_inst_name.substr(x_index + 1);
107 return uint32_t(std::stoul(packed_bit_width_str));
108 }
109
GenerateShaderCode(const std::string & body,const std::string & capabilities_and_extensions="",const std::string & execution_model="Fragment")110 std::string GenerateShaderCode(
111 const std::string& body,
112 const std::string& capabilities_and_extensions = "",
113 const std::string& execution_model = "Fragment") {
114 std::ostringstream ss;
115 ss << R"(
116 OpCapability Shader
117 OpCapability Float16
118 OpCapability Float64
119 OpCapability Int16
120 OpCapability Int64
121 )";
122
123 ss << capabilities_and_extensions;
124 ss << "%extinst = OpExtInstImport \"GLSL.std.450\"\n";
125 ss << "OpMemoryModel Logical GLSL450\n";
126 ss << "OpEntryPoint " << execution_model << " %main \"main\""
127 << " %f32_output"
128 << " %f32vec2_output"
129 << " %u32_output"
130 << " %u32vec2_output"
131 << " %u64_output"
132 << " %f32_input"
133 << " %f32vec2_input"
134 << " %u32_input"
135 << " %u32vec2_input"
136 << " %u64_input"
137 << "\n";
138 if (execution_model == "Fragment") {
139 ss << "OpExecutionMode %main OriginUpperLeft\n";
140 }
141
142 ss << R"(
143 %void = OpTypeVoid
144 %func = OpTypeFunction %void
145 %bool = OpTypeBool
146 %f16 = OpTypeFloat 16
147 %f32 = OpTypeFloat 32
148 %f64 = OpTypeFloat 64
149 %u32 = OpTypeInt 32 0
150 %s32 = OpTypeInt 32 1
151 %u64 = OpTypeInt 64 0
152 %s64 = OpTypeInt 64 1
153 %u16 = OpTypeInt 16 0
154 %s16 = OpTypeInt 16 1
155 %f32vec2 = OpTypeVector %f32 2
156 %f32vec3 = OpTypeVector %f32 3
157 %f32vec4 = OpTypeVector %f32 4
158 %f64vec2 = OpTypeVector %f64 2
159 %f64vec3 = OpTypeVector %f64 3
160 %f64vec4 = OpTypeVector %f64 4
161 %u32vec2 = OpTypeVector %u32 2
162 %u32vec3 = OpTypeVector %u32 3
163 %s32vec2 = OpTypeVector %s32 2
164 %u32vec4 = OpTypeVector %u32 4
165 %s32vec4 = OpTypeVector %s32 4
166 %u64vec2 = OpTypeVector %u64 2
167 %s64vec2 = OpTypeVector %s64 2
168 %f64mat22 = OpTypeMatrix %f64vec2 2
169 %f32mat22 = OpTypeMatrix %f32vec2 2
170 %f32mat23 = OpTypeMatrix %f32vec2 3
171 %f32mat32 = OpTypeMatrix %f32vec3 2
172 %f32mat33 = OpTypeMatrix %f32vec3 3
173
174 %f32_0 = OpConstant %f32 0
175 %f32_1 = OpConstant %f32 1
176 %f32_2 = OpConstant %f32 2
177 %f32_3 = OpConstant %f32 3
178 %f32_4 = OpConstant %f32 4
179 %f32_h = OpConstant %f32 0.5
180 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
181 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
182 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
183 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
184 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
185 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
186
187 %f64_0 = OpConstant %f64 0
188 %f64_1 = OpConstant %f64 1
189 %f64_2 = OpConstant %f64 2
190 %f64_3 = OpConstant %f64 3
191 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
192 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
193 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
194
195 %f16_0 = OpConstant %f16 0
196 %f16_1 = OpConstant %f16 1
197 %f16_h = OpConstant %f16 0.5
198
199 %u32_0 = OpConstant %u32 0
200 %u32_1 = OpConstant %u32 1
201 %u32_2 = OpConstant %u32 2
202 %u32_3 = OpConstant %u32 3
203
204 %s32_0 = OpConstant %s32 0
205 %s32_1 = OpConstant %s32 1
206 %s32_2 = OpConstant %s32 2
207 %s32_3 = OpConstant %s32 3
208
209 %u64_0 = OpConstant %u64 0
210 %u64_1 = OpConstant %u64 1
211 %u64_2 = OpConstant %u64 2
212 %u64_3 = OpConstant %u64 3
213
214 %s64_0 = OpConstant %s64 0
215 %s64_1 = OpConstant %s64 1
216 %s64_2 = OpConstant %s64 2
217 %s64_3 = OpConstant %s64 3
218
219 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
220 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
221
222 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
223 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
224
225 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
226 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
227
228 %s64vec2_01 = OpConstantComposite %s64vec2 %s64_0 %s64_1
229 %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
230
231 %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
232 %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
233
234 %f32_ptr_output = OpTypePointer Output %f32
235 %f32vec2_ptr_output = OpTypePointer Output %f32vec2
236
237 %u32_ptr_output = OpTypePointer Output %u32
238 %u32vec2_ptr_output = OpTypePointer Output %u32vec2
239
240 %u64_ptr_output = OpTypePointer Output %u64
241
242 %f32_output = OpVariable %f32_ptr_output Output
243 %f32vec2_output = OpVariable %f32vec2_ptr_output Output
244
245 %u32_output = OpVariable %u32_ptr_output Output
246 %u32vec2_output = OpVariable %u32vec2_ptr_output Output
247
248 %u64_output = OpVariable %u64_ptr_output Output
249
250 %f32_ptr_input = OpTypePointer Input %f32
251 %f32vec2_ptr_input = OpTypePointer Input %f32vec2
252
253 %u32_ptr_input = OpTypePointer Input %u32
254 %u32vec2_ptr_input = OpTypePointer Input %u32vec2
255
256 %u64_ptr_input = OpTypePointer Input %u64
257
258 %f32_input = OpVariable %f32_ptr_input Input
259 %f32vec2_input = OpVariable %f32vec2_ptr_input Input
260
261 %u32_input = OpVariable %u32_ptr_input Input
262 %u32vec2_input = OpVariable %u32vec2_ptr_input Input
263
264 %u64_input = OpVariable %u64_ptr_input Input
265
266 %struct_f16_u16 = OpTypeStruct %f16 %u16
267 %struct_f32_f32 = OpTypeStruct %f32 %f32
268 %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
269 %struct_f32_u32 = OpTypeStruct %f32 %u32
270 %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
271 %struct_u32_f32 = OpTypeStruct %u32 %f32
272 %struct_u32_u32 = OpTypeStruct %u32 %u32
273 %struct_f32_f64 = OpTypeStruct %f32 %f64
274 %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
275 %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
276
277 %main = OpFunction %void None %func
278 %main_entry = OpLabel
279 )";
280
281 ss << body;
282
283 ss << R"(
284 OpReturn
285 OpFunctionEnd)";
286
287 return ss.str();
288 }
289
GenerateKernelCode(const std::string & body,const std::string & capabilities_and_extensions="",const std::string & memory_model="Physical32")290 std::string GenerateKernelCode(
291 const std::string& body,
292 const std::string& capabilities_and_extensions = "",
293 const std::string& memory_model = "Physical32") {
294 std::ostringstream ss;
295 ss << R"(
296 OpCapability Addresses
297 OpCapability Kernel
298 OpCapability Linkage
299 OpCapability GenericPointer
300 OpCapability Int8
301 OpCapability Int16
302 OpCapability Int64
303 OpCapability Float16
304 OpCapability Float64
305 OpCapability Vector16
306 OpCapability Matrix
307 )";
308
309 ss << capabilities_and_extensions;
310 ss << "%extinst = OpExtInstImport \"OpenCL.std\"\n";
311 ss << "OpMemoryModel " << memory_model << " OpenCL\n";
312
313 ss << R"(
314 %void = OpTypeVoid
315 %func = OpTypeFunction %void
316 %bool = OpTypeBool
317 %f16 = OpTypeFloat 16
318 %f32 = OpTypeFloat 32
319 %f64 = OpTypeFloat 64
320 %u32 = OpTypeInt 32 0
321 %u64 = OpTypeInt 64 0
322 %u16 = OpTypeInt 16 0
323 %u8 = OpTypeInt 8 0
324 %f32vec2 = OpTypeVector %f32 2
325 %f32vec3 = OpTypeVector %f32 3
326 %f32vec4 = OpTypeVector %f32 4
327 %f32vec8 = OpTypeVector %f32 8
328 %f16vec8 = OpTypeVector %f16 8
329 %f32vec16 = OpTypeVector %f32 16
330 %f64vec2 = OpTypeVector %f64 2
331 %f64vec3 = OpTypeVector %f64 3
332 %f64vec4 = OpTypeVector %f64 4
333 %u32vec2 = OpTypeVector %u32 2
334 %u32vec3 = OpTypeVector %u32 3
335 %u32vec4 = OpTypeVector %u32 4
336 %u32vec8 = OpTypeVector %u32 8
337 %u64vec2 = OpTypeVector %u64 2
338 %f64mat22 = OpTypeMatrix %f64vec2 2
339 %f32mat22 = OpTypeMatrix %f32vec2 2
340 %f32mat23 = OpTypeMatrix %f32vec2 3
341 %f32mat32 = OpTypeMatrix %f32vec3 2
342 %f32mat33 = OpTypeMatrix %f32vec3 3
343
344 %f32_0 = OpConstant %f32 0
345 %f32_1 = OpConstant %f32 1
346 %f32_2 = OpConstant %f32 2
347 %f32_3 = OpConstant %f32 3
348 %f32_4 = OpConstant %f32 4
349 %f32_h = OpConstant %f32 0.5
350 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
351 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
352 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
353 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
354 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
355 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
356 %f32vec8_01010101 = OpConstantComposite %f32vec8 %f32_0 %f32_1 %f32_0 %f32_1 %f32_0 %f32_1 %f32_0 %f32_1
357
358 %f64_0 = OpConstant %f64 0
359 %f64_1 = OpConstant %f64 1
360 %f64_2 = OpConstant %f64 2
361 %f64_3 = OpConstant %f64 3
362 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
363 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
364 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
365
366 %f16_0 = OpConstant %f16 0
367 %f16_1 = OpConstant %f16 1
368
369 %u8_0 = OpConstant %u8 0
370 %u8_1 = OpConstant %u8 1
371 %u8_2 = OpConstant %u8 2
372 %u8_3 = OpConstant %u8 3
373
374 %u16_0 = OpConstant %u16 0
375 %u16_1 = OpConstant %u16 1
376 %u16_2 = OpConstant %u16 2
377 %u16_3 = OpConstant %u16 3
378
379 %u32_0 = OpConstant %u32 0
380 %u32_1 = OpConstant %u32 1
381 %u32_2 = OpConstant %u32 2
382 %u32_3 = OpConstant %u32 3
383 %u32_256 = OpConstant %u32 256
384
385 %u64_0 = OpConstant %u64 0
386 %u64_1 = OpConstant %u64 1
387 %u64_2 = OpConstant %u64 2
388 %u64_3 = OpConstant %u64 3
389 %u64_256 = OpConstant %u64 256
390
391 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
392 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
393 %u32vec3_012 = OpConstantComposite %u32vec3 %u32_0 %u32_1 %u32_2
394 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
395
396 %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
397
398 %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
399 %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
400
401 %struct_f32_f32 = OpTypeStruct %f32 %f32
402 %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
403 %struct_f32_u32 = OpTypeStruct %f32 %u32
404 %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
405 %struct_u32_f32 = OpTypeStruct %u32 %f32
406 %struct_u32_u32 = OpTypeStruct %u32 %u32
407 %struct_f32_f64 = OpTypeStruct %f32 %f64
408 %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
409 %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
410
411 %f16vec8_ptr_workgroup = OpTypePointer Workgroup %f16vec8
412 %f16vec8_workgroup = OpVariable %f16vec8_ptr_workgroup Workgroup
413 %f16_ptr_workgroup = OpTypePointer Workgroup %f16
414
415 %u32vec8_ptr_workgroup = OpTypePointer Workgroup %u32vec8
416 %u32vec8_workgroup = OpVariable %u32vec8_ptr_workgroup Workgroup
417 %u32_ptr_workgroup = OpTypePointer Workgroup %u32
418
419 %f32vec8_ptr_workgroup = OpTypePointer Workgroup %f32vec8
420 %f32vec8_workgroup = OpVariable %f32vec8_ptr_workgroup Workgroup
421 %f32_ptr_workgroup = OpTypePointer Workgroup %f32
422
423 %u32arr = OpTypeArray %u32 %u32_256
424 %u32arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %u32arr
425 %u32arr_cross_workgroup = OpVariable %u32arr_ptr_cross_workgroup CrossWorkgroup
426 %u32_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %u32
427
428 %f32arr = OpTypeArray %f32 %u32_256
429 %f32arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32arr
430 %f32arr_cross_workgroup = OpVariable %f32arr_ptr_cross_workgroup CrossWorkgroup
431 %f32_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32
432
433 %f32vec2arr = OpTypeArray %f32vec2 %u32_256
434 %f32vec2arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32vec2arr
435 %f32vec2arr_cross_workgroup = OpVariable %f32vec2arr_ptr_cross_workgroup CrossWorkgroup
436 %f32vec2_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %f32vec2
437
438 %struct_arr = OpTypeArray %struct_f32_f32 %u32_256
439 %struct_arr_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %struct_arr
440 %struct_arr_cross_workgroup = OpVariable %struct_arr_ptr_cross_workgroup CrossWorkgroup
441 %struct_ptr_cross_workgroup = OpTypePointer CrossWorkgroup %struct_f32_f32
442
443 %f16vec8_ptr_uniform_constant = OpTypePointer UniformConstant %f16vec8
444 %f16vec8_uniform_constant = OpVariable %f16vec8_ptr_uniform_constant UniformConstant
445 %f16_ptr_uniform_constant = OpTypePointer UniformConstant %f16
446
447 %u32vec8_ptr_uniform_constant = OpTypePointer UniformConstant %u32vec8
448 %u32vec8_uniform_constant = OpVariable %u32vec8_ptr_uniform_constant UniformConstant
449 %u32_ptr_uniform_constant = OpTypePointer UniformConstant %u32
450
451 %f32vec8_ptr_uniform_constant = OpTypePointer UniformConstant %f32vec8
452 %f32vec8_uniform_constant = OpVariable %f32vec8_ptr_uniform_constant UniformConstant
453 %f32_ptr_uniform_constant = OpTypePointer UniformConstant %f32
454
455 %f16vec8_ptr_input = OpTypePointer Input %f16vec8
456 %f16vec8_input = OpVariable %f16vec8_ptr_input Input
457 %f16_ptr_input = OpTypePointer Input %f16
458
459 %u32vec8_ptr_input = OpTypePointer Input %u32vec8
460 %u32vec8_input = OpVariable %u32vec8_ptr_input Input
461 %u32_ptr_input = OpTypePointer Input %u32
462
463 %f32_ptr_generic = OpTypePointer Generic %f32
464 %u32_ptr_generic = OpTypePointer Generic %u32
465
466 %f32_ptr_function = OpTypePointer Function %f32
467 %f32vec2_ptr_function = OpTypePointer Function %f32vec2
468 %u32_ptr_function = OpTypePointer Function %u32
469 %u64_ptr_function = OpTypePointer Function %u64
470 %u32vec2_ptr_function = OpTypePointer Function %u32vec2
471
472 %u8arr = OpTypeArray %u8 %u32_256
473 %u8arr_ptr_uniform_constant = OpTypePointer UniformConstant %u8arr
474 %u8arr_uniform_constant = OpVariable %u8arr_ptr_uniform_constant UniformConstant
475 %u8_ptr_uniform_constant = OpTypePointer UniformConstant %u8
476 %u8_ptr_generic = OpTypePointer Generic %u8
477
478 %main = OpFunction %void None %func
479 %main_entry = OpLabel
480 )";
481
482 ss << body;
483
484 ss << R"(
485 OpReturn
486 OpFunctionEnd)";
487
488 return ss.str();
489 }
490
GenerateShaderCodeForDebugInfo(const std::string & op_string_instructions,const std::string & op_const_instructions,const std::string & debug_instructions_before_main,const std::string & body,const std::string & capabilities_and_extensions="",const std::string & execution_model="Fragment")491 std::string GenerateShaderCodeForDebugInfo(
492 const std::string& op_string_instructions,
493 const std::string& op_const_instructions,
494 const std::string& debug_instructions_before_main, const std::string& body,
495 const std::string& capabilities_and_extensions = "",
496 const std::string& execution_model = "Fragment") {
497 std::ostringstream ss;
498 ss << R"(
499 OpCapability Shader
500 OpCapability Float16
501 OpCapability Float64
502 OpCapability Int16
503 OpCapability Int64
504 )";
505
506 ss << capabilities_and_extensions;
507 ss << "%extinst = OpExtInstImport \"GLSL.std.450\"\n";
508 ss << "OpMemoryModel Logical GLSL450\n";
509 ss << "OpEntryPoint " << execution_model << " %main \"main\""
510 << " %f32_output"
511 << " %f32vec2_output"
512 << " %u32_output"
513 << " %u32vec2_output"
514 << " %u64_output"
515 << " %f32_input"
516 << " %f32vec2_input"
517 << " %u32_input"
518 << " %u32vec2_input"
519 << " %u64_input"
520 << "\n";
521 if (execution_model == "Fragment") {
522 ss << "OpExecutionMode %main OriginUpperLeft\n";
523 }
524
525 ss << op_string_instructions;
526
527 ss << R"(
528 %void = OpTypeVoid
529 %func = OpTypeFunction %void
530 %bool = OpTypeBool
531 %f16 = OpTypeFloat 16
532 %f32 = OpTypeFloat 32
533 %f64 = OpTypeFloat 64
534 %u32 = OpTypeInt 32 0
535 %s32 = OpTypeInt 32 1
536 %u64 = OpTypeInt 64 0
537 %s64 = OpTypeInt 64 1
538 %u16 = OpTypeInt 16 0
539 %s16 = OpTypeInt 16 1
540 %f32vec2 = OpTypeVector %f32 2
541 %f32vec3 = OpTypeVector %f32 3
542 %f32vec4 = OpTypeVector %f32 4
543 %f64vec2 = OpTypeVector %f64 2
544 %f64vec3 = OpTypeVector %f64 3
545 %f64vec4 = OpTypeVector %f64 4
546 %u32vec2 = OpTypeVector %u32 2
547 %u32vec3 = OpTypeVector %u32 3
548 %s32vec2 = OpTypeVector %s32 2
549 %u32vec4 = OpTypeVector %u32 4
550 %s32vec4 = OpTypeVector %s32 4
551 %u64vec2 = OpTypeVector %u64 2
552 %s64vec2 = OpTypeVector %s64 2
553 %f64mat22 = OpTypeMatrix %f64vec2 2
554 %f32mat22 = OpTypeMatrix %f32vec2 2
555 %f32mat23 = OpTypeMatrix %f32vec2 3
556 %f32mat32 = OpTypeMatrix %f32vec3 2
557 %f32mat33 = OpTypeMatrix %f32vec3 3
558
559 %f32_0 = OpConstant %f32 0
560 %f32_1 = OpConstant %f32 1
561 %f32_2 = OpConstant %f32 2
562 %f32_3 = OpConstant %f32 3
563 %f32_4 = OpConstant %f32 4
564 %f32_h = OpConstant %f32 0.5
565 %f32vec2_01 = OpConstantComposite %f32vec2 %f32_0 %f32_1
566 %f32vec2_12 = OpConstantComposite %f32vec2 %f32_1 %f32_2
567 %f32vec3_012 = OpConstantComposite %f32vec3 %f32_0 %f32_1 %f32_2
568 %f32vec3_123 = OpConstantComposite %f32vec3 %f32_1 %f32_2 %f32_3
569 %f32vec4_0123 = OpConstantComposite %f32vec4 %f32_0 %f32_1 %f32_2 %f32_3
570 %f32vec4_1234 = OpConstantComposite %f32vec4 %f32_1 %f32_2 %f32_3 %f32_4
571
572 %f64_0 = OpConstant %f64 0
573 %f64_1 = OpConstant %f64 1
574 %f64_2 = OpConstant %f64 2
575 %f64_3 = OpConstant %f64 3
576 %f64vec2_01 = OpConstantComposite %f64vec2 %f64_0 %f64_1
577 %f64vec3_012 = OpConstantComposite %f64vec3 %f64_0 %f64_1 %f64_2
578 %f64vec4_0123 = OpConstantComposite %f64vec4 %f64_0 %f64_1 %f64_2 %f64_3
579
580 %f16_0 = OpConstant %f16 0
581 %f16_1 = OpConstant %f16 1
582 %f16_h = OpConstant %f16 0.5
583
584 %u32_0 = OpConstant %u32 0
585 %u32_1 = OpConstant %u32 1
586 %u32_2 = OpConstant %u32 2
587 %u32_3 = OpConstant %u32 3
588
589 %s32_0 = OpConstant %s32 0
590 %s32_1 = OpConstant %s32 1
591 %s32_2 = OpConstant %s32 2
592 %s32_3 = OpConstant %s32 3
593
594 %u64_0 = OpConstant %u64 0
595 %u64_1 = OpConstant %u64 1
596 %u64_2 = OpConstant %u64 2
597 %u64_3 = OpConstant %u64 3
598
599 %s64_0 = OpConstant %s64 0
600 %s64_1 = OpConstant %s64 1
601 %s64_2 = OpConstant %s64 2
602 %s64_3 = OpConstant %s64 3
603 )";
604
605 ss << op_const_instructions;
606
607 ss << R"(
608 %s32vec2_01 = OpConstantComposite %s32vec2 %s32_0 %s32_1
609 %u32vec2_01 = OpConstantComposite %u32vec2 %u32_0 %u32_1
610
611 %s32vec2_12 = OpConstantComposite %s32vec2 %s32_1 %s32_2
612 %u32vec2_12 = OpConstantComposite %u32vec2 %u32_1 %u32_2
613
614 %s32vec4_0123 = OpConstantComposite %s32vec4 %s32_0 %s32_1 %s32_2 %s32_3
615 %u32vec4_0123 = OpConstantComposite %u32vec4 %u32_0 %u32_1 %u32_2 %u32_3
616
617 %s64vec2_01 = OpConstantComposite %s64vec2 %s64_0 %s64_1
618 %u64vec2_01 = OpConstantComposite %u64vec2 %u64_0 %u64_1
619
620 %f32mat22_1212 = OpConstantComposite %f32mat22 %f32vec2_12 %f32vec2_12
621 %f32mat23_121212 = OpConstantComposite %f32mat23 %f32vec2_12 %f32vec2_12 %f32vec2_12
622
623 %f32_ptr_output = OpTypePointer Output %f32
624 %f32vec2_ptr_output = OpTypePointer Output %f32vec2
625
626 %u32_ptr_output = OpTypePointer Output %u32
627 %u32vec2_ptr_output = OpTypePointer Output %u32vec2
628
629 %u64_ptr_output = OpTypePointer Output %u64
630
631 %f32_output = OpVariable %f32_ptr_output Output
632 %f32vec2_output = OpVariable %f32vec2_ptr_output Output
633
634 %u32_output = OpVariable %u32_ptr_output Output
635 %u32vec2_output = OpVariable %u32vec2_ptr_output Output
636
637 %u64_output = OpVariable %u64_ptr_output Output
638
639 %f32_ptr_input = OpTypePointer Input %f32
640 %f32vec2_ptr_input = OpTypePointer Input %f32vec2
641
642 %u32_ptr_input = OpTypePointer Input %u32
643 %u32vec2_ptr_input = OpTypePointer Input %u32vec2
644
645 %u64_ptr_input = OpTypePointer Input %u64
646
647 %f32_ptr_function = OpTypePointer Function %f32
648
649 %f32_input = OpVariable %f32_ptr_input Input
650 %f32vec2_input = OpVariable %f32vec2_ptr_input Input
651
652 %u32_input = OpVariable %u32_ptr_input Input
653 %u32vec2_input = OpVariable %u32vec2_ptr_input Input
654
655 %u64_input = OpVariable %u64_ptr_input Input
656
657 %u32_ptr_function = OpTypePointer Function %u32
658
659 %struct_f16_u16 = OpTypeStruct %f16 %u16
660 %struct_f32_f32 = OpTypeStruct %f32 %f32
661 %struct_f32_f32_f32 = OpTypeStruct %f32 %f32 %f32
662 %struct_f32_u32 = OpTypeStruct %f32 %u32
663 %struct_f32_u32_f32 = OpTypeStruct %f32 %u32 %f32
664 %struct_u32_f32 = OpTypeStruct %u32 %f32
665 %struct_u32_u32 = OpTypeStruct %u32 %u32
666 %struct_f32_f64 = OpTypeStruct %f32 %f64
667 %struct_f32vec2_f32vec2 = OpTypeStruct %f32vec2 %f32vec2
668 %struct_f32vec2_u32vec2 = OpTypeStruct %f32vec2 %u32vec2
669 )";
670
671 ss << debug_instructions_before_main;
672
673 ss << R"(
674 %main = OpFunction %void None %func
675 %main_entry = OpLabel
676 )";
677
678 ss << body;
679
680 ss << R"(
681 OpReturn
682 OpFunctionEnd)";
683
684 return ss.str();
685 }
686
TEST_F(ValidateOldDebugInfo,UseDebugInstructionOutOfFunction)687 TEST_F(ValidateOldDebugInfo, UseDebugInstructionOutOfFunction) {
688 const std::string src = R"(
689 %code = OpString "main() {}"
690 )";
691
692 const std::string dbg_inst = R"(
693 %cu = OpExtInst %void %DbgExt DebugCompilationUnit %code 1 1
694 )";
695
696 const std::string extension = R"(
697 %DbgExt = OpExtInstImport "DebugInfo"
698 )";
699
700 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
701 extension, "Vertex"));
702 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
703 }
704
TEST_F(ValidateOpenCL100DebugInfo,UseDebugInstructionOutOfFunction)705 TEST_F(ValidateOpenCL100DebugInfo, UseDebugInstructionOutOfFunction) {
706 const std::string src = R"(
707 %src = OpString "simple.hlsl"
708 %code = OpString "main() {}"
709 )";
710
711 const std::string dbg_inst = R"(
712 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
713 )";
714
715 const std::string extension = R"(
716 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
717 )";
718
719 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
720 extension, "Vertex"));
721 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
722 }
723
TEST_F(ValidateOpenCL100DebugInfo,DebugSourceInFunction)724 TEST_F(ValidateOpenCL100DebugInfo, DebugSourceInFunction) {
725 const std::string src = R"(
726 %src = OpString "simple.hlsl"
727 %code = OpString "main() {}"
728 )";
729
730 const std::string dbg_inst = R"(
731 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
732 )";
733
734 const std::string extension = R"(
735 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
736 )";
737
738 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", "", dbg_inst,
739 extension, "Vertex"));
740 ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
741 EXPECT_THAT(
742 getDiagnosticString(),
743 HasSubstr("Debug info extension instructions other than DebugScope, "
744 "DebugNoScope, DebugDeclare, DebugValue must appear between "
745 "section 9 (types, constants, global variables) and section 10 "
746 "(function declarations)"));
747 }
748
TEST_P(ValidateLocalDebugInfoOutOfFunction,OpenCLDebugInfo100DebugScope)749 TEST_P(ValidateLocalDebugInfoOutOfFunction, OpenCLDebugInfo100DebugScope) {
750 const std::string src = R"(
751 %src = OpString "simple.hlsl"
752 %code = OpString "void main() {}"
753 %void_name = OpString "void"
754 %main_name = OpString "main"
755 %main_linkage_name = OpString "v_main"
756 %int_name = OpString "int"
757 %foo_name = OpString "foo"
758 )";
759
760 const std::string dbg_inst_header = R"(
761 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
762 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
763 %int_info = OpExtInst %void %DbgExt DebugTypeBasic %int_name %u32_0 Signed
764 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
765 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main
766 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %int_info %dbg_src 1 1 %main_info FlagIsLocal
767 %expr = OpExtInst %void %DbgExt DebugExpression
768 )";
769
770 const std::string body = R"(
771 %foo = OpVariable %u32_ptr_function Function
772 %foo_val = OpLoad %u32 %foo
773 )";
774
775 const std::string extension = R"(
776 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
777 )";
778
779 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
780 src, "", dbg_inst_header + GetParam(), body, extension, "Vertex"));
781 ASSERT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions());
782 EXPECT_THAT(getDiagnosticString(),
783 HasSubstr("DebugScope, DebugNoScope, DebugDeclare, DebugValue "
784 "of debug info extension must appear in a function "
785 "body"));
786 }
787
788 INSTANTIATE_TEST_SUITE_P(
789 AllLocalDebugInfo, ValidateLocalDebugInfoOutOfFunction,
790 ::testing::ValuesIn(std::vector<std::string>{
791 "%main_scope = OpExtInst %void %DbgExt DebugScope %main_info",
792 "%no_scope = OpExtInst %void %DbgExt DebugNoScope",
793 }));
794
TEST_F(ValidateOpenCL100DebugInfo,DebugFunctionForwardReference)795 TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionForwardReference) {
796 const std::string src = R"(
797 %src = OpString "simple.hlsl"
798 %code = OpString "void main() {}"
799 %void_name = OpString "void"
800 %main_name = OpString "main"
801 %main_linkage_name = OpString "v_main"
802 )";
803
804 const std::string dbg_inst_header = R"(
805 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
806 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
807 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
808 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main
809 )";
810
811 const std::string body = R"(
812 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info
813 )";
814
815 const std::string extension = R"(
816 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
817 )";
818
819 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
820 src, "", dbg_inst_header, body, extension, "Vertex"));
821 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
822 }
823
TEST_F(ValidateOpenCL100DebugInfo,DebugFunctionMissingOpFunction)824 TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionMissingOpFunction) {
825 const std::string src = R"(
826 %src = OpString "simple.hlsl"
827 %code = OpString "void main() {}"
828 %void_name = OpString "void"
829 %main_name = OpString "main"
830 %main_linkage_name = OpString "v_main"
831 )";
832
833 const std::string dbg_inst_header = R"(
834 %dbgNone = OpExtInst %void %DbgExt DebugInfoNone
835 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
836 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
837 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
838 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %dbgNone
839 )";
840
841 const std::string body = R"(
842 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info
843 )";
844
845 const std::string extension = R"(
846 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
847 )";
848
849 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
850 src, "", dbg_inst_header, body, extension, "Vertex"));
851 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
852 }
853
TEST_F(ValidateOpenCL100DebugInfo,DebugScopeBeforeOpVariableInFunction)854 TEST_F(ValidateOpenCL100DebugInfo, DebugScopeBeforeOpVariableInFunction) {
855 const std::string src = R"(
856 %src = OpString "simple.hlsl"
857 %code = OpString "float4 main(float arg) {
858 float foo;
859 return float4(0, 0, 0, 0);
860 }
861 "
862 %float_name = OpString "float"
863 %main_name = OpString "main"
864 %main_linkage_name = OpString "v4f_main_f"
865 )";
866
867 const std::string size_const = R"(
868 %int_32 = OpConstant %u32 32
869 )";
870
871 const std::string dbg_inst_header = R"(
872 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
873 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
874 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
875 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
876 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %v4float_info %float_info
877 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main
878 )";
879
880 const std::string body = R"(
881 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info
882 %foo = OpVariable %f32_ptr_function Function
883 )";
884
885 const std::string extension = R"(
886 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
887 )";
888
889 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
890 src, size_const, dbg_inst_header, body, extension, "Vertex"));
891 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
892 }
893
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeCompositeSizeDebugInfoNone)894 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeCompositeSizeDebugInfoNone) {
895 const std::string src = R"(
896 %src = OpString "simple.hlsl"
897 %code = OpString "OpaqueType foo;
898 main() {}
899 "
900 %ty_name = OpString "struct VS_OUTPUT"
901 )";
902
903 const std::string dbg_inst_header = R"(
904 %dbg_none = OpExtInst %void %DbgExt DebugInfoNone
905 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
906 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
907 %opaque = OpExtInst %void %DbgExt DebugTypeComposite %ty_name Class %dbg_src 1 1 %comp_unit %ty_name %dbg_none FlagIsPublic
908 )";
909
910 const std::string extension = R"(
911 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
912 )";
913
914 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst_header,
915 "", extension, "Vertex"));
916 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
917 }
918
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeCompositeForwardReference)919 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeCompositeForwardReference) {
920 const std::string src = R"(
921 %src = OpString "simple.hlsl"
922 %code = OpString "struct VS_OUTPUT {
923 float4 pos : SV_POSITION;
924 float4 color : COLOR;
925 };
926 main() {}
927 "
928 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
929 %float_name = OpString "float"
930 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
931 %VS_OUTPUT_color_name = OpString "color : COLOR"
932 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
933 )";
934
935 const std::string size_const = R"(
936 %int_32 = OpConstant %u32 32
937 %int_128 = OpConstant %u32 128
938 )";
939
940 const std::string dbg_inst_header = R"(
941 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
942 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
943 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %VS_OUTPUT_color_info
944 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
945 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
946 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic
947 %VS_OUTPUT_color_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_color_name %v4float_info %dbg_src 3 3 %VS_OUTPUT_info %int_128 %int_128 FlagIsPublic
948 )";
949
950 const std::string extension = R"(
951 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
952 )";
953
954 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
955 src, size_const, dbg_inst_header, "", extension, "Vertex"));
956 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
957 }
958
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeCompositeMissingReference)959 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeCompositeMissingReference) {
960 const std::string src = R"(
961 %src = OpString "simple.hlsl"
962 %code = OpString "struct VS_OUTPUT {
963 float4 pos : SV_POSITION;
964 float4 color : COLOR;
965 };
966 main() {}
967 "
968 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
969 %float_name = OpString "float"
970 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
971 %VS_OUTPUT_color_name = OpString "color : COLOR"
972 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
973 )";
974
975 const std::string size_const = R"(
976 %int_32 = OpConstant %u32 32
977 %int_128 = OpConstant %u32 128
978 )";
979
980 const std::string dbg_inst_header = R"(
981 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
982 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
983 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %VS_OUTPUT_color_info
984 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
985 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
986 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic
987 )";
988
989 const std::string extension = R"(
990 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
991 )";
992
993 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
994 src, size_const, dbg_inst_header, "", extension, "Vertex"));
995 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
996 EXPECT_THAT(getDiagnosticString(),
997 HasSubstr("forward referenced IDs have not been defined"));
998 }
999
TEST_F(ValidateOpenCL100DebugInfo,DebugInstructionWrongResultType)1000 TEST_F(ValidateOpenCL100DebugInfo, DebugInstructionWrongResultType) {
1001 const std::string src = R"(
1002 %src = OpString "simple.hlsl"
1003 %code = OpString "main() {}"
1004 )";
1005
1006 const std::string dbg_inst = R"(
1007 %dbg_src = OpExtInst %bool %DbgExt DebugSource %src %code
1008 )";
1009
1010 const std::string extension = R"(
1011 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1012 )";
1013
1014 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1015 extension, "Vertex"));
1016 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1017 EXPECT_THAT(getDiagnosticString(),
1018 HasSubstr("expected result type must be a result id of "
1019 "OpTypeVoid"));
1020 }
1021
TEST_F(ValidateOpenCL100DebugInfo,DebugCompilationUnit)1022 TEST_F(ValidateOpenCL100DebugInfo, DebugCompilationUnit) {
1023 const std::string src = R"(
1024 %src = OpString "simple.hlsl"
1025 %code = OpString "main() {}"
1026 )";
1027
1028 const std::string dbg_inst = R"(
1029 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1030 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1031 )";
1032
1033 const std::string extension = R"(
1034 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1035 )";
1036
1037 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1038 extension, "Vertex"));
1039 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1040 }
1041
TEST_F(ValidateOpenCL100DebugInfo,DebugCompilationUnitFail)1042 TEST_F(ValidateOpenCL100DebugInfo, DebugCompilationUnitFail) {
1043 const std::string src = R"(
1044 %src = OpString "simple.hlsl"
1045 %code = OpString "main() {}"
1046 )";
1047
1048 const std::string dbg_inst = R"(
1049 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1050 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %src HLSL
1051 )";
1052
1053 const std::string extension = R"(
1054 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1055 )";
1056
1057 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1058 extension, "Vertex"));
1059 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1060 EXPECT_THAT(getDiagnosticString(),
1061 HasSubstr("expected operand Source must be a result id of "
1062 "DebugSource"));
1063 }
1064
TEST_F(ValidateOpenCL100DebugInfo,DebugSourceFailFile)1065 TEST_F(ValidateOpenCL100DebugInfo, DebugSourceFailFile) {
1066 const std::string src = R"(
1067 %code = OpString "main() {}"
1068 )";
1069
1070 const std::string dbg_inst = R"(
1071 %dbg_src = OpExtInst %void %DbgExt DebugSource %DbgExt %code
1072 )";
1073
1074 const std::string extension = R"(
1075 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1076 )";
1077
1078 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1079 extension, "Vertex"));
1080 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1081 EXPECT_THAT(getDiagnosticString(),
1082 HasSubstr("expected operand File must be a result id of "
1083 "OpString"));
1084 }
1085
TEST_F(ValidateOpenCL100DebugInfo,DebugSourceFailSource)1086 TEST_F(ValidateOpenCL100DebugInfo, DebugSourceFailSource) {
1087 const std::string src = R"(
1088 %src = OpString "simple.hlsl"
1089 )";
1090
1091 const std::string dbg_inst = R"(
1092 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %DbgExt
1093 )";
1094
1095 const std::string extension = R"(
1096 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1097 )";
1098
1099 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1100 extension, "Vertex"));
1101 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1102 EXPECT_THAT(getDiagnosticString(),
1103 HasSubstr("expected operand Text must be a result id of "
1104 "OpString"));
1105 }
1106
TEST_F(ValidateOpenCL100DebugInfo,DebugSourceNoText)1107 TEST_F(ValidateOpenCL100DebugInfo, DebugSourceNoText) {
1108 const std::string src = R"(
1109 %src = OpString "simple.hlsl"
1110 )";
1111
1112 const std::string dbg_inst = R"(
1113 %dbg_src = OpExtInst %void %DbgExt DebugSource %src
1114 )";
1115
1116 const std::string extension = R"(
1117 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1118 )";
1119
1120 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst, "",
1121 extension, "Vertex"));
1122 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1123 }
1124
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeBasicFailName)1125 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeBasicFailName) {
1126 const std::string src = R"(
1127 %src = OpString "simple.hlsl"
1128 %code = OpString "float4 main(float arg) {
1129 float foo;
1130 return float4(0, 0, 0, 0);
1131 }
1132 "
1133 %float_name = OpString "float"
1134 )";
1135
1136 const std::string size_const = R"(
1137 %int_32 = OpConstant %u32 32
1138 )";
1139
1140 const std::string dbg_inst_header = R"(
1141 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1142 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1143 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %int_32 %int_32 Float
1144 )";
1145
1146 const std::string extension = R"(
1147 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1148 )";
1149
1150 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1151 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1152 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1153 EXPECT_THAT(getDiagnosticString(),
1154 HasSubstr("expected operand Name must be a result id of "
1155 "OpString"));
1156 }
1157
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeBasicFailSize)1158 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeBasicFailSize) {
1159 const std::string src = R"(
1160 %src = OpString "simple.hlsl"
1161 %code = OpString "float4 main(float arg) {
1162 float foo;
1163 return float4(0, 0, 0, 0);
1164 }
1165 "
1166 %float_name = OpString "float"
1167 )";
1168
1169 const std::string size_const = R"(
1170 %int_32 = OpConstant %u32 32
1171 )";
1172
1173 const std::string dbg_inst_header = R"(
1174 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1175 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1176 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %float_name Float
1177 )";
1178
1179 const std::string extension = R"(
1180 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1181 )";
1182
1183 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1184 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1185 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1186 EXPECT_THAT(getDiagnosticString(),
1187 HasSubstr("expected operand Size must be a result id of "
1188 "OpConstant"));
1189 }
1190
TEST_F(ValidateOpenCL100DebugInfo,DebugTypePointer)1191 TEST_F(ValidateOpenCL100DebugInfo, DebugTypePointer) {
1192 const std::string src = R"(
1193 %src = OpString "simple.hlsl"
1194 %code = OpString "float4 main(float arg) {
1195 float foo;
1196 return float4(0, 0, 0, 0);
1197 }
1198 "
1199 %float_name = OpString "float"
1200 )";
1201
1202 const std::string size_const = R"(
1203 %int_32 = OpConstant %u32 32
1204 )";
1205
1206 const std::string dbg_inst_header = R"(
1207 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1208 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1209 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1210 %pfloat_info = OpExtInst %void %DbgExt DebugTypePointer %float_info Function FlagIsLocal
1211 )";
1212
1213 const std::string extension = R"(
1214 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1215 )";
1216
1217 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1218 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1219 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1220 }
1221
TEST_F(ValidateOpenCL100DebugInfo,DebugTypePointerFail)1222 TEST_F(ValidateOpenCL100DebugInfo, DebugTypePointerFail) {
1223 const std::string src = R"(
1224 %src = OpString "simple.hlsl"
1225 %code = OpString "float4 main(float arg) {
1226 float foo;
1227 return float4(0, 0, 0, 0);
1228 }
1229 "
1230 %float_name = OpString "float"
1231 )";
1232
1233 const std::string size_const = R"(
1234 %int_32 = OpConstant %u32 32
1235 )";
1236
1237 const std::string dbg_inst_header = R"(
1238 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1239 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1240 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1241 %pfloat_info = OpExtInst %void %DbgExt DebugTypePointer %dbg_src Function FlagIsLocal
1242 )";
1243
1244 const std::string extension = R"(
1245 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1246 )";
1247
1248 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1249 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1250 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1251 EXPECT_THAT(getDiagnosticString(),
1252 HasSubstr("expected operand Base Type must be a result id of "
1253 "DebugTypeBasic"));
1254 }
1255
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeQualifier)1256 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeQualifier) {
1257 const std::string src = R"(
1258 %src = OpString "simple.hlsl"
1259 %code = OpString "float4 main(float arg) {
1260 float foo;
1261 return float4(0, 0, 0, 0);
1262 }
1263 "
1264 %float_name = OpString "float"
1265 )";
1266
1267 const std::string size_const = R"(
1268 %int_32 = OpConstant %u32 32
1269 )";
1270
1271 const std::string dbg_inst_header = R"(
1272 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1273 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1274 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1275 %cfloat_info = OpExtInst %void %DbgExt DebugTypeQualifier %float_info ConstType
1276 )";
1277
1278 const std::string extension = R"(
1279 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1280 )";
1281
1282 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1283 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1284 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1285 }
1286
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeQualifierFail)1287 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeQualifierFail) {
1288 const std::string src = R"(
1289 %src = OpString "simple.hlsl"
1290 %code = OpString "float4 main(float arg) {
1291 float foo;
1292 return float4(0, 0, 0, 0);
1293 }
1294 "
1295 %float_name = OpString "float"
1296 )";
1297
1298 const std::string size_const = R"(
1299 %int_32 = OpConstant %u32 32
1300 )";
1301
1302 const std::string dbg_inst_header = R"(
1303 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1304 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1305 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1306 %cfloat_info = OpExtInst %void %DbgExt DebugTypeQualifier %comp_unit ConstType
1307 )";
1308
1309 const std::string extension = R"(
1310 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1311 )";
1312
1313 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1314 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1315 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1316 EXPECT_THAT(getDiagnosticString(),
1317 HasSubstr("expected operand Base Type must be a result id of "
1318 "DebugTypeBasic"));
1319 }
1320
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArray)1321 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArray) {
1322 const std::string src = R"(
1323 %src = OpString "simple.hlsl"
1324 %code = OpString "main() {}"
1325 %float_name = OpString "float"
1326 )";
1327
1328 const std::string size_const = R"(
1329 %int_32 = OpConstant %u32 32
1330 )";
1331
1332 const std::string dbg_inst_header = R"(
1333 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1334 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1335 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1336 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %int_32
1337 )";
1338
1339 const std::string extension = R"(
1340 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1341 )";
1342
1343 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1344 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1345 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1346 }
1347
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayWithVariableSize)1348 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayWithVariableSize) {
1349 const std::string src = R"(
1350 %src = OpString "simple.hlsl"
1351 %code = OpString "main() {}"
1352 %float_name = OpString "float"
1353 %int_name = OpString "int"
1354 %main_name = OpString "main"
1355 %foo_name = OpString "foo"
1356 )";
1357
1358 const std::string size_const = R"(
1359 %int_32 = OpConstant %u32 32
1360 )";
1361
1362 const std::string dbg_inst_header = R"(
1363 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1364 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1365 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1366 %uint_info = OpExtInst %void %DbgExt DebugTypeBasic %int_name %int_32 Unsigned
1367 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
1368 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main
1369 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %uint_info %dbg_src 1 1 %main_info FlagIsLocal
1370 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %foo_info
1371 )";
1372
1373 const std::string extension = R"(
1374 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1375 )";
1376
1377 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1378 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1379 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1380 }
1381
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailBaseType)1382 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailBaseType) {
1383 const std::string src = R"(
1384 %src = OpString "simple.hlsl"
1385 %code = OpString "main() {}"
1386 %float_name = OpString "float"
1387 )";
1388
1389 const std::string size_const = R"(
1390 %int_32 = OpConstant %u32 32
1391 )";
1392
1393 const std::string dbg_inst_header = R"(
1394 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1395 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1396 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1397 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %comp_unit %int_32
1398 )";
1399
1400 const std::string extension = R"(
1401 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1402 )";
1403
1404 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1405 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1406 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1407 EXPECT_THAT(getDiagnosticString(),
1408 HasSubstr("expected operand Base Type is not a valid debug "
1409 "type"));
1410 }
1411
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailComponentCount)1412 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailComponentCount) {
1413 const std::string src = R"(
1414 %src = OpString "simple.hlsl"
1415 %code = OpString "main() {}"
1416 %float_name = OpString "float"
1417 )";
1418
1419 const std::string size_const = R"(
1420 %int_32 = OpConstant %u32 32
1421 )";
1422
1423 const std::string dbg_inst_header = R"(
1424 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1425 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1426 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1427 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %float_info
1428 )";
1429
1430 const std::string extension = R"(
1431 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1432 )";
1433
1434 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1435 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1436 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1437 EXPECT_THAT(getDiagnosticString(),
1438 HasSubstr("Component Count must be OpConstant with a 32- or "
1439 "64-bits integer scalar type or DebugGlobalVariable or "
1440 "DebugLocalVariable with a 32- or 64-bits unsigned "
1441 "integer scalar type"));
1442 }
1443
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailComponentCountFloat)1444 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailComponentCountFloat) {
1445 const std::string src = R"(
1446 %src = OpString "simple.hlsl"
1447 %code = OpString "main() {}"
1448 %float_name = OpString "float"
1449 )";
1450
1451 const std::string size_const = R"(
1452 %int_32 = OpConstant %u32 32
1453 )";
1454
1455 const std::string dbg_inst_header = R"(
1456 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1457 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1458 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1459 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %f32_4
1460 )";
1461
1462 const std::string extension = R"(
1463 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1464 )";
1465
1466 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1467 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1468 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1469 EXPECT_THAT(getDiagnosticString(),
1470 HasSubstr("Component Count must be OpConstant with a 32- or "
1471 "64-bits integer scalar type or DebugGlobalVariable or "
1472 "DebugLocalVariable with a 32- or 64-bits unsigned "
1473 "integer scalar type"));
1474 }
1475
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailComponentCountZero)1476 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailComponentCountZero) {
1477 const std::string src = R"(
1478 %src = OpString "simple.hlsl"
1479 %code = OpString "main() {}"
1480 %float_name = OpString "float"
1481 )";
1482
1483 const std::string size_const = R"(
1484 %int_32 = OpConstant %u32 32
1485 )";
1486
1487 const std::string dbg_inst_header = R"(
1488 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1489 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1490 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1491 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %u32_0
1492 )";
1493
1494 const std::string extension = R"(
1495 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1496 )";
1497
1498 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1499 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1500 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1501 EXPECT_THAT(getDiagnosticString(),
1502 HasSubstr("Component Count must be OpConstant with a 32- or "
1503 "64-bits integer scalar type or DebugGlobalVariable or "
1504 "DebugLocalVariable with a 32- or 64-bits unsigned "
1505 "integer scalar type"));
1506 }
1507
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeArrayFailVariableSizeTypeFloat)1508 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArrayFailVariableSizeTypeFloat) {
1509 const std::string src = R"(
1510 %src = OpString "simple.hlsl"
1511 %code = OpString "main() {}"
1512 %float_name = OpString "float"
1513 %main_name = OpString "main"
1514 %foo_name = OpString "foo"
1515 )";
1516
1517 const std::string size_const = R"(
1518 %int_32 = OpConstant %u32 32
1519 )";
1520
1521 const std::string dbg_inst_header = R"(
1522 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1523 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1524 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1525 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
1526 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main
1527 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 1 %main_info FlagIsLocal
1528 %float_arr_info = OpExtInst %void %DbgExt DebugTypeArray %float_info %foo_info
1529 )";
1530
1531 const std::string extension = R"(
1532 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1533 )";
1534
1535 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1536 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1537 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1538 EXPECT_THAT(getDiagnosticString(),
1539 HasSubstr("Component Count must be OpConstant with a 32- or "
1540 "64-bits integer scalar type or DebugGlobalVariable or "
1541 "DebugLocalVariable with a 32- or 64-bits unsigned "
1542 "integer scalar type"));
1543 }
1544
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeVector)1545 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVector) {
1546 const std::string src = R"(
1547 %src = OpString "simple.hlsl"
1548 %code = OpString "main() {}"
1549 %float_name = OpString "float"
1550 )";
1551
1552 const std::string size_const = R"(
1553 %int_32 = OpConstant %u32 32
1554 )";
1555
1556 const std::string dbg_inst_header = R"(
1557 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1558 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1559 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1560 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
1561 )";
1562
1563 const std::string extension = R"(
1564 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1565 )";
1566
1567 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1568 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1569 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1570 }
1571
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeVectorFail)1572 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVectorFail) {
1573 const std::string src = R"(
1574 %src = OpString "simple.hlsl"
1575 %code = OpString "main() {}"
1576 %float_name = OpString "float"
1577 )";
1578
1579 const std::string size_const = R"(
1580 %int_32 = OpConstant %u32 32
1581 )";
1582
1583 const std::string dbg_inst_header = R"(
1584 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1585 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1586 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1587 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src 4
1588 )";
1589
1590 const std::string extension = R"(
1591 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1592 )";
1593
1594 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1595 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1596 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1597 EXPECT_THAT(getDiagnosticString(),
1598 HasSubstr("expected operand Base Type must be a result id of "
1599 "DebugTypeBasic"));
1600 }
1601
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeVectorFailComponentZero)1602 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVectorFailComponentZero) {
1603 const std::string src = R"(
1604 %src = OpString "simple.hlsl"
1605 %code = OpString "main() {}"
1606 %float_name = OpString "float"
1607 )";
1608
1609 const std::string size_const = R"(
1610 %int_32 = OpConstant %u32 32
1611 )";
1612
1613 const std::string dbg_inst_header = R"(
1614 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1615 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1616 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1617 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src 0
1618 )";
1619
1620 const std::string extension = R"(
1621 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1622 )";
1623
1624 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1625 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1626 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1627 EXPECT_THAT(getDiagnosticString(),
1628 HasSubstr("expected operand Base Type must be a result id of "
1629 "DebugTypeBasic"));
1630 }
1631
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeVectorFailComponentFive)1632 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeVectorFailComponentFive) {
1633 const std::string src = R"(
1634 %src = OpString "simple.hlsl"
1635 %code = OpString "main() {}"
1636 %float_name = OpString "float"
1637 )";
1638
1639 const std::string size_const = R"(
1640 %int_32 = OpConstant %u32 32
1641 )";
1642
1643 const std::string dbg_inst_header = R"(
1644 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1645 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1646 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1647 %vfloat_info = OpExtInst %void %DbgExt DebugTypeVector %dbg_src 5
1648 )";
1649
1650 const std::string extension = R"(
1651 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1652 )";
1653
1654 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1655 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1656 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1657 EXPECT_THAT(getDiagnosticString(),
1658 HasSubstr("expected operand Base Type must be a result id of "
1659 "DebugTypeBasic"));
1660 }
1661
TEST_F(ValidateOpenCL100DebugInfo,DebugTypedef)1662 TEST_F(ValidateOpenCL100DebugInfo, DebugTypedef) {
1663 const std::string src = R"(
1664 %src = OpString "simple.hlsl"
1665 %code = OpString "main() {}"
1666 %float_name = OpString "float"
1667 %foo_name = OpString "foo"
1668 )";
1669
1670 const std::string size_const = R"(
1671 %int_32 = OpConstant %u32 32
1672 )";
1673
1674 const std::string dbg_inst_header = R"(
1675 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1676 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1677 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1678 %foo_info = OpExtInst %void %DbgExt DebugTypedef %foo_name %float_info %dbg_src 1 1 %comp_unit
1679 )";
1680
1681 const std::string extension = R"(
1682 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1683 )";
1684
1685 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1686 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1687 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1688 }
1689
TEST_P(ValidateOpenCL100DebugInfoDebugTypedef,Fail)1690 TEST_P(ValidateOpenCL100DebugInfoDebugTypedef, Fail) {
1691 const std::string src = R"(
1692 %src = OpString "simple.hlsl"
1693 %code = OpString "main() {}"
1694 %float_name = OpString "float"
1695 %foo_name = OpString "foo"
1696 )";
1697
1698 const std::string size_const = R"(
1699 %int_32 = OpConstant %u32 32
1700 )";
1701
1702 const auto& param = GetParam();
1703
1704 std::ostringstream ss;
1705 ss << R"(
1706 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1707 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1708 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1709 %foo_info = OpExtInst %void %DbgExt DebugTypedef )";
1710 ss << param.first;
1711
1712 const std::string extension = R"(
1713 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1714 )";
1715
1716 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
1717 "", extension, "Vertex"));
1718 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1719 EXPECT_THAT(getDiagnosticString(),
1720 HasSubstr("expected operand " + param.second +
1721 " must be a result id of "));
1722 }
1723
1724 INSTANTIATE_TEST_SUITE_P(
1725 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypedef,
1726 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
1727 std::make_pair(R"(%dbg_src %float_info %dbg_src 1 1 %comp_unit)",
1728 "Name"),
1729 std::make_pair(R"(%foo_name %dbg_src %dbg_src 1 1 %comp_unit)",
1730 "Base Type"),
1731 std::make_pair(R"(%foo_name %float_info %comp_unit 1 1 %comp_unit)",
1732 "Source"),
1733 std::make_pair(R"(%foo_name %float_info %dbg_src 1 1 %dbg_src)",
1734 "Parent"),
1735 }));
1736
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeFunction)1737 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunction) {
1738 const std::string src = R"(
1739 %src = OpString "simple.hlsl"
1740 %code = OpString "main() {}"
1741 %main_name = OpString "main"
1742 %main_linkage_name = OpString "v_main"
1743 %float_name = OpString "float"
1744 )";
1745
1746 const std::string size_const = R"(
1747 %int_32 = OpConstant %u32 32
1748 )";
1749
1750 const std::string dbg_inst_header = R"(
1751 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1752 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1753 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1754 %main_type_info1 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
1755 %main_type_info2 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %float_info
1756 %main_type_info3 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %float_info %float_info
1757 %main_type_info4 = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void %float_info %float_info
1758 )";
1759
1760 const std::string extension = R"(
1761 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1762 )";
1763
1764 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1765 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1766 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1767 }
1768
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeFunctionFailReturn)1769 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunctionFailReturn) {
1770 const std::string src = R"(
1771 %src = OpString "simple.hlsl"
1772 %code = OpString "main() {}"
1773 %main_name = OpString "main"
1774 %main_linkage_name = OpString "v_main"
1775 %float_name = OpString "float"
1776 )";
1777
1778 const std::string size_const = R"(
1779 %int_32 = OpConstant %u32 32
1780 )";
1781
1782 const std::string dbg_inst_header = R"(
1783 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1784 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1785 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1786 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %dbg_src %float_info
1787 )";
1788
1789 const std::string extension = R"(
1790 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1791 )";
1792
1793 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1794 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1795 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1796 EXPECT_THAT(
1797 getDiagnosticString(),
1798 HasSubstr("expected operand Return Type is not a valid debug type"));
1799 }
1800
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeFunctionFailParam)1801 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeFunctionFailParam) {
1802 const std::string src = R"(
1803 %src = OpString "simple.hlsl"
1804 %code = OpString "main() {}"
1805 %main_name = OpString "main"
1806 %main_linkage_name = OpString "v_main"
1807 %float_name = OpString "float"
1808 )";
1809
1810 const std::string size_const = R"(
1811 %int_32 = OpConstant %u32 32
1812 )";
1813
1814 const std::string dbg_inst_header = R"(
1815 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1816 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1817 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1818 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %float_info %void
1819 )";
1820
1821 const std::string extension = R"(
1822 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1823 )";
1824
1825 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1826 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1827 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1828 EXPECT_THAT(
1829 getDiagnosticString(),
1830 HasSubstr("expected operand Parameter Types is not a valid debug type"));
1831 }
1832
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeEnum)1833 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeEnum) {
1834 const std::string src = R"(
1835 %src = OpString "simple.hlsl"
1836 %code = OpString "main() {}"
1837 %float_name = OpString "float"
1838 %foo_name = OpString "foo"
1839 )";
1840
1841 const std::string size_const = R"(
1842 %int_32 = OpConstant %u32 32
1843 )";
1844
1845 const std::string dbg_inst_header = R"(
1846 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1847 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1848 %none = OpExtInst %void %DbgExt DebugInfoNone
1849 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1850 %foo_info1 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name %u32_1 %foo_name
1851 %foo_info2 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %none %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name %u32_1 %foo_name
1852 %foo_info3 = OpExtInst %void %DbgExt DebugTypeEnum %foo_name %none %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic
1853 )";
1854
1855 const std::string extension = R"(
1856 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1857 )";
1858
1859 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1860 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1861 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1862 }
1863
TEST_P(ValidateOpenCL100DebugInfoDebugTypeEnum,Fail)1864 TEST_P(ValidateOpenCL100DebugInfoDebugTypeEnum, Fail) {
1865 const std::string src = R"(
1866 %src = OpString "simple.hlsl"
1867 %code = OpString "main() {}"
1868 %float_name = OpString "float"
1869 %foo_name = OpString "foo"
1870 )";
1871
1872 const std::string size_const = R"(
1873 %int_32 = OpConstant %u32 32
1874 )";
1875
1876 const auto& param = GetParam();
1877
1878 std::ostringstream ss;
1879 ss << R"(
1880 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1881 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1882 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1883 %foo_info = OpExtInst %void %DbgExt DebugTypeEnum )";
1884 ss << param.first;
1885
1886 const std::string extension = R"(
1887 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1888 )";
1889
1890 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
1891 "", extension, "Vertex"));
1892 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
1893 EXPECT_THAT(getDiagnosticString(),
1894 HasSubstr("expected operand " + param.second));
1895 }
1896
1897 INSTANTIATE_TEST_SUITE_P(
1898 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypeEnum,
1899 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
1900 std::make_pair(
1901 R"(%dbg_src %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name)",
1902 "Name"),
1903 std::make_pair(
1904 R"(%foo_name %dbg_src %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name)",
1905 "Underlying Types"),
1906 std::make_pair(
1907 R"(%foo_name %float_info %comp_unit 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %foo_name)",
1908 "Source"),
1909 std::make_pair(
1910 R"(%foo_name %float_info %dbg_src 1 1 %dbg_src %int_32 FlagIsPublic %u32_0 %foo_name)",
1911 "Parent"),
1912 std::make_pair(
1913 R"(%foo_name %float_info %dbg_src 1 1 %comp_unit %void FlagIsPublic %u32_0 %foo_name)",
1914 "Size"),
1915 std::make_pair(
1916 R"(%foo_name %float_info %dbg_src 1 1 %comp_unit %u32_0 FlagIsPublic %u32_0 %foo_name)",
1917 "Size"),
1918 std::make_pair(
1919 R"(%foo_name %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %foo_name %foo_name)",
1920 "Value"),
1921 std::make_pair(
1922 R"(%foo_name %float_info %dbg_src 1 1 %comp_unit %int_32 FlagIsPublic %u32_0 %u32_1)",
1923 "Name"),
1924 }));
1925
TEST_F(ValidateOpenCL100DebugInfo,DebugTypeCompositeFunctionAndInheritance)1926 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeCompositeFunctionAndInheritance) {
1927 const std::string src = R"(
1928 %src = OpString "simple.hlsl"
1929 %code = OpString "struct VS_OUTPUT {
1930 float4 pos : SV_POSITION;
1931 };
1932 struct foo : VS_OUTPUT {
1933 };
1934 main() {}
1935 "
1936 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
1937 %float_name = OpString "float"
1938 %foo_name = OpString "foo"
1939 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
1940 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
1941 %main_name = OpString "main"
1942 %main_linkage_name = OpString "v4f_main_f"
1943 )";
1944
1945 const std::string size_const = R"(
1946 %int_32 = OpConstant %u32 32
1947 %int_128 = OpConstant %u32 128
1948 )";
1949
1950 const std::string dbg_inst_header = R"(
1951 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
1952 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
1953 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child
1954 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
1955 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
1956 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic
1957 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %v4float_info %float_info
1958 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main
1959 %foo_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Structure %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic
1960 %child = OpExtInst %void %DbgExt DebugTypeInheritance %foo_info %VS_OUTPUT_info %int_128 %int_128 FlagIsPublic
1961 )";
1962
1963 const std::string extension = R"(
1964 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
1965 )";
1966
1967 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
1968 src, size_const, dbg_inst_header, "", extension, "Vertex"));
1969 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
1970 }
1971
TEST_P(ValidateOpenCL100DebugInfoDebugTypeComposite,Fail)1972 TEST_P(ValidateOpenCL100DebugInfoDebugTypeComposite, Fail) {
1973 const std::string src = R"(
1974 %src = OpString "simple.hlsl"
1975 %code = OpString "struct VS_OUTPUT {
1976 float4 pos : SV_POSITION;
1977 };
1978 struct foo : VS_OUTPUT {
1979 };
1980 main() {}
1981 "
1982 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
1983 %float_name = OpString "float"
1984 %foo_name = OpString "foo"
1985 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
1986 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
1987 %main_name = OpString "main"
1988 %main_linkage_name = OpString "v4f_main_f"
1989 )";
1990
1991 const std::string size_const = R"(
1992 %int_32 = OpConstant %u32 32
1993 %int_128 = OpConstant %u32 128
1994 )";
1995
1996 const auto& param = GetParam();
1997
1998 std::ostringstream ss;
1999 ss << R"(
2000 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2001 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2002 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite )";
2003 ss << param.first;
2004 ss << R"(
2005 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2006 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
2007 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember %VS_OUTPUT_pos_name %v4float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_128 FlagIsPublic
2008 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %v4float_info %float_info
2009 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main
2010 %foo_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Structure %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic
2011 %child = OpExtInst %void %DbgExt DebugTypeInheritance %foo_info %VS_OUTPUT_info %int_128 %int_128 FlagIsPublic
2012 )";
2013
2014 const std::string extension = R"(
2015 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2016 )";
2017
2018 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
2019 "", extension, "Vertex"));
2020 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2021 EXPECT_THAT(getDiagnosticString(),
2022 HasSubstr("expected operand " + param.second + " must be "));
2023 }
2024
2025 INSTANTIATE_TEST_SUITE_P(
2026 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypeComposite,
2027 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2028 std::make_pair(
2029 R"(%dbg_src Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
2030 "Name"),
2031 std::make_pair(
2032 R"(%VS_OUTPUT_name Structure %comp_unit 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
2033 "Source"),
2034 std::make_pair(
2035 R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %dbg_src %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
2036 "Parent"),
2037 std::make_pair(
2038 R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %int_128 %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
2039 "Linkage Name"),
2040 std::make_pair(
2041 R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %dbg_src FlagIsPublic %VS_OUTPUT_pos_info %main_info %child)",
2042 "Size"),
2043 std::make_pair(
2044 R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %dbg_src %main_info %child)",
2045 "Members"),
2046 std::make_pair(
2047 R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %dbg_src %child)",
2048 "Members"),
2049 std::make_pair(
2050 R"(%VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_128 FlagIsPublic %VS_OUTPUT_pos_info %main_info %dbg_src)",
2051 "Members"),
2052 }));
2053
TEST_P(ValidateOpenCL100DebugInfoDebugTypeMember,Fail)2054 TEST_P(ValidateOpenCL100DebugInfoDebugTypeMember, Fail) {
2055 const std::string src = R"(
2056 %src = OpString "simple.hlsl"
2057 %code = OpString "struct VS_OUTPUT {
2058 float pos : SV_POSITION;
2059 };
2060 main() {}
2061 "
2062 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
2063 %float_name = OpString "float"
2064 %VS_OUTPUT_pos_name = OpString "pos : SV_POSITION"
2065 %VS_OUTPUT_linkage_name = OpString "VS_OUTPUT"
2066 )";
2067
2068 const std::string size_const = R"(
2069 %int_32 = OpConstant %u32 32
2070 )";
2071
2072 const auto& param = GetParam();
2073
2074 std::ostringstream ss;
2075 ss << R"(
2076 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2077 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2078 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_linkage_name %int_32 FlagIsPublic %VS_OUTPUT_pos_info
2079 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2080 %VS_OUTPUT_pos_info = OpExtInst %void %DbgExt DebugTypeMember )";
2081 ss << param.first;
2082
2083 const std::string extension = R"(
2084 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2085 )";
2086
2087 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
2088 "", extension, "Vertex"));
2089 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2090 if (!param.second.empty()) {
2091 EXPECT_THAT(getDiagnosticString(),
2092 HasSubstr("expected operand " + param.second +
2093 " must be a result id of "));
2094 }
2095 }
2096
2097 INSTANTIATE_TEST_SUITE_P(
2098 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypeMember,
2099 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2100 std::make_pair(
2101 R"(%dbg_src %float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_32 FlagIsPublic)",
2102 "Name"),
2103 std::make_pair(
2104 R"(%VS_OUTPUT_pos_name %dbg_src %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %int_32 FlagIsPublic)",
2105 ""),
2106 std::make_pair(
2107 R"(%VS_OUTPUT_pos_name %float_info %float_info 2 3 %VS_OUTPUT_info %u32_0 %int_32 FlagIsPublic)",
2108 "Source"),
2109 std::make_pair(
2110 R"(%VS_OUTPUT_pos_name %float_info %dbg_src 2 3 %float_info %u32_0 %int_32 FlagIsPublic)",
2111 "Parent"),
2112 std::make_pair(
2113 R"(%VS_OUTPUT_pos_name %float_info %dbg_src 2 3 %VS_OUTPUT_info %void %int_32 FlagIsPublic)",
2114 "Offset"),
2115 std::make_pair(
2116 R"(%VS_OUTPUT_pos_name %float_info %dbg_src 2 3 %VS_OUTPUT_info %u32_0 %void FlagIsPublic)",
2117 "Size"),
2118 }));
2119
TEST_P(ValidateOpenCL100DebugInfoDebugTypeInheritance,Fail)2120 TEST_P(ValidateOpenCL100DebugInfoDebugTypeInheritance, Fail) {
2121 const std::string src = R"(
2122 %src = OpString "simple.hlsl"
2123 %code = OpString "struct VS_OUTPUT {};
2124 struct foo : VS_OUTPUT {};
2125 "
2126 %VS_OUTPUT_name = OpString "struct VS_OUTPUT"
2127 %foo_name = OpString "foo"
2128 )";
2129
2130 const auto& param = GetParam();
2131
2132 std::ostringstream ss;
2133 ss << R"(
2134 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2135 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2136 %VS_OUTPUT_info = OpExtInst %void %DbgExt DebugTypeComposite %VS_OUTPUT_name Structure %dbg_src 1 1 %comp_unit %VS_OUTPUT_name %u32_0 FlagIsPublic %child
2137 %foo_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Structure %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic
2138 %bar_info = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Union %dbg_src 1 1 %comp_unit %foo_name %u32_0 FlagIsPublic
2139 %child = OpExtInst %void %DbgExt DebugTypeInheritance )"
2140 << param.first;
2141
2142 const std::string extension = R"(
2143 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2144 )";
2145
2146 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "",
2147 extension, "Vertex"));
2148 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2149 EXPECT_THAT(getDiagnosticString(),
2150 HasSubstr("expected operand " + param.second));
2151 }
2152
2153 INSTANTIATE_TEST_SUITE_P(
2154 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugTypeInheritance,
2155 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2156 std::make_pair(R"(%dbg_src %VS_OUTPUT_info %u32_0 %u32_0 FlagIsPublic)",
2157 "Child must be a result id of"),
2158 std::make_pair(R"(%foo_info %dbg_src %u32_0 %u32_0 FlagIsPublic)",
2159 "Parent must be a result id of"),
2160 std::make_pair(
2161 R"(%bar_info %VS_OUTPUT_info %u32_0 %u32_0 FlagIsPublic)",
2162 "Child must be class or struct debug type"),
2163 std::make_pair(R"(%foo_info %bar_info %u32_0 %u32_0 FlagIsPublic)",
2164 "Parent must be class or struct debug type"),
2165 std::make_pair(R"(%foo_info %VS_OUTPUT_info %void %u32_0 FlagIsPublic)",
2166 "Offset"),
2167 std::make_pair(R"(%foo_info %VS_OUTPUT_info %u32_0 %void FlagIsPublic)",
2168 "Size"),
2169 }));
TEST_P(ValidateGlslStd450SqrtLike,Success)2170 TEST_P(ValidateGlslStd450SqrtLike, Success) {
2171 const std::string ext_inst_name = GetParam();
2172 std::ostringstream ss;
2173 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
2174 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
2175 << " %f32vec2_01\n";
2176 ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n";
2177 CompileSuccessfully(GenerateShaderCode(ss.str()));
2178 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2179 }
2180
TEST_F(ValidateOpenCL100DebugInfo,DebugFunctionDeclaration)2181 TEST_F(ValidateOpenCL100DebugInfo, DebugFunctionDeclaration) {
2182 const std::string src = R"(
2183 %src = OpString "simple.hlsl"
2184 %code = OpString "struct VS_OUTPUT {
2185 float4 pos : SV_POSITION;
2186 };
2187 main() {}
2188 "
2189 %main_name = OpString "main"
2190 %main_linkage_name = OpString "v4f_main_f"
2191 )";
2192
2193 const std::string dbg_inst_header = R"(
2194 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2195 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2196 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
2197 %main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic
2198 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)";
2199
2200 const std::string extension = R"(
2201 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2202 )";
2203
2204 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst_header,
2205 "", extension, "Vertex"));
2206 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2207 }
2208
TEST_P(ValidateOpenCL100DebugInfoDebugFunction,Fail)2209 TEST_P(ValidateOpenCL100DebugInfoDebugFunction, Fail) {
2210 const std::string src = R"(
2211 %src = OpString "simple.hlsl"
2212 %code = OpString "struct VS_OUTPUT {
2213 float4 pos : SV_POSITION;
2214 };
2215 main() {}
2216 "
2217 %main_name = OpString "main"
2218 %main_linkage_name = OpString "v4f_main_f"
2219 )";
2220
2221 const auto& param = GetParam();
2222
2223 std::ostringstream ss;
2224 ss << R"(
2225 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2226 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2227 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
2228 %main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration %main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic
2229 %main_info = OpExtInst %void %DbgExt DebugFunction )"
2230 << param.first;
2231
2232 const std::string extension = R"(
2233 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2234 )";
2235
2236 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "",
2237 extension, "Vertex"));
2238 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2239 EXPECT_THAT(getDiagnosticString(),
2240 HasSubstr("expected operand " + param.second));
2241 }
2242
2243 INSTANTIATE_TEST_SUITE_P(
2244 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugFunction,
2245 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2246 std::make_pair(
2247 R"(%u32_0 %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)",
2248 "Name"),
2249 std::make_pair(
2250 R"(%main_name %dbg_src %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)",
2251 "Type"),
2252 std::make_pair(
2253 R"(%main_name %main_type_info %comp_unit 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main)",
2254 "Source"),
2255 std::make_pair(
2256 R"(%main_name %main_type_info %dbg_src 12 1 %dbg_src %main_linkage_name FlagIsPublic 13 %main)",
2257 "Parent"),
2258 std::make_pair(
2259 R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %void FlagIsPublic 13 %main)",
2260 "Linkage Name"),
2261 std::make_pair(
2262 R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %void)",
2263 "Function"),
2264 std::make_pair(
2265 R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic 13 %main %dbg_src)",
2266 "Declaration"),
2267 }));
2268
TEST_P(ValidateOpenCL100DebugInfoDebugFunctionDeclaration,Fail)2269 TEST_P(ValidateOpenCL100DebugInfoDebugFunctionDeclaration, Fail) {
2270 const std::string src = R"(
2271 %src = OpString "simple.hlsl"
2272 %code = OpString "struct VS_OUTPUT {
2273 float4 pos : SV_POSITION;
2274 };
2275 main() {}
2276 "
2277 %main_name = OpString "main"
2278 %main_linkage_name = OpString "v4f_main_f"
2279 )";
2280
2281 const auto& param = GetParam();
2282
2283 std::ostringstream ss;
2284 ss << R"(
2285 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2286 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2287 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
2288 %main_decl = OpExtInst %void %DbgExt DebugFunctionDeclaration )"
2289 << param.first;
2290
2291 const std::string extension = R"(
2292 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2293 )";
2294
2295 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "",
2296 extension, "Vertex"));
2297 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2298 EXPECT_THAT(getDiagnosticString(),
2299 HasSubstr("expected operand " + param.second));
2300 }
2301
2302 INSTANTIATE_TEST_SUITE_P(
2303 AllOpenCL100DebugInfoFail,
2304 ValidateOpenCL100DebugInfoDebugFunctionDeclaration,
2305 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2306 std::make_pair(
2307 R"(%u32_0 %main_type_info %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic)",
2308 "Name"),
2309 std::make_pair(
2310 R"(%main_name %dbg_src %dbg_src 12 1 %comp_unit %main_linkage_name FlagIsPublic)",
2311 "Type"),
2312 std::make_pair(
2313 R"(%main_name %main_type_info %comp_unit 12 1 %comp_unit %main_linkage_name FlagIsPublic)",
2314 "Source"),
2315 std::make_pair(
2316 R"(%main_name %main_type_info %dbg_src 12 1 %dbg_src %main_linkage_name FlagIsPublic)",
2317 "Parent"),
2318 std::make_pair(
2319 R"(%main_name %main_type_info %dbg_src 12 1 %comp_unit %void FlagIsPublic)",
2320 "Linkage Name"),
2321 }));
2322
TEST_F(ValidateOpenCL100DebugInfo,DebugLexicalBlock)2323 TEST_F(ValidateOpenCL100DebugInfo, DebugLexicalBlock) {
2324 const std::string src = R"(
2325 %src = OpString "simple.hlsl"
2326 %code = OpString "main() {}"
2327 %main_name = OpString "main"
2328 )";
2329
2330 const std::string dbg_inst_header = R"(
2331 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2332 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2333 %main_block = OpExtInst %void %DbgExt DebugLexicalBlock %dbg_src 1 1 %comp_unit %main_name)";
2334
2335 const std::string extension = R"(
2336 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2337 )";
2338
2339 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", dbg_inst_header,
2340 "", extension, "Vertex"));
2341 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2342 }
2343
TEST_P(ValidateOpenCL100DebugInfoDebugLexicalBlock,Fail)2344 TEST_P(ValidateOpenCL100DebugInfoDebugLexicalBlock, Fail) {
2345 const std::string src = R"(
2346 %src = OpString "simple.hlsl"
2347 %code = OpString "main() {}"
2348 %main_name = OpString "main"
2349 )";
2350
2351 const auto& param = GetParam();
2352
2353 std::ostringstream ss;
2354 ss << R"(
2355 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2356 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2357 %main_block = OpExtInst %void %DbgExt DebugLexicalBlock )"
2358 << param.first;
2359
2360 const std::string extension = R"(
2361 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2362 )";
2363
2364 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, "", ss.str(), "",
2365 extension, "Vertex"));
2366 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2367 EXPECT_THAT(getDiagnosticString(),
2368 HasSubstr("expected operand " + param.second));
2369 }
2370
2371 INSTANTIATE_TEST_SUITE_P(
2372 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugLexicalBlock,
2373 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2374 std::make_pair(R"(%comp_unit 1 1 %comp_unit %main_name)", "Source"),
2375 std::make_pair(R"(%dbg_src 1 1 %dbg_src %main_name)", "Parent"),
2376 std::make_pair(R"(%dbg_src 1 1 %comp_unit %void)", "Name"),
2377 }));
2378
TEST_F(ValidateOpenCL100DebugInfo,DebugScopeFailScope)2379 TEST_F(ValidateOpenCL100DebugInfo, DebugScopeFailScope) {
2380 const std::string src = R"(
2381 %src = OpString "simple.hlsl"
2382 %code = OpString "void main() {}"
2383 )";
2384
2385 const std::string dbg_inst_header = R"(
2386 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2387 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2388 )";
2389
2390 const std::string body = R"(
2391 %main_scope = OpExtInst %void %DbgExt DebugScope %dbg_src
2392 )";
2393
2394 const std::string extension = R"(
2395 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2396 )";
2397
2398 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2399 src, "", dbg_inst_header, body, extension, "Vertex"));
2400 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2401 EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Scope"));
2402 }
2403
TEST_F(ValidateOpenCL100DebugInfo,DebugScopeFailInlinedAt)2404 TEST_F(ValidateOpenCL100DebugInfo, DebugScopeFailInlinedAt) {
2405 const std::string src = R"(
2406 %src = OpString "simple.hlsl"
2407 %code = OpString "void main() {}"
2408 )";
2409
2410 const std::string dbg_inst_header = R"(
2411 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2412 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2413 )";
2414
2415 const std::string body = R"(
2416 %main_scope = OpExtInst %void %DbgExt DebugScope %comp_unit %dbg_src
2417 )";
2418
2419 const std::string extension = R"(
2420 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2421 )";
2422
2423 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2424 src, "", dbg_inst_header, body, extension, "Vertex"));
2425 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2426 EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Inlined At"));
2427 }
2428
TEST_F(ValidateOpenCL100DebugInfo,DebugLocalVariable)2429 TEST_F(ValidateOpenCL100DebugInfo, DebugLocalVariable) {
2430 const std::string src = R"(
2431 %src = OpString "simple.hlsl"
2432 %code = OpString "void main() { float foo; }"
2433 %float_name = OpString "float"
2434 %foo_name = OpString "foo"
2435 )";
2436
2437 const std::string size_const = R"(
2438 %int_32 = OpConstant %u32 32
2439 )";
2440
2441 const std::string dbg_inst_header = R"(
2442 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2443 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2444 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2445 %foo = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
2446 )";
2447
2448 const std::string extension = R"(
2449 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2450 )";
2451
2452 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2453 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2454 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2455 }
2456
TEST_P(ValidateOpenCL100DebugInfoDebugLocalVariable,Fail)2457 TEST_P(ValidateOpenCL100DebugInfoDebugLocalVariable, Fail) {
2458 const std::string src = R"(
2459 %src = OpString "simple.hlsl"
2460 %code = OpString "void main() { float foo; }"
2461 %float_name = OpString "float"
2462 %foo_name = OpString "foo"
2463 )";
2464
2465 const std::string size_const = R"(
2466 %int_32 = OpConstant %u32 32
2467 )";
2468
2469 const auto& param = GetParam();
2470
2471 std::ostringstream ss;
2472 ss << R"(
2473 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2474 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2475 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2476 %foo = OpExtInst %void %DbgExt DebugLocalVariable )"
2477 << param.first;
2478
2479 const std::string extension = R"(
2480 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2481 )";
2482
2483 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
2484 "", extension, "Vertex"));
2485 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2486 EXPECT_THAT(getDiagnosticString(),
2487 HasSubstr("expected operand " + param.second));
2488 }
2489
2490 INSTANTIATE_TEST_SUITE_P(
2491 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugLocalVariable,
2492 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2493 std::make_pair(
2494 R"(%void %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0)",
2495 "Name"),
2496 std::make_pair(
2497 R"(%foo_name %dbg_src %dbg_src 1 10 %comp_unit FlagIsLocal 0)",
2498 "Type"),
2499 std::make_pair(
2500 R"(%foo_name %float_info %comp_unit 1 10 %comp_unit FlagIsLocal 0)",
2501 "Source"),
2502 std::make_pair(
2503 R"(%foo_name %float_info %dbg_src 1 10 %dbg_src FlagIsLocal 0)",
2504 "Parent"),
2505 }));
2506
TEST_F(ValidateOpenCL100DebugInfo,DebugDeclare)2507 TEST_F(ValidateOpenCL100DebugInfo, DebugDeclare) {
2508 const std::string src = R"(
2509 %src = OpString "simple.hlsl"
2510 %code = OpString "void main() { float foo; }"
2511 %float_name = OpString "float"
2512 %foo_name = OpString "foo"
2513 )";
2514
2515 const std::string size_const = R"(
2516 %int_32 = OpConstant %u32 32
2517 )";
2518
2519 const std::string dbg_inst_header = R"(
2520 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2521 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2522 %null_expr = OpExtInst %void %DbgExt DebugExpression
2523 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2524 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
2525 )";
2526
2527 const std::string body = R"(
2528 %foo = OpVariable %f32_ptr_function Function
2529 %decl = OpExtInst %void %DbgExt DebugDeclare %foo_info %foo %null_expr
2530 )";
2531
2532 const std::string extension = R"(
2533 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2534 )";
2535
2536 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2537 src, size_const, dbg_inst_header, body, extension, "Vertex"));
2538 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2539 }
2540
TEST_F(ValidateOpenCL100DebugInfo,DebugDeclareParam)2541 TEST_F(ValidateOpenCL100DebugInfo, DebugDeclareParam) {
2542 CompileSuccessfully(R"(
2543 OpCapability Shader
2544 %1 = OpExtInstImport "OpenCL.DebugInfo.100"
2545 OpMemoryModel Logical GLSL450
2546 OpEntryPoint Vertex %main "main" %in_var_COLOR
2547 %4 = OpString "test.hlsl"
2548 OpSource HLSL 620 %4 "#line 1 \"test.hlsl\"
2549 void main(float foo:COLOR) {}
2550 "
2551 %11 = OpString "#line 1 \"test.hlsl\"
2552 void main(float foo:COLOR) {}
2553 "
2554 %14 = OpString "float"
2555 %17 = OpString "src.main"
2556 %20 = OpString "foo"
2557 OpName %in_var_COLOR "in.var.COLOR"
2558 OpName %main "main"
2559 OpName %param_var_foo "param.var.foo"
2560 OpName %src_main "src.main"
2561 OpName %foo "foo"
2562 OpName %bb_entry "bb.entry"
2563 OpDecorate %in_var_COLOR Location 0
2564 %uint = OpTypeInt 32 0
2565 %uint_32 = OpConstant %uint 32
2566 %float = OpTypeFloat 32
2567 %_ptr_Input_float = OpTypePointer Input %float
2568 %void = OpTypeVoid
2569 %23 = OpTypeFunction %void
2570 %_ptr_Function_float = OpTypePointer Function %float
2571 %29 = OpTypeFunction %void %_ptr_Function_float
2572 OpLine %4 1 21
2573 %in_var_COLOR = OpVariable %_ptr_Input_float Input
2574 %10 = OpExtInst %void %1 DebugExpression
2575 %12 = OpExtInst %void %1 DebugSource %4 %11
2576 %13 = OpExtInst %void %1 DebugCompilationUnit 1 4 %12 HLSL
2577 %15 = OpExtInst %void %1 DebugTypeBasic %14 %uint_32 Float
2578 %16 = OpExtInst %void %1 DebugTypeFunction FlagIsProtected|FlagIsPrivate %void %15
2579 %18 = OpExtInst %void %1 DebugFunction %17 %16 %12 1 1 %13 %17 FlagIsProtected|FlagIsPrivate 1 %src_main
2580 %21 = OpExtInst %void %1 DebugLocalVariable %20 %15 %12 1 17 %18 FlagIsLocal 0
2581 %22 = OpExtInst %void %1 DebugLexicalBlock %12 1 28 %18
2582 OpLine %4 1 1
2583 %main = OpFunction %void None %23
2584 %24 = OpLabel
2585 OpLine %4 1 17
2586 %param_var_foo = OpVariable %_ptr_Function_float Function
2587 %27 = OpLoad %float %in_var_COLOR
2588 OpLine %4 1 1
2589 %28 = OpFunctionCall %void %src_main %param_var_foo
2590 OpReturn
2591 OpFunctionEnd
2592 %src_main = OpFunction %void None %29
2593 OpLine %4 1 17
2594 %foo = OpFunctionParameter %_ptr_Function_float
2595 %31 = OpExtInst %void %1 DebugDeclare %21 %foo %10
2596 %bb_entry = OpLabel
2597 OpLine %4 1 29
2598 OpReturn
2599 OpFunctionEnd
2600 )");
2601 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2602 }
2603
2604 TEST_P(ValidateOpenCL100DebugInfoDebugDeclare, Fail) {
2605 const std::string src = R"(
2606 %src = OpString "simple.hlsl"
2607 %code = OpString "void main() { float foo; }"
2608 %float_name = OpString "float"
2609 %foo_name = OpString "foo"
2610 )";
2611
2612 const std::string size_const = R"(
2613 %int_32 = OpConstant %u32 32
2614 )";
2615
2616 const std::string dbg_inst_header = R"(
2617 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2618 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2619 %null_expr = OpExtInst %void %DbgExt DebugExpression
2620 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2621 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
2622 )";
2623
2624 const auto& param = GetParam();
2625
2626 std::ostringstream ss;
2627 ss << R"(
2628 %foo = OpVariable %f32_ptr_function Function
2629 %decl = OpExtInst %void %DbgExt DebugDeclare )"
2630 << param.first;
2631
2632 const std::string extension = R"(
2633 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2634 )";
2635
2636 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2637 src, size_const, dbg_inst_header, ss.str(), extension, "Vertex"));
2638 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2639 EXPECT_THAT(getDiagnosticString(),
2640 HasSubstr("expected operand " + param.second));
2641 }
2642
2643 INSTANTIATE_TEST_SUITE_P(
2644 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugDeclare,
2645 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
2646 std::make_pair(R"(%dbg_src %foo %null_expr)", "Local Variable"),
2647 std::make_pair(R"(%foo_info %void %null_expr)", "Variable"),
2648 std::make_pair(R"(%foo_info %foo %dbg_src)", "Expression"),
2649 }));
2650
2651 TEST_F(ValidateOpenCL100DebugInfo, DebugExpression) {
2652 const std::string dbg_inst_header = R"(
2653 %op0 = OpExtInst %void %DbgExt DebugOperation Deref
2654 %op1 = OpExtInst %void %DbgExt DebugOperation Plus
2655 %null_expr = OpExtInst %void %DbgExt DebugExpression %op0 %op1
2656 )";
2657
2658 const std::string extension = R"(
2659 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2660 )";
2661
2662 CompileSuccessfully(GenerateShaderCodeForDebugInfo("", "", dbg_inst_header,
2663 "", extension, "Vertex"));
2664 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2665 }
2666
2667 TEST_F(ValidateOpenCL100DebugInfo, DebugExpressionFail) {
2668 const std::string dbg_inst_header = R"(
2669 %op = OpExtInst %void %DbgExt DebugOperation Deref
2670 %null_expr = OpExtInst %void %DbgExt DebugExpression %op %void
2671 )";
2672
2673 const std::string extension = R"(
2674 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2675 )";
2676
2677 CompileSuccessfully(GenerateShaderCodeForDebugInfo("", "", dbg_inst_header,
2678 "", extension, "Vertex"));
2679 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2680 EXPECT_THAT(
2681 getDiagnosticString(),
2682 HasSubstr(
2683 "expected operand Operation must be a result id of DebugOperation"));
2684 }
2685
2686 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeTemplate) {
2687 const std::string src = R"(
2688 %src = OpString "simple.hlsl"
2689 %code = OpString "OpaqueType foo;
2690 main() {}
2691 "
2692 %float_name = OpString "float"
2693 %ty_name = OpString "Texture"
2694 %t_name = OpString "T"
2695 )";
2696
2697 const std::string size_const = R"(
2698 %int_32 = OpConstant %u32 32
2699 %int_128 = OpConstant %u32 128
2700 )";
2701
2702 const std::string dbg_inst_header = R"(
2703 %dbg_none = OpExtInst %void %DbgExt DebugInfoNone
2704 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2705 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2706 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2707 %opaque = OpExtInst %void %DbgExt DebugTypeComposite %ty_name Class %dbg_src 1 1 %comp_unit %ty_name %dbg_none FlagIsPublic
2708 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0
2709 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %opaque %param
2710 )";
2711
2712 const std::string extension = R"(
2713 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2714 )";
2715
2716 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2717 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2718 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2719 }
2720
2721 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeTemplateUsedForVariableType) {
2722 const std::string src = R"(
2723 %src = OpString "simple.hlsl"
2724 %code = OpString "OpaqueType foo;
2725 main() {}
2726 "
2727 %float_name = OpString "float"
2728 %ty_name = OpString "Texture"
2729 %t_name = OpString "T"
2730 %foo_name = OpString "foo"
2731 )";
2732
2733 const std::string size_const = R"(
2734 %int_32 = OpConstant %u32 32
2735 %int_128 = OpConstant %u32 128
2736 )";
2737
2738 const std::string dbg_inst_header = R"(
2739 %dbg_none = OpExtInst %void %DbgExt DebugInfoNone
2740 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2741 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2742 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2743 %opaque = OpExtInst %void %DbgExt DebugTypeComposite %ty_name Class %dbg_src 1 1 %comp_unit %ty_name %dbg_none FlagIsPublic
2744 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0
2745 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %opaque %param
2746 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %temp %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate
2747 )";
2748
2749 const std::string extension = R"(
2750 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2751 )";
2752
2753 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2754 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2755 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2756 }
2757
2758 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeTemplateFunction) {
2759 const std::string src = R"(
2760 %src = OpString "simple.hlsl"
2761 %code = OpString "OpaqueType foo;
2762 main() {}
2763 "
2764 %float_name = OpString "float"
2765 %ty_name = OpString "Texture"
2766 %t_name = OpString "T"
2767 %main_name = OpString "main"
2768 )";
2769
2770 const std::string size_const = R"(
2771 %int_32 = OpConstant %u32 32
2772 %int_128 = OpConstant %u32 128
2773 )";
2774
2775 const std::string dbg_inst_header = R"(
2776 %dbg_none = OpExtInst %void %DbgExt DebugInfoNone
2777 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2778 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2779 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2780 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0
2781 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %param %param
2782 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main
2783 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %main_info %param
2784 )";
2785
2786 const std::string extension = R"(
2787 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2788 )";
2789
2790 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2791 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2792 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2793 }
2794
2795 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeTemplateFailTarget) {
2796 const std::string src = R"(
2797 %src = OpString "simple.hlsl"
2798 %code = OpString "OpaqueType foo;
2799 main() {}
2800 "
2801 %float_name = OpString "float"
2802 %ty_name = OpString "Texture"
2803 %t_name = OpString "T"
2804 %main_name = OpString "main"
2805 )";
2806
2807 const std::string size_const = R"(
2808 %int_32 = OpConstant %u32 32
2809 %int_128 = OpConstant %u32 128
2810 )";
2811
2812 const std::string dbg_inst_header = R"(
2813 %dbg_none = OpExtInst %void %DbgExt DebugInfoNone
2814 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2815 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2816 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2817 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0
2818 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %float_info %param
2819 )";
2820
2821 const std::string extension = R"(
2822 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2823 )";
2824
2825 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2826 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2827 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2828 EXPECT_THAT(getDiagnosticString(),
2829 HasSubstr("expected operand Target must be DebugTypeComposite or "
2830 "DebugFunction"));
2831 }
2832
2833 TEST_F(ValidateOpenCL100DebugInfo, DebugTypeTemplateFailParam) {
2834 const std::string src = R"(
2835 %src = OpString "simple.hlsl"
2836 %code = OpString "OpaqueType foo;
2837 main() {}
2838 "
2839 %float_name = OpString "float"
2840 %ty_name = OpString "Texture"
2841 %t_name = OpString "T"
2842 %main_name = OpString "main"
2843 )";
2844
2845 const std::string size_const = R"(
2846 %int_32 = OpConstant %u32 32
2847 %int_128 = OpConstant %u32 128
2848 )";
2849
2850 const std::string dbg_inst_header = R"(
2851 %dbg_none = OpExtInst %void %DbgExt DebugInfoNone
2852 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2853 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2854 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2855 %param = OpExtInst %void %DbgExt DebugTypeTemplateParameter %t_name %float_info %dbg_none %dbg_src 0 0
2856 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %param %param
2857 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_name FlagIsPublic 1 %main
2858 %temp = OpExtInst %void %DbgExt DebugTypeTemplate %main_info %float_info
2859 )";
2860
2861 const std::string extension = R"(
2862 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2863 )";
2864
2865 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2866 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2867 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
2868 EXPECT_THAT(
2869 getDiagnosticString(),
2870 HasSubstr(
2871 "expected operand Parameters must be DebugTypeTemplateParameter or "
2872 "DebugTypeTemplateTemplateParameter"));
2873 }
2874
2875 TEST_F(ValidateOpenCL100DebugInfo, DebugGlobalVariable) {
2876 const std::string src = R"(
2877 %src = OpString "simple.hlsl"
2878 %code = OpString "float foo; void main() {}"
2879 %float_name = OpString "float"
2880 %foo_name = OpString "foo"
2881 )";
2882
2883 const std::string size_const = R"(
2884 %int_32 = OpConstant %u32 32
2885 )";
2886
2887 const std::string dbg_inst_header = R"(
2888 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2889 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2890 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2891 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate
2892 )";
2893
2894 const std::string extension = R"(
2895 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2896 )";
2897
2898 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2899 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2900 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2901 }
2902
2903 TEST_F(ValidateOpenCL100DebugInfo, DebugGlobalVariableStaticMember) {
2904 const std::string src = R"(
2905 %src = OpString "simple.hlsl"
2906 %code = OpString "float foo; void main() {}"
2907 %float_name = OpString "float"
2908 %foo_name = OpString "foo"
2909 )";
2910
2911 const std::string size_const = R"(
2912 %int_32 = OpConstant %u32 32
2913 )";
2914
2915 const std::string dbg_inst_header = R"(
2916 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2917 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2918 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2919 %t = OpExtInst %void %DbgExt DebugTypeComposite %foo_name Class %dbg_src 0 0 %comp_unit %foo_name %int_32 FlagIsPublic %a
2920 %a = OpExtInst %void %DbgExt DebugTypeMember %foo_name %float_info %dbg_src 0 0 %t %u32_0 %int_32 FlagIsPublic
2921 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate %a
2922 )";
2923
2924 const std::string extension = R"(
2925 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2926 )";
2927
2928 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2929 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2930 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2931 }
2932
2933 TEST_F(ValidateOpenCL100DebugInfo, DebugGlobalVariableDebugInfoNone) {
2934 const std::string src = R"(
2935 %src = OpString "simple.hlsl"
2936 %code = OpString "float foo; void main() {}"
2937 %float_name = OpString "float"
2938 %foo_name = OpString "foo"
2939 )";
2940
2941 const std::string size_const = R"(
2942 %int_32 = OpConstant %u32 32
2943 )";
2944
2945 const std::string dbg_inst_header = R"(
2946 %dbgNone = OpExtInst %void %DbgExt DebugInfoNone
2947 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2948 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2949 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2950 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %dbgNone FlagIsProtected|FlagIsPrivate
2951 )";
2952
2953 const std::string extension = R"(
2954 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2955 )";
2956
2957 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2958 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2959 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2960 }
2961
2962 TEST_F(ValidateOpenCL100DebugInfo, DebugGlobalVariableConst) {
2963 const std::string src = R"(
2964 %src = OpString "simple.hlsl"
2965 %code = OpString "float foo; void main() {}"
2966 %float_name = OpString "float"
2967 %foo_name = OpString "foo"
2968 )";
2969
2970 const std::string size_const = R"(
2971 %int_32 = OpConstant %u32 32
2972 )";
2973
2974 const std::string dbg_inst_header = R"(
2975 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
2976 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
2977 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
2978 %foo = OpExtInst %void %DbgExt DebugGlobalVariable %foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %int_32 FlagIsProtected|FlagIsPrivate
2979 )";
2980
2981 const std::string extension = R"(
2982 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
2983 )";
2984
2985 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
2986 src, size_const, dbg_inst_header, "", extension, "Vertex"));
2987 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
2988 }
2989
2990 TEST_P(ValidateOpenCL100DebugInfoDebugGlobalVariable, Fail) {
2991 const std::string src = R"(
2992 %src = OpString "simple.hlsl"
2993 %code = OpString "float foo; void main() {}"
2994 %float_name = OpString "float"
2995 %foo_name = OpString "foo"
2996 )";
2997
2998 const std::string size_const = R"(
2999 %int_32 = OpConstant %u32 32
3000 )";
3001
3002 const auto& param = GetParam();
3003
3004 std::ostringstream ss;
3005 ss << R"(
3006 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3007 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3008 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
3009 %foo = OpExtInst %void %DbgExt DebugGlobalVariable )"
3010 << param.first;
3011
3012 const std::string extension = R"(
3013 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3014 )";
3015
3016 CompileSuccessfully(GenerateShaderCodeForDebugInfo(src, size_const, ss.str(),
3017 "", extension, "Vertex"));
3018 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3019 EXPECT_THAT(getDiagnosticString(),
3020 HasSubstr("expected operand " + param.second));
3021 }
3022
3023 INSTANTIATE_TEST_SUITE_P(
3024 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugGlobalVariable,
3025 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
3026 std::make_pair(
3027 R"(%void %float_info %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate)",
3028 "Name"),
3029 std::make_pair(
3030 R"(%foo_name %dbg_src %dbg_src 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate)",
3031 "Type"),
3032 std::make_pair(
3033 R"(%foo_name %float_info %comp_unit 0 0 %comp_unit %foo_name %f32_input FlagIsProtected|FlagIsPrivate)",
3034 "Source"),
3035 std::make_pair(
3036 R"(%foo_name %float_info %dbg_src 0 0 %dbg_src %foo_name %f32_input FlagIsProtected|FlagIsPrivate)",
3037 "Scope"),
3038 std::make_pair(
3039 R"(%foo_name %float_info %dbg_src 0 0 %comp_unit %void %f32_input FlagIsProtected|FlagIsPrivate)",
3040 "Linkage Name"),
3041 std::make_pair(
3042 R"(%foo_name %float_info %dbg_src 0 0 %comp_unit %foo_name %void FlagIsProtected|FlagIsPrivate)",
3043 "Variable"),
3044 }));
3045
3046 TEST_F(ValidateOpenCL100DebugInfo, DebugInlinedAt) {
3047 const std::string src = R"(
3048 %src = OpString "simple.hlsl"
3049 %code = OpString "void main() {}"
3050 %void_name = OpString "void"
3051 %main_name = OpString "main"
3052 %main_linkage_name = OpString "v_main"
3053 )";
3054
3055 const std::string dbg_inst_header = R"(
3056 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3057 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3058 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
3059 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main
3060 %inlined_at = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info
3061 %inlined_at_recursive = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info %inlined_at
3062 )";
3063
3064 const std::string body = R"(
3065 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info %inlined_at
3066 )";
3067
3068 const std::string extension = R"(
3069 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3070 )";
3071
3072 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
3073 src, "", dbg_inst_header, body, extension, "Vertex"));
3074 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3075 }
3076
3077 TEST_F(ValidateOpenCL100DebugInfo, DebugInlinedAtFail) {
3078 const std::string src = R"(
3079 %src = OpString "simple.hlsl"
3080 %code = OpString "void main() {}"
3081 %void_name = OpString "void"
3082 %main_name = OpString "main"
3083 %main_linkage_name = OpString "v_main"
3084 )";
3085
3086 const std::string dbg_inst_header = R"(
3087 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3088 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3089 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
3090 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main
3091 %inlined_at = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info
3092 %inlined_at_recursive = OpExtInst %void %DbgExt DebugInlinedAt 0 %inlined_at
3093 )";
3094
3095 const std::string body = R"(
3096 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info %inlined_at
3097 )";
3098
3099 const std::string extension = R"(
3100 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3101 )";
3102
3103 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
3104 src, "", dbg_inst_header, body, extension, "Vertex"));
3105 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3106 EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Scope"));
3107 }
3108
3109 TEST_F(ValidateOpenCL100DebugInfo, DebugInlinedAtFail2) {
3110 const std::string src = R"(
3111 %src = OpString "simple.hlsl"
3112 %code = OpString "void main() {}"
3113 %void_name = OpString "void"
3114 %main_name = OpString "main"
3115 %main_linkage_name = OpString "v_main"
3116 )";
3117
3118 const std::string dbg_inst_header = R"(
3119 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3120 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3121 %main_type_info = OpExtInst %void %DbgExt DebugTypeFunction FlagIsPublic %void
3122 %main_info = OpExtInst %void %DbgExt DebugFunction %main_name %main_type_info %dbg_src 1 1 %comp_unit %main_linkage_name FlagIsPublic 1 %main
3123 %inlined_at = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info
3124 %inlined_at_recursive = OpExtInst %void %DbgExt DebugInlinedAt 0 %main_info %main_info
3125 )";
3126
3127 const std::string body = R"(
3128 %main_scope = OpExtInst %void %DbgExt DebugScope %main_info %inlined_at
3129 )";
3130
3131 const std::string extension = R"(
3132 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3133 )";
3134
3135 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
3136 src, "", dbg_inst_header, body, extension, "Vertex"));
3137 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3138 EXPECT_THAT(getDiagnosticString(), HasSubstr("expected operand Inlined"));
3139 }
3140
3141 TEST_F(ValidateOpenCL100DebugInfo, DebugValue) {
3142 const std::string src = R"(
3143 %src = OpString "simple.hlsl"
3144 %code = OpString "void main() { float foo; }"
3145 %float_name = OpString "float"
3146 %foo_name = OpString "foo"
3147 )";
3148
3149 const std::string size_const = R"(
3150 %int_3 = OpConstant %u32 3
3151 %int_32 = OpConstant %u32 32
3152 )";
3153
3154 const std::string dbg_inst_header = R"(
3155 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3156 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3157 %null_expr = OpExtInst %void %DbgExt DebugExpression
3158 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
3159 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
3160 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %v4float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
3161 )";
3162
3163 const std::string body = R"(
3164 %value = OpExtInst %void %DbgExt DebugValue %foo_info %int_32 %null_expr %int_3
3165 )";
3166
3167 const std::string extension = R"(
3168 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3169 )";
3170
3171 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
3172 src, size_const, dbg_inst_header, body, extension, "Vertex"));
3173 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3174 }
3175
3176 TEST_F(ValidateOpenCL100DebugInfo, DebugValueWithVariableIndex) {
3177 const std::string src = R"(
3178 %src = OpString "simple.hlsl"
3179 %code = OpString "void main() { float foo; }"
3180 %float_name = OpString "float"
3181 %int_name = OpString "int"
3182 %foo_name = OpString "foo"
3183 %len_name = OpString "length"
3184 )";
3185
3186 const std::string size_const = R"(
3187 %int_3 = OpConstant %u32 3
3188 %int_32 = OpConstant %u32 32
3189 )";
3190
3191 const std::string dbg_inst_header = R"(
3192 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3193 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3194 %null_expr = OpExtInst %void %DbgExt DebugExpression
3195 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
3196 %int_info = OpExtInst %void %DbgExt DebugTypeBasic %int_name %int_32 Signed
3197 %v4float_info = OpExtInst %void %DbgExt DebugTypeVector %float_info 4
3198 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %v4float_info %dbg_src 1 10 %comp_unit FlagIsLocal
3199 %len_info = OpExtInst %void %DbgExt DebugLocalVariable %len_name %int_info %dbg_src 0 0 %comp_unit FlagIsLocal
3200 )";
3201
3202 const std::string body = R"(
3203 %value = OpExtInst %void %DbgExt DebugValue %foo_info %int_32 %null_expr %len_info
3204 )";
3205
3206 const std::string extension = R"(
3207 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3208 )";
3209
3210 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
3211 src, size_const, dbg_inst_header, body, extension, "Vertex"));
3212 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3213 }
3214
3215 TEST_P(ValidateOpenCL100DebugInfoDebugValue, Fail) {
3216 const std::string src = R"(
3217 %src = OpString "simple.hlsl"
3218 %code = OpString "void main() { float foo; }"
3219 %float_name = OpString "float"
3220 %foo_name = OpString "foo"
3221 )";
3222
3223 const std::string size_const = R"(
3224 %int_32 = OpConstant %u32 32
3225 )";
3226
3227 const std::string dbg_inst_header = R"(
3228 %dbg_src = OpExtInst %void %DbgExt DebugSource %src %code
3229 %comp_unit = OpExtInst %void %DbgExt DebugCompilationUnit 2 4 %dbg_src HLSL
3230 %null_expr = OpExtInst %void %DbgExt DebugExpression
3231 %float_info = OpExtInst %void %DbgExt DebugTypeBasic %float_name %int_32 Float
3232 %foo_info = OpExtInst %void %DbgExt DebugLocalVariable %foo_name %float_info %dbg_src 1 10 %comp_unit FlagIsLocal 0
3233 )";
3234
3235 const auto& param = GetParam();
3236
3237 std::ostringstream ss;
3238 ss << R"(
3239 %decl = OpExtInst %void %DbgExt DebugValue )"
3240 << param.first;
3241
3242 const std::string extension = R"(
3243 %DbgExt = OpExtInstImport "OpenCL.DebugInfo.100"
3244 )";
3245
3246 CompileSuccessfully(GenerateShaderCodeForDebugInfo(
3247 src, size_const, dbg_inst_header, ss.str(), extension, "Vertex"));
3248 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3249 EXPECT_THAT(getDiagnosticString(),
3250 HasSubstr("expected operand " + param.second));
3251 }
3252
3253 INSTANTIATE_TEST_SUITE_P(
3254 AllOpenCL100DebugInfoFail, ValidateOpenCL100DebugInfoDebugValue,
3255 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
3256 std::make_pair(R"(%dbg_src %int_32 %null_expr)", "Local Variable"),
3257 std::make_pair(R"(%foo_info %int_32 %dbg_src)", "Expression"),
3258 std::make_pair(R"(%foo_info %int_32 %null_expr %dbg_src)", "Indexes"),
3259 }));
3260
3261 TEST_P(ValidateGlslStd450SqrtLike, IntResultType) {
3262 const std::string ext_inst_name = GetParam();
3263 const std::string body =
3264 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
3265
3266 CompileSuccessfully(GenerateShaderCode(body));
3267 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3268 EXPECT_THAT(getDiagnosticString(),
3269 HasSubstr("GLSL.std.450 " + ext_inst_name +
3270 ": expected Result Type to be a float scalar "
3271 "or vector type"));
3272 }
3273
3274 TEST_P(ValidateGlslStd450SqrtLike, IntOperand) {
3275 const std::string ext_inst_name = GetParam();
3276 const std::string body =
3277 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
3278
3279 CompileSuccessfully(GenerateShaderCode(body));
3280 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3281 EXPECT_THAT(getDiagnosticString(),
3282 HasSubstr("GLSL.std.450 " + ext_inst_name +
3283 ": expected types of all operands to be equal to "
3284 "Result Type"));
3285 }
3286
3287 INSTANTIATE_TEST_SUITE_P(AllSqrtLike, ValidateGlslStd450SqrtLike,
3288 ::testing::ValuesIn(std::vector<std::string>{
3289 "Round",
3290 "RoundEven",
3291 "FAbs",
3292 "Trunc",
3293 "FSign",
3294 "Floor",
3295 "Ceil",
3296 "Fract",
3297 "Sqrt",
3298 "InverseSqrt",
3299 "Normalize",
3300 }));
3301
3302 TEST_P(ValidateGlslStd450FMinLike, Success) {
3303 const std::string ext_inst_name = GetParam();
3304 std::ostringstream ss;
3305 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
3306 << " %f32_0 %f32_1\n";
3307 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
3308 << " %f32vec2_01 %f32vec2_12\n";
3309 ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
3310 << " %f64_0 %f64_0\n";
3311 CompileSuccessfully(GenerateShaderCode(ss.str()));
3312 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3313 }
3314
3315 TEST_P(ValidateGlslStd450FMinLike, IntResultType) {
3316 const std::string ext_inst_name = GetParam();
3317 const std::string body =
3318 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n";
3319
3320 CompileSuccessfully(GenerateShaderCode(body));
3321 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3322 EXPECT_THAT(getDiagnosticString(),
3323 HasSubstr("GLSL.std.450 " + ext_inst_name +
3324 ": expected Result Type to be a float scalar "
3325 "or vector type"));
3326 }
3327
3328 TEST_P(ValidateGlslStd450FMinLike, IntOperand1) {
3329 const std::string ext_inst_name = GetParam();
3330 const std::string body =
3331 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
3332
3333 CompileSuccessfully(GenerateShaderCode(body));
3334 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3335 EXPECT_THAT(getDiagnosticString(),
3336 HasSubstr("GLSL.std.450 " + ext_inst_name +
3337 ": expected types of all operands to be equal to "
3338 "Result Type"));
3339 }
3340
3341 TEST_P(ValidateGlslStd450FMinLike, IntOperand2) {
3342 const std::string ext_inst_name = GetParam();
3343 const std::string body =
3344 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
3345
3346 CompileSuccessfully(GenerateShaderCode(body));
3347 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3348 EXPECT_THAT(getDiagnosticString(),
3349 HasSubstr("GLSL.std.450 " + ext_inst_name +
3350 ": expected types of all operands to be equal to "
3351 "Result Type"));
3352 }
3353
3354 INSTANTIATE_TEST_SUITE_P(AllFMinLike, ValidateGlslStd450FMinLike,
3355 ::testing::ValuesIn(std::vector<std::string>{
3356 "FMin",
3357 "FMax",
3358 "Step",
3359 "Reflect",
3360 "NMin",
3361 "NMax",
3362 }));
3363
3364 TEST_P(ValidateGlslStd450FClampLike, Success) {
3365 const std::string ext_inst_name = GetParam();
3366 std::ostringstream ss;
3367 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
3368 << " %f32_0 %f32_1 %f32_2\n";
3369 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
3370 << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n";
3371 ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
3372 << " %f64_0 %f64_0 %f64_1\n";
3373 CompileSuccessfully(GenerateShaderCode(ss.str()));
3374 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3375 }
3376
3377 TEST_P(ValidateGlslStd450FClampLike, IntResultType) {
3378 const std::string ext_inst_name = GetParam();
3379 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
3380 " %f32_0 %f32_1 %f32_2\n";
3381
3382 CompileSuccessfully(GenerateShaderCode(body));
3383 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3384 EXPECT_THAT(getDiagnosticString(),
3385 HasSubstr("GLSL.std.450 " + ext_inst_name +
3386 ": expected Result Type to be a float scalar "
3387 "or vector type"));
3388 }
3389
3390 TEST_P(ValidateGlslStd450FClampLike, IntOperand1) {
3391 const std::string ext_inst_name = GetParam();
3392 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
3393 " %u32_0 %f32_0 %f32_1\n";
3394
3395 CompileSuccessfully(GenerateShaderCode(body));
3396 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3397 EXPECT_THAT(getDiagnosticString(),
3398 HasSubstr("GLSL.std.450 " + ext_inst_name +
3399 ": expected types of all operands to be equal to "
3400 "Result Type"));
3401 }
3402
3403 TEST_P(ValidateGlslStd450FClampLike, IntOperand2) {
3404 const std::string ext_inst_name = GetParam();
3405 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
3406 " %f32_0 %u32_0 %f32_1\n";
3407
3408 CompileSuccessfully(GenerateShaderCode(body));
3409 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3410 EXPECT_THAT(getDiagnosticString(),
3411 HasSubstr("GLSL.std.450 " + ext_inst_name +
3412 ": expected types of all operands to be equal to "
3413 "Result Type"));
3414 }
3415
3416 TEST_P(ValidateGlslStd450FClampLike, IntOperand3) {
3417 const std::string ext_inst_name = GetParam();
3418 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
3419 " %f32_1 %f32_0 %u32_2\n";
3420
3421 CompileSuccessfully(GenerateShaderCode(body));
3422 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3423 EXPECT_THAT(getDiagnosticString(),
3424 HasSubstr("GLSL.std.450 " + ext_inst_name +
3425 ": expected types of all operands to be equal to "
3426 "Result Type"));
3427 }
3428
3429 INSTANTIATE_TEST_SUITE_P(AllFClampLike, ValidateGlslStd450FClampLike,
3430 ::testing::ValuesIn(std::vector<std::string>{
3431 "FClamp",
3432 "FMix",
3433 "SmoothStep",
3434 "Fma",
3435 "FaceForward",
3436 "NClamp",
3437 }));
3438
3439 TEST_P(ValidateGlslStd450SAbsLike, Success) {
3440 const std::string ext_inst_name = GetParam();
3441 std::ostringstream ss;
3442 ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name << " %u32_1\n";
3443 ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name << " %s32_1\n";
3444 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
3445 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %s32_1\n";
3446 ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3447 << " %s32vec2_01\n";
3448 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3449 << " %u32vec2_01\n";
3450 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3451 << " %s32vec2_01\n";
3452 ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3453 << " %u32vec2_01\n";
3454 CompileSuccessfully(GenerateShaderCode(ss.str()));
3455 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3456 }
3457
3458 TEST_P(ValidateGlslStd450SAbsLike, FloatResultType) {
3459 const std::string ext_inst_name = GetParam();
3460 const std::string body =
3461 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
3462
3463 CompileSuccessfully(GenerateShaderCode(body));
3464 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3465 EXPECT_THAT(getDiagnosticString(),
3466 HasSubstr("GLSL.std.450 " + ext_inst_name +
3467 ": expected Result Type to be an int scalar "
3468 "or vector type"));
3469 }
3470
3471 TEST_P(ValidateGlslStd450SAbsLike, FloatOperand) {
3472 const std::string ext_inst_name = GetParam();
3473 const std::string body =
3474 "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %f32_0\n";
3475
3476 CompileSuccessfully(GenerateShaderCode(body));
3477 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3478 EXPECT_THAT(getDiagnosticString(),
3479 HasSubstr("GLSL.std.450 " + ext_inst_name +
3480 ": expected all operands to be int scalars or "
3481 "vectors"));
3482 }
3483
3484 TEST_P(ValidateGlslStd450SAbsLike, WrongDimOperand) {
3485 const std::string ext_inst_name = GetParam();
3486 const std::string body =
3487 "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %s32vec2_01\n";
3488
3489 CompileSuccessfully(GenerateShaderCode(body));
3490 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3491 EXPECT_THAT(getDiagnosticString(),
3492 HasSubstr("GLSL.std.450 " + ext_inst_name +
3493 ": expected all operands to have the same dimension as "
3494 "Result Type"));
3495 }
3496
3497 TEST_P(ValidateGlslStd450SAbsLike, WrongBitWidthOperand) {
3498 const std::string ext_inst_name = GetParam();
3499 const std::string body =
3500 "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s32_0\n";
3501
3502 CompileSuccessfully(GenerateShaderCode(body));
3503 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3504 EXPECT_THAT(getDiagnosticString(),
3505 HasSubstr("GLSL.std.450 " + ext_inst_name +
3506 ": expected all operands to have the same bit width as "
3507 "Result Type"));
3508 }
3509
3510 INSTANTIATE_TEST_SUITE_P(AllSAbsLike, ValidateGlslStd450SAbsLike,
3511 ::testing::ValuesIn(std::vector<std::string>{
3512 "SAbs",
3513 "SSign",
3514 "FindILsb",
3515 "FindUMsb",
3516 "FindSMsb",
3517 }));
3518
3519 TEST_F(ValidateExtInst, FindUMsbNot32Bit) {
3520 const std::string body = R"(
3521 %val1 = OpExtInst %s64 %extinst FindUMsb %u64_1
3522 )";
3523
3524 CompileSuccessfully(GenerateShaderCode(body));
3525 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3526 EXPECT_THAT(getDiagnosticString(),
3527 HasSubstr("GLSL.std.450 FindUMsb: this instruction is currently "
3528 "limited to 32-bit width components"));
3529 }
3530
3531 TEST_F(ValidateExtInst, FindSMsbNot32Bit) {
3532 const std::string body = R"(
3533 %val1 = OpExtInst %s64 %extinst FindSMsb %u64_1
3534 )";
3535
3536 CompileSuccessfully(GenerateShaderCode(body));
3537 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3538 EXPECT_THAT(getDiagnosticString(),
3539 HasSubstr("GLSL.std.450 FindSMsb: this instruction is currently "
3540 "limited to 32-bit width components"));
3541 }
3542
3543 TEST_P(ValidateGlslStd450UMinLike, Success) {
3544 const std::string ext_inst_name = GetParam();
3545 std::ostringstream ss;
3546 ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name
3547 << " %u32_1 %s32_2\n";
3548 ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name
3549 << " %s32_1 %u32_2\n";
3550 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
3551 << " %u32_1 %s32_2\n";
3552 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
3553 << " %s32_1 %u32_2\n";
3554 ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3555 << " %s32vec2_01 %u32vec2_01\n";
3556 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3557 << " %u32vec2_01 %s32vec2_01\n";
3558 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3559 << " %s32vec2_01 %u32vec2_01\n";
3560 ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3561 << " %u32vec2_01 %s32vec2_01\n";
3562 ss << "%val9 = OpExtInst %s64 %extinst " << ext_inst_name
3563 << " %u64_1 %s64_0\n";
3564 CompileSuccessfully(GenerateShaderCode(ss.str()));
3565 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3566 }
3567
3568 TEST_P(ValidateGlslStd450UMinLike, FloatResultType) {
3569 const std::string ext_inst_name = GetParam();
3570 const std::string body =
3571 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
3572
3573 CompileSuccessfully(GenerateShaderCode(body));
3574 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3575 EXPECT_THAT(getDiagnosticString(),
3576 HasSubstr("GLSL.std.450 " + ext_inst_name +
3577 ": expected Result Type to be an int scalar "
3578 "or vector type"));
3579 }
3580
3581 TEST_P(ValidateGlslStd450UMinLike, FloatOperand1) {
3582 const std::string ext_inst_name = GetParam();
3583 const std::string body =
3584 "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
3585
3586 CompileSuccessfully(GenerateShaderCode(body));
3587 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3588 EXPECT_THAT(getDiagnosticString(),
3589 HasSubstr("GLSL.std.450 " + ext_inst_name +
3590 ": expected all operands to be int scalars or "
3591 "vectors"));
3592 }
3593
3594 TEST_P(ValidateGlslStd450UMinLike, FloatOperand2) {
3595 const std::string ext_inst_name = GetParam();
3596 const std::string body =
3597 "%val1 = OpExtInst %s32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
3598
3599 CompileSuccessfully(GenerateShaderCode(body));
3600 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3601 EXPECT_THAT(getDiagnosticString(),
3602 HasSubstr("GLSL.std.450 " + ext_inst_name +
3603 ": expected all operands to be int scalars or "
3604 "vectors"));
3605 }
3606
3607 TEST_P(ValidateGlslStd450UMinLike, WrongDimOperand1) {
3608 const std::string ext_inst_name = GetParam();
3609 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3610 " %s32vec2_01 %s32_0\n";
3611
3612 CompileSuccessfully(GenerateShaderCode(body));
3613 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3614 EXPECT_THAT(getDiagnosticString(),
3615 HasSubstr("GLSL.std.450 " + ext_inst_name +
3616 ": expected all operands to have the same dimension as "
3617 "Result Type"));
3618 }
3619
3620 TEST_P(ValidateGlslStd450UMinLike, WrongDimOperand2) {
3621 const std::string ext_inst_name = GetParam();
3622 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3623 " %s32_0 %s32vec2_01\n";
3624
3625 CompileSuccessfully(GenerateShaderCode(body));
3626 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3627 EXPECT_THAT(getDiagnosticString(),
3628 HasSubstr("GLSL.std.450 " + ext_inst_name +
3629 ": expected all operands to have the same dimension as "
3630 "Result Type"));
3631 }
3632
3633 TEST_P(ValidateGlslStd450UMinLike, WrongBitWidthOperand1) {
3634 const std::string ext_inst_name = GetParam();
3635 const std::string body =
3636 "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s32_0 %s64_0\n";
3637
3638 CompileSuccessfully(GenerateShaderCode(body));
3639 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3640 EXPECT_THAT(getDiagnosticString(),
3641 HasSubstr("GLSL.std.450 " + ext_inst_name +
3642 ": expected all operands to have the same bit width as "
3643 "Result Type"));
3644 }
3645
3646 TEST_P(ValidateGlslStd450UMinLike, WrongBitWidthOperand2) {
3647 const std::string ext_inst_name = GetParam();
3648 const std::string body =
3649 "%val1 = OpExtInst %s64 %extinst " + ext_inst_name + " %s64_0 %s32_0\n";
3650
3651 CompileSuccessfully(GenerateShaderCode(body));
3652 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3653 EXPECT_THAT(getDiagnosticString(),
3654 HasSubstr("GLSL.std.450 " + ext_inst_name +
3655 ": expected all operands to have the same bit width as "
3656 "Result Type"));
3657 }
3658
3659 INSTANTIATE_TEST_SUITE_P(AllUMinLike, ValidateGlslStd450UMinLike,
3660 ::testing::ValuesIn(std::vector<std::string>{
3661 "UMin",
3662 "SMin",
3663 "UMax",
3664 "SMax",
3665 }));
3666
3667 TEST_P(ValidateGlslStd450UClampLike, Success) {
3668 const std::string ext_inst_name = GetParam();
3669 std::ostringstream ss;
3670 ss << "%val1 = OpExtInst %s32 %extinst " << ext_inst_name
3671 << " %s32_0 %u32_1 %s32_2\n";
3672 ss << "%val2 = OpExtInst %s32 %extinst " << ext_inst_name
3673 << " %u32_0 %s32_1 %u32_2\n";
3674 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
3675 << " %s32_0 %u32_1 %s32_2\n";
3676 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
3677 << " %u32_0 %s32_1 %u32_2\n";
3678 ss << "%val5 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3679 << " %s32vec2_01 %u32vec2_01 %u32vec2_12\n";
3680 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3681 << " %u32vec2_01 %s32vec2_01 %s32vec2_12\n";
3682 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
3683 << " %s32vec2_01 %u32vec2_01 %u32vec2_12\n";
3684 ss << "%val8 = OpExtInst %s32vec2 %extinst " << ext_inst_name
3685 << " %u32vec2_01 %s32vec2_01 %s32vec2_12\n";
3686 ss << "%val9 = OpExtInst %s64 %extinst " << ext_inst_name
3687 << " %u64_1 %s64_0 %s64_1\n";
3688 CompileSuccessfully(GenerateShaderCode(ss.str()));
3689 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3690 }
3691
3692 TEST_P(ValidateGlslStd450UClampLike, FloatResultType) {
3693 const std::string ext_inst_name = GetParam();
3694 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
3695 " %u32_0 %u32_0 %u32_1\n";
3696
3697 CompileSuccessfully(GenerateShaderCode(body));
3698 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3699 EXPECT_THAT(getDiagnosticString(),
3700 HasSubstr("GLSL.std.450 " + ext_inst_name +
3701 ": expected Result Type to be an int scalar "
3702 "or vector type"));
3703 }
3704
3705 TEST_P(ValidateGlslStd450UClampLike, FloatOperand1) {
3706 const std::string ext_inst_name = GetParam();
3707 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3708 " %f32_0 %u32_0 %u32_1\n";
3709
3710 CompileSuccessfully(GenerateShaderCode(body));
3711 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3712 EXPECT_THAT(getDiagnosticString(),
3713 HasSubstr("GLSL.std.450 " + ext_inst_name +
3714 ": expected all operands to be int scalars or "
3715 "vectors"));
3716 }
3717
3718 TEST_P(ValidateGlslStd450UClampLike, FloatOperand2) {
3719 const std::string ext_inst_name = GetParam();
3720 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3721 " %u32_0 %f32_0 %u32_1\n";
3722
3723 CompileSuccessfully(GenerateShaderCode(body));
3724 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3725 EXPECT_THAT(getDiagnosticString(),
3726 HasSubstr("GLSL.std.450 " + ext_inst_name +
3727 ": expected all operands to be int scalars or "
3728 "vectors"));
3729 }
3730
3731 TEST_P(ValidateGlslStd450UClampLike, FloatOperand3) {
3732 const std::string ext_inst_name = GetParam();
3733 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3734 " %u32_0 %u32_0 %f32_1\n";
3735
3736 CompileSuccessfully(GenerateShaderCode(body));
3737 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3738 EXPECT_THAT(getDiagnosticString(),
3739 HasSubstr("GLSL.std.450 " + ext_inst_name +
3740 ": expected all operands to be int scalars or "
3741 "vectors"));
3742 }
3743
3744 TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand1) {
3745 const std::string ext_inst_name = GetParam();
3746 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3747 " %s32vec2_01 %s32_0 %u32_1\n";
3748
3749 CompileSuccessfully(GenerateShaderCode(body));
3750 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3751 EXPECT_THAT(getDiagnosticString(),
3752 HasSubstr("GLSL.std.450 " + ext_inst_name +
3753 ": expected all operands to have the same dimension as "
3754 "Result Type"));
3755 }
3756
3757 TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand2) {
3758 const std::string ext_inst_name = GetParam();
3759 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3760 " %s32_0 %s32vec2_01 %u32_1\n";
3761
3762 CompileSuccessfully(GenerateShaderCode(body));
3763 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3764 EXPECT_THAT(getDiagnosticString(),
3765 HasSubstr("GLSL.std.450 " + ext_inst_name +
3766 ": expected all operands to have the same dimension as "
3767 "Result Type"));
3768 }
3769
3770 TEST_P(ValidateGlslStd450UClampLike, WrongDimOperand3) {
3771 const std::string ext_inst_name = GetParam();
3772 const std::string body = "%val1 = OpExtInst %s32 %extinst " + ext_inst_name +
3773 " %s32_0 %u32_1 %s32vec2_01\n";
3774
3775 CompileSuccessfully(GenerateShaderCode(body));
3776 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3777 EXPECT_THAT(getDiagnosticString(),
3778 HasSubstr("GLSL.std.450 " + ext_inst_name +
3779 ": expected all operands to have the same dimension as "
3780 "Result Type"));
3781 }
3782
3783 TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand1) {
3784 const std::string ext_inst_name = GetParam();
3785 const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
3786 " %s32_0 %s64_0 %s64_1\n";
3787
3788 CompileSuccessfully(GenerateShaderCode(body));
3789 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3790 EXPECT_THAT(getDiagnosticString(),
3791 HasSubstr("GLSL.std.450 " + ext_inst_name +
3792 ": expected all operands to have the same bit width as "
3793 "Result Type"));
3794 }
3795
3796 TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand2) {
3797 const std::string ext_inst_name = GetParam();
3798 const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
3799 " %s64_0 %s32_0 %s64_1\n";
3800
3801 CompileSuccessfully(GenerateShaderCode(body));
3802 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3803 EXPECT_THAT(getDiagnosticString(),
3804 HasSubstr("GLSL.std.450 " + ext_inst_name +
3805 ": expected all operands to have the same bit width as "
3806 "Result Type"));
3807 }
3808
3809 TEST_P(ValidateGlslStd450UClampLike, WrongBitWidthOperand3) {
3810 const std::string ext_inst_name = GetParam();
3811 const std::string body = "%val1 = OpExtInst %s64 %extinst " + ext_inst_name +
3812 " %s64_0 %s64_0 %s32_1\n";
3813
3814 CompileSuccessfully(GenerateShaderCode(body));
3815 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3816 EXPECT_THAT(getDiagnosticString(),
3817 HasSubstr("GLSL.std.450 " + ext_inst_name +
3818 ": expected all operands to have the same bit width as "
3819 "Result Type"));
3820 }
3821
3822 INSTANTIATE_TEST_SUITE_P(AllUClampLike, ValidateGlslStd450UClampLike,
3823 ::testing::ValuesIn(std::vector<std::string>{
3824 "UClamp",
3825 "SClamp",
3826 }));
3827
3828 TEST_P(ValidateGlslStd450SinLike, Success) {
3829 const std::string ext_inst_name = GetParam();
3830 std::ostringstream ss;
3831 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
3832 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
3833 << " %f32vec2_01\n";
3834 CompileSuccessfully(GenerateShaderCode(ss.str()));
3835 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3836 }
3837
3838 TEST_P(ValidateGlslStd450SinLike, IntResultType) {
3839 const std::string ext_inst_name = GetParam();
3840 const std::string body =
3841 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
3842
3843 CompileSuccessfully(GenerateShaderCode(body));
3844 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3845 EXPECT_THAT(getDiagnosticString(),
3846 HasSubstr("GLSL.std.450 " + ext_inst_name +
3847 ": expected Result Type to be a 16 or 32-bit scalar "
3848 "or vector float type"));
3849 }
3850
3851 TEST_P(ValidateGlslStd450SinLike, F64ResultType) {
3852 const std::string ext_inst_name = GetParam();
3853 const std::string body =
3854 "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32_0\n";
3855
3856 CompileSuccessfully(GenerateShaderCode(body));
3857 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3858 EXPECT_THAT(getDiagnosticString(),
3859 HasSubstr("GLSL.std.450 " + ext_inst_name +
3860 ": expected Result Type to be a 16 or 32-bit scalar "
3861 "or vector float type"));
3862 }
3863
3864 TEST_P(ValidateGlslStd450SinLike, IntOperand) {
3865 const std::string ext_inst_name = GetParam();
3866 const std::string body =
3867 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
3868
3869 CompileSuccessfully(GenerateShaderCode(body));
3870 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3871 EXPECT_THAT(getDiagnosticString(),
3872 HasSubstr("GLSL.std.450 " + ext_inst_name +
3873 ": expected types of all operands to be equal to "
3874 "Result Type"));
3875 }
3876
3877 INSTANTIATE_TEST_SUITE_P(AllSinLike, ValidateGlslStd450SinLike,
3878 ::testing::ValuesIn(std::vector<std::string>{
3879 "Radians",
3880 "Degrees",
3881 "Sin",
3882 "Cos",
3883 "Tan",
3884 "Asin",
3885 "Acos",
3886 "Atan",
3887 "Sinh",
3888 "Cosh",
3889 "Tanh",
3890 "Asinh",
3891 "Acosh",
3892 "Atanh",
3893 "Exp",
3894 "Exp2",
3895 "Log",
3896 "Log2",
3897 }));
3898
3899 TEST_P(ValidateGlslStd450PowLike, Success) {
3900 const std::string ext_inst_name = GetParam();
3901 std::ostringstream ss;
3902 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
3903 << " %f32_1 %f32_1\n";
3904 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
3905 << " %f32vec2_01 %f32vec2_12\n";
3906 CompileSuccessfully(GenerateShaderCode(ss.str()));
3907 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3908 }
3909
3910 TEST_P(ValidateGlslStd450PowLike, IntResultType) {
3911 const std::string ext_inst_name = GetParam();
3912 const std::string body =
3913 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_1 %f32_0\n";
3914
3915 CompileSuccessfully(GenerateShaderCode(body));
3916 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3917 EXPECT_THAT(getDiagnosticString(),
3918 HasSubstr("GLSL.std.450 " + ext_inst_name +
3919 ": expected Result Type to be a 16 or 32-bit scalar "
3920 "or vector float type"));
3921 }
3922
3923 TEST_P(ValidateGlslStd450PowLike, F64ResultType) {
3924 const std::string ext_inst_name = GetParam();
3925 const std::string body =
3926 "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32_1 %f32_0\n";
3927
3928 CompileSuccessfully(GenerateShaderCode(body));
3929 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3930 EXPECT_THAT(getDiagnosticString(),
3931 HasSubstr("GLSL.std.450 " + ext_inst_name +
3932 ": expected Result Type to be a 16 or 32-bit scalar "
3933 "or vector float type"));
3934 }
3935
3936 TEST_P(ValidateGlslStd450PowLike, IntOperand1) {
3937 const std::string ext_inst_name = GetParam();
3938 const std::string body =
3939 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
3940
3941 CompileSuccessfully(GenerateShaderCode(body));
3942 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3943 EXPECT_THAT(getDiagnosticString(),
3944 HasSubstr("GLSL.std.450 " + ext_inst_name +
3945 ": expected types of all operands to be equal to "
3946 "Result Type"));
3947 }
3948
3949 TEST_P(ValidateGlslStd450PowLike, IntOperand2) {
3950 const std::string ext_inst_name = GetParam();
3951 const std::string body =
3952 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
3953
3954 CompileSuccessfully(GenerateShaderCode(body));
3955 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3956 EXPECT_THAT(getDiagnosticString(),
3957 HasSubstr("GLSL.std.450 " + ext_inst_name +
3958 ": expected types of all operands to be equal to "
3959 "Result Type"));
3960 }
3961
3962 INSTANTIATE_TEST_SUITE_P(AllPowLike, ValidateGlslStd450PowLike,
3963 ::testing::ValuesIn(std::vector<std::string>{
3964 "Atan2",
3965 "Pow",
3966 }));
3967
3968 TEST_F(ValidateExtInst, GlslStd450DeterminantSuccess) {
3969 const std::string body = R"(
3970 %val1 = OpExtInst %f32 %extinst Determinant %f32mat22_1212
3971 )";
3972
3973 CompileSuccessfully(GenerateShaderCode(body));
3974 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
3975 }
3976
3977 TEST_F(ValidateExtInst, GlslStd450DeterminantIncompatibleResultType) {
3978 const std::string body = R"(
3979 %val1 = OpExtInst %f64 %extinst Determinant %f32mat22_1212
3980 )";
3981
3982 CompileSuccessfully(GenerateShaderCode(body));
3983 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3984 EXPECT_THAT(getDiagnosticString(),
3985 HasSubstr("GLSL.std.450 Determinant: "
3986 "expected operand X component type to be equal to "
3987 "Result Type"));
3988 }
3989
3990 TEST_F(ValidateExtInst, GlslStd450DeterminantNotMatrix) {
3991 const std::string body = R"(
3992 %val1 = OpExtInst %f32 %extinst Determinant %f32_1
3993 )";
3994
3995 CompileSuccessfully(GenerateShaderCode(body));
3996 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
3997 EXPECT_THAT(getDiagnosticString(),
3998 HasSubstr("GLSL.std.450 Determinant: "
3999 "expected operand X to be a square matrix"));
4000 }
4001
4002 TEST_F(ValidateExtInst, GlslStd450DeterminantMatrixNotSquare) {
4003 const std::string body = R"(
4004 %val1 = OpExtInst %f32 %extinst Determinant %f32mat23_121212
4005 )";
4006
4007 CompileSuccessfully(GenerateShaderCode(body));
4008 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4009 EXPECT_THAT(getDiagnosticString(),
4010 HasSubstr("GLSL.std.450 Determinant: "
4011 "expected operand X to be a square matrix"));
4012 }
4013
4014 TEST_F(ValidateExtInst, GlslStd450MatrixInverseSuccess) {
4015 const std::string body = R"(
4016 %val1 = OpExtInst %f32mat22 %extinst MatrixInverse %f32mat22_1212
4017 )";
4018
4019 CompileSuccessfully(GenerateShaderCode(body));
4020 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4021 }
4022
4023 TEST_F(ValidateExtInst, GlslStd450MatrixInverseIncompatibleResultType) {
4024 const std::string body = R"(
4025 %val1 = OpExtInst %f32mat33 %extinst MatrixInverse %f32mat22_1212
4026 )";
4027
4028 CompileSuccessfully(GenerateShaderCode(body));
4029 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4030 EXPECT_THAT(getDiagnosticString(),
4031 HasSubstr("GLSL.std.450 MatrixInverse: "
4032 "expected operand X type to be equal to "
4033 "Result Type"));
4034 }
4035
4036 TEST_F(ValidateExtInst, GlslStd450MatrixInverseNotMatrix) {
4037 const std::string body = R"(
4038 %val1 = OpExtInst %f32 %extinst MatrixInverse %f32mat22_1212
4039 )";
4040
4041 CompileSuccessfully(GenerateShaderCode(body));
4042 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4043 EXPECT_THAT(getDiagnosticString(),
4044 HasSubstr("GLSL.std.450 MatrixInverse: "
4045 "expected Result Type to be a square matrix"));
4046 }
4047
4048 TEST_F(ValidateExtInst, GlslStd450MatrixInverseMatrixNotSquare) {
4049 const std::string body = R"(
4050 %val1 = OpExtInst %f32mat23 %extinst MatrixInverse %f32mat23_121212
4051 )";
4052
4053 CompileSuccessfully(GenerateShaderCode(body));
4054 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4055 EXPECT_THAT(getDiagnosticString(),
4056 HasSubstr("GLSL.std.450 MatrixInverse: "
4057 "expected Result Type to be a square matrix"));
4058 }
4059
4060 TEST_F(ValidateExtInst, GlslStd450ModfSuccess) {
4061 const std::string body = R"(
4062 %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32_output
4063 %val2 = OpExtInst %f32vec2 %extinst Modf %f32vec2_01 %f32vec2_output
4064 )";
4065
4066 CompileSuccessfully(GenerateShaderCode(body));
4067 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4068 }
4069
4070 TEST_F(ValidateExtInst, GlslStd450ModfIntResultType) {
4071 const std::string body = R"(
4072 %val1 = OpExtInst %u32 %extinst Modf %f32_h %f32_output
4073 )";
4074
4075 CompileSuccessfully(GenerateShaderCode(body));
4076 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4077 EXPECT_THAT(getDiagnosticString(),
4078 HasSubstr("GLSL.std.450 Modf: "
4079 "expected Result Type to be a scalar or vector "
4080 "float type"));
4081 }
4082
4083 TEST_F(ValidateExtInst, GlslStd450ModfXNotOfResultType) {
4084 const std::string body = R"(
4085 %val1 = OpExtInst %f32 %extinst Modf %f64_0 %f32_output
4086 )";
4087
4088 CompileSuccessfully(GenerateShaderCode(body));
4089 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4090 EXPECT_THAT(getDiagnosticString(),
4091 HasSubstr("GLSL.std.450 Modf: "
4092 "expected operand X type to be equal to Result Type"));
4093 }
4094
4095 TEST_F(ValidateExtInst, GlslStd450ModfINotPointer) {
4096 const std::string body = R"(
4097 %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32_1
4098 )";
4099
4100 CompileSuccessfully(GenerateShaderCode(body));
4101 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4102 EXPECT_THAT(getDiagnosticString(),
4103 HasSubstr("GLSL.std.450 Modf: "
4104 "expected operand I to be a pointer"));
4105 }
4106
4107 TEST_F(ValidateExtInst, GlslStd450ModfIDataNotOfResultType) {
4108 const std::string body = R"(
4109 %val1 = OpExtInst %f32 %extinst Modf %f32_h %f32vec2_output
4110 )";
4111
4112 CompileSuccessfully(GenerateShaderCode(body));
4113 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4114 EXPECT_THAT(getDiagnosticString(),
4115 HasSubstr("GLSL.std.450 Modf: "
4116 "expected operand I data type to be equal to "
4117 "Result Type"));
4118 }
4119
4120 TEST_F(ValidateExtInst, GlslStd450ModfStructSuccess) {
4121 const std::string body = R"(
4122 %val1 = OpExtInst %struct_f32_f32 %extinst ModfStruct %f32_h
4123 %val2 = OpExtInst %struct_f32vec2_f32vec2 %extinst ModfStruct %f32vec2_01
4124 )";
4125
4126 CompileSuccessfully(GenerateShaderCode(body));
4127 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4128 }
4129
4130 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeNotStruct) {
4131 const std::string body = R"(
4132 %val1 = OpExtInst %f32 %extinst ModfStruct %f32_h
4133 )";
4134
4135 CompileSuccessfully(GenerateShaderCode(body));
4136 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4137 EXPECT_THAT(getDiagnosticString(),
4138 HasSubstr("GLSL.std.450 ModfStruct: "
4139 "expected Result Type to be a struct with two "
4140 "identical scalar or vector float type members"));
4141 }
4142
4143 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructWrongSize) {
4144 const std::string body = R"(
4145 %val1 = OpExtInst %struct_f32_f32_f32 %extinst ModfStruct %f32_h
4146 )";
4147
4148 CompileSuccessfully(GenerateShaderCode(body));
4149 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4150 EXPECT_THAT(getDiagnosticString(),
4151 HasSubstr("GLSL.std.450 ModfStruct: "
4152 "expected Result Type to be a struct with two "
4153 "identical scalar or vector float type members"));
4154 }
4155
4156 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructWrongFirstMember) {
4157 const std::string body = R"(
4158 %val1 = OpExtInst %struct_u32_f32 %extinst ModfStruct %f32_h
4159 )";
4160
4161 CompileSuccessfully(GenerateShaderCode(body));
4162 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4163 EXPECT_THAT(getDiagnosticString(),
4164 HasSubstr("GLSL.std.450 ModfStruct: "
4165 "expected Result Type to be a struct with two "
4166 "identical scalar or vector float type members"));
4167 }
4168
4169 TEST_F(ValidateExtInst, GlslStd450ModfStructResultTypeStructMembersNotEqual) {
4170 const std::string body = R"(
4171 %val1 = OpExtInst %struct_f32_f64 %extinst ModfStruct %f32_h
4172 )";
4173
4174 CompileSuccessfully(GenerateShaderCode(body));
4175 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4176 EXPECT_THAT(getDiagnosticString(),
4177 HasSubstr("GLSL.std.450 ModfStruct: "
4178 "expected Result Type to be a struct with two "
4179 "identical scalar or vector float type members"));
4180 }
4181
4182 TEST_F(ValidateExtInst, GlslStd450ModfStructXWrongType) {
4183 const std::string body = R"(
4184 %val1 = OpExtInst %struct_f32_f32 %extinst ModfStruct %f64_0
4185 )";
4186
4187 CompileSuccessfully(GenerateShaderCode(body));
4188 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4189 EXPECT_THAT(getDiagnosticString(),
4190 HasSubstr("GLSL.std.450 ModfStruct: "
4191 "expected operand X type to be equal to members of "
4192 "Result Type struct"));
4193 }
4194
4195 TEST_F(ValidateExtInst, GlslStd450FrexpSuccess) {
4196 const std::string body = R"(
4197 %val1 = OpExtInst %f32 %extinst Frexp %f32_h %u32_output
4198 %val2 = OpExtInst %f32vec2 %extinst Frexp %f32vec2_01 %u32vec2_output
4199 )";
4200
4201 CompileSuccessfully(GenerateShaderCode(body));
4202 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4203 }
4204
4205 TEST_F(ValidateExtInst, GlslStd450FrexpIntResultType) {
4206 const std::string body = R"(
4207 %val1 = OpExtInst %u32 %extinst Frexp %f32_h %u32_output
4208 )";
4209
4210 CompileSuccessfully(GenerateShaderCode(body));
4211 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4212 EXPECT_THAT(getDiagnosticString(),
4213 HasSubstr("GLSL.std.450 Frexp: "
4214 "expected Result Type to be a scalar or vector "
4215 "float type"));
4216 }
4217
4218 TEST_F(ValidateExtInst, GlslStd450FrexpWrongXType) {
4219 const std::string body = R"(
4220 %val1 = OpExtInst %f32 %extinst Frexp %u32_1 %u32_output
4221 )";
4222
4223 CompileSuccessfully(GenerateShaderCode(body));
4224 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4225 EXPECT_THAT(getDiagnosticString(),
4226 HasSubstr("GLSL.std.450 Frexp: "
4227 "expected operand X type to be equal to Result Type"));
4228 }
4229
4230 TEST_F(ValidateExtInst, GlslStd450FrexpExpNotPointer) {
4231 const std::string body = R"(
4232 %val1 = OpExtInst %f32 %extinst Frexp %f32_1 %u32_1
4233 )";
4234
4235 CompileSuccessfully(GenerateShaderCode(body));
4236 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4237 EXPECT_THAT(getDiagnosticString(),
4238 HasSubstr("GLSL.std.450 Frexp: "
4239 "expected operand Exp to be a pointer"));
4240 }
4241
4242 TEST_F(ValidateExtInst, GlslStd450FrexpExpNotInt32Pointer) {
4243 const std::string body = R"(
4244 %val1 = OpExtInst %f32 %extinst Frexp %f32_1 %f32_output
4245 )";
4246
4247 CompileSuccessfully(GenerateShaderCode(body));
4248 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4249 EXPECT_THAT(getDiagnosticString(),
4250 HasSubstr("GLSL.std.450 Frexp: "
4251 "expected operand Exp data type to be a 32-bit int "
4252 "scalar or vector type"));
4253 }
4254
4255 TEST_F(ValidateExtInst, GlslStd450FrexpExpWrongComponentNumber) {
4256 const std::string body = R"(
4257 %val1 = OpExtInst %f32vec2 %extinst Frexp %f32vec2_01 %u32_output
4258 )";
4259
4260 CompileSuccessfully(GenerateShaderCode(body));
4261 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4262 EXPECT_THAT(getDiagnosticString(),
4263 HasSubstr("GLSL.std.450 Frexp: "
4264 "expected operand Exp data type to have the same "
4265 "component number as Result Type"));
4266 }
4267
4268 TEST_F(ValidateExtInst, GlslStd450LdexpSuccess) {
4269 const std::string body = R"(
4270 %val1 = OpExtInst %f32 %extinst Ldexp %f32_h %u32_2
4271 %val2 = OpExtInst %f32vec2 %extinst Ldexp %f32vec2_01 %u32vec2_12
4272 %val3 = OpExtInst %f32 %extinst Ldexp %f32_h %u64_1
4273 )";
4274
4275 CompileSuccessfully(GenerateShaderCode(body));
4276 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4277 }
4278
4279 TEST_F(ValidateExtInst, GlslStd450LdexpIntResultType) {
4280 const std::string body = R"(
4281 %val1 = OpExtInst %u32 %extinst Ldexp %f32_h %u32_2
4282 )";
4283
4284 CompileSuccessfully(GenerateShaderCode(body));
4285 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4286 EXPECT_THAT(getDiagnosticString(),
4287 HasSubstr("GLSL.std.450 Ldexp: "
4288 "expected Result Type to be a scalar or vector "
4289 "float type"));
4290 }
4291
4292 TEST_F(ValidateExtInst, GlslStd450LdexpWrongXType) {
4293 const std::string body = R"(
4294 %val1 = OpExtInst %f32 %extinst Ldexp %u32_1 %u32_2
4295 )";
4296
4297 CompileSuccessfully(GenerateShaderCode(body));
4298 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4299 EXPECT_THAT(getDiagnosticString(),
4300 HasSubstr("GLSL.std.450 Ldexp: "
4301 "expected operand X type to be equal to Result Type"));
4302 }
4303
4304 TEST_F(ValidateExtInst, GlslStd450LdexpFloatExp) {
4305 const std::string body = R"(
4306 %val1 = OpExtInst %f32 %extinst Ldexp %f32_1 %f32_2
4307 )";
4308
4309 CompileSuccessfully(GenerateShaderCode(body));
4310 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4311 EXPECT_THAT(getDiagnosticString(),
4312 HasSubstr("GLSL.std.450 Ldexp: "
4313 "expected operand Exp to be a 32-bit int scalar "
4314 "or vector type"));
4315 }
4316
4317 TEST_F(ValidateExtInst, GlslStd450LdexpExpWrongSize) {
4318 const std::string body = R"(
4319 %val1 = OpExtInst %f32vec2 %extinst Ldexp %f32vec2_12 %u32_2
4320 )";
4321
4322 CompileSuccessfully(GenerateShaderCode(body));
4323 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4324 EXPECT_THAT(getDiagnosticString(),
4325 HasSubstr("GLSL.std.450 Ldexp: "
4326 "expected operand Exp to have the same component "
4327 "number as Result Type"));
4328 }
4329
4330 TEST_F(ValidateExtInst, GlslStd450FrexpStructSuccess) {
4331 const std::string body = R"(
4332 %val1 = OpExtInst %struct_f32_u32 %extinst FrexpStruct %f32_h
4333 %val2 = OpExtInst %struct_f32vec2_u32vec2 %extinst FrexpStruct %f32vec2_01
4334 )";
4335
4336 CompileSuccessfully(GenerateShaderCode(body));
4337 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4338 }
4339
4340 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeNotStruct) {
4341 const std::string body = R"(
4342 %val1 = OpExtInst %f32 %extinst FrexpStruct %f32_h
4343 )";
4344
4345 CompileSuccessfully(GenerateShaderCode(body));
4346 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4347 EXPECT_THAT(getDiagnosticString(),
4348 HasSubstr("GLSL.std.450 FrexpStruct: "
4349 "expected Result Type to be a struct with two members, "
4350 "first member a float scalar or vector, second member "
4351 "a 32-bit int scalar or vector with the same number of "
4352 "components as the first member"));
4353 }
4354
4355 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongSize) {
4356 const std::string body = R"(
4357 %val1 = OpExtInst %struct_f32_u32_f32 %extinst FrexpStruct %f32_h
4358 )";
4359
4360 CompileSuccessfully(GenerateShaderCode(body));
4361 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4362 EXPECT_THAT(getDiagnosticString(),
4363 HasSubstr("GLSL.std.450 FrexpStruct: "
4364 "expected Result Type to be a struct with two members, "
4365 "first member a float scalar or vector, second member "
4366 "a 32-bit int scalar or vector with the same number of "
4367 "components as the first member"));
4368 }
4369
4370 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongMember1) {
4371 const std::string body = R"(
4372 %val1 = OpExtInst %struct_u32_u32 %extinst FrexpStruct %f32_h
4373 )";
4374
4375 CompileSuccessfully(GenerateShaderCode(body));
4376 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4377 EXPECT_THAT(getDiagnosticString(),
4378 HasSubstr("GLSL.std.450 FrexpStruct: "
4379 "expected Result Type to be a struct with two members, "
4380 "first member a float scalar or vector, second member "
4381 "a 32-bit int scalar or vector with the same number of "
4382 "components as the first member"));
4383 }
4384
4385 TEST_F(ValidateExtInst, GlslStd450FrexpStructResultTypeStructWrongMember2) {
4386 const std::string body = R"(
4387 %val1 = OpExtInst %struct_f32_f32 %extinst FrexpStruct %f32_h
4388 )";
4389
4390 CompileSuccessfully(GenerateShaderCode(body));
4391 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4392 EXPECT_THAT(getDiagnosticString(),
4393 HasSubstr("GLSL.std.450 FrexpStruct: "
4394 "expected Result Type to be a struct with two members, "
4395 "first member a float scalar or vector, second member "
4396 "a 32-bit int scalar or vector with the same number of "
4397 "components as the first member"));
4398 }
4399
4400 TEST_F(ValidateExtInst, GlslStd450FrexpStructXWrongType) {
4401 const std::string body = R"(
4402 %val1 = OpExtInst %struct_f32_u32 %extinst FrexpStruct %f64_0
4403 )";
4404
4405 CompileSuccessfully(GenerateShaderCode(body));
4406 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4407 EXPECT_THAT(getDiagnosticString(),
4408 HasSubstr("GLSL.std.450 FrexpStruct: "
4409 "expected operand X type to be equal to the first "
4410 "member of Result Type struct"));
4411 }
4412
4413 TEST_F(ValidateExtInst,
4414 GlslStd450FrexpStructResultTypeStructRightInt16Member2) {
4415 const std::string body = R"(
4416 %val1 = OpExtInst %struct_f16_u16 %extinst FrexpStruct %f16_h
4417 )";
4418
4419 const std::string extension = R"(
4420 OpExtension "SPV_AMD_gpu_shader_int16"
4421 )";
4422
4423 CompileSuccessfully(GenerateShaderCode(body, extension));
4424 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4425 }
4426
4427 TEST_F(ValidateExtInst,
4428 GlslStd450FrexpStructResultTypeStructWrongInt16Member2) {
4429 const std::string body = R"(
4430 %val1 = OpExtInst %struct_f16_u16 %extinst FrexpStruct %f16_h
4431 )";
4432
4433 CompileSuccessfully(GenerateShaderCode(body));
4434 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4435 EXPECT_THAT(getDiagnosticString(),
4436 HasSubstr("GLSL.std.450 FrexpStruct: "
4437 "expected Result Type to be a struct with two members, "
4438 "first member a float scalar or vector, second member "
4439 "a 32-bit int scalar or vector with the same number of "
4440 "components as the first member"));
4441 }
4442
4443 TEST_P(ValidateGlslStd450Pack, Success) {
4444 const std::string ext_inst_name = GetParam();
4445 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4446 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4447 const uint32_t total_bit_width = num_components * packed_bit_width;
4448 const std::string vec_str =
4449 num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
4450
4451 std::ostringstream body;
4452 body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
4453 << ext_inst_name << vec_str;
4454 body << "%val2 = OpExtInst %s" << total_bit_width << " %extinst "
4455 << ext_inst_name << vec_str;
4456 CompileSuccessfully(GenerateShaderCode(body.str()));
4457 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4458 }
4459
4460 TEST_P(ValidateGlslStd450Pack, Float32ResultType) {
4461 const std::string ext_inst_name = GetParam();
4462 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4463 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4464 const uint32_t total_bit_width = num_components * packed_bit_width;
4465 const std::string vec_str =
4466 num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
4467
4468 std::ostringstream body;
4469 body << "%val1 = OpExtInst %f" << total_bit_width << " %extinst "
4470 << ext_inst_name << vec_str;
4471
4472 std::ostringstream expected;
4473 expected << "GLSL.std.450 " << ext_inst_name
4474 << ": expected Result Type to be " << total_bit_width
4475 << "-bit int scalar type";
4476
4477 CompileSuccessfully(GenerateShaderCode(body.str()));
4478 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4479 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4480 }
4481
4482 TEST_P(ValidateGlslStd450Pack, Int16ResultType) {
4483 const std::string ext_inst_name = GetParam();
4484 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4485 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4486 const uint32_t total_bit_width = num_components * packed_bit_width;
4487 const std::string vec_str =
4488 num_components == 2 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
4489
4490 std::ostringstream body;
4491 body << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << vec_str;
4492
4493 std::ostringstream expected;
4494 expected << "GLSL.std.450 " << ext_inst_name
4495 << ": expected Result Type to be " << total_bit_width
4496 << "-bit int scalar type";
4497
4498 CompileSuccessfully(GenerateShaderCode(body.str()));
4499 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4500 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4501 }
4502
4503 TEST_P(ValidateGlslStd450Pack, VNotVector) {
4504 const std::string ext_inst_name = GetParam();
4505 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4506 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4507 const uint32_t total_bit_width = num_components * packed_bit_width;
4508
4509 std::ostringstream body;
4510 body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
4511 << ext_inst_name << " %f32_1\n";
4512
4513 std::ostringstream expected;
4514 expected << "GLSL.std.450 " << ext_inst_name
4515 << ": expected operand V to be a 32-bit float vector of size "
4516 << num_components;
4517
4518 CompileSuccessfully(GenerateShaderCode(body.str()));
4519 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4520 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4521 }
4522
4523 TEST_P(ValidateGlslStd450Pack, VNotFloatVector) {
4524 const std::string ext_inst_name = GetParam();
4525 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4526 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4527 const uint32_t total_bit_width = num_components * packed_bit_width;
4528 const std::string vec_str =
4529 num_components == 2 ? " %u32vec2_01\n" : " %u32vec4_0123\n";
4530
4531 std::ostringstream body;
4532 body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
4533 << ext_inst_name << vec_str;
4534
4535 std::ostringstream expected;
4536 expected << "GLSL.std.450 " << ext_inst_name
4537 << ": expected operand V to be a 32-bit float vector of size "
4538 << num_components;
4539
4540 CompileSuccessfully(GenerateShaderCode(body.str()));
4541 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4542 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4543 }
4544
4545 TEST_P(ValidateGlslStd450Pack, VNotFloat32Vector) {
4546 const std::string ext_inst_name = GetParam();
4547 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4548 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4549 const uint32_t total_bit_width = num_components * packed_bit_width;
4550 const std::string vec_str =
4551 num_components == 2 ? " %f64vec2_01\n" : " %f64vec4_0123\n";
4552
4553 std::ostringstream body;
4554 body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
4555 << ext_inst_name << vec_str;
4556
4557 std::ostringstream expected;
4558 expected << "GLSL.std.450 " << ext_inst_name
4559 << ": expected operand V to be a 32-bit float vector of size "
4560 << num_components;
4561
4562 CompileSuccessfully(GenerateShaderCode(body.str()));
4563 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4564 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4565 }
4566
4567 TEST_P(ValidateGlslStd450Pack, VWrongSizeVector) {
4568 const std::string ext_inst_name = GetParam();
4569 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4570 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4571 const uint32_t total_bit_width = num_components * packed_bit_width;
4572 const std::string vec_str =
4573 num_components == 4 ? " %f32vec2_01\n" : " %f32vec4_0123\n";
4574
4575 std::ostringstream body;
4576 body << "%val1 = OpExtInst %u" << total_bit_width << " %extinst "
4577 << ext_inst_name << vec_str;
4578
4579 std::ostringstream expected;
4580 expected << "GLSL.std.450 " << ext_inst_name
4581 << ": expected operand V to be a 32-bit float vector of size "
4582 << num_components;
4583
4584 CompileSuccessfully(GenerateShaderCode(body.str()));
4585 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4586 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4587 }
4588
4589 INSTANTIATE_TEST_SUITE_P(AllPack, ValidateGlslStd450Pack,
4590 ::testing::ValuesIn(std::vector<std::string>{
4591 "PackSnorm4x8",
4592 "PackUnorm4x8",
4593 "PackSnorm2x16",
4594 "PackUnorm2x16",
4595 "PackHalf2x16",
4596 }));
4597
4598 TEST_F(ValidateExtInst, PackDouble2x32Success) {
4599 const std::string body = R"(
4600 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u32vec2_01
4601 )";
4602
4603 CompileSuccessfully(GenerateShaderCode(body));
4604 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4605 }
4606
4607 TEST_F(ValidateExtInst, PackDouble2x32Float32ResultType) {
4608 const std::string body = R"(
4609 %val1 = OpExtInst %f32 %extinst PackDouble2x32 %u32vec2_01
4610 )";
4611
4612 CompileSuccessfully(GenerateShaderCode(body));
4613 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4614 EXPECT_THAT(getDiagnosticString(),
4615 HasSubstr("GLSL.std.450 PackDouble2x32: expected Result Type to "
4616 "be 64-bit float scalar type"));
4617 }
4618
4619 TEST_F(ValidateExtInst, PackDouble2x32Int64ResultType) {
4620 const std::string body = R"(
4621 %val1 = OpExtInst %u64 %extinst PackDouble2x32 %u32vec2_01
4622 )";
4623
4624 CompileSuccessfully(GenerateShaderCode(body));
4625 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4626 EXPECT_THAT(getDiagnosticString(),
4627 HasSubstr("GLSL.std.450 PackDouble2x32: expected Result Type to "
4628 "be 64-bit float scalar type"));
4629 }
4630
4631 TEST_F(ValidateExtInst, PackDouble2x32VNotVector) {
4632 const std::string body = R"(
4633 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u64_1
4634 )";
4635
4636 CompileSuccessfully(GenerateShaderCode(body));
4637 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4638 EXPECT_THAT(getDiagnosticString(),
4639 HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
4640 "a 32-bit int vector of size 2"));
4641 }
4642
4643 TEST_F(ValidateExtInst, PackDouble2x32VNotIntVector) {
4644 const std::string body = R"(
4645 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %f32vec2_01
4646 )";
4647
4648 CompileSuccessfully(GenerateShaderCode(body));
4649 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4650 EXPECT_THAT(getDiagnosticString(),
4651 HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
4652 "a 32-bit int vector of size 2"));
4653 }
4654
4655 TEST_F(ValidateExtInst, PackDouble2x32VNotInt32Vector) {
4656 const std::string body = R"(
4657 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u64vec2_01
4658 )";
4659
4660 CompileSuccessfully(GenerateShaderCode(body));
4661 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4662 EXPECT_THAT(getDiagnosticString(),
4663 HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
4664 "a 32-bit int vector of size 2"));
4665 }
4666
4667 TEST_F(ValidateExtInst, PackDouble2x32VWrongSize) {
4668 const std::string body = R"(
4669 %val1 = OpExtInst %f64 %extinst PackDouble2x32 %u32vec4_0123
4670 )";
4671
4672 CompileSuccessfully(GenerateShaderCode(body));
4673 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4674 EXPECT_THAT(getDiagnosticString(),
4675 HasSubstr("GLSL.std.450 PackDouble2x32: expected operand V to be "
4676 "a 32-bit int vector of size 2"));
4677 }
4678
4679 TEST_P(ValidateGlslStd450Unpack, Success) {
4680 const std::string ext_inst_name = GetParam();
4681 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4682 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4683 const uint32_t total_bit_width = num_components * packed_bit_width;
4684 const std::string result_type_str =
4685 num_components == 2 ? "%f32vec2" : " %f32vec4";
4686
4687 std::ostringstream body;
4688 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4689 << ext_inst_name << " %u" << total_bit_width << "_1\n";
4690 body << "%val2 = OpExtInst " << result_type_str << " %extinst "
4691 << ext_inst_name << " %s" << total_bit_width << "_1\n";
4692 CompileSuccessfully(GenerateShaderCode(body.str()));
4693 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4694 }
4695
4696 TEST_P(ValidateGlslStd450Unpack, ResultTypeNotVector) {
4697 const std::string ext_inst_name = GetParam();
4698 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4699 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4700 const uint32_t total_bit_width = num_components * packed_bit_width;
4701 const std::string result_type_str = "%f32";
4702
4703 std::ostringstream body;
4704 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4705 << ext_inst_name << " %u" << total_bit_width << "_1\n";
4706
4707 std::ostringstream expected;
4708 expected << "GLSL.std.450 " << ext_inst_name
4709 << ": expected Result Type to be a 32-bit float vector of size "
4710 << num_components;
4711
4712 CompileSuccessfully(GenerateShaderCode(body.str()));
4713 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4714 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4715 }
4716
4717 TEST_P(ValidateGlslStd450Unpack, ResultTypeNotFloatVector) {
4718 const std::string ext_inst_name = GetParam();
4719 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4720 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4721 const uint32_t total_bit_width = num_components * packed_bit_width;
4722 const std::string result_type_str =
4723 num_components == 2 ? "%u32vec2" : " %u32vec4";
4724
4725 std::ostringstream body;
4726 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4727 << ext_inst_name << " %u" << total_bit_width << "_1\n";
4728
4729 std::ostringstream expected;
4730 expected << "GLSL.std.450 " << ext_inst_name
4731 << ": expected Result Type to be a 32-bit float vector of size "
4732 << num_components;
4733
4734 CompileSuccessfully(GenerateShaderCode(body.str()));
4735 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4736 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4737 }
4738
4739 TEST_P(ValidateGlslStd450Unpack, ResultTypeNotFloat32Vector) {
4740 const std::string ext_inst_name = GetParam();
4741 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4742 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4743 const uint32_t total_bit_width = num_components * packed_bit_width;
4744 const std::string result_type_str =
4745 num_components == 2 ? "%f64vec2" : " %f64vec4";
4746
4747 std::ostringstream body;
4748 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4749 << ext_inst_name << " %u" << total_bit_width << "_1\n";
4750
4751 std::ostringstream expected;
4752 expected << "GLSL.std.450 " << ext_inst_name
4753 << ": expected Result Type to be a 32-bit float vector of size "
4754 << num_components;
4755
4756 CompileSuccessfully(GenerateShaderCode(body.str()));
4757 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4758 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4759 }
4760
4761 TEST_P(ValidateGlslStd450Unpack, ResultTypeWrongSize) {
4762 const std::string ext_inst_name = GetParam();
4763 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4764 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4765 const uint32_t total_bit_width = num_components * packed_bit_width;
4766 const std::string result_type_str =
4767 num_components == 4 ? "%f32vec2" : " %f32vec4";
4768
4769 std::ostringstream body;
4770 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4771 << ext_inst_name << " %u" << total_bit_width << "_1\n";
4772
4773 std::ostringstream expected;
4774 expected << "GLSL.std.450 " << ext_inst_name
4775 << ": expected Result Type to be a 32-bit float vector of size "
4776 << num_components;
4777
4778 CompileSuccessfully(GenerateShaderCode(body.str()));
4779 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4780 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4781 }
4782
4783 TEST_P(ValidateGlslStd450Unpack, ResultPNotInt) {
4784 const std::string ext_inst_name = GetParam();
4785 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4786 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4787 const uint32_t total_bit_width = num_components * packed_bit_width;
4788 const std::string result_type_str =
4789 num_components == 2 ? "%f32vec2" : " %f32vec4";
4790
4791 std::ostringstream body;
4792 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4793 << ext_inst_name << " %f" << total_bit_width << "_1\n";
4794
4795 std::ostringstream expected;
4796 expected << "GLSL.std.450 " << ext_inst_name
4797 << ": expected operand P to be a " << total_bit_width
4798 << "-bit int scalar";
4799
4800 CompileSuccessfully(GenerateShaderCode(body.str()));
4801 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4802 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4803 }
4804
4805 TEST_P(ValidateGlslStd450Unpack, ResultPWrongBitWidth) {
4806 const std::string ext_inst_name = GetParam();
4807 const uint32_t num_components = GetPackedNumComponents(ext_inst_name);
4808 const uint32_t packed_bit_width = GetPackedBitWidth(ext_inst_name);
4809 const uint32_t total_bit_width = num_components * packed_bit_width;
4810 const uint32_t wrong_bit_width = total_bit_width == 32 ? 64 : 32;
4811 const std::string result_type_str =
4812 num_components == 2 ? "%f32vec2" : " %f32vec4";
4813
4814 std::ostringstream body;
4815 body << "%val1 = OpExtInst " << result_type_str << " %extinst "
4816 << ext_inst_name << " %u" << wrong_bit_width << "_1\n";
4817
4818 std::ostringstream expected;
4819 expected << "GLSL.std.450 " << ext_inst_name
4820 << ": expected operand P to be a " << total_bit_width
4821 << "-bit int scalar";
4822
4823 CompileSuccessfully(GenerateShaderCode(body.str()));
4824 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4825 EXPECT_THAT(getDiagnosticString(), HasSubstr(expected.str()));
4826 }
4827
4828 INSTANTIATE_TEST_SUITE_P(AllUnpack, ValidateGlslStd450Unpack,
4829 ::testing::ValuesIn(std::vector<std::string>{
4830 "UnpackSnorm4x8",
4831 "UnpackUnorm4x8",
4832 "UnpackSnorm2x16",
4833 "UnpackUnorm2x16",
4834 "UnpackHalf2x16",
4835 }));
4836
4837 TEST_F(ValidateExtInst, UnpackDouble2x32Success) {
4838 const std::string body = R"(
4839 %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %f64_1
4840 )";
4841
4842 CompileSuccessfully(GenerateShaderCode(body));
4843 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4844 }
4845
4846 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotVector) {
4847 const std::string body = R"(
4848 %val1 = OpExtInst %u64 %extinst UnpackDouble2x32 %f64_1
4849 )";
4850
4851 CompileSuccessfully(GenerateShaderCode(body));
4852 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4853 EXPECT_THAT(getDiagnosticString(),
4854 HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
4855 "to be a 32-bit int vector of size 2"));
4856 }
4857
4858 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotIntVector) {
4859 const std::string body = R"(
4860 %val1 = OpExtInst %f32vec2 %extinst UnpackDouble2x32 %f64_1
4861 )";
4862
4863 CompileSuccessfully(GenerateShaderCode(body));
4864 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4865 EXPECT_THAT(getDiagnosticString(),
4866 HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
4867 "to be a 32-bit int vector of size 2"));
4868 }
4869
4870 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeNotInt32Vector) {
4871 const std::string body = R"(
4872 %val1 = OpExtInst %u64vec2 %extinst UnpackDouble2x32 %f64_1
4873 )";
4874
4875 CompileSuccessfully(GenerateShaderCode(body));
4876 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4877 EXPECT_THAT(getDiagnosticString(),
4878 HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
4879 "to be a 32-bit int vector of size 2"));
4880 }
4881
4882 TEST_F(ValidateExtInst, UnpackDouble2x32ResultTypeWrongSize) {
4883 const std::string body = R"(
4884 %val1 = OpExtInst %u32vec4 %extinst UnpackDouble2x32 %f64_1
4885 )";
4886
4887 CompileSuccessfully(GenerateShaderCode(body));
4888 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4889 EXPECT_THAT(getDiagnosticString(),
4890 HasSubstr("GLSL.std.450 UnpackDouble2x32: expected Result Type "
4891 "to be a 32-bit int vector of size 2"));
4892 }
4893
4894 TEST_F(ValidateExtInst, UnpackDouble2x32VNotFloat) {
4895 const std::string body = R"(
4896 %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %u64_1
4897 )";
4898
4899 CompileSuccessfully(GenerateShaderCode(body));
4900 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4901 EXPECT_THAT(getDiagnosticString(),
4902 HasSubstr("GLSL.std.450 UnpackDouble2x32: expected operand V to "
4903 "be a 64-bit float scalar"));
4904 }
4905
4906 TEST_F(ValidateExtInst, UnpackDouble2x32VNotFloat64) {
4907 const std::string body = R"(
4908 %val1 = OpExtInst %u32vec2 %extinst UnpackDouble2x32 %f32_1
4909 )";
4910
4911 CompileSuccessfully(GenerateShaderCode(body));
4912 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4913 EXPECT_THAT(getDiagnosticString(),
4914 HasSubstr("GLSL.std.450 UnpackDouble2x32: expected operand V to "
4915 "be a 64-bit float scalar"));
4916 }
4917
4918 TEST_F(ValidateExtInst, GlslStd450LengthSuccess) {
4919 const std::string body = R"(
4920 %val1 = OpExtInst %f32 %extinst Length %f32_1
4921 %val2 = OpExtInst %f32 %extinst Length %f32vec2_01
4922 %val3 = OpExtInst %f32 %extinst Length %f32vec4_0123
4923 )";
4924
4925 CompileSuccessfully(GenerateShaderCode(body));
4926 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4927 }
4928
4929 TEST_F(ValidateExtInst, GlslStd450LengthIntResultType) {
4930 const std::string body = R"(
4931 %val1 = OpExtInst %u32 %extinst Length %f32vec2_01
4932 )";
4933
4934 CompileSuccessfully(GenerateShaderCode(body));
4935 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4936 EXPECT_THAT(getDiagnosticString(),
4937 HasSubstr("GLSL.std.450 Length: "
4938 "expected Result Type to be a float scalar type"));
4939 }
4940
4941 TEST_F(ValidateExtInst, GlslStd450LengthIntX) {
4942 const std::string body = R"(
4943 %val1 = OpExtInst %f32 %extinst Length %u32vec2_01
4944 )";
4945
4946 CompileSuccessfully(GenerateShaderCode(body));
4947 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4948 EXPECT_THAT(getDiagnosticString(),
4949 HasSubstr("GLSL.std.450 Length: "
4950 "expected operand X to be of float scalar or "
4951 "vector type"));
4952 }
4953
4954 TEST_F(ValidateExtInst, GlslStd450LengthDifferentType) {
4955 const std::string body = R"(
4956 %val1 = OpExtInst %f64 %extinst Length %f32vec2_01
4957 )";
4958
4959 CompileSuccessfully(GenerateShaderCode(body));
4960 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4961 EXPECT_THAT(getDiagnosticString(),
4962 HasSubstr("GLSL.std.450 Length: "
4963 "expected operand X component type to be equal to "
4964 "Result Type"));
4965 }
4966
4967 TEST_F(ValidateExtInst, GlslStd450DistanceSuccess) {
4968 const std::string body = R"(
4969 %val1 = OpExtInst %f32 %extinst Distance %f32_0 %f32_1
4970 %val2 = OpExtInst %f32 %extinst Distance %f32vec2_01 %f32vec2_12
4971 %val3 = OpExtInst %f32 %extinst Distance %f32vec4_0123 %f32vec4_1234
4972 )";
4973
4974 CompileSuccessfully(GenerateShaderCode(body));
4975 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
4976 }
4977
4978 TEST_F(ValidateExtInst, GlslStd450DistanceIntResultType) {
4979 const std::string body = R"(
4980 %val1 = OpExtInst %u32 %extinst Distance %f32vec2_01 %f32vec2_12
4981 )";
4982
4983 CompileSuccessfully(GenerateShaderCode(body));
4984 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4985 EXPECT_THAT(getDiagnosticString(),
4986 HasSubstr("GLSL.std.450 Distance: "
4987 "expected Result Type to be a float scalar type"));
4988 }
4989
4990 TEST_F(ValidateExtInst, GlslStd450DistanceIntP0) {
4991 const std::string body = R"(
4992 %val1 = OpExtInst %f32 %extinst Distance %u32_0 %f32_1
4993 )";
4994
4995 CompileSuccessfully(GenerateShaderCode(body));
4996 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
4997 EXPECT_THAT(getDiagnosticString(),
4998 HasSubstr("GLSL.std.450 Distance: "
4999 "expected operand P0 to be of float scalar or "
5000 "vector type"));
5001 }
5002
5003 TEST_F(ValidateExtInst, GlslStd450DistanceF64VectorP0) {
5004 const std::string body = R"(
5005 %val1 = OpExtInst %f32 %extinst Distance %f64vec2_01 %f32vec2_12
5006 )";
5007
5008 CompileSuccessfully(GenerateShaderCode(body));
5009 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5010 EXPECT_THAT(getDiagnosticString(),
5011 HasSubstr("GLSL.std.450 Distance: "
5012 "expected operand P0 component type to be equal to "
5013 "Result Type"));
5014 }
5015
5016 TEST_F(ValidateExtInst, GlslStd450DistanceIntP1) {
5017 const std::string body = R"(
5018 %val1 = OpExtInst %f32 %extinst Distance %f32_0 %u32_1
5019 )";
5020
5021 CompileSuccessfully(GenerateShaderCode(body));
5022 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5023 EXPECT_THAT(getDiagnosticString(),
5024 HasSubstr("GLSL.std.450 Distance: "
5025 "expected operand P1 to be of float scalar or "
5026 "vector type"));
5027 }
5028
5029 TEST_F(ValidateExtInst, GlslStd450DistanceF64VectorP1) {
5030 const std::string body = R"(
5031 %val1 = OpExtInst %f32 %extinst Distance %f32vec2_12 %f64vec2_01
5032 )";
5033
5034 CompileSuccessfully(GenerateShaderCode(body));
5035 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5036 EXPECT_THAT(getDiagnosticString(),
5037 HasSubstr("GLSL.std.450 Distance: "
5038 "expected operand P1 component type to be equal to "
5039 "Result Type"));
5040 }
5041
5042 TEST_F(ValidateExtInst, GlslStd450DistanceDifferentSize) {
5043 const std::string body = R"(
5044 %val1 = OpExtInst %f32 %extinst Distance %f32vec2_01 %f32vec4_0123
5045 )";
5046
5047 CompileSuccessfully(GenerateShaderCode(body));
5048 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5049 EXPECT_THAT(getDiagnosticString(),
5050 HasSubstr("GLSL.std.450 Distance: "
5051 "expected operands P0 and P1 to have the same number "
5052 "of components"));
5053 }
5054
5055 TEST_F(ValidateExtInst, GlslStd450CrossSuccess) {
5056 const std::string body = R"(
5057 %val1 = OpExtInst %f32vec3 %extinst Cross %f32vec3_012 %f32vec3_123
5058 )";
5059
5060 CompileSuccessfully(GenerateShaderCode(body));
5061 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5062 }
5063
5064 TEST_F(ValidateExtInst, GlslStd450CrossIntVectorResultType) {
5065 const std::string body = R"(
5066 %val1 = OpExtInst %u32vec3 %extinst Cross %f32vec3_012 %f32vec3_123
5067 )";
5068
5069 CompileSuccessfully(GenerateShaderCode(body));
5070 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5071 EXPECT_THAT(getDiagnosticString(),
5072 HasSubstr("GLSL.std.450 Cross: "
5073 "expected Result Type to be a float vector type"));
5074 }
5075
5076 TEST_F(ValidateExtInst, GlslStd450CrossResultTypeWrongSize) {
5077 const std::string body = R"(
5078 %val1 = OpExtInst %f32vec2 %extinst Cross %f32vec3_012 %f32vec3_123
5079 )";
5080
5081 CompileSuccessfully(GenerateShaderCode(body));
5082 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5083 EXPECT_THAT(getDiagnosticString(),
5084 HasSubstr("GLSL.std.450 Cross: "
5085 "expected Result Type to have 3 components"));
5086 }
5087
5088 TEST_F(ValidateExtInst, GlslStd450CrossXWrongType) {
5089 const std::string body = R"(
5090 %val1 = OpExtInst %f32vec3 %extinst Cross %f64vec3_012 %f32vec3_123
5091 )";
5092
5093 CompileSuccessfully(GenerateShaderCode(body));
5094 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5095 EXPECT_THAT(getDiagnosticString(),
5096 HasSubstr("GLSL.std.450 Cross: "
5097 "expected operand X type to be equal to Result Type"));
5098 }
5099
5100 TEST_F(ValidateExtInst, GlslStd450CrossYWrongType) {
5101 const std::string body = R"(
5102 %val1 = OpExtInst %f32vec3 %extinst Cross %f32vec3_123 %f64vec3_012
5103 )";
5104
5105 CompileSuccessfully(GenerateShaderCode(body));
5106 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5107 EXPECT_THAT(getDiagnosticString(),
5108 HasSubstr("GLSL.std.450 Cross: "
5109 "expected operand Y type to be equal to Result Type"));
5110 }
5111
5112 TEST_F(ValidateExtInst, GlslStd450RefractSuccess) {
5113 const std::string body = R"(
5114 %val1 = OpExtInst %f32 %extinst Refract %f32_1 %f32_1 %f32_1
5115 %val2 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f16_1
5116 )";
5117
5118 CompileSuccessfully(GenerateShaderCode(body));
5119 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5120 }
5121
5122 TEST_F(ValidateExtInst, GlslStd450RefractIntVectorResultType) {
5123 const std::string body = R"(
5124 %val1 = OpExtInst %u32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f32_1
5125 )";
5126
5127 CompileSuccessfully(GenerateShaderCode(body));
5128 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5129 EXPECT_THAT(getDiagnosticString(),
5130 HasSubstr("GLSL.std.450 Refract: "
5131 "expected Result Type to be a float scalar or "
5132 "vector type"));
5133 }
5134
5135 TEST_F(ValidateExtInst, GlslStd450RefractIntVectorI) {
5136 const std::string body = R"(
5137 %val1 = OpExtInst %f32vec2 %extinst Refract %u32vec2_01 %f32vec2_01 %f32_1
5138 )";
5139
5140 CompileSuccessfully(GenerateShaderCode(body));
5141 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5142 EXPECT_THAT(getDiagnosticString(),
5143 HasSubstr("GLSL.std.450 Refract: "
5144 "expected operand I to be of type equal to "
5145 "Result Type"));
5146 }
5147
5148 TEST_F(ValidateExtInst, GlslStd450RefractIntVectorN) {
5149 const std::string body = R"(
5150 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %u32vec2_01 %f32_1
5151 )";
5152
5153 CompileSuccessfully(GenerateShaderCode(body));
5154 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5155 EXPECT_THAT(getDiagnosticString(),
5156 HasSubstr("GLSL.std.450 Refract: "
5157 "expected operand N to be of type equal to "
5158 "Result Type"));
5159 }
5160
5161 TEST_F(ValidateExtInst, GlslStd450RefractIntEta) {
5162 const std::string body = R"(
5163 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %u32_1
5164 )";
5165
5166 CompileSuccessfully(GenerateShaderCode(body));
5167 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5168 EXPECT_THAT(getDiagnosticString(),
5169 HasSubstr("GLSL.std.450 Refract: "
5170 "expected operand Eta to be a float scalar"));
5171 }
5172
5173 TEST_F(ValidateExtInst, GlslStd450RefractFloat64Eta) {
5174 // SPIR-V issue 337: Eta can be 64-bit float scalar.
5175 const std::string body = R"(
5176 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f64_1
5177 )";
5178
5179 CompileSuccessfully(GenerateShaderCode(body));
5180 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5181 EXPECT_THAT(getDiagnosticString(), Eq(""));
5182 }
5183
5184 TEST_F(ValidateExtInst, GlslStd450RefractVectorEta) {
5185 const std::string body = R"(
5186 %val1 = OpExtInst %f32vec2 %extinst Refract %f32vec2_01 %f32vec2_01 %f32vec2_01
5187 )";
5188
5189 CompileSuccessfully(GenerateShaderCode(body));
5190 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5191 EXPECT_THAT(getDiagnosticString(),
5192 HasSubstr("GLSL.std.450 Refract: "
5193 "expected operand Eta to be a float scalar"));
5194 }
5195
5196 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidSuccess) {
5197 const std::string body = R"(
5198 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
5199 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %f32vec2_input
5200 )";
5201
5202 CompileSuccessfully(
5203 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5204 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5205 }
5206
5207 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidInternalSuccess) {
5208 const std::string body = R"(
5209 %ld1 = OpLoad %f32 %f32_input
5210 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %ld1
5211 %ld2 = OpLoad %f32vec2 %f32vec2_input
5212 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %ld2
5213 )";
5214
5215 CompileSuccessfully(
5216 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5217 getValidatorOptions()->before_hlsl_legalization = true;
5218 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5219 }
5220
5221 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidInternalInvalidDataF32) {
5222 const std::string body = R"(
5223 %ld1 = OpLoad %f32 %f32_input
5224 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %ld1
5225 )";
5226
5227 CompileSuccessfully(
5228 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5229 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5230 EXPECT_THAT(getDiagnosticString(),
5231 HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5232 "expected Interpolant to be a pointer"));
5233 }
5234
5235 TEST_F(ValidateExtInst,
5236 GlslStd450InterpolateAtCentroidInternalInvalidDataF32Vec2) {
5237 const std::string body = R"(
5238 %ld2 = OpLoad %f32vec2 %f32vec2_input
5239 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtCentroid %ld2
5240 )";
5241
5242 CompileSuccessfully(
5243 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5244 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5245 EXPECT_THAT(getDiagnosticString(),
5246 HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5247 "expected Interpolant to be a pointer"));
5248 }
5249
5250 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNoCapability) {
5251 const std::string body = R"(
5252 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
5253 )";
5254
5255 CompileSuccessfully(GenerateShaderCode(body));
5256 ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
5257 EXPECT_THAT(getDiagnosticString(),
5258 HasSubstr("GLSL.std.450 InterpolateAtCentroid requires "
5259 "capability InterpolationFunction"));
5260 }
5261
5262 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidIntResultType) {
5263 const std::string body = R"(
5264 %val1 = OpExtInst %u32 %extinst InterpolateAtCentroid %f32_input
5265 )";
5266
5267 CompileSuccessfully(
5268 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5269 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5270 EXPECT_THAT(getDiagnosticString(),
5271 HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5272 "expected Result Type to be a 32-bit float scalar "
5273 "or vector type"));
5274 }
5275
5276 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidF64ResultType) {
5277 const std::string body = R"(
5278 %val1 = OpExtInst %f64 %extinst InterpolateAtCentroid %f32_input
5279 )";
5280
5281 CompileSuccessfully(
5282 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5283 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5284 EXPECT_THAT(getDiagnosticString(),
5285 HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5286 "expected Result Type to be a 32-bit float scalar "
5287 "or vector type"));
5288 }
5289
5290 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidNotPointer) {
5291 const std::string body = R"(
5292 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_1
5293 )";
5294
5295 CompileSuccessfully(
5296 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5297 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5298 EXPECT_THAT(getDiagnosticString(),
5299 HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5300 "expected Interpolant to be a pointer"));
5301 }
5302
5303 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongDataType) {
5304 const std::string body = R"(
5305 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32vec2_input
5306 )";
5307
5308 CompileSuccessfully(
5309 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5310 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5311 EXPECT_THAT(getDiagnosticString(),
5312 HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5313 "expected Interpolant data type to be equal to "
5314 "Result Type"));
5315 }
5316
5317 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongStorageClass) {
5318 const std::string body = R"(
5319 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_output
5320 )";
5321
5322 CompileSuccessfully(
5323 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5324 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5325 EXPECT_THAT(getDiagnosticString(),
5326 HasSubstr("GLSL.std.450 InterpolateAtCentroid: "
5327 "expected Interpolant storage class to be Input"));
5328 }
5329
5330 TEST_F(ValidateExtInst, GlslStd450InterpolateAtCentroidWrongExecutionModel) {
5331 const std::string body = R"(
5332 %val1 = OpExtInst %f32 %extinst InterpolateAtCentroid %f32_input
5333 )";
5334
5335 CompileSuccessfully(GenerateShaderCode(
5336 body, "OpCapability InterpolationFunction\n", "Vertex"));
5337 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5338 EXPECT_THAT(getDiagnosticString(),
5339 HasSubstr("GLSL.std.450 InterpolateAtCentroid requires "
5340 "Fragment execution model"));
5341 }
5342
5343 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleSuccess) {
5344 const std::string body = R"(
5345 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
5346 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %f32vec2_input %u32_1
5347 )";
5348
5349 CompileSuccessfully(
5350 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5351 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5352 }
5353
5354 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleInternalSuccess) {
5355 const std::string body = R"(
5356 %ld1 = OpLoad %f32 %f32_input
5357 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %ld1 %u32_1
5358 %ld2 = OpLoad %f32vec2 %f32vec2_input
5359 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %ld2 %u32_1
5360 )";
5361
5362 CompileSuccessfully(
5363 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5364 getValidatorOptions()->before_hlsl_legalization = true;
5365 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5366 }
5367
5368 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleInternalInvalidDataF32) {
5369 const std::string body = R"(
5370 %ld1 = OpLoad %f32 %f32_input
5371 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %ld1 %u32_1
5372 )";
5373
5374 CompileSuccessfully(
5375 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5376 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5377 EXPECT_THAT(getDiagnosticString(),
5378 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5379 "expected Interpolant to be a pointer"));
5380 }
5381
5382 TEST_F(ValidateExtInst,
5383 GlslStd450InterpolateAtSampleInternalInvalidDataF32Vec2) {
5384 const std::string body = R"(
5385 %ld2 = OpLoad %f32vec2 %f32vec2_input
5386 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtSample %ld2 %u32_1
5387 )";
5388
5389 CompileSuccessfully(
5390 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5391 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5392 EXPECT_THAT(getDiagnosticString(),
5393 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5394 "expected Interpolant to be a pointer"));
5395 }
5396
5397 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNoCapability) {
5398 const std::string body = R"(
5399 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
5400 )";
5401
5402 CompileSuccessfully(GenerateShaderCode(body));
5403 ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
5404 EXPECT_THAT(getDiagnosticString(),
5405 HasSubstr("GLSL.std.450 InterpolateAtSample requires "
5406 "capability InterpolationFunction"));
5407 }
5408
5409 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleIntResultType) {
5410 const std::string body = R"(
5411 %val1 = OpExtInst %u32 %extinst InterpolateAtSample %f32_input %u32_1
5412 )";
5413
5414 CompileSuccessfully(
5415 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5416 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5417 EXPECT_THAT(getDiagnosticString(),
5418 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5419 "expected Result Type to be a 32-bit float scalar "
5420 "or vector type"));
5421 }
5422
5423 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleF64ResultType) {
5424 const std::string body = R"(
5425 %val1 = OpExtInst %f64 %extinst InterpolateAtSample %f32_input %u32_1
5426 )";
5427
5428 CompileSuccessfully(
5429 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5430 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5431 EXPECT_THAT(getDiagnosticString(),
5432 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5433 "expected Result Type to be a 32-bit float scalar "
5434 "or vector type"));
5435 }
5436
5437 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleNotPointer) {
5438 const std::string body = R"(
5439 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_1 %u32_1
5440 )";
5441
5442 CompileSuccessfully(
5443 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5444 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5445 EXPECT_THAT(getDiagnosticString(),
5446 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5447 "expected Interpolant to be a pointer"));
5448 }
5449
5450 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongDataType) {
5451 const std::string body = R"(
5452 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32vec2_input %u32_1
5453 )";
5454
5455 CompileSuccessfully(
5456 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5457 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5458 EXPECT_THAT(getDiagnosticString(),
5459 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5460 "expected Interpolant data type to be equal to "
5461 "Result Type"));
5462 }
5463
5464 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongStorageClass) {
5465 const std::string body = R"(
5466 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_output %u32_1
5467 )";
5468
5469 CompileSuccessfully(
5470 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5471 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5472 EXPECT_THAT(getDiagnosticString(),
5473 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5474 "expected Interpolant storage class to be Input"));
5475 }
5476
5477 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleFloatSample) {
5478 const std::string body = R"(
5479 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %f32_1
5480 )";
5481
5482 CompileSuccessfully(
5483 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5484 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5485 EXPECT_THAT(getDiagnosticString(),
5486 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5487 "expected Sample to be 32-bit integer"));
5488 }
5489
5490 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleU64Sample) {
5491 const std::string body = R"(
5492 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u64_1
5493 )";
5494
5495 CompileSuccessfully(
5496 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5497 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5498 EXPECT_THAT(getDiagnosticString(),
5499 HasSubstr("GLSL.std.450 InterpolateAtSample: "
5500 "expected Sample to be 32-bit integer"));
5501 }
5502
5503 TEST_F(ValidateExtInst, GlslStd450InterpolateAtSampleWrongExecutionModel) {
5504 const std::string body = R"(
5505 %val1 = OpExtInst %f32 %extinst InterpolateAtSample %f32_input %u32_1
5506 )";
5507
5508 CompileSuccessfully(GenerateShaderCode(
5509 body, "OpCapability InterpolationFunction\n", "Vertex"));
5510 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5511 EXPECT_THAT(getDiagnosticString(),
5512 HasSubstr("GLSL.std.450 InterpolateAtSample requires "
5513 "Fragment execution model"));
5514 }
5515
5516 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetSuccess) {
5517 const std::string body = R"(
5518 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5519 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01
5520 )";
5521
5522 CompileSuccessfully(
5523 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5524 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5525 }
5526
5527 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetInternalSuccess) {
5528 const std::string body = R"(
5529 %ld1 = OpLoad %f32 %f32_input
5530 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %ld1 %f32vec2_01
5531 %ld2 = OpLoad %f32vec2 %f32vec2_input
5532 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %ld2 %f32vec2_01
5533 )";
5534
5535 CompileSuccessfully(
5536 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5537 getValidatorOptions()->before_hlsl_legalization = true;
5538 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5539 }
5540
5541 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetInternalInvalidDataF32) {
5542 const std::string body = R"(
5543 %ld1 = OpLoad %f32 %f32_input
5544 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %ld1 %f32vec2_01
5545 )";
5546
5547 CompileSuccessfully(
5548 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5549 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5550 EXPECT_THAT(getDiagnosticString(),
5551 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5552 "expected Interpolant to be a pointer"));
5553 }
5554
5555 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetInternalInvalidDataF32Vec2) {
5556 const std::string body = R"(
5557 %ld2 = OpLoad %f32vec2 %f32vec2_input
5558 %val2 = OpExtInst %f32vec2 %extinst InterpolateAtOffset %ld2 %f32vec2_01
5559 )";
5560
5561 CompileSuccessfully(
5562 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5563 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5564 EXPECT_THAT(getDiagnosticString(),
5565 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5566 "expected Interpolant to be a pointer"));
5567 }
5568
5569 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNoCapability) {
5570 const std::string body = R"(
5571 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5572 )";
5573
5574 CompileSuccessfully(GenerateShaderCode(body));
5575 ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
5576 EXPECT_THAT(getDiagnosticString(),
5577 HasSubstr("GLSL.std.450 InterpolateAtOffset requires "
5578 "capability InterpolationFunction"));
5579 }
5580
5581 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetIntResultType) {
5582 const std::string body = R"(
5583 %val1 = OpExtInst %u32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5584 )";
5585
5586 CompileSuccessfully(
5587 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5588 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5589 EXPECT_THAT(getDiagnosticString(),
5590 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5591 "expected Result Type to be a 32-bit float scalar "
5592 "or vector type"));
5593 }
5594
5595 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetF64ResultType) {
5596 const std::string body = R"(
5597 %val1 = OpExtInst %f64 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5598 )";
5599
5600 CompileSuccessfully(
5601 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5602 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5603 EXPECT_THAT(getDiagnosticString(),
5604 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5605 "expected Result Type to be a 32-bit float scalar "
5606 "or vector type"));
5607 }
5608
5609 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetNotPointer) {
5610 const std::string body = R"(
5611 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_1 %f32vec2_01
5612 )";
5613
5614 CompileSuccessfully(
5615 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5616 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5617 EXPECT_THAT(getDiagnosticString(),
5618 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5619 "expected Interpolant to be a pointer"));
5620 }
5621
5622 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongDataType) {
5623 const std::string body = R"(
5624 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32vec2_input %f32vec2_01
5625 )";
5626
5627 CompileSuccessfully(
5628 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5629 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5630 EXPECT_THAT(getDiagnosticString(),
5631 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5632 "expected Interpolant data type to be equal to "
5633 "Result Type"));
5634 }
5635
5636 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongStorageClass) {
5637 const std::string body = R"(
5638 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_output %f32vec2_01
5639 )";
5640
5641 CompileSuccessfully(
5642 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5643 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5644 EXPECT_THAT(getDiagnosticString(),
5645 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5646 "expected Interpolant storage class to be Input"));
5647 }
5648
5649 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector) {
5650 const std::string body = R"(
5651 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32_0
5652 )";
5653
5654 CompileSuccessfully(
5655 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5656 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5657 EXPECT_THAT(getDiagnosticString(),
5658 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5659 "expected Offset to be a vector of 2 32-bit floats"));
5660 }
5661
5662 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotVector2) {
5663 const std::string body = R"(
5664 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec3_012
5665 )";
5666
5667 CompileSuccessfully(
5668 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5669 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5670 EXPECT_THAT(getDiagnosticString(),
5671 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5672 "expected Offset to be a vector of 2 32-bit floats"));
5673 }
5674
5675 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloatVector) {
5676 const std::string body = R"(
5677 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %u32vec2_01
5678 )";
5679
5680 CompileSuccessfully(
5681 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5682 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5683 EXPECT_THAT(getDiagnosticString(),
5684 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5685 "expected Offset to be a vector of 2 32-bit floats"));
5686 }
5687
5688 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetOffsetNotFloat32Vector) {
5689 const std::string body = R"(
5690 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f64vec2_01
5691 )";
5692
5693 CompileSuccessfully(
5694 GenerateShaderCode(body, "OpCapability InterpolationFunction\n"));
5695 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5696 EXPECT_THAT(getDiagnosticString(),
5697 HasSubstr("GLSL.std.450 InterpolateAtOffset: "
5698 "expected Offset to be a vector of 2 32-bit floats"));
5699 }
5700
5701 TEST_F(ValidateExtInst, GlslStd450InterpolateAtOffsetWrongExecutionModel) {
5702 const std::string body = R"(
5703 %val1 = OpExtInst %f32 %extinst InterpolateAtOffset %f32_input %f32vec2_01
5704 )";
5705
5706 CompileSuccessfully(GenerateShaderCode(
5707 body, "OpCapability InterpolationFunction\n", "Vertex"));
5708 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
5709 EXPECT_THAT(getDiagnosticString(),
5710 HasSubstr("GLSL.std.450 InterpolateAtOffset requires "
5711 "Fragment execution model"));
5712 }
5713
5714 TEST_P(ValidateOpenCLStdSqrtLike, Success) {
5715 const std::string ext_inst_name = GetParam();
5716 std::ostringstream ss;
5717 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0\n";
5718 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5719 << " %f32vec2_01\n";
5720 ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
5721 << " %f32vec4_0123\n";
5722 ss << "%val4 = OpExtInst %f64 %extinst " << ext_inst_name << " %f64_0\n";
5723 CompileSuccessfully(GenerateKernelCode(ss.str()));
5724 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5725 }
5726
5727 TEST_P(ValidateOpenCLStdSqrtLike, IntResultType) {
5728 const std::string ext_inst_name = GetParam();
5729 const std::string body =
5730 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
5731
5732 CompileSuccessfully(GenerateKernelCode(body));
5733 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5734 EXPECT_THAT(getDiagnosticString(),
5735 HasSubstr("OpenCL.std " + ext_inst_name +
5736 ": expected Result Type to be a float scalar "
5737 "or vector type"));
5738 }
5739
5740 TEST_P(ValidateOpenCLStdSqrtLike, IntOperand) {
5741 const std::string ext_inst_name = GetParam();
5742 const std::string body =
5743 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
5744
5745 CompileSuccessfully(GenerateKernelCode(body));
5746 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5747 EXPECT_THAT(getDiagnosticString(),
5748 HasSubstr("OpenCL.std " + ext_inst_name +
5749 ": expected types of all operands to be equal to "
5750 "Result Type"));
5751 }
5752
5753 INSTANTIATE_TEST_SUITE_P(
5754 AllSqrtLike, ValidateOpenCLStdSqrtLike,
5755 ::testing::ValuesIn(std::vector<std::string>{
5756 "acos", "acosh", "acospi", "asin",
5757 "asinh", "asinpi", "atan", "atanh",
5758 "atanpi", "cbrt", "ceil", "cos",
5759 "cosh", "cospi", "erfc", "erf",
5760 "exp", "exp2", "exp10", "expm1",
5761 "fabs", "floor", "log", "log2",
5762 "log10", "log1p", "logb", "rint",
5763 "round", "rsqrt", "sin", "sinh",
5764 "sinpi", "sqrt", "tan", "tanh",
5765 "tanpi", "tgamma", "trunc", "half_cos",
5766 "half_exp", "half_exp2", "half_exp10", "half_log",
5767 "half_log2", "half_log10", "half_recip", "half_rsqrt",
5768 "half_sin", "half_sqrt", "half_tan", "lgamma",
5769 "native_cos", "native_exp", "native_exp2", "native_exp10",
5770 "native_log", "native_log2", "native_log10", "native_recip",
5771 "native_rsqrt", "native_sin", "native_sqrt", "native_tan",
5772 "degrees", "radians", "sign",
5773 }));
5774
5775 TEST_P(ValidateOpenCLStdFMinLike, Success) {
5776 const std::string ext_inst_name = GetParam();
5777 std::ostringstream ss;
5778 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5779 << " %f32_0 %f32_1\n";
5780 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5781 << " %f32vec2_01 %f32vec2_12\n";
5782 ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
5783 << " %f64_0 %f64_0\n";
5784 CompileSuccessfully(GenerateKernelCode(ss.str()));
5785 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5786 }
5787
5788 TEST_P(ValidateOpenCLStdFMinLike, IntResultType) {
5789 const std::string ext_inst_name = GetParam();
5790 const std::string body =
5791 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %f32_1\n";
5792
5793 CompileSuccessfully(GenerateKernelCode(body));
5794 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5795 EXPECT_THAT(getDiagnosticString(),
5796 HasSubstr("OpenCL.std " + ext_inst_name +
5797 ": expected Result Type to be a float scalar "
5798 "or vector type"));
5799 }
5800
5801 TEST_P(ValidateOpenCLStdFMinLike, IntOperand1) {
5802 const std::string ext_inst_name = GetParam();
5803 const std::string body =
5804 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %f32_1\n";
5805
5806 CompileSuccessfully(GenerateKernelCode(body));
5807 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5808 EXPECT_THAT(getDiagnosticString(),
5809 HasSubstr("OpenCL.std " + ext_inst_name +
5810 ": expected types of all operands to be equal to "
5811 "Result Type"));
5812 }
5813
5814 TEST_P(ValidateOpenCLStdFMinLike, IntOperand2) {
5815 const std::string ext_inst_name = GetParam();
5816 const std::string body =
5817 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %f32_0 %u32_1\n";
5818
5819 CompileSuccessfully(GenerateKernelCode(body));
5820 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5821 EXPECT_THAT(getDiagnosticString(),
5822 HasSubstr("OpenCL.std " + ext_inst_name +
5823 ": expected types of all operands to be equal to "
5824 "Result Type"));
5825 }
5826
5827 INSTANTIATE_TEST_SUITE_P(AllFMinLike, ValidateOpenCLStdFMinLike,
5828 ::testing::ValuesIn(std::vector<std::string>{
5829 "atan2", "atan2pi", "copysign",
5830 "fdim", "fmax", "fmin",
5831 "fmod", "maxmag", "minmag",
5832 "hypot", "nextafter", "pow",
5833 "powr", "remainder", "half_divide",
5834 "half_powr", "native_divide", "native_powr",
5835 "step", "fmax_common", "fmin_common",
5836 }));
5837
5838 TEST_P(ValidateOpenCLStdFClampLike, Success) {
5839 const std::string ext_inst_name = GetParam();
5840 std::ostringstream ss;
5841 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
5842 << " %f32_0 %f32_1 %f32_2\n";
5843 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
5844 << " %f32vec2_01 %f32vec2_01 %f32vec2_12\n";
5845 ss << "%val3 = OpExtInst %f64 %extinst " << ext_inst_name
5846 << " %f64_0 %f64_0 %f64_1\n";
5847 CompileSuccessfully(GenerateKernelCode(ss.str()));
5848 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5849 }
5850
5851 TEST_P(ValidateOpenCLStdFClampLike, IntResultType) {
5852 const std::string ext_inst_name = GetParam();
5853 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
5854 " %f32_0 %f32_1 %f32_2\n";
5855
5856 CompileSuccessfully(GenerateKernelCode(body));
5857 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5858 EXPECT_THAT(getDiagnosticString(),
5859 HasSubstr("OpenCL.std " + ext_inst_name +
5860 ": expected Result Type to be a float scalar "
5861 "or vector type"));
5862 }
5863
5864 TEST_P(ValidateOpenCLStdFClampLike, IntOperand1) {
5865 const std::string ext_inst_name = GetParam();
5866 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5867 " %u32_0 %f32_0 %f32_1\n";
5868
5869 CompileSuccessfully(GenerateKernelCode(body));
5870 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5871 EXPECT_THAT(getDiagnosticString(),
5872 HasSubstr("OpenCL.std " + ext_inst_name +
5873 ": expected types of all operands to be equal to "
5874 "Result Type"));
5875 }
5876
5877 TEST_P(ValidateOpenCLStdFClampLike, IntOperand2) {
5878 const std::string ext_inst_name = GetParam();
5879 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5880 " %f32_0 %u32_0 %f32_1\n";
5881
5882 CompileSuccessfully(GenerateKernelCode(body));
5883 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5884 EXPECT_THAT(getDiagnosticString(),
5885 HasSubstr("OpenCL.std " + ext_inst_name +
5886 ": expected types of all operands to be equal to "
5887 "Result Type"));
5888 }
5889
5890 TEST_P(ValidateOpenCLStdFClampLike, IntOperand3) {
5891 const std::string ext_inst_name = GetParam();
5892 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
5893 " %f32_1 %f32_0 %u32_2\n";
5894
5895 CompileSuccessfully(GenerateKernelCode(body));
5896 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5897 EXPECT_THAT(getDiagnosticString(),
5898 HasSubstr("OpenCL.std " + ext_inst_name +
5899 ": expected types of all operands to be equal to "
5900 "Result Type"));
5901 }
5902
5903 INSTANTIATE_TEST_SUITE_P(AllFClampLike, ValidateOpenCLStdFClampLike,
5904 ::testing::ValuesIn(std::vector<std::string>{
5905 "fma",
5906 "mad",
5907 "fclamp",
5908 "mix",
5909 "smoothstep",
5910 }));
5911
5912 TEST_P(ValidateOpenCLStdSAbsLike, Success) {
5913 const std::string ext_inst_name = GetParam();
5914 std::ostringstream ss;
5915 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5916 ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5917 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5918 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name << " %u32_1\n";
5919 ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5920 << " %u32vec2_01\n";
5921 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5922 << " %u32vec2_01\n";
5923 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5924 << " %u32vec2_01\n";
5925 ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5926 << " %u32vec2_01\n";
5927 CompileSuccessfully(GenerateKernelCode(ss.str()));
5928 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
5929 }
5930
5931 TEST_P(ValidateOpenCLStdSAbsLike, FloatResultType) {
5932 const std::string ext_inst_name = GetParam();
5933 const std::string body =
5934 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0\n";
5935
5936 CompileSuccessfully(GenerateKernelCode(body));
5937 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5938 EXPECT_THAT(getDiagnosticString(),
5939 HasSubstr("OpenCL.std " + ext_inst_name +
5940 ": expected Result Type to be an int scalar "
5941 "or vector type"));
5942 }
5943
5944 TEST_P(ValidateOpenCLStdSAbsLike, FloatOperand) {
5945 const std::string ext_inst_name = GetParam();
5946 const std::string body =
5947 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0\n";
5948
5949 CompileSuccessfully(GenerateKernelCode(body));
5950 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5951 EXPECT_THAT(
5952 getDiagnosticString(),
5953 HasSubstr("OpenCL.std " + ext_inst_name +
5954 ": expected types of all operands to be equal to Result Type"));
5955 }
5956
5957 TEST_P(ValidateOpenCLStdSAbsLike, U64Operand) {
5958 const std::string ext_inst_name = GetParam();
5959 const std::string body =
5960 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0\n";
5961
5962 CompileSuccessfully(GenerateKernelCode(body));
5963 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
5964 EXPECT_THAT(
5965 getDiagnosticString(),
5966 HasSubstr("OpenCL.std " + ext_inst_name +
5967 ": expected types of all operands to be equal to Result Type"));
5968 }
5969
5970 INSTANTIATE_TEST_SUITE_P(AllSAbsLike, ValidateOpenCLStdSAbsLike,
5971 ::testing::ValuesIn(std::vector<std::string>{
5972 "s_abs",
5973 "clz",
5974 "ctz",
5975 "popcount",
5976 "u_abs",
5977 }));
5978
5979 TEST_P(ValidateOpenCLStdUMinLike, Success) {
5980 const std::string ext_inst_name = GetParam();
5981 std::ostringstream ss;
5982 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
5983 << " %u32_1 %u32_2\n";
5984 ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
5985 << " %u32_1 %u32_2\n";
5986 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
5987 << " %u32_1 %u32_2\n";
5988 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
5989 << " %u32_1 %u32_2\n";
5990 ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5991 << " %u32vec2_01 %u32vec2_01\n";
5992 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5993 << " %u32vec2_01 %u32vec2_01\n";
5994 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5995 << " %u32vec2_01 %u32vec2_01\n";
5996 ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
5997 << " %u32vec2_01 %u32vec2_01\n";
5998 ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name
5999 << " %u64_1 %u64_0\n";
6000 CompileSuccessfully(GenerateKernelCode(ss.str()));
6001 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6002 }
6003
6004 TEST_P(ValidateOpenCLStdUMinLike, FloatResultType) {
6005 const std::string ext_inst_name = GetParam();
6006 const std::string body =
6007 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
6008
6009 CompileSuccessfully(GenerateKernelCode(body));
6010 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6011 EXPECT_THAT(getDiagnosticString(),
6012 HasSubstr("OpenCL.std " + ext_inst_name +
6013 ": expected Result Type to be an int scalar "
6014 "or vector type"));
6015 }
6016
6017 TEST_P(ValidateOpenCLStdUMinLike, FloatOperand1) {
6018 const std::string ext_inst_name = GetParam();
6019 const std::string body =
6020 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
6021
6022 CompileSuccessfully(GenerateKernelCode(body));
6023 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6024 EXPECT_THAT(
6025 getDiagnosticString(),
6026 HasSubstr("OpenCL.std " + ext_inst_name +
6027 ": expected types of all operands to be equal to Result Type"));
6028 }
6029
6030 TEST_P(ValidateOpenCLStdUMinLike, FloatOperand2) {
6031 const std::string ext_inst_name = GetParam();
6032 const std::string body =
6033 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
6034
6035 CompileSuccessfully(GenerateKernelCode(body));
6036 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6037 EXPECT_THAT(
6038 getDiagnosticString(),
6039 HasSubstr("OpenCL.std " + ext_inst_name +
6040 ": expected types of all operands to be equal to Result Type"));
6041 }
6042
6043 TEST_P(ValidateOpenCLStdUMinLike, U64Operand1) {
6044 const std::string ext_inst_name = GetParam();
6045 const std::string body =
6046 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n";
6047
6048 CompileSuccessfully(GenerateKernelCode(body));
6049 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6050 EXPECT_THAT(
6051 getDiagnosticString(),
6052 HasSubstr("OpenCL.std " + ext_inst_name +
6053 ": expected types of all operands to be equal to Result Type"));
6054 }
6055
6056 TEST_P(ValidateOpenCLStdUMinLike, U64Operand2) {
6057 const std::string ext_inst_name = GetParam();
6058 const std::string body =
6059 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n";
6060
6061 CompileSuccessfully(GenerateKernelCode(body));
6062 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6063 EXPECT_THAT(
6064 getDiagnosticString(),
6065 HasSubstr("OpenCL.std " + ext_inst_name +
6066 ": expected types of all operands to be equal to Result Type"));
6067 }
6068
6069 INSTANTIATE_TEST_SUITE_P(AllUMinLike, ValidateOpenCLStdUMinLike,
6070 ::testing::ValuesIn(std::vector<std::string>{
6071 "s_max",
6072 "u_max",
6073 "s_min",
6074 "u_min",
6075 "s_abs_diff",
6076 "s_add_sat",
6077 "u_add_sat",
6078 "s_mul_hi",
6079 "rotate",
6080 "s_sub_sat",
6081 "u_sub_sat",
6082 "s_hadd",
6083 "u_hadd",
6084 "s_rhadd",
6085 "u_rhadd",
6086 "u_abs_diff",
6087 "u_mul_hi",
6088 }));
6089
6090 TEST_P(ValidateOpenCLStdUClampLike, Success) {
6091 const std::string ext_inst_name = GetParam();
6092 std::ostringstream ss;
6093 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
6094 << " %u32_0 %u32_1 %u32_2\n";
6095 ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
6096 << " %u32_0 %u32_1 %u32_2\n";
6097 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
6098 << " %u32_0 %u32_1 %u32_2\n";
6099 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
6100 << " %u32_0 %u32_1 %u32_2\n";
6101 ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6102 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6103 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6104 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6105 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6106 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6107 ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6108 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6109 ss << "%val9 = OpExtInst %u64 %extinst " << ext_inst_name
6110 << " %u64_1 %u64_0 %u64_1\n";
6111 CompileSuccessfully(GenerateKernelCode(ss.str()));
6112 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6113 }
6114
6115 TEST_P(ValidateOpenCLStdUClampLike, FloatResultType) {
6116 const std::string ext_inst_name = GetParam();
6117 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6118 " %u32_0 %u32_0 %u32_1\n";
6119
6120 CompileSuccessfully(GenerateKernelCode(body));
6121 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6122 EXPECT_THAT(getDiagnosticString(),
6123 HasSubstr("OpenCL.std " + ext_inst_name +
6124 ": expected Result Type to be an int scalar "
6125 "or vector type"));
6126 }
6127
6128 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand1) {
6129 const std::string ext_inst_name = GetParam();
6130 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6131 " %f32_0 %u32_0 %u32_1\n";
6132
6133 CompileSuccessfully(GenerateKernelCode(body));
6134 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6135 EXPECT_THAT(
6136 getDiagnosticString(),
6137 HasSubstr("OpenCL.std " + ext_inst_name +
6138 ": expected types of all operands to be equal to Result Type"));
6139 }
6140
6141 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand2) {
6142 const std::string ext_inst_name = GetParam();
6143 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6144 " %u32_0 %f32_0 %u32_1\n";
6145
6146 CompileSuccessfully(GenerateKernelCode(body));
6147 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6148 EXPECT_THAT(
6149 getDiagnosticString(),
6150 HasSubstr("OpenCL.std " + ext_inst_name +
6151 ": expected types of all operands to be equal to Result Type"));
6152 }
6153
6154 TEST_P(ValidateOpenCLStdUClampLike, FloatOperand3) {
6155 const std::string ext_inst_name = GetParam();
6156 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6157 " %u32_0 %u32_0 %f32_1\n";
6158
6159 CompileSuccessfully(GenerateKernelCode(body));
6160 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6161 EXPECT_THAT(
6162 getDiagnosticString(),
6163 HasSubstr("OpenCL.std " + ext_inst_name +
6164 ": expected types of all operands to be equal to Result Type"));
6165 }
6166
6167 TEST_P(ValidateOpenCLStdUClampLike, U64Operand1) {
6168 const std::string ext_inst_name = GetParam();
6169 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6170 " %f32_0 %u32_0 %u64_1\n";
6171
6172 CompileSuccessfully(GenerateKernelCode(body));
6173 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6174 EXPECT_THAT(
6175 getDiagnosticString(),
6176 HasSubstr("OpenCL.std " + ext_inst_name +
6177 ": expected types of all operands to be equal to Result Type"));
6178 }
6179
6180 TEST_P(ValidateOpenCLStdUClampLike, U64Operand2) {
6181 const std::string ext_inst_name = GetParam();
6182 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6183 " %u32_0 %f32_0 %u64_1\n";
6184
6185 CompileSuccessfully(GenerateKernelCode(body));
6186 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6187 EXPECT_THAT(
6188 getDiagnosticString(),
6189 HasSubstr("OpenCL.std " + ext_inst_name +
6190 ": expected types of all operands to be equal to Result Type"));
6191 }
6192
6193 TEST_P(ValidateOpenCLStdUClampLike, U64Operand3) {
6194 const std::string ext_inst_name = GetParam();
6195 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6196 " %u32_0 %u32_0 %u64_1\n";
6197
6198 CompileSuccessfully(GenerateKernelCode(body));
6199 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6200 EXPECT_THAT(
6201 getDiagnosticString(),
6202 HasSubstr("OpenCL.std " + ext_inst_name +
6203 ": expected types of all operands to be equal to Result Type"));
6204 }
6205
6206 INSTANTIATE_TEST_SUITE_P(AllUClampLike, ValidateOpenCLStdUClampLike,
6207 ::testing::ValuesIn(std::vector<std::string>{
6208 "s_clamp",
6209 "u_clamp",
6210 "s_mad_hi",
6211 "u_mad_sat",
6212 "s_mad_sat",
6213 "u_mad_hi",
6214 }));
6215
6216 // -------------------------------------------------------------
6217 TEST_P(ValidateOpenCLStdUMul24Like, Success) {
6218 const std::string ext_inst_name = GetParam();
6219 std::ostringstream ss;
6220 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
6221 << " %u32_1 %u32_2\n";
6222 ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
6223 << " %u32_1 %u32_2\n";
6224 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
6225 << " %u32_1 %u32_2\n";
6226 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
6227 << " %u32_1 %u32_2\n";
6228 ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6229 << " %u32vec2_01 %u32vec2_01\n";
6230 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6231 << " %u32vec2_01 %u32vec2_01\n";
6232 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6233 << " %u32vec2_01 %u32vec2_01\n";
6234 ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6235 << " %u32vec2_01 %u32vec2_01\n";
6236 CompileSuccessfully(GenerateKernelCode(ss.str()));
6237 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6238 }
6239
6240 TEST_P(ValidateOpenCLStdUMul24Like, FloatResultType) {
6241 const std::string ext_inst_name = GetParam();
6242 const std::string body =
6243 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32_0 %u32_0\n";
6244
6245 CompileSuccessfully(GenerateKernelCode(body));
6246 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6247 EXPECT_THAT(
6248 getDiagnosticString(),
6249 HasSubstr(
6250 "OpenCL.std " + ext_inst_name +
6251 ": expected Result Type to be a 32-bit int scalar or vector type"));
6252 }
6253
6254 TEST_P(ValidateOpenCLStdUMul24Like, U64ResultType) {
6255 const std::string ext_inst_name = GetParam();
6256 const std::string body =
6257 "%val1 = OpExtInst %u64 %extinst " + ext_inst_name + " %u64_0 %u64_0\n";
6258
6259 CompileSuccessfully(GenerateKernelCode(body));
6260 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6261 EXPECT_THAT(
6262 getDiagnosticString(),
6263 HasSubstr(
6264 "OpenCL.std " + ext_inst_name +
6265 ": expected Result Type to be a 32-bit int scalar or vector type"));
6266 }
6267
6268 TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand1) {
6269 const std::string ext_inst_name = GetParam();
6270 const std::string body =
6271 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_0 %u32_0\n";
6272
6273 CompileSuccessfully(GenerateKernelCode(body));
6274 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6275 EXPECT_THAT(
6276 getDiagnosticString(),
6277 HasSubstr("OpenCL.std " + ext_inst_name +
6278 ": expected types of all operands to be equal to Result Type"));
6279 }
6280
6281 TEST_P(ValidateOpenCLStdUMul24Like, FloatOperand2) {
6282 const std::string ext_inst_name = GetParam();
6283 const std::string body =
6284 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %f32_0\n";
6285
6286 CompileSuccessfully(GenerateKernelCode(body));
6287 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6288 EXPECT_THAT(
6289 getDiagnosticString(),
6290 HasSubstr("OpenCL.std " + ext_inst_name +
6291 ": expected types of all operands to be equal to Result Type"));
6292 }
6293
6294 TEST_P(ValidateOpenCLStdUMul24Like, U64Operand1) {
6295 const std::string ext_inst_name = GetParam();
6296 const std::string body =
6297 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u64_0 %u32_0\n";
6298
6299 CompileSuccessfully(GenerateKernelCode(body));
6300 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6301 EXPECT_THAT(
6302 getDiagnosticString(),
6303 HasSubstr("OpenCL.std " + ext_inst_name +
6304 ": expected types of all operands to be equal to Result Type"));
6305 }
6306
6307 TEST_P(ValidateOpenCLStdUMul24Like, U64Operand2) {
6308 const std::string ext_inst_name = GetParam();
6309 const std::string body =
6310 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %u32_0 %u64_0\n";
6311
6312 CompileSuccessfully(GenerateKernelCode(body));
6313 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6314 EXPECT_THAT(
6315 getDiagnosticString(),
6316 HasSubstr("OpenCL.std " + ext_inst_name +
6317 ": expected types of all operands to be equal to Result Type"));
6318 }
6319
6320 INSTANTIATE_TEST_SUITE_P(AllUMul24Like, ValidateOpenCLStdUMul24Like,
6321 ::testing::ValuesIn(std::vector<std::string>{
6322 "s_mul24",
6323 "u_mul24",
6324 }));
6325
6326 TEST_P(ValidateOpenCLStdUMad24Like, Success) {
6327 const std::string ext_inst_name = GetParam();
6328 std::ostringstream ss;
6329 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
6330 << " %u32_0 %u32_1 %u32_2\n";
6331 ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
6332 << " %u32_0 %u32_1 %u32_2\n";
6333 ss << "%val3 = OpExtInst %u32 %extinst " << ext_inst_name
6334 << " %u32_0 %u32_1 %u32_2\n";
6335 ss << "%val4 = OpExtInst %u32 %extinst " << ext_inst_name
6336 << " %u32_0 %u32_1 %u32_2\n";
6337 ss << "%val5 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6338 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6339 ss << "%val6 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6340 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6341 ss << "%val7 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6342 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6343 ss << "%val8 = OpExtInst %u32vec2 %extinst " << ext_inst_name
6344 << " %u32vec2_01 %u32vec2_01 %u32vec2_12\n";
6345 CompileSuccessfully(GenerateKernelCode(ss.str()));
6346 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6347 }
6348
6349 TEST_P(ValidateOpenCLStdUMad24Like, FloatResultType) {
6350 const std::string ext_inst_name = GetParam();
6351 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6352 " %u32_0 %u32_0 %u32_1\n";
6353
6354 CompileSuccessfully(GenerateKernelCode(body));
6355 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6356 EXPECT_THAT(
6357 getDiagnosticString(),
6358 HasSubstr(
6359 "OpenCL.std " + ext_inst_name +
6360 ": expected Result Type to be a 32-bit int scalar or vector type"));
6361 }
6362
6363 TEST_P(ValidateOpenCLStdUMad24Like, U64ResultType) {
6364 const std::string ext_inst_name = GetParam();
6365 const std::string body = "%val1 = OpExtInst %u64 %extinst " + ext_inst_name +
6366 " %u64_0 %u64_0 %u64_1\n";
6367
6368 CompileSuccessfully(GenerateKernelCode(body));
6369 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6370 EXPECT_THAT(
6371 getDiagnosticString(),
6372 HasSubstr(
6373 "OpenCL.std " + ext_inst_name +
6374 ": expected Result Type to be a 32-bit int scalar or vector type"));
6375 }
6376
6377 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand1) {
6378 const std::string ext_inst_name = GetParam();
6379 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6380 " %f32_0 %u32_0 %u32_1\n";
6381
6382 CompileSuccessfully(GenerateKernelCode(body));
6383 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6384 EXPECT_THAT(
6385 getDiagnosticString(),
6386 HasSubstr("OpenCL.std " + ext_inst_name +
6387 ": expected types of all operands to be equal to Result Type"));
6388 }
6389
6390 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand2) {
6391 const std::string ext_inst_name = GetParam();
6392 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6393 " %u32_0 %f32_0 %u32_1\n";
6394
6395 CompileSuccessfully(GenerateKernelCode(body));
6396 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6397 EXPECT_THAT(
6398 getDiagnosticString(),
6399 HasSubstr("OpenCL.std " + ext_inst_name +
6400 ": expected types of all operands to be equal to Result Type"));
6401 }
6402
6403 TEST_P(ValidateOpenCLStdUMad24Like, FloatOperand3) {
6404 const std::string ext_inst_name = GetParam();
6405 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6406 " %u32_0 %u32_0 %f32_1\n";
6407
6408 CompileSuccessfully(GenerateKernelCode(body));
6409 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6410 EXPECT_THAT(
6411 getDiagnosticString(),
6412 HasSubstr("OpenCL.std " + ext_inst_name +
6413 ": expected types of all operands to be equal to Result Type"));
6414 }
6415
6416 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand1) {
6417 const std::string ext_inst_name = GetParam();
6418 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6419 " %f32_0 %u32_0 %u64_1\n";
6420
6421 CompileSuccessfully(GenerateKernelCode(body));
6422 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6423 EXPECT_THAT(
6424 getDiagnosticString(),
6425 HasSubstr("OpenCL.std " + ext_inst_name +
6426 ": expected types of all operands to be equal to Result Type"));
6427 }
6428
6429 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand2) {
6430 const std::string ext_inst_name = GetParam();
6431 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6432 " %u32_0 %f32_0 %u64_1\n";
6433
6434 CompileSuccessfully(GenerateKernelCode(body));
6435 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6436 EXPECT_THAT(
6437 getDiagnosticString(),
6438 HasSubstr("OpenCL.std " + ext_inst_name +
6439 ": expected types of all operands to be equal to Result Type"));
6440 }
6441
6442 TEST_P(ValidateOpenCLStdUMad24Like, U64Operand3) {
6443 const std::string ext_inst_name = GetParam();
6444 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6445 " %u32_0 %u32_0 %u64_1\n";
6446
6447 CompileSuccessfully(GenerateKernelCode(body));
6448 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6449 EXPECT_THAT(
6450 getDiagnosticString(),
6451 HasSubstr("OpenCL.std " + ext_inst_name +
6452 ": expected types of all operands to be equal to Result Type"));
6453 }
6454
6455 INSTANTIATE_TEST_SUITE_P(AllUMad24Like, ValidateOpenCLStdUMad24Like,
6456 ::testing::ValuesIn(std::vector<std::string>{
6457 "s_mad24",
6458 "u_mad24",
6459 }));
6460
6461 TEST_F(ValidateExtInst, OpenCLStdCrossSuccess) {
6462 const std::string body = R"(
6463 %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_012 %f32vec3_123
6464 %val2 = OpExtInst %f32vec4 %extinst cross %f32vec4_0123 %f32vec4_0123
6465 )";
6466
6467 CompileSuccessfully(GenerateKernelCode(body));
6468 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6469 }
6470
6471 TEST_F(ValidateExtInst, OpenCLStdCrossIntVectorResultType) {
6472 const std::string body = R"(
6473 %val1 = OpExtInst %u32vec3 %extinst cross %f32vec3_012 %f32vec3_123
6474 )";
6475
6476 CompileSuccessfully(GenerateKernelCode(body));
6477 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6478 EXPECT_THAT(getDiagnosticString(),
6479 HasSubstr("OpenCL.std cross: "
6480 "expected Result Type to be a float vector type"));
6481 }
6482
6483 TEST_F(ValidateExtInst, OpenCLStdCrossResultTypeWrongSize) {
6484 const std::string body = R"(
6485 %val1 = OpExtInst %f32vec2 %extinst cross %f32vec3_012 %f32vec3_123
6486 )";
6487
6488 CompileSuccessfully(GenerateKernelCode(body));
6489 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6490 EXPECT_THAT(getDiagnosticString(),
6491 HasSubstr("OpenCL.std cross: "
6492 "expected Result Type to have 3 or 4 components"));
6493 }
6494
6495 TEST_F(ValidateExtInst, OpenCLStdCrossXWrongType) {
6496 const std::string body = R"(
6497 %val1 = OpExtInst %f32vec3 %extinst cross %f64vec3_012 %f32vec3_123
6498 )";
6499
6500 CompileSuccessfully(GenerateKernelCode(body));
6501 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6502 EXPECT_THAT(getDiagnosticString(),
6503 HasSubstr("OpenCL.std cross: "
6504 "expected operand X type to be equal to Result Type"));
6505 }
6506
6507 TEST_F(ValidateExtInst, OpenCLStdCrossYWrongType) {
6508 const std::string body = R"(
6509 %val1 = OpExtInst %f32vec3 %extinst cross %f32vec3_123 %f64vec3_012
6510 )";
6511
6512 CompileSuccessfully(GenerateKernelCode(body));
6513 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6514 EXPECT_THAT(getDiagnosticString(),
6515 HasSubstr("OpenCL.std cross: "
6516 "expected operand Y type to be equal to Result Type"));
6517 }
6518
6519 TEST_P(ValidateOpenCLStdLengthLike, Success) {
6520 const std::string ext_inst_name = GetParam();
6521 std::ostringstream ss;
6522 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32vec2_01\n";
6523 ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name
6524 << " %f32vec4_0123\n";
6525
6526 CompileSuccessfully(GenerateKernelCode(ss.str()));
6527 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6528 }
6529
6530 TEST_P(ValidateOpenCLStdLengthLike, IntResultType) {
6531 const std::string ext_inst_name = GetParam();
6532 const std::string body =
6533 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32vec2_01\n";
6534
6535 CompileSuccessfully(GenerateKernelCode(body));
6536 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6537 EXPECT_THAT(getDiagnosticString(),
6538 HasSubstr("OpenCL.std " + ext_inst_name +
6539 ": "
6540 "expected Result Type to be a float scalar type"));
6541 }
6542
6543 TEST_P(ValidateOpenCLStdLengthLike, IntX) {
6544 const std::string ext_inst_name = GetParam();
6545 const std::string body =
6546 "%val1 = OpExtInst %f32 %extinst " + ext_inst_name + " %u32vec2_01\n";
6547
6548 CompileSuccessfully(GenerateKernelCode(body));
6549 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6550 EXPECT_THAT(getDiagnosticString(),
6551 HasSubstr("OpenCL.std " + ext_inst_name +
6552 ": "
6553 "expected operand P to be a float scalar or vector"));
6554 }
6555
6556 TEST_P(ValidateOpenCLStdLengthLike, VectorTooBig) {
6557 const std::string ext_inst_name = GetParam();
6558 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6559 " %f32vec8_01010101\n";
6560
6561 CompileSuccessfully(GenerateKernelCode(body));
6562 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6563 EXPECT_THAT(
6564 getDiagnosticString(),
6565 HasSubstr("OpenCL.std " + ext_inst_name +
6566 ": "
6567 "expected operand P to have no more than 4 components"));
6568 }
6569
6570 TEST_P(ValidateOpenCLStdLengthLike, DifferentType) {
6571 const std::string ext_inst_name = GetParam();
6572 const std::string body =
6573 "%val1 = OpExtInst %f64 %extinst " + ext_inst_name + " %f32vec2_01\n";
6574
6575 CompileSuccessfully(GenerateKernelCode(body));
6576 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6577 EXPECT_THAT(getDiagnosticString(),
6578 HasSubstr("OpenCL.std " + ext_inst_name +
6579 ": "
6580 "expected operand P component type to be equal to "
6581 "Result Type"));
6582 }
6583
6584 INSTANTIATE_TEST_SUITE_P(AllLengthLike, ValidateOpenCLStdLengthLike,
6585 ::testing::ValuesIn(std::vector<std::string>{
6586 "length",
6587 "fast_length",
6588 }));
6589
6590 TEST_P(ValidateOpenCLStdDistanceLike, Success) {
6591 const std::string ext_inst_name = GetParam();
6592 std::ostringstream ss;
6593 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
6594 << " %f32vec2_01 %f32vec2_01\n";
6595 ss << "%val2 = OpExtInst %f32 %extinst " << ext_inst_name
6596 << " %f32vec4_0123 %f32vec4_1234\n";
6597 ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name
6598 << " %f32_0 %f32_1\n";
6599
6600 CompileSuccessfully(GenerateKernelCode(ss.str()));
6601 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6602 }
6603
6604 TEST_P(ValidateOpenCLStdDistanceLike, IntResultType) {
6605 const std::string ext_inst_name = GetParam();
6606 const std::string body = "%val1 = OpExtInst %u32 %extinst " + ext_inst_name +
6607 " %f32vec2_01 %f32vec2_12\n";
6608
6609 CompileSuccessfully(GenerateKernelCode(body));
6610 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6611 EXPECT_THAT(getDiagnosticString(),
6612 HasSubstr("OpenCL.std " + ext_inst_name +
6613 ": "
6614 "expected Result Type to be a float scalar type"));
6615 }
6616
6617 TEST_P(ValidateOpenCLStdDistanceLike, IntP0) {
6618 const std::string ext_inst_name = GetParam();
6619 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6620 " %u32vec2_01 %f32vec2_12\n";
6621
6622 CompileSuccessfully(GenerateKernelCode(body));
6623 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6624 EXPECT_THAT(
6625 getDiagnosticString(),
6626 HasSubstr("OpenCL.std " + ext_inst_name +
6627 ": "
6628 "expected operand P0 to be of float scalar or vector type"));
6629 }
6630
6631 TEST_P(ValidateOpenCLStdDistanceLike, VectorTooBig) {
6632 const std::string ext_inst_name = GetParam();
6633 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6634 " %f32vec8_01010101 %f32vec8_01010101\n";
6635
6636 CompileSuccessfully(GenerateKernelCode(body));
6637 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6638 EXPECT_THAT(
6639 getDiagnosticString(),
6640 HasSubstr("OpenCL.std " + ext_inst_name +
6641 ": "
6642 "expected operand P0 to have no more than 4 components"));
6643 }
6644
6645 TEST_P(ValidateOpenCLStdDistanceLike, F64P0) {
6646 const std::string ext_inst_name = GetParam();
6647 const std::string body = "%val1 = OpExtInst %f32 %extinst " + ext_inst_name +
6648 " %f64vec2_01 %f32vec2_12\n";
6649
6650 CompileSuccessfully(GenerateKernelCode(body));
6651 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6652 EXPECT_THAT(
6653 getDiagnosticString(),
6654 HasSubstr(
6655 "OpenCL.std " + ext_inst_name +
6656 ": "
6657 "expected operand P0 component type to be equal to Result Type"));
6658 }
6659
6660 TEST_P(ValidateOpenCLStdDistanceLike, DifferentOperands) {
6661 const std::string ext_inst_name = GetParam();
6662 const std::string body = "%val1 = OpExtInst %f64 %extinst " + ext_inst_name +
6663 " %f64vec2_01 %f32vec2_12\n";
6664
6665 CompileSuccessfully(GenerateKernelCode(body));
6666 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6667 EXPECT_THAT(getDiagnosticString(),
6668 HasSubstr("OpenCL.std " + ext_inst_name +
6669 ": "
6670 "expected operands P0 and P1 to be of the same type"));
6671 }
6672
6673 INSTANTIATE_TEST_SUITE_P(AllDistanceLike, ValidateOpenCLStdDistanceLike,
6674 ::testing::ValuesIn(std::vector<std::string>{
6675 "distance",
6676 "fast_distance",
6677 }));
6678
6679 TEST_P(ValidateOpenCLStdNormalizeLike, Success) {
6680 const std::string ext_inst_name = GetParam();
6681 std::ostringstream ss;
6682 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
6683 << " %f32vec2_01\n";
6684 ss << "%val2 = OpExtInst %f32vec4 %extinst " << ext_inst_name
6685 << " %f32vec4_0123\n";
6686 ss << "%val3 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_2\n";
6687
6688 CompileSuccessfully(GenerateKernelCode(ss.str()));
6689 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6690 }
6691
6692 TEST_P(ValidateOpenCLStdNormalizeLike, IntResultType) {
6693 const std::string ext_inst_name = GetParam();
6694 const std::string body =
6695 "%val1 = OpExtInst %u32 %extinst " + ext_inst_name + " %f32_2\n";
6696
6697 CompileSuccessfully(GenerateKernelCode(body));
6698 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6699 EXPECT_THAT(
6700 getDiagnosticString(),
6701 HasSubstr("OpenCL.std " + ext_inst_name +
6702 ": "
6703 "expected Result Type to be a float scalar or vector type"));
6704 }
6705
6706 TEST_P(ValidateOpenCLStdNormalizeLike, VectorTooBig) {
6707 const std::string ext_inst_name = GetParam();
6708 const std::string body = "%val1 = OpExtInst %f32vec8 %extinst " +
6709 ext_inst_name + " %f32vec8_01010101\n";
6710
6711 CompileSuccessfully(GenerateKernelCode(body));
6712 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6713 EXPECT_THAT(
6714 getDiagnosticString(),
6715 HasSubstr("OpenCL.std " + ext_inst_name +
6716 ": "
6717 "expected Result Type to have no more than 4 components"));
6718 }
6719
6720 TEST_P(ValidateOpenCLStdNormalizeLike, DifferentType) {
6721 const std::string ext_inst_name = GetParam();
6722 const std::string body =
6723 "%val1 = OpExtInst %f64vec2 %extinst " + ext_inst_name + " %f32vec2_01\n";
6724
6725 CompileSuccessfully(GenerateKernelCode(body));
6726 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6727 EXPECT_THAT(getDiagnosticString(),
6728 HasSubstr("OpenCL.std " + ext_inst_name +
6729 ": "
6730 "expected operand P type to be equal to Result Type"));
6731 }
6732
6733 INSTANTIATE_TEST_SUITE_P(AllNormalizeLike, ValidateOpenCLStdNormalizeLike,
6734 ::testing::ValuesIn(std::vector<std::string>{
6735 "normalize",
6736 "fast_normalize",
6737 }));
6738
6739 TEST_F(ValidateExtInst, OpenCLStdBitselectSuccess) {
6740 const std::string body = R"(
6741 %val1 = OpExtInst %f32 %extinst bitselect %f32_2 %f32_1 %f32_1
6742 %val2 = OpExtInst %f32vec4 %extinst bitselect %f32vec4_0123 %f32vec4_1234 %f32vec4_0123
6743 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %u32_1
6744 %val4 = OpExtInst %u32vec4 %extinst bitselect %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
6745 %val5 = OpExtInst %u64 %extinst bitselect %u64_2 %u64_1 %u64_1
6746 )";
6747
6748 CompileSuccessfully(GenerateKernelCode(body));
6749 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6750 }
6751
6752 TEST_F(ValidateExtInst, OpenCLStdBitselectWrongResultType) {
6753 const std::string body = R"(
6754 %val3 = OpExtInst %struct_f32_f32 %extinst bitselect %u32_2 %u32_1 %u32_1
6755 )";
6756
6757 CompileSuccessfully(GenerateKernelCode(body));
6758 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6759 EXPECT_THAT(
6760 getDiagnosticString(),
6761 HasSubstr(
6762 "OpenCL.std bitselect: "
6763 "expected Result Type to be an int or float scalar or vector type"));
6764 }
6765
6766 TEST_F(ValidateExtInst, OpenCLStdBitselectAWrongType) {
6767 const std::string body = R"(
6768 %val3 = OpExtInst %u32 %extinst bitselect %f32_2 %u32_1 %u32_1
6769 )";
6770
6771 CompileSuccessfully(GenerateKernelCode(body));
6772 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6773 EXPECT_THAT(
6774 getDiagnosticString(),
6775 HasSubstr("OpenCL.std bitselect: "
6776 "expected types of all operands to be equal to Result Type"));
6777 }
6778
6779 TEST_F(ValidateExtInst, OpenCLStdBitselectBWrongType) {
6780 const std::string body = R"(
6781 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %f32_1 %u32_1
6782 )";
6783
6784 CompileSuccessfully(GenerateKernelCode(body));
6785 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6786 EXPECT_THAT(
6787 getDiagnosticString(),
6788 HasSubstr("OpenCL.std bitselect: "
6789 "expected types of all operands to be equal to Result Type"));
6790 }
6791
6792 TEST_F(ValidateExtInst, OpenCLStdBitselectCWrongType) {
6793 const std::string body = R"(
6794 %val3 = OpExtInst %u32 %extinst bitselect %u32_2 %u32_1 %f32_1
6795 )";
6796
6797 CompileSuccessfully(GenerateKernelCode(body));
6798 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6799 EXPECT_THAT(
6800 getDiagnosticString(),
6801 HasSubstr("OpenCL.std bitselect: "
6802 "expected types of all operands to be equal to Result Type"));
6803 }
6804
6805 TEST_F(ValidateExtInst, OpenCLStdSelectSuccess) {
6806 const std::string body = R"(
6807 %val1 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %u32_1
6808 %val2 = OpExtInst %f32vec4 %extinst select %f32vec4_0123 %f32vec4_1234 %u32vec4_0123
6809 %val3 = OpExtInst %u32 %extinst select %u32_2 %u32_1 %u32_1
6810 %val4 = OpExtInst %u32vec4 %extinst select %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
6811 %val5 = OpExtInst %u64 %extinst select %u64_2 %u64_1 %u64_1
6812 )";
6813
6814 CompileSuccessfully(GenerateKernelCode(body));
6815 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6816 }
6817
6818 TEST_F(ValidateExtInst, OpenCLStdSelectWrongResultType) {
6819 const std::string body = R"(
6820 %val3 = OpExtInst %struct_f32_f32 %extinst select %u32_2 %u32_1 %u32_1
6821 )";
6822
6823 CompileSuccessfully(GenerateKernelCode(body));
6824 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6825 EXPECT_THAT(
6826 getDiagnosticString(),
6827 HasSubstr(
6828 "OpenCL.std select: "
6829 "expected Result Type to be an int or float scalar or vector type"));
6830 }
6831
6832 TEST_F(ValidateExtInst, OpenCLStdSelectAWrongType) {
6833 const std::string body = R"(
6834 %val3 = OpExtInst %u32 %extinst select %f32_2 %u32_1 %u32_1
6835 )";
6836
6837 CompileSuccessfully(GenerateKernelCode(body));
6838 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6839 EXPECT_THAT(getDiagnosticString(),
6840 HasSubstr("OpenCL.std select: "
6841 "expected operand A type to be equal to Result Type"));
6842 }
6843
6844 TEST_F(ValidateExtInst, OpenCLStdSelectBWrongType) {
6845 const std::string body = R"(
6846 %val3 = OpExtInst %u32 %extinst select %u32_2 %f32_1 %u32_1
6847 )";
6848
6849 CompileSuccessfully(GenerateKernelCode(body));
6850 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6851 EXPECT_THAT(getDiagnosticString(),
6852 HasSubstr("OpenCL.std select: "
6853 "expected operand B type to be equal to Result Type"));
6854 }
6855
6856 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongType) {
6857 const std::string body = R"(
6858 %val3 = OpExtInst %f32 %extinst select %f32_2 %f32_1 %f32_1
6859 )";
6860
6861 CompileSuccessfully(GenerateKernelCode(body));
6862 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6863 EXPECT_THAT(getDiagnosticString(),
6864 HasSubstr("OpenCL.std select: "
6865 "expected operand C to be an int scalar or vector"));
6866 }
6867
6868 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongComponentNumber) {
6869 const std::string body = R"(
6870 %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u32_1
6871 )";
6872
6873 CompileSuccessfully(GenerateKernelCode(body));
6874 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6875 EXPECT_THAT(getDiagnosticString(),
6876 HasSubstr("OpenCL.std select: "
6877 "expected operand C to have the same number of "
6878 "components as Result Type"));
6879 }
6880
6881 TEST_F(ValidateExtInst, OpenCLStdSelectCWrongBitWidth) {
6882 const std::string body = R"(
6883 %val3 = OpExtInst %f32vec2 %extinst select %f32vec2_12 %f32vec2_01 %u64vec2_01
6884 )";
6885
6886 CompileSuccessfully(GenerateKernelCode(body));
6887 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6888 EXPECT_THAT(
6889 getDiagnosticString(),
6890 HasSubstr(
6891 "OpenCL.std select: "
6892 "expected operand C to have the same bit width as Result Type"));
6893 }
6894
6895 TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical32) {
6896 const std::string ext_inst_name = GetParam();
6897 const std::string rounding_mode =
6898 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6899
6900 std::ostringstream ss;
6901 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6902 if (std::string::npos == ext_inst_name.find("halfn")) {
6903 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6904 << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n";
6905 ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6906 << " %f64_0 %u32_2 %ptr" << rounding_mode << "\n";
6907 } else {
6908 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6909 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6910 ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6911 << " %f32vec4_0123 %u32_0 %ptr" << rounding_mode << "\n";
6912 ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name
6913 << " %f64vec2_01 %u32_2 %ptr" << rounding_mode << "\n";
6914 }
6915
6916 CompileSuccessfully(GenerateKernelCode(ss.str()));
6917 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6918 }
6919
6920 TEST_P(ValidateOpenCLStdVStoreHalfLike, SuccessPhysical64) {
6921 const std::string ext_inst_name = GetParam();
6922 const std::string rounding_mode =
6923 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6924
6925 std::ostringstream ss;
6926 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6927 if (std::string::npos == ext_inst_name.find("halfn")) {
6928 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6929 << " %f32_1 %u64_1 %ptr" << rounding_mode << "\n";
6930 ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6931 << " %f64_0 %u64_2 %ptr" << rounding_mode << "\n";
6932 } else {
6933 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6934 << " %f32vec2_01 %u64_1 %ptr" << rounding_mode << "\n";
6935 ss << "%val2 = OpExtInst %void %extinst " << ext_inst_name
6936 << " %f32vec4_0123 %u64_0 %ptr" << rounding_mode << "\n";
6937 ss << "%val3 = OpExtInst %void %extinst " << ext_inst_name
6938 << " %f64vec2_01 %u64_2 %ptr" << rounding_mode << "\n";
6939 }
6940
6941 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
6942 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
6943 }
6944
6945 TEST_P(ValidateOpenCLStdVStoreHalfLike, NonVoidResultType) {
6946 const std::string ext_inst_name = GetParam();
6947 const std::string rounding_mode =
6948 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6949
6950 std::ostringstream ss;
6951 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6952 if (std::string::npos == ext_inst_name.find("halfn")) {
6953 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
6954 << " %f32_1 %u32_1 %ptr" << rounding_mode << "\n";
6955 } else {
6956 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
6957 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6958 }
6959
6960 CompileSuccessfully(GenerateKernelCode(ss.str()));
6961 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6962 EXPECT_THAT(getDiagnosticString(),
6963 HasSubstr("OpenCL.std " + ext_inst_name +
6964 ": expected Result Type to be void"));
6965 }
6966
6967 TEST_P(ValidateOpenCLStdVStoreHalfLike, WrongDataType) {
6968 const std::string ext_inst_name = GetParam();
6969 const std::string rounding_mode =
6970 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6971
6972 std::ostringstream ss;
6973 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
6974 if (std::string::npos == ext_inst_name.find("halfn")) {
6975 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6976 << " %f64vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
6977 CompileSuccessfully(GenerateKernelCode(ss.str()));
6978 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6979 EXPECT_THAT(getDiagnosticString(),
6980 HasSubstr("OpenCL.std " + ext_inst_name +
6981 ": expected Data to be a 32 or 64-bit float scalar"));
6982 } else {
6983 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
6984 << " %f64_0 %u32_1 %ptr" << rounding_mode << "\n";
6985 CompileSuccessfully(GenerateKernelCode(ss.str()));
6986 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
6987 EXPECT_THAT(getDiagnosticString(),
6988 HasSubstr("OpenCL.std " + ext_inst_name +
6989 ": expected Data to be a 32 or 64-bit float vector"));
6990 }
6991 }
6992
6993 TEST_P(ValidateOpenCLStdVStoreHalfLike, AddressingModelLogical) {
6994 const std::string ext_inst_name = GetParam();
6995 const std::string rounding_mode =
6996 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
6997
6998 std::ostringstream ss;
6999 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7000 if (std::string::npos == ext_inst_name.find("halfn")) {
7001 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7002 << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
7003 } else {
7004 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7005 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
7006 }
7007
7008 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7009 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7010 EXPECT_THAT(getDiagnosticString(),
7011 HasSubstr("OpenCL.std " + ext_inst_name +
7012 " can only be used with physical addressing models"));
7013 }
7014
7015 TEST_P(ValidateOpenCLStdVStoreHalfLike, OffsetNotSizeT) {
7016 const std::string ext_inst_name = GetParam();
7017 const std::string rounding_mode =
7018 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
7019
7020 std::ostringstream ss;
7021 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7022 if (std::string::npos == ext_inst_name.find("halfn")) {
7023 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7024 << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
7025 } else {
7026 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7027 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
7028 }
7029
7030 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7031 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7032 EXPECT_THAT(
7033 getDiagnosticString(),
7034 HasSubstr("OpenCL.std " + ext_inst_name +
7035 ": "
7036 "expected operand Offset to be of type size_t (64-bit integer "
7037 "for the addressing model used in the module)"));
7038 }
7039
7040 TEST_P(ValidateOpenCLStdVStoreHalfLike, PNotPointer) {
7041 const std::string ext_inst_name = GetParam();
7042 const std::string rounding_mode =
7043 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
7044
7045 std::ostringstream ss;
7046 if (std::string::npos == ext_inst_name.find("halfn")) {
7047 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7048 << " %f32_0 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n";
7049 } else {
7050 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7051 << " %f32vec2_01 %u32_1 %f16_ptr_workgroup" << rounding_mode << "\n";
7052 }
7053
7054 CompileSuccessfully(GenerateKernelCode(ss.str()));
7055 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7056 EXPECT_THAT(getDiagnosticString(),
7057 HasSubstr("Operand 89[%_ptr_Workgroup_half] cannot be a type"));
7058 }
7059
7060 TEST_P(ValidateOpenCLStdVStoreHalfLike, ConstPointer) {
7061 const std::string ext_inst_name = GetParam();
7062 const std::string rounding_mode =
7063 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
7064
7065 std::ostringstream ss;
7066 ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7067 "%f16vec8_uniform_constant %u32_1\n";
7068 if (std::string::npos == ext_inst_name.find("halfn")) {
7069 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7070 << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
7071 } else {
7072 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7073 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
7074 }
7075
7076 CompileSuccessfully(GenerateKernelCode(ss.str()));
7077 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7078 EXPECT_THAT(getDiagnosticString(),
7079 HasSubstr("OpenCL.std " + ext_inst_name +
7080 ": expected operand P storage class to be Generic, "
7081 "CrossWorkgroup, Workgroup or Function"));
7082 }
7083
7084 TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeInt) {
7085 const std::string ext_inst_name = GetParam();
7086 const std::string rounding_mode =
7087 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
7088
7089 std::ostringstream ss;
7090 ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
7091 if (std::string::npos == ext_inst_name.find("halfn")) {
7092 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7093 << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
7094 } else {
7095 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7096 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
7097 }
7098
7099 CompileSuccessfully(GenerateKernelCode(ss.str()));
7100 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7101 EXPECT_THAT(
7102 getDiagnosticString(),
7103 HasSubstr("OpenCL.std " + ext_inst_name +
7104 ": expected operand P data type to be 16-bit float scalar"));
7105 }
7106
7107 TEST_P(ValidateOpenCLStdVStoreHalfLike, PDataTypeFloat32) {
7108 const std::string ext_inst_name = GetParam();
7109 const std::string rounding_mode =
7110 ext_inst_name.substr(ext_inst_name.length() - 2) == "_r" ? " RTE" : "";
7111
7112 std::ostringstream ss;
7113 ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7114 if (std::string::npos == ext_inst_name.find("halfn")) {
7115 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7116 << " %f32_0 %u32_1 %ptr" << rounding_mode << "\n";
7117 } else {
7118 ss << "%val1 = OpExtInst %void %extinst " << ext_inst_name
7119 << " %f32vec2_01 %u32_1 %ptr" << rounding_mode << "\n";
7120 }
7121
7122 CompileSuccessfully(GenerateKernelCode(ss.str()));
7123 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7124 EXPECT_THAT(
7125 getDiagnosticString(),
7126 HasSubstr("OpenCL.std " + ext_inst_name +
7127 ": expected operand P data type to be 16-bit float scalar"));
7128 }
7129
7130 INSTANTIATE_TEST_SUITE_P(AllVStoreHalfLike, ValidateOpenCLStdVStoreHalfLike,
7131 ::testing::ValuesIn(std::vector<std::string>{
7132 "vstore_half",
7133 "vstore_half_r",
7134 "vstore_halfn",
7135 "vstore_halfn_r",
7136 "vstorea_halfn",
7137 "vstorea_halfn_r",
7138 }));
7139
7140 TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical32) {
7141 const std::string ext_inst_name = GetParam();
7142
7143 std::ostringstream ss;
7144 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7145 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7146 << " %u32_1 %ptr 2\n";
7147 ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name
7148 << " %u32_1 %ptr 3\n";
7149 ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
7150 << " %u32_1 %ptr 4\n";
7151
7152 CompileSuccessfully(GenerateKernelCode(ss.str()));
7153 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7154 }
7155
7156 TEST_P(ValidateOpenCLStdVLoadHalfLike, SuccessPhysical64) {
7157 const std::string ext_inst_name = GetParam();
7158
7159 std::ostringstream ss;
7160 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7161 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7162 << " %u64_1 %ptr 2\n";
7163 ss << "%val2 = OpExtInst %f32vec3 %extinst " << ext_inst_name
7164 << " %u64_1 %ptr 3\n";
7165 ss << "%val3 = OpExtInst %f32vec4 %extinst " << ext_inst_name
7166 << " %u64_1 %ptr 4\n";
7167
7168 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7169 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7170 }
7171
7172 TEST_P(ValidateOpenCLStdVLoadHalfLike, ResultTypeNotFloatVector) {
7173 const std::string ext_inst_name = GetParam();
7174
7175 std::ostringstream ss;
7176 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7177 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
7178 << " %u32_1 %ptr 1\n";
7179
7180 CompileSuccessfully(GenerateKernelCode(ss.str()));
7181 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7182 EXPECT_THAT(getDiagnosticString(),
7183 HasSubstr("OpenCL.std " + ext_inst_name +
7184 ": expected Result Type to be a float vector type"));
7185 }
7186
7187 TEST_P(ValidateOpenCLStdVLoadHalfLike, AddressingModelLogical) {
7188 const std::string ext_inst_name = GetParam();
7189
7190 std::ostringstream ss;
7191 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7192 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7193 << " %u32_1 %ptr 2\n";
7194
7195 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7196 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7197 EXPECT_THAT(getDiagnosticString(),
7198 HasSubstr("OpenCL.std " + ext_inst_name +
7199 " can only be used with physical addressing models"));
7200 }
7201
7202 TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetNotSizeT) {
7203 const std::string ext_inst_name = GetParam();
7204
7205 std::ostringstream ss;
7206 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7207 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7208 << " %u64_1 %ptr 2\n";
7209
7210 CompileSuccessfully(GenerateKernelCode(ss.str()));
7211 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7212 EXPECT_THAT(
7213 getDiagnosticString(),
7214 HasSubstr("OpenCL.std " + ext_inst_name +
7215 ": expected operand Offset to be of type size_t (32-bit "
7216 "integer for the addressing model used in the module)"));
7217 }
7218
7219 TEST_P(ValidateOpenCLStdVLoadHalfLike, PNotPointer) {
7220 const std::string ext_inst_name = GetParam();
7221
7222 std::ostringstream ss;
7223 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7224 << " %u32_1 %f16_ptr_workgroup 2\n";
7225
7226 CompileSuccessfully(GenerateKernelCode(ss.str()));
7227 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7228 EXPECT_THAT(getDiagnosticString(),
7229 HasSubstr("Operand 89[%_ptr_Workgroup_half] cannot be a type"));
7230 }
7231
7232 TEST_P(ValidateOpenCLStdVLoadHalfLike, OffsetWrongStorageType) {
7233 const std::string ext_inst_name = GetParam();
7234
7235 std::ostringstream ss;
7236 ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
7237 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7238 << " %u32_1 %ptr 2\n";
7239
7240 CompileSuccessfully(GenerateKernelCode(ss.str()));
7241 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7242 EXPECT_THAT(
7243 getDiagnosticString(),
7244 HasSubstr("OpenCL.std " + ext_inst_name +
7245 ": expected operand P storage class to be UniformConstant, "
7246 "Generic, CrossWorkgroup, Workgroup or Function"));
7247 }
7248
7249 TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeInt) {
7250 const std::string ext_inst_name = GetParam();
7251
7252 std::ostringstream ss;
7253 ss << "%ptr = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
7254 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7255 << " %u32_1 %ptr 2\n";
7256
7257 CompileSuccessfully(GenerateKernelCode(ss.str()));
7258 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7259 EXPECT_THAT(
7260 getDiagnosticString(),
7261 HasSubstr("OpenCL.std " + ext_inst_name +
7262 ": expected operand P data type to be 16-bit float scalar"));
7263 }
7264
7265 TEST_P(ValidateOpenCLStdVLoadHalfLike, PDataTypeFloat32) {
7266 const std::string ext_inst_name = GetParam();
7267
7268 std::ostringstream ss;
7269 ss << "%ptr = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7270 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7271 << " %u32_1 %ptr 2\n";
7272
7273 CompileSuccessfully(GenerateKernelCode(ss.str()));
7274 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7275 EXPECT_THAT(
7276 getDiagnosticString(),
7277 HasSubstr("OpenCL.std " + ext_inst_name +
7278 ": expected operand P data type to be 16-bit float scalar"));
7279 }
7280
7281 TEST_P(ValidateOpenCLStdVLoadHalfLike, WrongN) {
7282 const std::string ext_inst_name = GetParam();
7283
7284 std::ostringstream ss;
7285 ss << "%ptr = OpAccessChain %f16_ptr_workgroup %f16vec8_workgroup %u32_1\n";
7286 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
7287 << " %u32_1 %ptr 3\n";
7288
7289 CompileSuccessfully(GenerateKernelCode(ss.str()));
7290 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7291 EXPECT_THAT(getDiagnosticString(),
7292 HasSubstr("OpenCL.std " + ext_inst_name +
7293 ": expected literal N to be equal to the number of "
7294 "components of Result Type"));
7295 }
7296
7297 INSTANTIATE_TEST_SUITE_P(AllVLoadHalfLike, ValidateOpenCLStdVLoadHalfLike,
7298 ::testing::ValuesIn(std::vector<std::string>{
7299 "vload_halfn",
7300 "vloada_halfn",
7301 }));
7302
7303 TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical32) {
7304 std::ostringstream ss;
7305 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7306 "%f32vec8_uniform_constant %u32_1\n";
7307 ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7308 ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u32_1 %ptr 3\n";
7309 ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u32_1 %ptr 4\n";
7310
7311 CompileSuccessfully(GenerateKernelCode(ss.str()));
7312 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7313 }
7314
7315 TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical32) {
7316 std::ostringstream ss;
7317 ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
7318 "%u32vec8_uniform_constant %u32_1\n";
7319 ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7320 ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u32_1 %ptr 3\n";
7321 ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u32_1 %ptr 4\n";
7322
7323 CompileSuccessfully(GenerateKernelCode(ss.str()));
7324 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7325 }
7326
7327 TEST_F(ValidateExtInst, VLoadNSuccessFloatPhysical64) {
7328 std::ostringstream ss;
7329 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7330 "%f32vec8_uniform_constant %u32_1\n";
7331 ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n";
7332 ss << "%val2 = OpExtInst %f32vec3 %extinst vloadn %u64_1 %ptr 3\n";
7333 ss << "%val3 = OpExtInst %f32vec4 %extinst vloadn %u64_1 %ptr 4\n";
7334
7335 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7336 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7337 }
7338
7339 TEST_F(ValidateExtInst, VLoadNSuccessIntPhysical64) {
7340 std::ostringstream ss;
7341 ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
7342 "%u32vec8_uniform_constant %u32_1\n";
7343 ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u64_1 %ptr 2\n";
7344 ss << "%val2 = OpExtInst %u32vec3 %extinst vloadn %u64_1 %ptr 3\n";
7345 ss << "%val3 = OpExtInst %u32vec4 %extinst vloadn %u64_1 %ptr 4\n";
7346
7347 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7348 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7349 }
7350
7351 TEST_F(ValidateExtInst, VLoadNWrongResultType) {
7352 std::ostringstream ss;
7353 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7354 "%f32vec8_uniform_constant %u32_1\n";
7355 ss << "%val1 = OpExtInst %f32 %extinst vloadn %u32_1 %ptr 2\n";
7356
7357 CompileSuccessfully(GenerateKernelCode(ss.str()));
7358 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7359 EXPECT_THAT(
7360 getDiagnosticString(),
7361 HasSubstr("OpenCL.std vloadn: "
7362 "expected Result Type to be an int or float vector type"));
7363 }
7364
7365 TEST_F(ValidateExtInst, VLoadNAddressingModelLogical) {
7366 std::ostringstream ss;
7367 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7368 "%f32vec8_uniform_constant %u32_1\n";
7369 ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7370
7371 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7372 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7373 EXPECT_THAT(getDiagnosticString(),
7374 HasSubstr("OpenCL.std vloadn can only be used with physical "
7375 "addressing models"));
7376 }
7377
7378 TEST_F(ValidateExtInst, VLoadNOffsetNotSizeT) {
7379 std::ostringstream ss;
7380 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7381 "%f32vec8_uniform_constant %u32_1\n";
7382 ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u64_1 %ptr 2\n";
7383
7384 CompileSuccessfully(GenerateKernelCode(ss.str()));
7385 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7386 EXPECT_THAT(
7387 getDiagnosticString(),
7388 HasSubstr(
7389 "OpenCL.std vloadn: expected operand Offset to be of type size_t "
7390 "(32-bit integer for the addressing model used in the module)"));
7391 }
7392
7393 TEST_F(ValidateExtInst, VLoadNPNotPointer) {
7394 std::ostringstream ss;
7395 ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 "
7396 "%f32_ptr_uniform_constant 2\n";
7397
7398 CompileSuccessfully(GenerateKernelCode(ss.str()));
7399 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7400 EXPECT_THAT(getDiagnosticString(),
7401 HasSubstr("Operand 120[%_ptr_UniformConstant_float] cannot be a "
7402 "type"));
7403 }
7404
7405 TEST_F(ValidateExtInst, VLoadNWrongStorageClass) {
7406 std::ostringstream ss;
7407 ss << "%ptr = OpAccessChain %u32_ptr_input %u32vec8_input %u32_1\n";
7408 ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7409
7410 CompileSuccessfully(GenerateKernelCode(ss.str()));
7411 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7412 EXPECT_THAT(getDiagnosticString(),
7413 HasSubstr("OpenCL.std vloadn: expected operand P storage class "
7414 "to be UniformConstant, Generic, CrossWorkgroup, "
7415 "Workgroup or Function"));
7416 }
7417
7418 TEST_F(ValidateExtInst, VLoadNWrongComponentType) {
7419 std::ostringstream ss;
7420 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7421 "%f32vec8_uniform_constant %u32_1\n";
7422 ss << "%val1 = OpExtInst %u32vec2 %extinst vloadn %u32_1 %ptr 2\n";
7423
7424 CompileSuccessfully(GenerateKernelCode(ss.str()));
7425 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7426 EXPECT_THAT(getDiagnosticString(),
7427 HasSubstr("OpenCL.std vloadn: expected operand P data type to be "
7428 "equal to component type of Result Type"));
7429 }
7430
7431 TEST_F(ValidateExtInst, VLoadNWrongN) {
7432 std::ostringstream ss;
7433 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7434 "%f32vec8_uniform_constant %u32_1\n";
7435 ss << "%val1 = OpExtInst %f32vec2 %extinst vloadn %u32_1 %ptr 3\n";
7436
7437 CompileSuccessfully(GenerateKernelCode(ss.str()));
7438 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7439 EXPECT_THAT(getDiagnosticString(),
7440 HasSubstr("OpenCL.std vloadn: expected literal N to be equal to "
7441 "the number of components of Result Type"));
7442 }
7443
7444 TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical32) {
7445 std::ostringstream ss;
7446 ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7447 "%f16vec8_uniform_constant %u32_1\n";
7448 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7449 ss << "%val2 = OpExtInst %f64 %extinst vload_half %u32_1 %ptr\n";
7450
7451 CompileSuccessfully(GenerateKernelCode(ss.str()));
7452 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7453 }
7454
7455 TEST_F(ValidateExtInst, VLoadHalfSuccessPhysical64) {
7456 std::ostringstream ss;
7457 ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7458 "%f16vec8_uniform_constant %u32_1\n";
7459 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
7460 ss << "%val2 = OpExtInst %f64 %extinst vload_half %u64_1 %ptr\n";
7461
7462 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7463 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7464 }
7465
7466 TEST_F(ValidateExtInst, VLoadHalfWrongResultType) {
7467 std::ostringstream ss;
7468 ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7469 "%f16vec8_uniform_constant %u32_1\n";
7470 ss << "%val1 = OpExtInst %u32 %extinst vload_half %u32_1 %ptr\n";
7471
7472 CompileSuccessfully(GenerateKernelCode(ss.str()));
7473 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7474 EXPECT_THAT(getDiagnosticString(),
7475 HasSubstr("OpenCL.std vload_half: "
7476 "expected Result Type to be a float scalar type"));
7477 }
7478
7479 TEST_F(ValidateExtInst, VLoadHalfAddressingModelLogical) {
7480 std::ostringstream ss;
7481 ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7482 "%f16vec8_uniform_constant %u32_1\n";
7483 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7484
7485 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7486 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7487 EXPECT_THAT(getDiagnosticString(),
7488 HasSubstr("OpenCL.std vload_half can only be used with physical "
7489 "addressing models"));
7490 }
7491
7492 TEST_F(ValidateExtInst, VLoadHalfOffsetNotSizeT) {
7493 std::ostringstream ss;
7494 ss << "%ptr = OpAccessChain %f16_ptr_uniform_constant "
7495 "%f16vec8_uniform_constant %u32_1\n";
7496 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u64_1 %ptr\n";
7497
7498 CompileSuccessfully(GenerateKernelCode(ss.str()));
7499 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7500 EXPECT_THAT(
7501 getDiagnosticString(),
7502 HasSubstr(
7503 "OpenCL.std vload_half: expected operand Offset to be of type size_t "
7504 "(32-bit integer for the addressing model used in the module)"));
7505 }
7506
7507 TEST_F(ValidateExtInst, VLoadHalfPNotPointer) {
7508 std::ostringstream ss;
7509 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 "
7510 "%f16_ptr_uniform_constant\n";
7511
7512 CompileSuccessfully(GenerateKernelCode(ss.str()));
7513 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7514 EXPECT_THAT(getDiagnosticString(),
7515 HasSubstr("Operand 114[%_ptr_UniformConstant_half] cannot be a "
7516 "type"));
7517 }
7518
7519 TEST_F(ValidateExtInst, VLoadHalfWrongStorageClass) {
7520 std::ostringstream ss;
7521 ss << "%ptr = OpAccessChain %f16_ptr_input %f16vec8_input %u32_1\n";
7522 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7523
7524 CompileSuccessfully(GenerateKernelCode(ss.str()));
7525 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7526 EXPECT_THAT(
7527 getDiagnosticString(),
7528 HasSubstr(
7529 "OpenCL.std vload_half: expected operand P storage class to be "
7530 "UniformConstant, Generic, CrossWorkgroup, Workgroup or Function"));
7531 }
7532
7533 TEST_F(ValidateExtInst, VLoadHalfPDataTypeInt) {
7534 std::ostringstream ss;
7535 ss << "%ptr = OpAccessChain %u32_ptr_uniform_constant "
7536 "%u32vec8_uniform_constant %u32_1\n";
7537 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7538
7539 CompileSuccessfully(GenerateKernelCode(ss.str()));
7540 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7541 EXPECT_THAT(getDiagnosticString(),
7542 HasSubstr("OpenCL.std vload_half: expected operand P data type "
7543 "to be 16-bit float scalar"));
7544 }
7545
7546 TEST_F(ValidateExtInst, VLoadHalfPDataTypeFloat32) {
7547 std::ostringstream ss;
7548 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
7549 "%f32vec8_uniform_constant %u32_1\n";
7550 ss << "%val1 = OpExtInst %f32 %extinst vload_half %u32_1 %ptr\n";
7551
7552 CompileSuccessfully(GenerateKernelCode(ss.str()));
7553 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7554 EXPECT_THAT(getDiagnosticString(),
7555 HasSubstr("OpenCL.std vload_half: expected operand P data type "
7556 "to be 16-bit float scalar"));
7557 }
7558
7559 TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical32) {
7560 std::ostringstream ss;
7561 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7562 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7563 ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
7564 ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u32_1 "
7565 "%ptr_g\n";
7566
7567 CompileSuccessfully(GenerateKernelCode(ss.str()));
7568 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7569 }
7570
7571 TEST_F(ValidateExtInst, VStoreNSuccessFloatPhysical64) {
7572 std::ostringstream ss;
7573 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7574 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7575 ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u64_1 %ptr_g\n";
7576 ss << "%val2 = OpExtInst %void %extinst vstoren %f32vec4_0123 %u64_1 "
7577 "%ptr_g\n";
7578
7579 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7580 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7581 }
7582
7583 TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical32) {
7584 std::ostringstream ss;
7585 ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
7586 ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
7587 ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
7588 ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u32_1 "
7589 "%ptr_g\n";
7590
7591 CompileSuccessfully(GenerateKernelCode(ss.str()));
7592 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7593 }
7594
7595 TEST_F(ValidateExtInst, VStoreNSuccessIntPhysical64) {
7596 std::ostringstream ss;
7597 ss << "%ptr_w = OpAccessChain %u32_ptr_workgroup %u32vec8_workgroup %u32_1\n";
7598 ss << "%ptr_g = OpPtrCastToGeneric %u32_ptr_generic %ptr_w\n";
7599 ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u64_1 %ptr_g\n";
7600 ss << "%val2 = OpExtInst %void %extinst vstoren %u32vec4_0123 %u64_1 "
7601 "%ptr_g\n";
7602
7603 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7604 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7605 }
7606
7607 TEST_F(ValidateExtInst, VStoreNResultTypeNotVoid) {
7608 std::ostringstream ss;
7609 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7610 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7611 ss << "%val1 = OpExtInst %f32 %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
7612
7613 CompileSuccessfully(GenerateKernelCode(ss.str()));
7614 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7615 EXPECT_THAT(getDiagnosticString(),
7616 HasSubstr("OpenCL.std vstoren: expected Result Type to be void"));
7617 }
7618
7619 TEST_F(ValidateExtInst, VStoreNDataWrongType) {
7620 std::ostringstream ss;
7621 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7622 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7623 ss << "%val1 = OpExtInst %void %extinst vstoren %f32_1 %u32_1 %ptr_g\n";
7624
7625 CompileSuccessfully(GenerateKernelCode(ss.str()));
7626 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7627 EXPECT_THAT(
7628 getDiagnosticString(),
7629 HasSubstr(
7630 "OpenCL.std vstoren: expected Data to be an int or float vector"));
7631 }
7632
7633 TEST_F(ValidateExtInst, VStoreNAddressingModelLogical) {
7634 std::ostringstream ss;
7635 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7636 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7637 ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
7638
7639 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Logical"));
7640 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7641 EXPECT_THAT(getDiagnosticString(),
7642 HasSubstr("OpenCL.std vstoren can only be used with physical "
7643 "addressing models"));
7644 }
7645
7646 TEST_F(ValidateExtInst, VStoreNOffsetNotSizeT) {
7647 std::ostringstream ss;
7648 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7649 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7650 ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_g\n";
7651
7652 CompileSuccessfully(GenerateKernelCode(ss.str(), "", "Physical64"));
7653 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7654 EXPECT_THAT(
7655 getDiagnosticString(),
7656 HasSubstr(
7657 "OpenCL.std vstoren: expected operand Offset to be of type size_t "
7658 "(64-bit integer for the addressing model used in the module)"));
7659 }
7660
7661 TEST_F(ValidateExtInst, VStoreNPNotPointer) {
7662 std::ostringstream ss;
7663 ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 "
7664 "%f32_ptr_generic\n";
7665
7666 CompileSuccessfully(GenerateKernelCode(ss.str()));
7667 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7668 EXPECT_THAT(getDiagnosticString(),
7669 HasSubstr("Operand 127[%_ptr_Generic_float] cannot be a type"));
7670 }
7671
7672 TEST_F(ValidateExtInst, VStoreNWrongStorageClass) {
7673 std::ostringstream ss;
7674 ss << "%ptr_w = OpAccessChain %f32_ptr_uniform_constant "
7675 "%f32vec8_uniform_constant %u32_1\n";
7676 ss << "%val1 = OpExtInst %void %extinst vstoren %f32vec2_01 %u32_1 %ptr_w\n";
7677
7678 CompileSuccessfully(GenerateKernelCode(ss.str()));
7679 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7680 EXPECT_THAT(
7681 getDiagnosticString(),
7682 HasSubstr("OpenCL.std vstoren: expected operand P storage class "
7683 "to be Generic, CrossWorkgroup, Workgroup or Function"));
7684 }
7685
7686 TEST_F(ValidateExtInst, VStorePWrongDataType) {
7687 std::ostringstream ss;
7688 ss << "%ptr_w = OpAccessChain %f32_ptr_workgroup %f32vec8_workgroup %u32_1\n";
7689 ss << "%ptr_g = OpPtrCastToGeneric %f32_ptr_generic %ptr_w\n";
7690 ss << "%val1 = OpExtInst %void %extinst vstoren %u32vec2_01 %u32_1 %ptr_g\n";
7691
7692 CompileSuccessfully(GenerateKernelCode(ss.str()));
7693 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7694 EXPECT_THAT(getDiagnosticString(),
7695 HasSubstr("OpenCL.std vstoren: expected operand P data type to "
7696 "be equal to the type of operand Data components"));
7697 }
7698
7699 TEST_F(ValidateExtInst, OpenCLStdShuffleSuccess) {
7700 const std::string body = R"(
7701 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %u32vec2_01
7702 %val2 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec4_0123
7703 %val3 = OpExtInst %u32vec2 %extinst shuffle %u32vec4_0123 %u32vec2_01
7704 %val4 = OpExtInst %u32vec4 %extinst shuffle %u32vec4_0123 %u32vec4_0123
7705 )";
7706
7707 CompileSuccessfully(GenerateKernelCode(body));
7708 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7709 }
7710
7711 TEST_F(ValidateExtInst, OpenCLStdShuffleWrongResultType) {
7712 const std::string body = R"(
7713 %val1 = OpExtInst %f32 %extinst shuffle %f32vec4_0123 %u32vec2_01
7714 )";
7715
7716 CompileSuccessfully(GenerateKernelCode(body));
7717 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7718 EXPECT_THAT(
7719 getDiagnosticString(),
7720 HasSubstr("OpenCL.std shuffle: "
7721 "expected Result Type to be an int or float vector type"));
7722 }
7723
7724 TEST_F(ValidateExtInst, OpenCLStdShuffleResultTypeInvalidNumComponents) {
7725 const std::string body = R"(
7726 %val1 = OpExtInst %f32vec3 %extinst shuffle %f32vec4_0123 %u32vec3_012
7727 )";
7728
7729 CompileSuccessfully(GenerateKernelCode(body));
7730 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7731 EXPECT_THAT(
7732 getDiagnosticString(),
7733 HasSubstr("OpenCL.std shuffle: "
7734 "expected Result Type to have 2, 4, 8 or 16 components"));
7735 }
7736
7737 TEST_F(ValidateExtInst, OpenCLStdShuffleXWrongType) {
7738 const std::string body = R"(
7739 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32_0 %u32vec2_01
7740 )";
7741
7742 CompileSuccessfully(GenerateKernelCode(body));
7743 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7744 EXPECT_THAT(getDiagnosticString(),
7745 HasSubstr("OpenCL.std shuffle: "
7746 "expected operand X to be an int or float vector"));
7747 }
7748
7749 TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidNumComponents) {
7750 const std::string body = R"(
7751 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec3_012 %u32vec2_01
7752 )";
7753
7754 CompileSuccessfully(GenerateKernelCode(body));
7755 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7756 EXPECT_THAT(getDiagnosticString(),
7757 HasSubstr("OpenCL.std shuffle: "
7758 "expected operand X to have 2, 4, 8 or 16 components"));
7759 }
7760
7761 TEST_F(ValidateExtInst, OpenCLStdShuffleXInvalidComponentType) {
7762 const std::string body = R"(
7763 %val1 = OpExtInst %f32vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
7764 )";
7765
7766 CompileSuccessfully(GenerateKernelCode(body));
7767 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7768 EXPECT_THAT(
7769 getDiagnosticString(),
7770 HasSubstr(
7771 "OpenCL.std shuffle: "
7772 "expected operand X and Result Type to have equal component types"));
7773 }
7774
7775 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskNotIntVector) {
7776 const std::string body = R"(
7777 %val1 = OpExtInst %f32vec2 %extinst shuffle %f32vec4_0123 %f32vec2_01
7778 )";
7779
7780 CompileSuccessfully(GenerateKernelCode(body));
7781 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7782 EXPECT_THAT(getDiagnosticString(),
7783 HasSubstr("OpenCL.std shuffle: "
7784 "expected operand Shuffle Mask to be an int vector"));
7785 }
7786
7787 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidNumComponents) {
7788 const std::string body = R"(
7789 %val1 = OpExtInst %f32vec4 %extinst shuffle %f32vec4_0123 %u32vec2_01
7790 )";
7791
7792 CompileSuccessfully(GenerateKernelCode(body));
7793 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7794 EXPECT_THAT(getDiagnosticString(),
7795 HasSubstr("OpenCL.std shuffle: "
7796 "expected operand Shuffle Mask to have the same number "
7797 "of components as Result Type"));
7798 }
7799
7800 TEST_F(ValidateExtInst, OpenCLStdShuffleShuffleMaskInvalidBitWidth) {
7801 const std::string body = R"(
7802 %val1 = OpExtInst %f64vec2 %extinst shuffle %f64vec4_0123 %u32vec2_01
7803 )";
7804
7805 CompileSuccessfully(GenerateKernelCode(body));
7806 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7807 EXPECT_THAT(getDiagnosticString(),
7808 HasSubstr("OpenCL.std shuffle: "
7809 "expected operand Shuffle Mask components to have the "
7810 "same bit width as Result Type components"));
7811 }
7812
7813 TEST_F(ValidateExtInst, OpenCLStdShuffle2Success) {
7814 const std::string body = R"(
7815 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
7816 %val2 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec4_0123
7817 %val3 = OpExtInst %u32vec2 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec2_01
7818 %val4 = OpExtInst %u32vec4 %extinst shuffle2 %u32vec4_0123 %u32vec4_0123 %u32vec4_0123
7819 )";
7820
7821 CompileSuccessfully(GenerateKernelCode(body));
7822 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7823 }
7824
7825 TEST_F(ValidateExtInst, OpenCLStdShuffle2WrongResultType) {
7826 const std::string body = R"(
7827 %val1 = OpExtInst %f32 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
7828 )";
7829
7830 CompileSuccessfully(GenerateKernelCode(body));
7831 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7832 EXPECT_THAT(
7833 getDiagnosticString(),
7834 HasSubstr("OpenCL.std shuffle2: "
7835 "expected Result Type to be an int or float vector type"));
7836 }
7837
7838 TEST_F(ValidateExtInst, OpenCLStdShuffle2ResultTypeInvalidNumComponents) {
7839 const std::string body = R"(
7840 %val1 = OpExtInst %f32vec3 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec3_012
7841 )";
7842
7843 CompileSuccessfully(GenerateKernelCode(body));
7844 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7845 EXPECT_THAT(
7846 getDiagnosticString(),
7847 HasSubstr("OpenCL.std shuffle2: "
7848 "expected Result Type to have 2, 4, 8 or 16 components"));
7849 }
7850
7851 TEST_F(ValidateExtInst, OpenCLStdShuffle2XWrongType) {
7852 const std::string body = R"(
7853 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32_0 %f32_0 %u32vec2_01
7854 )";
7855
7856 CompileSuccessfully(GenerateKernelCode(body));
7857 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7858 EXPECT_THAT(getDiagnosticString(),
7859 HasSubstr("OpenCL.std shuffle2: "
7860 "expected operand X to be an int or float vector"));
7861 }
7862
7863 TEST_F(ValidateExtInst, OpenCLStdShuffle2YTypeDifferentFromX) {
7864 const std::string body = R"(
7865 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec2_01 %f32vec4_0123 %u32vec2_01
7866 )";
7867
7868 CompileSuccessfully(GenerateKernelCode(body));
7869 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7870 EXPECT_THAT(getDiagnosticString(),
7871 HasSubstr("OpenCL.std shuffle2: "
7872 "expected operands X and Y to be of the same type"));
7873 }
7874
7875 TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidNumComponents) {
7876 const std::string body = R"(
7877 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec3_012 %f32vec3_012 %u32vec2_01
7878 )";
7879
7880 CompileSuccessfully(GenerateKernelCode(body));
7881 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7882 EXPECT_THAT(getDiagnosticString(),
7883 HasSubstr("OpenCL.std shuffle2: "
7884 "expected operand X to have 2, 4, 8 or 16 components"));
7885 }
7886
7887 TEST_F(ValidateExtInst, OpenCLStdShuffle2XInvalidComponentType) {
7888 const std::string body = R"(
7889 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
7890 )";
7891
7892 CompileSuccessfully(GenerateKernelCode(body));
7893 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7894 EXPECT_THAT(
7895 getDiagnosticString(),
7896 HasSubstr(
7897 "OpenCL.std shuffle2: "
7898 "expected operand X and Result Type to have equal component types"));
7899 }
7900
7901 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskNotIntVector) {
7902 const std::string body = R"(
7903 %val1 = OpExtInst %f32vec2 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %f32vec2_01
7904 )";
7905
7906 CompileSuccessfully(GenerateKernelCode(body));
7907 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7908 EXPECT_THAT(getDiagnosticString(),
7909 HasSubstr("OpenCL.std shuffle2: "
7910 "expected operand Shuffle Mask to be an int vector"));
7911 }
7912
7913 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidNumComponents) {
7914 const std::string body = R"(
7915 %val1 = OpExtInst %f32vec4 %extinst shuffle2 %f32vec4_0123 %f32vec4_0123 %u32vec2_01
7916 )";
7917
7918 CompileSuccessfully(GenerateKernelCode(body));
7919 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7920 EXPECT_THAT(getDiagnosticString(),
7921 HasSubstr("OpenCL.std shuffle2: "
7922 "expected operand Shuffle Mask to have the same number "
7923 "of components as Result Type"));
7924 }
7925
7926 TEST_F(ValidateExtInst, OpenCLStdShuffle2ShuffleMaskInvalidBitWidth) {
7927 const std::string body = R"(
7928 %val1 = OpExtInst %f64vec2 %extinst shuffle2 %f64vec4_0123 %f64vec4_0123 %u32vec2_01
7929 )";
7930
7931 CompileSuccessfully(GenerateKernelCode(body));
7932 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7933 EXPECT_THAT(getDiagnosticString(),
7934 HasSubstr("OpenCL.std shuffle2: "
7935 "expected operand Shuffle Mask components to have the "
7936 "same bit width as Result Type components"));
7937 }
7938
7939 TEST_F(ValidateExtInst, OpenCLStdPrintfSuccess) {
7940 const std::string body = R"(
7941 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7942 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
7943 )";
7944
7945 CompileSuccessfully(GenerateKernelCode(body));
7946 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
7947 }
7948
7949 TEST_F(ValidateExtInst, OpenCLStdPrintfBoolResultType) {
7950 const std::string body = R"(
7951 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7952 %val1 = OpExtInst %bool %extinst printf %format %u32_0 %u32_1
7953 )";
7954
7955 CompileSuccessfully(GenerateKernelCode(body));
7956 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7957 EXPECT_THAT(
7958 getDiagnosticString(),
7959 HasSubstr(
7960 "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
7961 }
7962
7963 TEST_F(ValidateExtInst, OpenCLStdPrintfU64ResultType) {
7964 const std::string body = R"(
7965 %format = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7966 %val1 = OpExtInst %u64 %extinst printf %format %u32_0 %u32_1
7967 )";
7968
7969 CompileSuccessfully(GenerateKernelCode(body));
7970 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7971 EXPECT_THAT(
7972 getDiagnosticString(),
7973 HasSubstr(
7974 "OpenCL.std printf: expected Result Type to be a 32-bit int type"));
7975 }
7976
7977 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotPointer) {
7978 const std::string body = R"(
7979 %val1 = OpExtInst %u32 %extinst printf %u8_ptr_uniform_constant %u32_0 %u32_1
7980 )";
7981
7982 CompileSuccessfully(GenerateKernelCode(body));
7983 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
7984 EXPECT_THAT(getDiagnosticString(),
7985 HasSubstr("Operand 137[%_ptr_UniformConstant_uchar] cannot be a "
7986 "type"));
7987 }
7988
7989 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotUniformConstStorageClass) {
7990 const std::string body = R"(
7991 %format_const = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
7992 %format = OpBitcast %u8_ptr_generic %format_const
7993 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
7994 )";
7995
7996 CompileSuccessfully(GenerateKernelCode(body));
7997 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
7998 EXPECT_THAT(getDiagnosticString(),
7999 HasSubstr("OpenCL.std printf: expected Format storage class to "
8000 "be UniformConstant"));
8001 }
8002
8003 TEST_F(ValidateExtInst, OpenCLStdPrintfFormatNotU8Pointer) {
8004 const std::string body = R"(
8005 %format = OpAccessChain %u32_ptr_uniform_constant %u32vec8_uniform_constant %u32_0
8006 %val1 = OpExtInst %u32 %extinst printf %format %u32_0 %u32_1
8007 )";
8008
8009 CompileSuccessfully(GenerateKernelCode(body));
8010 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8011 EXPECT_THAT(
8012 getDiagnosticString(),
8013 HasSubstr(
8014 "OpenCL.std printf: expected Format data type to be 8-bit int"));
8015 }
8016
8017 TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Success) {
8018 const std::string body = R"(
8019 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
8020 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8021 )";
8022
8023 CompileSuccessfully(GenerateKernelCode(body));
8024 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8025 }
8026
8027 TEST_F(ValidateExtInst, OpenCLStdPrefetchU32Physical64Success) {
8028 const std::string body = R"(
8029 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
8030 %val1 = OpExtInst %void %extinst prefetch %ptr %u64_256
8031 )";
8032
8033 CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
8034 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8035 }
8036
8037 TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Success) {
8038 const std::string body = R"(
8039 %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
8040 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8041 )";
8042
8043 CompileSuccessfully(GenerateKernelCode(body));
8044 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8045 }
8046
8047 TEST_F(ValidateExtInst, OpenCLStdPrefetchF32Vec2Success) {
8048 const std::string body = R"(
8049 %ptr = OpAccessChain %f32vec2_ptr_cross_workgroup %f32vec2arr_cross_workgroup %u32_0
8050 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8051 )";
8052
8053 CompileSuccessfully(GenerateKernelCode(body));
8054 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8055 }
8056
8057 TEST_F(ValidateExtInst, OpenCLStdPrefetchResultTypeNotVoid) {
8058 const std::string body = R"(
8059 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
8060 %val1 = OpExtInst %u32 %extinst prefetch %ptr %u32_256
8061 )";
8062
8063 CompileSuccessfully(GenerateKernelCode(body));
8064 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8065 EXPECT_THAT(
8066 getDiagnosticString(),
8067 HasSubstr("OpenCL.std prefetch: expected Result Type to be void"));
8068 }
8069
8070 TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotPointer) {
8071 const std::string body = R"(
8072 %val1 = OpExtInst %void %extinst prefetch %u32_ptr_cross_workgroup %u32_256
8073 )";
8074
8075 CompileSuccessfully(GenerateKernelCode(body));
8076 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8077 EXPECT_THAT(getDiagnosticString(),
8078 HasSubstr("Operand 99[%_ptr_CrossWorkgroup_uint] cannot be a "
8079 "type"));
8080 }
8081
8082 TEST_F(ValidateExtInst, OpenCLStdPrefetchPtrNotCrossWorkgroup) {
8083 const std::string body = R"(
8084 %ptr = OpAccessChain %u8_ptr_uniform_constant %u8arr_uniform_constant %u32_0
8085 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8086 )";
8087
8088 CompileSuccessfully(GenerateKernelCode(body));
8089 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8090 EXPECT_THAT(getDiagnosticString(),
8091 HasSubstr("OpenCL.std prefetch: expected operand Ptr storage "
8092 "class to be CrossWorkgroup"));
8093 }
8094
8095 TEST_F(ValidateExtInst, OpenCLStdPrefetchInvalidDataType) {
8096 const std::string body = R"(
8097 %ptr = OpAccessChain %struct_ptr_cross_workgroup %struct_arr_cross_workgroup %u32_0
8098 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8099 )";
8100
8101 CompileSuccessfully(GenerateKernelCode(body));
8102 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8103 EXPECT_THAT(getDiagnosticString(),
8104 HasSubstr("OpenCL.std prefetch: expected Ptr data type to be int "
8105 "or float scalar or vector"));
8106 }
8107
8108 TEST_F(ValidateExtInst, OpenCLStdPrefetchAddressingModelLogical) {
8109 const std::string body = R"(
8110 %ptr = OpAccessChain %u32_ptr_cross_workgroup %u32arr_cross_workgroup %u32_0
8111 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8112 )";
8113
8114 CompileSuccessfully(GenerateKernelCode(body, "", "Logical"));
8115 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8116 EXPECT_THAT(getDiagnosticString(),
8117 HasSubstr("OpenCL.std prefetch can only be used with physical "
8118 "addressing models"));
8119 }
8120
8121 TEST_F(ValidateExtInst, OpenCLStdPrefetchNumElementsNotSizeT) {
8122 const std::string body = R"(
8123 %ptr = OpAccessChain %f32_ptr_cross_workgroup %f32arr_cross_workgroup %u32_0
8124 %val1 = OpExtInst %void %extinst prefetch %ptr %u32_256
8125 )";
8126
8127 CompileSuccessfully(GenerateKernelCode(body, "", "Physical64"));
8128 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8129 EXPECT_THAT(getDiagnosticString(),
8130 HasSubstr("OpenCL.std prefetch: expected operand Num Elements to "
8131 "be of type size_t (64-bit integer for the addressing "
8132 "model used in the module)"));
8133 }
8134
8135 TEST_P(ValidateOpenCLStdFractLike, Success) {
8136 const std::string ext_inst_name = GetParam();
8137 std::ostringstream ss;
8138 ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8139 ss << "%var_f32vec2 = OpVariable %f32vec2_ptr_function Function\n";
8140 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8141 << " %f32_0 %var_f32\n";
8142 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
8143 << " %f32vec2_01 %var_f32vec2\n";
8144
8145 CompileSuccessfully(GenerateKernelCode(ss.str()));
8146 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8147 }
8148
8149 TEST_P(ValidateOpenCLStdFractLike, IntResultType) {
8150 const std::string ext_inst_name = GetParam();
8151 std::ostringstream ss;
8152 ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8153 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
8154 << " %f32_0 %var_f32\n";
8155
8156 CompileSuccessfully(GenerateKernelCode(ss.str()));
8157 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8158 EXPECT_THAT(
8159 getDiagnosticString(),
8160 HasSubstr("OpenCL.std " + ext_inst_name +
8161 ": expected Result Type to be a float scalar or vector type"));
8162 }
8163
8164 TEST_P(ValidateOpenCLStdFractLike, XWrongType) {
8165 const std::string ext_inst_name = GetParam();
8166 std::ostringstream ss;
8167 ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8168 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8169 << " %f64_0 %var_f32\n";
8170
8171 CompileSuccessfully(GenerateKernelCode(ss.str()));
8172 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8173 EXPECT_THAT(
8174 getDiagnosticString(),
8175 HasSubstr("OpenCL.std " + ext_inst_name +
8176 ": expected type of operand X to be equal to Result Type"));
8177 }
8178
8179 TEST_P(ValidateOpenCLStdFractLike, NotPointer) {
8180 const std::string ext_inst_name = GetParam();
8181 std::ostringstream ss;
8182 ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8183 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8184 << " %f32_0 %f32_1\n";
8185
8186 CompileSuccessfully(GenerateKernelCode(ss.str()));
8187 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8188 EXPECT_THAT(getDiagnosticString(),
8189 HasSubstr("OpenCL.std " + ext_inst_name +
8190 ": expected the last operand to be a pointer"));
8191 }
8192
8193 TEST_P(ValidateOpenCLStdFractLike, PointerInvalidStorageClass) {
8194 const std::string ext_inst_name = GetParam();
8195 std::ostringstream ss;
8196 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
8197 "%f32vec8_uniform_constant %u32_1\n";
8198 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
8199
8200 CompileSuccessfully(GenerateKernelCode(ss.str()));
8201 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8202 EXPECT_THAT(getDiagnosticString(),
8203 HasSubstr("OpenCL.std " + ext_inst_name +
8204 ": expected storage class of the pointer to be "
8205 "Generic, CrossWorkgroup, Workgroup or Function"));
8206 }
8207
8208 TEST_P(ValidateOpenCLStdFractLike, PointerWrongDataType) {
8209 const std::string ext_inst_name = GetParam();
8210 std::ostringstream ss;
8211 ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8212 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8213 << " %f32_0 %var_u32\n";
8214
8215 CompileSuccessfully(GenerateKernelCode(ss.str()));
8216 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8217 EXPECT_THAT(
8218 getDiagnosticString(),
8219 HasSubstr(
8220 "OpenCL.std " + ext_inst_name +
8221 ": expected data type of the pointer to be equal to Result Type"));
8222 }
8223
8224 INSTANTIATE_TEST_SUITE_P(AllFractLike, ValidateOpenCLStdFractLike,
8225 ::testing::ValuesIn(std::vector<std::string>{
8226 "fract",
8227 "modf",
8228 "sincos",
8229 }));
8230
8231 TEST_F(ValidateExtInst, OpenCLStdRemquoSuccess) {
8232 const std::string body = R"(
8233 %var_u32 = OpVariable %u32_ptr_function Function
8234 %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
8235 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32
8236 %val2 = OpExtInst %f32vec2 %extinst remquo %f32vec2_01 %f32vec2_12 %var_u32vec2
8237 )";
8238
8239 CompileSuccessfully(GenerateKernelCode(body));
8240 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8241 }
8242
8243 TEST_F(ValidateExtInst, OpenCLStdRemquoIntResultType) {
8244 const std::string body = R"(
8245 %var_u32 = OpVariable %u32_ptr_function Function
8246 %val1 = OpExtInst %u32 %extinst remquo %f32_3 %f32_2 %var_u32
8247 )";
8248
8249 CompileSuccessfully(GenerateKernelCode(body));
8250 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8251 EXPECT_THAT(
8252 getDiagnosticString(),
8253 HasSubstr("OpenCL.std remquo: "
8254 "expected Result Type to be a float scalar or vector type"));
8255 }
8256
8257 TEST_F(ValidateExtInst, OpenCLStdRemquoXWrongType) {
8258 const std::string body = R"(
8259 %var_u32 = OpVariable %f32_ptr_function Function
8260 %val1 = OpExtInst %f32 %extinst remquo %u32_3 %f32_2 %var_u32
8261 )";
8262
8263 CompileSuccessfully(GenerateKernelCode(body));
8264 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8265 EXPECT_THAT(
8266 getDiagnosticString(),
8267 HasSubstr("OpenCL.std remquo: "
8268 "expected type of operand X to be equal to Result Type"));
8269 }
8270
8271 TEST_F(ValidateExtInst, OpenCLStdRemquoYWrongType) {
8272 const std::string body = R"(
8273 %var_u32 = OpVariable %f32_ptr_function Function
8274 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %u32_2 %var_u32
8275 )";
8276
8277 CompileSuccessfully(GenerateKernelCode(body));
8278 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8279 EXPECT_THAT(
8280 getDiagnosticString(),
8281 HasSubstr("OpenCL.std remquo: "
8282 "expected type of operand Y to be equal to Result Type"));
8283 }
8284
8285 TEST_F(ValidateExtInst, OpenCLStdRemquoNotPointer) {
8286 const std::string body = R"(
8287 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %f32_1
8288 )";
8289
8290 CompileSuccessfully(GenerateKernelCode(body));
8291 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8292 EXPECT_THAT(getDiagnosticString(),
8293 HasSubstr("OpenCL.std remquo: "
8294 "expected the last operand to be a pointer"));
8295 }
8296
8297 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongStorageClass) {
8298 const std::string body = R"(
8299 %ptr = OpAccessChain %f32_ptr_uniform_constant %f32vec8_uniform_constant %u32_1
8300 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %ptr
8301 )";
8302
8303 CompileSuccessfully(GenerateKernelCode(body));
8304 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8305 EXPECT_THAT(getDiagnosticString(),
8306 HasSubstr("OpenCL.std remquo: "
8307 "expected storage class of the pointer to be Generic, "
8308 "CrossWorkgroup, Workgroup or Function"));
8309 }
8310
8311 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataType) {
8312 const std::string body = R"(
8313 %var_f32 = OpVariable %f32_ptr_function Function
8314 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_f32
8315 )";
8316
8317 CompileSuccessfully(GenerateKernelCode(body));
8318 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8319 EXPECT_THAT(getDiagnosticString(),
8320 HasSubstr("OpenCL.std remquo: "
8321 "expected data type of the pointer to be a 32-bit int "
8322 "scalar or vector type"));
8323 }
8324
8325 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongDataTypeWidth) {
8326 const std::string body = R"(
8327 %var_u64 = OpVariable %u64_ptr_function Function
8328 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u64
8329 )";
8330 CompileSuccessfully(GenerateKernelCode(body));
8331 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8332 EXPECT_THAT(getDiagnosticString(),
8333 HasSubstr("OpenCL.std remquo: "
8334 "expected data type of the pointer to be a 32-bit int "
8335 "scalar or vector type"));
8336 }
8337
8338 TEST_F(ValidateExtInst, OpenCLStdRemquoPointerWrongNumberOfComponents) {
8339 const std::string body = R"(
8340 %var_u32vec2 = OpVariable %u32vec2_ptr_function Function
8341 %val1 = OpExtInst %f32 %extinst remquo %f32_3 %f32_2 %var_u32vec2
8342 )";
8343
8344 CompileSuccessfully(GenerateKernelCode(body));
8345 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8346 EXPECT_THAT(
8347 getDiagnosticString(),
8348 HasSubstr("OpenCL.std remquo: "
8349 "expected data type of the pointer to have the same number "
8350 "of components as Result Type"));
8351 }
8352
8353 TEST_P(ValidateOpenCLStdFrexpLike, Success) {
8354 const std::string ext_inst_name = GetParam();
8355 std::ostringstream ss;
8356 ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8357 ss << "%var_u32vec2 = OpVariable %u32vec2_ptr_function Function\n";
8358 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8359 << " %f32_0 %var_u32\n";
8360 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
8361 << " %f32vec2_01 %var_u32vec2\n";
8362
8363 CompileSuccessfully(GenerateKernelCode(ss.str()));
8364 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8365 }
8366
8367 TEST_P(ValidateOpenCLStdFrexpLike, IntResultType) {
8368 const std::string ext_inst_name = GetParam();
8369 std::ostringstream ss;
8370 ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8371 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
8372 << " %f32_0 %var_u32\n";
8373
8374 CompileSuccessfully(GenerateKernelCode(ss.str()));
8375 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8376 EXPECT_THAT(
8377 getDiagnosticString(),
8378 HasSubstr("OpenCL.std " + ext_inst_name +
8379 ": expected Result Type to be a float scalar or vector type"));
8380 }
8381
8382 TEST_P(ValidateOpenCLStdFrexpLike, XWrongType) {
8383 const std::string ext_inst_name = GetParam();
8384 std::ostringstream ss;
8385 ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8386 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8387 << " %f64_0 %var_u32\n";
8388
8389 CompileSuccessfully(GenerateKernelCode(ss.str()));
8390 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8391 EXPECT_THAT(
8392 getDiagnosticString(),
8393 HasSubstr("OpenCL.std " + ext_inst_name +
8394 ": expected type of operand X to be equal to Result Type"));
8395 }
8396
8397 TEST_P(ValidateOpenCLStdFrexpLike, NotPointer) {
8398 const std::string ext_inst_name = GetParam();
8399 std::ostringstream ss;
8400 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8401 << " %f32_0 %u32_1\n";
8402
8403 CompileSuccessfully(GenerateKernelCode(ss.str()));
8404 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8405 EXPECT_THAT(getDiagnosticString(),
8406 HasSubstr("OpenCL.std " + ext_inst_name +
8407 ": expected the last operand to be a pointer"));
8408 }
8409
8410 TEST_P(ValidateOpenCLStdFrexpLike, PointerInvalidStorageClass) {
8411 const std::string ext_inst_name = GetParam();
8412 std::ostringstream ss;
8413 ss << "%ptr = OpAccessChain %f32_ptr_uniform_constant "
8414 "%f32vec8_uniform_constant %u32_1\n";
8415 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name << " %f32_0 %ptr\n";
8416
8417 CompileSuccessfully(GenerateKernelCode(ss.str()));
8418 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8419 EXPECT_THAT(getDiagnosticString(),
8420 HasSubstr("OpenCL.std " + ext_inst_name +
8421 ": expected storage class of the pointer to be "
8422 "Generic, CrossWorkgroup, Workgroup or Function"));
8423 }
8424
8425 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeFloat) {
8426 const std::string ext_inst_name = GetParam();
8427 std::ostringstream ss;
8428 ss << "%var_f32 = OpVariable %f32_ptr_function Function\n";
8429 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8430 << " %f32_0 %var_f32\n";
8431
8432 CompileSuccessfully(GenerateKernelCode(ss.str()));
8433 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8434 EXPECT_THAT(getDiagnosticString(),
8435 HasSubstr("OpenCL.std " + ext_inst_name +
8436 ": expected data type of the pointer to be a 32-bit "
8437 "int scalar or vector type"));
8438 }
8439
8440 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeU64) {
8441 const std::string ext_inst_name = GetParam();
8442 std::ostringstream ss;
8443 ss << "%var_u64 = OpVariable %u64_ptr_function Function\n";
8444 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8445 << " %f32_0 %var_u64\n";
8446
8447 CompileSuccessfully(GenerateKernelCode(ss.str()));
8448 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8449 EXPECT_THAT(getDiagnosticString(),
8450 HasSubstr("OpenCL.std " + ext_inst_name +
8451 ": expected data type of the pointer to be a 32-bit "
8452 "int scalar or vector type"));
8453 }
8454
8455 TEST_P(ValidateOpenCLStdFrexpLike, PointerDataTypeDiffSize) {
8456 const std::string ext_inst_name = GetParam();
8457 std::ostringstream ss;
8458 ss << "%var_u32 = OpVariable %u32_ptr_function Function\n";
8459 ss << "%val1 = OpExtInst %f32vec2 %extinst " << ext_inst_name
8460 << " %f32vec2_01 %var_u32\n";
8461
8462 CompileSuccessfully(GenerateKernelCode(ss.str()));
8463 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8464 EXPECT_THAT(getDiagnosticString(),
8465 HasSubstr("OpenCL.std " + ext_inst_name +
8466 ": expected data type of the pointer to have the same "
8467 "number of components as Result Type"));
8468 }
8469
8470 INSTANTIATE_TEST_SUITE_P(AllFrexpLike, ValidateOpenCLStdFrexpLike,
8471 ::testing::ValuesIn(std::vector<std::string>{
8472 "frexp",
8473 "lgamma_r",
8474 }));
8475
8476 TEST_F(ValidateExtInst, OpenCLStdIlogbSuccess) {
8477 const std::string body = R"(
8478 %val1 = OpExtInst %u32 %extinst ilogb %f32_3
8479 %val2 = OpExtInst %u32vec2 %extinst ilogb %f32vec2_12
8480 )";
8481
8482 CompileSuccessfully(GenerateKernelCode(body));
8483 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8484 }
8485
8486 TEST_F(ValidateExtInst, OpenCLStdIlogbFloatResultType) {
8487 const std::string body = R"(
8488 %val1 = OpExtInst %f32 %extinst ilogb %f32_3
8489 )";
8490
8491 CompileSuccessfully(GenerateKernelCode(body));
8492 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8493 EXPECT_THAT(
8494 getDiagnosticString(),
8495 HasSubstr(
8496 "OpenCL.std ilogb: "
8497 "expected Result Type to be a 32-bit int scalar or vector type"));
8498 }
8499
8500 TEST_F(ValidateExtInst, OpenCLStdIlogbIntX) {
8501 const std::string body = R"(
8502 %val1 = OpExtInst %u32 %extinst ilogb %u32_3
8503 )";
8504
8505 CompileSuccessfully(GenerateKernelCode(body));
8506 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8507 EXPECT_THAT(getDiagnosticString(),
8508 HasSubstr("OpenCL.std ilogb: "
8509 "expected operand X to be a float scalar or vector"));
8510 }
8511
8512 TEST_F(ValidateExtInst, OpenCLStdIlogbDiffSize) {
8513 const std::string body = R"(
8514 %val2 = OpExtInst %u32vec2 %extinst ilogb %f32_1
8515 )";
8516
8517 CompileSuccessfully(GenerateKernelCode(body));
8518 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8519 EXPECT_THAT(getDiagnosticString(),
8520 HasSubstr("OpenCL.std ilogb: "
8521 "expected operand X to have the same number of "
8522 "components as Result Type"));
8523 }
8524
8525 TEST_F(ValidateExtInst, OpenCLStdNanSuccess) {
8526 const std::string body = R"(
8527 %val1 = OpExtInst %f32 %extinst nan %u32_3
8528 %val2 = OpExtInst %f32vec2 %extinst nan %u32vec2_12
8529 )";
8530
8531 CompileSuccessfully(GenerateKernelCode(body));
8532 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8533 }
8534
8535 TEST_F(ValidateExtInst, OpenCLStdNanIntResultType) {
8536 const std::string body = R"(
8537 %val1 = OpExtInst %u32 %extinst nan %u32_3
8538 )";
8539
8540 CompileSuccessfully(GenerateKernelCode(body));
8541 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8542 EXPECT_THAT(
8543 getDiagnosticString(),
8544 HasSubstr("OpenCL.std nan: "
8545 "expected Result Type to be a float scalar or vector type"));
8546 }
8547
8548 TEST_F(ValidateExtInst, OpenCLStdNanFloatNancode) {
8549 const std::string body = R"(
8550 %val1 = OpExtInst %f32 %extinst nan %f32_3
8551 )";
8552
8553 CompileSuccessfully(GenerateKernelCode(body));
8554 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8555 EXPECT_THAT(getDiagnosticString(),
8556 HasSubstr("OpenCL.std nan: "
8557 "expected Nancode to be an int scalar or vector type"));
8558 }
8559
8560 TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffSize) {
8561 const std::string body = R"(
8562 %val1 = OpExtInst %f32 %extinst nan %u32vec2_12
8563 )";
8564
8565 CompileSuccessfully(GenerateKernelCode(body));
8566 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8567 EXPECT_THAT(getDiagnosticString(),
8568 HasSubstr("OpenCL.std nan: "
8569 "expected Nancode to have the same number of "
8570 "components as Result Type"));
8571 }
8572
8573 TEST_F(ValidateExtInst, OpenCLStdNanFloatDiffBitWidth) {
8574 const std::string body = R"(
8575 %val1 = OpExtInst %f64 %extinst nan %u32_2
8576 )";
8577
8578 CompileSuccessfully(GenerateKernelCode(body));
8579 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8580 EXPECT_THAT(
8581 getDiagnosticString(),
8582 HasSubstr("OpenCL.std nan: "
8583 "expected Nancode to have the same bit width as Result Type"));
8584 }
8585
8586 TEST_P(ValidateOpenCLStdLdexpLike, Success) {
8587 const std::string ext_inst_name = GetParam();
8588 std::ostringstream ss;
8589 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8590 << " %f32_0 %u32_1\n";
8591 ss << "%val2 = OpExtInst %f32vec2 %extinst " << ext_inst_name
8592 << " %f32vec2_12 %u32vec2_12\n";
8593
8594 CompileSuccessfully(GenerateKernelCode(ss.str()));
8595 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8596 }
8597
8598 TEST_P(ValidateOpenCLStdLdexpLike, IntResultType) {
8599 const std::string ext_inst_name = GetParam();
8600 std::ostringstream ss;
8601 ss << "%val1 = OpExtInst %u32 %extinst " << ext_inst_name
8602 << " %f32_0 %u32_1\n";
8603
8604 CompileSuccessfully(GenerateKernelCode(ss.str()));
8605 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8606 EXPECT_THAT(
8607 getDiagnosticString(),
8608 HasSubstr("OpenCL.std " + ext_inst_name +
8609 ": expected Result Type to be a float scalar or vector type"));
8610 }
8611
8612 TEST_P(ValidateOpenCLStdLdexpLike, XWrongType) {
8613 const std::string ext_inst_name = GetParam();
8614 std::ostringstream ss;
8615 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8616 << " %u32_0 %u32_1\n";
8617
8618 CompileSuccessfully(GenerateKernelCode(ss.str()));
8619 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8620 EXPECT_THAT(
8621 getDiagnosticString(),
8622 HasSubstr("OpenCL.std " + ext_inst_name +
8623 ": expected type of operand X to be equal to Result Type"));
8624 }
8625
8626 TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt) {
8627 const std::string ext_inst_name = GetParam();
8628 std::ostringstream ss;
8629 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8630 << " %f32_0 %f32_1\n";
8631
8632 CompileSuccessfully(GenerateKernelCode(ss.str()));
8633 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8634 EXPECT_THAT(
8635 getDiagnosticString(),
8636 HasSubstr("OpenCL.std " + ext_inst_name +
8637 ": expected the exponent to be a 32-bit int scalar or vector"));
8638 }
8639
8640 TEST_P(ValidateOpenCLStdLdexpLike, ExponentNotInt32) {
8641 const std::string ext_inst_name = GetParam();
8642 std::ostringstream ss;
8643 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8644 << " %f32_0 %u64_1\n";
8645
8646 CompileSuccessfully(GenerateKernelCode(ss.str()));
8647 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8648 EXPECT_THAT(
8649 getDiagnosticString(),
8650 HasSubstr("OpenCL.std " + ext_inst_name +
8651 ": expected the exponent to be a 32-bit int scalar or vector"));
8652 }
8653
8654 TEST_P(ValidateOpenCLStdLdexpLike, ExponentWrongSize) {
8655 const std::string ext_inst_name = GetParam();
8656 std::ostringstream ss;
8657 ss << "%val1 = OpExtInst %f32 %extinst " << ext_inst_name
8658 << " %f32_0 %u32vec2_01\n";
8659
8660 CompileSuccessfully(GenerateKernelCode(ss.str()));
8661 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8662 EXPECT_THAT(getDiagnosticString(),
8663 HasSubstr("OpenCL.std " + ext_inst_name +
8664 ": expected the exponent to have the same number of "
8665 "components as Result Type"));
8666 }
8667
8668 INSTANTIATE_TEST_SUITE_P(AllLdexpLike, ValidateOpenCLStdLdexpLike,
8669 ::testing::ValuesIn(std::vector<std::string>{
8670 "ldexp",
8671 "pown",
8672 "rootn",
8673 }));
8674
8675 TEST_P(ValidateOpenCLStdUpsampleLike, Success) {
8676 const std::string ext_inst_name = GetParam();
8677 std::ostringstream ss;
8678 ss << "%val1 = OpExtInst %u16 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
8679 ss << "%val2 = OpExtInst %u32 %extinst " << ext_inst_name
8680 << " %u16_1 %u16_2\n";
8681 ss << "%val3 = OpExtInst %u64 %extinst " << ext_inst_name
8682 << " %u32_1 %u32_2\n";
8683 ss << "%val4 = OpExtInst %u64vec2 %extinst " << ext_inst_name
8684 << " %u32vec2_01 %u32vec2_01\n";
8685
8686 CompileSuccessfully(GenerateKernelCode(ss.str()));
8687 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8688 }
8689
8690 TEST_P(ValidateOpenCLStdUpsampleLike, FloatResultType) {
8691 const std::string ext_inst_name = GetParam();
8692 std::ostringstream ss;
8693 ss << "%val1 = OpExtInst %f64 %extinst " << ext_inst_name
8694 << " %u32_1 %u32_2\n";
8695
8696 CompileSuccessfully(GenerateKernelCode(ss.str()));
8697 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8698 EXPECT_THAT(
8699 getDiagnosticString(),
8700 HasSubstr("OpenCL.std " + ext_inst_name +
8701 ": expected Result Type to be an int scalar or vector type"));
8702 }
8703
8704 TEST_P(ValidateOpenCLStdUpsampleLike, InvalidResultTypeBitWidth) {
8705 const std::string ext_inst_name = GetParam();
8706 std::ostringstream ss;
8707 ss << "%val1 = OpExtInst %u8 %extinst " << ext_inst_name << " %u8_1 %u8_2\n";
8708
8709 CompileSuccessfully(GenerateKernelCode(ss.str()));
8710 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8711 EXPECT_THAT(
8712 getDiagnosticString(),
8713 HasSubstr(
8714 "OpenCL.std " + ext_inst_name +
8715 ": expected bit width of Result Type components to be 16, 32 or 64"));
8716 }
8717
8718 TEST_P(ValidateOpenCLStdUpsampleLike, LoHiDiffType) {
8719 const std::string ext_inst_name = GetParam();
8720 std::ostringstream ss;
8721 ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
8722 << " %u32_1 %u16_2\n";
8723
8724 CompileSuccessfully(GenerateKernelCode(ss.str()));
8725 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8726 EXPECT_THAT(getDiagnosticString(),
8727 HasSubstr("OpenCL.std " + ext_inst_name +
8728 ": expected Hi and Lo operands to have the same type"));
8729 }
8730
8731 TEST_P(ValidateOpenCLStdUpsampleLike, DiffNumberOfComponents) {
8732 const std::string ext_inst_name = GetParam();
8733 std::ostringstream ss;
8734 ss << "%val1 = OpExtInst %u64vec2 %extinst " << ext_inst_name
8735 << " %u32_1 %u32_2\n";
8736
8737 CompileSuccessfully(GenerateKernelCode(ss.str()));
8738 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8739 EXPECT_THAT(getDiagnosticString(),
8740 HasSubstr("OpenCL.std " + ext_inst_name +
8741 ": expected Hi and Lo operands to have the same number "
8742 "of components as Result Type"));
8743 }
8744
8745 TEST_P(ValidateOpenCLStdUpsampleLike, HiLoWrongBitWidth) {
8746 const std::string ext_inst_name = GetParam();
8747 std::ostringstream ss;
8748 ss << "%val1 = OpExtInst %u64 %extinst " << ext_inst_name
8749 << " %u16_1 %u16_2\n";
8750
8751 CompileSuccessfully(GenerateKernelCode(ss.str()));
8752 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8753 EXPECT_THAT(
8754 getDiagnosticString(),
8755 HasSubstr("OpenCL.std " + ext_inst_name +
8756 ": expected bit width of components of Hi and Lo operands to "
8757 "be half of the bit width of components of Result Type"));
8758 }
8759
8760 INSTANTIATE_TEST_SUITE_P(AllUpsampleLike, ValidateOpenCLStdUpsampleLike,
8761 ::testing::ValuesIn(std::vector<std::string>{
8762 "u_upsample",
8763 "s_upsample",
8764 }));
8765
8766 TEST_F(ValidateClspvReflection, RequiresNonSemanticExtension) {
8767 const std::string text = R"(
8768 OpCapability Shader
8769 OpCapability Linkage
8770 %1 = OpExtInstImport "NonSemantic.ClspvReflection.1"
8771 OpMemoryModel Logical GLSL450
8772 )";
8773
8774 CompileSuccessfully(text);
8775 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8776 EXPECT_THAT(getDiagnosticString(),
8777 HasSubstr("NonSemantic extended instruction sets cannot be "
8778 "declared without SPV_KHR_non_semantic_info"));
8779 }
8780
8781 TEST_F(ValidateClspvReflection, MissingVersion) {
8782 const std::string text = R"(
8783 OpCapability Shader
8784 OpCapability Linkage
8785 OpExtension "SPV_KHR_non_semantic_info"
8786 %1 = OpExtInstImport "NonSemantic.ClspvReflection."
8787 OpMemoryModel Logical GLSL450
8788 %2 = OpTypeVoid
8789 %3 = OpTypeInt 32 0
8790 %4 = OpConstant %3 1
8791 %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
8792 )";
8793
8794 CompileSuccessfully(text);
8795 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8796 EXPECT_THAT(getDiagnosticString(),
8797 HasSubstr("Missing NonSemantic.ClspvReflection import version"));
8798 }
8799
8800 TEST_F(ValidateClspvReflection, BadVersion0) {
8801 const std::string text = R"(
8802 OpCapability Shader
8803 OpCapability Linkage
8804 OpExtension "SPV_KHR_non_semantic_info"
8805 %1 = OpExtInstImport "NonSemantic.ClspvReflection.0"
8806 OpMemoryModel Logical GLSL450
8807 %2 = OpTypeVoid
8808 %3 = OpTypeInt 32 0
8809 %4 = OpConstant %3 1
8810 %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
8811 )";
8812
8813 CompileSuccessfully(text);
8814 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8815 EXPECT_THAT(getDiagnosticString(),
8816 HasSubstr("Unknown NonSemantic.ClspvReflection import version"));
8817 }
8818
8819 TEST_F(ValidateClspvReflection, BadVersionNotANumber) {
8820 const std::string text = R"(
8821 OpCapability Shader
8822 OpCapability Linkage
8823 OpExtension "SPV_KHR_non_semantic_info"
8824 %1 = OpExtInstImport "NonSemantic.ClspvReflection.1a"
8825 OpMemoryModel Logical GLSL450
8826 %2 = OpTypeVoid
8827 %3 = OpTypeInt 32 0
8828 %4 = OpConstant %3 1
8829 %5 = OpExtInst %2 %1 SpecConstantWorkDim %4
8830 )";
8831
8832 CompileSuccessfully(text);
8833 ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
8834 EXPECT_THAT(getDiagnosticString(),
8835 HasSubstr("NonSemantic.ClspvReflection import does not encode "
8836 "the version correctly"));
8837 }
8838
8839 TEST_F(ValidateClspvReflection, Kernel) {
8840 const std::string text = R"(
8841 OpCapability Shader
8842 OpExtension "SPV_KHR_non_semantic_info"
8843 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8844 OpMemoryModel Logical GLSL450
8845 OpEntryPoint GLCompute %foo "foo"
8846 OpExecutionMode %foo LocalSize 1 1 1
8847 %foo_name = OpString "foo"
8848 %void = OpTypeVoid
8849 %void_fn = OpTypeFunction %void
8850 %foo = OpFunction %void None %void_fn
8851 %entry = OpLabel
8852 OpReturn
8853 OpFunctionEnd
8854 %decl = OpExtInst %void %ext Kernel %foo %foo_name
8855 )";
8856
8857 CompileSuccessfully(text);
8858 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
8859 }
8860
8861 TEST_F(ValidateClspvReflection, KernelNotAFunction) {
8862 const std::string text = R"(
8863 OpCapability Shader
8864 OpExtension "SPV_KHR_non_semantic_info"
8865 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8866 OpMemoryModel Logical GLSL450
8867 OpEntryPoint GLCompute %foo "foo"
8868 OpExecutionMode %foo LocalSize 1 1 1
8869 %foo_name = OpString "foo"
8870 %void = OpTypeVoid
8871 %void_fn = OpTypeFunction %void
8872 %foo = OpFunction %void None %void_fn
8873 %entry = OpLabel
8874 OpReturn
8875 OpFunctionEnd
8876 %decl = OpExtInst %void %ext Kernel %foo_name %foo_name
8877 )";
8878
8879 CompileSuccessfully(text);
8880 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8881 EXPECT_THAT(getDiagnosticString(),
8882 HasSubstr("Kernel does not reference a function"));
8883 }
8884
8885 TEST_F(ValidateClspvReflection, KernelNotAnEntryPoint) {
8886 const std::string text = R"(
8887 OpCapability Shader
8888 OpExtension "SPV_KHR_non_semantic_info"
8889 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8890 OpMemoryModel Logical GLSL450
8891 OpEntryPoint GLCompute %foo "foo"
8892 OpExecutionMode %foo LocalSize 1 1 1
8893 %foo_name = OpString "foo"
8894 %void = OpTypeVoid
8895 %void_fn = OpTypeFunction %void
8896 %foo = OpFunction %void None %void_fn
8897 %entry = OpLabel
8898 OpReturn
8899 OpFunctionEnd
8900 %bar = OpFunction %void None %void_fn
8901 %bar_entry = OpLabel
8902 OpReturn
8903 OpFunctionEnd
8904 %decl = OpExtInst %void %ext Kernel %bar %foo_name
8905 )";
8906
8907 CompileSuccessfully(text);
8908 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8909 EXPECT_THAT(getDiagnosticString(),
8910 HasSubstr("Kernel does not reference an entry-point"));
8911 }
8912
8913 TEST_F(ValidateClspvReflection, KernelNotGLCompute) {
8914 const std::string text = R"(
8915 OpCapability Shader
8916 OpExtension "SPV_KHR_non_semantic_info"
8917 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8918 OpMemoryModel Logical GLSL450
8919 OpEntryPoint Fragment %foo "foo"
8920 OpExecutionMode %foo OriginUpperLeft
8921 %foo_name = OpString "foo"
8922 %void = OpTypeVoid
8923 %void_fn = OpTypeFunction %void
8924 %foo = OpFunction %void None %void_fn
8925 %entry = OpLabel
8926 OpReturn
8927 OpFunctionEnd
8928 %decl = OpExtInst %void %ext Kernel %foo %foo_name
8929 )";
8930
8931 CompileSuccessfully(text);
8932 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8933 EXPECT_THAT(getDiagnosticString(),
8934 HasSubstr("Kernel must refer only to GLCompute entry-points"));
8935 }
8936
8937 TEST_F(ValidateClspvReflection, KernelNameMismatch) {
8938 const std::string text = R"(
8939 OpCapability Shader
8940 OpExtension "SPV_KHR_non_semantic_info"
8941 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8942 OpMemoryModel Logical GLSL450
8943 OpEntryPoint GLCompute %foo "foo"
8944 OpExecutionMode %foo LocalSize 1 1 1
8945 %foo_name = OpString "bar"
8946 %void = OpTypeVoid
8947 %void_fn = OpTypeFunction %void
8948 %foo = OpFunction %void None %void_fn
8949 %entry = OpLabel
8950 OpReturn
8951 OpFunctionEnd
8952 %decl = OpExtInst %void %ext Kernel %foo %foo_name
8953 )";
8954
8955 CompileSuccessfully(text);
8956 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
8957 EXPECT_THAT(getDiagnosticString(),
8958 HasSubstr("Name must match an entry-point for Kernel"));
8959 }
8960
8961 using ArgumentBasics =
8962 spvtest::ValidateBase<std::pair<std::string, std::string>>;
8963
8964 INSTANTIATE_TEST_SUITE_P(
8965 ValidateClspvReflectionArgumentKernel, ArgumentBasics,
8966 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
8967 std::make_pair("ArgumentStorageBuffer", "%int_0 %int_0"),
8968 std::make_pair("ArgumentUniform", "%int_0 %int_0"),
8969 std::make_pair("ArgumentPodStorageBuffer",
8970 "%int_0 %int_0 %int_0 %int_4"),
8971 std::make_pair("ArgumentPodUniform", "%int_0 %int_0 %int_0 %int_4"),
8972 std::make_pair("ArgumentPodPushConstant", "%int_0 %int_4"),
8973 std::make_pair("ArgumentSampledImage", "%int_0 %int_0"),
8974 std::make_pair("ArgumentStorageImage", "%int_0 %int_0"),
8975 std::make_pair("ArgumentSampler", "%int_0 %int_0"),
8976 std::make_pair("ArgumentWorkgroup", "%int_0 %int_0")}));
8977
8978 TEST_P(ArgumentBasics, KernelNotAnExtendedInstruction) {
8979 const std::string ext_inst = std::get<0>(GetParam());
8980 const std::string extra = std::get<1>(GetParam());
8981 const std::string text = R"(
8982 OpCapability Shader
8983 OpExtension "SPV_KHR_non_semantic_info"
8984 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
8985 OpMemoryModel Logical GLSL450
8986 OpEntryPoint GLCompute %foo "foo"
8987 OpExecutionMode %foo LocalSize 1 1 1
8988 %foo_name = OpString "foo"
8989 %void = OpTypeVoid
8990 %int = OpTypeInt 32 0
8991 %int_0 = OpConstant %int 0
8992 %int_4 = OpConstant %int 4
8993 %void_fn = OpTypeFunction %void
8994 %foo = OpFunction %void None %void_fn
8995 %entry = OpLabel
8996 OpReturn
8997 OpFunctionEnd
8998 %in = OpExtInst %void %ext )" +
8999 ext_inst + " %int_0 %int_0 " + extra;
9000
9001 CompileSuccessfully(text);
9002 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9003 EXPECT_THAT(getDiagnosticString(),
9004 HasSubstr("Kernel must be a Kernel extended instruction"));
9005 }
9006
9007 TEST_P(ArgumentBasics, KernelFromDifferentImport) {
9008 const std::string ext_inst = std::get<0>(GetParam());
9009 const std::string extra = std::get<1>(GetParam());
9010 const std::string text = R"(
9011 OpCapability Shader
9012 OpExtension "SPV_KHR_non_semantic_info"
9013 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9014 %ext2 = OpExtInstImport "NonSemantic.ClspvReflection.1"
9015 OpMemoryModel Logical GLSL450
9016 OpEntryPoint GLCompute %foo "foo"
9017 OpExecutionMode %foo LocalSize 1 1 1
9018 %foo_name = OpString "foo"
9019 %void = OpTypeVoid
9020 %int = OpTypeInt 32 0
9021 %int_0 = OpConstant %int 0
9022 %int_4 = OpConstant %int 4
9023 %void_fn = OpTypeFunction %void
9024 %foo = OpFunction %void None %void_fn
9025 %entry = OpLabel
9026 OpReturn
9027 OpFunctionEnd
9028 %decl = OpExtInst %void %ext2 Kernel %foo %foo_name
9029 %in = OpExtInst %void %ext )" +
9030 ext_inst + " %decl %int_0 " + extra;
9031
9032 CompileSuccessfully(text);
9033 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9034 EXPECT_THAT(
9035 getDiagnosticString(),
9036 HasSubstr("Kernel must be from the same extended instruction import"));
9037 }
9038
9039 TEST_P(ArgumentBasics, KernelWrongExtendedInstruction) {
9040 const std::string ext_inst = std::get<0>(GetParam());
9041 const std::string extra = std::get<1>(GetParam());
9042 const std::string text = R"(
9043 OpCapability Shader
9044 OpExtension "SPV_KHR_non_semantic_info"
9045 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9046 OpMemoryModel Logical GLSL450
9047 OpEntryPoint GLCompute %foo "foo"
9048 OpExecutionMode %foo LocalSize 1 1 1
9049 %foo_name = OpString "foo"
9050 %void = OpTypeVoid
9051 %int = OpTypeInt 32 0
9052 %int_0 = OpConstant %int 0
9053 %int_4 = OpConstant %int 4
9054 %void_fn = OpTypeFunction %void
9055 %foo = OpFunction %void None %void_fn
9056 %entry = OpLabel
9057 OpReturn
9058 OpFunctionEnd
9059 %decl = OpExtInst %void %ext ArgumentInfo %foo_name
9060 %in = OpExtInst %void %ext )" +
9061 ext_inst + " %decl %int_0 " + extra;
9062
9063 CompileSuccessfully(text);
9064 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9065 EXPECT_THAT(getDiagnosticString(),
9066 HasSubstr("Kernel must be a Kernel extended instruction"));
9067 }
9068
9069 TEST_P(ArgumentBasics, ArgumentInfo) {
9070 const std::string ext_inst = std::get<0>(GetParam());
9071 const std::string operands = std::get<1>(GetParam());
9072 const std::string text = R"(
9073 OpCapability Shader
9074 OpExtension "SPV_KHR_non_semantic_info"
9075 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9076 OpMemoryModel Logical GLSL450
9077 OpEntryPoint GLCompute %foo "foo"
9078 OpExecutionMode %foo LocalSize 1 1 1
9079 %foo_name = OpString "foo"
9080 %in_name = OpString "in"
9081 %void = OpTypeVoid
9082 %int = OpTypeInt 32 0
9083 %int_0 = OpConstant %int 0
9084 %int_4 = OpConstant %int 4
9085 %void_fn = OpTypeFunction %void
9086 %foo = OpFunction %void None %void_fn
9087 %entry = OpLabel
9088 OpReturn
9089 OpFunctionEnd
9090 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9091 %info = OpExtInst %void %ext ArgumentInfo %in_name
9092 %in = OpExtInst %void %ext )" +
9093 ext_inst + " %decl %int_0 " + operands + " %info";
9094
9095 CompileSuccessfully(text);
9096 ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
9097 }
9098
9099 TEST_P(ArgumentBasics, ArgumentInfoNotAnExtendedInstruction) {
9100 const std::string ext_inst = std::get<0>(GetParam());
9101 const std::string operands = std::get<1>(GetParam());
9102 const std::string text = R"(
9103 OpCapability Shader
9104 OpExtension "SPV_KHR_non_semantic_info"
9105 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9106 OpMemoryModel Logical GLSL450
9107 OpEntryPoint GLCompute %foo "foo"
9108 OpExecutionMode %foo LocalSize 1 1 1
9109 %foo_name = OpString "foo"
9110 %void = OpTypeVoid
9111 %int = OpTypeInt 32 0
9112 %int_0 = OpConstant %int 0
9113 %int_4 = OpConstant %int 4
9114 %void_fn = OpTypeFunction %void
9115 %foo = OpFunction %void None %void_fn
9116 %entry = OpLabel
9117 OpReturn
9118 OpFunctionEnd
9119 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9120 %in = OpExtInst %void %ext )" +
9121 ext_inst + " %decl %int_0 " + operands + " %int_0";
9122
9123 CompileSuccessfully(text);
9124 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9125 EXPECT_THAT(
9126 getDiagnosticString(),
9127 HasSubstr("ArgInfo must be an ArgumentInfo extended instruction"));
9128 }
9129
9130 TEST_P(ArgumentBasics, ArgumentInfoFromDifferentImport) {
9131 const std::string ext_inst = std::get<0>(GetParam());
9132 const std::string operands = std::get<1>(GetParam());
9133 const std::string text = R"(
9134 OpCapability Shader
9135 OpExtension "SPV_KHR_non_semantic_info"
9136 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9137 %ext2 = OpExtInstImport "NonSemantic.ClspvReflection.1"
9138 OpMemoryModel Logical GLSL450
9139 OpEntryPoint GLCompute %foo "foo"
9140 OpExecutionMode %foo LocalSize 1 1 1
9141 %foo_name = OpString "foo"
9142 %in_name = OpString "in"
9143 %void = OpTypeVoid
9144 %int = OpTypeInt 32 0
9145 %int_0 = OpConstant %int 0
9146 %int_4 = OpConstant %int 4
9147 %void_fn = OpTypeFunction %void
9148 %foo = OpFunction %void None %void_fn
9149 %entry = OpLabel
9150 OpReturn
9151 OpFunctionEnd
9152 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9153 %info = OpExtInst %void %ext2 ArgumentInfo %in_name
9154 %in = OpExtInst %void %ext )" +
9155 ext_inst + " %decl %int_0 " + operands + " %info";
9156
9157 CompileSuccessfully(text);
9158 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9159 EXPECT_THAT(
9160 getDiagnosticString(),
9161 HasSubstr("ArgInfo must be from the same extended instruction import"));
9162 }
9163
9164 using Uint32Constant =
9165 spvtest::ValidateBase<std::pair<std::string, std::string>>;
9166
9167 INSTANTIATE_TEST_SUITE_P(
9168 ValidateClspvReflectionUint32Constants, Uint32Constant,
9169 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
9170 std::make_pair("ArgumentStorageBuffer %decl %float_0 %int_0 %int_0",
9171 "Ordinal"),
9172 std::make_pair("ArgumentStorageBuffer %decl %null %int_0 %int_0",
9173 "Ordinal"),
9174 std::make_pair("ArgumentStorageBuffer %decl %int_0 %float_0 %int_0",
9175 "DescriptorSet"),
9176 std::make_pair("ArgumentStorageBuffer %decl %int_0 %null %int_0",
9177 "DescriptorSet"),
9178 std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %float_0",
9179 "Binding"),
9180 std::make_pair("ArgumentStorageBuffer %decl %int_0 %int_0 %null",
9181 "Binding"),
9182 std::make_pair("ArgumentUniform %decl %float_0 %int_0 %int_0",
9183 "Ordinal"),
9184 std::make_pair("ArgumentUniform %decl %null %int_0 %int_0", "Ordinal"),
9185 std::make_pair("ArgumentUniform %decl %int_0 %float_0 %int_0",
9186 "DescriptorSet"),
9187 std::make_pair("ArgumentUniform %decl %int_0 %null %int_0",
9188 "DescriptorSet"),
9189 std::make_pair("ArgumentUniform %decl %int_0 %int_0 %float_0",
9190 "Binding"),
9191 std::make_pair("ArgumentUniform %decl %int_0 %int_0 %null", "Binding"),
9192 std::make_pair("ArgumentSampledImage %decl %float_0 %int_0 %int_0",
9193 "Ordinal"),
9194 std::make_pair("ArgumentSampledImage %decl %null %int_0 %int_0",
9195 "Ordinal"),
9196 std::make_pair("ArgumentSampledImage %decl %int_0 %float_0 %int_0",
9197 "DescriptorSet"),
9198 std::make_pair("ArgumentSampledImage %decl %int_0 %null %int_0",
9199 "DescriptorSet"),
9200 std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %float_0",
9201 "Binding"),
9202 std::make_pair("ArgumentSampledImage %decl %int_0 %int_0 %null",
9203 "Binding"),
9204 std::make_pair("ArgumentStorageImage %decl %float_0 %int_0 %int_0",
9205 "Ordinal"),
9206 std::make_pair("ArgumentStorageImage %decl %null %int_0 %int_0",
9207 "Ordinal"),
9208 std::make_pair("ArgumentStorageImage %decl %int_0 %float_0 %int_0",
9209 "DescriptorSet"),
9210 std::make_pair("ArgumentStorageImage %decl %int_0 %null %int_0",
9211 "DescriptorSet"),
9212 std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %float_0",
9213 "Binding"),
9214 std::make_pair("ArgumentStorageImage %decl %int_0 %int_0 %null",
9215 "Binding"),
9216 std::make_pair("ArgumentSampler %decl %float_0 %int_0 %int_0",
9217 "Ordinal"),
9218 std::make_pair("ArgumentSampler %decl %null %int_0 %int_0", "Ordinal"),
9219 std::make_pair("ArgumentSampler %decl %int_0 %float_0 %int_0",
9220 "DescriptorSet"),
9221 std::make_pair("ArgumentSampler %decl %int_0 %null %int_0",
9222 "DescriptorSet"),
9223 std::make_pair("ArgumentSampler %decl %int_0 %int_0 %float_0",
9224 "Binding"),
9225 std::make_pair("ArgumentSampler %decl %int_0 %int_0 %null", "Binding"),
9226 std::make_pair("ArgumentPodStorageBuffer %decl %float_0 %int_0 %int_0 "
9227 "%int_0 %int_4",
9228 "Ordinal"),
9229 std::make_pair(
9230 "ArgumentPodStorageBuffer %decl %null %int_0 %int_0 %int_0 %int_4",
9231 "Ordinal"),
9232 std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %float_0 %int_0 "
9233 "%int_0 %int_4",
9234 "DescriptorSet"),
9235 std::make_pair(
9236 "ArgumentPodStorageBuffer %decl %int_0 %null %int_0 %int_0 %int_4",
9237 "DescriptorSet"),
9238 std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %float_0 "
9239 "%int_0 %int_4",
9240 "Binding"),
9241 std::make_pair(
9242 "ArgumentPodStorageBuffer %decl %int_0 %int_0 %null %int_0 %int_4",
9243 "Binding"),
9244 std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 "
9245 "%float_0 %int_4",
9246 "Offset"),
9247 std::make_pair(
9248 "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %null %int_4",
9249 "Offset"),
9250 std::make_pair("ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 "
9251 "%int_0 %float_0",
9252 "Size"),
9253 std::make_pair(
9254 "ArgumentPodStorageBuffer %decl %int_0 %int_0 %int_0 %int_0 %null",
9255 "Size"),
9256 std::make_pair(
9257 "ArgumentPodUniform %decl %float_0 %int_0 %int_0 %int_0 %int_4",
9258 "Ordinal"),
9259 std::make_pair(
9260 "ArgumentPodUniform %decl %null %int_0 %int_0 %int_0 %int_4",
9261 "Ordinal"),
9262 std::make_pair(
9263 "ArgumentPodUniform %decl %int_0 %float_0 %int_0 %int_0 %int_4",
9264 "DescriptorSet"),
9265 std::make_pair(
9266 "ArgumentPodUniform %decl %int_0 %null %int_0 %int_0 %int_4",
9267 "DescriptorSet"),
9268 std::make_pair(
9269 "ArgumentPodUniform %decl %int_0 %int_0 %float_0 %int_0 %int_4",
9270 "Binding"),
9271 std::make_pair(
9272 "ArgumentPodUniform %decl %int_0 %int_0 %null %int_0 %int_4",
9273 "Binding"),
9274 std::make_pair(
9275 "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %float_0 %int_4",
9276 "Offset"),
9277 std::make_pair(
9278 "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %null %int_4",
9279 "Offset"),
9280 std::make_pair(
9281 "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %float_0",
9282 "Size"),
9283 std::make_pair(
9284 "ArgumentPodUniform %decl %int_0 %int_0 %int_0 %int_0 %null",
9285 "Size"),
9286 std::make_pair("ArgumentPodPushConstant %decl %float_0 %int_0 %int_4",
9287 "Ordinal"),
9288 std::make_pair("ArgumentPodPushConstant %decl %null %int_0 %int_4",
9289 "Ordinal"),
9290 std::make_pair("ArgumentPodPushConstant %decl %int_0 %float_0 %int_4",
9291 "Offset"),
9292 std::make_pair("ArgumentPodPushConstant %decl %int_0 %null %int_4",
9293 "Offset"),
9294 std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %float_0",
9295 "Size"),
9296 std::make_pair("ArgumentPodPushConstant %decl %int_0 %int_0 %null",
9297 "Size"),
9298 std::make_pair("ArgumentWorkgroup %decl %float_0 %int_0 %int_4",
9299 "Ordinal"),
9300 std::make_pair("ArgumentWorkgroup %decl %null %int_0 %int_4",
9301 "Ordinal"),
9302 std::make_pair("ArgumentWorkgroup %decl %int_0 %float_0 %int_4",
9303 "SpecId"),
9304 std::make_pair("ArgumentWorkgroup %decl %int_0 %null %int_4", "SpecId"),
9305 std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %float_0",
9306 "ElemSize"),
9307 std::make_pair("ArgumentWorkgroup %decl %int_0 %int_0 %null",
9308 "ElemSize"),
9309 std::make_pair("SpecConstantWorkgroupSize %float_0 %int_0 %int_4", "X"),
9310 std::make_pair("SpecConstantWorkgroupSize %null %int_0 %int_4", "X"),
9311 std::make_pair("SpecConstantWorkgroupSize %int_0 %float_0 %int_4", "Y"),
9312 std::make_pair("SpecConstantWorkgroupSize %int_0 %null %int_4", "Y"),
9313 std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %float_0", "Z"),
9314 std::make_pair("SpecConstantWorkgroupSize %int_0 %int_0 %null", "Z"),
9315 std::make_pair("SpecConstantGlobalOffset %float_0 %int_0 %int_4", "X"),
9316 std::make_pair("SpecConstantGlobalOffset %null %int_0 %int_4", "X"),
9317 std::make_pair("SpecConstantGlobalOffset %int_0 %float_0 %int_4", "Y"),
9318 std::make_pair("SpecConstantGlobalOffset %int_0 %null %int_4", "Y"),
9319 std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %float_0", "Z"),
9320 std::make_pair("SpecConstantGlobalOffset %int_0 %int_0 %null", "Z"),
9321 std::make_pair("SpecConstantWorkDim %float_0", "Dim"),
9322 std::make_pair("SpecConstantWorkDim %null", "Dim"),
9323 std::make_pair("PushConstantGlobalOffset %float_0 %int_0", "Offset"),
9324 std::make_pair("PushConstantGlobalOffset %null %int_0", "Offset"),
9325 std::make_pair("PushConstantGlobalOffset %int_0 %float_0", "Size"),
9326 std::make_pair("PushConstantGlobalOffset %int_0 %null", "Size"),
9327 std::make_pair("PushConstantEnqueuedLocalSize %float_0 %int_0",
9328 "Offset"),
9329 std::make_pair("PushConstantEnqueuedLocalSize %null %int_0", "Offset"),
9330 std::make_pair("PushConstantEnqueuedLocalSize %int_0 %float_0", "Size"),
9331 std::make_pair("PushConstantEnqueuedLocalSize %int_0 %null", "Size"),
9332 std::make_pair("PushConstantGlobalSize %float_0 %int_0", "Offset"),
9333 std::make_pair("PushConstantGlobalSize %null %int_0", "Offset"),
9334 std::make_pair("PushConstantGlobalSize %int_0 %float_0", "Size"),
9335 std::make_pair("PushConstantGlobalSize %int_0 %null", "Size"),
9336 std::make_pair("PushConstantRegionOffset %float_0 %int_0", "Offset"),
9337 std::make_pair("PushConstantRegionOffset %null %int_0", "Offset"),
9338 std::make_pair("PushConstantRegionOffset %int_0 %float_0", "Size"),
9339 std::make_pair("PushConstantRegionOffset %int_0 %null", "Size"),
9340 std::make_pair("PushConstantNumWorkgroups %float_0 %int_0", "Offset"),
9341 std::make_pair("PushConstantNumWorkgroups %null %int_0", "Offset"),
9342 std::make_pair("PushConstantNumWorkgroups %int_0 %float_0", "Size"),
9343 std::make_pair("PushConstantNumWorkgroups %int_0 %null", "Size"),
9344 std::make_pair("PushConstantRegionGroupOffset %float_0 %int_0",
9345 "Offset"),
9346 std::make_pair("PushConstantRegionGroupOffset %null %int_0", "Offset"),
9347 std::make_pair("PushConstantRegionGroupOffset %int_0 %float_0", "Size"),
9348 std::make_pair("PushConstantRegionGroupOffset %int_0 %null", "Size"),
9349 std::make_pair("ConstantDataStorageBuffer %float_0 %int_0 %data",
9350 "DescriptorSet"),
9351 std::make_pair("ConstantDataStorageBuffer %null %int_0 %data",
9352 "DescriptorSet"),
9353 std::make_pair("ConstantDataStorageBuffer %int_0 %float_0 %data",
9354 "Binding"),
9355 std::make_pair("ConstantDataStorageBuffer %int_0 %null %data",
9356 "Binding"),
9357 std::make_pair("ConstantDataUniform %float_0 %int_0 %data",
9358 "DescriptorSet"),
9359 std::make_pair("ConstantDataUniform %null %int_0 %data",
9360 "DescriptorSet"),
9361 std::make_pair("ConstantDataUniform %int_0 %float_0 %data", "Binding"),
9362 std::make_pair("ConstantDataUniform %int_0 %null %data", "Binding"),
9363 std::make_pair("LiteralSampler %float_0 %int_0 %int_4",
9364 "DescriptorSet"),
9365 std::make_pair("LiteralSampler %null %int_0 %int_4", "DescriptorSet"),
9366 std::make_pair("LiteralSampler %int_0 %float_0 %int_4", "Binding"),
9367 std::make_pair("LiteralSampler %int_0 %null %int_4", "Binding"),
9368 std::make_pair("LiteralSampler %int_0 %int_0 %float_0", "Mask"),
9369 std::make_pair("LiteralSampler %int_0 %int_0 %null", "Mask"),
9370 std::make_pair(
9371 "PropertyRequiredWorkgroupSize %decl %float_0 %int_1 %int_4", "X"),
9372 std::make_pair(
9373 "PropertyRequiredWorkgroupSize %decl %null %int_1 %int_4", "X"),
9374 std::make_pair(
9375 "PropertyRequiredWorkgroupSize %decl %int_1 %float_0 %int_4", "Y"),
9376 std::make_pair(
9377 "PropertyRequiredWorkgroupSize %decl %int_1 %null %int_4", "Y"),
9378 std::make_pair(
9379 "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %float_0", "Z"),
9380 std::make_pair(
9381 "PropertyRequiredWorkgroupSize %decl %int_1 %int_1 %null", "Z")}));
9382
9383 TEST_P(Uint32Constant, Invalid) {
9384 const std::string ext_inst = std::get<0>(GetParam());
9385 const std::string name = std::get<1>(GetParam());
9386 const std::string text = R"(
9387 OpCapability Shader
9388 OpExtension "SPV_KHR_non_semantic_info"
9389 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9390 OpMemoryModel Logical GLSL450
9391 OpEntryPoint GLCompute %foo "foo"
9392 OpExecutionMode %foo LocalSize 1 1 1
9393 %foo_name = OpString "foo"
9394 %data = OpString "1234"
9395 %void = OpTypeVoid
9396 %int = OpTypeInt 32 0
9397 %int_0 = OpConstant %int 0
9398 %int_1 = OpConstant %int 1
9399 %int_4 = OpConstant %int 4
9400 %null = OpConstantNull %int
9401 %float = OpTypeFloat 32
9402 %float_0 = OpConstant %float 0
9403 %void_fn = OpTypeFunction %void
9404 %foo = OpFunction %void None %void_fn
9405 %entry = OpLabel
9406 OpReturn
9407 OpFunctionEnd
9408 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9409 %inst = OpExtInst %void %ext )" +
9410 ext_inst;
9411
9412 CompileSuccessfully(text);
9413 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9414 EXPECT_THAT(
9415 getDiagnosticString(),
9416 HasSubstr(name + " must be a 32-bit unsigned integer OpConstant"));
9417 }
9418
9419 using StringOperand =
9420 spvtest::ValidateBase<std::pair<std::string, std::string>>;
9421
9422 INSTANTIATE_TEST_SUITE_P(
9423 ValidateClspvReflectionStringOperands, StringOperand,
9424 ::testing::ValuesIn(std::vector<std::pair<std::string, std::string>>{
9425 std::make_pair("ConstantDataStorageBuffer %int_0 %int_0 %int_0",
9426 "Data"),
9427 std::make_pair("ConstantDataUniform %int_0 %int_0 %int_0", "Data")}));
9428
9429 TEST_P(StringOperand, Invalid) {
9430 const std::string ext_inst = std::get<0>(GetParam());
9431 const std::string name = std::get<1>(GetParam());
9432 const std::string text = R"(
9433 OpCapability Shader
9434 OpExtension "SPV_KHR_non_semantic_info"
9435 %ext = OpExtInstImport "NonSemantic.ClspvReflection.1"
9436 OpMemoryModel Logical GLSL450
9437 OpEntryPoint GLCompute %foo "foo"
9438 OpExecutionMode %foo LocalSize 1 1 1
9439 %foo_name = OpString "foo"
9440 %data = OpString "1234"
9441 %void = OpTypeVoid
9442 %int = OpTypeInt 32 0
9443 %int_0 = OpConstant %int 0
9444 %int_1 = OpConstant %int 1
9445 %int_4 = OpConstant %int 4
9446 %null = OpConstantNull %int
9447 %float = OpTypeFloat 32
9448 %float_0 = OpConstant %float 0
9449 %void_fn = OpTypeFunction %void
9450 %foo = OpFunction %void None %void_fn
9451 %entry = OpLabel
9452 OpReturn
9453 OpFunctionEnd
9454 %decl = OpExtInst %void %ext Kernel %foo %foo_name
9455 %inst = OpExtInst %void %ext )" +
9456 ext_inst;
9457
9458 CompileSuccessfully(text);
9459 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
9460 EXPECT_THAT(getDiagnosticString(), HasSubstr(name + " must be an OpString"));
9461 }
9462
9463 } // namespace
9464 } // namespace val
9465 } // namespace spvtools
9466