Refactor: Compatible compute and graphics VerifyIO
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / spirv_assembly / vktSpvAsmPointerParameterTests.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 Google Inc.
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  *//*!
20  * \file
21  * \brief SPIR-V Assembly Tests for pointers as function parameters.
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktSpvAsmPointerParameterTests.hpp"
25 #include "vktSpvAsmComputeShaderCase.hpp"
26 #include "vktSpvAsmComputeShaderTestUtil.hpp"
27 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
28
29 namespace vkt
30 {
31 namespace SpirVAssembly
32 {
33
34 using namespace vk;
35 using std::map;
36 using std::string;
37 using std::vector;
38 using tcu::IVec3;
39 using tcu::Vec4;
40 using tcu::RGBA;
41
42 namespace
43 {
44
45 void addComputePointerParamToParamTest (tcu::TestCaseGroup* group)
46 {
47         tcu::TestContext&       testCtx                         = group->getTestContext();
48         const int                       numFloats                       = 128;
49         ComputeShaderSpec       spec;
50         vector<float>           expectedOutput;
51
52         // Implements the following pseudo GLSL shader:
53         //
54         //      float func(alias float* f, alias float* g)
55         //      {
56         //              *g = 5.0;
57         //              *f = 2.0;
58         //              return *g;
59         //      }
60         //
61         //      void main()
62         //      {
63         //              float a = 0.0;
64         //              o = func(&a, &a);  // should return 2.0
65         //              float b = 0.0;
66         //              o += func(&a, &b); // should return 5.0
67         //      }
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"
119                         "                          OpReturn\n"
120                         "                          OpFunctionEnd\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"
129                         "                          OpFunctionEnd\n";
130
131         expectedOutput.reserve(numFloats);
132         for (deUint32 numIdx = 0; numIdx < numFloats; ++numIdx)
133                 expectedOutput.push_back(7.0f);
134
135         spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
136
137         spec.assembly                           = shaderSource;
138         spec.numWorkGroups                      = IVec3(numFloats, 1, 1);
139
140         group->addChild(new SpvAsmComputeShaderCase(testCtx, "param_to_param", "", spec));
141 }
142
143 void addComputePointerParamToGlobalTest (tcu::TestCaseGroup* group)
144 {
145         tcu::TestContext&       testCtx                         = group->getTestContext();
146         const int                       numFloats                       = 128;
147         ComputeShaderSpec       spec;
148         vector<float>           expectedOutput;
149
150         // Implements the following pseudo GLSL shader:
151         //
152         //      alias float a = 0.0;
153         //
154         //      float func0(alias float* f0) // f in Private storage class
155         //      {
156         //              *a = 5.0;
157         //              *f0 = 2.0;
158         //              return *a;
159         //      }
160         //
161         //      float func1(alias float* f1) // f in Function storage class
162         //      {
163         //              *a = 5.0;
164         //              *f1 = 2.0;
165         //              return *a;
166         //      }
167         //
168         //      void main()
169         //      {
170         //              o = func0(&a);  // should return 2.0
171         //              float b = 0.0;
172         //              o += func1(&b); // should return 5.0
173         //      }
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"
228                         "                          OpReturn\n"
229                         "                          OpFunctionEnd\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"
237                         "                          OpFunctionEnd\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"
245                         "                          OpFunctionEnd\n";
246
247         expectedOutput.reserve(numFloats);
248         for (deUint32 numIdx = 0; numIdx < numFloats; ++numIdx)
249                 expectedOutput.push_back(7.0f);
250
251         spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
252
253         spec.assembly                           = shaderSource;
254         spec.numWorkGroups                      = IVec3(numFloats, 1, 1);
255
256         group->addChild(new SpvAsmComputeShaderCase(testCtx, "param_to_global", "", spec));
257 }
258
259 void addComputePointerBufferMemoryTest (tcu::TestCaseGroup* group)
260 {
261         tcu::TestContext&       testCtx                         = group->getTestContext();
262         const int                       numFloats                       = 128;
263         ComputeShaderSpec       spec;
264         vector<float>           expectedOutput;
265
266         // Implements the following pseudo GLSL shader:
267         //
268         //      layout (binding = 0) buffer Output
269         //      {
270         //              vec4 arr0[16];
271         //              vec4 arr1[];
272         //      } dataOutput;
273         //
274         //      void func0(vec4* f0[16], uint i)
275         //      {
276         //              f0[i] = vec4(5.0);
277         //      }
278         //
279         //      void func1(vec4* f1[], uint i)
280         //      {
281         //              f1[i] = vec4(2.0);
282         //      }
283         //
284         //      void main()
285         //      {
286         //              uint idx = gl_GlobalInvocationID.x;
287         //              func0(dataOutput.arr0, idx);
288         //              func1(dataOutput.arr1, idx);
289         //      }
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"
350                         "                          OpReturn\n"
351                         "                          OpFunctionEnd\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"
359                         "                          OpReturn\n"
360                         "                          OpFunctionEnd\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"
368                         "                          OpReturn\n"
369                         "                          OpFunctionEnd\n";
370
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);
376
377         spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
378
379         spec.assembly                                   = shaderSource;
380         spec.numWorkGroups                              = IVec3(16, 1, 1);
381
382         group->addChild(new SpvAsmComputeShaderCase(testCtx, "buffer_memory", "", spec));
383 }
384
385 void addComputePointerBufferMemoryVariablePointersTest (tcu::TestCaseGroup* group)
386 {
387         tcu::TestContext&       testCtx                         = group->getTestContext();
388         const int                       numFloats                       = 128;
389         ComputeShaderSpec       spec;
390         VulkanFeatures          requiredFeatures;
391         vector<float>           expectedOutput;
392
393         // Implements the following pseudo GLSL shader:
394         //
395         //      layout (binding = 0) buffer Output
396         //      {
397         //              vec4 arr0[16];
398         //              vec4 arr1[];
399         //      } dataOutput;
400         //
401         //      void func0(vec4* f0[16], uint i)
402         //      {
403         //              f0[i] = vec4(5.0);
404         //      }
405         //
406         //      void func1(vec4* f1[], uint i)
407         //      {
408         //              f1[i] = vec4(2.0);
409         //      }
410         //
411         //      void main()
412         //      {
413         //              uint idx = gl_GlobalInvocationID.x;
414         //              func0(dataOutput.arr0, idx);
415         //              func1(dataOutput.arr1, idx);
416         //      }
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"
475                         "                          OpReturn\n"
476                         "                          OpFunctionEnd\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"
484                         "                          OpReturn\n"
485                         "                          OpFunctionEnd\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"
493                         "                          OpReturn\n"
494                         "                          OpFunctionEnd\n";
495
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);
501
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");
505
506         spec.assembly                                   = shaderSource;
507         spec.numWorkGroups                              = IVec3(16, 1, 1);
508         spec.requestedVulkanFeatures    = requiredFeatures;
509
510         group->addChild(new SpvAsmComputeShaderCase(testCtx, "buffer_memory_variable_pointers", "", spec));
511 }
512
513 void addComputePointerWorkgroupMemoryVariablePointersTest (tcu::TestCaseGroup* group)
514 {
515         tcu::TestContext&       testCtx                         = group->getTestContext();
516         const int                       numFloats                       = 128;
517         ComputeShaderSpec       spec;
518         VulkanFeatures          requiredFeatures;
519         vector<float>           expectedOutput;
520
521         // Implements the following pseudo GLSL shader:
522         //
523         //      layout (local_size_x = 16, local_size_y = 1, local_size_z = 1) in;
524         //
525         //      layout (binding = 0) buffer Output
526         //      {
527         //              vec4 arr0[16];
528         //              vec4 arr1[];
529         //      } dataOutput;
530         //
531         //      shared struct
532         //      {
533         //              vec4 arr0[16];
534         //              vec4 arr1[16];
535         //      } sharedData;
536         //
537         //      void func0(vec4* f0[16], uint i)
538         //      {
539         //              f0[i] = vec4(i);
540         //      }
541         //
542         //      void func1(vec4* f1[16], uint i)
543         //      {
544         //              f1[i] = vec4(i+5);
545         //      }
546         //
547         //      void main()
548         //      {
549         //              uint idx = gl_LocalInvocationID.x;
550         //              func0(sharedData.arr0, idx);
551         //              func1(sharedData.arr1, idx);
552         //              barier();
553         //              dataOutput.arr0[idx] = sharedData.arr1[(idx+1) % 16];
554         //              dataOutput.arr1[idx] = sharedData.arr0[(idx+1) % 16];
555         //      }
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"
631                         "                          OpReturn\n"
632                         "                          OpFunctionEnd\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"
642                         "                          OpReturn\n"
643                         "                          OpFunctionEnd\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"
654                         "                          OpReturn\n"
655                         "                          OpFunctionEnd\n";
656
657         expectedOutput.reserve(numFloats);
658         for (deUint32 vecIdx = 0; vecIdx < numFloats / 8; ++vecIdx)
659         {
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);
664         }
665         for (deUint32 vecIdx = 0; vecIdx < numFloats / 8; ++vecIdx)
666         {
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);
671         }
672
673         spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
674         requiredFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS;
675         spec.extensions.push_back("VK_KHR_variable_pointers");
676
677         spec.assembly                                   = shaderSource;
678         spec.numWorkGroups                              = IVec3(1, 1, 1);
679
680         group->addChild(new SpvAsmComputeShaderCase(testCtx, "workgroup_memory_variable_pointers", "", spec));
681 }
682
683 void addGraphicsPointerParamToParamTest (tcu::TestCaseGroup* group)
684 {
685         map<string, string>     fragments;
686         RGBA                            defaultColors[4];
687         GraphicsResources       resources;
688         vector<string>          extensions;
689         vector<float>           expectedOutput;
690         VulkanFeatures          requiredFeatures;
691
692         // Implements the following pseudo GLSL shader:
693         //
694         //      float func(alias float* f, alias float* g)
695         //      {
696         //              *g = 5.0;
697         //              *f = 2.0;
698         //              return *g;
699         //      }
700         //
701         //      vec4 test_code(vec4 param)
702         //      {
703         //              float a = 0.0;
704         //              o = func(&a, &a);  // should return 2.0
705         //              float b = 0.0;
706         //              o += func(&a, &b); // should return 5.0
707         //              return param;
708         //      }
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"
725                 "                          OpFunctionEnd\n";
726
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";
734
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"
750                 "                          OpFunctionEnd\n";
751
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));
756
757         createTestsForAllStages("global_to_param", defaultColors, defaultColors, fragments, resources, extensions, group, requiredFeatures);
758 }
759
760 void addGraphicsPointerParamToGlobalTest (tcu::TestCaseGroup* group)
761 {
762         map<string, string>     fragments;
763         RGBA                            defaultColors[4];
764         GraphicsResources       resources;
765         vector<string>          extensions;
766         vector<float>           expectedOutput;
767         VulkanFeatures          requiredFeatures;
768
769         // Implements the following pseudo GLSL shader:
770         //
771         //      alias float a = 0.0;
772         //
773         //      float func0(alias float* f0) // f in Private storage class
774         //      {
775         //              *a = 5.0;
776         //              *f0 = 2.0;
777         //              return *a;
778         //      }
779         //
780         //      float func1(alias float* f1) // f in Function storage class
781         //      {
782         //              *a = 5.0;
783         //              *f1 = 2.0;
784         //              return *a;
785         //      }
786         //
787         //      vec4 test_code(vec4 param)
788         //      {
789         //              o = func0(&a);  // should return 2.0
790         //              float b = 0.0;
791         //              o += func1(&b); // should return 5.0
792         //              return param;
793         //      }
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"
812                 "                          OpFunctionEnd\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"
820                 "                          OpFunctionEnd\n";
821
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";
830
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"
845                 "                          OpFunctionEnd\n";
846
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));
851
852         createTestsForAllStages("param_to_global", defaultColors, defaultColors, fragments, resources, extensions, group, requiredFeatures);
853 }
854
855 void addGraphicsPointerBufferMemoryTest (tcu::TestCaseGroup* group)
856 {
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;
864
865         // Implements the following pseudo GLSL shader:
866         //
867         //      layout (binding = 0) buffer Output
868         //      {
869         //              vec4 arr0[2];
870         //              vec4 arr1[];
871         //      } dataOutput;
872         //
873         //      void func0(vec4* f0[2], uint i)
874         //      {
875         //              f0[i] = vec4(5.0);
876         //      }
877         //
878         //      void func1(vec4* f1[], uint i)
879         //      {
880         //              f1[i] = vec4(2.0);
881         //      }
882         //
883         //      vec4 test_code(vec4 param)
884         //      {
885         //              func0(dataOutput.arr0, idx);
886         //              func1(dataOutput.arr1, idx);
887         //              return param;
888         //      }
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"
911                 "                          OpReturn\n"
912                 "                          OpFunctionEnd\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"
920                 "                          OpReturn\n"
921                 "                          OpFunctionEnd\n";
922
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";
935
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"
945                 "                          OpFunctionEnd\n";
946
947         fragments["extension"]  =
948                 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
949
950         getDefaultColors(defaultColors);
951
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);
956
957         requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
958         resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
959
960         createTestsForAllStages("buffer_memory", defaultColors, defaultColors, fragments, resources, extensions, group, requiredFeatures);
961 }
962
963 void addGraphicsPointerBufferMemoryVariablePointersTest (tcu::TestCaseGroup* group)
964 {
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;
972
973         // Implements the following pseudo GLSL shader:
974         //
975         //      layout (binding = 0) buffer Output
976         //      {
977         //              vec4 arr0[2];
978         //              vec4 arr1[];
979         //      } dataOutput;
980         //
981         //      void func0(vec4* f0[2], uint i)
982         //      {
983         //              f0[i] = vec4(5.0);
984         //      }
985         //
986         //      void func1(vec4* f1[], uint i)
987         //      {
988         //              f1[i] = vec4(2.0);
989         //      }
990         //
991         //      vec4 test_code(vec4 param)
992         //      {
993         //              func0(dataOutput.arr0, idx);
994         //              func1(dataOutput.arr1, idx);
995         //              return param;
996         //      }
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"
1019                 "                          OpReturn\n"
1020                 "                          OpFunctionEnd\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"
1028                 "                          OpReturn\n"
1029                 "                          OpFunctionEnd\n";
1030
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";
1039
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"
1049                 "                          OpFunctionEnd\n";
1050
1051         fragments["extension"]  =
1052                 "OpExtension \"SPV_KHR_variable_pointers\"\n"
1053                 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
1054
1055         fragments["capability"] =
1056                 "OpCapability VariablePointersStorageBuffer\n";
1057
1058         getDefaultColors(defaultColors);
1059
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);
1064
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));
1068
1069         createTestsForAllStages("buffer_memory_variable_pointers", defaultColors, defaultColors, fragments, resources, extensions, group, requiredFeatures);
1070 }
1071
1072 } // anonymous
1073
1074 tcu::TestCaseGroup* createPointerParameterComputeGroup (tcu::TestContext& testCtx)
1075 {
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());
1082
1083         return group.release();
1084 }
1085
1086 tcu::TestCaseGroup* createPointerParameterGraphicsGroup (tcu::TestContext& testCtx)
1087 {
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());
1093
1094         return group.release();
1095 }
1096
1097 } // SpirVAssembly
1098 } // vkt