Require variablePointersStorageBuffer feature in pointer_parameter tests
[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         VulkanFeatures          requiredFeatures;
266
267         // Implements the following pseudo GLSL shader:
268         //
269         //      layout (binding = 0) buffer Output
270         //      {
271         //              vec4 arr0[16];
272         //              vec4 arr1[];
273         //      } dataOutput;
274         //
275         //      void func0(vec4* f0[16], uint i)
276         //      {
277         //              f0[i] = vec4(5.0);
278         //      }
279         //
280         //      void func1(vec4* f1[], uint i)
281         //      {
282         //              f1[i] = vec4(2.0);
283         //      }
284         //
285         //      void main()
286         //      {
287         //              uint idx = gl_GlobalInvocationID.x;
288         //              func0(dataOutput.arr0, idx);
289         //              func1(dataOutput.arr1, idx);
290         //      }
291         const string            shaderSource            =
292                         "                          OpCapability Shader\n"
293                         "                          OpCapability VariablePointersStorageBuffer\n"
294                         "                          OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
295                         "                          OpExtension \"SPV_KHR_variable_pointers\"\n"
296                         "                     %1 = OpExtInstImport \"GLSL.std.450\"\n"
297                         "                          OpMemoryModel Logical GLSL450\n"
298                         "                          OpEntryPoint GLCompute %main \"main\" %gl_GlobalInvocationID\n"
299                         "                          OpExecutionMode %main LocalSize 1 1 1\n"
300                         "                          OpSource GLSL 430\n"
301                         "                          OpMemberDecorate %Output 0 Offset 0\n"
302                         "                          OpMemberDecorate %Output 1 Offset 256\n"
303                         "                          OpDecorate %arr_vec4_16 ArrayStride 16\n"
304                         "                          OpDecorate %arr_vec4_rt ArrayStride 16\n"
305                         "                          OpDecorate %Output Block\n"
306                         "                          OpDecorate %dataOutput DescriptorSet 0\n"
307                         "                          OpDecorate %dataOutput Binding 0\n"
308                         "                          OpDecorate %f0 DescriptorSet 0\n"
309                         "                          OpDecorate %f0 Binding 0\n"
310                         "                          OpDecorate %f1 DescriptorSet 0\n"
311                         "                          OpDecorate %f1 Binding 0\n"
312                         "                          OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId\n"
313                         "                  %void = OpTypeVoid\n"
314                         "             %void_func = OpTypeFunction %void\n"
315                         "                 %float = OpTypeFloat 32\n"
316                         "   %_ptr_Function_float = OpTypePointer Function %float\n"
317                         "               %float_5 = OpConstant %float 5\n"
318                         "               %float_2 = OpConstant %float 2\n"
319                         "                  %uint = OpTypeInt 32 0\n"
320                         "    %_ptr_Function_uint = OpTypePointer Function %uint\n"
321                         "               %uint_16 = OpConstant %uint 16\n"
322                         "                  %vec4 = OpTypeVector %float 4\n"
323                         "                %vec4_5 = OpConstantComposite %vec4 %float_5 %float_5 %float_5 %float_5\n"
324                         "                %vec4_2 = OpConstantComposite %vec4 %float_2 %float_2 %float_2 %float_2\n"
325                         "           %arr_vec4_16 = OpTypeArray %vec4 %uint_16\n"
326                         "           %arr_vec4_rt = OpTypeRuntimeArray %vec4\n"
327                         "       %arr_vec4_16_ptr = OpTypePointer StorageBuffer %arr_vec4_16\n"
328                         "       %arr_vec4_rt_ptr = OpTypePointer StorageBuffer %arr_vec4_rt\n"
329                         "            %func0_decl = OpTypeFunction %void %arr_vec4_16_ptr %_ptr_Function_uint\n"
330                         "            %func1_decl = OpTypeFunction %void %arr_vec4_rt_ptr %_ptr_Function_uint\n"
331                         "                %Output = OpTypeStruct %arr_vec4_16 %arr_vec4_rt\n"
332                         "        %_ptr_sb_Output = OpTypePointer StorageBuffer %Output\n"
333                         "            %dataOutput = OpVariable %_ptr_sb_Output StorageBuffer\n"
334                         "                   %int = OpTypeInt 32 1\n"
335                         "                 %int_0 = OpConstant %int 0\n"
336                         "                 %int_1 = OpConstant %int 1\n"
337                         "                %v3uint = OpTypeVector %uint 3\n"
338                         "     %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
339                         " %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
340                         "                %uint_0 = OpConstant %uint 0\n"
341                         "       %_ptr_Input_uint = OpTypePointer Input %uint\n"
342                         "          %_ptr_sb_vec4 = OpTypePointer StorageBuffer %vec4\n"
343                         "                  %main = OpFunction %void None %void_func\n"
344                         "                 %entry = OpLabel\n"
345                         "                   %idx = OpVariable %_ptr_Function_uint Function\n"
346                         "            %inv_id_ptr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0\n"
347                         "                %inv_id = OpLoad %uint %inv_id_ptr\n"
348                         "                          OpStore %idx %inv_id\n"
349                         "                  %ptr0 = OpAccessChain %arr_vec4_16_ptr %dataOutput %int_0\n"
350                         "                  %ptr1 = OpAccessChain %arr_vec4_rt_ptr %dataOutput %int_1\n"
351                         "                  %ret0 = OpFunctionCall %void %func0 %ptr0 %idx\n"
352                         "                  %ret1 = OpFunctionCall %void %func1 %ptr1 %idx\n"
353                         "                          OpReturn\n"
354                         "                          OpFunctionEnd\n"
355                         "                 %func0 = OpFunction %void None %func0_decl\n"
356                         "                    %f0 = OpFunctionParameter %arr_vec4_16_ptr\n"
357                         "                    %i0 = OpFunctionParameter %_ptr_Function_uint\n"
358                         "           %func0_entry = OpLabel\n"
359                         "                  %idx0 = OpLoad %uint %i0\n"
360                         "              %out_ptr0 = OpAccessChain %_ptr_sb_vec4 %f0 %idx0\n"
361                         "                          OpStore %out_ptr0 %vec4_5\n"
362                         "                          OpReturn\n"
363                         "                          OpFunctionEnd\n"
364                         "                 %func1 = OpFunction %void None %func1_decl\n"
365                         "                    %f1 = OpFunctionParameter %arr_vec4_rt_ptr\n"
366                         "                    %i1 = OpFunctionParameter %_ptr_Function_uint\n"
367                         "           %func1_entry = OpLabel\n"
368                         "                  %idx1 = OpLoad %uint %i1\n"
369                         "              %out_ptr1 = OpAccessChain %_ptr_sb_vec4 %f1 %idx1\n"
370                         "                          OpStore %out_ptr1 %vec4_2\n"
371                         "                          OpReturn\n"
372                         "                          OpFunctionEnd\n";
373
374         expectedOutput.reserve(numFloats);
375         for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
376                 expectedOutput.push_back(5.0f);
377         for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
378                 expectedOutput.push_back(2.0f);
379
380         requiredFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER;
381
382         spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
383
384         spec.assembly                                   = shaderSource;
385         spec.numWorkGroups                              = IVec3(16, 1, 1);
386         spec.requestedVulkanFeatures    = requiredFeatures;
387         spec.extensions.push_back("VK_KHR_variable_pointers");
388
389         group->addChild(new SpvAsmComputeShaderCase(testCtx, "buffer_memory", "", spec));
390 }
391
392 void addComputePointerBufferMemoryVariablePointersTest (tcu::TestCaseGroup* group)
393 {
394         tcu::TestContext&       testCtx                         = group->getTestContext();
395         const int                       numFloats                       = 128;
396         ComputeShaderSpec       spec;
397         VulkanFeatures          requiredFeatures;
398         vector<float>           expectedOutput;
399
400         // Implements the following pseudo GLSL shader:
401         //
402         //      layout (binding = 0) buffer Output
403         //      {
404         //              vec4 arr0[16];
405         //              vec4 arr1[];
406         //      } dataOutput;
407         //
408         //      void func0(vec4* f0[16], uint i)
409         //      {
410         //              f0[i] = vec4(5.0);
411         //      }
412         //
413         //      void func1(vec4* f1[], uint i)
414         //      {
415         //              f1[i] = vec4(2.0);
416         //      }
417         //
418         //      void main()
419         //      {
420         //              uint idx = gl_GlobalInvocationID.x;
421         //              func0(dataOutput.arr0, idx);
422         //              func1(dataOutput.arr1, idx);
423         //      }
424         const string            shaderSource            =
425                         "                          OpCapability Shader\n"
426                         "                          OpCapability VariablePointersStorageBuffer\n"
427                         "                          OpExtension \"SPV_KHR_variable_pointers\"\n"
428                         "                          OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
429                         "                     %1 = OpExtInstImport \"GLSL.std.450\"\n"
430                         "                          OpMemoryModel Logical GLSL450\n"
431                         "                          OpEntryPoint GLCompute %main \"main\" %gl_GlobalInvocationID\n"
432                         "                          OpExecutionMode %main LocalSize 1 1 1\n"
433                         "                          OpSource GLSL 430\n"
434                         "                          OpMemberDecorate %Output 0 Offset 0\n"
435                         "                          OpMemberDecorate %Output 1 Offset 256\n"
436                         "                          OpDecorate %arr_vec4_16 ArrayStride 16\n"
437                         "                          OpDecorate %arr_vec4_rt ArrayStride 16\n"
438                         "                          OpDecorate %Output Block\n"
439                         "                          OpDecorate %dataOutput DescriptorSet 0\n"
440                         "                          OpDecorate %dataOutput Binding 0\n"
441                         "                          OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId\n"
442                         "                  %void = OpTypeVoid\n"
443                         "             %void_func = OpTypeFunction %void\n"
444                         "                 %float = OpTypeFloat 32\n"
445                         "   %_ptr_Function_float = OpTypePointer Function %float\n"
446                         "               %float_5 = OpConstant %float 5\n"
447                         "               %float_2 = OpConstant %float 2\n"
448                         "                  %uint = OpTypeInt 32 0\n"
449                         "    %_ptr_Function_uint = OpTypePointer Function %uint\n"
450                         "               %uint_16 = OpConstant %uint 16\n"
451                         "                  %vec4 = OpTypeVector %float 4\n"
452                         "                %vec4_5 = OpConstantComposite %vec4 %float_5 %float_5 %float_5 %float_5\n"
453                         "                %vec4_2 = OpConstantComposite %vec4 %float_2 %float_2 %float_2 %float_2\n"
454                         "           %arr_vec4_16 = OpTypeArray %vec4 %uint_16\n"
455                         "           %arr_vec4_rt = OpTypeRuntimeArray %vec4\n"
456                         "       %arr_vec4_16_ptr = OpTypePointer StorageBuffer %arr_vec4_16\n"
457                         "       %arr_vec4_rt_ptr = OpTypePointer StorageBuffer %arr_vec4_rt\n"
458                         "            %func0_decl = OpTypeFunction %void %arr_vec4_16_ptr %_ptr_Function_uint\n"
459                         "            %func1_decl = OpTypeFunction %void %arr_vec4_rt_ptr %_ptr_Function_uint\n"
460                         "                %Output = OpTypeStruct %arr_vec4_16 %arr_vec4_rt\n"
461                         "        %_ptr_sb_Output = OpTypePointer StorageBuffer %Output\n"
462                         "            %dataOutput = OpVariable %_ptr_sb_Output StorageBuffer\n"
463                         "                   %int = OpTypeInt 32 1\n"
464                         "                 %int_0 = OpConstant %int 0\n"
465                         "                 %int_1 = OpConstant %int 1\n"
466                         "                %v3uint = OpTypeVector %uint 3\n"
467                         "     %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
468                         " %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
469                         "                %uint_0 = OpConstant %uint 0\n"
470                         "       %_ptr_Input_uint = OpTypePointer Input %uint\n"
471                         "          %_ptr_sb_vec4 = OpTypePointer StorageBuffer %vec4\n"
472                         "                  %main = OpFunction %void None %void_func\n"
473                         "                 %entry = OpLabel\n"
474                         "                   %idx = OpVariable %_ptr_Function_uint Function\n"
475                         "            %inv_id_ptr = OpAccessChain %_ptr_Input_uint %gl_GlobalInvocationID %uint_0\n"
476                         "                %inv_id = OpLoad %uint %inv_id_ptr\n"
477                         "                          OpStore %idx %inv_id\n"
478                         "                  %ptr0 = OpAccessChain %arr_vec4_16_ptr %dataOutput %int_0\n"
479                         "                  %ptr1 = OpAccessChain %arr_vec4_rt_ptr %dataOutput %int_1\n"
480                         "                  %ret0 = OpFunctionCall %void %func0 %ptr0 %idx\n"
481                         "                  %ret1 = OpFunctionCall %void %func1 %ptr1 %idx\n"
482                         "                          OpReturn\n"
483                         "                          OpFunctionEnd\n"
484                         "                 %func0 = OpFunction %void None %func0_decl\n"
485                         "                    %f0 = OpFunctionParameter %arr_vec4_16_ptr\n"
486                         "                    %i0 = OpFunctionParameter %_ptr_Function_uint\n"
487                         "           %func0_entry = OpLabel\n"
488                         "                  %idx0 = OpLoad %uint %i0\n"
489                         "              %out_ptr0 = OpAccessChain %_ptr_sb_vec4 %f0 %idx0\n"
490                         "                          OpStore %out_ptr0 %vec4_5\n"
491                         "                          OpReturn\n"
492                         "                          OpFunctionEnd\n"
493                         "                 %func1 = OpFunction %void None %func1_decl\n"
494                         "                    %f1 = OpFunctionParameter %arr_vec4_rt_ptr\n"
495                         "                    %i1 = OpFunctionParameter %_ptr_Function_uint\n"
496                         "           %func1_entry = OpLabel\n"
497                         "                  %idx1 = OpLoad %uint %i1\n"
498                         "              %out_ptr1 = OpAccessChain %_ptr_sb_vec4 %f1 %idx1\n"
499                         "                          OpStore %out_ptr1 %vec4_2\n"
500                         "                          OpReturn\n"
501                         "                          OpFunctionEnd\n";
502
503         expectedOutput.reserve(numFloats);
504         for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
505                 expectedOutput.push_back(5.0f);
506         for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
507                 expectedOutput.push_back(2.0f);
508
509         requiredFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER;
510         spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
511         spec.extensions.push_back("VK_KHR_variable_pointers");
512
513         spec.assembly                                   = shaderSource;
514         spec.numWorkGroups                              = IVec3(16, 1, 1);
515         spec.requestedVulkanFeatures    = requiredFeatures;
516
517         group->addChild(new SpvAsmComputeShaderCase(testCtx, "buffer_memory_variable_pointers", "", spec));
518 }
519
520 void addComputePointerWorkgroupMemoryVariablePointersTest (tcu::TestCaseGroup* group)
521 {
522         tcu::TestContext&       testCtx                         = group->getTestContext();
523         const int                       numFloats                       = 128;
524         ComputeShaderSpec       spec;
525         VulkanFeatures          requiredFeatures;
526         vector<float>           expectedOutput;
527
528         // Implements the following pseudo GLSL shader:
529         //
530         //      layout (local_size_x = 16, local_size_y = 1, local_size_z = 1) in;
531         //
532         //      layout (binding = 0) buffer Output
533         //      {
534         //              vec4 arr0[16];
535         //              vec4 arr1[];
536         //      } dataOutput;
537         //
538         //      shared struct
539         //      {
540         //              vec4 arr0[16];
541         //              vec4 arr1[16];
542         //      } sharedData;
543         //
544         //      void func0(vec4* f0[16], uint i)
545         //      {
546         //              f0[i] = vec4(i);
547         //      }
548         //
549         //      void func1(vec4* f1[16], uint i)
550         //      {
551         //              f1[i] = vec4(i+5);
552         //      }
553         //
554         //      void main()
555         //      {
556         //              uint idx = gl_LocalInvocationID.x;
557         //              func0(sharedData.arr0, idx);
558         //              func1(sharedData.arr1, idx);
559         //              barier();
560         //              dataOutput.arr0[idx] = sharedData.arr1[(idx+1) % 16];
561         //              dataOutput.arr1[idx] = sharedData.arr0[(idx+1) % 16];
562         //      }
563         const string            shaderSource            =
564                         "                          OpCapability Shader\n"
565                         "                          OpCapability VariablePointers\n"
566                         "                          OpExtension \"SPV_KHR_variable_pointers\"\n"
567                         "                          OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
568                         "                     %1 = OpExtInstImport \"GLSL.std.450\"\n"
569                         "                          OpMemoryModel Logical GLSL450\n"
570                         "                          OpEntryPoint GLCompute %main \"main\" %gl_LocalInvocationID\n"
571                         "                          OpExecutionMode %main LocalSize 16 1 1\n"
572                         "                          OpSource GLSL 430\n"
573                         "                          OpMemberDecorate %Output 0 Offset 0\n"
574                         "                          OpMemberDecorate %Output 1 Offset 256\n"
575                         "                          OpMemberDecorate %struct 0 Offset 0\n"
576                         "                          OpMemberDecorate %struct 1 Offset 256\n"
577                         "                          OpDecorate %arr_vec4_16 ArrayStride 16\n"
578                         "                          OpDecorate %arr_vec4_rt ArrayStride 16\n"
579                         "                          OpDecorate %Output Block\n"
580                         "                          OpDecorate %dataOutput DescriptorSet 0\n"
581                         "                          OpDecorate %dataOutput Binding 0\n"
582                         "                          OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId\n"
583                         "                  %void = OpTypeVoid\n"
584                         "             %void_func = OpTypeFunction %void\n"
585                         "                 %float = OpTypeFloat 32\n"
586                         "   %_ptr_Function_float = OpTypePointer Function %float\n"
587                         "                  %uint = OpTypeInt 32 0\n"
588                         "    %_ptr_Function_uint = OpTypePointer Function %uint\n"
589                         "                %uint_1 = OpConstant %uint 1\n"
590                         "                %uint_2 = OpConstant %uint 2\n"
591                         "                %uint_5 = OpConstant %uint 5\n"
592                         "               %uint_16 = OpConstant %uint 16\n"
593                         "              %uint_264 = OpConstant %uint 264\n"
594                         "                  %vec4 = OpTypeVector %float 4\n"
595                         "           %arr_vec4_16 = OpTypeArray %vec4 %uint_16\n"
596                         "           %arr_vec4_rt = OpTypeRuntimeArray %vec4\n"
597                         "    %arr_vec4_16_sb_ptr = OpTypePointer StorageBuffer %arr_vec4_16\n"
598                         "    %arr_vec4_rt_sb_ptr = OpTypePointer StorageBuffer %arr_vec4_rt\n"
599                         "    %arr_vec4_16_wg_ptr = OpTypePointer Workgroup %arr_vec4_16\n"
600                         "             %func_decl = OpTypeFunction %void %arr_vec4_16_wg_ptr %_ptr_Function_uint\n"
601                         "                %Output = OpTypeStruct %arr_vec4_16 %arr_vec4_rt\n"
602                         "                %struct = OpTypeStruct %arr_vec4_16 %arr_vec4_16\n"
603                         "        %_ptr_sb_struct = OpTypePointer StorageBuffer %Output\n"
604                         "        %_ptr_wg_struct = OpTypePointer Workgroup %struct\n"
605                         "            %dataOutput = OpVariable %_ptr_sb_struct StorageBuffer\n"
606                         "            %sharedData = OpVariable %_ptr_wg_struct Workgroup\n"
607                         "                   %int = OpTypeInt 32 1\n"
608                         "                 %int_0 = OpConstant %int 0\n"
609                         "                 %int_1 = OpConstant %int 1\n"
610                         "                %v3uint = OpTypeVector %uint 3\n"
611                         "     %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
612                         "  %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
613                         "                %uint_0 = OpConstant %uint 0\n"
614                         "       %_ptr_Input_uint = OpTypePointer Input %uint\n"
615                         "          %_ptr_sb_vec4 = OpTypePointer StorageBuffer %vec4\n"
616                         "          %_ptr_wg_vec4 = OpTypePointer Workgroup %vec4\n"
617                         "                  %main = OpFunction %void None %void_func\n"
618                         "                 %entry = OpLabel\n"
619                         "                   %idx = OpVariable %_ptr_Function_uint Function\n"
620                         "            %inv_id_ptr = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %uint_0\n"
621                         "                %inv_id = OpLoad %uint %inv_id_ptr\n"
622                         "                          OpStore %idx %inv_id\n"
623                         "                  %ptr0 = OpAccessChain %arr_vec4_16_wg_ptr %sharedData %int_0\n"
624                         "                  %ptr1 = OpAccessChain %arr_vec4_16_wg_ptr %sharedData %int_1\n"
625                         "                  %ret0 = OpFunctionCall %void %func0 %ptr0 %idx\n"
626                         "                  %ret1 = OpFunctionCall %void %func1 %ptr1 %idx\n"
627                         "                          OpControlBarrier %uint_2 %uint_2 %uint_264\n"
628                         "          %inv_id_plus1 = OpIAdd %uint %inv_id %uint_1\n"
629                         "            %inv_id_mod = OpUMod %uint %inv_id_plus1 %uint_16\n"
630                         "       %shared_arr1_ptr = OpAccessChain %_ptr_wg_vec4 %sharedData %int_1 %inv_id_mod\n"
631                         "      %shared_arr1_data = OpLoad %vec4 %shared_arr1_ptr\n"
632                         "               %outPtr0 = OpAccessChain %_ptr_sb_vec4 %dataOutput %int_0 %inv_id\n"
633                         "                          OpStore %outPtr0 %shared_arr1_data\n"
634                         "       %shared_arr0_ptr = OpAccessChain %_ptr_wg_vec4 %sharedData %int_0 %inv_id_mod\n"
635                         "      %shared_arr0_data = OpLoad %vec4 %shared_arr0_ptr\n"
636                         "               %outPtr1 = OpAccessChain %_ptr_sb_vec4 %dataOutput %int_1 %inv_id\n"
637                         "                          OpStore %outPtr1 %shared_arr0_data\n"
638                         "                          OpReturn\n"
639                         "                          OpFunctionEnd\n"
640                         "                 %func0 = OpFunction %void None %func_decl\n"
641                         "                    %f0 = OpFunctionParameter %arr_vec4_16_wg_ptr\n"
642                         "                    %i0 = OpFunctionParameter %_ptr_Function_uint\n"
643                         "           %func0_entry = OpLabel\n"
644                         "                  %idx0 = OpLoad %uint %i0\n"
645                         "              %out_ptr0 = OpAccessChain %_ptr_wg_vec4 %f0 %idx0\n"
646                         "             %idxFloat0 = OpConvertUToF %float %idx0\n"
647                         "              %outData0 = OpCompositeConstruct %vec4 %idxFloat0 %idxFloat0 %idxFloat0 %idxFloat0\n"
648                         "                          OpStore %out_ptr0 %outData0\n"
649                         "                          OpReturn\n"
650                         "                          OpFunctionEnd\n"
651                         "                 %func1 = OpFunction %void None %func_decl\n"
652                         "                    %f1 = OpFunctionParameter %arr_vec4_16_wg_ptr\n"
653                         "                    %i1 = OpFunctionParameter %_ptr_Function_uint\n"
654                         "           %func1_entry = OpLabel\n"
655                         "                  %idx1 = OpLoad %uint %i1\n"
656                         "              %out_ptr1 = OpAccessChain %_ptr_wg_vec4 %f1 %idx1\n"
657                         "              %idxPlus5 = OpIAdd %uint %idx1 %uint_5\n"
658                         "             %idxFloat1 = OpConvertUToF %float %idxPlus5\n"
659                         "              %outData1 = OpCompositeConstruct %vec4 %idxFloat1 %idxFloat1 %idxFloat1 %idxFloat1\n"
660                         "                          OpStore %out_ptr1 %outData1\n"
661                         "                          OpReturn\n"
662                         "                          OpFunctionEnd\n";
663
664         expectedOutput.reserve(numFloats);
665         for (deUint32 vecIdx = 0; vecIdx < numFloats / 8; ++vecIdx)
666         {
667                 const deUint32  shuffleIdx      = (vecIdx + 1) % 16;
668                 const float             val                     = (float)(shuffleIdx + 5);
669                 for (deUint32 i = 0; i < 4; ++i)
670                         expectedOutput.push_back(val);
671         }
672         for (deUint32 vecIdx = 0; vecIdx < numFloats / 8; ++vecIdx)
673         {
674                 const deUint32  shuffleIdx      = (vecIdx + 1) % 16;
675                 const float             val                     = (float)shuffleIdx;
676                 for (deUint32 i = 0; i < 4; ++i)
677                         expectedOutput.push_back(val);
678         }
679
680         spec.outputs.push_back(BufferSp(new Float32Buffer(expectedOutput)));
681         requiredFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS;
682         spec.extensions.push_back("VK_KHR_variable_pointers");
683
684         spec.assembly                                   = shaderSource;
685         spec.numWorkGroups                              = IVec3(1, 1, 1);
686         spec.requestedVulkanFeatures    = requiredFeatures;
687
688         group->addChild(new SpvAsmComputeShaderCase(testCtx, "workgroup_memory_variable_pointers", "", spec));
689 }
690
691 void addGraphicsPointerParamToParamTest (tcu::TestCaseGroup* group)
692 {
693         map<string, string>     fragments;
694         RGBA                            defaultColors[4];
695         GraphicsResources       resources;
696         vector<string>          extensions;
697         vector<float>           expectedOutput;
698         VulkanFeatures          requiredFeatures;
699
700         // Implements the following pseudo GLSL shader:
701         //
702         //      float func(alias float* f, alias float* g)
703         //      {
704         //              *g = 5.0;
705         //              *f = 2.0;
706         //              return *g;
707         //      }
708         //
709         //      vec4 test_code(vec4 param)
710         //      {
711         //              float a = 0.0;
712         //              o = func(&a, &a);  // should return 2.0
713         //              float b = 0.0;
714         //              o += func(&a, &b); // should return 5.0
715         //              return param;
716         //      }
717         fragments["pre_main"]   =
718                 "            %func0_decl = OpTypeFunction %f32 %fp_f32 %fp_f32\n"
719                 "               %c_f32_5 = OpConstant %f32 5\n"
720                 "               %c_f32_2 = OpConstant %f32 2\n"
721                 "                %Output = OpTypeStruct %f32\n"
722                 "   %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
723                 "            %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
724                 "      %_ptr_Uniform_f32 = OpTypePointer Uniform %f32\n"
725                 "                  %func = OpFunction %f32 None %func0_decl\n"
726                 "                     %f = OpFunctionParameter %fp_f32\n"
727                 "                     %g = OpFunctionParameter %fp_f32\n"
728                 "            %func_entry = OpLabel\n"
729                 "                          OpStore %g %c_f32_5\n"
730                 "                          OpStore %f %c_f32_2\n"
731                 "                   %ret = OpLoad %f32 %g\n"
732                 "                          OpReturnValue %ret\n"
733                 "                          OpFunctionEnd\n";
734
735         fragments["decoration"] =
736                 "                          OpMemberDecorate %Output 0 Offset 0\n"
737                 "                          OpDecorate %Output BufferBlock\n"
738                 "                          OpDecorate %dataOutput DescriptorSet 0\n"
739                 "                          OpDecorate %dataOutput Binding 0\n"
740                 "                          OpDecorate %f Aliased\n"
741                 "                          OpDecorate %g Aliased\n";
742
743         fragments["testfun"]    =
744                 "             %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
745                 "                 %param = OpFunctionParameter %v4f32\n"
746                 "                 %entry = OpLabel\n"
747                 "                     %a = OpVariable %fp_f32 Function %c_f32_0\n"
748                 "                     %b = OpVariable %fp_f32 Function %c_f32_0\n"
749                 "                     %o = OpVariable %fp_f32 Function %c_f32_0\n"
750                 "                  %ret0 = OpFunctionCall %f32 %func %a %a\n"
751                 "                          OpStore %o %ret0\n"
752                 "                  %ret1 = OpFunctionCall %f32 %func %a %b\n"
753                 "                 %o_val = OpLoad %f32 %o\n"
754                 "                   %sum = OpFAdd %f32 %o_val %ret1\n"
755                 "               %out_ptr = OpAccessChain %_ptr_Uniform_f32 %dataOutput %c_i32_0\n"
756                 "                          OpStore %out_ptr %sum\n"
757                 "                          OpReturnValue %param\n"
758                 "                          OpFunctionEnd\n";
759
760         getDefaultColors(defaultColors);
761         expectedOutput.push_back(7.0f);
762         requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
763         resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
764
765         createTestsForAllStages("global_to_param", defaultColors, defaultColors, fragments, resources, extensions, group, requiredFeatures);
766 }
767
768 void addGraphicsPointerParamToGlobalTest (tcu::TestCaseGroup* group)
769 {
770         map<string, string>     fragments;
771         RGBA                            defaultColors[4];
772         GraphicsResources       resources;
773         vector<string>          extensions;
774         vector<float>           expectedOutput;
775         VulkanFeatures          requiredFeatures;
776
777         // Implements the following pseudo GLSL shader:
778         //
779         //      alias float a = 0.0;
780         //
781         //      float func0(alias float* f0) // f in Private storage class
782         //      {
783         //              *a = 5.0;
784         //              *f0 = 2.0;
785         //              return *a;
786         //      }
787         //
788         //      float func1(alias float* f1) // f in Function storage class
789         //      {
790         //              *a = 5.0;
791         //              *f1 = 2.0;
792         //              return *a;
793         //      }
794         //
795         //      vec4 test_code(vec4 param)
796         //      {
797         //              o = func0(&a);  // should return 2.0
798         //              float b = 0.0;
799         //              o += func1(&b); // should return 5.0
800         //              return param;
801         //      }
802         fragments["pre_main"] =
803                 "                %pp_f32 = OpTypePointer Private %f32\n"
804                 "            %func0_decl = OpTypeFunction %f32 %pp_f32\n"
805                 "            %func1_decl = OpTypeFunction %f32 %fp_f32\n"
806                 "               %c_f32_5 = OpConstant %f32 5\n"
807                 "               %c_f32_2 = OpConstant %f32 2\n"
808                 "                %Output = OpTypeStruct %f32\n"
809                 "   %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
810                 "            %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
811                 "      %_ptr_Uniform_f32 = OpTypePointer Uniform %f32\n"
812                 "                     %a = OpVariable %pp_f32 Private %c_f32_0\n"
813                 "                 %func0 = OpFunction %f32 None %func0_decl\n"
814                 "                    %f0 = OpFunctionParameter %pp_f32\n"
815                 "           %func0_entry = OpLabel\n"
816                 "                          OpStore %a %c_f32_5\n"
817                 "                          OpStore %f0 %c_f32_2\n"
818                 "             %func0_ret = OpLoad %f32 %a\n"
819                 "                          OpReturnValue %func0_ret\n"
820                 "                          OpFunctionEnd\n"
821                 "                 %func1 = OpFunction %f32 None %func1_decl\n"
822                 "                    %f1 = OpFunctionParameter %fp_f32\n"
823                 "           %func1_entry = OpLabel\n"
824                 "                          OpStore %a %c_f32_5\n"
825                 "                          OpStore %f1 %c_f32_2\n"
826                 "             %func1_ret = OpLoad %f32 %a\n"
827                 "                          OpReturnValue %func1_ret\n"
828                 "                          OpFunctionEnd\n";
829
830         fragments["decoration"] =
831                 "                          OpMemberDecorate %Output 0 Offset 0\n"
832                 "                          OpDecorate %Output BufferBlock\n"
833                 "                          OpDecorate %dataOutput DescriptorSet 0\n"
834                 "                          OpDecorate %dataOutput Binding 0\n"
835                 "                          OpDecorate %f0 Aliased\n"
836                 "                          OpDecorate %f1 Aliased\n"
837                 "                          OpDecorate %a Aliased\n";
838
839         fragments["testfun"] =
840                 "             %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
841                 "                 %param = OpFunctionParameter %v4f32\n"
842                 "                 %entry = OpLabel\n"
843                 "                     %b = OpVariable %fp_f32 Function %c_f32_0\n"
844                 "                     %o = OpVariable %fp_f32 Function %c_f32_0\n"
845                 "                  %ret0 = OpFunctionCall %f32 %func0 %a\n"
846                 "                          OpStore %o %ret0\n"
847                 "                  %ret1 = OpFunctionCall %f32 %func1 %b\n"
848                 "                 %o_val = OpLoad %f32 %o\n"
849                 "                   %sum = OpFAdd %f32 %o_val %ret1\n"
850                 "               %out_ptr = OpAccessChain %_ptr_Uniform_f32 %dataOutput %c_i32_0\n"
851                 "                          OpStore %out_ptr %sum\n"
852                 "                          OpReturnValue %param\n"
853                 "                          OpFunctionEnd\n";
854
855         getDefaultColors(defaultColors);
856         expectedOutput.push_back(7.0f);
857         requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
858         resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
859
860         createTestsForAllStages("param_to_global", defaultColors, defaultColors, fragments, resources, extensions, group, requiredFeatures);
861 }
862
863 void addGraphicsPointerBufferMemoryTest (tcu::TestCaseGroup* group)
864 {
865         const int                       numFloats                       = 16;
866         map<string, string>     fragments;
867         RGBA                            defaultColors[4];
868         GraphicsResources       resources;
869         vector<string>          extensions;
870         vector<float>           expectedOutput;
871         VulkanFeatures          requiredFeatures;
872
873         // Implements the following pseudo GLSL shader:
874         //
875         //      layout (binding = 0) buffer Output
876         //      {
877         //              vec4 arr0[2];
878         //              vec4 arr1[];
879         //      } dataOutput;
880         //
881         //      void func0(vec4* f0[2], uint i)
882         //      {
883         //              f0[i] = vec4(5.0);
884         //      }
885         //
886         //      void func1(vec4* f1[], uint i)
887         //      {
888         //              f1[i] = vec4(2.0);
889         //      }
890         //
891         //      vec4 test_code(vec4 param)
892         //      {
893         //              func0(dataOutput.arr0, idx);
894         //              func1(dataOutput.arr1, idx);
895         //              return param;
896         //      }
897         fragments["pre_main"]   =
898                 "           %arr_v4f32_2 = OpTypeArray %v4f32 %c_u32_2\n"
899                 "          %arr_v4f32_rt = OpTypeRuntimeArray %v4f32\n"
900                 "       %arr_v4f32_2_ptr = OpTypePointer StorageBuffer %arr_v4f32_2\n"
901                 "      %arr_v4f32_rt_ptr = OpTypePointer StorageBuffer %arr_v4f32_rt\n"
902                 "            %func0_decl = OpTypeFunction %void %arr_v4f32_2_ptr\n"
903                 "            %func1_decl = OpTypeFunction %void %arr_v4f32_rt_ptr\n"
904                 "               %c_f32_5 = OpConstant %f32 5\n"
905                 "               %c_f32_2 = OpConstant %f32 2\n"
906                 "             %c_v4f32_5 = OpConstantComposite %v4f32 %c_f32_5 %c_f32_5 %c_f32_5 %c_f32_5\n"
907                 "             %c_v4f32_2 = OpConstantComposite %v4f32 %c_f32_2 %c_f32_2 %c_f32_2 %c_f32_2\n"
908                 "                %Output = OpTypeStruct %arr_v4f32_2 %arr_v4f32_rt\n"
909                 "        %_ptr_sb_Output = OpTypePointer StorageBuffer %Output\n"
910                 "            %dataOutput = OpVariable %_ptr_sb_Output StorageBuffer\n"
911                 "         %_ptr_sb_v4f32 = OpTypePointer StorageBuffer %v4f32\n"
912                 "                 %func0 = OpFunction %void None %func0_decl\n"
913                 "                    %f0 = OpFunctionParameter %arr_v4f32_2_ptr\n"
914                 "            %func0Entry = OpLabel\n"
915                 "              %out_ptr0 = OpAccessChain %_ptr_sb_v4f32 %f0 %c_i32_0\n"
916                 "                          OpStore %out_ptr0 %c_v4f32_5\n"
917                 "              %out_ptr1 = OpAccessChain %_ptr_sb_v4f32 %f0 %c_i32_1\n"
918                 "                          OpStore %out_ptr1 %c_v4f32_5\n"
919                 "                          OpReturn\n"
920                 "                          OpFunctionEnd\n"
921                 "                 %func1 = OpFunction %void None %func1_decl\n"
922                 "                    %f1 = OpFunctionParameter %arr_v4f32_rt_ptr\n"
923                 "            %func1Entry = OpLabel\n"
924                 "              %out_ptr2 = OpAccessChain %_ptr_sb_v4f32 %f1 %c_i32_0\n"
925                 "                          OpStore %out_ptr2 %c_v4f32_2\n"
926                 "              %out_ptr3 = OpAccessChain %_ptr_sb_v4f32 %f1 %c_i32_1\n"
927                 "                          OpStore %out_ptr3 %c_v4f32_2\n"
928                 "                          OpReturn\n"
929                 "                          OpFunctionEnd\n";
930
931         fragments["decoration"] =
932                 "                          OpMemberDecorate %Output 0 Offset 0\n"
933                 "                          OpMemberDecorate %Output 1 Offset 32\n"
934                 "                          OpDecorate %Output Block\n"
935                 "                          OpDecorate %dataOutput DescriptorSet 0\n"
936                 "                          OpDecorate %dataOutput Binding 0\n"
937                 "                          OpDecorate %f0 DescriptorSet 0\n"
938                 "                          OpDecorate %f0 Binding 0\n"
939                 "                          OpDecorate %f1 DescriptorSet 0\n"
940                 "                          OpDecorate %f1 Binding 0\n"
941                 "                          OpDecorate %arr_v4f32_2 ArrayStride 16\n"
942                 "                          OpDecorate %arr_v4f32_rt ArrayStride 16\n";
943
944         fragments["testfun"]    =
945                 "             %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
946                 "                 %param = OpFunctionParameter %v4f32\n"
947                 "                 %entry = OpLabel\n"
948                 "                  %ptr0 = OpAccessChain %arr_v4f32_2_ptr %dataOutput %c_i32_0\n"
949                 "                  %ptr1 = OpAccessChain %arr_v4f32_rt_ptr %dataOutput %c_i32_1\n"
950                 "                  %ret0 = OpFunctionCall %void %func0 %ptr0\n"
951                 "                  %ret1 = OpFunctionCall %void %func1 %ptr1\n"
952                 "                          OpReturnValue %param\n"
953                 "                          OpFunctionEnd\n";
954
955         fragments["extension"]  =
956                 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
957                 "OpExtension \"SPV_KHR_variable_pointers\"\n";
958
959         fragments["capability"] =
960                 "OpCapability VariablePointersStorageBuffer\n";
961
962         getDefaultColors(defaultColors);
963
964         for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
965                 expectedOutput.push_back(5.0f);
966         for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
967                 expectedOutput.push_back(2.0f);
968
969         extensions.push_back("VK_KHR_variable_pointers");
970         requiredFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER;
971         requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
972         resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
973
974         createTestsForAllStages("buffer_memory", defaultColors, defaultColors, fragments, resources, extensions, group, requiredFeatures);
975 }
976
977 void addGraphicsPointerBufferMemoryVariablePointersTest (tcu::TestCaseGroup* group)
978 {
979         const int                       numFloats                       = 16;
980         map<string, string>     fragments;
981         RGBA                            defaultColors[4];
982         GraphicsResources       resources;
983         vector<string>          extensions;
984         vector<float>           expectedOutput;
985         VulkanFeatures          requiredFeatures;
986
987         // Implements the following pseudo GLSL shader:
988         //
989         //      layout (binding = 0) buffer Output
990         //      {
991         //              vec4 arr0[2];
992         //              vec4 arr1[];
993         //      } dataOutput;
994         //
995         //      void func0(vec4* f0[2], uint i)
996         //      {
997         //              f0[i] = vec4(5.0);
998         //      }
999         //
1000         //      void func1(vec4* f1[], uint i)
1001         //      {
1002         //              f1[i] = vec4(2.0);
1003         //      }
1004         //
1005         //      vec4 test_code(vec4 param)
1006         //      {
1007         //              func0(dataOutput.arr0, idx);
1008         //              func1(dataOutput.arr1, idx);
1009         //              return param;
1010         //      }
1011         fragments["pre_main"]   =
1012                 "           %arr_v4f32_2 = OpTypeArray %v4f32 %c_u32_2\n"
1013                 "          %arr_v4f32_rt = OpTypeRuntimeArray %v4f32\n"
1014                 "       %arr_v4f32_2_ptr = OpTypePointer StorageBuffer %arr_v4f32_2\n"
1015                 "      %arr_v4f32_rt_ptr = OpTypePointer StorageBuffer %arr_v4f32_rt\n"
1016                 "            %func0_decl = OpTypeFunction %void %arr_v4f32_2_ptr\n"
1017                 "            %func1_decl = OpTypeFunction %void %arr_v4f32_rt_ptr\n"
1018                 "               %c_f32_5 = OpConstant %f32 5\n"
1019                 "               %c_f32_2 = OpConstant %f32 2\n"
1020                 "             %c_v4f32_5 = OpConstantComposite %v4f32 %c_f32_5 %c_f32_5 %c_f32_5 %c_f32_5\n"
1021                 "             %c_v4f32_2 = OpConstantComposite %v4f32 %c_f32_2 %c_f32_2 %c_f32_2 %c_f32_2\n"
1022                 "                %Output = OpTypeStruct %arr_v4f32_2 %arr_v4f32_rt\n"
1023                 "        %_ptr_sb_Output = OpTypePointer StorageBuffer %Output\n"
1024                 "            %dataOutput = OpVariable %_ptr_sb_Output StorageBuffer\n"
1025                 "         %_ptr_sb_v4f32 = OpTypePointer StorageBuffer %v4f32\n"
1026                 "                 %func0 = OpFunction %void None %func0_decl\n"
1027                 "                    %f0 = OpFunctionParameter %arr_v4f32_2_ptr\n"
1028                 "            %func0Entry = OpLabel\n"
1029                 "              %out_ptr0 = OpAccessChain %_ptr_sb_v4f32 %f0 %c_i32_0\n"
1030                 "                          OpStore %out_ptr0 %c_v4f32_5\n"
1031                 "              %out_ptr1 = OpAccessChain %_ptr_sb_v4f32 %f0 %c_i32_1\n"
1032                 "                          OpStore %out_ptr1 %c_v4f32_5\n"
1033                 "                          OpReturn\n"
1034                 "                          OpFunctionEnd\n"
1035                 "                 %func1 = OpFunction %void None %func1_decl\n"
1036                 "                    %f1 = OpFunctionParameter %arr_v4f32_rt_ptr\n"
1037                 "            %func1Entry = OpLabel\n"
1038                 "              %out_ptr2 = OpAccessChain %_ptr_sb_v4f32 %f1 %c_i32_0\n"
1039                 "                          OpStore %out_ptr2 %c_v4f32_2\n"
1040                 "              %out_ptr3 = OpAccessChain %_ptr_sb_v4f32 %f1 %c_i32_1\n"
1041                 "                          OpStore %out_ptr3 %c_v4f32_2\n"
1042                 "                          OpReturn\n"
1043                 "                          OpFunctionEnd\n";
1044
1045         fragments["decoration"] =
1046                 "                          OpMemberDecorate %Output 0 Offset 0\n"
1047                 "                          OpMemberDecorate %Output 1 Offset 32\n"
1048                 "                          OpDecorate %Output Block\n"
1049                 "                          OpDecorate %dataOutput DescriptorSet 0\n"
1050                 "                          OpDecorate %dataOutput Binding 0\n"
1051                 "                          OpDecorate %arr_v4f32_2 ArrayStride 16\n"
1052                 "                          OpDecorate %arr_v4f32_rt ArrayStride 16\n";
1053
1054         fragments["testfun"]    =
1055                 "             %test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
1056                 "                 %param = OpFunctionParameter %v4f32\n"
1057                 "                 %entry = OpLabel\n"
1058                 "                  %ptr0 = OpAccessChain %arr_v4f32_2_ptr %dataOutput %c_i32_0\n"
1059                 "                  %ptr1 = OpAccessChain %arr_v4f32_rt_ptr %dataOutput %c_i32_1\n"
1060                 "                  %ret0 = OpFunctionCall %void %func0 %ptr0\n"
1061                 "                  %ret1 = OpFunctionCall %void %func1 %ptr1\n"
1062                 "                          OpReturnValue %param\n"
1063                 "                          OpFunctionEnd\n";
1064
1065         fragments["extension"]  =
1066                 "OpExtension \"SPV_KHR_variable_pointers\"\n"
1067                 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
1068
1069         fragments["capability"] =
1070                 "OpCapability VariablePointersStorageBuffer\n";
1071
1072         getDefaultColors(defaultColors);
1073
1074         for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
1075                 expectedOutput.push_back(5.0f);
1076         for (deUint32 numIdx = 0; numIdx < numFloats / 2; ++numIdx)
1077                 expectedOutput.push_back(2.0f);
1078
1079         extensions.push_back("VK_KHR_variable_pointers");
1080         requiredFeatures.extVariablePointers = EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER;
1081         requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = DE_TRUE;
1082         resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(expectedOutput)), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
1083
1084         createTestsForAllStages("buffer_memory_variable_pointers", defaultColors, defaultColors, fragments, resources, extensions, group, requiredFeatures);
1085 }
1086
1087 } // anonymous
1088
1089 tcu::TestCaseGroup* createPointerParameterComputeGroup (tcu::TestContext& testCtx)
1090 {
1091         de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "pointer_parameter", "Compute tests for pointer as function parameter."));
1092         addComputePointerParamToParamTest(group.get());
1093         addComputePointerParamToGlobalTest(group.get());
1094         addComputePointerBufferMemoryTest(group.get());
1095         addComputePointerBufferMemoryVariablePointersTest(group.get());
1096         addComputePointerWorkgroupMemoryVariablePointersTest(group.get());
1097
1098         return group.release();
1099 }
1100
1101 tcu::TestCaseGroup* createPointerParameterGraphicsGroup (tcu::TestContext& testCtx)
1102 {
1103         de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "pointer_parameter", "Graphics tests for pointer as function parameter."));
1104         addGraphicsPointerParamToParamTest(group.get());
1105         addGraphicsPointerParamToGlobalTest(group.get());
1106         addGraphicsPointerBufferMemoryTest(group.get());
1107         addGraphicsPointerBufferMemoryVariablePointersTest(group.get());
1108
1109         return group.release();
1110 }
1111
1112 } // SpirVAssembly
1113 } // vkt