1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2018 Google Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief SPIR-V Assembly Tests for pointers as function parameters.
22 *//*--------------------------------------------------------------------*/
24 #include "vktSpvAsmPointerParameterTests.hpp"
25 #include "vktSpvAsmComputeShaderCase.hpp"
26 #include "vktSpvAsmComputeShaderTestUtil.hpp"
27 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
31 namespace SpirVAssembly
45 void addComputePointerParamToParamTest (tcu::TestCaseGroup* group)
47 tcu::TestContext& testCtx = group->getTestContext();
48 const int numFloats = 128;
49 ComputeShaderSpec spec;
50 vector<float> expectedOutput;
52 // Implements the following pseudo GLSL shader:
54 // float func(alias float* f, alias float* g)
64 // o = func(&a, &a); // should return 2.0
66 // o += func(&a, &b); // should return 5.0
68 const string shaderSource =
69 " OpCapability Shader\n"
70 " %1 = OpExtInstImport \"GLSL.std.450\"\n"
71 " OpMemoryModel Logical GLSL450\n"
72 " OpEntryPoint GLCompute %main \"main\" %gl_GlobalInvocationID\n"
73 " OpExecutionMode %main LocalSize 1 1 1\n"
74 " OpSource GLSL 430\n"
75 " OpDecorate %_arr_float_uint_128 ArrayStride 4\n"
76 " OpMemberDecorate %Output 0 Offset 0\n"
77 " OpDecorate %Output BufferBlock\n"
78 " OpDecorate %dataOutput DescriptorSet 0\n"
79 " OpDecorate %dataOutput Binding 0\n"
80 " OpDecorate %f Aliased\n"
81 " OpDecorate %g Aliased\n"
82 " OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId\n"
83 " %void = OpTypeVoid\n"
84 " %void_func = OpTypeFunction %void\n"
85 " %float = OpTypeFloat 32\n"
86 " %_ptr_Function_float = OpTypePointer Function %float\n"
87 " %func0_decl = OpTypeFunction %float %_ptr_Function_float %_ptr_Function_float\n"
88 " %float_0 = OpConstant %float 0\n"
89 " %float_5 = OpConstant %float 5\n"
90 " %float_2 = OpConstant %float 2\n"
91 " %uint = OpTypeInt 32 0\n"
92 " %uint_128 = OpConstant %uint 128\n"
93 " %_arr_float_uint_128 = OpTypeArray %float %uint_128\n"
94 " %Output = OpTypeStruct %_arr_float_uint_128\n"
95 " %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
96 " %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
97 " %int = OpTypeInt 32 1\n"
98 " %int_0 = OpConstant %int 0\n"
99 " %v3uint = OpTypeVector %uint 3\n"
100 " %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
101 " %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
102 " %uint_0 = OpConstant %uint 0\n"
103 " %_ptr_Input_uint = OpTypePointer Input %uint\n"
104 " %_ptr_Uniform_float = OpTypePointer Uniform %float\n"
105 " %main = OpFunction %void None %void_func\n"
106 " %entry = OpLabel\n"
107 " %a = OpVariable %_ptr_Function_float Function %float_0\n"
108 " %b = OpVariable %_ptr_Function_float Function %float_0\n"
109 " %o = OpVariable %_ptr_Function_float Function %float_0\n"
110 " %ret0 = OpFunctionCall %float %func %a %a\n"
111 " OpStore %o %ret0\n"
112 " %ret1 = OpFunctionCall %float %func %a %b\n"
113 " %o_val = OpLoad %float %o\n"
114 " %sum = OpFAdd %float %o_val %ret1\n"
115 " %inv_id_ptr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0\n"
116 " %inv_id = OpLoad %uint %inv_id_ptr\n"
117 " %out_ptr = OpAccessChain %_ptr_Uniform_float %dataOutput %int_0 %inv_id\n"
118 " OpStore %out_ptr %sum\n"
121 " %func = OpFunction %float None %func0_decl\n"
122 " %f = OpFunctionParameter %_ptr_Function_float\n"
123 " %g = OpFunctionParameter %_ptr_Function_float\n"
124 " %func_entry = OpLabel\n"
125 " OpStore %g %float_5\n"
126 " OpStore %f %float_2\n"
127 " %ret = OpLoad %float %g\n"
128 " OpReturnValue %ret\n"
131 expectedOutput.reserve(numFloats);
132 for (deUint32 numIdx = 0; numIdx < numFloats; ++numIdx)
133 expectedOutput.push_back(7.0f);
135 spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
137 spec.assembly = shaderSource;
138 spec.numWorkGroups = IVec3(numFloats, 1, 1);
140 group->addChild(new SpvAsmComputeShaderCase(testCtx, "param_to_param", "", spec));
143 void addComputePointerParamToGlobalTest (tcu::TestCaseGroup* group)
145 tcu::TestContext& testCtx = group->getTestContext();
146 const int numFloats = 128;
147 ComputeShaderSpec spec;
148 vector<float> expectedOutput;
150 // Implements the following pseudo GLSL shader:
152 // alias float a = 0.0;
154 // float func0(alias float* f0) // f in Private storage class
161 // float func1(alias float* f1) // f in Function storage class
170 // o = func0(&a); // should return 2.0
172 // o += func1(&b); // should return 5.0
174 const string shaderSource =
175 " OpCapability Shader\n"
176 " %1 = OpExtInstImport \"GLSL.std.450\"\n"
177 " OpMemoryModel Logical GLSL450\n"
178 " OpEntryPoint GLCompute %main \"main\" %gl_GlobalInvocationID\n"
179 " OpExecutionMode %main LocalSize 1 1 1\n"
180 " OpSource GLSL 430\n"
181 " OpDecorate %_arr_float_uint_128 ArrayStride 4\n"
182 " OpMemberDecorate %Output 0 Offset 0\n"
183 " OpDecorate %Output BufferBlock\n"
184 " OpDecorate %dataOutput DescriptorSet 0\n"
185 " OpDecorate %dataOutput Binding 0\n"
186 " OpDecorate %f0 Aliased\n"
187 " OpDecorate %f1 Aliased\n"
188 " OpDecorate %a Aliased\n"
189 " OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId\n"
190 " %void = OpTypeVoid\n"
191 " %void_func = OpTypeFunction %void\n"
192 " %float = OpTypeFloat 32\n"
193 " %_ptr_Function_float = OpTypePointer Function %float\n"
194 " %_ptr_Private_float = OpTypePointer Private %float\n"
195 " %func0_decl = OpTypeFunction %float %_ptr_Private_float\n"
196 " %func1_decl = OpTypeFunction %float %_ptr_Function_float\n"
197 " %float_0 = OpConstant %float 0\n"
198 " %float_5 = OpConstant %float 5\n"
199 " %float_2 = OpConstant %float 2\n"
200 " %uint = OpTypeInt 32 0\n"
201 " %uint_128 = OpConstant %uint 128\n"
202 " %_arr_float_uint_128 = OpTypeArray %float %uint_128\n"
203 " %Output = OpTypeStruct %_arr_float_uint_128\n"
204 " %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
205 " %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
206 " %int = OpTypeInt 32 1\n"
207 " %int_0 = OpConstant %int 0\n"
208 " %v3uint = OpTypeVector %uint 3\n"
209 " %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
210 " %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
211 " %uint_0 = OpConstant %uint 0\n"
212 " %_ptr_Input_uint = OpTypePointer Input %uint\n"
213 " %_ptr_Uniform_float = OpTypePointer Uniform %float\n"
214 " %a = OpVariable %_ptr_Private_float Private %float_0\n"
215 " %main = OpFunction %void None %void_func\n"
216 " %entry = OpLabel\n"
217 " %b = OpVariable %_ptr_Function_float Function %float_0\n"
218 " %o = OpVariable %_ptr_Function_float Function %float_0\n"
219 " %ret0 = OpFunctionCall %float %func0 %a\n"
220 " OpStore %o %ret0\n"
221 " %ret1 = OpFunctionCall %float %func1 %b\n"
222 " %o_val = OpLoad %float %o\n"
223 " %sum = OpFAdd %float %o_val %ret1\n"
224 " %inv_id_ptr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0\n"
225 " %inv_id = OpLoad %uint %inv_id_ptr\n"
226 " %out_ptr = OpAccessChain %_ptr_Uniform_float %dataOutput %int_0 %inv_id\n"
227 " OpStore %out_ptr %sum\n"
230 " %func0 = OpFunction %float None %func0_decl\n"
231 " %f0 = OpFunctionParameter %_ptr_Private_float\n"
232 " %func0_entry = OpLabel\n"
233 " OpStore %a %float_5\n"
234 " OpStore %f0 %float_2\n"
235 " %func0_ret = OpLoad %float %a\n"
236 " OpReturnValue %func0_ret\n"
238 " %func1 = OpFunction %float None %func1_decl\n"
239 " %f1 = OpFunctionParameter %_ptr_Function_float\n"
240 " %func1_entry = OpLabel\n"
241 " OpStore %a %float_5\n"
242 " OpStore %f1 %float_2\n"
243 " %func1_ret = OpLoad %float %a\n"
244 " OpReturnValue %func1_ret\n"
247 expectedOutput.reserve(numFloats);
248 for (deUint32 numIdx = 0; numIdx < numFloats; ++numIdx)
249 expectedOutput.push_back(7.0f);
251 spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
253 spec.assembly = shaderSource;
254 spec.numWorkGroups = IVec3(numFloats, 1, 1);
256 group->addChild(new SpvAsmComputeShaderCase(testCtx, "param_to_global", "", spec));
259 void addComputePointerBufferMemoryTest (tcu::TestCaseGroup* group)
261 tcu::TestContext& testCtx = group->getTestContext();
262 const int numFloats = 128;
263 ComputeShaderSpec spec;
264 vector<float> expectedOutput;
266 // Implements the following pseudo GLSL shader:
268 // layout (binding = 0) buffer Output
274 // void func0(vec4* f0[16], uint i)
276 // f0[i] = vec4(5.0);
279 // void func1(vec4* f1[], uint i)
281 // f1[i] = vec4(2.0);
286 // uint idx = gl_GlobalInvocationID.x;
287 // func0(dataOutput.arr0, idx);
288 // func1(dataOutput.arr1, idx);
290 const string shaderSource =
291 " OpCapability Shader\n"
292 " OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
293 " %1 = OpExtInstImport \"GLSL.std.450\"\n"
294 " OpMemoryModel Logical GLSL450\n"
295 " OpEntryPoint GLCompute %main \"main\" %gl_GlobalInvocationID\n"
296 " OpExecutionMode %main LocalSize 1 1 1\n"
297 " OpSource GLSL 430\n"
298 " OpMemberDecorate %Output 0 Offset 0\n"
299 " OpMemberDecorate %Output 1 Offset 256\n"
300 " OpDecorate %arr_vec4_16 ArrayStride 16\n"
301 " OpDecorate %arr_vec4_rt ArrayStride 16\n"
302 " OpDecorate %Output Block\n"
303 " OpDecorate %dataOutput DescriptorSet 0\n"
304 " OpDecorate %dataOutput Binding 0\n"
305 " OpDecorate %f0 DescriptorSet 0\n"
306 " OpDecorate %f0 Binding 0\n"
307 " OpDecorate %f1 DescriptorSet 0\n"
308 " OpDecorate %f1 Binding 0\n"
309 " OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId\n"
310 " %void = OpTypeVoid\n"
311 " %void_func = OpTypeFunction %void\n"
312 " %float = OpTypeFloat 32\n"
313 " %_ptr_Function_float = OpTypePointer Function %float\n"
314 " %float_5 = OpConstant %float 5\n"
315 " %float_2 = OpConstant %float 2\n"
316 " %uint = OpTypeInt 32 0\n"
317 " %_ptr_Function_uint = OpTypePointer Function %uint\n"
318 " %uint_16 = OpConstant %uint 16\n"
319 " %vec4 = OpTypeVector %float 4\n"
320 " %vec4_5 = OpConstantComposite %vec4 %float_5 %float_5 %float_5 %float_5\n"
321 " %vec4_2 = OpConstantComposite %vec4 %float_2 %float_2 %float_2 %float_2\n"
322 " %arr_vec4_16 = OpTypeArray %vec4 %uint_16\n"
323 " %arr_vec4_rt = OpTypeRuntimeArray %vec4\n"
324 " %arr_vec4_16_ptr = OpTypePointer StorageBuffer %arr_vec4_16\n"
325 " %arr_vec4_rt_ptr = OpTypePointer StorageBuffer %arr_vec4_rt\n"
326 " %func0_decl = OpTypeFunction %void %arr_vec4_16_ptr %_ptr_Function_uint\n"
327 " %func1_decl = OpTypeFunction %void %arr_vec4_rt_ptr %_ptr_Function_uint\n"
328 " %Output = OpTypeStruct %arr_vec4_16 %arr_vec4_rt\n"
329 " %_ptr_sb_Output = OpTypePointer StorageBuffer %Output\n"
330 " %dataOutput = OpVariable %_ptr_sb_Output StorageBuffer\n"
331 " %int = OpTypeInt 32 1\n"
332 " %int_0 = OpConstant %int 0\n"
333 " %int_1 = OpConstant %int 1\n"
334 " %v3uint = OpTypeVector %uint 3\n"
335 " %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
336 " %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
337 " %uint_0 = OpConstant %uint 0\n"
338 " %_ptr_Input_uint = OpTypePointer Input %uint\n"
339 " %_ptr_sb_vec4 = OpTypePointer StorageBuffer %vec4\n"
340 " %main = OpFunction %void None %void_func\n"
341 " %entry = OpLabel\n"
342 " %idx = OpVariable %_ptr_Function_uint Function\n"
343 " %inv_id_ptr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0\n"
344 " %inv_id = OpLoad %uint %inv_id_ptr\n"
345 " OpStore %idx %inv_id\n"
346 " %ptr0 = OpAccessChain %arr_vec4_16_ptr %dataOutput %int_0\n"
347 " %ptr1 = OpAccessChain %arr_vec4_rt_ptr %dataOutput %int_1\n"
348 " %ret0 = OpFunctionCall %void %func0 %ptr0 %idx\n"
349 " %ret1 = OpFunctionCall %void %func1 %ptr1 %idx\n"
352 " %func0 = OpFunction %void None %func0_decl\n"
353 " %f0 = OpFunctionParameter %arr_vec4_16_ptr\n"
354 " %i0 = OpFunctionParameter %_ptr_Function_uint\n"
355 " %func0_entry = OpLabel\n"
356 " %idx0 = OpLoad %uint %i0\n"
357 " %out_ptr0 = OpAccessChain %_ptr_sb_vec4 %f0 %idx0\n"
358 " OpStore %out_ptr0 %vec4_5\n"
361 " %func1 = OpFunction %void None %func1_decl\n"
362 " %f1 = OpFunctionParameter %arr_vec4_rt_ptr\n"
363 " %i1 = OpFunctionParameter %_ptr_Function_uint\n"
364 " %func1_entry = OpLabel\n"
365 " %idx1 = OpLoad %uint %i1\n"
366 " %out_ptr1 = OpAccessChain %_ptr_sb_vec4 %f1 %idx1\n"
367 " OpStore %out_ptr1 %vec4_2\n"
371 expectedOutput.reserve(numFloats);
372 for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
373 expectedOutput.push_back(5.0f);
374 for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
375 expectedOutput.push_back(2.0f);
377 spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
379 spec.assembly = shaderSource;
380 spec.numWorkGroups = IVec3(16, 1, 1);
382 group->addChild(new SpvAsmComputeShaderCase(testCtx, "buffer_memory", "", spec));
385 void addComputePointerBufferMemoryVariablePointersTest (tcu::TestCaseGroup* group)
387 tcu::TestContext& testCtx = group->getTestContext();
388 const int numFloats = 128;
389 ComputeShaderSpec spec;
390 VulkanFeatures requiredFeatures;
391 vector<float> expectedOutput;
393 // Implements the following pseudo GLSL shader:
395 // layout (binding = 0) buffer Output
401 // void func0(vec4* f0[16], uint i)
403 // f0[i] = vec4(5.0);
406 // void func1(vec4* f1[], uint i)
408 // f1[i] = vec4(2.0);
413 // uint idx = gl_GlobalInvocationID.x;
414 // func0(dataOutput.arr0, idx);
415 // func1(dataOutput.arr1, idx);
417 const string shaderSource =
418 " OpCapability Shader\n"
419 " OpCapability VariablePointersStorageBuffer\n"
420 " OpExtension \"SPV_KHR_variable_pointers\"\n"
421 " OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
422 " %1 = OpExtInstImport \"GLSL.std.450\"\n"
423 " OpMemoryModel Logical GLSL450\n"
424 " OpEntryPoint GLCompute %main \"main\" %gl_GlobalInvocationID\n"
425 " OpExecutionMode %main LocalSize 1 1 1\n"
426 " OpSource GLSL 430\n"
427 " OpMemberDecorate %Output 0 Offset 0\n"
428 " OpMemberDecorate %Output 1 Offset 256\n"
429 " OpDecorate %arr_vec4_16 ArrayStride 16\n"
430 " OpDecorate %arr_vec4_rt ArrayStride 16\n"
431 " OpDecorate %Output Block\n"
432 " OpDecorate %dataOutput DescriptorSet 0\n"
433 " OpDecorate %dataOutput Binding 0\n"
434 " OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId\n"
435 " %void = OpTypeVoid\n"
436 " %void_func = OpTypeFunction %void\n"
437 " %float = OpTypeFloat 32\n"
438 " %_ptr_Function_float = OpTypePointer Function %float\n"
439 " %float_5 = OpConstant %float 5\n"
440 " %float_2 = OpConstant %float 2\n"
441 " %uint = OpTypeInt 32 0\n"
442 " %_ptr_Function_uint = OpTypePointer Function %uint\n"
443 " %uint_16 = OpConstant %uint 16\n"
444 " %vec4 = OpTypeVector %float 4\n"
445 " %vec4_5 = OpConstantComposite %vec4 %float_5 %float_5 %float_5 %float_5\n"
446 " %vec4_2 = OpConstantComposite %vec4 %float_2 %float_2 %float_2 %float_2\n"
447 " %arr_vec4_16 = OpTypeArray %vec4 %uint_16\n"
448 " %arr_vec4_rt = OpTypeRuntimeArray %vec4\n"
449 " %arr_vec4_16_ptr = OpTypePointer StorageBuffer %arr_vec4_16\n"
450 " %arr_vec4_rt_ptr = OpTypePointer StorageBuffer %arr_vec4_rt\n"
451 " %func0_decl = OpTypeFunction %void %arr_vec4_16_ptr %_ptr_Function_uint\n"
452 " %func1_decl = OpTypeFunction %void %arr_vec4_rt_ptr %_ptr_Function_uint\n"
453 " %Output = OpTypeStruct %arr_vec4_16 %arr_vec4_rt\n"
454 " %_ptr_sb_Output = OpTypePointer StorageBuffer %Output\n"
455 " %dataOutput = OpVariable %_ptr_sb_Output StorageBuffer\n"
456 " %int = OpTypeInt 32 1\n"
457 " %int_0 = OpConstant %int 0\n"
458 " %int_1 = OpConstant %int 1\n"
459 " %v3uint = OpTypeVector %uint 3\n"
460 " %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
461 " %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
462 " %uint_0 = OpConstant %uint 0\n"
463 " %_ptr_Input_uint = OpTypePointer Input %uint\n"
464 " %_ptr_sb_vec4 = OpTypePointer StorageBuffer %vec4\n"
465 " %main = OpFunction %void None %void_func\n"
466 " %entry = OpLabel\n"
467 " %idx = OpVariable %_ptr_Function_uint Function\n"
468 " %inv_id_ptr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0\n"
469 " %inv_id = OpLoad %uint %inv_id_ptr\n"
470 " OpStore %idx %inv_id\n"
471 " %ptr0 = OpAccessChain %arr_vec4_16_ptr %dataOutput %int_0\n"
472 " %ptr1 = OpAccessChain %arr_vec4_rt_ptr %dataOutput %int_1\n"
473 " %ret0 = OpFunctionCall %void %func0 %ptr0 %idx\n"
474 " %ret1 = OpFunctionCall %void %func1 %ptr1 %idx\n"
477 " %func0 = OpFunction %void None %func0_decl\n"
478 " %f0 = OpFunctionParameter %arr_vec4_16_ptr\n"
479 " %i0 = OpFunctionParameter %_ptr_Function_uint\n"
480 " %func0_entry = OpLabel\n"
481 " %idx0 = OpLoad %uint %i0\n"
482 " %out_ptr0 = OpAccessChain %_ptr_sb_vec4 %f0 %idx0\n"
483 " OpStore %out_ptr0 %vec4_5\n"
486 " %func1 = OpFunction %void None %func1_decl\n"
487 " %f1 = OpFunctionParameter %arr_vec4_rt_ptr\n"
488 " %i1 = OpFunctionParameter %_ptr_Function_uint\n"
489 " %func1_entry = OpLabel\n"
490 " %idx1 = OpLoad %uint %i1\n"
491 " %out_ptr1 = OpAccessChain %_ptr_sb_vec4 %f1 %idx1\n"
492 " OpStore %out_ptr1 %vec4_2\n"
496 expectedOutput.reserve(numFloats);
497 for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
498 expectedOutput.push_back(5.0f);
499 for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
500 expectedOutput.push_back(2.0f);
502 requiredFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER;
503 spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
504 spec.extensions.push_back("VK_KHR_variable_pointers");
506 spec.assembly = shaderSource;
507 spec.numWorkGroups = IVec3(16, 1, 1);
508 spec.requestedVulkanFeatures = requiredFeatures;
510 group->addChild(new SpvAsmComputeShaderCase(testCtx, "buffer_memory_variable_pointers", "", spec));
513 void addComputePointerWorkgroupMemoryVariablePointersTest (tcu::TestCaseGroup* group)
515 tcu::TestContext& testCtx = group->getTestContext();
516 const int numFloats = 128;
517 ComputeShaderSpec spec;
518 VulkanFeatures requiredFeatures;
519 vector<float> expectedOutput;
521 // Implements the following pseudo GLSL shader:
523 // layout (local_size_x = 16, local_size_y = 1, local_size_z = 1) in;
525 // layout (binding = 0) buffer Output
537 // void func0(vec4* f0[16], uint i)
542 // void func1(vec4* f1[16], uint i)
544 // f1[i] = vec4(i+5);
549 // uint idx = gl_LocalInvocationID.x;
550 // func0(sharedData.arr0, idx);
551 // func1(sharedData.arr1, idx);
553 // dataOutput.arr0[idx] = sharedData.arr1[(idx+1) % 16];
554 // dataOutput.arr1[idx] = sharedData.arr0[(idx+1) % 16];
556 const string shaderSource =
557 " OpCapability Shader\n"
558 " OpCapability VariablePointers\n"
559 " OpExtension \"SPV_KHR_variable_pointers\"\n"
560 " OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
561 " %1 = OpExtInstImport \"GLSL.std.450\"\n"
562 " OpMemoryModel Logical GLSL450\n"
563 " OpEntryPoint GLCompute %main \"main\" %gl_LocalInvocationID\n"
564 " OpExecutionMode %main LocalSize 16 1 1\n"
565 " OpSource GLSL 430\n"
566 " OpMemberDecorate %Output 0 Offset 0\n"
567 " OpMemberDecorate %Output 1 Offset 256\n"
568 " OpMemberDecorate %struct 0 Offset 0\n"
569 " OpMemberDecorate %struct 1 Offset 256\n"
570 " OpDecorate %arr_vec4_16 ArrayStride 16\n"
571 " OpDecorate %arr_vec4_rt ArrayStride 16\n"
572 " OpDecorate %Output Block\n"
573 " OpDecorate %dataOutput DescriptorSet 0\n"
574 " OpDecorate %dataOutput Binding 0\n"
575 " OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId\n"
576 " %void = OpTypeVoid\n"
577 " %void_func = OpTypeFunction %void\n"
578 " %float = OpTypeFloat 32\n"
579 " %_ptr_Function_float = OpTypePointer Function %float\n"
580 " %uint = OpTypeInt 32 0\n"
581 " %_ptr_Function_uint = OpTypePointer Function %uint\n"
582 " %uint_1 = OpConstant %uint 1\n"
583 " %uint_2 = OpConstant %uint 2\n"
584 " %uint_5 = OpConstant %uint 5\n"
585 " %uint_16 = OpConstant %uint 16\n"
586 " %uint_264 = OpConstant %uint 264\n"
587 " %vec4 = OpTypeVector %float 4\n"
588 " %arr_vec4_16 = OpTypeArray %vec4 %uint_16\n"
589 " %arr_vec4_rt = OpTypeRuntimeArray %vec4\n"
590 " %arr_vec4_16_sb_ptr = OpTypePointer StorageBuffer %arr_vec4_16\n"
591 " %arr_vec4_rt_sb_ptr = OpTypePointer StorageBuffer %arr_vec4_rt\n"
592 " %arr_vec4_16_wg_ptr = OpTypePointer Workgroup %arr_vec4_16\n"
593 " %func_decl = OpTypeFunction %void %arr_vec4_16_wg_ptr %_ptr_Function_uint\n"
594 " %Output = OpTypeStruct %arr_vec4_16 %arr_vec4_rt\n"
595 " %struct = OpTypeStruct %arr_vec4_16 %arr_vec4_16\n"
596 " %_ptr_sb_struct = OpTypePointer StorageBuffer %Output\n"
597 " %_ptr_wg_struct = OpTypePointer Workgroup %struct\n"
598 " %dataOutput = OpVariable %_ptr_sb_struct StorageBuffer\n"
599 " %sharedData = OpVariable %_ptr_wg_struct Workgroup\n"
600 " %int = OpTypeInt 32 1\n"
601 " %int_0 = OpConstant %int 0\n"
602 " %int_1 = OpConstant %int 1\n"
603 " %v3uint = OpTypeVector %uint 3\n"
604 " %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
605 " %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
606 " %uint_0 = OpConstant %uint 0\n"
607 " %_ptr_Input_uint = OpTypePointer Input %uint\n"
608 " %_ptr_sb_vec4 = OpTypePointer StorageBuffer %vec4\n"
609 " %_ptr_wg_vec4 = OpTypePointer Workgroup %vec4\n"
610 " %main = OpFunction %void None %void_func\n"
611 " %entry = OpLabel\n"
612 " %idx = OpVariable %_ptr_Function_uint Function\n"
613 " %inv_id_ptr = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %uint_0\n"
614 " %inv_id = OpLoad %uint %inv_id_ptr\n"
615 " OpStore %idx %inv_id\n"
616 " %ptr0 = OpAccessChain %arr_vec4_16_wg_ptr %sharedData %int_0\n"
617 " %ptr1 = OpAccessChain %arr_vec4_16_wg_ptr %sharedData %int_1\n"
618 " %ret0 = OpFunctionCall %void %func0 %ptr0 %idx\n"
619 " %ret1 = OpFunctionCall %void %func1 %ptr1 %idx\n"
620 " OpControlBarrier %uint_2 %uint_2 %uint_264\n"
621 " %inv_id_plus1 = OpIAdd %uint %inv_id %uint_1\n"
622 " %inv_id_mod = OpUMod %uint %inv_id_plus1 %uint_16\n"
623 " %shared_arr1_ptr = OpAccessChain %_ptr_wg_vec4 %sharedData %int_1 %inv_id_mod\n"
624 " %shared_arr1_data = OpLoad %vec4 %shared_arr1_ptr\n"
625 " %outPtr0 = OpAccessChain %_ptr_sb_vec4 %dataOutput %int_0 %inv_id\n"
626 " OpStore %outPtr0 %shared_arr1_data\n"
627 " %shared_arr0_ptr = OpAccessChain %_ptr_wg_vec4 %sharedData %int_0 %inv_id_mod\n"
628 " %shared_arr0_data = OpLoad %vec4 %shared_arr0_ptr\n"
629 " %outPtr1 = OpAccessChain %_ptr_sb_vec4 %dataOutput %int_1 %inv_id\n"
630 " OpStore %outPtr1 %shared_arr0_data\n"
633 " %func0 = OpFunction %void None %func_decl\n"
634 " %f0 = OpFunctionParameter %arr_vec4_16_wg_ptr\n"
635 " %i0 = OpFunctionParameter %_ptr_Function_uint\n"
636 " %func0_entry = OpLabel\n"
637 " %idx0 = OpLoad %uint %i0\n"
638 " %out_ptr0 = OpAccessChain %_ptr_wg_vec4 %f0 %idx0\n"
639 " %idxFloat0 = OpConvertUToF %float %idx0\n"
640 " %outData0 = OpCompositeConstruct %vec4 %idxFloat0 %idxFloat0 %idxFloat0 %idxFloat0\n"
641 " OpStore %out_ptr0 %outData0\n"
644 " %func1 = OpFunction %void None %func_decl\n"
645 " %f1 = OpFunctionParameter %arr_vec4_16_wg_ptr\n"
646 " %i1 = OpFunctionParameter %_ptr_Function_uint\n"
647 " %func1_entry = OpLabel\n"
648 " %idx1 = OpLoad %uint %i1\n"
649 " %out_ptr1 = OpAccessChain %_ptr_wg_vec4 %f1 %idx1\n"
650 " %idxPlus5 = OpIAdd %uint %idx1 %uint_5\n"
651 " %idxFloat1 = OpConvertUToF %float %idxPlus5\n"
652 " %outData1 = OpCompositeConstruct %vec4 %idxFloat1 %idxFloat1 %idxFloat1 %idxFloat1\n"
653 " OpStore %out_ptr1 %outData1\n"
657 expectedOutput.reserve(numFloats);
658 for (deUint32 vecIdx = 0; vecIdx < numFloats / 8; ++vecIdx)
660 const deUint32 shuffleIdx = (vecIdx + 1) % 16;
661 const float val = (float)(shuffleIdx + 5);
662 for (deUint32 i = 0; i < 4; ++i)
663 expectedOutput.push_back(val);
665 for (deUint32 vecIdx = 0; vecIdx < numFloats / 8; ++vecIdx)
667 const deUint32 shuffleIdx = (vecIdx + 1) % 16;
668 const float val = (float)shuffleIdx;
669 for (deUint32 i = 0; i < 4; ++i)
670 expectedOutput.push_back(val);
673 spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
674 requiredFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS;
675 spec.extensions.push_back("VK_KHR_variable_pointers");
677 spec.assembly = shaderSource;
678 spec.numWorkGroups = IVec3(1, 1, 1);
680 group->addChild(new SpvAsmComputeShaderCase(testCtx, "workgroup_memory_variable_pointers", "", spec));
683 void addGraphicsPointerParamToParamTest (tcu::TestCaseGroup* group)
685 map<string, string> fragments;
686 RGBA defaultColors[4];
687 GraphicsResources resources;
688 vector<string> extensions;
689 vector<float> expectedOutput;
690 VulkanFeatures requiredFeatures;
692 // Implements the following pseudo GLSL shader:
694 // float func(alias float* f, alias float* g)
701 // vec4 test_code(vec4 param)
704 // o = func(&a, &a); // should return 2.0
706 // o += func(&a, &b); // should return 5.0
709 fragments["pre_main"] =
710 " %func0_decl = OpTypeFunction %f32 %fp_f32 %fp_f32\n"
711 " %c_f32_5 = OpConstant %f32 5\n"
712 " %c_f32_2 = OpConstant %f32 2\n"
713 " %Output = OpTypeStruct %f32\n"
714 " %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
715 " %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
716 " %_ptr_Uniform_f32 = OpTypePointer Uniform %f32\n"
717 " %func = OpFunction %f32 None %func0_decl\n"
718 " %f = OpFunctionParameter %fp_f32\n"
719 " %g = OpFunctionParameter %fp_f32\n"
720 " %func_entry = OpLabel\n"
721 " OpStore %g %c_f32_5\n"
722 " OpStore %f %c_f32_2\n"
723 " %ret = OpLoad %f32 %g\n"
724 " OpReturnValue %ret\n"
727 fragments["decoration"] =
728 " OpMemberDecorate %Output 0 Offset 0\n"
729 " OpDecorate %Output BufferBlock\n"
730 " OpDecorate %dataOutput DescriptorSet 0\n"
731 " OpDecorate %dataOutput Binding 0\n"
732 " OpDecorate %f Aliased\n"
733 " OpDecorate %g Aliased\n";
735 fragments["testfun"] =
736 " %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
737 " %param = OpFunctionParameter %v4f32\n"
738 " %entry = OpLabel\n"
739 " %a = OpVariable %fp_f32 Function %c_f32_0\n"
740 " %b = OpVariable %fp_f32 Function %c_f32_0\n"
741 " %o = OpVariable %fp_f32 Function %c_f32_0\n"
742 " %ret0 = OpFunctionCall %f32 %func %a %a\n"
743 " OpStore %o %ret0\n"
744 " %ret1 = OpFunctionCall %f32 %func %a %b\n"
745 " %o_val = OpLoad %f32 %o\n"
746 " %sum = OpFAdd %f32 %o_val %ret1\n"
747 " %out_ptr = OpAccessChain %_ptr_Uniform_f32 %dataOutput %c_i32_0\n"
748 " OpStore %out_ptr %sum\n"
749 " OpReturnValue %param\n"
752 getDefaultColors(defaultColors);
753 expectedOutput.push_back(7.0f);
754 requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
755 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
757 createTestsForAllStages("global_to_param", defaultColors, defaultColors, fragments, resources, extensions, group, requiredFeatures);
760 void addGraphicsPointerParamToGlobalTest (tcu::TestCaseGroup* group)
762 map<string, string> fragments;
763 RGBA defaultColors[4];
764 GraphicsResources resources;
765 vector<string> extensions;
766 vector<float> expectedOutput;
767 VulkanFeatures requiredFeatures;
769 // Implements the following pseudo GLSL shader:
771 // alias float a = 0.0;
773 // float func0(alias float* f0) // f in Private storage class
780 // float func1(alias float* f1) // f in Function storage class
787 // vec4 test_code(vec4 param)
789 // o = func0(&a); // should return 2.0
791 // o += func1(&b); // should return 5.0
794 fragments["pre_main"] =
795 " %pp_f32 = OpTypePointer Private %f32\n"
796 " %func0_decl = OpTypeFunction %f32 %pp_f32\n"
797 " %func1_decl = OpTypeFunction %f32 %fp_f32\n"
798 " %c_f32_5 = OpConstant %f32 5\n"
799 " %c_f32_2 = OpConstant %f32 2\n"
800 " %Output = OpTypeStruct %f32\n"
801 " %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
802 " %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
803 " %_ptr_Uniform_f32 = OpTypePointer Uniform %f32\n"
804 " %a = OpVariable %pp_f32 Private %c_f32_0\n"
805 " %func0 = OpFunction %f32 None %func0_decl\n"
806 " %f0 = OpFunctionParameter %pp_f32\n"
807 " %func0_entry = OpLabel\n"
808 " OpStore %a %c_f32_5\n"
809 " OpStore %f0 %c_f32_2\n"
810 " %func0_ret = OpLoad %f32 %a\n"
811 " OpReturnValue %func0_ret\n"
813 " %func1 = OpFunction %f32 None %func1_decl\n"
814 " %f1 = OpFunctionParameter %fp_f32\n"
815 " %func1_entry = OpLabel\n"
816 " OpStore %a %c_f32_5\n"
817 " OpStore %f1 %c_f32_2\n"
818 " %func1_ret = OpLoad %f32 %a\n"
819 " OpReturnValue %func1_ret\n"
822 fragments["decoration"] =
823 " OpMemberDecorate %Output 0 Offset 0\n"
824 " OpDecorate %Output BufferBlock\n"
825 " OpDecorate %dataOutput DescriptorSet 0\n"
826 " OpDecorate %dataOutput Binding 0\n"
827 " OpDecorate %f0 Aliased\n"
828 " OpDecorate %f1 Aliased\n"
829 " OpDecorate %a Aliased\n";
831 fragments["testfun"] =
832 " %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
833 " %param = OpFunctionParameter %v4f32\n"
834 " %entry = OpLabel\n"
835 " %b = OpVariable %fp_f32 Function %c_f32_0\n"
836 " %o = OpVariable %fp_f32 Function %c_f32_0\n"
837 " %ret0 = OpFunctionCall %f32 %func0 %a\n"
838 " OpStore %o %ret0\n"
839 " %ret1 = OpFunctionCall %f32 %func1 %b\n"
840 " %o_val = OpLoad %f32 %o\n"
841 " %sum = OpFAdd %f32 %o_val %ret1\n"
842 " %out_ptr = OpAccessChain %_ptr_Uniform_f32 %dataOutput %c_i32_0\n"
843 " OpStore %out_ptr %sum\n"
844 " OpReturnValue %param\n"
847 getDefaultColors(defaultColors);
848 expectedOutput.push_back(7.0f);
849 requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
850 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
852 createTestsForAllStages("param_to_global", defaultColors, defaultColors, fragments, resources, extensions, group, requiredFeatures);
855 void addGraphicsPointerBufferMemoryTest (tcu::TestCaseGroup* group)
857 const int numFloats = 16;
858 map<string, string> fragments;
859 RGBA defaultColors[4];
860 GraphicsResources resources;
861 vector<string> extensions;
862 vector<float> expectedOutput;
863 VulkanFeatures requiredFeatures;
865 // Implements the following pseudo GLSL shader:
867 // layout (binding = 0) buffer Output
873 // void func0(vec4* f0[2], uint i)
875 // f0[i] = vec4(5.0);
878 // void func1(vec4* f1[], uint i)
880 // f1[i] = vec4(2.0);
883 // vec4 test_code(vec4 param)
885 // func0(dataOutput.arr0, idx);
886 // func1(dataOutput.arr1, idx);
889 fragments["pre_main"] =
890 " %arr_v4f32_2 = OpTypeArray %v4f32 %c_u32_2\n"
891 " %arr_v4f32_rt = OpTypeRuntimeArray %v4f32\n"
892 " %arr_v4f32_2_ptr = OpTypePointer StorageBuffer %arr_v4f32_2\n"
893 " %arr_v4f32_rt_ptr = OpTypePointer StorageBuffer %arr_v4f32_rt\n"
894 " %func0_decl = OpTypeFunction %void %arr_v4f32_2_ptr\n"
895 " %func1_decl = OpTypeFunction %void %arr_v4f32_rt_ptr\n"
896 " %c_f32_5 = OpConstant %f32 5\n"
897 " %c_f32_2 = OpConstant %f32 2\n"
898 " %c_v4f32_5 = OpConstantComposite %v4f32 %c_f32_5 %c_f32_5 %c_f32_5 %c_f32_5\n"
899 " %c_v4f32_2 = OpConstantComposite %v4f32 %c_f32_2 %c_f32_2 %c_f32_2 %c_f32_2\n"
900 " %Output = OpTypeStruct %arr_v4f32_2 %arr_v4f32_rt\n"
901 " %_ptr_sb_Output = OpTypePointer StorageBuffer %Output\n"
902 " %dataOutput = OpVariable %_ptr_sb_Output StorageBuffer\n"
903 " %_ptr_sb_v4f32 = OpTypePointer StorageBuffer %v4f32\n"
904 " %func0 = OpFunction %void None %func0_decl\n"
905 " %f0 = OpFunctionParameter %arr_v4f32_2_ptr\n"
906 " %func0Entry = OpLabel\n"
907 " %out_ptr0 = OpAccessChain %_ptr_sb_v4f32 %f0 %c_i32_0\n"
908 " OpStore %out_ptr0 %c_v4f32_5\n"
909 " %out_ptr1 = OpAccessChain %_ptr_sb_v4f32 %f0 %c_i32_1\n"
910 " OpStore %out_ptr1 %c_v4f32_5\n"
913 " %func1 = OpFunction %void None %func1_decl\n"
914 " %f1 = OpFunctionParameter %arr_v4f32_rt_ptr\n"
915 " %func1Entry = OpLabel\n"
916 " %out_ptr2 = OpAccessChain %_ptr_sb_v4f32 %f1 %c_i32_0\n"
917 " OpStore %out_ptr2 %c_v4f32_2\n"
918 " %out_ptr3 = OpAccessChain %_ptr_sb_v4f32 %f1 %c_i32_1\n"
919 " OpStore %out_ptr3 %c_v4f32_2\n"
923 fragments["decoration"] =
924 " OpMemberDecorate %Output 0 Offset 0\n"
925 " OpMemberDecorate %Output 1 Offset 32\n"
926 " OpDecorate %Output Block\n"
927 " OpDecorate %dataOutput DescriptorSet 0\n"
928 " OpDecorate %dataOutput Binding 0\n"
929 " OpDecorate %f0 DescriptorSet 0\n"
930 " OpDecorate %f0 Binding 0\n"
931 " OpDecorate %f1 DescriptorSet 0\n"
932 " OpDecorate %f1 Binding 0\n"
933 " OpDecorate %arr_v4f32_2 ArrayStride 16\n"
934 " OpDecorate %arr_v4f32_rt ArrayStride 16\n";
936 fragments["testfun"] =
937 " %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
938 " %param = OpFunctionParameter %v4f32\n"
939 " %entry = OpLabel\n"
940 " %ptr0 = OpAccessChain %arr_v4f32_2_ptr %dataOutput %c_i32_0\n"
941 " %ptr1 = OpAccessChain %arr_v4f32_rt_ptr %dataOutput %c_i32_1\n"
942 " %ret0 = OpFunctionCall %void %func0 %ptr0\n"
943 " %ret1 = OpFunctionCall %void %func1 %ptr1\n"
944 " OpReturnValue %param\n"
947 fragments["extension"] =
948 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
950 getDefaultColors(defaultColors);
952 for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
953 expectedOutput.push_back(5.0f);
954 for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
955 expectedOutput.push_back(2.0f);
957 requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
958 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
960 createTestsForAllStages("buffer_memory", defaultColors, defaultColors, fragments, resources, extensions, group, requiredFeatures);
963 void addGraphicsPointerBufferMemoryVariablePointersTest (tcu::TestCaseGroup* group)
965 const int numFloats = 16;
966 map<string, string> fragments;
967 RGBA defaultColors[4];
968 GraphicsResources resources;
969 vector<string> extensions;
970 vector<float> expectedOutput;
971 VulkanFeatures requiredFeatures;
973 // Implements the following pseudo GLSL shader:
975 // layout (binding = 0) buffer Output
981 // void func0(vec4* f0[2], uint i)
983 // f0[i] = vec4(5.0);
986 // void func1(vec4* f1[], uint i)
988 // f1[i] = vec4(2.0);
991 // vec4 test_code(vec4 param)
993 // func0(dataOutput.arr0, idx);
994 // func1(dataOutput.arr1, idx);
997 fragments["pre_main"] =
998 " %arr_v4f32_2 = OpTypeArray %v4f32 %c_u32_2\n"
999 " %arr_v4f32_rt = OpTypeRuntimeArray %v4f32\n"
1000 " %arr_v4f32_2_ptr = OpTypePointer StorageBuffer %arr_v4f32_2\n"
1001 " %arr_v4f32_rt_ptr = OpTypePointer StorageBuffer %arr_v4f32_rt\n"
1002 " %func0_decl = OpTypeFunction %void %arr_v4f32_2_ptr\n"
1003 " %func1_decl = OpTypeFunction %void %arr_v4f32_rt_ptr\n"
1004 " %c_f32_5 = OpConstant %f32 5\n"
1005 " %c_f32_2 = OpConstant %f32 2\n"
1006 " %c_v4f32_5 = OpConstantComposite %v4f32 %c_f32_5 %c_f32_5 %c_f32_5 %c_f32_5\n"
1007 " %c_v4f32_2 = OpConstantComposite %v4f32 %c_f32_2 %c_f32_2 %c_f32_2 %c_f32_2\n"
1008 " %Output = OpTypeStruct %arr_v4f32_2 %arr_v4f32_rt\n"
1009 " %_ptr_sb_Output = OpTypePointer StorageBuffer %Output\n"
1010 " %dataOutput = OpVariable %_ptr_sb_Output StorageBuffer\n"
1011 " %_ptr_sb_v4f32 = OpTypePointer StorageBuffer %v4f32\n"
1012 " %func0 = OpFunction %void None %func0_decl\n"
1013 " %f0 = OpFunctionParameter %arr_v4f32_2_ptr\n"
1014 " %func0Entry = OpLabel\n"
1015 " %out_ptr0 = OpAccessChain %_ptr_sb_v4f32 %f0 %c_i32_0\n"
1016 " OpStore %out_ptr0 %c_v4f32_5\n"
1017 " %out_ptr1 = OpAccessChain %_ptr_sb_v4f32 %f0 %c_i32_1\n"
1018 " OpStore %out_ptr1 %c_v4f32_5\n"
1021 " %func1 = OpFunction %void None %func1_decl\n"
1022 " %f1 = OpFunctionParameter %arr_v4f32_rt_ptr\n"
1023 " %func1Entry = OpLabel\n"
1024 " %out_ptr2 = OpAccessChain %_ptr_sb_v4f32 %f1 %c_i32_0\n"
1025 " OpStore %out_ptr2 %c_v4f32_2\n"
1026 " %out_ptr3 = OpAccessChain %_ptr_sb_v4f32 %f1 %c_i32_1\n"
1027 " OpStore %out_ptr3 %c_v4f32_2\n"
1031 fragments["decoration"] =
1032 " OpMemberDecorate %Output 0 Offset 0\n"
1033 " OpMemberDecorate %Output 1 Offset 32\n"
1034 " OpDecorate %Output Block\n"
1035 " OpDecorate %dataOutput DescriptorSet 0\n"
1036 " OpDecorate %dataOutput Binding 0\n"
1037 " OpDecorate %arr_v4f32_2 ArrayStride 16\n"
1038 " OpDecorate %arr_v4f32_rt ArrayStride 16\n";
1040 fragments["testfun"] =
1041 " %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
1042 " %param = OpFunctionParameter %v4f32\n"
1043 " %entry = OpLabel\n"
1044 " %ptr0 = OpAccessChain %arr_v4f32_2_ptr %dataOutput %c_i32_0\n"
1045 " %ptr1 = OpAccessChain %arr_v4f32_rt_ptr %dataOutput %c_i32_1\n"
1046 " %ret0 = OpFunctionCall %void %func0 %ptr0\n"
1047 " %ret1 = OpFunctionCall %void %func1 %ptr1\n"
1048 " OpReturnValue %param\n"
1051 fragments["extension"] =
1052 "OpExtension \"SPV_KHR_variable_pointers\"\n"
1053 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
1055 fragments["capability"] =
1056 "OpCapability VariablePointersStorageBuffer\n";
1058 getDefaultColors(defaultColors);
1060 for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
1061 expectedOutput.push_back(5.0f);
1062 for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
1063 expectedOutput.push_back(2.0f);
1065 extensions.push_back("VK_KHR_variable_pointers");
1066 requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
1067 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
1069 createTestsForAllStages("buffer_memory_variable_pointers", defaultColors, defaultColors, fragments, resources, extensions, group, requiredFeatures);
1074 tcu::TestCaseGroup* createPointerParameterComputeGroup (tcu::TestContext& testCtx)
1076 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "pointer_parameter", "Compute tests for pointer as function parameter."));
1077 addComputePointerParamToParamTest(group.get());
1078 addComputePointerParamToGlobalTest(group.get());
1079 addComputePointerBufferMemoryTest(group.get());
1080 addComputePointerBufferMemoryVariablePointersTest(group.get());
1081 addComputePointerWorkgroupMemoryVariablePointersTest(group.get());
1083 return group.release();
1086 tcu::TestCaseGroup* createPointerParameterGraphicsGroup (tcu::TestContext& testCtx)
1088 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "pointer_parameter", "Graphics tests for pointer as function parameter."));
1089 addGraphicsPointerParamToParamTest(group.get());
1090 addGraphicsPointerParamToGlobalTest(group.get());
1091 addGraphicsPointerBufferMemoryTest(group.get());
1092 addGraphicsPointerBufferMemoryVariablePointersTest(group.get());
1094 return group.release();