1 // Copyright (c) 2018 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 // Validation tests for memory/storage
16
17 #include <string>
18 #include <vector>
19
20 #include "gmock/gmock.h"
21 #include "test/unit_spirv.h"
22 #include "test/val/val_fixtures.h"
23
24 namespace spvtools {
25 namespace val {
26 namespace {
27
28 using ::testing::Eq;
29 using ::testing::HasSubstr;
30
31 using ValidateMemory = spvtest::ValidateBase<bool>;
32
TEST_F(ValidateMemory,VulkanUniformConstantOnNonOpaqueResourceBad)33 TEST_F(ValidateMemory, VulkanUniformConstantOnNonOpaqueResourceBad) {
34 std::string spirv = R"(
35 OpCapability Shader
36 OpMemoryModel Logical GLSL450
37 OpEntryPoint Fragment %func "func"
38 OpExecutionMode %func OriginUpperLeft
39 %float = OpTypeFloat 32
40 %float_ptr = OpTypePointer UniformConstant %float
41 %2 = OpVariable %float_ptr UniformConstant
42 %void = OpTypeVoid
43 %functy = OpTypeFunction %void
44 %func = OpFunction %void None %functy
45 %1 = OpLabel
46 OpReturn
47 OpFunctionEnd
48 )";
49 CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
50 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
51 EXPECT_THAT(
52 getDiagnosticString(),
53 HasSubstr("From Vulkan spec, section 14.5.2:\n"
54 "Variables identified with the UniformConstant storage class "
55 "are used only as handles to refer to opaque resources. Such "
56 "variables must be typed as OpTypeImage, OpTypeSampler, "
57 "OpTypeSampledImage, OpTypeAccelerationStructureNV, or an "
58 "array of one of these types."));
59 }
60
TEST_F(ValidateMemory,VulkanUniformConstantOnOpaqueResourceGood)61 TEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceGood) {
62 std::string spirv = R"(
63 OpCapability Shader
64 OpMemoryModel Logical GLSL450
65 OpEntryPoint Fragment %func "func"
66 OpExecutionMode %func OriginUpperLeft
67 OpDecorate %2 DescriptorSet 0
68 OpDecorate %2 Binding 0
69 %sampler = OpTypeSampler
70 %sampler_ptr = OpTypePointer UniformConstant %sampler
71 %2 = OpVariable %sampler_ptr UniformConstant
72 %void = OpTypeVoid
73 %functy = OpTypeFunction %void
74 %func = OpFunction %void None %functy
75 %1 = OpLabel
76 OpReturn
77 OpFunctionEnd
78 )";
79 CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
80 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
81 }
82
TEST_F(ValidateMemory,VulkanUniformConstantOnNonOpaqueResourceArrayBad)83 TEST_F(ValidateMemory, VulkanUniformConstantOnNonOpaqueResourceArrayBad) {
84 std::string spirv = R"(
85 OpCapability Shader
86 OpMemoryModel Logical GLSL450
87 OpEntryPoint Fragment %func "func"
88 OpExecutionMode %func OriginUpperLeft
89 %float = OpTypeFloat 32
90 %uint = OpTypeInt 32 0
91 %array_size = OpConstant %uint 5
92 %array = OpTypeArray %float %array_size
93 %array_ptr = OpTypePointer UniformConstant %array
94 %2 = OpVariable %array_ptr UniformConstant
95 %void = OpTypeVoid
96 %functy = OpTypeFunction %void
97 %func = OpFunction %void None %functy
98 %1 = OpLabel
99 OpReturn
100 OpFunctionEnd
101 )";
102 CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
103 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
104 EXPECT_THAT(
105 getDiagnosticString(),
106 HasSubstr("From Vulkan spec, section 14.5.2:\n"
107 "Variables identified with the UniformConstant storage class "
108 "are used only as handles to refer to opaque resources. Such "
109 "variables must be typed as OpTypeImage, OpTypeSampler, "
110 "OpTypeSampledImage, OpTypeAccelerationStructureNV, or an "
111 "array of one of these types."));
112 }
113
TEST_F(ValidateMemory,VulkanUniformConstantOnOpaqueResourceArrayGood)114 TEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceArrayGood) {
115 std::string spirv = R"(
116 OpCapability Shader
117 OpMemoryModel Logical GLSL450
118 OpEntryPoint Fragment %func "func"
119 OpExecutionMode %func OriginUpperLeft
120 OpDecorate %2 DescriptorSet 0
121 OpDecorate %2 Binding 0
122 %sampler = OpTypeSampler
123 %uint = OpTypeInt 32 0
124 %array_size = OpConstant %uint 5
125 %array = OpTypeArray %sampler %array_size
126 %array_ptr = OpTypePointer UniformConstant %array
127 %2 = OpVariable %array_ptr UniformConstant
128 %void = OpTypeVoid
129 %functy = OpTypeFunction %void
130 %func = OpFunction %void None %functy
131 %1 = OpLabel
132 OpReturn
133 OpFunctionEnd
134 )";
135 CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
136 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
137 }
138
TEST_F(ValidateMemory,VulkanUniformConstantOnOpaqueResourceRuntimeArrayGood)139 TEST_F(ValidateMemory, VulkanUniformConstantOnOpaqueResourceRuntimeArrayGood) {
140 std::string spirv = R"(
141 OpCapability Shader
142 OpMemoryModel Logical GLSL450
143 OpEntryPoint Fragment %func "func"
144 OpExecutionMode %func OriginUpperLeft
145 OpDecorate %2 DescriptorSet 0
146 OpDecorate %2 Binding 0
147 %sampler = OpTypeSampler
148 %uint = OpTypeInt 32 0
149 %array = OpTypeRuntimeArray %sampler
150 %array_ptr = OpTypePointer UniformConstant %array
151 %2 = OpVariable %array_ptr UniformConstant
152 %void = OpTypeVoid
153 %functy = OpTypeFunction %void
154 %func = OpFunction %void None %functy
155 %1 = OpLabel
156 OpReturn
157 OpFunctionEnd
158 )";
159 CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
160 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
161 }
162
TEST_F(ValidateMemory,VulkanUniformOnIntBad)163 TEST_F(ValidateMemory, VulkanUniformOnIntBad) {
164 char src[] = R"(
165 OpCapability Shader
166 OpMemoryModel Logical GLSL450
167 OpEntryPoint GLCompute %kernel "main"
168 OpExecutionMode %kernel LocalSize 1 1 1
169
170 OpDecorate %var DescriptorSet 0
171 OpDecorate %var Binding 0
172
173 %voidty = OpTypeVoid
174 %kernelty = OpTypeFunction %voidty
175 %intty = OpTypeInt 32 0
176 %varty = OpTypePointer Uniform %intty
177 %value = OpConstant %intty 42
178
179 %var = OpVariable %varty Uniform
180
181 %kernel = OpFunction %voidty None %kernelty
182 %label = OpLabel
183 OpStore %var %value
184 OpReturn
185 OpFunctionEnd
186 )";
187 CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
188 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
189 EXPECT_THAT(
190 getDiagnosticString(),
191 HasSubstr("From Vulkan spec, section 14.5.2:\n"
192 "Variables identified with the Uniform storage class are used "
193 "to access transparent buffer backed resources. Such variables "
194 "must be typed as OpTypeStruct, or an array of this type"));
195 }
196
197 // #version 440
198 // #extension GL_EXT_nonuniform_qualifier : enable
199 // layout(binding = 1) uniform sampler2D s2d[][2];
200 // layout(location = 0) in nonuniformEXT int i;
201 // void main()
202 // {
203 // vec4 v = texture(s2d[i][i], vec2(0.3));
204 // }
TEST_F(ValidateMemory,VulkanUniformOnRuntimeArrayOfArrayBad)205 TEST_F(ValidateMemory, VulkanUniformOnRuntimeArrayOfArrayBad) {
206 char src[] = R"(
207 OpCapability Shader
208 OpCapability ShaderNonUniformEXT
209 OpCapability RuntimeDescriptorArrayEXT
210 OpCapability SampledImageArrayNonUniformIndexingEXT
211 OpExtension "SPV_EXT_descriptor_indexing"
212 %1 = OpExtInstImport "GLSL.std.450"
213 OpMemoryModel Logical GLSL450
214 OpEntryPoint Vertex %main "main" %i
215 OpSource GLSL 440
216 OpSourceExtension "GL_EXT_nonuniform_qualifier"
217 OpName %main "main"
218 OpName %v "v"
219 OpName %s2d "s2d"
220 OpName %i "i"
221 OpDecorate %s2d DescriptorSet 0
222 OpDecorate %s2d Binding 1
223 OpDecorate %i Location 0
224 OpDecorate %i NonUniformEXT
225 OpDecorate %21 NonUniformEXT
226 OpDecorate %22 NonUniformEXT
227 OpDecorate %25 NonUniformEXT
228 %void = OpTypeVoid
229 %3 = OpTypeFunction %void
230 %float = OpTypeFloat 32
231 %v4float = OpTypeVector %float 4
232 %_ptr_Function_v4float = OpTypePointer Function %v4float
233 %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
234 %11 = OpTypeSampledImage %10
235 %uint = OpTypeInt 32 0
236 %uint_2 = OpConstant %uint 2
237 %_arr_11_uint_2 = OpTypeArray %11 %uint_2
238 %_runtimearr__arr_11_uint_2 = OpTypeRuntimeArray %_arr_11_uint_2
239 %_ptr_Uniform__runtimearr__arr_11_uint_2 = OpTypePointer Uniform %_runtimearr__arr_11_uint_2
240 %s2d = OpVariable %_ptr_Uniform__runtimearr__arr_11_uint_2 Uniform
241 %int = OpTypeInt 32 1
242 %_ptr_Input_int = OpTypePointer Input %int
243 %i = OpVariable %_ptr_Input_int Input
244 %_ptr_Uniform_11 = OpTypePointer Uniform %11
245 %v2float = OpTypeVector %float 2
246 %float_0_300000012 = OpConstant %float 0.300000012
247 %28 = OpConstantComposite %v2float %float_0_300000012 %float_0_300000012
248 %float_0 = OpConstant %float 0
249 %main = OpFunction %void None %3
250 %5 = OpLabel
251 %v = OpVariable %_ptr_Function_v4float Function
252 %21 = OpLoad %int %i
253 %22 = OpLoad %int %i
254 %24 = OpAccessChain %_ptr_Uniform_11 %s2d %21 %22
255 %25 = OpLoad %11 %24
256 %30 = OpImageSampleExplicitLod %v4float %25 %28 Lod %float_0
257 OpStore %v %30
258 OpReturn
259 OpFunctionEnd
260 )";
261 CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
262 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
263 EXPECT_THAT(
264 getDiagnosticString(),
265 HasSubstr("From Vulkan spec, section 14.5.2:\n"
266 "Variables identified with the Uniform storage class are used "
267 "to access transparent buffer backed resources. Such variables "
268 "must be typed as OpTypeStruct, or an array of this type"));
269 }
270
271 // #version 440
272 // layout (set=1, binding=1) uniform sampler2D variableName[2][2];
273 // void main() {
274 // }
TEST_F(ValidateMemory,VulkanUniformOnArrayOfArrayBad)275 TEST_F(ValidateMemory, VulkanUniformOnArrayOfArrayBad) {
276 char src[] = R"(
277 OpCapability Shader
278 %1 = OpExtInstImport "GLSL.std.450"
279 OpMemoryModel Logical GLSL450
280 OpEntryPoint Vertex %main "main"
281 OpSource GLSL 440
282 OpName %main "main"
283 OpName %variableName "variableName"
284 OpDecorate %variableName DescriptorSet 1
285 OpDecorate %variableName Binding 1
286 %void = OpTypeVoid
287 %3 = OpTypeFunction %void
288 %float = OpTypeFloat 32
289 %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
290 %8 = OpTypeSampledImage %7
291 %uint = OpTypeInt 32 0
292 %uint_2 = OpConstant %uint 2
293 %_arr_8_uint_2 = OpTypeArray %8 %uint_2
294 %_arr__arr_8_uint_2_uint_2 = OpTypeArray %_arr_8_uint_2 %uint_2
295 %_ptr_Uniform__arr__arr_8_uint_2_uint_2 = OpTypePointer Uniform %_arr__arr_8_uint_2_uint_2
296 %variableName = OpVariable %_ptr_Uniform__arr__arr_8_uint_2_uint_2 Uniform
297 %main = OpFunction %void None %3
298 %5 = OpLabel
299 OpReturn
300 OpFunctionEnd
301 )";
302 CompileSuccessfully(src, SPV_ENV_VULKAN_1_1);
303 ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
304 EXPECT_THAT(
305 getDiagnosticString(),
306 HasSubstr("From Vulkan spec, section 14.5.2:\n"
307 "Variables identified with the Uniform storage class are used "
308 "to access transparent buffer backed resources. Such variables "
309 "must be typed as OpTypeStruct, or an array of this type"));
310 }
311
TEST_F(ValidateMemory,MismatchingStorageClassesBad)312 TEST_F(ValidateMemory, MismatchingStorageClassesBad) {
313 std::string spirv = R"(
314 OpCapability Shader
315 OpMemoryModel Logical GLSL450
316 OpEntryPoint Fragment %func "func"
317 OpExecutionMode %func OriginUpperLeft
318 %float = OpTypeFloat 32
319 %float_ptr = OpTypePointer Uniform %float
320 %void = OpTypeVoid
321 %functy = OpTypeFunction %void
322 %func = OpFunction %void None %functy
323 %1 = OpLabel
324 %2 = OpVariable %float_ptr Function
325 OpReturn
326 OpFunctionEnd
327 )";
328 CompileSuccessfully(spirv.c_str());
329 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
330 EXPECT_THAT(
331 getDiagnosticString(),
332 HasSubstr(
333 "From SPIR-V spec, section 3.32.8 on OpVariable:\n"
334 "Its Storage Class operand must be the same as the Storage Class "
335 "operand of the result type."));
336 }
337
TEST_F(ValidateMemory,MatchingStorageClassesGood)338 TEST_F(ValidateMemory, MatchingStorageClassesGood) {
339 std::string spirv = R"(
340 OpCapability Shader
341 OpMemoryModel Logical GLSL450
342 OpEntryPoint Fragment %func "func"
343 OpExecutionMode %func OriginUpperLeft
344 %float = OpTypeFloat 32
345 %float_ptr = OpTypePointer Function %float
346 %void = OpTypeVoid
347 %functy = OpTypeFunction %void
348 %func = OpFunction %void None %functy
349 %1 = OpLabel
350 %2 = OpVariable %float_ptr Function
351 OpReturn
352 OpFunctionEnd
353 )";
354 CompileSuccessfully(spirv.c_str());
355 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
356 }
357
TEST_F(ValidateMemory,WebGPUInitializerWithOutputStorageClassesGood)358 TEST_F(ValidateMemory, WebGPUInitializerWithOutputStorageClassesGood) {
359 std::string spirv = R"(
360 OpCapability Shader
361 OpCapability VulkanMemoryModelKHR
362 OpExtension "SPV_KHR_vulkan_memory_model"
363 OpMemoryModel Logical VulkanKHR
364 OpEntryPoint Fragment %func "func"
365 OpExecutionMode %func OriginUpperLeft
366 %float = OpTypeFloat 32
367 %float_ptr = OpTypePointer Output %float
368 %init_val = OpConstant %float 1.0
369 %1 = OpVariable %float_ptr Output %init_val
370 %void = OpTypeVoid
371 %functy = OpTypeFunction %void
372 %func = OpFunction %void None %functy
373 %2 = OpLabel
374 OpReturn
375 OpFunctionEnd
376 )";
377 CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0);
378 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0));
379 }
380
TEST_F(ValidateMemory,WebGPUInitializerWithFunctionStorageClassesGood)381 TEST_F(ValidateMemory, WebGPUInitializerWithFunctionStorageClassesGood) {
382 std::string spirv = R"(
383 OpCapability Shader
384 OpCapability VulkanMemoryModelKHR
385 OpExtension "SPV_KHR_vulkan_memory_model"
386 OpMemoryModel Logical VulkanKHR
387 OpEntryPoint Fragment %func "func"
388 OpExecutionMode %func OriginUpperLeft
389 %float = OpTypeFloat 32
390 %float_ptr = OpTypePointer Function %float
391 %init_val = OpConstant %float 1.0
392 %void = OpTypeVoid
393 %functy = OpTypeFunction %void
394 %func = OpFunction %void None %functy
395 %1 = OpLabel
396 %2 = OpVariable %float_ptr Function %init_val
397 OpReturn
398 OpFunctionEnd
399 )";
400 CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0);
401 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0));
402 }
403
TEST_F(ValidateMemory,WebGPUInitializerWithPrivateStorageClassesGood)404 TEST_F(ValidateMemory, WebGPUInitializerWithPrivateStorageClassesGood) {
405 std::string spirv = R"(
406 OpCapability Shader
407 OpCapability VulkanMemoryModelKHR
408 OpExtension "SPV_KHR_vulkan_memory_model"
409 OpMemoryModel Logical VulkanKHR
410 OpEntryPoint Fragment %func "func"
411 OpExecutionMode %func OriginUpperLeft
412 %float = OpTypeFloat 32
413 %float_ptr = OpTypePointer Private %float
414 %init_val = OpConstant %float 1.0
415 %1 = OpVariable %float_ptr Private %init_val
416 %void = OpTypeVoid
417 %functy = OpTypeFunction %void
418 %func = OpFunction %void None %functy
419 %2 = OpLabel
420 OpReturn
421 OpFunctionEnd
422 )";
423 CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0);
424 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_WEBGPU_0));
425 }
426
TEST_F(ValidateMemory,WebGPUInitializerWithDisallowedStorageClassesBad)427 TEST_F(ValidateMemory, WebGPUInitializerWithDisallowedStorageClassesBad) {
428 std::string spirv = R"(
429 OpCapability Shader
430 OpCapability VulkanMemoryModelKHR
431 OpExtension "SPV_KHR_vulkan_memory_model"
432 OpMemoryModel Logical VulkanKHR
433 OpEntryPoint Fragment %func "func"
434 OpExecutionMode %func OriginUpperLeft
435 %float = OpTypeFloat 32
436 %float_ptr = OpTypePointer Uniform %float
437 %init_val = OpConstant %float 1.0
438 %1 = OpVariable %float_ptr Uniform %init_val
439 %void = OpTypeVoid
440 %functy = OpTypeFunction %void
441 %func = OpFunction %void None %functy
442 %2 = OpLabel
443 OpReturn
444 OpFunctionEnd
445 )";
446 CompileSuccessfully(spirv.c_str(), SPV_ENV_WEBGPU_0);
447 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_WEBGPU_0));
448 EXPECT_THAT(
449 getDiagnosticString(),
450 HasSubstr(
451 "OpVariable, <id> '5[%5]', has a disallowed initializer & storage "
452 "class combination.\nFrom WebGPU execution environment spec:\n"
453 "Variable declarations that include initializers must have one of "
454 "the following storage classes: Output, Private, or Function\n"
455 " %5 = OpVariable %_ptr_Uniform_float Uniform %float_1\n"));
456 }
457
TEST_F(ValidateMemory,VulkanInitializerWithOutputStorageClassesGood)458 TEST_F(ValidateMemory, VulkanInitializerWithOutputStorageClassesGood) {
459 std::string spirv = R"(
460 OpCapability Shader
461 OpMemoryModel Logical GLSL450
462 OpEntryPoint Fragment %func "func"
463 OpExecutionMode %func OriginUpperLeft
464 %float = OpTypeFloat 32
465 %float_ptr = OpTypePointer Output %float
466 %init_val = OpConstant %float 1.0
467 %1 = OpVariable %float_ptr Output %init_val
468 %void = OpTypeVoid
469 %functy = OpTypeFunction %void
470 %func = OpFunction %void None %functy
471 %2 = OpLabel
472 OpReturn
473 OpFunctionEnd
474 )";
475 CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
476 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
477 }
478
TEST_F(ValidateMemory,VulkanInitializerWithFunctionStorageClassesGood)479 TEST_F(ValidateMemory, VulkanInitializerWithFunctionStorageClassesGood) {
480 std::string spirv = R"(
481 OpCapability Shader
482 OpMemoryModel Logical GLSL450
483 OpEntryPoint Fragment %func "func"
484 OpExecutionMode %func OriginUpperLeft
485 %float = OpTypeFloat 32
486 %float_ptr = OpTypePointer Function %float
487 %init_val = OpConstant %float 1.0
488 %void = OpTypeVoid
489 %functy = OpTypeFunction %void
490 %func = OpFunction %void None %functy
491 %1 = OpLabel
492 %2 = OpVariable %float_ptr Function %init_val
493 OpReturn
494 OpFunctionEnd
495 )";
496 CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
497 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
498 }
499
TEST_F(ValidateMemory,VulkanInitializerWithPrivateStorageClassesGood)500 TEST_F(ValidateMemory, VulkanInitializerWithPrivateStorageClassesGood) {
501 std::string spirv = R"(
502 OpCapability Shader
503 OpMemoryModel Logical GLSL450
504 OpEntryPoint Fragment %func "func"
505 OpExecutionMode %func OriginUpperLeft
506 %float = OpTypeFloat 32
507 %float_ptr = OpTypePointer Private %float
508 %init_val = OpConstant %float 1.0
509 %1 = OpVariable %float_ptr Private %init_val
510 %void = OpTypeVoid
511 %functy = OpTypeFunction %void
512 %func = OpFunction %void None %functy
513 %2 = OpLabel
514 OpReturn
515 OpFunctionEnd
516 )";
517 CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
518 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
519 }
520
TEST_F(ValidateMemory,VulkanInitializerWithDisallowedStorageClassesBad)521 TEST_F(ValidateMemory, VulkanInitializerWithDisallowedStorageClassesBad) {
522 std::string spirv = R"(
523 OpCapability Shader
524 OpMemoryModel Logical GLSL450
525 OpEntryPoint Fragment %func "func"
526 OpExecutionMode %func OriginUpperLeft
527 %float = OpTypeFloat 32
528 %float_ptr = OpTypePointer Input %float
529 %init_val = OpConstant %float 1.0
530 %1 = OpVariable %float_ptr Input %init_val
531 %void = OpTypeVoid
532 %functy = OpTypeFunction %void
533 %func = OpFunction %void None %functy
534 %2 = OpLabel
535 OpReturn
536 OpFunctionEnd
537 )";
538 CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
539 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
540 EXPECT_THAT(
541 getDiagnosticString(),
542 HasSubstr(
543 "OpVariable, <id> '5[%5]', has a disallowed initializer & storage "
544 "class combination.\nFrom Vulkan spec, Appendix A:\n"
545 "Variable declarations that include initializers must have one of "
546 "the following storage classes: Output, Private, or Function\n "
547 "%5 = OpVariable %_ptr_Input_float Input %float_1\n"));
548 }
549
TEST_F(ValidateMemory,ArrayLenCorrectResultType)550 TEST_F(ValidateMemory, ArrayLenCorrectResultType) {
551 std::string spirv = R"(
552 OpCapability Shader
553 OpMemoryModel Logical GLSL450
554 OpEntryPoint Fragment %1 "main"
555 OpExecutionMode %1 OriginUpperLeft
556 %void = OpTypeVoid
557 %3 = OpTypeFunction %void
558 %float = OpTypeFloat 32
559 %uint = OpTypeInt 32 0
560 %_runtimearr_float = OpTypeRuntimeArray %float
561 %_struct_7 = OpTypeStruct %_runtimearr_float
562 %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
563 %1 = OpFunction %void None %3
564 %9 = OpLabel
565 %10 = OpVariable %_ptr_Function__struct_7 Function
566 %11 = OpArrayLength %uint %10 0
567 OpReturn
568 OpFunctionEnd
569
570 )";
571
572 CompileSuccessfully(spirv.c_str());
573 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
574 }
575
TEST_F(ValidateMemory,ArrayLenIndexCorrectWith2Members)576 TEST_F(ValidateMemory, ArrayLenIndexCorrectWith2Members) {
577 std::string spirv = R"(
578 OpCapability Shader
579 OpMemoryModel Logical GLSL450
580 OpEntryPoint Fragment %1 "main"
581 OpExecutionMode %1 OriginUpperLeft
582 %void = OpTypeVoid
583 %3 = OpTypeFunction %void
584 %float = OpTypeFloat 32
585 %uint = OpTypeInt 32 0
586 %_runtimearr_float = OpTypeRuntimeArray %float
587 %_struct_7 = OpTypeStruct %float %_runtimearr_float
588 %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
589 %1 = OpFunction %void None %3
590 %9 = OpLabel
591 %10 = OpVariable %_ptr_Function__struct_7 Function
592 %11 = OpArrayLength %uint %10 1
593 OpReturn
594 OpFunctionEnd
595
596 )";
597
598 CompileSuccessfully(spirv.c_str());
599 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
600 }
601
TEST_F(ValidateMemory,ArrayLenResultNotIntType)602 TEST_F(ValidateMemory, ArrayLenResultNotIntType) {
603 std::string spirv = R"(
604 OpCapability Shader
605 OpMemoryModel Logical GLSL450
606 OpEntryPoint Fragment %1 "main"
607 OpExecutionMode %1 OriginUpperLeft
608 %void = OpTypeVoid
609 %3 = OpTypeFunction %void
610 %float = OpTypeFloat 32
611 %_runtimearr_float = OpTypeRuntimeArray %float
612 %_struct_6 = OpTypeStruct %_runtimearr_float
613 %_ptr_Function__struct_6 = OpTypePointer Function %_struct_6
614 %1 = OpFunction %void None %3
615 %8 = OpLabel
616 %9 = OpVariable %_ptr_Function__struct_6 Function
617 %10 = OpArrayLength %float %9 0
618 OpReturn
619 OpFunctionEnd
620 )";
621
622 CompileSuccessfully(spirv.c_str());
623 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
624 EXPECT_THAT(
625 getDiagnosticString(),
626 HasSubstr(
627 "The Result Type of OpArrayLength <id> '10[%10]' must be OpTypeInt "
628 "with width 32 and signedness 0.\n %10 = OpArrayLength %float %9 "
629 "0\n"));
630 }
631
TEST_F(ValidateMemory,ArrayLenResultNot32bits)632 TEST_F(ValidateMemory, ArrayLenResultNot32bits) {
633 std::string spirv = R"(
634 OpCapability Shader
635 OpCapability Int16
636 OpMemoryModel Logical GLSL450
637 OpEntryPoint Fragment %1 "main"
638 OpExecutionMode %1 OriginUpperLeft
639 %void = OpTypeVoid
640 %3 = OpTypeFunction %void
641 %float = OpTypeFloat 32
642 %ushort = OpTypeInt 16 0
643 %_runtimearr_float = OpTypeRuntimeArray %float
644 %_struct_7 = OpTypeStruct %_runtimearr_float
645 %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
646 %1 = OpFunction %void None %3
647 %9 = OpLabel
648 %10 = OpVariable %_ptr_Function__struct_7 Function
649 %11 = OpArrayLength %ushort %10 0
650 OpReturn
651 OpFunctionEnd
652
653 )";
654
655 CompileSuccessfully(spirv.c_str());
656 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
657 EXPECT_THAT(
658 getDiagnosticString(),
659 HasSubstr(
660 "The Result Type of OpArrayLength <id> '11[%11]' must be OpTypeInt "
661 "with width 32 and signedness 0.\n %11 = OpArrayLength %ushort %10 "
662 "0\n"));
663 }
664
TEST_F(ValidateMemory,ArrayLenResultSigned)665 TEST_F(ValidateMemory, ArrayLenResultSigned) {
666 std::string spirv = R"(
667 OpCapability Shader
668 OpMemoryModel Logical GLSL450
669 OpEntryPoint Fragment %1 "main"
670 OpExecutionMode %1 OriginUpperLeft
671 %void = OpTypeVoid
672 %3 = OpTypeFunction %void
673 %float = OpTypeFloat 32
674 %int = OpTypeInt 32 1
675 %_runtimearr_float = OpTypeRuntimeArray %float
676 %_struct_7 = OpTypeStruct %_runtimearr_float
677 %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
678 %1 = OpFunction %void None %3
679 %9 = OpLabel
680 %10 = OpVariable %_ptr_Function__struct_7 Function
681 %11 = OpArrayLength %int %10 0
682 OpReturn
683 OpFunctionEnd
684
685 )";
686
687 CompileSuccessfully(spirv.c_str());
688 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
689 EXPECT_THAT(
690 getDiagnosticString(),
691 HasSubstr(
692 "The Result Type of OpArrayLength <id> '11[%11]' must be OpTypeInt "
693 "with width 32 and signedness 0.\n %11 = OpArrayLength %int %10 "
694 "0\n"));
695 }
696
TEST_F(ValidateMemory,ArrayLenInputNotStruct)697 TEST_F(ValidateMemory, ArrayLenInputNotStruct) {
698 std::string spirv = R"(
699 OpCapability Shader
700 OpMemoryModel Logical GLSL450
701 OpEntryPoint Fragment %1 "main"
702 OpExecutionMode %1 OriginUpperLeft
703 %void = OpTypeVoid
704 %3 = OpTypeFunction %void
705 %float = OpTypeFloat 32
706 %uint = OpTypeInt 32 0
707 %_runtimearr_float = OpTypeRuntimeArray %float
708 %_struct_7 = OpTypeStruct %_runtimearr_float
709 %_ptr_Function_float = OpTypePointer Function %float
710 %1 = OpFunction %void None %3
711 %9 = OpLabel
712 %10 = OpVariable %_ptr_Function_float Function
713 %11 = OpArrayLength %uint %10 0
714 OpReturn
715 OpFunctionEnd
716
717 )";
718
719 CompileSuccessfully(spirv.c_str());
720 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
721 EXPECT_THAT(getDiagnosticString(),
722 HasSubstr("The Struture's type in OpArrayLength <id> '11[%11]' "
723 "must be a pointer to an OpTypeStruct."));
724 }
725
TEST_F(ValidateMemory,ArrayLenInputLastMemberNoRTA)726 TEST_F(ValidateMemory, ArrayLenInputLastMemberNoRTA) {
727 std::string spirv = R"(
728 OpCapability Shader
729 OpMemoryModel Logical GLSL450
730 OpEntryPoint Fragment %1 "main"
731 OpExecutionMode %1 OriginUpperLeft
732 %void = OpTypeVoid
733 %3 = OpTypeFunction %void
734 %float = OpTypeFloat 32
735 %uint = OpTypeInt 32 0
736 %_runtimearr_float = OpTypeRuntimeArray %float
737 %_struct_7 = OpTypeStruct %float
738 %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
739 %1 = OpFunction %void None %3
740 %9 = OpLabel
741 %10 = OpVariable %_ptr_Function__struct_7 Function
742 %11 = OpArrayLength %uint %10 0
743 OpReturn
744 OpFunctionEnd
745
746 )";
747
748 CompileSuccessfully(spirv.c_str());
749 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
750 EXPECT_THAT(
751 getDiagnosticString(),
752 HasSubstr("The Struture's last member in OpArrayLength <id> '11[%11]' "
753 "must be an OpTypeRuntimeArray.\n %11 = OpArrayLength %uint "
754 "%10 0\n"));
755 }
756
TEST_F(ValidateMemory,ArrayLenInputLastMemberNoRTA2)757 TEST_F(ValidateMemory, ArrayLenInputLastMemberNoRTA2) {
758 std::string spirv = R"(
759 OpCapability Shader
760 OpMemoryModel Logical GLSL450
761 OpEntryPoint Fragment %1 "main"
762 OpExecutionMode %1 OriginUpperLeft
763 %void = OpTypeVoid
764 %3 = OpTypeFunction %void
765 %float = OpTypeFloat 32
766 %uint = OpTypeInt 32 0
767 %_runtimearr_float = OpTypeRuntimeArray %float
768 %_struct_7 = OpTypeStruct %_runtimearr_float %float
769 %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
770 %1 = OpFunction %void None %3
771 %9 = OpLabel
772 %10 = OpVariable %_ptr_Function__struct_7 Function
773 %11 = OpArrayLength %uint %10 1
774 OpReturn
775 OpFunctionEnd
776
777 )";
778
779 CompileSuccessfully(spirv.c_str());
780 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
781 EXPECT_THAT(
782 getDiagnosticString(),
783 HasSubstr("The Struture's last member in OpArrayLength <id> '11[%11]' "
784 "must be an OpTypeRuntimeArray.\n %11 = OpArrayLength %uint "
785 "%10 1\n"));
786 }
787
TEST_F(ValidateMemory,ArrayLenIndexNotLastMember)788 TEST_F(ValidateMemory, ArrayLenIndexNotLastMember) {
789 std::string spirv = R"(
790 OpCapability Shader
791 OpMemoryModel Logical GLSL450
792 OpEntryPoint Fragment %1 "main"
793 OpExecutionMode %1 OriginUpperLeft
794 %void = OpTypeVoid
795 %3 = OpTypeFunction %void
796 %float = OpTypeFloat 32
797 %uint = OpTypeInt 32 0
798 %_runtimearr_float = OpTypeRuntimeArray %float
799 %_struct_7 = OpTypeStruct %float %_runtimearr_float
800 %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
801 %1 = OpFunction %void None %3
802 %9 = OpLabel
803 %10 = OpVariable %_ptr_Function__struct_7 Function
804 %11 = OpArrayLength %uint %10 0
805 OpReturn
806 OpFunctionEnd
807
808 )";
809
810 CompileSuccessfully(spirv.c_str());
811 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
812 EXPECT_THAT(
813 getDiagnosticString(),
814 HasSubstr(
815 "The array member in OpArrayLength <id> '11[%11]' must be an the "
816 "last member of the struct.\n %11 = OpArrayLength %uint %10 0\n"));
817 }
818
TEST_F(ValidateMemory,ArrayLenIndexNotPointerToStruct)819 TEST_F(ValidateMemory, ArrayLenIndexNotPointerToStruct) {
820 std::string spirv = R"(
821 OpCapability Shader
822 OpMemoryModel Logical GLSL450
823 OpEntryPoint Fragment %1 "main"
824 OpExecutionMode %1 OriginUpperLeft
825 %void = OpTypeVoid
826 %3 = OpTypeFunction %void
827 %float = OpTypeFloat 32
828 %uint = OpTypeInt 32 0
829 %_runtimearr_float = OpTypeRuntimeArray %float
830 %_struct_7 = OpTypeStruct %float %_runtimearr_float
831 %_ptr_Function__struct_7 = OpTypePointer Function %_struct_7
832 %1 = OpFunction %void None %3
833 %9 = OpLabel
834 %10 = OpVariable %_ptr_Function__struct_7 Function
835 %11 = OpLoad %_struct_7 %10
836 %12 = OpArrayLength %uint %11 0
837 OpReturn
838 OpFunctionEnd
839
840 )";
841
842 CompileSuccessfully(spirv.c_str());
843 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
844 EXPECT_THAT(
845 getDiagnosticString(),
846 HasSubstr(
847 "The Struture's type in OpArrayLength <id> '12[%12]' must be a "
848 "pointer to an OpTypeStruct.\n %12 = OpArrayLength %uint %11 0\n"));
849 }
850
TEST_F(ValidateMemory,ArrayLenPointerIsAType)851 TEST_F(ValidateMemory, ArrayLenPointerIsAType) {
852 std::string spirv = R"(
853 OpCapability Shader
854 OpMemoryModel Logical GLSL450
855 OpEntryPoint Fragment %1 "main"
856 OpExecutionMode %1 OriginUpperLeft
857 %void = OpTypeVoid
858 %3 = OpTypeFunction %void
859 %float = OpTypeFloat 32
860 %uint = OpTypeInt 32 0
861 %1 = OpFunction %void None %3
862 %9 = OpLabel
863 %12 = OpArrayLength %uint %float 0
864 OpReturn
865 OpFunctionEnd
866
867 )";
868
869 CompileSuccessfully(spirv.c_str());
870 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
871 EXPECT_THAT(getDiagnosticString(), HasSubstr("Operand 4[%float] cannot be a "
872 "type"));
873 }
874
TEST_F(ValidateMemory,PushConstantNotStructGood)875 TEST_F(ValidateMemory, PushConstantNotStructGood) {
876 std::string spirv = R"(
877 OpCapability Shader
878 OpMemoryModel Logical GLSL450
879 OpEntryPoint Fragment %1 "main"
880 OpExecutionMode %1 OriginUpperLeft
881
882 %void = OpTypeVoid
883 %voidfn = OpTypeFunction %void
884 %float = OpTypeFloat 32
885 %ptr = OpTypePointer PushConstant %float
886 %pc = OpVariable %ptr PushConstant
887
888 %1 = OpFunction %void None %voidfn
889 %label = OpLabel
890 OpReturn
891 OpFunctionEnd
892 )";
893 CompileSuccessfully(spirv);
894 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
895 }
896
TEST_F(ValidateMemory,VulkanPushConstantNotStructBad)897 TEST_F(ValidateMemory, VulkanPushConstantNotStructBad) {
898 std::string spirv = R"(
899 OpCapability Shader
900 OpMemoryModel Logical GLSL450
901 OpEntryPoint Fragment %1 "main"
902 OpExecutionMode %1 OriginUpperLeft
903
904 %void = OpTypeVoid
905 %voidfn = OpTypeFunction %void
906 %float = OpTypeFloat 32
907 %ptr = OpTypePointer PushConstant %float
908 %pc = OpVariable %ptr PushConstant
909
910 %1 = OpFunction %void None %voidfn
911 %label = OpLabel
912 OpReturn
913 OpFunctionEnd
914 )";
915 CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
916 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
917 EXPECT_THAT(getDiagnosticString(),
918 HasSubstr("PushConstant OpVariable <id> '6[%6]' has illegal "
919 "type.\nFrom Vulkan spec, section 14.5.1:\n"
920 "Such variables must be typed as OpTypeStruct, "
921 "or an array of this type"));
922 }
923
TEST_F(ValidateMemory,VulkanPushConstant)924 TEST_F(ValidateMemory, VulkanPushConstant) {
925 std::string spirv = R"(
926 OpCapability Shader
927 OpMemoryModel Logical GLSL450
928 OpEntryPoint Fragment %1 "main"
929 OpExecutionMode %1 OriginUpperLeft
930
931 OpDecorate %struct Block
932 OpMemberDecorate %struct 0 Offset 0
933
934 %void = OpTypeVoid
935 %voidfn = OpTypeFunction %void
936 %float = OpTypeFloat 32
937 %struct = OpTypeStruct %float
938 %ptr = OpTypePointer PushConstant %struct
939 %pc = OpVariable %ptr PushConstant
940
941 %1 = OpFunction %void None %voidfn
942 %label = OpLabel
943 OpReturn
944 OpFunctionEnd
945 )";
946 CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
947 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
948 }
949
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeLoadBad1)950 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadBad1) {
951 const std::string spirv = R"(
952 OpCapability Shader
953 OpCapability VulkanMemoryModelKHR
954 OpCapability Linkage
955 OpExtension "SPV_KHR_vulkan_memory_model"
956 OpMemoryModel Logical VulkanKHR
957 %void = OpTypeVoid
958 %int = OpTypeInt 32 0
959 %device = OpConstant %int 1
960 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
961 %var = OpVariable %int_ptr_ssbo StorageBuffer
962 %voidfn = OpTypeFunction %void
963 %func = OpFunction %void None %voidfn
964 %entry = OpLabel
965 %load = OpLoad %int %var MakePointerVisibleKHR|NonPrivatePointerKHR %device
966 OpReturn
967 OpFunctionEnd
968 )";
969
970 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
971 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
972 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
973 EXPECT_THAT(
974 getDiagnosticString(),
975 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
976 "VulkanMemoryModelDeviceScopeKHR capability"));
977 }
978
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeLoadBad2)979 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadBad2) {
980 const std::string spirv = R"(
981 OpCapability Shader
982 OpCapability VulkanMemoryModelKHR
983 OpCapability Linkage
984 OpExtension "SPV_KHR_vulkan_memory_model"
985 OpMemoryModel Logical VulkanKHR
986 %void = OpTypeVoid
987 %int = OpTypeInt 32 0
988 %device = OpConstant %int 1
989 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
990 %var = OpVariable %int_ptr_ssbo StorageBuffer
991 %voidfn = OpTypeFunction %void
992 %func = OpFunction %void None %voidfn
993 %entry = OpLabel
994 %load = OpLoad %int %var Aligned|MakePointerVisibleKHR|NonPrivatePointerKHR 4 %device
995 OpReturn
996 OpFunctionEnd
997 )";
998
999 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1000 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1001 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1002 EXPECT_THAT(
1003 getDiagnosticString(),
1004 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1005 "VulkanMemoryModelDeviceScopeKHR capability"));
1006 }
1007
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeLoadGood1)1008 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadGood1) {
1009 const std::string spirv = R"(
1010 OpCapability Shader
1011 OpCapability VulkanMemoryModelKHR
1012 OpCapability VulkanMemoryModelDeviceScopeKHR
1013 OpCapability Linkage
1014 OpExtension "SPV_KHR_vulkan_memory_model"
1015 OpMemoryModel Logical VulkanKHR
1016 %void = OpTypeVoid
1017 %int = OpTypeInt 32 0
1018 %device = OpConstant %int 1
1019 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1020 %var = OpVariable %int_ptr_ssbo StorageBuffer
1021 %voidfn = OpTypeFunction %void
1022 %func = OpFunction %void None %voidfn
1023 %entry = OpLabel
1024 %load = OpLoad %int %var MakePointerVisibleKHR|NonPrivatePointerKHR %device
1025 OpReturn
1026 OpFunctionEnd
1027 )";
1028
1029 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1030 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1031 }
1032
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeLoadGood2)1033 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeLoadGood2) {
1034 const std::string spirv = R"(
1035 OpCapability Shader
1036 OpCapability VulkanMemoryModelKHR
1037 OpCapability VulkanMemoryModelDeviceScopeKHR
1038 OpCapability Linkage
1039 OpExtension "SPV_KHR_vulkan_memory_model"
1040 OpMemoryModel Logical VulkanKHR
1041 %void = OpTypeVoid
1042 %int = OpTypeInt 32 0
1043 %device = OpConstant %int 1
1044 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1045 %var = OpVariable %int_ptr_ssbo StorageBuffer
1046 %voidfn = OpTypeFunction %void
1047 %func = OpFunction %void None %voidfn
1048 %entry = OpLabel
1049 %load = OpLoad %int %var Aligned|MakePointerVisibleKHR|NonPrivatePointerKHR 4 %device
1050 OpReturn
1051 OpFunctionEnd
1052 )";
1053
1054 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1055 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1056 }
1057
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeStoreBad1)1058 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreBad1) {
1059 const std::string spirv = R"(
1060 OpCapability Shader
1061 OpCapability VulkanMemoryModelKHR
1062 OpCapability Linkage
1063 OpExtension "SPV_KHR_vulkan_memory_model"
1064 OpMemoryModel Logical VulkanKHR
1065 %void = OpTypeVoid
1066 %int = OpTypeInt 32 0
1067 %device = OpConstant %int 1
1068 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1069 %var = OpVariable %int_ptr_ssbo StorageBuffer
1070 %voidfn = OpTypeFunction %void
1071 %func = OpFunction %void None %voidfn
1072 %entry = OpLabel
1073 OpStore %var %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
1074 OpReturn
1075 OpFunctionEnd
1076 )";
1077
1078 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1079 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1080 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1081 EXPECT_THAT(
1082 getDiagnosticString(),
1083 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1084 "VulkanMemoryModelDeviceScopeKHR capability"));
1085 }
1086
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeStoreBad2)1087 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreBad2) {
1088 const std::string spirv = R"(
1089 OpCapability Shader
1090 OpCapability VulkanMemoryModelKHR
1091 OpCapability Linkage
1092 OpExtension "SPV_KHR_vulkan_memory_model"
1093 OpMemoryModel Logical VulkanKHR
1094 %void = OpTypeVoid
1095 %int = OpTypeInt 32 0
1096 %device = OpConstant %int 1
1097 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1098 %var = OpVariable %int_ptr_ssbo StorageBuffer
1099 %voidfn = OpTypeFunction %void
1100 %func = OpFunction %void None %voidfn
1101 %entry = OpLabel
1102 OpStore %var %device Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device
1103 OpReturn
1104 OpFunctionEnd
1105 )";
1106
1107 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1108 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1109 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1110 EXPECT_THAT(
1111 getDiagnosticString(),
1112 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1113 "VulkanMemoryModelDeviceScopeKHR capability"));
1114 }
1115
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeStoreGood1)1116 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreGood1) {
1117 const std::string spirv = R"(
1118 OpCapability Shader
1119 OpCapability VulkanMemoryModelKHR
1120 OpCapability VulkanMemoryModelDeviceScopeKHR
1121 OpCapability Linkage
1122 OpExtension "SPV_KHR_vulkan_memory_model"
1123 OpMemoryModel Logical VulkanKHR
1124 %void = OpTypeVoid
1125 %int = OpTypeInt 32 0
1126 %device = OpConstant %int 1
1127 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1128 %var = OpVariable %int_ptr_ssbo StorageBuffer
1129 %voidfn = OpTypeFunction %void
1130 %func = OpFunction %void None %voidfn
1131 %entry = OpLabel
1132 OpStore %var %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
1133 OpReturn
1134 OpFunctionEnd
1135 )";
1136
1137 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1138 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1139 }
1140
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeStoreGood2)1141 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeStoreGood2) {
1142 const std::string spirv = R"(
1143 OpCapability Shader
1144 OpCapability VulkanMemoryModelKHR
1145 OpCapability VulkanMemoryModelDeviceScopeKHR
1146 OpCapability Linkage
1147 OpExtension "SPV_KHR_vulkan_memory_model"
1148 OpMemoryModel Logical VulkanKHR
1149 %void = OpTypeVoid
1150 %int = OpTypeInt 32 0
1151 %device = OpConstant %int 1
1152 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1153 %var = OpVariable %int_ptr_ssbo StorageBuffer
1154 %voidfn = OpTypeFunction %void
1155 %func = OpFunction %void None %voidfn
1156 %entry = OpLabel
1157 OpStore %var %device Aligned|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device
1158 OpReturn
1159 OpFunctionEnd
1160 )";
1161
1162 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1163 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1164 }
1165
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemoryBad1)1166 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad1) {
1167 const std::string spirv = R"(
1168 OpCapability Shader
1169 OpCapability VulkanMemoryModelKHR
1170 OpCapability Linkage
1171 OpExtension "SPV_KHR_vulkan_memory_model"
1172 OpMemoryModel Logical VulkanKHR
1173 %void = OpTypeVoid
1174 %int = OpTypeInt 32 0
1175 %device = OpConstant %int 1
1176 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1177 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1178 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1179 %voidfn = OpTypeFunction %void
1180 %func = OpFunction %void None %voidfn
1181 %entry = OpLabel
1182 OpCopyMemory %var1 %var2 MakePointerAvailableKHR|NonPrivatePointerKHR %device
1183 OpReturn
1184 OpFunctionEnd
1185 )";
1186
1187 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1188 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1189 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1190 EXPECT_THAT(
1191 getDiagnosticString(),
1192 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1193 "VulkanMemoryModelDeviceScopeKHR capability"));
1194 }
1195
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemoryBad2)1196 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad2) {
1197 const std::string spirv = R"(
1198 OpCapability Shader
1199 OpCapability VulkanMemoryModelKHR
1200 OpCapability Linkage
1201 OpExtension "SPV_KHR_vulkan_memory_model"
1202 OpMemoryModel Logical VulkanKHR
1203 %void = OpTypeVoid
1204 %int = OpTypeInt 32 0
1205 %device = OpConstant %int 1
1206 %workgroup = OpConstant %int 1
1207 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1208 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1209 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1210 %voidfn = OpTypeFunction %void
1211 %func = OpFunction %void None %voidfn
1212 %entry = OpLabel
1213 OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
1214 OpReturn
1215 OpFunctionEnd
1216 )";
1217
1218 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1219 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1220 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1221 EXPECT_THAT(
1222 getDiagnosticString(),
1223 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1224 "VulkanMemoryModelDeviceScopeKHR capability"));
1225 }
1226
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemoryBad3)1227 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryBad3) {
1228 const std::string spirv = R"(
1229 OpCapability Shader
1230 OpCapability VulkanMemoryModelKHR
1231 OpCapability Linkage
1232 OpExtension "SPV_KHR_vulkan_memory_model"
1233 OpMemoryModel Logical VulkanKHR
1234 %void = OpTypeVoid
1235 %int = OpTypeInt 32 0
1236 %device = OpConstant %int 1
1237 %workgroup = OpConstant %int 1
1238 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1239 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1240 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1241 %voidfn = OpTypeFunction %void
1242 %func = OpFunction %void None %voidfn
1243 %entry = OpLabel
1244 OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
1245 OpReturn
1246 OpFunctionEnd
1247 )";
1248
1249 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1250 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1251 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1252 EXPECT_THAT(
1253 getDiagnosticString(),
1254 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1255 "VulkanMemoryModelDeviceScopeKHR capability"));
1256 }
1257
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemoryGood1)1258 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryGood1) {
1259 const std::string spirv = R"(
1260 OpCapability Shader
1261 OpCapability VulkanMemoryModelKHR
1262 OpCapability VulkanMemoryModelDeviceScopeKHR
1263 OpCapability Linkage
1264 OpExtension "SPV_KHR_vulkan_memory_model"
1265 OpMemoryModel Logical VulkanKHR
1266 %void = OpTypeVoid
1267 %int = OpTypeInt 32 0
1268 %device = OpConstant %int 1
1269 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1270 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1271 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1272 %voidfn = OpTypeFunction %void
1273 %func = OpFunction %void None %voidfn
1274 %entry = OpLabel
1275 OpCopyMemory %var1 %var2 MakePointerAvailableKHR|NonPrivatePointerKHR %device
1276 OpReturn
1277 OpFunctionEnd
1278 )";
1279
1280 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1281 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1282 }
1283
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemoryGood2)1284 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryGood2) {
1285 const std::string spirv = R"(
1286 OpCapability Shader
1287 OpCapability VulkanMemoryModelKHR
1288 OpCapability VulkanMemoryModelDeviceScopeKHR
1289 OpCapability Linkage
1290 OpExtension "SPV_KHR_vulkan_memory_model"
1291 OpMemoryModel Logical VulkanKHR
1292 %void = OpTypeVoid
1293 %int = OpTypeInt 32 0
1294 %device = OpConstant %int 1
1295 %workgroup = OpConstant %int 2
1296 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1297 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1298 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1299 %voidfn = OpTypeFunction %void
1300 %func = OpFunction %void None %voidfn
1301 %entry = OpLabel
1302 OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
1303 OpReturn
1304 OpFunctionEnd
1305 )";
1306
1307 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1308 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1309 }
1310
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemoryGood3)1311 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemoryGood3) {
1312 const std::string spirv = R"(
1313 OpCapability Shader
1314 OpCapability VulkanMemoryModelKHR
1315 OpCapability VulkanMemoryModelDeviceScopeKHR
1316 OpCapability Linkage
1317 OpExtension "SPV_KHR_vulkan_memory_model"
1318 OpMemoryModel Logical VulkanKHR
1319 %void = OpTypeVoid
1320 %int = OpTypeInt 32 0
1321 %device = OpConstant %int 1
1322 %workgroup = OpConstant %int 2
1323 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1324 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1325 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1326 %voidfn = OpTypeFunction %void
1327 %func = OpFunction %void None %voidfn
1328 %entry = OpLabel
1329 OpCopyMemory %var1 %var2 Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
1330 OpReturn
1331 OpFunctionEnd
1332 )";
1333
1334 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1335 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1336 }
1337
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemorySizedBad1)1338 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad1) {
1339 const std::string spirv = R"(
1340 OpCapability Shader
1341 OpCapability VulkanMemoryModelKHR
1342 OpCapability Linkage
1343 OpCapability Addresses
1344 OpExtension "SPV_KHR_vulkan_memory_model"
1345 OpMemoryModel Logical VulkanKHR
1346 %void = OpTypeVoid
1347 %int = OpTypeInt 32 0
1348 %device = OpConstant %int 1
1349 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1350 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1351 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1352 %voidfn = OpTypeFunction %void
1353 %func = OpFunction %void None %voidfn
1354 %entry = OpLabel
1355 OpCopyMemorySized %var1 %var2 %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
1356 OpReturn
1357 OpFunctionEnd
1358 )";
1359
1360 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1361 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1362 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1363 EXPECT_THAT(
1364 getDiagnosticString(),
1365 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1366 "VulkanMemoryModelDeviceScopeKHR capability"));
1367 }
1368
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemorySizedBad2)1369 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad2) {
1370 const std::string spirv = R"(
1371 OpCapability Shader
1372 OpCapability VulkanMemoryModelKHR
1373 OpCapability Linkage
1374 OpCapability Addresses
1375 OpExtension "SPV_KHR_vulkan_memory_model"
1376 OpMemoryModel Logical VulkanKHR
1377 %void = OpTypeVoid
1378 %int = OpTypeInt 32 0
1379 %device = OpConstant %int 1
1380 %workgroup = OpConstant %int 1
1381 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1382 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1383 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1384 %voidfn = OpTypeFunction %void
1385 %func = OpFunction %void None %voidfn
1386 %entry = OpLabel
1387 OpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
1388 OpReturn
1389 OpFunctionEnd
1390 )";
1391
1392 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1393 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1394 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1395 EXPECT_THAT(
1396 getDiagnosticString(),
1397 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1398 "VulkanMemoryModelDeviceScopeKHR capability"));
1399 }
1400
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemorySizedBad3)1401 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedBad3) {
1402 const std::string spirv = R"(
1403 OpCapability Shader
1404 OpCapability VulkanMemoryModelKHR
1405 OpCapability Linkage
1406 OpCapability Addresses
1407 OpExtension "SPV_KHR_vulkan_memory_model"
1408 OpMemoryModel Logical VulkanKHR
1409 %void = OpTypeVoid
1410 %int = OpTypeInt 32 0
1411 %device = OpConstant %int 1
1412 %workgroup = OpConstant %int 1
1413 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1414 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1415 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1416 %voidfn = OpTypeFunction %void
1417 %func = OpFunction %void None %voidfn
1418 %entry = OpLabel
1419 OpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
1420 OpReturn
1421 OpFunctionEnd
1422 )";
1423
1424 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1425 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
1426 ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1427 EXPECT_THAT(
1428 getDiagnosticString(),
1429 HasSubstr("Use of device scope with VulkanKHR memory model requires the "
1430 "VulkanMemoryModelDeviceScopeKHR capability"));
1431 }
1432
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemorySizedGood1)1433 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood1) {
1434 const std::string spirv = R"(
1435 OpCapability Shader
1436 OpCapability VulkanMemoryModelKHR
1437 OpCapability VulkanMemoryModelDeviceScopeKHR
1438 OpCapability Linkage
1439 OpCapability Addresses
1440 OpExtension "SPV_KHR_vulkan_memory_model"
1441 OpMemoryModel Logical VulkanKHR
1442 %void = OpTypeVoid
1443 %int = OpTypeInt 32 0
1444 %device = OpConstant %int 1
1445 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1446 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1447 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1448 %voidfn = OpTypeFunction %void
1449 %func = OpFunction %void None %voidfn
1450 %entry = OpLabel
1451 OpCopyMemorySized %var1 %var2 %device MakePointerAvailableKHR|NonPrivatePointerKHR %device
1452 OpReturn
1453 OpFunctionEnd
1454 )";
1455
1456 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1457 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1458 }
1459
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemorySizedGood2)1460 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood2) {
1461 const std::string spirv = R"(
1462 OpCapability Shader
1463 OpCapability VulkanMemoryModelKHR
1464 OpCapability VulkanMemoryModelDeviceScopeKHR
1465 OpCapability Linkage
1466 OpCapability Addresses
1467 OpExtension "SPV_KHR_vulkan_memory_model"
1468 OpMemoryModel Logical VulkanKHR
1469 %void = OpTypeVoid
1470 %int = OpTypeInt 32 0
1471 %device = OpConstant %int 1
1472 %workgroup = OpConstant %int 2
1473 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1474 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1475 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1476 %voidfn = OpTypeFunction %void
1477 %func = OpFunction %void None %voidfn
1478 %entry = OpLabel
1479 OpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %device %workgroup
1480 OpReturn
1481 OpFunctionEnd
1482 )";
1483
1484 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1485 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1486 }
1487
TEST_F(ValidateMemory,VulkanMemoryModelDeviceScopeCopyMemorySizedGood3)1488 TEST_F(ValidateMemory, VulkanMemoryModelDeviceScopeCopyMemorySizedGood3) {
1489 const std::string spirv = R"(
1490 OpCapability Shader
1491 OpCapability VulkanMemoryModelKHR
1492 OpCapability VulkanMemoryModelDeviceScopeKHR
1493 OpCapability Linkage
1494 OpCapability Addresses
1495 OpExtension "SPV_KHR_vulkan_memory_model"
1496 OpMemoryModel Logical VulkanKHR
1497 %void = OpTypeVoid
1498 %int = OpTypeInt 32 0
1499 %device = OpConstant %int 1
1500 %workgroup = OpConstant %int 2
1501 %int_ptr_ssbo = OpTypePointer StorageBuffer %int
1502 %var1 = OpVariable %int_ptr_ssbo StorageBuffer
1503 %var2 = OpVariable %int_ptr_ssbo StorageBuffer
1504 %voidfn = OpTypeFunction %void
1505 %func = OpFunction %void None %voidfn
1506 %entry = OpLabel
1507 OpCopyMemorySized %var1 %var2 %device Aligned|MakePointerVisibleKHR|MakePointerAvailableKHR|NonPrivatePointerKHR 4 %workgroup %device
1508 OpReturn
1509 OpFunctionEnd
1510 )";
1511
1512 CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
1513 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
1514 }
1515
1516 } // namespace
1517 } // namespace val
1518 } // namespace spvtools
1519