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\nOpCapability Float16\n";
337
338 features.ext16BitStorage.storageBuffer16BitAccess = true;
339 features.extFloat16Int8.shaderFloat16 = true;
340
341 vector<deFloat16> inputData = getFloat16s(rnd, numElements);
342 vector<deFloat16> outputData;
343 ComputeShaderSpec spec;
344
345 outputData.reserve(numElements);
346 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
347 outputData.push_back(inputData[numElements - numIdx - 1]);
348
349 spec.assembly = shaderSource.specialize(shaderSpec);
350 spec.numWorkGroups = IVec3(1, 1, 1);
351 spec.extensions.push_back("VK_KHR_16bit_storage");
352 spec.extensions.push_back("VK_KHR_shader_float16_int8");
353 spec.requestedVulkanFeatures = features;
354 spec.verifyIO = checkResultsFloat16;
355
356 spec.inputs.push_back(Resource(BufferSp(new Float16Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
357 spec.outputs.push_back(Resource(BufferSp(new Float16Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
358
359 group->addChild(new SpvAsmComputeShaderCase(testCtx, "float16", "", spec));
360 }
361
362 // int64
363 {
364 VulkanFeatures features;
365 map<string, string> shaderSpec;
366
367 shaderSpec["sizeBytes"] = "8";
368 shaderSpec["dataTypeDecl"] = "%i64 = OpTypeInt 64 1";
369 shaderSpec["dataType"] = "i64";
370 shaderSpec["capabilities"] = "OpCapability Int64\n";
371
372 features.coreFeatures.shaderInt64 = VK_TRUE;
373
374 vector<deInt64> inputData = getInt64s(rnd, numElements);
375 vector<deInt64> outputData;
376 ComputeShaderSpec spec;
377
378 outputData.reserve(numElements);
379 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
380 outputData.push_back(inputData[numElements - numIdx - 1]);
381
382 spec.assembly = shaderSource.specialize(shaderSpec);
383 spec.numWorkGroups = IVec3(1, 1, 1);
384 spec.requestedVulkanFeatures = features;
385
386 spec.inputs.push_back(Resource(BufferSp(new Int64Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
387 spec.outputs.push_back(Resource(BufferSp(new Int64Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
388
389 group->addChild(new SpvAsmComputeShaderCase(testCtx, "int64", "", spec));
390 }
391
392 // int32
393 {
394 map<string, string> shaderSpec;
395
396 shaderSpec["sizeBytes"] = "4";
397 shaderSpec["dataTypeDecl"] = "";
398 shaderSpec["dataType"] = "i32";
399
400 vector<deInt32> inputData = getInt32s(rnd, numElements);
401 vector<deInt32> outputData;
402 ComputeShaderSpec spec;
403
404 outputData.reserve(numElements);
405 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
406 outputData.push_back(inputData[numElements - numIdx - 1]);
407
408 spec.assembly = shaderSource.specialize(shaderSpec);
409 spec.numWorkGroups = IVec3(1, 1, 1);
410
411 spec.inputs.push_back(Resource(BufferSp(new Int32Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
412 spec.outputs.push_back(Resource(BufferSp(new Int32Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
413
414 group->addChild(new SpvAsmComputeShaderCase(testCtx, "int32", "", spec));
415 }
416
417 // int16
418 {
419 VulkanFeatures features;
420 map<string, string> shaderSpec;
421
422 shaderSpec["sizeBytes"] = "2";
423 shaderSpec["dataTypeDecl"] = "%i16 = OpTypeInt 16 1";
424 shaderSpec["dataType"] = "i16";
425 shaderSpec["extensions"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
426 shaderSpec["capabilities"] = "OpCapability Int16\n";
427
428 features.coreFeatures.shaderInt16 = true;
429 features.ext16BitStorage.storageBuffer16BitAccess = true;
430
431 vector<deInt16> inputData = getInt16s(rnd, numElements);
432 vector<deInt16> outputData;
433 ComputeShaderSpec spec;
434
435 outputData.reserve(numElements);
436 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
437 outputData.push_back(inputData[numElements - numIdx - 1]);
438
439 spec.assembly = shaderSource.specialize(shaderSpec);
440 spec.numWorkGroups = IVec3(1, 1, 1);
441 spec.extensions.push_back("VK_KHR_16bit_storage");
442 spec.requestedVulkanFeatures = features;
443
444 spec.inputs.push_back(Resource(BufferSp(new Int16Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
445 spec.outputs.push_back(Resource(BufferSp(new Int16Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
446
447 group->addChild(new SpvAsmComputeShaderCase(testCtx, "int16", "", spec));
448 }
449
450 // int8
451 {
452 VulkanFeatures features;
453 map<string, string> shaderSpec;
454
455 shaderSpec["sizeBytes"] = "1";
456 shaderSpec["dataTypeDecl"] = "%i8 = OpTypeInt 8 1";
457 shaderSpec["dataType"] = "i8";
458 shaderSpec["capabilities"] = "OpCapability UniformAndStorageBuffer8BitAccess\nOpCapability Int8\n";
459 shaderSpec["extensions"] = "OpExtension \"SPV_KHR_8bit_storage\"\n";
460
461 features.ext8BitStorage.storageBuffer8BitAccess = true;
462 features.extFloat16Int8.shaderInt8 = true;
463
464 vector<deInt8> inputData = getInt8s(rnd, numElements);
465 vector<deInt8> outputData;
466 ComputeShaderSpec spec;
467
468 outputData.reserve(numElements);
469 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
470 outputData.push_back(inputData[numElements - numIdx - 1]);
471
472 spec.assembly = shaderSource.specialize(shaderSpec);
473 spec.numWorkGroups = IVec3(1, 1, 1);
474 spec.extensions.push_back("VK_KHR_8bit_storage");
475 spec.extensions.push_back("VK_KHR_shader_float16_int8");
476 spec.requestedVulkanFeatures = features;
477
478 spec.inputs.push_back(Resource(BufferSp(new Int8Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
479 spec.outputs.push_back(Resource(BufferSp(new Int8Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
480
481 group->addChild(new SpvAsmComputeShaderCase(testCtx, "int8", "", spec));
482 }
483
484 // uint64
485 {
486 VulkanFeatures features;
487 map<string, string> shaderSpec;
488
489 shaderSpec["sizeBytes"] = "8";
490 shaderSpec["dataTypeDecl"] = "%u64 = OpTypeInt 64 0";
491 shaderSpec["dataType"] = "u64";
492 shaderSpec["capabilities"] = "OpCapability Int64\n";
493
494 features.coreFeatures.shaderInt64 = VK_TRUE;
495
496 vector<deUint64> inputData;
497 vector<deUint64> outputData;
498 ComputeShaderSpec spec;
499
500 inputData.reserve(numElements);
501 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
502 inputData.push_back(rnd.getUint64());
503
504 outputData.reserve(numElements);
505 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
506 outputData.push_back(inputData[numElements - numIdx - 1]);
507
508 spec.assembly = shaderSource.specialize(shaderSpec);
509 spec.numWorkGroups = IVec3(1, 1, 1);
510 spec.requestedVulkanFeatures = features;
511
512 spec.inputs.push_back(Resource(BufferSp(new Uint64Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
513 spec.outputs.push_back(Resource(BufferSp(new Uint64Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
514
515 group->addChild(new SpvAsmComputeShaderCase(testCtx, "uint64", "", spec));
516 }
517
518 // uint32
519 {
520 map<string, string> shaderSpec;
521
522 shaderSpec["sizeBytes"] = "4";
523 shaderSpec["dataTypeDecl"] = "";
524 shaderSpec["dataType"] = "u32";
525
526 vector<deUint32> inputData;
527 vector<deUint32> outputData;
528 ComputeShaderSpec spec;
529
530 inputData.reserve(numElements);
531 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
532 inputData.push_back(rnd.getUint32());
533
534 outputData.reserve(numElements);
535 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
536 outputData.push_back(inputData[numElements - numIdx - 1]);
537
538 spec.assembly = shaderSource.specialize(shaderSpec);
539 spec.numWorkGroups = IVec3(1, 1, 1);
540
541 spec.inputs.push_back(Resource(BufferSp(new Uint32Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
542 spec.outputs.push_back(Resource(BufferSp(new Uint32Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
543
544 group->addChild(new SpvAsmComputeShaderCase(testCtx, "uint32", "", spec));
545 }
546
547 // uint16
548 {
549 VulkanFeatures features;
550 map<string, string> shaderSpec;
551
552 shaderSpec["sizeBytes"] = "2";
553 shaderSpec["dataTypeDecl"] = "%u16 = OpTypeInt 16 0";
554 shaderSpec["dataType"] = "u16";
555 shaderSpec["capabilities"] = "OpCapability Int16\n";
556 shaderSpec["extensions"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
557
558 features.coreFeatures.shaderInt16 = true;
559 features.ext16BitStorage.storageBuffer16BitAccess = true;
560
561 vector<deUint16> inputData;
562 vector<deUint16> outputData;
563 ComputeShaderSpec spec;
564
565 inputData.reserve(numElements);
566 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
567 inputData.push_back(rnd.getUint16());
568
569 outputData.reserve(numElements);
570 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
571 outputData.push_back(inputData[numElements - numIdx - 1]);
572
573 spec.assembly = shaderSource.specialize(shaderSpec);
574 spec.numWorkGroups = IVec3(1, 1, 1);
575 spec.extensions.push_back("VK_KHR_16bit_storage");
576 spec.requestedVulkanFeatures = features;
577
578 spec.inputs.push_back(Resource(BufferSp(new Uint16Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
579 spec.outputs.push_back(Resource(BufferSp(new Uint16Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
580
581 group->addChild(new SpvAsmComputeShaderCase(testCtx, "uint16", "", spec));
582 }
583
584 // uint8
585 {
586 VulkanFeatures features;
587 map<string, string> shaderSpec;
588
589 shaderSpec["sizeBytes"] = "1";
590 shaderSpec["dataTypeDecl"] = "%u8 = OpTypeInt 8 0";
591 shaderSpec["dataType"] = "u8";
592 shaderSpec["capabilities"] = "OpCapability UniformAndStorageBuffer8BitAccess\nOpCapability Int8\n";
593 shaderSpec["extensions"] = "OpExtension \"SPV_KHR_8bit_storage\"\n";
594
595 features.ext8BitStorage.storageBuffer8BitAccess = true;
596 features.extFloat16Int8.shaderInt8 = true;
597
598 vector<deUint8> inputData;
599 vector<deUint8> outputData;
600 ComputeShaderSpec spec;
601
602 inputData.reserve(numElements);
603 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
604 inputData.push_back(rnd.getUint8());
605
606 outputData.reserve(numElements);
607 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
608 outputData.push_back(inputData[numElements - numIdx - 1]);
609
610 spec.assembly = shaderSource.specialize(shaderSpec);
611 spec.numWorkGroups = IVec3(1, 1, 1);
612 spec.extensions.push_back("VK_KHR_8bit_storage");
613 spec.extensions.push_back("VK_KHR_shader_float16_int8");
614 spec.requestedVulkanFeatures = features;
615
616 spec.inputs.push_back(Resource(BufferSp(new Uint8Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
617 spec.outputs.push_back(Resource(BufferSp(new Uint8Buffer(outputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
618
619 group->addChild(new SpvAsmComputeShaderCase(testCtx, "uint8", "", spec));
620 }
621 }
622
623 } // anonymous
624
createWorkgroupMemoryComputeGroup(tcu::TestContext & testCtx)625 tcu::TestCaseGroup* createWorkgroupMemoryComputeGroup (tcu::TestContext& testCtx)
626 {
627 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "workgroup_memory", "Compute tests for workgroup memory.."));
628 addComputeWorkgroupMemoryTests(group.get());
629
630 return group.release();
631 }
632
633 } // SpirVAssembly
634 } // vkt
635