• 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 workgroup memory.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSpvAsmWorkgroupMemoryTests.hpp"
25 #include "vktSpvAsmComputeShaderCase.hpp"
26 #include "vktSpvAsmComputeShaderTestUtil.hpp"
27 #include "tcuStringTemplate.hpp"
28 #include "tcuFloat.hpp"
29 
30 namespace vkt
31 {
32 namespace SpirVAssembly
33 {
34 
35 using namespace vk;
36 using std::map;
37 using std::string;
38 using std::vector;
39 using tcu::IVec3;
40 using tcu::Vec4;
41 using tcu::StringTemplate;
42 using tcu::Float16;
43 using tcu::Float32;
44 
45 namespace
46 {
47 
48 struct DataType
49 {
50 	string		name;
51 	string		type;
52 	deUint32	sizeBytes;
53 };
54 
checkResultsFloat16(const vector<Resource> & inputs,const vector<AllocationSp> & outputAllocs,const vector<Resource> & expectedOutputs,tcu::TestLog & log)55 bool checkResultsFloat16 (const vector<Resource>&		inputs,
56 						  const vector<AllocationSp>&	outputAllocs,
57 						  const vector<Resource>&		expectedOutputs,
58 						  tcu::TestLog&					log)
59 {
60 	DE_UNREF(inputs);
61 	DE_UNREF(log);
62 
63 	std::vector<deUint8> expectedBytes;
64 	expectedOutputs.front().getBuffer()->getPackedBytes(expectedBytes);
65 
66 	const deUint16*	results		= reinterpret_cast<const deUint16*>(outputAllocs.front()->getHostPtr());
67 	const deUint16*	expected	= reinterpret_cast<const deUint16*>(&expectedBytes[0]);
68 
69 	for (size_t i = 0; i < expectedBytes.size() / sizeof (deUint16); i++)
70 	{
71 		if (results[i] == expected[i])
72 			continue;
73 
74 		if (Float16(results[i]).isNaN() && Float16(expected[i]).isNaN())
75 			continue;
76 
77 		return false;
78 	}
79 
80 	return true;
81 }
82 
83 
checkResultsFloat32(const vector<Resource> & inputs,const vector<AllocationSp> & outputAllocs,const vector<Resource> & expectedOutputs,tcu::TestLog & log)84 bool checkResultsFloat32 (const vector<Resource>&		inputs,
85 						  const vector<AllocationSp>&	outputAllocs,
86 						  const vector<Resource>&		expectedOutputs,
87 						  tcu::TestLog&					log)
88 {
89 	DE_UNREF(inputs);
90 	DE_UNREF(log);
91 
92 	std::vector<deUint8> expectedBytes;
93 	expectedOutputs.front().getBuffer()->getPackedBytes(expectedBytes);
94 
95 	const deUint32*	results		= reinterpret_cast<const deUint32*>(outputAllocs.front()->getHostPtr());
96 	const deUint32*	expected	= reinterpret_cast<const deUint32*>(&expectedBytes[0]);
97 
98 	for (size_t i = 0; i < expectedBytes.size() / sizeof (deUint32); i++)
99 	{
100 		if (results[i] == expected[i])
101 			continue;
102 
103 		if (Float32(results[i]).isNaN() && Float32(expected[i]).isNaN())
104 			continue;
105 
106 		return false;
107 	}
108 
109 	return true;
110 }
111 
isNanFloat64(deUint64 f)112 bool isNanFloat64 (deUint64 f)
113 {
114 	// NaN has full exponent bits and non-zero mantissa.
115 	const deUint64	exponentBits	= 0x7ff0000000000000;
116 	const deUint64	mantissaBits	= 0x000fffffffffffff;
117 	return ((f & exponentBits) == exponentBits && (f & mantissaBits) != 0);
118 }
119 
checkResultsFloat64(const vector<Resource> & inputs,const vector<AllocationSp> & outputAllocs,const vector<Resource> & expectedOutputs,tcu::TestLog & log)120 bool checkResultsFloat64 (const vector<Resource>&		inputs,
121 						  const vector<AllocationSp>&	outputAllocs,
122 						  const vector<Resource>&		expectedOutputs,
123 						  tcu::TestLog&					log)
124 {
125 	DE_UNREF(inputs);
126 	DE_UNREF(log);
127 
128 	std::vector<deUint8> expectedBytes;
129 	expectedOutputs.front().getBuffer()->getPackedBytes(expectedBytes);
130 
131 	const deUint64*	results		= reinterpret_cast<const deUint64*>(outputAllocs.front()->getHostPtr());
132 	const deUint64*	expected	= reinterpret_cast<const deUint64*>(&expectedBytes[0]);
133 
134 	for (size_t i = 0; i < expectedBytes.size() / sizeof (deUint64); i++)
135 	{
136 		if (results[i] == expected[i])
137 			continue;
138 
139 		if (isNanFloat64(results[i]) && isNanFloat64(expected[i]))
140 			continue;
141 
142 		return false;
143 	}
144 
145 	return true;
146 }
147 
addComputeWorkgroupMemoryTests(tcu::TestCaseGroup * group)148 void addComputeWorkgroupMemoryTests (tcu::TestCaseGroup* group)
149 {
150 	tcu::TestContext&		testCtx			= group->getTestContext();
151 	de::Random				rnd				(deStringHash(group->getName()));
152 	const int				numElements		= 128;
153 
154 	/*
155 	For each data type (TYPE) run the following shader:
156 
157 	#version 430
158 
159 	layout (local_size_x = 16, local_size_y = 4, local_size_z = 2) in;
160 
161 	layout (binding = 0) buffer Input
162 	{
163 		TYPE data[128];
164 	} dataInput;
165 
166 	layout (binding = 1) buffer Output
167 	{
168 		TYPE data[128];
169 	} dataOutput;
170 
171 	shared TYPE sharedData[128];
172 
173 	void main()
174 	{
175 		uint idx = gl_LocalInvocationID.z * 64 + gl_LocalInvocationID.y * 16 + gl_LocalInvocationID.x;
176 		sharedData[idx] = dataInput.data[idx];
177 		memoryBarrierShared();
178 		barrier();
179 		dataOutput.data[idx] = sharedData[127-idx];
180 	}
181 	*/
182 
183 	const StringTemplate	shaderSource	(
184 			"                                     OpCapability Shader\n"
185 			"${capabilities:opt}"
186 			"${extensions:opt}"
187 			"                                %1 = OpExtInstImport \"GLSL.std.450\"\n"
188 			"                                     OpMemoryModel Logical GLSL450\n"
189 			"                                     OpEntryPoint GLCompute %main \"main\" %gl_LocalInvocationID\n"
190 			"                                     OpExecutionMode %main LocalSize 16 4 2\n"
191 			"                                     OpSource GLSL 430\n"
192 			"                                     OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId\n"
193 			"                                     OpDecorate %_arr_uint_128_0 ArrayStride ${sizeBytes}\n"
194 			"                                     OpMemberDecorate %Input 0 Offset 0\n"
195 			"                                     OpDecorate %Input BufferBlock\n"
196 			"                                     OpDecorate %dataInput DescriptorSet 0\n"
197 			"                                     OpDecorate %dataInput Binding 0\n"
198 			"                                     OpDecorate %_arr_uint_128_1 ArrayStride ${sizeBytes}\n"
199 			"                                     OpMemberDecorate %Output 0 Offset 0\n"
200 			"                                     OpDecorate %Output BufferBlock\n"
201 			"                                     OpDecorate %dataOutput DescriptorSet 0\n"
202 			"                                     OpDecorate %dataOutput Binding 1\n"
203 			"                                     OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize\n"
204 			"                             %void = OpTypeVoid\n"
205 			"                                %3 = OpTypeFunction %void\n"
206 			"                              %u32 = OpTypeInt 32 0\n"
207 			"               %_ptr_Function_uint = OpTypePointer Function %u32\n"
208 			"                           %v3uint = OpTypeVector %u32 3\n"
209 			"                %_ptr_Input_v3uint = OpTypePointer Input %v3uint\n"
210 			"             %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input\n"
211 			"                           %uint_2 = OpConstant %u32 2\n"
212 			"                  %_ptr_Input_uint = OpTypePointer Input %u32\n"
213 			"                          %uint_64 = OpConstant %u32 64\n"
214 			"                           %uint_1 = OpConstant %u32 1\n"
215 			"                          %uint_16 = OpConstant %u32 16\n"
216 			"                           %uint_0 = OpConstant %u32 0\n"
217 			"                         %uint_127 = OpConstant %u32 127\n"
218 			"                           %uint_4 = OpConstant %u32 4\n"
219 			"                              %i32 = OpTypeInt 32 1\n"
220 			"${dataTypeDecl}\n"
221 			"                         %uint_128 = OpConstant %u32 128\n"
222 			"                    %_arr_uint_128 = OpTypeArray %${dataType} %uint_128\n"
223 			"     %_ptr_Workgroup__arr_uint_128 = OpTypePointer Workgroup %_arr_uint_128\n"
224 			"                       %sharedData = OpVariable %_ptr_Workgroup__arr_uint_128 Workgroup\n"
225 			"                  %_arr_uint_128_0 = OpTypeArray %${dataType} %uint_128\n"
226 			"                            %Input = OpTypeStruct %_arr_uint_128_0\n"
227 			"               %_ptr_Uniform_Input = OpTypePointer Uniform %Input\n"
228 			"                        %dataInput = OpVariable %_ptr_Uniform_Input Uniform\n"
229 			"                            %int_0 = OpConstant %i32 0\n"
230 			"                     %_ptr_Uniform = OpTypePointer Uniform %${dataType}\n"
231 			"                   %_ptr_Workgroup = OpTypePointer Workgroup %${dataType}\n"
232 			"                         %uint_264 = OpConstant %u32 264\n"
233 			"                  %_arr_uint_128_1 = OpTypeArray %${dataType} %uint_128\n"
234 			"                           %Output = OpTypeStruct %_arr_uint_128_1\n"
235 			"              %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
236 			"                       %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
237 			"                 %gl_WorkGroupSize = OpConstantComposite %v3uint %uint_16 %uint_4 %uint_2\n"
238 			"                             %main = OpFunction %void None %3\n"
239 			"                                %5 = OpLabel\n"
240 			"                              %idx = OpVariable %_ptr_Function_uint Function\n"
241 			"                               %14 = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %uint_2\n"
242 			"                               %15 = OpLoad %u32 %14\n"
243 			"                               %17 = OpIMul %u32 %15 %uint_64\n"
244 			"                               %19 = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %uint_1\n"
245 			"                               %20 = OpLoad %u32 %19\n"
246 			"                               %22 = OpIMul %u32 %20 %uint_16\n"
247 			"                               %23 = OpIAdd %u32 %17 %22\n"
248 			"                               %25 = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %uint_0\n"
249 			"                               %26 = OpLoad %u32 %25\n"
250 			"                               %27 = OpIAdd %u32 %23 %26\n"
251 			"                                     OpStore %idx %27\n"
252 			"                               %33 = OpLoad %u32 %idx\n"
253 			"                               %39 = OpLoad %u32 %idx\n"
254 			"                               %41 = OpAccessChain %_ptr_Uniform %dataInput %int_0 %39\n"
255 			"                               %42 = OpLoad %${dataType} %41\n"
256 			"                               %44 = OpAccessChain %_ptr_Workgroup %sharedData %33\n"
257 			"                                     OpStore %44 %42\n"
258 			"                                     OpMemoryBarrier %uint_1 %uint_264\n"
259 			"                                     OpControlBarrier %uint_2 %uint_2 %uint_264\n"
260 			"                               %50 = OpLoad %u32 %idx\n"
261 			"                               %52 = OpLoad %u32 %idx\n"
262 			"                               %53 = OpISub %u32 %uint_127 %52\n"
263 			"                               %54 = OpAccessChain %_ptr_Workgroup %sharedData %53\n"
264 			"                               %55 = OpLoad %${dataType} %54\n"
265 			"                               %56 = OpAccessChain %_ptr_Uniform %dataOutput %int_0 %50\n"
266 			"                                     OpStore %56 %55\n"
267 			"                                     OpReturn\n"
268 			"                                     OpFunctionEnd\n");
269 
270 	// float64
271 	{
272 		VulkanFeatures		features;
273 		map<string, string>	shaderSpec;
274 
275 		shaderSpec["sizeBytes"]		= "8";
276 		shaderSpec["dataTypeDecl"]	= "%f64 = OpTypeFloat 64";
277 		shaderSpec["dataType"]		= "f64";
278 		shaderSpec["capabilities"]	= "OpCapability Float64\n";
279 
280 		features.coreFeatures.shaderFloat64 = VK_TRUE;
281 
282 		vector<double>		inputData	= getFloat64s(rnd, numElements);
283 		vector<double>		outputData;
284 		ComputeShaderSpec	spec;
285 
286 		outputData.reserve(numElements);
287 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
288 			outputData.push_back(inputData[numElements - numIdx - 1]);
289 
290 		spec.assembly					= shaderSource.specialize(shaderSpec);
291 		spec.numWorkGroups				= IVec3(1, 1, 1);
292 		spec.verifyIO					= checkResultsFloat64;
293 		spec.requestedVulkanFeatures	= features;
294 
295 		spec.inputs.push_back(Resource(BufferSp(new Float64Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
296 		spec.outputs.push_back(Resource(BufferSp(new Float64Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
297 
298 		group->addChild(new SpvAsmComputeShaderCase(testCtx, "float64", "", spec));
299 	}
300 
301 	// float32
302 	{
303 		map<string, string>	shaderSpec;
304 
305 		shaderSpec["sizeBytes"]		= "4";
306 		shaderSpec["dataTypeDecl"]	= "%f32 = OpTypeFloat 32";
307 		shaderSpec["dataType"]		= "f32";
308 
309 		vector<float>		inputData	= getFloat32s(rnd, numElements);
310 		vector<float>		outputData;
311 		ComputeShaderSpec	spec;
312 
313 		outputData.reserve(numElements);
314 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
315 			outputData.push_back(inputData[numElements - numIdx - 1]);
316 
317 		spec.assembly		= shaderSource.specialize(shaderSpec);
318 		spec.numWorkGroups	= IVec3(1, 1, 1);
319 		spec.verifyIO		= checkResultsFloat32;
320 
321 		spec.inputs.push_back(Resource(BufferSp(new Float32Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
322 		spec.outputs.push_back(Resource(BufferSp(new Float32Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
323 
324 		group->addChild(new SpvAsmComputeShaderCase(testCtx, "float32", "", spec));
325 	}
326 
327 	// float16
328 	{
329 		VulkanFeatures		features;
330 		map<string, string>	shaderSpec;
331 
332 		shaderSpec["sizeBytes"]		= "2";
333 		shaderSpec["dataTypeDecl"]	= "%f16 = OpTypeFloat 16";
334 		shaderSpec["dataType"]		= "f16";
335 		shaderSpec["extensions"]	= "OpExtension \"SPV_KHR_16bit_storage\"\n";
336 		shaderSpec["capabilities"]	= "OpCapability StorageUniformBufferBlock16\n";
337 
338 		features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
339 
340 		vector<deFloat16>	inputData	= getFloat16s(rnd, numElements);
341 		vector<deFloat16>	outputData;
342 		ComputeShaderSpec	spec;
343 
344 		outputData.reserve(numElements);
345 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
346 			outputData.push_back(inputData[numElements - numIdx - 1]);
347 
348 		spec.assembly		= shaderSource.specialize(shaderSpec);
349 		spec.numWorkGroups	= IVec3(1, 1, 1);
350 		spec.extensions.push_back("VK_KHR_16bit_storage");
351 		spec.requestedVulkanFeatures = features;
352 		spec.verifyIO		= checkResultsFloat16;
353 
354 		spec.inputs.push_back(Resource(BufferSp(new Float16Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
355 		spec.outputs.push_back(Resource(BufferSp(new Float16Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
356 
357 		group->addChild(new SpvAsmComputeShaderCase(testCtx, "float16", "", spec));
358 	}
359 
360 	// int64
361 	{
362 		VulkanFeatures		features;
363 		map<string, string>	shaderSpec;
364 
365 		shaderSpec["sizeBytes"]		= "8";
366 		shaderSpec["dataTypeDecl"]	= "%i64 = OpTypeInt 64 1";
367 		shaderSpec["dataType"]		= "i64";
368 		shaderSpec["capabilities"]	= "OpCapability Int64\n";
369 
370 		features.coreFeatures.shaderInt64 = VK_TRUE;
371 
372 		vector<deInt64>		inputData	= getInt64s(rnd, numElements);
373 		vector<deInt64>		outputData;
374 		ComputeShaderSpec	spec;
375 
376 		outputData.reserve(numElements);
377 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
378 			outputData.push_back(inputData[numElements - numIdx - 1]);
379 
380 		spec.assembly					= shaderSource.specialize(shaderSpec);
381 		spec.numWorkGroups				= IVec3(1, 1, 1);
382 		spec.requestedVulkanFeatures	= features;
383 
384 		spec.inputs.push_back(Resource(BufferSp(new Int64Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
385 		spec.outputs.push_back(Resource(BufferSp(new Int64Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
386 
387 		group->addChild(new SpvAsmComputeShaderCase(testCtx, "int64", "", spec));
388 	}
389 
390 	// int32
391 	{
392 		map<string, string>	shaderSpec;
393 
394 		shaderSpec["sizeBytes"]		= "4";
395 		shaderSpec["dataTypeDecl"]	= "";
396 		shaderSpec["dataType"]		= "i32";
397 
398 		vector<deInt32>		inputData	= getInt32s(rnd, numElements);
399 		vector<deInt32>		outputData;
400 		ComputeShaderSpec	spec;
401 
402 		outputData.reserve(numElements);
403 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
404 			outputData.push_back(inputData[numElements - numIdx - 1]);
405 
406 		spec.assembly		= shaderSource.specialize(shaderSpec);
407 		spec.numWorkGroups	= IVec3(1, 1, 1);
408 
409 		spec.inputs.push_back(Resource(BufferSp(new Int32Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
410 		spec.outputs.push_back(Resource(BufferSp(new Int32Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
411 
412 		group->addChild(new SpvAsmComputeShaderCase(testCtx, "int32", "", spec));
413 	}
414 
415 	// int16
416 	{
417 		VulkanFeatures		features;
418 		map<string, string>	shaderSpec;
419 
420 		shaderSpec["sizeBytes"]		= "2";
421 		shaderSpec["dataTypeDecl"]	= "%i16 = OpTypeInt 16 1";
422 		shaderSpec["dataType"]		= "i16";
423 		shaderSpec["extensions"]	= "OpExtension \"SPV_KHR_16bit_storage\"\n";
424 		shaderSpec["capabilities"]	= "OpCapability Int16\n";
425 
426 		features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
427 
428 		vector<deInt16>		inputData	= getInt16s(rnd, numElements);
429 		vector<deInt16>		outputData;
430 		ComputeShaderSpec	spec;
431 
432 		outputData.reserve(numElements);
433 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
434 			outputData.push_back(inputData[numElements - numIdx - 1]);
435 
436 		spec.assembly		= shaderSource.specialize(shaderSpec);
437 		spec.numWorkGroups	= IVec3(1, 1, 1);
438 		spec.extensions.push_back("VK_KHR_16bit_storage");
439 		spec.requestedVulkanFeatures = features;
440 
441 		spec.inputs.push_back(Resource(BufferSp(new Int16Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
442 		spec.outputs.push_back(Resource(BufferSp(new Int16Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
443 
444 		group->addChild(new SpvAsmComputeShaderCase(testCtx, "int16", "", spec));
445 	}
446 
447 	// int8
448 	{
449 		VulkanFeatures		features;
450 		map<string, string>	shaderSpec;
451 
452 		shaderSpec["sizeBytes"]		= "1";
453 		shaderSpec["dataTypeDecl"]	= "%i8 = OpTypeInt 8 1";
454 		shaderSpec["dataType"]		= "i8";
455 		shaderSpec["capabilities"]	= "OpCapability UniformAndStorageBuffer8BitAccess\n";
456 		shaderSpec["extensions"]	= "OpExtension \"SPV_KHR_8bit_storage\"\n";
457 
458 		features.ext8BitStorage = EXT8BITSTORAGEFEATURES_UNIFORM_STORAGE_BUFFER;
459 
460 		vector<deInt8>		inputData	= getInt8s(rnd, numElements);
461 		vector<deInt8>		outputData;
462 		ComputeShaderSpec	spec;
463 
464 		outputData.reserve(numElements);
465 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
466 			outputData.push_back(inputData[numElements - numIdx - 1]);
467 
468 		spec.assembly		= shaderSource.specialize(shaderSpec);
469 		spec.numWorkGroups	= IVec3(1, 1, 1);
470 		spec.extensions.push_back("VK_KHR_8bit_storage");
471 		spec.requestedVulkanFeatures = features;
472 
473 		spec.inputs.push_back(Resource(BufferSp(new Int8Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
474 		spec.outputs.push_back(Resource(BufferSp(new Int8Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
475 
476 		group->addChild(new SpvAsmComputeShaderCase(testCtx, "int8", "", spec));
477 	}
478 
479 	// uint64
480 	{
481 		VulkanFeatures		features;
482 		map<string, string>	shaderSpec;
483 
484 		shaderSpec["sizeBytes"]		= "8";
485 		shaderSpec["dataTypeDecl"]	= "%u64 = OpTypeInt 64 0";
486 		shaderSpec["dataType"]		= "u64";
487 		shaderSpec["capabilities"]	= "OpCapability Int64\n";
488 
489 		features.coreFeatures.shaderInt64 = VK_TRUE;
490 
491 		vector<deUint64>	inputData;
492 		vector<deUint64>	outputData;
493 		ComputeShaderSpec	spec;
494 
495 		inputData.reserve(numElements);
496 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
497 			inputData.push_back(rnd.getUint64());
498 
499 		outputData.reserve(numElements);
500 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
501 			outputData.push_back(inputData[numElements - numIdx - 1]);
502 
503 		spec.assembly					= shaderSource.specialize(shaderSpec);
504 		spec.numWorkGroups				= IVec3(1, 1, 1);
505 		spec.requestedVulkanFeatures	= features;
506 
507 		spec.inputs.push_back(Resource(BufferSp(new Uint64Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
508 		spec.outputs.push_back(Resource(BufferSp(new Uint64Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
509 
510 		group->addChild(new SpvAsmComputeShaderCase(testCtx, "uint64", "", spec));
511 	}
512 
513 	// uint32
514 	{
515 		map<string, string>	shaderSpec;
516 
517 		shaderSpec["sizeBytes"]		= "4";
518 		shaderSpec["dataTypeDecl"]	= "";
519 		shaderSpec["dataType"]		= "u32";
520 
521 		vector<deUint32>	inputData;
522 		vector<deUint32>	outputData;
523 		ComputeShaderSpec	spec;
524 
525 		inputData.reserve(numElements);
526 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
527 			inputData.push_back(rnd.getUint32());
528 
529 		outputData.reserve(numElements);
530 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
531 			outputData.push_back(inputData[numElements - numIdx - 1]);
532 
533 		spec.assembly		= shaderSource.specialize(shaderSpec);
534 		spec.numWorkGroups	= IVec3(1, 1, 1);
535 
536 		spec.inputs.push_back(Resource(BufferSp(new Uint32Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
537 		spec.outputs.push_back(Resource(BufferSp(new Uint32Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
538 
539 		group->addChild(new SpvAsmComputeShaderCase(testCtx, "uint32", "", spec));
540 	}
541 
542 	// uint16
543 	{
544 		VulkanFeatures		features;
545 		map<string, string>	shaderSpec;
546 
547 		shaderSpec["sizeBytes"]		= "2";
548 		shaderSpec["dataTypeDecl"]	= "%u16 = OpTypeInt 16 0";
549 		shaderSpec["dataType"]		= "u16";
550 		shaderSpec["capabilities"]	= "OpCapability Int16\n";
551 		shaderSpec["extensions"]	= "OpExtension \"SPV_KHR_16bit_storage\"\n";
552 
553 		features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
554 
555 		vector<deUint16>	inputData;
556 		vector<deUint16>	outputData;
557 		ComputeShaderSpec	spec;
558 
559 		inputData.reserve(numElements);
560 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
561 			inputData.push_back(rnd.getUint16());
562 
563 		outputData.reserve(numElements);
564 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
565 			outputData.push_back(inputData[numElements - numIdx - 1]);
566 
567 		spec.assembly		= shaderSource.specialize(shaderSpec);
568 		spec.numWorkGroups	= IVec3(1, 1, 1);
569 		spec.extensions.push_back("VK_KHR_16bit_storage");
570 		spec.requestedVulkanFeatures = features;
571 
572 		spec.inputs.push_back(Resource(BufferSp(new Uint16Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
573 		spec.outputs.push_back(Resource(BufferSp(new Uint16Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
574 
575 		group->addChild(new SpvAsmComputeShaderCase(testCtx, "uint16", "", spec));
576 	}
577 
578 	// uint8
579 	{
580 		VulkanFeatures		features;
581 		map<string, string>	shaderSpec;
582 
583 		shaderSpec["sizeBytes"]		= "1";
584 		shaderSpec["dataTypeDecl"]	= "%u8 = OpTypeInt 8 0";
585 		shaderSpec["dataType"]		= "u8";
586 		shaderSpec["capabilities"]	= "OpCapability UniformAndStorageBuffer8BitAccess\n";
587 		shaderSpec["extensions"]	= "OpExtension \"SPV_KHR_8bit_storage\"\n";
588 
589 		features.ext8BitStorage = EXT8BITSTORAGEFEATURES_UNIFORM_STORAGE_BUFFER;
590 
591 		vector<deUint8>		inputData;
592 		vector<deUint8>		outputData;
593 		ComputeShaderSpec	spec;
594 
595 		inputData.reserve(numElements);
596 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
597 			inputData.push_back(rnd.getUint8());
598 
599 		outputData.reserve(numElements);
600 		for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
601 			outputData.push_back(inputData[numElements - numIdx - 1]);
602 
603 		spec.assembly		= shaderSource.specialize(shaderSpec);
604 		spec.numWorkGroups	= IVec3(1, 1, 1);
605 		spec.extensions.push_back("VK_KHR_8bit_storage");
606 		spec.requestedVulkanFeatures = features;
607 
608 		spec.inputs.push_back(Resource(BufferSp(new Uint8Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
609 		spec.outputs.push_back(Resource(BufferSp(new Uint8Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
610 
611 		group->addChild(new SpvAsmComputeShaderCase(testCtx, "uint8", "", spec));
612 	}
613 }
614 
615 } // anonymous
616 
createWorkgroupMemoryComputeGroup(tcu::TestContext & testCtx)617 tcu::TestCaseGroup* createWorkgroupMemoryComputeGroup (tcu::TestContext& testCtx)
618 {
619 	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "workgroup_memory", "Compute tests for workgroup memory.."));
620 	addComputeWorkgroupMemoryTests(group.get());
621 
622 	return group.release();
623 }
624 
625 } // SpirVAssembly
626 } // vkt
627