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