1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief SPIR-V Assembly Tests for the VK_KHR_16bit_storage
22 *//*--------------------------------------------------------------------*/
24 // VK_KHR_16bit_storage
26 // \todo [2017-02-08 antiagainst] Additional corner cases to check:
28 // * Test {StorageInputOutput16} 16-to-16 one value to two:
29 // Like the current 16-to-16 tests, but write X16 to two different output variables.
30 // (Checks that the 16-bit intermediate value can be used twice.)
31 // Note: The current framework allows only one interface to be used.
32 // Maybe the best solution is to add custom shaders that manually use two interfaces.
34 #include "vktSpvAsm16bitStorageTests.hpp"
36 #include "tcuFloat.hpp"
37 #include "tcuRGBA.hpp"
38 #include "tcuStringTemplate.hpp"
39 #include "tcuTestLog.hpp"
40 #include "tcuVectorUtil.hpp"
43 #include "vkDeviceUtil.hpp"
44 #include "vkMemUtil.hpp"
45 #include "vkPlatform.hpp"
46 #include "vkPrograms.hpp"
47 #include "vkQueryUtil.hpp"
49 #include "vkRefUtil.hpp"
50 #include "vkStrUtil.hpp"
51 #include "vkTypeUtil.hpp"
53 #include "deRandom.hpp"
54 #include "deStringUtil.hpp"
55 #include "deUniquePtr.hpp"
58 #include "vktSpvAsmComputeShaderCase.hpp"
59 #include "vktSpvAsmComputeShaderTestUtil.hpp"
60 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
61 #include "vktTestCaseUtil.hpp"
62 #include "vktTestGroupUtil.hpp"
72 namespace SpirVAssembly
84 using tcu::TestStatus;
87 using tcu::StringTemplate;
95 SHADERTEMPLATE_TYPES = 0,
96 SHADERTEMPLATE_STRIDE32BIT_STD140,
97 SHADERTEMPLATE_STRIDE32BIT_STD430,
98 SHADERTEMPLATE_STRIDE16BIT_STD140,
99 SHADERTEMPLATE_STRIDE16BIT_STD430,
100 SHADERTEMPLATE_STRIDEMIX_STD140,
101 SHADERTEMPLATE_STRIDEMIX_STD430
104 bool compare16Bit (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log)
106 return compare16BitFloat (original, returned, flags, log);
109 bool compare16Bit (deUint16 original, float returned, RoundingModeFlags flags, tcu::TestLog& log)
112 return compare16BitFloat (original, returned, log);
115 bool compare16Bit (deInt16 original, deInt16 returned, RoundingModeFlags flags, tcu::TestLog& log)
119 return (returned == original);
122 struct StructTestData
124 const int structArraySize; //Size of Struct Array
125 const int nestedArraySize; //Max size of any nested arrays
133 vk::VkDescriptorType dtype;
136 static const Capability CAPABILITIES[] =
138 {"uniform_buffer_block", "StorageUniformBufferBlock16", "BufferBlock", VK_DESCRIPTOR_TYPE_STORAGE_BUFFER},
139 {"uniform", "StorageUniform16", "Block", VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER},
142 static const StructTestData structData = {7, 11};
144 VulkanFeatures get16BitStorageFeatures (const char* cap)
146 VulkanFeatures features;
147 if (string(cap) == "uniform_buffer_block")
148 features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
149 else if (string(cap) == "uniform")
150 features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM;
152 DE_ASSERT(false && "not supported");
157 int getStructSize(const ShaderTemplate shaderTemplate)
159 switch (shaderTemplate)
161 case SHADERTEMPLATE_STRIDE16BIT_STD140:
162 return 600 * structData.structArraySize; //size of struct in f16 with offsets
163 case SHADERTEMPLATE_STRIDE16BIT_STD430:
164 return 184 * structData.structArraySize; //size of struct in f16 with offsets
165 case SHADERTEMPLATE_STRIDE32BIT_STD140:
166 return 304 * structData.structArraySize; //size of struct in f32 with offsets
167 case SHADERTEMPLATE_STRIDE32BIT_STD430:
168 return 184 * structData.structArraySize; //size of struct in f32 with offset
169 case SHADERTEMPLATE_STRIDEMIX_STD140:
170 return 4480 * structData.structArraySize / 2; //size of struct in 16b with offset
171 case SHADERTEMPLATE_STRIDEMIX_STD430:
172 return 1216 * structData.structArraySize / 2; //size of struct in 16b with offset
179 // Batch function to check arrays of 16-bit floats.
181 // For comparing 16-bit floats, we need to consider both RTZ and RTE. So we can only recalculate
182 // the expected values here instead of get the expected values directly from the test case.
183 // Thus we need original floats here but not expected outputs.
184 template<RoundingModeFlags RoundingMode>
185 bool graphicsCheck16BitFloats (const std::vector<Resource>& originalFloats,
186 const vector<AllocationSp>& outputAllocs,
187 const std::vector<Resource>& expectedOutputs,
190 if (outputAllocs.size() != originalFloats.size())
193 for (deUint32 outputNdx = 0; outputNdx < outputAllocs.size(); ++outputNdx)
195 vector<deUint8> originalBytes;
196 originalFloats[outputNdx].getBytes(originalBytes);
198 const deUint16* returned = static_cast<const deUint16*>(outputAllocs[outputNdx]->getHostPtr());
199 const float* original = reinterpret_cast<const float*>(&originalBytes.front());
200 const deUint32 count = static_cast<deUint32>(expectedOutputs[outputNdx].getByteSize() / sizeof(deUint16));
201 const deUint32 inputStride = static_cast<deUint32>(originalBytes.size() / sizeof(float)) / count;
203 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
204 if (!compare16BitFloat(original[numNdx * inputStride], returned[numNdx], RoundingMode, log))
211 bool computeCheckBuffersFloats (const std::vector<Resource>& originalFloats,
212 const vector<AllocationSp>& outputAllocs,
213 const std::vector<Resource>& /*expectedOutputs*/,
214 tcu::TestLog& /*log*/)
216 std::vector<deUint8> result;
217 originalFloats.front().getBytes(result);
219 const deUint16 * results = reinterpret_cast<const deUint16 *>(&result[0]);
220 const deUint16 * expected = reinterpret_cast<const deUint16 *>(outputAllocs.front()->getHostPtr());
222 for (size_t i = 0; i < result.size() / sizeof (deUint16); ++i)
224 if (results[i] == expected[i])
227 if (Float16(results[i]).isNaN() && Float16(expected[i]).isNaN())
236 template<RoundingModeFlags RoundingMode>
237 bool computeCheck16BitFloats (const std::vector<Resource>& originalFloats,
238 const vector<AllocationSp>& outputAllocs,
239 const std::vector<Resource>& expectedOutputs,
242 if (outputAllocs.size() != originalFloats.size())
245 for (deUint32 outputNdx = 0; outputNdx < outputAllocs.size(); ++outputNdx)
247 vector<deUint8> originalBytes;
248 originalFloats[outputNdx].getBytes(originalBytes);
250 const deUint16* returned = static_cast<const deUint16*>(outputAllocs[outputNdx]->getHostPtr());
251 const float* original = reinterpret_cast<const float*>(&originalBytes.front());
252 const deUint32 count = static_cast<deUint32>(expectedOutputs[outputNdx].getByteSize() / sizeof(deUint16));
253 const deUint32 inputStride = static_cast<deUint32>(originalBytes.size() / sizeof(float)) / count;
255 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
256 if (!compare16BitFloat(original[numNdx * inputStride], returned[numNdx], RoundingMode, log))
263 // Batch function to check arrays of 32-bit floats.
265 // For comparing 32-bit floats, we just need the expected value precomputed in the test case.
266 // So we need expected outputs here but not original floats.
267 bool check32BitFloats (const std::vector<Resource>& /* originalFloats */,
268 const std::vector<AllocationSp>& outputAllocs,
269 const std::vector<Resource>& expectedOutputs,
272 if (outputAllocs.size() != expectedOutputs.size())
275 for (deUint32 outputNdx = 0; outputNdx < outputAllocs.size(); ++outputNdx)
277 vector<deUint8> expectedBytes;
278 expectedOutputs[outputNdx].getBytes(expectedBytes);
280 const float* returnedAsFloat = static_cast<const float*>(outputAllocs[outputNdx]->getHostPtr());
281 const float* expectedAsFloat = reinterpret_cast<const float*>(&expectedBytes.front());
282 const deUint32 count = static_cast<deUint32>(expectedBytes.size() / sizeof(float));
284 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
285 if (!compare32BitFloat(expectedAsFloat[numNdx], returnedAsFloat[numNdx], log))
292 // Generate and return 32-bit integers.
294 // Expected count to be at least 16.
295 vector<deInt32> getInt32s (de::Random& rnd, const deUint32 count)
297 vector<deInt32> data;
301 // Make sure we have boundary numbers.
302 data.push_back(deInt32(0x00000000)); // 0
303 data.push_back(deInt32(0x00000001)); // 1
304 data.push_back(deInt32(0x0000002a)); // 42
305 data.push_back(deInt32(0x00007fff)); // 32767
306 data.push_back(deInt32(0x00008000)); // 32768
307 data.push_back(deInt32(0x0000ffff)); // 65535
308 data.push_back(deInt32(0x00010000)); // 65536
309 data.push_back(deInt32(0x7fffffff)); // 2147483647
310 data.push_back(deInt32(0x80000000)); // -2147483648
311 data.push_back(deInt32(0x80000001)); // -2147483647
312 data.push_back(deInt32(0xffff0000)); // -65536
313 data.push_back(deInt32(0xffff0001)); // -65535
314 data.push_back(deInt32(0xffff8000)); // -32768
315 data.push_back(deInt32(0xffff8001)); // -32767
316 data.push_back(deInt32(0xffffffd6)); // -42
317 data.push_back(deInt32(0xffffffff)); // -1
319 DE_ASSERT(count >= data.size());
321 for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
322 data.push_back(static_cast<deInt32>(rnd.getUint32()));
327 // Generate and return 16-bit integers.
329 // Expected count to be at least 8.
330 vector<deInt16> getInt16s (de::Random& rnd, const deUint32 count)
332 vector<deInt16> data;
336 // Make sure we have boundary numbers.
337 data.push_back(deInt16(0x0000)); // 0
338 data.push_back(deInt16(0x0001)); // 1
339 data.push_back(deInt16(0x002a)); // 42
340 data.push_back(deInt16(0x7fff)); // 32767
341 data.push_back(deInt16(0x8000)); // -32868
342 data.push_back(deInt16(0x8001)); // -32767
343 data.push_back(deInt16(0xffd6)); // -42
344 data.push_back(deInt16(0xffff)); // -1
346 DE_ASSERT(count >= data.size());
348 for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
349 data.push_back(static_cast<deInt16>(rnd.getUint16()));
354 // IEEE-754 floating point numbers:
355 // +--------+------+----------+-------------+
356 // | binary | sign | exponent | significand |
357 // +--------+------+----------+-------------+
358 // | 16-bit | 1 | 5 | 10 |
359 // +--------+------+----------+-------------+
360 // | 32-bit | 1 | 8 | 23 |
361 // +--------+------+----------+-------------+
365 // 0 000 00 00 0000 0001 (0x0001: 2e-24: minimum positive denormalized)
366 // 0 000 00 11 1111 1111 (0x03ff: 2e-14 - 2e-24: maximum positive denormalized)
367 // 0 000 01 00 0000 0000 (0x0400: 2e-14: minimum positive normalized)
371 // 0 011 1110 1 001 0000 0000 0000 0000 0000 (0x3e900000: 0.28125: with exact match in 16-bit normalized)
372 // 0 011 1000 1 000 0000 0011 0000 0000 0000 (0x38803000: exact half way within two 16-bit normalized; round to zero: 0x0401)
373 // 1 011 1000 1 000 0000 0011 0000 0000 0000 (0xb8803000: exact half way within two 16-bit normalized; round to zero: 0x8402)
374 // 0 011 1000 1 000 0000 1111 1111 0000 0000 (0x3880ff00: not exact half way within two 16-bit normalized; round to zero: 0x0403)
375 // 1 011 1000 1 000 0000 1111 1111 0000 0000 (0xb880ff00: not exact half way within two 16-bit normalized; round to zero: 0x8404)
377 // Generate and return 32-bit floats
379 // The first 24 number pairs are manually picked, while the rest are randomly generated.
380 // Expected count to be at least 24 (numPicks).
381 vector<float> getFloat32s (de::Random& rnd, deUint32 count)
383 vector<float> float32;
385 float32.reserve(count);
388 float32.push_back(0.f);
389 float32.push_back(-0.f);
391 float32.push_back(std::numeric_limits<float>::infinity());
392 float32.push_back(-std::numeric_limits<float>::infinity());
394 float32.push_back(std::numeric_limits<float>::signaling_NaN());
395 float32.push_back(-std::numeric_limits<float>::signaling_NaN());
397 float32.push_back(std::numeric_limits<float>::quiet_NaN());
398 float32.push_back(-std::numeric_limits<float>::quiet_NaN());
400 // Denormalized 32-bit float matching 0 in 16-bit
401 float32.push_back(deFloatLdExp(1.f, -127));
402 float32.push_back(-deFloatLdExp(1.f, -127));
404 // Normalized 32-bit float matching 0 in 16-bit
405 float32.push_back(deFloatLdExp(1.f, -100));
406 float32.push_back(-deFloatLdExp(1.f, -100));
407 // Normalized 32-bit float with exact denormalized match in 16-bit
408 float32.push_back(deFloatLdExp(1.f, -24)); // 2e-24: minimum 16-bit positive denormalized
409 float32.push_back(-deFloatLdExp(1.f, -24)); // 2e-24: maximum 16-bit negative denormalized
410 // Normalized 32-bit float with exact normalized match in 16-bit
411 float32.push_back(deFloatLdExp(1.f, -14)); // 2e-14: minimum 16-bit positive normalized
412 float32.push_back(-deFloatLdExp(1.f, -14)); // 2e-14: maximum 16-bit negative normalized
413 // Normalized 32-bit float falling above half way within two 16-bit normalized
414 float32.push_back(bitwiseCast<float>(deUint32(0x3880ff00)));
415 float32.push_back(bitwiseCast<float>(deUint32(0xb880ff00)));
416 // Normalized 32-bit float falling exact half way within two 16-bit normalized
417 float32.push_back(bitwiseCast<float>(deUint32(0x38803000)));
418 float32.push_back(bitwiseCast<float>(deUint32(0xb8803000)));
420 float32.push_back(0.28125f);
421 float32.push_back(-0.28125f);
422 // Normalized 32-bit float matching infinity in 16-bit
423 float32.push_back(deFloatLdExp(1.f, 100));
424 float32.push_back(-deFloatLdExp(1.f, 100));
426 const deUint32 numPicks = static_cast<deUint32>(float32.size());
428 DE_ASSERT(count >= numPicks);
431 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
432 float32.push_back(rnd.getFloat());
437 // IEEE-754 floating point numbers:
438 // +--------+------+----------+-------------+
439 // | binary | sign | exponent | significand |
440 // +--------+------+----------+-------------+
441 // | 16-bit | 1 | 5 | 10 |
442 // +--------+------+----------+-------------+
443 // | 32-bit | 1 | 8 | 23 |
444 // +--------+------+----------+-------------+
448 // 0 000 00 00 0000 0001 (0x0001: 2e-24: minimum positive denormalized)
449 // 0 000 00 11 1111 1111 (0x03ff: 2e-14 - 2e-24: maximum positive denormalized)
450 // 0 000 01 00 0000 0000 (0x0400: 2e-14: minimum positive normalized)
452 // 0 000 00 00 0000 0000 (0x0000: +0)
453 // 0 111 11 00 0000 0000 (0x7c00: +Inf)
454 // 0 000 00 11 1111 0000 (0x03f0: +Denorm)
455 // 0 000 01 00 0000 0001 (0x0401: +Norm)
456 // 0 111 11 00 0000 1111 (0x7c0f: +SNaN)
457 // 0 111 11 00 1111 0000 (0x7c0f: +QNaN)
460 // Generate and return 16-bit floats and their corresponding 32-bit values.
462 // The first 14 number pairs are manually picked, while the rest are randomly generated.
463 // Expected count to be at least 14 (numPicks).
464 vector<deFloat16> getFloat16s (de::Random& rnd, deUint32 count)
466 vector<deFloat16> float16;
468 float16.reserve(count);
471 float16.push_back(deUint16(0x0000));
472 float16.push_back(deUint16(0x8000));
474 float16.push_back(deUint16(0x7c00));
475 float16.push_back(deUint16(0xfc00));
477 float16.push_back(deUint16(0x7c0f));
478 float16.push_back(deUint16(0xfc0f));
480 float16.push_back(deUint16(0x7cf0));
481 float16.push_back(deUint16(0xfcf0));
484 float16.push_back(deUint16(0x03f0));
485 float16.push_back(deUint16(0x83f0));
487 float16.push_back(deUint16(0x0401));
488 float16.push_back(deUint16(0x8401));
489 // Some normal number
490 float16.push_back(deUint16(0x14cb));
491 float16.push_back(deUint16(0x94cb));
493 const deUint32 numPicks = static_cast<deUint32>(float16.size());
495 DE_ASSERT(count >= numPicks);
498 for (deUint32 numIdx = 0; numIdx < count; ++numIdx)
499 float16.push_back(rnd.getUint16());
504 void addInfo(vector<bool>& info, int& ndx, const int count, bool isData)
506 for (int index = 0; index < count; ++index)
507 info[ndx++] = isData;
510 vector<deFloat16> data16bitStd140 (de::Random& rnd)
512 return getFloat16s(rnd, getStructSize(SHADERTEMPLATE_STRIDE16BIT_STD140));
515 vector<bool> info16bitStd140 (void)
518 vector<bool> infoData (getStructSize(SHADERTEMPLATE_STRIDE16BIT_STD140));
520 for(int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
522 infoData[ndx++] = true; //f16
523 infoData[ndx++] = false; //offset
525 infoData[ndx++] = true; //v2f16
526 infoData[ndx++] = true; //v2f16
528 addInfo(infoData, ndx, 3, true); //v3f16
529 infoData[ndx++] = false; //offset
531 addInfo(infoData, ndx, 4, true); //v4f16
532 addInfo(infoData, ndx, 4, false); //offset
535 for (int i = 0; i < 3; ++i)
537 infoData[ndx++] = true; //f16[0];
538 addInfo(infoData, ndx, 7, false); //offset
541 //struct {f16, v2f16[3]} [11]
542 for (int i = 0; i < structData.nestedArraySize; ++i)
545 infoData[ndx++] = true; //f16
546 addInfo(infoData, ndx, 7, false); //offset
547 //struct.f16.v2f16[3]
548 for (int j = 0; j < 3; ++j)
550 infoData[ndx++] = true; //v2f16
551 infoData[ndx++] = true; //v2f16
552 addInfo(infoData, ndx, 6, false); //offset
557 for (int i = 0; i < structData.nestedArraySize; ++i)
559 infoData[ndx++] = true; //v2f16
560 infoData[ndx++] = true; //v2f16
561 addInfo(infoData, ndx, 6, false); //offset
565 infoData[ndx++] = true; //f16
566 addInfo(infoData, ndx, 7, false); //offset
569 for (int i = 0; i < structData.nestedArraySize; ++i)
571 addInfo(infoData, ndx, 3, true); //vec3
572 addInfo(infoData, ndx, 5, false); //offset
576 for (int i = 0; i < 3; ++i)
578 addInfo(infoData, ndx, 4, true); //vec4
579 addInfo(infoData, ndx, 4, false); //offset
583 //Please check the data and offset
584 DE_ASSERT(ndx == static_cast<int>(infoData.size()));
589 vector<deFloat16> data16bitStd430 (de::Random& rnd)
591 return getFloat16s(rnd, getStructSize(SHADERTEMPLATE_STRIDE16BIT_STD430));
594 vector<bool> info16bitStd430 (void)
597 vector<bool> infoData (getStructSize(SHADERTEMPLATE_STRIDE16BIT_STD430));
599 for(int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
601 infoData[ndx++] = true; //f16
602 infoData[ndx++] = false; //offset
604 infoData[ndx++] = true; //v2f16
605 infoData[ndx++] = true; //v2f16
607 addInfo(infoData, ndx, 3, true); //v3f16
608 infoData[ndx++] = false; //offset
610 addInfo(infoData, ndx, 4, true); //v4f16
613 for (int i = 0; i < 3; ++i)
615 infoData[ndx++] = true; //f16;
617 addInfo(infoData, ndx, 1, false); //offset
619 //struct {f16, v2f16[3]} [11]
620 for (int i = 0; i < structData.nestedArraySize; ++i)
623 infoData[ndx++] = true; //f16
624 infoData[ndx++] = false; //offset
625 //struct.f16.v2f16[3]
626 for (int j = 0; j < 3; ++j)
628 infoData[ndx++] = true; //v2f16
629 infoData[ndx++] = true; //v2f16
634 for (int i = 0; i < structData.nestedArraySize; ++i)
636 infoData[ndx++] = true; //v2f16
637 infoData[ndx++] = true; //v2f16
641 infoData[ndx++] = true; //f16
642 infoData[ndx++] = false; //offset
645 for (int i = 0; i < structData.nestedArraySize; ++i)
647 addInfo(infoData, ndx, 3, true); //vec3
648 infoData[ndx++] = false; //offset
652 for (int i = 0; i < 3; ++i)
654 addInfo(infoData, ndx, 4, true); //vec4
658 //Please check the data and offset
659 DE_ASSERT(ndx == static_cast<int>(infoData.size()));
663 vector<float> data32bitStd140 (de::Random& rnd)
665 return getFloat32s(rnd, getStructSize(SHADERTEMPLATE_STRIDE32BIT_STD140));
668 vector<bool> info32bitStd140 (void)
671 vector<bool> infoData (getStructSize(SHADERTEMPLATE_STRIDE32BIT_STD140));
673 for(int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
675 infoData[ndx++] = true; //f32
676 infoData[ndx++] = false; //offset
678 infoData[ndx++] = true; //v2f32
679 infoData[ndx++] = true; //v2f32
681 addInfo(infoData, ndx, 3, true); //v3f32
682 infoData[ndx++] = false; //offset
684 addInfo(infoData, ndx, 4, true); //v4f16
687 for (int i = 0; i < 3; ++i)
689 infoData[ndx++] = true; //f32;
690 addInfo(infoData, ndx, 3, false); //offset
693 //struct {f32, v2f32[3]} [11]
694 for (int i = 0; i < structData.nestedArraySize; ++i)
697 infoData[ndx++] = true; //f32
698 addInfo(infoData, ndx, 3, false); //offset
699 //struct.f32.v2f16[3]
700 for (int j = 0; j < 3; ++j)
702 infoData[ndx++] = true; //v2f32
703 infoData[ndx++] = true; //v2f32
704 infoData[ndx++] = false; //offset
705 infoData[ndx++] = false; //offset
710 for (int i = 0; i < structData.nestedArraySize; ++i)
712 infoData[ndx++] = true; //v2f32
713 infoData[ndx++] = true; //v2f32
714 infoData[ndx++] = false; //offset
715 infoData[ndx++] = false; //offset
719 infoData[ndx++] = true; //f16
720 addInfo(infoData, ndx, 3, false); //offset
723 for (int i = 0; i < structData.nestedArraySize; ++i)
725 addInfo(infoData, ndx, 3, true); //v3f32
726 infoData[ndx++] = false; //offset
730 for (int i = 0; i < 3; ++i)
732 addInfo(infoData, ndx, 4, true); //vec4
736 //Please check the data and offset
737 DE_ASSERT(ndx == static_cast<int>(infoData.size()));
741 vector<float> data32bitStd430 (de::Random& rnd)
743 return getFloat32s(rnd, getStructSize(SHADERTEMPLATE_STRIDE32BIT_STD430));
746 vector<bool> info32bitStd430 (void)
749 vector<bool> infoData (getStructSize(SHADERTEMPLATE_STRIDE32BIT_STD430));
751 for(int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
753 infoData[ndx++] = true; //f32
754 infoData[ndx++] = false; //offset
756 infoData[ndx++] = true; //v2f32
757 infoData[ndx++] = true; //v2f32
759 addInfo(infoData, ndx, 3, true); //v3f32
760 infoData[ndx++] = false; //offset
762 addInfo(infoData, ndx, 4, true); //v4f16
765 for (int i = 0; i < 3; ++i)
767 infoData[ndx++] = true; //f32;
769 infoData[ndx++] = false; //offset
771 //struct {f32, v2f32[3]} [11]
772 for (int i = 0; i < structData.nestedArraySize; ++i)
775 infoData[ndx++] = true; //f32
776 infoData[ndx++] = false; //offset
777 //struct.f32.v2f16[3]
778 for (int j = 0; j < 3; ++j)
780 infoData[ndx++] = true; //v2f32
781 infoData[ndx++] = true; //v2f32
786 for (int i = 0; i < structData.nestedArraySize; ++i)
788 infoData[ndx++] = true; //v2f32
789 infoData[ndx++] = true; //v2f32
793 infoData[ndx++] = true; //f32
794 infoData[ndx++] = false; //offset
797 for (int i = 0; i < structData.nestedArraySize; ++i)
799 addInfo(infoData, ndx, 3, true); //v3f32
800 infoData[ndx++] = false; //offset
804 for (int i = 0; i < 3; ++i)
806 addInfo(infoData, ndx, 4, true); //vec4
810 //Please check the data and offset
811 DE_ASSERT(ndx == static_cast<int>(infoData.size()));
815 vector<deInt16> dataMixStd140 (de::Random& rnd)
817 return getInt16s(rnd, getStructSize(SHADERTEMPLATE_STRIDEMIX_STD140));
820 vector<bool> infoMixStd140 (void)
823 vector<bool> infoData (getStructSize(SHADERTEMPLATE_STRIDEMIX_STD140));
824 for(int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
826 infoData[ndx++] = true; //16b
827 addInfo(infoData, ndx, 1, false); //offset
829 addInfo(infoData, ndx, 2, true); //32b
831 addInfo(infoData, ndx, 2, true); //v2b16
832 addInfo(infoData, ndx, 2, false); //offset
834 addInfo(infoData, ndx, 4, true); //v2b32
836 addInfo(infoData, ndx, 3, true); //v3b16
837 addInfo(infoData, ndx, 1, false); //offset
839 addInfo(infoData, ndx, 6, true); //v3b32
840 addInfo(infoData, ndx, 2, false); //offset
842 addInfo(infoData, ndx, 4, true); //v4b16
843 addInfo(infoData, ndx, 4, false); //offset
845 addInfo(infoData, ndx, 8, true); //v4b32
847 //strut {b16, b32, v2b16[11], b32[11]}
848 for (int i = 0; i < structData.nestedArraySize; ++i)
850 infoData[ndx++] = true; //16b
851 addInfo(infoData, ndx, 1, false); //offset
853 addInfo(infoData, ndx, 2, true); //32b
854 addInfo(infoData, ndx, 4, false); //offset
856 for (int j = 0; j < structData.nestedArraySize; ++j)
858 addInfo(infoData, ndx, 2, true); //v2b16[11]
859 addInfo(infoData, ndx, 6, false); //offset
862 for (int j = 0; j < structData.nestedArraySize; ++j)
864 addInfo(infoData, ndx, 2, true); //b32[11]
865 addInfo(infoData, ndx, 6, false); //offset
869 for (int i = 0; i < structData.nestedArraySize; ++i)
871 infoData[ndx++] = true; //16b[11]
872 addInfo(infoData, ndx, 7, false); //offset
875 for (int i = 0; i < structData.nestedArraySize; ++i)
877 addInfo(infoData, ndx, 2, true); //b32bIn[11]
878 addInfo(infoData, ndx, 6, false); //offset
882 //Please check the data and offset
883 DE_ASSERT(ndx == static_cast<int>(infoData.size()));
887 vector<deInt16> dataMixStd430 (de::Random& rnd)
889 return getInt16s(rnd, getStructSize(SHADERTEMPLATE_STRIDEMIX_STD430));
892 vector<bool> infoMixStd430 (void)
895 vector<bool> infoData (getStructSize(SHADERTEMPLATE_STRIDEMIX_STD430));
896 for(int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
898 infoData[ndx++] = true; //16b
899 addInfo(infoData, ndx, 1, false); //offset
901 addInfo(infoData, ndx, 2, true); //32b
903 addInfo(infoData, ndx, 2, true); //v2b16
904 addInfo(infoData, ndx, 2, false); //offset
906 addInfo(infoData, ndx, 4, true); //v2b32
908 addInfo(infoData, ndx, 3, true); //v3b16
909 addInfo(infoData, ndx, 1, false); //offset
911 addInfo(infoData, ndx, 6, true); //v3b32
912 addInfo(infoData, ndx, 2, false); //offset
914 addInfo(infoData, ndx, 4, true); //v4b16
915 addInfo(infoData, ndx, 4, false); //offset
917 addInfo(infoData, ndx, 8, true); //v4b32
919 //strut {b16, b32, v2b16[11], b32[11]}
920 for (int i = 0; i < structData.nestedArraySize; ++i)
922 infoData[ndx++] = true; //16b
923 addInfo(infoData, ndx, 1, false); //offset
925 addInfo(infoData, ndx, 2, true); //32b
927 addInfo(infoData, ndx, 22, true); //v2b16[11]
929 addInfo(infoData, ndx, 22, true); //b32[11]
932 addInfo(infoData, ndx, 11, true); //16b[11]
933 infoData[ndx++] = false; //offset
935 addInfo(infoData, ndx, 22, true); //32b[11]
936 addInfo(infoData, ndx, 6, false); //offset
939 //Please check the data and offset
940 DE_ASSERT(ndx == static_cast<int>(infoData.size()));
944 template<typename originType, typename resultType, ShaderTemplate funcOrigin, ShaderTemplate funcResult>
945 bool compareStruct(const resultType* returned, const originType* original, tcu::TestLog& log)
947 vector<bool> resultInfo;
948 vector<bool> originInfo;
949 vector<resultType> resultToCompare;
950 vector<originType> originToCompare;
954 case SHADERTEMPLATE_STRIDE16BIT_STD140:
955 originInfo = info16bitStd140();
957 case SHADERTEMPLATE_STRIDE16BIT_STD430:
958 originInfo = info16bitStd430();
960 case SHADERTEMPLATE_STRIDE32BIT_STD140:
961 originInfo = info32bitStd140();
963 case SHADERTEMPLATE_STRIDE32BIT_STD430:
964 originInfo = info32bitStd430();
966 case SHADERTEMPLATE_STRIDEMIX_STD140:
967 originInfo = infoMixStd140();
969 case SHADERTEMPLATE_STRIDEMIX_STD430:
970 originInfo = infoMixStd430();
978 case SHADERTEMPLATE_STRIDE16BIT_STD140:
979 resultInfo = info16bitStd140();
981 case SHADERTEMPLATE_STRIDE16BIT_STD430:
982 resultInfo = info16bitStd430();
984 case SHADERTEMPLATE_STRIDE32BIT_STD140:
985 resultInfo = info32bitStd140();
987 case SHADERTEMPLATE_STRIDE32BIT_STD430:
988 resultInfo = info32bitStd430();
990 case SHADERTEMPLATE_STRIDEMIX_STD140:
991 resultInfo = infoMixStd140();
993 case SHADERTEMPLATE_STRIDEMIX_STD430:
994 resultInfo = infoMixStd430();
1000 for (unsigned int ndx = 0; ndx < static_cast<unsigned int>(resultInfo.size()); ++ndx)
1002 if (resultInfo[ndx])
1003 resultToCompare.push_back(returned[ndx]);
1006 for (unsigned int ndx = 0; ndx < static_cast<unsigned int>(originInfo.size()); ++ndx)
1008 if (originInfo[ndx])
1009 originToCompare.push_back(original[ndx]);
1012 //Different offset but that same amount of data
1013 DE_ASSERT(originToCompare.size() == resultToCompare.size());
1014 for (unsigned int ndx = 0; ndx < static_cast<unsigned int>(originToCompare.size()); ++ndx)
1016 if (!compare16Bit(originToCompare[ndx], resultToCompare[ndx], RoundingModeFlags(ROUNDINGMODE_RTE | ROUNDINGMODE_RTZ), log))
1022 template<typename originType, typename resultType, ShaderTemplate funcOrigin, ShaderTemplate funcResult>
1023 bool computeCheckStruct (const std::vector<Resource>& originalFloats,
1024 const vector<AllocationSp>& outputAllocs,
1025 const std::vector<Resource>& /* expectedOutputs */,
1028 for (deUint32 outputNdx = 0; outputNdx < outputAllocs.size(); ++outputNdx)
1030 vector<deUint8> originalBytes;
1031 originalFloats[outputNdx].getBytes(originalBytes);
1033 const resultType* returned = static_cast<const resultType*>(outputAllocs[outputNdx]->getHostPtr());
1034 const originType* original = reinterpret_cast<const originType*>(&originalBytes.front());
1036 if(!compareStruct<originType, resultType, funcOrigin, funcResult>(returned, original, log))
1042 template<typename originType, typename resultType, ShaderTemplate funcOrigin, ShaderTemplate funcResult>
1043 bool graphicsCheckStruct (const std::vector<Resource>& originalFloats,
1044 const vector<AllocationSp>& outputAllocs,
1045 const std::vector<Resource>& /* expectedOutputs */,
1048 for (deUint32 outputNdx = 0; outputNdx < static_cast<deUint32>(outputAllocs.size()); ++outputNdx)
1050 vector<deUint8> originalBytes;
1051 originalFloats[outputNdx].getBytes(originalBytes);
1053 const resultType* returned = static_cast<const resultType*>(outputAllocs[outputNdx]->getHostPtr());
1054 const originType* original = reinterpret_cast<const originType*>(&originalBytes.front());
1056 if(!compareStruct<originType, resultType, funcOrigin, funcResult>(returned, original, log))
1062 string getStructShaderComponet (const ShaderTemplate component)
1066 case SHADERTEMPLATE_TYPES:
1068 "%f16 = OpTypeFloat 16\n"
1069 "%v2f16 = OpTypeVector %f16 2\n"
1070 "%v3f16 = OpTypeVector %f16 3\n"
1071 "%v4f16 = OpTypeVector %f16 4\n"
1072 "%f16ptr = OpTypePointer Uniform %f16\n"
1073 "%v2f16ptr = OpTypePointer Uniform %v2f16\n"
1074 "%v3f16ptr = OpTypePointer Uniform %v3f16\n"
1075 "%v4f16ptr = OpTypePointer Uniform %v4f16\n"
1077 "%f32ptr = OpTypePointer Uniform %f32\n"
1078 "%v2f32ptr = OpTypePointer Uniform %v2f32\n"
1079 "%v3f32ptr = OpTypePointer Uniform %v3f32\n"
1080 "%v4f32ptr = OpTypePointer Uniform %v4f32\n");
1081 case SHADERTEMPLATE_STRIDE16BIT_STD140:
1083 //struct {f16, v2f16[3]} [11]
1084 "OpDecorate %v2f16arr3 ArrayStride 16\n"
1085 "OpMemberDecorate %struct16 0 Offset 0\n"
1086 "OpMemberDecorate %struct16 1 Offset 16\n"
1087 "OpDecorate %struct16arr11 ArrayStride 64\n"
1089 "OpDecorate %f16arr3 ArrayStride 16\n"
1090 "OpDecorate %v2f16arr11 ArrayStride 16\n"
1091 "OpDecorate %v3f16arr11 ArrayStride 16\n"
1092 "OpDecorate %v4f16arr3 ArrayStride 16\n"
1093 "OpDecorate %f16StructArr7 ArrayStride 1200\n"
1095 "OpMemberDecorate %f16Struct 0 Offset 0\n" //f16
1096 "OpMemberDecorate %f16Struct 1 Offset 4\n" //v2f16
1097 "OpMemberDecorate %f16Struct 2 Offset 8\n" //v3f16
1098 "OpMemberDecorate %f16Struct 3 Offset 16\n" //v4f16
1099 "OpMemberDecorate %f16Struct 4 Offset 32\n" //f16[3]
1100 "OpMemberDecorate %f16Struct 5 Offset 80\n" //struct {f16, v2f16[3]} [11]
1101 "OpMemberDecorate %f16Struct 6 Offset 784\n" //v2f16[11]
1102 "OpMemberDecorate %f16Struct 7 Offset 960\n" //f16
1103 "OpMemberDecorate %f16Struct 8 Offset 976\n" //v3f16[11]
1104 "OpMemberDecorate %f16Struct 9 Offset 1152\n"); //v4f16[3]
1106 case SHADERTEMPLATE_STRIDE16BIT_STD430:
1108 //struct {f16, v2f16[3]} [11]
1109 "OpDecorate %v2f16arr3 ArrayStride 4\n"
1110 "OpMemberDecorate %struct16 0 Offset 0\n"
1111 "OpMemberDecorate %struct16 1 Offset 4\n"
1112 "OpDecorate %struct16arr11 ArrayStride 16\n"
1114 "OpDecorate %f16arr3 ArrayStride 2\n"
1115 "OpDecorate %v2f16arr11 ArrayStride 4\n"
1116 "OpDecorate %v3f16arr11 ArrayStride 8\n"
1117 "OpDecorate %v4f16arr3 ArrayStride 8\n"
1118 "OpDecorate %f16StructArr7 ArrayStride 368\n"
1120 "OpMemberDecorate %f16Struct 0 Offset 0\n" //f16
1121 "OpMemberDecorate %f16Struct 1 Offset 4\n" //v2f16
1122 "OpMemberDecorate %f16Struct 2 Offset 8\n" //v3f16
1123 "OpMemberDecorate %f16Struct 3 Offset 16\n" //v4f16
1124 "OpMemberDecorate %f16Struct 4 Offset 24\n" //f16[3]
1125 "OpMemberDecorate %f16Struct 5 Offset 32\n" //struct {f16, v2f16[3]} [11]
1126 "OpMemberDecorate %f16Struct 6 Offset 208\n" //v2f16[11]
1127 "OpMemberDecorate %f16Struct 7 Offset 252\n" //f16
1128 "OpMemberDecorate %f16Struct 8 Offset 256\n" //v3f16[11]
1129 "OpMemberDecorate %f16Struct 9 Offset 344\n"); //v4f16[3]
1130 case SHADERTEMPLATE_STRIDE32BIT_STD140:
1132 //struct {f32, v2f32[3]} [11]
1133 "OpDecorate %v2f32arr3 ArrayStride 16\n"
1134 "OpMemberDecorate %struct32 0 Offset 0\n"
1135 "OpMemberDecorate %struct32 1 Offset 16\n"
1136 "OpDecorate %struct32arr11 ArrayStride 64\n"
1138 "OpDecorate %f32arr3 ArrayStride 16\n"
1139 "OpDecorate %v2f32arr11 ArrayStride 16\n"
1140 "OpDecorate %v3f32arr11 ArrayStride 16\n"
1141 "OpDecorate %v4f32arr3 ArrayStride 16\n"
1142 "OpDecorate %f32StructArr7 ArrayStride 1216\n"
1145 "OpMemberDecorate %f32Struct 0 Offset 0\n" //f32
1146 "OpMemberDecorate %f32Struct 1 Offset 8\n" //v2f32
1147 "OpMemberDecorate %f32Struct 2 Offset 16\n" //v3f32
1148 "OpMemberDecorate %f32Struct 3 Offset 32\n" //v4f32
1149 "OpMemberDecorate %f32Struct 4 Offset 48\n" //f32[3]
1150 "OpMemberDecorate %f32Struct 5 Offset 96\n" //struct {f32, v2f32[3]} [11]
1151 "OpMemberDecorate %f32Struct 6 Offset 800\n" //v2f32[11]
1152 "OpMemberDecorate %f32Struct 7 Offset 976\n" //f32
1153 "OpMemberDecorate %f32Struct 8 Offset 992\n" //v3f32[11]
1154 "OpMemberDecorate %f32Struct 9 Offset 1168\n"); //v4f32[3]
1156 case SHADERTEMPLATE_STRIDE32BIT_STD430:
1158 //struct {f32, v2f32[3]} [11]
1159 "OpDecorate %v2f32arr3 ArrayStride 8\n"
1160 "OpMemberDecorate %struct32 0 Offset 0\n"
1161 "OpMemberDecorate %struct32 1 Offset 8\n"
1162 "OpDecorate %struct32arr11 ArrayStride 32\n"
1164 "OpDecorate %f32arr3 ArrayStride 4\n"
1165 "OpDecorate %v2f32arr11 ArrayStride 8\n"
1166 "OpDecorate %v3f32arr11 ArrayStride 16\n"
1167 "OpDecorate %v4f32arr3 ArrayStride 16\n"
1168 "OpDecorate %f32StructArr7 ArrayStride 736\n"
1171 "OpMemberDecorate %f32Struct 0 Offset 0\n" //f32
1172 "OpMemberDecorate %f32Struct 1 Offset 8\n" //v2f32
1173 "OpMemberDecorate %f32Struct 2 Offset 16\n" //v3f32
1174 "OpMemberDecorate %f32Struct 3 Offset 32\n" //v4f32
1175 "OpMemberDecorate %f32Struct 4 Offset 48\n" //f32[3]
1176 "OpMemberDecorate %f32Struct 5 Offset 64\n" //struct {f32, v2f32[3]}[11]
1177 "OpMemberDecorate %f32Struct 6 Offset 416\n" //v2f32[11]
1178 "OpMemberDecorate %f32Struct 7 Offset 504\n" //f32
1179 "OpMemberDecorate %f32Struct 8 Offset 512\n" //v3f32[11]
1180 "OpMemberDecorate %f32Struct 9 Offset 688\n"); //v4f32[3]
1181 case SHADERTEMPLATE_STRIDEMIX_STD140:
1183 "\n"//strutNestedIn {b16, b32, v2b16[11], b32[11]}
1184 "OpDecorate %v2b16NestedArr11${InOut} ArrayStride 16\n" //v2b16[11]
1185 "OpDecorate %b32NestedArr11${InOut} ArrayStride 16\n" //b32[11]
1186 "OpMemberDecorate %sNested${InOut} 0 Offset 0\n" //b16
1187 "OpMemberDecorate %sNested${InOut} 1 Offset 4\n" //b32
1188 "OpMemberDecorate %sNested${InOut} 2 Offset 16\n" //v2b16[11]
1189 "OpMemberDecorate %sNested${InOut} 3 Offset 192\n" //b32[11]
1190 "OpDecorate %sNestedArr11${InOut} ArrayStride 368\n" //strutNestedIn[11]
1191 "\n"//strutIn {b16, b32, v2b16, v2b32, v3b16, v3b32, v4b16, v4b32, strutNestedIn[11], b16In[11], b32bIn[11]}
1192 "OpDecorate %sb16Arr11${InOut} ArrayStride 16\n" //b16In[11]
1193 "OpDecorate %sb32Arr11${InOut} ArrayStride 16\n" //b32bIn[11]
1194 "OpMemberDecorate %struct${InOut} 0 Offset 0\n" //b16
1195 "OpMemberDecorate %struct${InOut} 1 Offset 4\n" //b32
1196 "OpMemberDecorate %struct${InOut} 2 Offset 8\n" //v2b16
1197 "OpMemberDecorate %struct${InOut} 3 Offset 16\n" //v2b32
1198 "OpMemberDecorate %struct${InOut} 4 Offset 24\n" //v3b16
1199 "OpMemberDecorate %struct${InOut} 5 Offset 32\n" //v3b32
1200 "OpMemberDecorate %struct${InOut} 6 Offset 48\n" //v4b16
1201 "OpMemberDecorate %struct${InOut} 7 Offset 64\n" //v4b32
1202 "OpMemberDecorate %struct${InOut} 8 Offset 80\n" //strutNestedIn[11]
1203 "OpMemberDecorate %struct${InOut} 9 Offset 4128\n" //b16In[11]
1204 "OpMemberDecorate %struct${InOut} 10 Offset 4304\n" //b32bIn[11]
1205 "OpDecorate %structArr7${InOut} ArrayStride 4480\n"); //strutIn[7]
1206 case SHADERTEMPLATE_STRIDEMIX_STD430:
1208 "\n"//strutNestedOut {b16, b32, v2b16[11], b32[11]}
1209 "OpDecorate %v2b16NestedArr11${InOut} ArrayStride 4\n" //v2b16[11]
1210 "OpDecorate %b32NestedArr11${InOut} ArrayStride 4\n" //b32[11]
1211 "OpMemberDecorate %sNested${InOut} 0 Offset 0\n" //b16
1212 "OpMemberDecorate %sNested${InOut} 1 Offset 4\n" //b32
1213 "OpMemberDecorate %sNested${InOut} 2 Offset 8\n" //v2b16[11]
1214 "OpMemberDecorate %sNested${InOut} 3 Offset 52\n" //b32[11]
1215 "OpDecorate %sNestedArr11${InOut} ArrayStride 96\n" //strutNestedOut[11]
1216 "\n"//strutOut {b16, b32, v2b16, v2b32, v3b16, v3b32, v4b16, v4b32, strutNestedOut[11], b16Out[11], b32bOut[11]}
1217 "OpDecorate %sb16Arr11${InOut} ArrayStride 2\n" //b16Out[11]
1218 "OpDecorate %sb32Arr11${InOut} ArrayStride 4\n" //b32bOut[11]
1219 "OpMemberDecorate %struct${InOut} 0 Offset 0\n" //b16
1220 "OpMemberDecorate %struct${InOut} 1 Offset 4\n" //b32
1221 "OpMemberDecorate %struct${InOut} 2 Offset 8\n" //v2b16
1222 "OpMemberDecorate %struct${InOut} 3 Offset 16\n" //v2b32
1223 "OpMemberDecorate %struct${InOut} 4 Offset 24\n" //v3b16
1224 "OpMemberDecorate %struct${InOut} 5 Offset 32\n" //v3b32
1225 "OpMemberDecorate %struct${InOut} 6 Offset 48\n" //v4b16
1226 "OpMemberDecorate %struct${InOut} 7 Offset 64\n" //v4b32
1227 "OpMemberDecorate %struct${InOut} 8 Offset 80\n" //strutNestedOut[11]
1228 "OpMemberDecorate %struct${InOut} 9 Offset 1136\n" //b16Out[11]
1229 "OpMemberDecorate %struct${InOut} 10 Offset 1160\n" //b32bOut[11]
1230 "OpDecorate %structArr7${InOut} ArrayStride 1216\n"); //strutOut[7]
1237 /*Return string contains spirv loop begin.
1238 the spec should contains "exeCount" - with name of const i32, it is number of executions
1239 the spec should contains "loopName" - suffix for all local names
1240 %Val${loopName} - index which can be used inside loop
1241 "%ndxArr${loopName} = OpVariable %fp_i32 Function\n" - has to be defined outside
1242 The function should be always use with endLoop function*/
1243 std::string beginLoop(const std::map<std::string, std::string>& spec)
1245 const tcu::StringTemplate loopBegin (
1246 "OpStore %ndxArr${loopName} %zero\n"
1247 "OpBranch %Loop${loopName}\n"
1248 "%Loop${loopName} = OpLabel\n"
1249 "OpLoopMerge %MergeLabel1${loopName} %MergeLabel2${loopName} None\n"
1250 "OpBranch %Label1${loopName}\n"
1251 "%Label1${loopName} = OpLabel\n"
1252 "%Val${loopName} = OpLoad %i32 %ndxArr${loopName}\n"
1253 "%LessThan${loopName} = OpSLessThan %bool %Val${loopName} %${exeCount}\n"
1254 "OpBranchConditional %LessThan${loopName} %ifLabel${loopName} %MergeLabel1${loopName}\n"
1255 "%ifLabel${loopName} = OpLabel\n");
1256 return loopBegin.specialize(spec);
1258 /*Return string contains spirv loop end.
1259 the spec should contains "loopName" - suffix for all local names, suffix should be the same in beginLoop
1260 The function should be always use with beginLoop function*/
1261 std::string endLoop(const std::map<std::string, std::string>& spec)
1263 const tcu::StringTemplate loopEnd (
1264 "OpBranch %MergeLabel2${loopName}\n"
1265 "%MergeLabel2${loopName} = OpLabel\n"
1266 "%plusOne${loopName} = OpIAdd %i32 %Val${loopName} %c_i32_1\n"
1267 "OpStore %ndxArr${loopName} %plusOne${loopName}\n"
1268 "OpBranch %Loop${loopName}\n"
1269 "%MergeLabel1${loopName} = OpLabel\n");
1270 return loopEnd.specialize(spec);
1273 void addCompute16bitStorageUniform16To32Group (tcu::TestCaseGroup* group)
1275 tcu::TestContext& testCtx = group->getTestContext();
1276 de::Random rnd (deStringHash(group->getName()));
1277 const int numElements = 128;
1279 const StringTemplate shaderTemplate (
1280 "OpCapability Shader\n"
1281 "OpCapability ${capability}\n"
1282 "OpExtension \"SPV_KHR_16bit_storage\"\n"
1283 "OpMemoryModel Logical GLSL450\n"
1284 "OpEntryPoint GLCompute %main \"main\" %id\n"
1285 "OpExecutionMode %main LocalSize 1 1 1\n"
1286 "OpDecorate %id BuiltIn GlobalInvocationId\n"
1290 "OpMemberDecorate %SSBO32 0 Offset 0\n"
1291 "OpMemberDecorate %SSBO16 0 Offset 0\n"
1292 "OpDecorate %SSBO32 BufferBlock\n"
1293 "OpDecorate %SSBO16 ${storage}\n"
1294 "OpDecorate %ssbo32 DescriptorSet 0\n"
1295 "OpDecorate %ssbo16 DescriptorSet 0\n"
1296 "OpDecorate %ssbo32 Binding 1\n"
1297 "OpDecorate %ssbo16 Binding 0\n"
1299 "${matrix_decor:opt}\n"
1301 "%bool = OpTypeBool\n"
1302 "%void = OpTypeVoid\n"
1303 "%voidf = OpTypeFunction %void\n"
1304 "%u32 = OpTypeInt 32 0\n"
1305 "%i32 = OpTypeInt 32 1\n"
1306 "%f32 = OpTypeFloat 32\n"
1307 "%v3u32 = OpTypeVector %u32 3\n"
1308 "%uvec3ptr = OpTypePointer Input %v3u32\n"
1309 "%i32ptr = OpTypePointer Uniform %i32\n"
1310 "%f32ptr = OpTypePointer Uniform %f32\n"
1312 "%zero = OpConstant %i32 0\n"
1313 "%c_i32_1 = OpConstant %i32 1\n"
1314 "%c_i32_2 = OpConstant %i32 2\n"
1315 "%c_i32_3 = OpConstant %i32 3\n"
1316 "%c_i32_16 = OpConstant %i32 16\n"
1317 "%c_i32_32 = OpConstant %i32 32\n"
1318 "%c_i32_64 = OpConstant %i32 64\n"
1319 "%c_i32_128 = OpConstant %i32 128\n"
1320 "%c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
1322 "%i32arr = OpTypeArray %i32 %c_i32_128\n"
1323 "%f32arr = OpTypeArray %f32 %c_i32_128\n"
1326 "${matrix_types:opt}\n"
1328 "%SSBO32 = OpTypeStruct %${matrix_prefix:opt}${base32}arr\n"
1329 "%SSBO16 = OpTypeStruct %${matrix_prefix:opt}${base16}arr\n"
1330 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
1331 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
1332 "%ssbo32 = OpVariable %up_SSBO32 Uniform\n"
1333 "%ssbo16 = OpVariable %up_SSBO16 Uniform\n"
1335 "%id = OpVariable %uvec3ptr Input\n"
1337 "%main = OpFunction %void None %voidf\n"
1338 "%label = OpLabel\n"
1339 "%idval = OpLoad %v3u32 %id\n"
1340 "%x = OpCompositeExtract %u32 %idval 0\n"
1341 "%inloc = OpAccessChain %${base16}ptr %ssbo16 %zero %${arrayindex} ${index0:opt}\n"
1342 "%val16 = OpLoad %${base16} %inloc\n"
1343 "%val32 = ${convert} %${base32} %val16\n"
1344 "%outloc = OpAccessChain %${base32}ptr %ssbo32 %zero %x ${index0:opt}\n"
1345 " OpStore %outloc %val32\n"
1346 "${matrix_store:opt}\n"
1348 " OpFunctionEnd\n");
1351 const char floatTypes[] =
1352 "%f16 = OpTypeFloat 16\n"
1353 "%f16ptr = OpTypePointer Uniform %f16\n"
1354 "%f16arr = OpTypeArray %f16 %c_i32_128\n"
1355 "%v2f16 = OpTypeVector %f16 2\n"
1356 "%v2f32 = OpTypeVector %f32 2\n"
1357 "%v2f16ptr = OpTypePointer Uniform %v2f16\n"
1358 "%v2f32ptr = OpTypePointer Uniform %v2f32\n"
1359 "%v2f16arr = OpTypeArray %v2f16 %c_i32_64\n"
1360 "%v2f32arr = OpTypeArray %v2f32 %c_i32_64\n";
1362 struct CompositeType
1368 bool useConstantIndex;
1369 unsigned constantIndex;
1371 unsigned inputStride;
1374 const CompositeType cTypes[2][5] =
1377 {"scalar", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 2\n", false, 0, numElements, 1},
1378 {"scalar_const_idx_5", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 2\n", true, 5, numElements, 1},
1379 {"scalar_const_idx_8", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 2\n", true, 8, numElements, 1},
1380 {"vector", "v2f32", "v2f16", "OpDecorate %v2f32arr ArrayStride 8\nOpDecorate %v2f16arr ArrayStride 4\n", false, 0, numElements / 2, 2},
1381 {"matrix", "v2f32", "v2f16", "OpDecorate %m4v2f32arr ArrayStride 32\nOpDecorate %m4v2f16arr ArrayStride 16\n", false, 0, numElements / 8, 8}
1384 {"scalar", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 16\n", false, 0, numElements, 8},
1385 {"scalar_const_idx_5", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 16\n", true, 5, numElements, 8},
1386 {"scalar_const_idx_8", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 16\n", true, 8, numElements, 8},
1387 {"vector", "v2f32", "v2f16", "OpDecorate %v2f32arr ArrayStride 8\nOpDecorate %v2f16arr ArrayStride 16\n", false, 0, numElements / 2, 8},
1388 {"matrix", "v2f32", "v2f16", "OpDecorate %m4v2f32arr ArrayStride 32\nOpDecorate %m4v2f16arr ArrayStride 16\n", false, 0, numElements / 8, 8}
1392 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
1393 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes[capIdx]); ++tyIdx)
1395 ComputeShaderSpec spec;
1396 map<string, string> specs;
1397 string testName = string(CAPABILITIES[capIdx].name) + "_" + cTypes[capIdx][tyIdx].name + "_float";
1399 specs["capability"] = CAPABILITIES[capIdx].cap;
1400 specs["storage"] = CAPABILITIES[capIdx].decor;
1401 specs["stride"] = cTypes[capIdx][tyIdx].stride;
1402 specs["base32"] = cTypes[capIdx][tyIdx].base32;
1403 specs["base16"] = cTypes[capIdx][tyIdx].base16;
1404 specs["types"] = floatTypes;
1405 specs["convert"] = "OpFConvert";
1406 specs["constarrayidx"] = de::toString(cTypes[capIdx][tyIdx].constantIndex);
1407 if (cTypes[capIdx][tyIdx].useConstantIndex)
1408 specs["arrayindex"] = "c_i32_ci";
1410 specs["arrayindex"] = "x";
1412 const deUint32 inputStride = cTypes[capIdx][tyIdx].inputStride;
1413 const deUint32 count = cTypes[capIdx][tyIdx].count;
1414 const deUint32 scalarsPerItem = numElements / count;
1415 vector<deFloat16> float16Data = getFloat16s(rnd, numElements * inputStride);
1416 vector<float> float32Data;
1418 float32Data.reserve(numElements);
1419 for (deUint32 numIdx = 0; numIdx < count; ++numIdx)
1420 for (deUint32 scalarIdx = 0; scalarIdx < scalarsPerItem; scalarIdx++)
1421 float32Data.push_back(deFloat16To32(float16Data[numIdx * inputStride + scalarIdx]));
1423 vector<float> float32DataConstIdx;
1424 if (cTypes[capIdx][tyIdx].useConstantIndex)
1426 const deUint32 numFloats = numElements / cTypes[capIdx][tyIdx].count;
1427 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
1428 float32DataConstIdx.push_back(float32Data[cTypes[capIdx][tyIdx].constantIndex * numFloats + numIdx % numFloats]);
1431 if (strcmp(cTypes[capIdx][tyIdx].name, "matrix") == 0)
1433 specs["index0"] = "%zero";
1434 specs["matrix_prefix"] = "m4";
1435 specs["matrix_types"] =
1436 "%m4v2f16 = OpTypeMatrix %v2f16 4\n"
1437 "%m4v2f32 = OpTypeMatrix %v2f32 4\n"
1438 "%m4v2f16arr = OpTypeArray %m4v2f16 %c_i32_16\n"
1439 "%m4v2f32arr = OpTypeArray %m4v2f32 %c_i32_16\n";
1440 specs["matrix_decor"] =
1441 "OpMemberDecorate %SSBO32 0 ColMajor\n"
1442 "OpMemberDecorate %SSBO32 0 MatrixStride 8\n"
1443 "OpMemberDecorate %SSBO16 0 ColMajor\n"
1444 "OpMemberDecorate %SSBO16 0 MatrixStride 4\n";
1445 specs["matrix_store"] =
1446 "%inloc_1 = OpAccessChain %v2f16ptr %ssbo16 %zero %x %c_i32_1\n"
1447 "%val16_1 = OpLoad %v2f16 %inloc_1\n"
1448 "%val32_1 = OpFConvert %v2f32 %val16_1\n"
1449 "%outloc_1 = OpAccessChain %v2f32ptr %ssbo32 %zero %x %c_i32_1\n"
1450 " OpStore %outloc_1 %val32_1\n"
1452 "%inloc_2 = OpAccessChain %v2f16ptr %ssbo16 %zero %x %c_i32_2\n"
1453 "%val16_2 = OpLoad %v2f16 %inloc_2\n"
1454 "%val32_2 = OpFConvert %v2f32 %val16_2\n"
1455 "%outloc_2 = OpAccessChain %v2f32ptr %ssbo32 %zero %x %c_i32_2\n"
1456 " OpStore %outloc_2 %val32_2\n"
1458 "%inloc_3 = OpAccessChain %v2f16ptr %ssbo16 %zero %x %c_i32_3\n"
1459 "%val16_3 = OpLoad %v2f16 %inloc_3\n"
1460 "%val32_3 = OpFConvert %v2f32 %val16_3\n"
1461 "%outloc_3 = OpAccessChain %v2f32ptr %ssbo32 %zero %x %c_i32_3\n"
1462 " OpStore %outloc_3 %val32_3\n";
1465 spec.assembly = shaderTemplate.specialize(specs);
1466 spec.numWorkGroups = IVec3(cTypes[capIdx][tyIdx].count, 1, 1);
1467 spec.verifyIO = check32BitFloats;
1469 spec.inputs.push_back(Resource(BufferSp(new Float16Buffer(float16Data)), CAPABILITIES[capIdx].dtype));
1470 spec.outputs.push_back(Resource(BufferSp(new Float32Buffer(cTypes[capIdx][tyIdx].useConstantIndex ? float32DataConstIdx : float32Data))));
1471 spec.extensions.push_back("VK_KHR_16bit_storage");
1472 spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
1474 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
1479 const char sintTypes[] =
1480 "%i16 = OpTypeInt 16 1\n"
1481 "%i16ptr = OpTypePointer Uniform %i16\n"
1482 "%i16arr = OpTypeArray %i16 %c_i32_128\n"
1483 "%v4i16 = OpTypeVector %i16 4\n"
1484 "%v4i32 = OpTypeVector %i32 4\n"
1485 "%v4i16ptr = OpTypePointer Uniform %v4i16\n"
1486 "%v4i32ptr = OpTypePointer Uniform %v4i32\n"
1487 "%v4i16arr = OpTypeArray %v4i16 %c_i32_32\n"
1488 "%v4i32arr = OpTypeArray %v4i32 %c_i32_32\n";
1490 const char uintTypes[] =
1491 "%u16 = OpTypeInt 16 0\n"
1492 "%u16ptr = OpTypePointer Uniform %u16\n"
1493 "%u32ptr = OpTypePointer Uniform %u32\n"
1494 "%u16arr = OpTypeArray %u16 %c_i32_128\n"
1495 "%u32arr = OpTypeArray %u32 %c_i32_128\n"
1496 "%v4u16 = OpTypeVector %u16 4\n"
1497 "%v4u32 = OpTypeVector %u32 4\n"
1498 "%v4u16ptr = OpTypePointer Uniform %v4u16\n"
1499 "%v4u32ptr = OpTypePointer Uniform %v4u32\n"
1500 "%v4u16arr = OpTypeArray %v4u16 %c_i32_32\n"
1501 "%v4u32arr = OpTypeArray %v4u32 %c_i32_32\n";
1503 struct CompositeType
1512 bool useConstantIndex;
1513 unsigned constantIndex;
1515 unsigned inputStride;
1518 const CompositeType cTypes[2][8] =
1521 {"scalar_sint", true, sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 2\n", false, 0, numElements, 1},
1522 {"scalar_sint_const_idx_5", true, sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 2\n", true, 5, numElements, 1},
1523 {"scalar_sint_const_idx_8", true, sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 2\n", true, 8, numElements, 1},
1524 {"scalar_uint", false, uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 2\n", false, 0, numElements, 1},
1525 {"scalar_uint_const_idx_5", false, uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 2\n", true, 5, numElements, 1},
1526 {"scalar_uint_const_idx_8", false, uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 2\n", true, 8, numElements, 1},
1527 {"vector_sint", true, sintTypes, "v4i32", "v4i16", "OpSConvert", "OpDecorate %v4i32arr ArrayStride 16\nOpDecorate %v4i16arr ArrayStride 8\n", false, 0, numElements / 4, 4},
1528 {"vector_uint", false, uintTypes, "v4u32", "v4u16", "OpUConvert", "OpDecorate %v4u32arr ArrayStride 16\nOpDecorate %v4u16arr ArrayStride 8\n", false, 0, numElements / 4, 4}
1531 {"scalar_sint", true, sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 16\n", false, 0, numElements, 8},
1532 {"scalar_sint_const_idx_5", true, sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 16\n", true, 5, numElements, 8},
1533 {"scalar_sint_const_idx_8", true, sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 16\n", true, 8, numElements, 8},
1534 {"scalar_uint", false, uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 16\n", false, 0, numElements, 8},
1535 {"scalar_uint_const_idx_5", false, uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 16\n", true, 5, numElements, 8},
1536 {"scalar_uint_const_idx_8", false, uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 16\n", true, 8, numElements, 8},
1537 {"vector_sint", true, sintTypes, "v4i32", "v4i16", "OpSConvert", "OpDecorate %v4i32arr ArrayStride 16\nOpDecorate %v4i16arr ArrayStride 16\n", false, 0, numElements / 4, 8},
1538 {"vector_uint", false, uintTypes, "v4u32", "v4u16", "OpUConvert", "OpDecorate %v4u32arr ArrayStride 16\nOpDecorate %v4u16arr ArrayStride 16\n", false, 0, numElements / 4, 8}
1542 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
1543 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes[capIdx]); ++tyIdx)
1545 ComputeShaderSpec spec;
1546 map<string, string> specs;
1547 string testName = string(CAPABILITIES[capIdx].name) + "_" + cTypes[capIdx][tyIdx].name;
1548 const deUint32 inputStride = cTypes[capIdx][tyIdx].inputStride;
1549 vector<deInt16> inputs = getInt16s(rnd, numElements * inputStride);
1550 vector<deInt32> sOutputs;
1551 vector<deInt32> uOutputs;
1552 const deUint16 signBitMask = 0x8000;
1553 const deUint32 signExtendMask = 0xffff0000;
1554 const deUint32 count = cTypes[capIdx][tyIdx].count;
1555 const deUint32 scalarsPerItem = numElements / count;
1557 sOutputs.reserve(numElements);
1558 uOutputs.reserve(numElements);
1560 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
1561 for (deUint32 scalarIdx = 0; scalarIdx < scalarsPerItem; ++scalarIdx)
1563 const deInt16 input = inputs[numNdx * inputStride + scalarIdx];
1565 uOutputs.push_back(static_cast<deUint16>(input));
1566 if (input & signBitMask)
1567 sOutputs.push_back(static_cast<deInt32>(input | signExtendMask));
1569 sOutputs.push_back(static_cast<deInt32>(input));
1572 vector<deInt32> intDataConstIdx;
1574 if (cTypes[capIdx][tyIdx].useConstantIndex)
1576 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
1578 const deInt32 idx = cTypes[capIdx][tyIdx].constantIndex * scalarsPerItem + numIdx % scalarsPerItem;
1580 if (cTypes[capIdx][tyIdx].isSigned)
1581 intDataConstIdx.push_back(sOutputs[idx]);
1583 intDataConstIdx.push_back(uOutputs[idx]);
1587 specs["capability"] = CAPABILITIES[capIdx].cap;
1588 specs["storage"] = CAPABILITIES[capIdx].decor;
1589 specs["stride"] = cTypes[capIdx][tyIdx].stride;
1590 specs["base32"] = cTypes[capIdx][tyIdx].base32;
1591 specs["base16"] = cTypes[capIdx][tyIdx].base16;
1592 specs["types"] = cTypes[capIdx][tyIdx].types;
1593 specs["convert"] = cTypes[capIdx][tyIdx].opcode;
1594 specs["constarrayidx"] = de::toString(cTypes[capIdx][tyIdx].constantIndex);
1595 if (cTypes[capIdx][tyIdx].useConstantIndex)
1596 specs["arrayindex"] = "c_i32_ci";
1598 specs["arrayindex"] = "x";
1600 spec.assembly = shaderTemplate.specialize(specs);
1601 spec.numWorkGroups = IVec3(cTypes[capIdx][tyIdx].count, 1, 1);
1603 spec.inputs.push_back(Resource(BufferSp(new Int16Buffer(inputs)), CAPABILITIES[capIdx].dtype));
1604 if (cTypes[capIdx][tyIdx].useConstantIndex)
1605 spec.outputs.push_back(Resource(BufferSp(new Int32Buffer(intDataConstIdx))));
1606 else if (cTypes[capIdx][tyIdx].isSigned)
1607 spec.outputs.push_back(Resource(BufferSp(new Int32Buffer(sOutputs))));
1609 spec.outputs.push_back(Resource(BufferSp(new Int32Buffer(uOutputs))));
1610 spec.extensions.push_back("VK_KHR_16bit_storage");
1611 spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
1613 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
1618 void addCompute16bitStorageUniform16To32ChainAccessGroup (tcu::TestCaseGroup* group)
1620 tcu::TestContext& testCtx = group->getTestContext();
1621 de::Random rnd (deStringHash(group->getName()));
1622 const deUint32 structSize = 128; // In number of 16bit items. Includes padding.
1623 vector<deFloat16> inputDataFloat = getFloat16s(rnd, structSize * 4);
1624 vector<deInt16> inputDataInt = getInt16s(rnd, structSize * 4);
1625 vector<float> outputDataFloat;
1626 vector<deInt32> outputDataSInt;
1627 vector<deInt32> outputDataUInt;
1628 vector<tcu::UVec4> indices;
1630 // Input is an array of a struct that varies on 16bit data type being tested:
1634 // float16 scalars[3]
1641 // int16 array2D[4][3]
1646 // uint16 scalars[3]
1647 // uint16 array2D[4][3]
1650 const StringTemplate shaderTemplate (
1651 " OpCapability Shader\n"
1652 " OpCapability ${capability}\n"
1653 " OpExtension \"SPV_KHR_16bit_storage\"\n"
1654 " %1 = OpExtInstImport \"GLSL.std.450\"\n"
1655 " OpMemoryModel Logical GLSL450\n"
1656 " OpEntryPoint GLCompute %main \"main\"\n"
1657 " OpExecutionMode %main LocalSize 1 1 1\n"
1658 " OpSource GLSL 430\n"
1659 " OpDecorate %Output BufferBlock\n"
1660 " OpDecorate %dataOutput DescriptorSet 0\n"
1661 " OpDecorate %dataOutput Binding 1\n"
1662 " OpDecorate %scalarArray ArrayStride 16\n"
1663 " OpDecorate %scalarArray2D ArrayStride 48\n"
1664 " OpMemberDecorate %S 0 Offset 0\n"
1665 " OpMemberDecorate %S 1 Offset 48\n"
1666 " ${decoration:opt}\n"
1667 " OpMemberDecorate %S 2 Offset 240\n"
1668 " OpDecorate %_arr_S_uint_4 ArrayStride 256\n"
1669 " OpMemberDecorate %Input 0 Offset 0\n"
1670 " OpMemberDecorate %Output 0 Offset 0\n"
1671 " OpDecorate %Input ${storage}\n"
1672 " OpDecorate %dataInput DescriptorSet 0\n"
1673 " OpDecorate %dataInput Binding 0\n"
1674 " %f16 = OpTypeFloat 16\n"
1675 " %f32 = OpTypeFloat 32\n"
1676 " %i16 = OpTypeInt 16 1\n"
1677 " %i32 = OpTypeInt 32 1\n"
1678 " %u16 = OpTypeInt 16 0\n"
1679 " %u32 = OpTypeInt 32 0\n"
1680 " %void = OpTypeVoid\n"
1681 " %voidFunc = OpTypeFunction %void\n"
1682 " %_ptr_Function_uint = OpTypePointer Function %u32\n"
1683 " %v3u32 = OpTypeVector %u32 3\n"
1684 " %_ptr_Input_v3u32 = OpTypePointer Input %v3u32\n"
1685 " %int_0 = OpConstant %i32 0\n"
1686 " %uint_3 = OpConstant %u32 3\n"
1687 " %uint_4 = OpConstant %u32 4\n"
1688 " %s0 = OpConstant %u32 ${s0}\n"
1689 " %s1 = OpConstant %u32 ${s1}\n"
1690 " %s2 = OpConstant %u32 ${s2}\n"
1691 " %s3 = OpConstant %u32 ${s3}\n"
1692 " %Output = OpTypeStruct %${type}32\n"
1693 " %_ptr_Uniform_Output = OpTypePointer Uniform %Output\n"
1694 " %dataOutput = OpVariable %_ptr_Uniform_Output Uniform\n"
1695 " %scalarArray = OpTypeArray %${type}16 %uint_3\n"
1696 " %v3f16 = OpTypeVector %f16 3\n"
1697 " %v3i16 = OpTypeVector %i16 3\n"
1698 " %v3u16 = OpTypeVector %u16 3\n"
1699 " %matrix = OpTypeMatrix %v3f16 4\n"
1700 " %scalarArray2D = OpTypeArray %scalarArray %uint_4\n"
1701 " %S = OpTypeStruct %scalarArray %${type2D} %v3${type}16\n"
1702 " %_arr_S_uint_4 = OpTypeArray %S %uint_4\n"
1703 " %Input = OpTypeStruct %_arr_S_uint_4\n"
1704 " %_ptr_Uniform_Input = OpTypePointer Uniform %Input\n"
1705 " %dataInput = OpVariable %_ptr_Uniform_Input Uniform\n"
1706 " %_ptr_Uniform_16bit_data = OpTypePointer Uniform %${type}16\n"
1707 " %_ptr_Uniform_32bit_data = OpTypePointer Uniform %${type}32\n"
1708 " %main = OpFunction %void None %voidFunc\n"
1709 " %entry = OpLabel\n"
1710 " %dataPtr = ${accessChain}\n"
1711 " %data = OpLoad %${type}16 %dataPtr\n"
1712 " %converted = ${convert}\n"
1713 " %outPtr = OpAccessChain %_ptr_Uniform_32bit_data %dataOutput %int_0\n"
1714 " OpStore %outPtr %converted\n"
1716 " OpFunctionEnd\n");
1718 // Generate constant indices for OpChainAccess. We need to use constant values
1719 // when indexing into structures. This loop generates all permutations.
1720 for (deUint32 idx0 = 0; idx0 < 4; ++idx0)
1721 for (deUint32 idx1 = 0; idx1 < 3; ++idx1)
1722 for (deUint32 idx2 = 0; idx2 < (idx1 == 1u ? 4u : 3u); ++idx2)
1723 for (deUint32 idx3 = 0; idx3 < (idx1 == 1u ? 3u : 1u); ++idx3)
1724 indices.push_back(tcu::UVec4(idx0, idx1, idx2, idx3));
1727 for (deUint32 numIdx = 0; numIdx < (deUint32)indices.size(); ++numIdx)
1729 const deUint16 signBitMask = 0x8000;
1730 const deUint32 signExtendMask = 0xffff0000;
1731 // Determine the selected output float for the selected indices.
1732 const tcu::UVec4 vec = indices[numIdx];
1733 // Offsets are in multiples of 16bits. Floats are using matrix as the
1734 // second field, which has different layout rules than 2D array.
1735 // Therefore separate offset tables are needed.
1736 const deUint32 fieldOffsetsFloat[3][3] =
1742 const deUint32 fieldOffsetsInt[3][3] =
1748 const deUint32 offsetFloat = vec.x() * structSize + fieldOffsetsFloat[vec.y()][0] + fieldOffsetsFloat[vec.y()][1] * vec.z() + fieldOffsetsFloat[vec.y()][2] * vec.w();
1749 const deUint32 offsetInt = vec.x() * structSize + fieldOffsetsInt[vec.y()][0] + fieldOffsetsInt[vec.y()][1] * vec.z() + fieldOffsetsInt[vec.y()][2] * vec.w();
1750 const bool hasSign = inputDataInt[offsetInt] & signBitMask;
1752 outputDataFloat.push_back(deFloat16To32(inputDataFloat[offsetFloat]));
1753 outputDataUInt.push_back((deUint16)inputDataInt[offsetInt]);
1754 outputDataSInt.push_back((deInt32)(inputDataInt[offsetInt] | (hasSign ? signExtendMask : 0u)));
1757 for (deUint32 indicesIdx = 0; indicesIdx < (deUint32)indices.size(); ++indicesIdx)
1758 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
1760 string indexString = de::toString(indices[indicesIdx].x()) + "_" + de::toString(indices[indicesIdx].y()) + "_" + de::toString(indices[indicesIdx].z());
1761 if (indices[indicesIdx].y() == 1)
1762 indexString += string("_") + de::toString(indices[indicesIdx].w());
1764 const string testNameBase = string(CAPABILITIES[capIdx].name) + "_" + indexString + "_";
1765 const ComputeTestFeatures features = COMPUTE_TEST_USES_NONE;
1772 string type2D; // Matrix when using floats. 2D array otherwise.
1777 const DataType dataTypes[] =
1779 { "float", "f", "OpFConvert %f32 %data", "matrix", BufferSp(new Float16Buffer(inputDataFloat)), BufferSp(new Float32Buffer(vector<float>(1, outputDataFloat[indicesIdx]))) },
1780 { "int", "i", "OpSConvert %i32 %data", "scalarArray2D", BufferSp(new Int16Buffer(inputDataInt)), BufferSp(new Int32Buffer(vector<deInt32>(1, outputDataSInt[indicesIdx]))) },
1781 { "uint", "u", "OpUConvert %u32 %data", "scalarArray2D", BufferSp(new Int16Buffer(inputDataInt)), BufferSp(new Int32Buffer(vector<deInt32>(1, outputDataUInt[indicesIdx]))) }
1784 for (deUint32 dataTypeIdx = 0; dataTypeIdx < DE_LENGTH_OF_ARRAY(dataTypes); ++dataTypeIdx)
1786 const string testName = testNameBase + dataTypes[dataTypeIdx].name;
1787 map<string, string> specs;
1788 ComputeShaderSpec spec;
1790 specs["capability"] = CAPABILITIES[capIdx].cap;
1791 specs["storage"] = CAPABILITIES[capIdx].decor;
1792 specs["s0"] = de::toString(indices[indicesIdx].x());
1793 specs["s1"] = de::toString(indices[indicesIdx].y());
1794 specs["s2"] = de::toString(indices[indicesIdx].z());
1795 specs["s3"] = de::toString(indices[indicesIdx].w());
1796 specs["type"] = dataTypes[dataTypeIdx].type;
1797 specs["convert"] = dataTypes[dataTypeIdx].convert;
1798 specs["type2D"] = dataTypes[dataTypeIdx].type2D;
1800 if (indices[indicesIdx].y() == 1)
1801 specs["accessChain"] = "OpAccessChain %_ptr_Uniform_16bit_data %dataInput %int_0 %s0 %s1 %s2 %s3";
1803 specs["accessChain"] = "OpAccessChain %_ptr_Uniform_16bit_data %dataInput %int_0 %s0 %s1 %s2";
1805 if (dataTypeIdx == 0)
1807 spec.verifyIO = check32BitFloats;
1808 specs["decoration"] = "OpMemberDecorate %S 1 ColMajor\nOpMemberDecorate %S 1 MatrixStride 48\n";
1811 spec.assembly = shaderTemplate.specialize(specs);
1812 spec.numWorkGroups = IVec3(1, 1, 1);
1813 spec.extensions.push_back ("VK_KHR_16bit_storage");
1814 spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
1815 spec.inputs.push_back(Resource(dataTypes[dataTypeIdx].inputs, CAPABILITIES[capIdx].dtype));
1816 spec.outputs.push_back(Resource(dataTypes[dataTypeIdx].outputs));
1818 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec, features));
1823 void addCompute16bitStoragePushConstant16To32Group (tcu::TestCaseGroup* group)
1825 tcu::TestContext& testCtx = group->getTestContext();
1826 de::Random rnd (deStringHash(group->getName()));
1827 const int numElements = 64;
1829 const StringTemplate shaderTemplate (
1830 "OpCapability Shader\n"
1831 "OpCapability StoragePushConstant16\n"
1832 "OpExtension \"SPV_KHR_16bit_storage\"\n"
1833 "OpMemoryModel Logical GLSL450\n"
1834 "OpEntryPoint GLCompute %main \"main\" %id\n"
1835 "OpExecutionMode %main LocalSize 1 1 1\n"
1836 "OpDecorate %id BuiltIn GlobalInvocationId\n"
1840 "OpDecorate %PC16 BufferBlock\n"
1841 "OpMemberDecorate %PC16 0 Offset 0\n"
1842 "OpMemberDecorate %SSBO32 0 Offset 0\n"
1843 "OpDecorate %SSBO32 BufferBlock\n"
1844 "OpDecorate %ssbo32 DescriptorSet 0\n"
1845 "OpDecorate %ssbo32 Binding 0\n"
1847 "${matrix_decor:opt}\n"
1849 "%void = OpTypeVoid\n"
1850 "%voidf = OpTypeFunction %void\n"
1851 "%u32 = OpTypeInt 32 0\n"
1852 "%i32 = OpTypeInt 32 1\n"
1853 "%f32 = OpTypeFloat 32\n"
1854 "%v3u32 = OpTypeVector %u32 3\n"
1855 "%uvec3ptr = OpTypePointer Input %v3u32\n"
1856 "%i32ptr = OpTypePointer Uniform %i32\n"
1857 "%f32ptr = OpTypePointer Uniform %f32\n"
1859 "%zero = OpConstant %i32 0\n"
1860 "%c_i32_1 = OpConstant %i32 1\n"
1861 "%c_i32_8 = OpConstant %i32 8\n"
1862 "%c_i32_16 = OpConstant %i32 16\n"
1863 "%c_i32_32 = OpConstant %i32 32\n"
1864 "%c_i32_64 = OpConstant %i32 64\n"
1865 "%c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
1867 "%i32arr = OpTypeArray %i32 %c_i32_64\n"
1868 "%f32arr = OpTypeArray %f32 %c_i32_64\n"
1871 "${matrix_types:opt}\n"
1873 "%PC16 = OpTypeStruct %${matrix_prefix:opt}${base16}arr\n"
1874 "%pp_PC16 = OpTypePointer PushConstant %PC16\n"
1875 "%pc16 = OpVariable %pp_PC16 PushConstant\n"
1876 "%SSBO32 = OpTypeStruct %${matrix_prefix:opt}${base32}arr\n"
1877 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
1878 "%ssbo32 = OpVariable %up_SSBO32 Uniform\n"
1880 "%id = OpVariable %uvec3ptr Input\n"
1882 "%main = OpFunction %void None %voidf\n"
1883 "%label = OpLabel\n"
1884 "%idval = OpLoad %v3u32 %id\n"
1885 "%x = OpCompositeExtract %u32 %idval 0\n"
1886 "%inloc = OpAccessChain %${base16}ptr %pc16 %zero %${arrayindex} ${index0:opt}\n"
1887 "%val16 = OpLoad %${base16} %inloc\n"
1888 "%val32 = ${convert} %${base32} %val16\n"
1889 "%outloc = OpAccessChain %${base32}ptr %ssbo32 %zero %x ${index0:opt}\n"
1890 " OpStore %outloc %val32\n"
1891 "${matrix_store:opt}\n"
1893 " OpFunctionEnd\n");
1896 const char floatTypes[] =
1897 "%f16 = OpTypeFloat 16\n"
1898 "%f16ptr = OpTypePointer PushConstant %f16\n"
1899 "%f16arr = OpTypeArray %f16 %c_i32_64\n"
1900 "%v4f16 = OpTypeVector %f16 4\n"
1901 "%v4f32 = OpTypeVector %f32 4\n"
1902 "%v4f16ptr = OpTypePointer PushConstant %v4f16\n"
1903 "%v4f32ptr = OpTypePointer Uniform %v4f32\n"
1904 "%v4f16arr = OpTypeArray %v4f16 %c_i32_16\n"
1905 "%v4f32arr = OpTypeArray %v4f32 %c_i32_16\n";
1907 struct CompositeType
1913 bool useConstantIndex;
1914 unsigned constantIndex;
1918 const CompositeType cTypes[] =
1920 {"scalar", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 2\n", false, 0, numElements},
1921 {"scalar_const_idx_5", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 2\n", true, 5, numElements},
1922 {"scalar_const_idx_8", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 2\n", true, 8, numElements},
1923 {"vector", "v4f32", "v4f16", "OpDecorate %v4f32arr ArrayStride 16\nOpDecorate %v4f16arr ArrayStride 8\n", false, 0, numElements / 4},
1924 {"matrix", "v4f32", "v4f16", "OpDecorate %m2v4f32arr ArrayStride 32\nOpDecorate %m2v4f16arr ArrayStride 16\n", false, 0, numElements / 8},
1927 vector<deFloat16> float16Data = getFloat16s(rnd, numElements);
1928 vector<float> float32Data;
1930 float32Data.reserve(numElements);
1931 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
1932 float32Data.push_back(deFloat16To32(float16Data[numIdx]));
1934 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1936 ComputeShaderSpec spec;
1937 map<string, string> specs;
1938 string testName = string(cTypes[tyIdx].name) + "_float";
1940 vector<float> float32DataConstIdx;
1941 if (cTypes[tyIdx].useConstantIndex)
1943 const deUint32 numFloats = numElements / cTypes[tyIdx].count;
1944 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
1945 float32DataConstIdx.push_back(float32Data[cTypes[tyIdx].constantIndex * numFloats + numIdx % numFloats]);
1948 specs["stride"] = cTypes[tyIdx].stride;
1949 specs["base32"] = cTypes[tyIdx].base32;
1950 specs["base16"] = cTypes[tyIdx].base16;
1951 specs["types"] = floatTypes;
1952 specs["convert"] = "OpFConvert";
1953 specs["constarrayidx"] = de::toString(cTypes[tyIdx].constantIndex);
1954 if (cTypes[tyIdx].useConstantIndex)
1955 specs["arrayindex"] = "c_i32_ci";
1957 specs["arrayindex"] = "x";
1959 if (strcmp(cTypes[tyIdx].name, "matrix") == 0)
1961 specs["index0"] = "%zero";
1962 specs["matrix_prefix"] = "m2";
1963 specs["matrix_types"] =
1964 "%m2v4f16 = OpTypeMatrix %v4f16 2\n"
1965 "%m2v4f32 = OpTypeMatrix %v4f32 2\n"
1966 "%m2v4f16arr = OpTypeArray %m2v4f16 %c_i32_8\n"
1967 "%m2v4f32arr = OpTypeArray %m2v4f32 %c_i32_8\n";
1968 specs["matrix_decor"] =
1969 "OpMemberDecorate %SSBO32 0 ColMajor\n"
1970 "OpMemberDecorate %SSBO32 0 MatrixStride 16\n"
1971 "OpMemberDecorate %PC16 0 ColMajor\n"
1972 "OpMemberDecorate %PC16 0 MatrixStride 8\n";
1973 specs["matrix_store"] =
1974 "%inloc_1 = OpAccessChain %v4f16ptr %pc16 %zero %x %c_i32_1\n"
1975 "%val16_1 = OpLoad %v4f16 %inloc_1\n"
1976 "%val32_1 = OpFConvert %v4f32 %val16_1\n"
1977 "%outloc_1 = OpAccessChain %v4f32ptr %ssbo32 %zero %x %c_i32_1\n"
1978 " OpStore %outloc_1 %val32_1\n";
1981 spec.assembly = shaderTemplate.specialize(specs);
1982 spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
1983 spec.verifyIO = check32BitFloats;
1984 spec.pushConstants = BufferSp(new Float16Buffer(float16Data));
1986 spec.outputs.push_back(Resource(BufferSp(new Float32Buffer(cTypes[tyIdx].useConstantIndex ? float32DataConstIdx : float32Data))));
1987 spec.extensions.push_back("VK_KHR_16bit_storage");
1988 spec.requestedVulkanFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
1990 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
1994 const char sintTypes[] =
1995 "%i16 = OpTypeInt 16 1\n"
1996 "%i16ptr = OpTypePointer PushConstant %i16\n"
1997 "%i16arr = OpTypeArray %i16 %c_i32_64\n"
1998 "%v2i16 = OpTypeVector %i16 2\n"
1999 "%v2i32 = OpTypeVector %i32 2\n"
2000 "%v2i16ptr = OpTypePointer PushConstant %v2i16\n"
2001 "%v2i32ptr = OpTypePointer Uniform %v2i32\n"
2002 "%v2i16arr = OpTypeArray %v2i16 %c_i32_32\n"
2003 "%v2i32arr = OpTypeArray %v2i32 %c_i32_32\n";
2005 const char uintTypes[] =
2006 "%u16 = OpTypeInt 16 0\n"
2007 "%u16ptr = OpTypePointer PushConstant %u16\n"
2008 "%u32ptr = OpTypePointer Uniform %u32\n"
2009 "%u16arr = OpTypeArray %u16 %c_i32_64\n"
2010 "%u32arr = OpTypeArray %u32 %c_i32_64\n"
2011 "%v2u16 = OpTypeVector %u16 2\n"
2012 "%v2u32 = OpTypeVector %u32 2\n"
2013 "%v2u16ptr = OpTypePointer PushConstant %v2u16\n"
2014 "%v2u32ptr = OpTypePointer Uniform %v2u32\n"
2015 "%v2u16arr = OpTypeArray %v2u16 %c_i32_32\n"
2016 "%v2u32arr = OpTypeArray %v2u32 %c_i32_32\n";
2018 struct CompositeType
2027 bool useConstantIndex;
2028 unsigned constantIndex;
2032 const CompositeType cTypes[] =
2034 {"scalar_sint", true, sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 2\n", false, 0, numElements},
2035 {"scalar_sint_const_idx_5", true, sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 2\n", true, 5, numElements},
2036 {"scalar_sint_const_idx_8", true, sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 2\n", true, 8, numElements},
2037 {"scalar_uint", false, uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 2\n", false, 0, numElements},
2038 {"scalar_uint_const_idx_5", false, uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 2\n", true, 5, numElements},
2039 {"scalar_uint_const_idx_8", false, uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 2\n", true, 8, numElements},
2040 {"vector_sint", true, sintTypes, "v2i32", "v2i16", "OpSConvert", "OpDecorate %v2i32arr ArrayStride 8\nOpDecorate %v2i16arr ArrayStride 4\n", false, 0, numElements / 2},
2041 {"vector_uint", false, uintTypes, "v2u32", "v2u16", "OpUConvert", "OpDecorate %v2u32arr ArrayStride 8\nOpDecorate %v2u16arr ArrayStride 4\n", false, 0, numElements / 2},
2044 vector<deInt16> inputs = getInt16s(rnd, numElements);
2045 vector<deInt32> sOutputs;
2046 vector<deInt32> uOutputs;
2047 const deUint16 signBitMask = 0x8000;
2048 const deUint32 signExtendMask = 0xffff0000;
2050 sOutputs.reserve(inputs.size());
2051 uOutputs.reserve(inputs.size());
2053 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
2055 uOutputs.push_back(static_cast<deUint16>(inputs[numNdx]));
2056 if (inputs[numNdx] & signBitMask)
2057 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx] | signExtendMask));
2059 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx]));
2062 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
2064 ComputeShaderSpec spec;
2065 map<string, string> specs;
2066 const char* testName = cTypes[tyIdx].name;
2067 vector<deInt32> intDataConstIdx;
2069 if (cTypes[tyIdx].useConstantIndex)
2071 const deUint32 numInts = numElements / cTypes[tyIdx].count;
2073 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
2075 const deInt32 idx = cTypes[tyIdx].constantIndex * numInts + numIdx % numInts;
2077 if (cTypes[tyIdx].isSigned)
2078 intDataConstIdx.push_back(sOutputs[idx]);
2080 intDataConstIdx.push_back(uOutputs[idx]);
2084 specs["stride"] = cTypes[tyIdx].stride;
2085 specs["base32"] = cTypes[tyIdx].base32;
2086 specs["base16"] = cTypes[tyIdx].base16;
2087 specs["types"] = cTypes[tyIdx].types;
2088 specs["convert"] = cTypes[tyIdx].opcode;
2089 specs["constarrayidx"] = de::toString(cTypes[tyIdx].constantIndex);
2090 if (cTypes[tyIdx].useConstantIndex)
2091 specs["arrayindex"] = "c_i32_ci";
2093 specs["arrayindex"] = "x";
2095 spec.assembly = shaderTemplate.specialize(specs);
2096 spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
2097 spec.pushConstants = BufferSp(new Int16Buffer(inputs));
2099 if (cTypes[tyIdx].useConstantIndex)
2100 spec.outputs.push_back(Resource(BufferSp(new Int32Buffer(intDataConstIdx))));
2101 else if (cTypes[tyIdx].isSigned)
2102 spec.outputs.push_back(Resource(BufferSp(new Int32Buffer(sOutputs))));
2104 spec.outputs.push_back(Resource(BufferSp(new Int32Buffer(uOutputs))));
2105 spec.extensions.push_back("VK_KHR_16bit_storage");
2106 spec.requestedVulkanFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
2108 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName, testName, spec));
2113 void addGraphics16BitStorageUniformInt32To16Group (tcu::TestCaseGroup* testGroup)
2115 de::Random rnd (deStringHash(testGroup->getName()));
2116 map<string, string> fragments;
2117 const deUint32 numDataPoints = 256;
2118 RGBA defaultColors[4];
2119 vector<string> extensions;
2120 const StringTemplate capabilities ("OpCapability ${cap}\n");
2121 // inputs and outputs are declared to be vectors of signed integers.
2122 // However, depending on the test, they may be interpreted as unsiged
2123 // integers. That won't be a problem as long as we passed the bits
2124 // in faithfully to the pipeline.
2125 vector<deInt32> inputs = getInt32s(rnd, numDataPoints);
2126 vector<deInt16> outputs;
2128 outputs.reserve(inputs.size());
2129 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
2130 outputs.push_back(static_cast<deInt16>(0xffff & inputs[numNdx]));
2133 extensions.push_back("VK_KHR_16bit_storage");
2134 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
2136 getDefaultColors(defaultColors);
2144 const char* isSigned;
2147 const IntegerFacts intFacts[] =
2149 {"sint", "%i32", "%i16", "OpSConvert", "1"},
2150 {"uint", "%u32", "%u16", "OpUConvert", "0"},
2153 const StringTemplate scalarPreMain(
2154 "${itype16} = OpTypeInt 16 ${signed}\n"
2155 "%c_i32_256 = OpConstant %i32 256\n"
2156 " %up_i32 = OpTypePointer Uniform ${itype32}\n"
2157 " %up_i16 = OpTypePointer Uniform ${itype16}\n"
2158 " %ra_i32 = OpTypeArray ${itype32} %c_i32_256\n"
2159 " %ra_i16 = OpTypeArray ${itype16} %c_i32_256\n"
2160 " %SSBO32 = OpTypeStruct %ra_i32\n"
2161 " %SSBO16 = OpTypeStruct %ra_i16\n"
2162 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2163 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
2164 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2165 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n");
2167 const StringTemplate scalarDecoration(
2168 "OpDecorate %ra_i32 ArrayStride ${arraystride}\n"
2169 "OpDecorate %ra_i16 ArrayStride 2\n"
2170 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2171 "OpMemberDecorate %SSBO16 0 Offset 0\n"
2172 "OpDecorate %SSBO32 ${indecor}\n"
2173 "OpDecorate %SSBO16 BufferBlock\n"
2174 "OpDecorate %ssbo32 DescriptorSet 0\n"
2175 "OpDecorate %ssbo16 DescriptorSet 0\n"
2176 "OpDecorate %ssbo32 Binding 0\n"
2177 "OpDecorate %ssbo16 Binding 1\n");
2179 const StringTemplate scalarTestFunc(
2180 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
2181 " %param = OpFunctionParameter %v4f32\n"
2183 "%entry = OpLabel\n"
2184 " %i = OpVariable %fp_i32 Function\n"
2185 " OpStore %i %c_i32_0\n"
2188 " %loop = OpLabel\n"
2189 " %15 = OpLoad %i32 %i\n"
2190 " %lt = OpSLessThan %bool %15 %c_i32_256\n"
2191 " OpLoopMerge %merge %inc None\n"
2192 " OpBranchConditional %lt %write %merge\n"
2194 "%write = OpLabel\n"
2195 " %30 = OpLoad %i32 %i\n"
2196 " %src = OpAccessChain %up_i32 %ssbo32 %c_i32_0 %30\n"
2197 "%val32 = OpLoad ${itype32} %src\n"
2198 "%val16 = ${convert} ${itype16} %val32\n"
2199 " %dst = OpAccessChain %up_i16 %ssbo16 %c_i32_0 %30\n"
2200 " OpStore %dst %val16\n"
2204 " %37 = OpLoad %i32 %i\n"
2205 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
2209 "%merge = OpLabel\n"
2210 " OpReturnValue %param\n"
2214 const StringTemplate vecPreMain(
2215 "${itype16} = OpTypeInt 16 ${signed}\n"
2216 " %c_i32_64 = OpConstant %i32 64\n"
2217 "%v4itype16 = OpTypeVector ${itype16} 4\n"
2218 " %up_v4i32 = OpTypePointer Uniform ${v4itype32}\n"
2219 " %up_v4i16 = OpTypePointer Uniform %v4itype16\n"
2220 " %ra_v4i32 = OpTypeArray ${v4itype32} %c_i32_64\n"
2221 " %ra_v4i16 = OpTypeArray %v4itype16 %c_i32_64\n"
2222 " %SSBO32 = OpTypeStruct %ra_v4i32\n"
2223 " %SSBO16 = OpTypeStruct %ra_v4i16\n"
2224 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2225 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
2226 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2227 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n");
2229 const StringTemplate vecDecoration(
2230 "OpDecorate %ra_v4i32 ArrayStride 16\n"
2231 "OpDecorate %ra_v4i16 ArrayStride 8\n"
2232 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2233 "OpMemberDecorate %SSBO16 0 Offset 0\n"
2234 "OpDecorate %SSBO32 ${indecor}\n"
2235 "OpDecorate %SSBO16 BufferBlock\n"
2236 "OpDecorate %ssbo32 DescriptorSet 0\n"
2237 "OpDecorate %ssbo16 DescriptorSet 0\n"
2238 "OpDecorate %ssbo32 Binding 0\n"
2239 "OpDecorate %ssbo16 Binding 1\n");
2241 const StringTemplate vecTestFunc(
2242 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
2243 " %param = OpFunctionParameter %v4f32\n"
2245 "%entry = OpLabel\n"
2246 " %i = OpVariable %fp_i32 Function\n"
2247 " OpStore %i %c_i32_0\n"
2250 " %loop = OpLabel\n"
2251 " %15 = OpLoad %i32 %i\n"
2252 " %lt = OpSLessThan %bool %15 %c_i32_64\n"
2253 " OpLoopMerge %merge %inc None\n"
2254 " OpBranchConditional %lt %write %merge\n"
2256 "%write = OpLabel\n"
2257 " %30 = OpLoad %i32 %i\n"
2258 " %src = OpAccessChain %up_v4i32 %ssbo32 %c_i32_0 %30\n"
2259 "%val32 = OpLoad ${v4itype32} %src\n"
2260 "%val16 = ${convert} %v4itype16 %val32\n"
2261 " %dst = OpAccessChain %up_v4i16 %ssbo16 %c_i32_0 %30\n"
2262 " OpStore %dst %val16\n"
2266 " %37 = OpLoad %i32 %i\n"
2267 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
2271 "%merge = OpLabel\n"
2272 " OpReturnValue %param\n"
2278 const deUint32 arrayStrides[] = {4, 16};
2280 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
2281 for (deUint32 factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
2283 map<string, string> specs;
2284 string name = string(CAPABILITIES[capIdx].name) + "_scalar_" + intFacts[factIdx].name;
2286 specs["cap"] = CAPABILITIES[capIdx].cap;
2287 specs["indecor"] = CAPABILITIES[capIdx].decor;
2288 specs["itype32"] = intFacts[factIdx].type32;
2289 specs["v4itype32"] = "%v4" + string(intFacts[factIdx].type32).substr(1);
2290 specs["itype16"] = intFacts[factIdx].type16;
2291 specs["signed"] = intFacts[factIdx].isSigned;
2292 specs["convert"] = intFacts[factIdx].opcode;
2293 specs["arraystride"] = de::toString(arrayStrides[capIdx]);
2295 fragments["pre_main"] = scalarPreMain.specialize(specs);
2296 fragments["testfun"] = scalarTestFunc.specialize(specs);
2297 fragments["capability"] = capabilities.specialize(specs);
2298 fragments["decoration"] = scalarDecoration.specialize(specs);
2300 vector<deInt32> inputsPadded;
2301 for (size_t dataIdx = 0; dataIdx < inputs.size(); ++dataIdx)
2303 inputsPadded.push_back(inputs[dataIdx]);
2304 for (deUint32 padIdx = 0; padIdx < arrayStrides[capIdx] / 4 - 1; ++padIdx)
2305 inputsPadded.push_back(0);
2307 GraphicsResources resources;
2308 resources.inputs.push_back(Resource(BufferSp(new Int32Buffer(inputsPadded)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
2309 resources.outputs.push_back(Resource(BufferSp(new Int16Buffer(outputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
2311 resources.inputs.back().setDescriptorType(CAPABILITIES[capIdx].dtype);
2313 createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
2318 GraphicsResources resources;
2319 resources.inputs.push_back(Resource(BufferSp(new Int32Buffer(inputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
2320 resources.outputs.push_back(Resource(BufferSp(new Int16Buffer(outputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
2322 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
2323 for (deUint32 factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
2325 map<string, string> specs;
2326 string name = string(CAPABILITIES[capIdx].name) + "_vector_" + intFacts[factIdx].name;
2328 specs["cap"] = CAPABILITIES[capIdx].cap;
2329 specs["indecor"] = CAPABILITIES[capIdx].decor;
2330 specs["itype32"] = intFacts[factIdx].type32;
2331 specs["v4itype32"] = "%v4" + string(intFacts[factIdx].type32).substr(1);
2332 specs["itype16"] = intFacts[factIdx].type16;
2333 specs["signed"] = intFacts[factIdx].isSigned;
2334 specs["convert"] = intFacts[factIdx].opcode;
2336 fragments["pre_main"] = vecPreMain.specialize(specs);
2337 fragments["testfun"] = vecTestFunc.specialize(specs);
2338 fragments["capability"] = capabilities.specialize(specs);
2339 fragments["decoration"] = vecDecoration.specialize(specs);
2341 resources.inputs.back().setDescriptorType(CAPABILITIES[capIdx].dtype);
2343 createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
2348 void addCompute16bitStorageUniform16To16Group (tcu::TestCaseGroup* group)
2350 tcu::TestContext& testCtx = group->getTestContext();
2351 de::Random rnd (deStringHash(group->getName()));
2352 const int numElements = 128;
2353 const vector<deFloat16> float16Data = getFloat16s(rnd, numElements);
2354 const vector<deFloat16> float16DummyData (numElements, 0);
2355 ComputeShaderSpec spec;
2357 std::ostringstream shaderTemplate;
2358 shaderTemplate<<"OpCapability Shader\n"
2359 << "OpCapability StorageUniformBufferBlock16\n"
2360 << "OpExtension \"SPV_KHR_16bit_storage\"\n"
2361 << "OpMemoryModel Logical GLSL450\n"
2362 << "OpEntryPoint GLCompute %main \"main\" %id\n"
2363 << "OpExecutionMode %main LocalSize 1 1 1\n"
2364 << "OpDecorate %id BuiltIn GlobalInvocationId\n"
2365 << "OpDecorate %f16arr ArrayStride 2\n"
2366 << "OpMemberDecorate %SSBO_IN 0 Coherent\n"
2367 << "OpMemberDecorate %SSBO_OUT 0 Coherent\n"
2368 << "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
2369 << "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
2370 << "OpDecorate %SSBO_IN BufferBlock\n"
2371 << "OpDecorate %SSBO_OUT BufferBlock\n"
2372 << "OpDecorate %ssboIN DescriptorSet 0\n"
2373 << "OpDecorate %ssboOUT DescriptorSet 0\n"
2374 << "OpDecorate %ssboIN Binding 0\n"
2375 << "OpDecorate %ssboOUT Binding 1\n"
2377 << "%bool = OpTypeBool\n"
2378 << "%void = OpTypeVoid\n"
2379 << "%voidf = OpTypeFunction %void\n"
2380 << "%u32 = OpTypeInt 32 0\n"
2381 << "%i32 = OpTypeInt 32 1\n"
2382 << "%uvec3 = OpTypeVector %u32 3\n"
2383 << "%uvec3ptr = OpTypePointer Input %uvec3\n"
2384 << "%f16 = OpTypeFloat 16\n"
2385 << "%f16ptr = OpTypePointer Uniform %f16\n"
2387 << "%zero = OpConstant %i32 0\n"
2388 << "%c_size = OpConstant %i32 " << numElements << "\n"
2390 << "%f16arr = OpTypeArray %f16 %c_size\n"
2391 << "%SSBO_IN = OpTypeStruct %f16arr\n"
2392 << "%SSBO_OUT = OpTypeStruct %f16arr\n"
2393 << "%up_SSBOIN = OpTypePointer Uniform %SSBO_IN\n"
2394 << "%up_SSBOOUT = OpTypePointer Uniform %SSBO_OUT\n"
2395 << "%ssboIN = OpVariable %up_SSBOIN Uniform\n"
2396 << "%ssboOUT = OpVariable %up_SSBOOUT Uniform\n"
2398 << "%id = OpVariable %uvec3ptr Input\n"
2399 << "%main = OpFunction %void None %voidf\n"
2400 << "%label = OpLabel\n"
2401 << "%idval = OpLoad %uvec3 %id\n"
2402 << "%x = OpCompositeExtract %u32 %idval 0\n"
2403 << "%y = OpCompositeExtract %u32 %idval 1\n"
2405 << "%inlocx = OpAccessChain %f16ptr %ssboIN %zero %x \n"
2406 << "%valx = OpLoad %f16 %inlocx\n"
2407 << "%outlocx = OpAccessChain %f16ptr %ssboOUT %zero %x \n"
2408 << " OpStore %outlocx %valx\n"
2410 << "%inlocy = OpAccessChain %f16ptr %ssboIN %zero %y \n"
2411 << "%valy = OpLoad %f16 %inlocy\n"
2412 << "%outlocy = OpAccessChain %f16ptr %ssboOUT %zero %y \n"
2413 << " OpStore %outlocy %valy\n"
2416 << " OpFunctionEnd\n";
2418 spec.assembly = shaderTemplate.str();
2419 spec.numWorkGroups = IVec3(numElements, numElements, 1);
2420 spec.verifyIO = computeCheckBuffersFloats;
2421 spec.coherentMemory = true;
2422 spec.inputs.push_back(Resource(BufferSp(new Float16Buffer(float16Data))));
2423 spec.outputs.push_back(Resource(BufferSp(new Float16Buffer(float16DummyData))));
2424 spec.extensions.push_back("VK_KHR_16bit_storage");
2425 spec.requestedVulkanFeatures = get16BitStorageFeatures("uniform_buffer_block");
2427 group->addChild(new SpvAsmComputeShaderCase(testCtx, "stress_test", "Granularity stress test", spec));
2430 void addCompute16bitStorageUniform32To16Group (tcu::TestCaseGroup* group)
2432 tcu::TestContext& testCtx = group->getTestContext();
2433 de::Random rnd (deStringHash(group->getName()));
2434 const int numElements = 128;
2436 const StringTemplate shaderTemplate (
2437 "OpCapability Shader\n"
2438 "OpCapability ${capability}\n"
2439 "OpExtension \"SPV_KHR_16bit_storage\"\n"
2440 "OpMemoryModel Logical GLSL450\n"
2441 "OpEntryPoint GLCompute %main \"main\" %id\n"
2442 "OpExecutionMode %main LocalSize 1 1 1\n"
2443 "OpDecorate %id BuiltIn GlobalInvocationId\n"
2447 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2448 "OpMemberDecorate %SSBO16 0 Offset 0\n"
2449 "OpDecorate %SSBO32 ${storage}\n"
2450 "OpDecorate %SSBO16 BufferBlock\n"
2451 "OpDecorate %ssbo32 DescriptorSet 0\n"
2452 "OpDecorate %ssbo16 DescriptorSet 0\n"
2453 "OpDecorate %ssbo32 Binding 0\n"
2454 "OpDecorate %ssbo16 Binding 1\n"
2456 "${matrix_decor:opt}\n"
2460 "%bool = OpTypeBool\n"
2461 "%void = OpTypeVoid\n"
2462 "%voidf = OpTypeFunction %void\n"
2463 "%u32 = OpTypeInt 32 0\n"
2464 "%i32 = OpTypeInt 32 1\n"
2465 "%f32 = OpTypeFloat 32\n"
2466 "%uvec3 = OpTypeVector %u32 3\n"
2467 "%uvec3ptr = OpTypePointer Input %uvec3\n"
2468 "%i32ptr = OpTypePointer Uniform %i32\n"
2469 "%f32ptr = OpTypePointer Uniform %f32\n"
2471 "%zero = OpConstant %i32 0\n"
2472 "%c_i32_1 = OpConstant %i32 1\n"
2473 "%c_i32_16 = OpConstant %i32 16\n"
2474 "%c_i32_32 = OpConstant %i32 32\n"
2475 "%c_i32_64 = OpConstant %i32 64\n"
2476 "%c_i32_128 = OpConstant %i32 128\n"
2478 "%i32arr = OpTypeArray %i32 %c_i32_128\n"
2479 "%f32arr = OpTypeArray %f32 %c_i32_128\n"
2482 "${matrix_types:opt}\n"
2484 "%SSBO32 = OpTypeStruct %${matrix_prefix:opt}${base32}arr\n"
2485 "%SSBO16 = OpTypeStruct %${matrix_prefix:opt}${base16}arr\n"
2486 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2487 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
2488 "%ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2489 "%ssbo16 = OpVariable %up_SSBO16 Uniform\n"
2491 "%id = OpVariable %uvec3ptr Input\n"
2493 "%main = OpFunction %void None %voidf\n"
2494 "%label = OpLabel\n"
2495 "%idval = OpLoad %uvec3 %id\n"
2496 "%x = OpCompositeExtract %u32 %idval 0\n"
2497 "%inloc = OpAccessChain %${base32}ptr %ssbo32 %zero %x ${index0:opt}\n"
2498 "%val32 = OpLoad %${base32} %inloc\n"
2499 "%val16 = ${convert} %${base16} %val32\n"
2500 "%outloc = OpAccessChain %${base16}ptr %ssbo16 %zero %x ${index0:opt}\n"
2501 " OpStore %outloc %val16\n"
2502 "${matrix_store:opt}\n"
2504 " OpFunctionEnd\n");
2507 const char floatTypes[] =
2508 "%f16 = OpTypeFloat 16\n"
2509 "%f16ptr = OpTypePointer Uniform %f16\n"
2510 "%f16arr = OpTypeArray %f16 %c_i32_128\n"
2511 "%v4f16 = OpTypeVector %f16 4\n"
2512 "%v4f32 = OpTypeVector %f32 4\n"
2513 "%v4f16ptr = OpTypePointer Uniform %v4f16\n"
2514 "%v4f32ptr = OpTypePointer Uniform %v4f32\n"
2515 "%v4f16arr = OpTypeArray %v4f16 %c_i32_32\n"
2516 "%v4f32arr = OpTypeArray %v4f32 %c_i32_32\n";
2525 const RndMode rndModes[] =
2527 {"rtz", "OpDecorate %val16 FPRoundingMode RTZ", computeCheck16BitFloats<ROUNDINGMODE_RTZ>},
2528 {"rte", "OpDecorate %val16 FPRoundingMode RTE", computeCheck16BitFloats<ROUNDINGMODE_RTE>},
2529 {"unspecified_rnd_mode", "", computeCheck16BitFloats<RoundingModeFlags(ROUNDINGMODE_RTE | ROUNDINGMODE_RTZ)>},
2532 struct CompositeType
2539 unsigned inputStride;
2542 const CompositeType cTypes[2][3] =
2545 {"scalar", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 2\n", numElements, 1},
2546 {"vector", "v4f32", "v4f16", "OpDecorate %v4f32arr ArrayStride 16\nOpDecorate %v4f16arr ArrayStride 8\n", numElements / 4, 1},
2547 {"matrix", "v4f32", "v4f16", "OpDecorate %m2v4f32arr ArrayStride 32\nOpDecorate %m2v4f16arr ArrayStride 16\n", numElements / 8, 1}
2550 {"scalar", "f32", "f16", "OpDecorate %f32arr ArrayStride 16\nOpDecorate %f16arr ArrayStride 2\n", numElements, 4},
2551 {"vector", "v4f32", "v4f16", "OpDecorate %v4f32arr ArrayStride 16\nOpDecorate %v4f16arr ArrayStride 8\n", numElements / 4, 1},
2552 {"matrix", "v4f32", "v4f16", "OpDecorate %m2v4f32arr ArrayStride 32\nOpDecorate %m2v4f16arr ArrayStride 16\n", numElements / 8, 1}
2556 vector<deFloat16> float16DummyData (numElements, 0);
2558 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
2559 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes[capIdx]); ++tyIdx)
2560 for (deUint32 rndModeIdx = 0; rndModeIdx < DE_LENGTH_OF_ARRAY(rndModes); ++rndModeIdx)
2562 ComputeShaderSpec spec;
2563 map<string, string> specs;
2564 string testName = string(CAPABILITIES[capIdx].name) + "_" + cTypes[capIdx][tyIdx].name + "_float_" + rndModes[rndModeIdx].name;
2565 vector<float> float32Data = getFloat32s(rnd, numElements * cTypes[capIdx][tyIdx].inputStride);
2567 specs["capability"] = CAPABILITIES[capIdx].cap;
2568 specs["storage"] = CAPABILITIES[capIdx].decor;
2569 specs["stride"] = cTypes[capIdx][tyIdx].stride;
2570 specs["base32"] = cTypes[capIdx][tyIdx].base32;
2571 specs["base16"] = cTypes[capIdx][tyIdx].base16;
2572 specs["rounding"] = rndModes[rndModeIdx].decor;
2573 specs["types"] = floatTypes;
2574 specs["convert"] = "OpFConvert";
2576 if (strcmp(cTypes[capIdx][tyIdx].name, "matrix") == 0)
2578 if (strcmp(rndModes[rndModeIdx].name, "rtz") == 0)
2579 specs["rounding"] += "\nOpDecorate %val16_1 FPRoundingMode RTZ\n";
2580 else if (strcmp(rndModes[rndModeIdx].name, "rte") == 0)
2581 specs["rounding"] += "\nOpDecorate %val16_1 FPRoundingMode RTE\n";
2583 specs["index0"] = "%zero";
2584 specs["matrix_prefix"] = "m2";
2585 specs["matrix_types"] =
2586 "%m2v4f16 = OpTypeMatrix %v4f16 2\n"
2587 "%m2v4f32 = OpTypeMatrix %v4f32 2\n"
2588 "%m2v4f16arr = OpTypeArray %m2v4f16 %c_i32_16\n"
2589 "%m2v4f32arr = OpTypeArray %m2v4f32 %c_i32_16\n";
2590 specs["matrix_decor"] =
2591 "OpMemberDecorate %SSBO32 0 ColMajor\n"
2592 "OpMemberDecorate %SSBO32 0 MatrixStride 16\n"
2593 "OpMemberDecorate %SSBO16 0 ColMajor\n"
2594 "OpMemberDecorate %SSBO16 0 MatrixStride 8\n";
2595 specs["matrix_store"] =
2596 "%inloc_1 = OpAccessChain %v4f32ptr %ssbo32 %zero %x %c_i32_1\n"
2597 "%val32_1 = OpLoad %v4f32 %inloc_1\n"
2598 "%val16_1 = OpFConvert %v4f16 %val32_1\n"
2599 "%outloc_1 = OpAccessChain %v4f16ptr %ssbo16 %zero %x %c_i32_1\n"
2600 " OpStore %outloc_1 %val16_1\n";
2603 spec.assembly = shaderTemplate.specialize(specs);
2604 spec.numWorkGroups = IVec3(cTypes[capIdx][tyIdx].count, 1, 1);
2605 spec.verifyIO = rndModes[rndModeIdx].func;
2607 spec.inputs.push_back(Resource(BufferSp(new Float32Buffer(float32Data)), CAPABILITIES[capIdx].dtype));
2608 // We provided a custom verifyIO in the above in which inputs will be used for checking.
2609 // So put dummy data in the expected values.
2610 spec.outputs.push_back(Resource(BufferSp(new Float16Buffer(float16DummyData))));
2611 spec.extensions.push_back("VK_KHR_16bit_storage");
2612 spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
2614 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
2619 const char sintTypes[] =
2620 "%i16 = OpTypeInt 16 1\n"
2621 "%i16ptr = OpTypePointer Uniform %i16\n"
2622 "%i16arr = OpTypeArray %i16 %c_i32_128\n"
2623 "%v2i16 = OpTypeVector %i16 2\n"
2624 "%v2i32 = OpTypeVector %i32 2\n"
2625 "%v2i16ptr = OpTypePointer Uniform %v2i16\n"
2626 "%v2i32ptr = OpTypePointer Uniform %v2i32\n"
2627 "%v2i16arr = OpTypeArray %v2i16 %c_i32_64\n"
2628 "%v2i32arr = OpTypeArray %v2i32 %c_i32_64\n";
2630 const char uintTypes[] =
2631 "%u16 = OpTypeInt 16 0\n"
2632 "%u16ptr = OpTypePointer Uniform %u16\n"
2633 "%u32ptr = OpTypePointer Uniform %u32\n"
2634 "%u16arr = OpTypeArray %u16 %c_i32_128\n"
2635 "%u32arr = OpTypeArray %u32 %c_i32_128\n"
2636 "%v2u16 = OpTypeVector %u16 2\n"
2637 "%v2u32 = OpTypeVector %u32 2\n"
2638 "%v2u16ptr = OpTypePointer Uniform %v2u16\n"
2639 "%v2u32ptr = OpTypePointer Uniform %v2u32\n"
2640 "%v2u16arr = OpTypeArray %v2u16 %c_i32_64\n"
2641 "%v2u32arr = OpTypeArray %v2u32 %c_i32_64\n";
2643 struct CompositeType
2652 unsigned inputStride;
2655 const CompositeType cTypes[2][4] =
2658 {"scalar_sint", sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 2\n", numElements, 1},
2659 {"scalar_uint", uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 2\n", numElements, 1},
2660 {"vector_sint", sintTypes, "v2i32", "v2i16", "OpSConvert", "OpDecorate %v2i32arr ArrayStride 8\nOpDecorate %v2i16arr ArrayStride 4\n", numElements / 2, 2},
2661 {"vector_uint", uintTypes, "v2u32", "v2u16", "OpUConvert", "OpDecorate %v2u32arr ArrayStride 8\nOpDecorate %v2u16arr ArrayStride 4\n", numElements / 2, 2}
2664 {"scalar_sint", sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 16\nOpDecorate %i16arr ArrayStride 2\n", numElements, 4},
2665 {"scalar_uint", uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 16\nOpDecorate %u16arr ArrayStride 2\n", numElements, 4},
2666 {"vector_sint", sintTypes, "v2i32", "v2i16", "OpSConvert", "OpDecorate %v2i32arr ArrayStride 16\nOpDecorate %v2i16arr ArrayStride 4\n", numElements / 2, 4},
2667 {"vector_uint", uintTypes, "v2u32", "v2u16", "OpUConvert", "OpDecorate %v2u32arr ArrayStride 16\nOpDecorate %v2u16arr ArrayStride 4\n", numElements / 2, 4}
2671 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
2672 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes[capIdx]); ++tyIdx)
2674 ComputeShaderSpec spec;
2675 map<string, string> specs;
2676 string testName = string(CAPABILITIES[capIdx].name) + "_" + cTypes[capIdx][tyIdx].name;
2677 const deUint32 inputStride = cTypes[capIdx][tyIdx].inputStride;
2678 const deUint32 count = cTypes[capIdx][tyIdx].count;
2679 const deUint32 scalarsPerItem = numElements / count;
2681 vector<deInt32> inputs = getInt32s(rnd, numElements * inputStride);
2682 vector<deInt16> outputs;
2684 outputs.reserve(numElements);
2685 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
2686 for (deUint32 scalarIdx = 0; scalarIdx < scalarsPerItem; scalarIdx++)
2687 outputs.push_back(static_cast<deInt16>(0xffff & inputs[numNdx * inputStride + scalarIdx]));
2689 specs["capability"] = CAPABILITIES[capIdx].cap;
2690 specs["storage"] = CAPABILITIES[capIdx].decor;
2691 specs["stride"] = cTypes[capIdx][tyIdx].stride;
2692 specs["base32"] = cTypes[capIdx][tyIdx].base32;
2693 specs["base16"] = cTypes[capIdx][tyIdx].base16;
2694 specs["types"] = cTypes[capIdx][tyIdx].types;
2695 specs["convert"] = cTypes[capIdx][tyIdx].opcode;
2697 spec.assembly = shaderTemplate.specialize(specs);
2698 spec.numWorkGroups = IVec3(cTypes[capIdx][tyIdx].count, 1, 1);
2700 spec.inputs.push_back(Resource(BufferSp(new Int32Buffer(inputs)), CAPABILITIES[capIdx].dtype));
2701 spec.outputs.push_back(Resource(BufferSp(new Int16Buffer(outputs))));
2702 spec.extensions.push_back("VK_KHR_16bit_storage");
2703 spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
2705 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
2710 void addCompute16bitStorageUniform16StructTo32StructGroup (tcu::TestCaseGroup* group)
2712 tcu::TestContext& testCtx = group->getTestContext();
2713 de::Random rnd (deStringHash(group->getName()));
2714 const StringTemplate shaderTemplate (
2715 "OpCapability Shader\n"
2716 "OpCapability ${capability}\n"
2717 "OpExtension \"SPV_KHR_16bit_storage\"\n"
2718 "OpMemoryModel Logical GLSL450\n"
2719 "OpEntryPoint GLCompute %main \"main\" %id\n"
2720 "OpExecutionMode %main LocalSize 1 1 1\n"
2721 "OpDecorate %id BuiltIn GlobalInvocationId\n"
2727 "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
2728 "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
2729 "OpDecorate %SSBO_IN ${storage}\n"
2730 "OpDecorate %SSBO_OUT BufferBlock\n"
2731 "OpDecorate %ssboIN DescriptorSet 0\n"
2732 "OpDecorate %ssboOUT DescriptorSet 0\n"
2733 "OpDecorate %ssboIN Binding 0\n"
2734 "OpDecorate %ssboOUT Binding 1\n"
2736 "%bool = OpTypeBool\n"
2737 "%void = OpTypeVoid\n"
2738 "%voidf = OpTypeFunction %void\n"
2739 "%u32 = OpTypeInt 32 0\n"
2740 "%uvec3 = OpTypeVector %u32 3\n"
2741 "%uvec3ptr = OpTypePointer Input %uvec3\n"
2743 "%i32 = OpTypeInt 32 1\n"
2744 "%v2i32 = OpTypeVector %i32 2\n"
2745 "%v4i32 = OpTypeVector %i32 4\n"
2747 "%f32 = OpTypeFloat 32\n"
2748 "%v2f32 = OpTypeVector %f32 2\n"
2749 "%v3f32 = OpTypeVector %f32 3\n"
2750 "%v4f32 = OpTypeVector %f32 4\n"
2753 "%zero = OpConstant %i32 0\n"
2754 "%c_i32_1 = OpConstant %i32 1\n"
2755 "%c_i32_2 = OpConstant %i32 2\n"
2756 "%c_i32_3 = OpConstant %i32 3\n"
2757 "%c_i32_4 = OpConstant %i32 4\n"
2758 "%c_i32_5 = OpConstant %i32 5\n"
2759 "%c_i32_6 = OpConstant %i32 6\n"
2760 "%c_i32_7 = OpConstant %i32 7\n"
2761 "%c_i32_8 = OpConstant %i32 8\n"
2762 "%c_i32_9 = OpConstant %i32 9\n"
2764 "%c_u32_1 = OpConstant %u32 1\n"
2765 "%c_u32_3 = OpConstant %u32 3\n"
2766 "%c_u32_7 = OpConstant %u32 7\n"
2767 "%c_u32_11 = OpConstant %u32 11\n"
2769 "%f16arr3 = OpTypeArray %f16 %c_u32_3\n"
2770 "%v2f16arr3 = OpTypeArray %v2f16 %c_u32_3\n"
2771 "%v2f16arr11 = OpTypeArray %v2f16 %c_u32_11\n"
2772 "%v3f16arr11 = OpTypeArray %v3f16 %c_u32_11\n"
2773 "%v4f16arr3 = OpTypeArray %v4f16 %c_u32_3\n"
2774 "%struct16 = OpTypeStruct %f16 %v2f16arr3\n"
2775 "%struct16arr11 = OpTypeArray %struct16 %c_u32_11\n"
2776 "%f16Struct = OpTypeStruct %f16 %v2f16 %v3f16 %v4f16 %f16arr3 %struct16arr11 %v2f16arr11 %f16 %v3f16arr11 %v4f16arr3\n"
2778 "%f32arr3 = OpTypeArray %f32 %c_u32_3\n"
2779 "%v2f32arr3 = OpTypeArray %v2f32 %c_u32_3\n"
2780 "%v2f32arr11 = OpTypeArray %v2f32 %c_u32_11\n"
2781 "%v3f32arr11 = OpTypeArray %v3f32 %c_u32_11\n"
2782 "%v4f32arr3 = OpTypeArray %v4f32 %c_u32_3\n"
2783 "%struct32 = OpTypeStruct %f32 %v2f32arr3\n"
2784 "%struct32arr11 = OpTypeArray %struct32 %c_u32_11\n"
2785 "%f32Struct = OpTypeStruct %f32 %v2f32 %v3f32 %v4f32 %f32arr3 %struct32arr11 %v2f32arr11 %f32 %v3f32arr11 %v4f32arr3\n"
2787 "%f16StructArr7 = OpTypeArray %f16Struct %c_u32_7\n"
2788 "%f32StructArr7 = OpTypeArray %f32Struct %c_u32_7\n"
2789 "%SSBO_IN = OpTypeStruct %f16StructArr7\n"
2790 "%SSBO_OUT = OpTypeStruct %f32StructArr7\n"
2791 "%up_SSBOIN = OpTypePointer Uniform %SSBO_IN\n"
2792 "%up_SSBOOUT = OpTypePointer Uniform %SSBO_OUT\n"
2793 "%ssboIN = OpVariable %up_SSBOIN Uniform\n"
2794 "%ssboOUT = OpVariable %up_SSBOOUT Uniform\n"
2796 "%id = OpVariable %uvec3ptr Input\n"
2797 "%main = OpFunction %void None %voidf\n"
2798 "%label = OpLabel\n"
2800 "%idval = OpLoad %uvec3 %id\n"
2801 "%x = OpCompositeExtract %u32 %idval 0\n"
2802 "%y = OpCompositeExtract %u32 %idval 1\n"
2804 "%f16src = OpAccessChain %f16ptr %ssboIN %zero %x %zero\n"
2805 "%val_f16 = OpLoad %f16 %f16src\n"
2806 "%val_f32 = OpFConvert %f32 %val_f16\n"
2807 "%f32dst = OpAccessChain %f32ptr %ssboOUT %zero %x %zero\n"
2808 "OpStore %f32dst %val_f32\n"
2810 "%v2f16src = OpAccessChain %v2f16ptr %ssboIN %zero %x %c_i32_1\n"
2811 "%val_v2f16 = OpLoad %v2f16 %v2f16src\n"
2812 "%val_v2f32 = OpFConvert %v2f32 %val_v2f16\n"
2813 "%v2f32dst = OpAccessChain %v2f32ptr %ssboOUT %zero %x %c_i32_1\n"
2814 "OpStore %v2f32dst %val_v2f32\n"
2816 "%v3f16src = OpAccessChain %v3f16ptr %ssboIN %zero %x %c_i32_2\n"
2817 "%val_v3f16 = OpLoad %v3f16 %v3f16src\n"
2818 "%val_v3f32 = OpFConvert %v3f32 %val_v3f16\n"
2819 "%v3f32dst = OpAccessChain %v3f32ptr %ssboOUT %zero %x %c_i32_2\n"
2820 "OpStore %v3f32dst %val_v3f32\n"
2822 "%v4f16src = OpAccessChain %v4f16ptr %ssboIN %zero %x %c_i32_3\n"
2823 "%val_v4f16 = OpLoad %v4f16 %v4f16src\n"
2824 "%val_v4f32 = OpFConvert %v4f32 %val_v4f16\n"
2825 "%v4f32dst = OpAccessChain %v4f32ptr %ssboOUT %zero %x %c_i32_3\n"
2826 "OpStore %v4f32dst %val_v4f32\n"
2828 //struct {f16, v2f16[3]}
2829 "%Sf16src = OpAccessChain %f16ptr %ssboIN %zero %x %c_i32_5 %y %zero\n"
2830 "%Sval_f16 = OpLoad %f16 %Sf16src\n"
2831 "%Sval_f32 = OpFConvert %f32 %Sval_f16\n"
2832 "%Sf32dst2 = OpAccessChain %f32ptr %ssboOUT %zero %x %c_i32_5 %y %zero\n"
2833 "OpStore %Sf32dst2 %Sval_f32\n"
2835 "%Sv2f16src0 = OpAccessChain %v2f16ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %zero\n"
2836 "%Sv2f16_0 = OpLoad %v2f16 %Sv2f16src0\n"
2837 "%Sv2f32_0 = OpFConvert %v2f32 %Sv2f16_0\n"
2838 "%Sv2f32dst_0 = OpAccessChain %v2f32ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %zero\n"
2839 "OpStore %Sv2f32dst_0 %Sv2f32_0\n"
2841 "%Sv2f16src1 = OpAccessChain %v2f16ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %c_i32_1\n"
2842 "%Sv2f16_1 = OpLoad %v2f16 %Sv2f16src1\n"
2843 "%Sv2f32_1 = OpFConvert %v2f32 %Sv2f16_1\n"
2844 "%Sv2f32dst_1 = OpAccessChain %v2f32ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %c_i32_1\n"
2845 "OpStore %Sv2f32dst_1 %Sv2f32_1\n"
2847 "%Sv2f16src2 = OpAccessChain %v2f16ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %c_i32_2\n"
2848 "%Sv2f16_2 = OpLoad %v2f16 %Sv2f16src2\n"
2849 "%Sv2f32_2 = OpFConvert %v2f32 %Sv2f16_2\n"
2850 "%Sv2f32dst_2 = OpAccessChain %v2f32ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %c_i32_2\n"
2851 "OpStore %Sv2f32dst_2 %Sv2f32_2\n"
2854 "%v2f16src2 = OpAccessChain %v2f16ptr %ssboIN %zero %x %c_i32_6 %y\n"
2855 "%val2_v2f16 = OpLoad %v2f16 %v2f16src2\n"
2856 "%val2_v2f32 = OpFConvert %v2f32 %val2_v2f16\n"
2857 "%v2f32dst2 = OpAccessChain %v2f32ptr %ssboOUT %zero %x %c_i32_6 %y\n"
2858 "OpStore %v2f32dst2 %val2_v2f32\n"
2860 "%f16src2 = OpAccessChain %f16ptr %ssboIN %zero %x %c_i32_7\n"
2861 "%val2_f16 = OpLoad %f16 %f16src2\n"
2862 "%val2_f32 = OpFConvert %f32 %val2_f16\n"
2863 "%f32dst2 = OpAccessChain %f32ptr %ssboOUT %zero %x %c_i32_7\n"
2864 "OpStore %f32dst2 %val2_f32\n"
2866 "%v3f16src2 = OpAccessChain %v3f16ptr %ssboIN %zero %x %c_i32_8 %y\n"
2867 "%val2_v3f16 = OpLoad %v3f16 %v3f16src2\n"
2868 "%val2_v3f32 = OpFConvert %v3f32 %val2_v3f16\n"
2869 "%v3f32dst2 = OpAccessChain %v3f32ptr %ssboOUT %zero %x %c_i32_8 %y\n"
2870 "OpStore %v3f32dst2 %val2_v3f32\n"
2873 //Array with 3 elements
2874 "%LessThan3 = OpSLessThan %bool %y %c_i32_3\n"
2875 "OpSelectionMerge %BlockIf None\n"
2876 "OpBranchConditional %LessThan3 %LabelIf %BlockIf\n"
2877 "%LabelIf = OpLabel\n"
2878 " %f16src3 = OpAccessChain %f16ptr %ssboIN %zero %x %c_i32_4 %y\n"
2879 " %val3_f16 = OpLoad %f16 %f16src3\n"
2880 " %val3_f32 = OpFConvert %f32 %val3_f16\n"
2881 " %f32dst3 = OpAccessChain %f32ptr %ssboOUT %zero %x %c_i32_4 %y\n"
2882 " OpStore %f32dst3 %val3_f32\n"
2884 " %v4f16src2 = OpAccessChain %v4f16ptr %ssboIN %zero %x %c_i32_9 %y\n"
2885 " %val2_v4f16 = OpLoad %v4f16 %v4f16src2\n"
2886 " %val2_v4f32 = OpFConvert %v4f32 %val2_v4f16\n"
2887 " %v4f32dst2 = OpAccessChain %v4f32ptr %ssboOUT %zero %x %c_i32_9 %y\n"
2888 " OpStore %v4f32dst2 %val2_v4f32\n"
2889 "OpBranch %BlockIf\n"
2890 "%BlockIf = OpLabel\n"
2893 " OpFunctionEnd\n");
2896 vector<float> float32Data (getStructSize(SHADERTEMPLATE_STRIDE32BIT_STD430), 0.0f);
2898 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
2900 vector<deFloat16> float16DData = (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == CAPABILITIES[capIdx].dtype) ? data16bitStd430(rnd) : data16bitStd140(rnd);
2901 ComputeShaderSpec spec;
2902 map<string, string> specs;
2903 string testName = string(CAPABILITIES[capIdx].name);
2905 specs["capability"] = CAPABILITIES[capIdx].cap;
2906 specs["storage"] = CAPABILITIES[capIdx].decor;
2907 specs["strideF16"] = getStructShaderComponet((VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == CAPABILITIES[capIdx].dtype) ? SHADERTEMPLATE_STRIDE16BIT_STD430 : SHADERTEMPLATE_STRIDE16BIT_STD140);
2908 specs["strideF32"] = getStructShaderComponet(SHADERTEMPLATE_STRIDE32BIT_STD430);
2909 specs["types"] = getStructShaderComponet(SHADERTEMPLATE_TYPES);
2911 spec.assembly = shaderTemplate.specialize(specs);
2912 spec.numWorkGroups = IVec3(structData.structArraySize, structData.nestedArraySize, 1);
2913 spec.verifyIO = (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == CAPABILITIES[capIdx].dtype) ? computeCheckStruct<deFloat16, float, SHADERTEMPLATE_STRIDE16BIT_STD430, SHADERTEMPLATE_STRIDE32BIT_STD430>
2914 : computeCheckStruct<deFloat16, float, SHADERTEMPLATE_STRIDE16BIT_STD140, SHADERTEMPLATE_STRIDE32BIT_STD430>;
2915 spec.inputs.push_back(Resource(BufferSp(new Float16Buffer(float16DData)), CAPABILITIES[capIdx].dtype));
2916 spec.outputs.push_back(Resource(BufferSp(new Float32Buffer(float32Data))));
2917 spec.extensions.push_back("VK_KHR_16bit_storage");
2918 spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
2920 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
2925 void addCompute16bitStorageUniform32StructTo16StructGroup (tcu::TestCaseGroup* group)
2927 tcu::TestContext& testCtx = group->getTestContext();
2928 de::Random rnd (deStringHash(group->getName()));
2930 const StringTemplate shaderTemplate (
2931 "OpCapability Shader\n"
2932 "OpCapability ${capability}\n"
2933 "OpExtension \"SPV_KHR_16bit_storage\"\n"
2934 "OpMemoryModel Logical GLSL450\n"
2935 "OpEntryPoint GLCompute %main \"main\" %id\n"
2936 "OpExecutionMode %main LocalSize 1 1 1\n"
2937 "OpDecorate %id BuiltIn GlobalInvocationId\n"
2943 "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
2944 "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
2945 "OpDecorate %SSBO_IN ${storage}\n"
2946 "OpDecorate %SSBO_OUT BufferBlock\n"
2947 "OpDecorate %ssboIN DescriptorSet 0\n"
2948 "OpDecorate %ssboOUT DescriptorSet 0\n"
2949 "OpDecorate %ssboIN Binding 0\n"
2950 "OpDecorate %ssboOUT Binding 1\n"
2952 "%bool = OpTypeBool\n"
2953 "%void = OpTypeVoid\n"
2954 "%voidf = OpTypeFunction %void\n"
2955 "%u32 = OpTypeInt 32 0\n"
2956 "%uvec3 = OpTypeVector %u32 3\n"
2957 "%uvec3ptr = OpTypePointer Input %uvec3\n"
2959 "%i32 = OpTypeInt 32 1\n"
2960 "%v2i32 = OpTypeVector %i32 2\n"
2961 "%v4i32 = OpTypeVector %i32 4\n"
2963 "%f32 = OpTypeFloat 32\n"
2964 "%v2f32 = OpTypeVector %f32 2\n"
2965 "%v3f32 = OpTypeVector %f32 3\n"
2966 "%v4f32 = OpTypeVector %f32 4\n"
2969 "%zero = OpConstant %i32 0\n"
2970 "%c_i32_1 = OpConstant %i32 1\n"
2971 "%c_i32_2 = OpConstant %i32 2\n"
2972 "%c_i32_3 = OpConstant %i32 3\n"
2973 "%c_i32_4 = OpConstant %i32 4\n"
2974 "%c_i32_5 = OpConstant %i32 5\n"
2975 "%c_i32_6 = OpConstant %i32 6\n"
2976 "%c_i32_7 = OpConstant %i32 7\n"
2977 "%c_i32_8 = OpConstant %i32 8\n"
2978 "%c_i32_9 = OpConstant %i32 9\n"
2980 "%c_u32_1 = OpConstant %u32 1\n"
2981 "%c_u32_3 = OpConstant %u32 3\n"
2982 "%c_u32_7 = OpConstant %u32 7\n"
2983 "%c_u32_11 = OpConstant %u32 11\n"
2985 "%f16arr3 = OpTypeArray %f16 %c_u32_3\n"
2986 "%v2f16arr3 = OpTypeArray %v2f16 %c_u32_3\n"
2987 "%v2f16arr11 = OpTypeArray %v2f16 %c_u32_11\n"
2988 "%v3f16arr11 = OpTypeArray %v3f16 %c_u32_11\n"
2989 "%v4f16arr3 = OpTypeArray %v4f16 %c_u32_3\n"
2990 "%struct16 = OpTypeStruct %f16 %v2f16arr3\n"
2991 "%struct16arr11 = OpTypeArray %struct16 %c_u32_11\n"
2992 "%f16Struct = OpTypeStruct %f16 %v2f16 %v3f16 %v4f16 %f16arr3 %struct16arr11 %v2f16arr11 %f16 %v3f16arr11 %v4f16arr3\n"
2994 "%f32arr3 = OpTypeArray %f32 %c_u32_3\n"
2995 "%v2f32arr3 = OpTypeArray %v2f32 %c_u32_3\n"
2996 "%v2f32arr11 = OpTypeArray %v2f32 %c_u32_11\n"
2997 "%v3f32arr11 = OpTypeArray %v3f32 %c_u32_11\n"
2998 "%v4f32arr3 = OpTypeArray %v4f32 %c_u32_3\n"
2999 "%struct32 = OpTypeStruct %f32 %v2f32arr3\n"
3000 "%struct32arr11 = OpTypeArray %struct32 %c_u32_11\n"
3001 "%f32Struct = OpTypeStruct %f32 %v2f32 %v3f32 %v4f32 %f32arr3 %struct32arr11 %v2f32arr11 %f32 %v3f32arr11 %v4f32arr3\n"
3003 "%f16StructArr7 = OpTypeArray %f16Struct %c_u32_7\n"
3004 "%f32StructArr7 = OpTypeArray %f32Struct %c_u32_7\n"
3005 "%SSBO_IN = OpTypeStruct %f32StructArr7\n"
3006 "%SSBO_OUT = OpTypeStruct %f16StructArr7\n"
3007 "%up_SSBOIN = OpTypePointer Uniform %SSBO_IN\n"
3008 "%up_SSBOOUT = OpTypePointer Uniform %SSBO_OUT\n"
3009 "%ssboIN = OpVariable %up_SSBOIN Uniform\n"
3010 "%ssboOUT = OpVariable %up_SSBOOUT Uniform\n"
3012 "%id = OpVariable %uvec3ptr Input\n"
3013 "%main = OpFunction %void None %voidf\n"
3014 "%label = OpLabel\n"
3016 "%idval = OpLoad %uvec3 %id\n"
3017 "%x = OpCompositeExtract %u32 %idval 0\n"
3018 "%y = OpCompositeExtract %u32 %idval 1\n"
3020 "%f32src = OpAccessChain %f32ptr %ssboIN %zero %x %zero\n"
3021 "%val_f32 = OpLoad %f32 %f32src\n"
3022 "%val_f16 = OpFConvert %f16 %val_f32\n"
3023 "%f16dst = OpAccessChain %f16ptr %ssboOUT %zero %x %zero\n"
3024 "OpStore %f16dst %val_f16\n"
3026 "%v2f32src = OpAccessChain %v2f32ptr %ssboIN %zero %x %c_i32_1\n"
3027 "%val_v2f32 = OpLoad %v2f32 %v2f32src\n"
3028 "%val_v2f16 = OpFConvert %v2f16 %val_v2f32\n"
3029 "%v2f16dst = OpAccessChain %v2f16ptr %ssboOUT %zero %x %c_i32_1\n"
3030 "OpStore %v2f16dst %val_v2f16\n"
3032 "%v3f32src = OpAccessChain %v3f32ptr %ssboIN %zero %x %c_i32_2\n"
3033 "%val_v3f32 = OpLoad %v3f32 %v3f32src\n"
3034 "%val_v3f16 = OpFConvert %v3f16 %val_v3f32\n"
3035 "%v3f16dst = OpAccessChain %v3f16ptr %ssboOUT %zero %x %c_i32_2\n"
3036 "OpStore %v3f16dst %val_v3f16\n"
3038 "%v4f32src = OpAccessChain %v4f32ptr %ssboIN %zero %x %c_i32_3\n"
3039 "%val_v4f32 = OpLoad %v4f32 %v4f32src\n"
3040 "%val_v4f16 = OpFConvert %v4f16 %val_v4f32\n"
3041 "%v4f16dst = OpAccessChain %v4f16ptr %ssboOUT %zero %x %c_i32_3\n"
3042 "OpStore %v4f16dst %val_v4f16\n"
3045 //struct {f16, v2f16[3]}
3046 "%Sf32src = OpAccessChain %f32ptr %ssboIN %zero %x %c_i32_5 %y %zero\n"
3047 "%Sval_f32 = OpLoad %f32 %Sf32src\n"
3048 "%Sval_f16 = OpFConvert %f16 %Sval_f32\n"
3049 "%Sf16dst2 = OpAccessChain %f16ptr %ssboOUT %zero %x %c_i32_5 %y %zero\n"
3050 "OpStore %Sf16dst2 %Sval_f16\n"
3052 "%Sv2f32src0 = OpAccessChain %v2f32ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %zero\n"
3053 "%Sv2f32_0 = OpLoad %v2f32 %Sv2f32src0\n"
3054 "%Sv2f16_0 = OpFConvert %v2f16 %Sv2f32_0\n"
3055 "%Sv2f16dst_0 = OpAccessChain %v2f16ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %zero\n"
3056 "OpStore %Sv2f16dst_0 %Sv2f16_0\n"
3058 "%Sv2f32src1 = OpAccessChain %v2f32ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %c_i32_1\n"
3059 "%Sv2f32_1 = OpLoad %v2f32 %Sv2f32src1\n"
3060 "%Sv2f16_1 = OpFConvert %v2f16 %Sv2f32_1\n"
3061 "%Sv2f16dst_1 = OpAccessChain %v2f16ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %c_i32_1\n"
3062 "OpStore %Sv2f16dst_1 %Sv2f16_1\n"
3064 "%Sv2f32src2 = OpAccessChain %v2f32ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %c_i32_2\n"
3065 "%Sv2f32_2 = OpLoad %v2f32 %Sv2f32src2\n"
3066 "%Sv2f16_2 = OpFConvert %v2f16 %Sv2f32_2\n"
3067 "%Sv2f16dst_2 = OpAccessChain %v2f16ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %c_i32_2\n"
3068 "OpStore %Sv2f16dst_2 %Sv2f16_2\n"
3071 "%v2f32src2 = OpAccessChain %v2f32ptr %ssboIN %zero %x %c_i32_6 %y\n"
3072 "%val2_v2f32 = OpLoad %v2f32 %v2f32src2\n"
3073 "%val2_v2f16 = OpFConvert %v2f16 %val2_v2f32\n"
3074 "%v2f16dst2 = OpAccessChain %v2f16ptr %ssboOUT %zero %x %c_i32_6 %y\n"
3075 "OpStore %v2f16dst2 %val2_v2f16\n"
3077 "%f32src2 = OpAccessChain %f32ptr %ssboIN %zero %x %c_i32_7\n"
3078 "%val2_f32 = OpLoad %f32 %f32src2\n"
3079 "%val2_f16 = OpFConvert %f16 %val2_f32\n"
3080 "%f16dst2 = OpAccessChain %f16ptr %ssboOUT %zero %x %c_i32_7\n"
3081 "OpStore %f16dst2 %val2_f16\n"
3083 "%v3f32src2 = OpAccessChain %v3f32ptr %ssboIN %zero %x %c_i32_8 %y\n"
3084 "%val2_v3f32 = OpLoad %v3f32 %v3f32src2\n"
3085 "%val2_v3f16 = OpFConvert %v3f16 %val2_v3f32\n"
3086 "%v3f16dst2 = OpAccessChain %v3f16ptr %ssboOUT %zero %x %c_i32_8 %y\n"
3087 "OpStore %v3f16dst2 %val2_v3f16\n"
3090 //Array with 3 elements
3091 "%LessThan3 = OpSLessThan %bool %y %c_i32_3\n"
3092 "OpSelectionMerge %BlockIf None\n"
3093 "OpBranchConditional %LessThan3 %LabelIf %BlockIf\n"
3094 " %LabelIf = OpLabel\n"
3095 " %f32src3 = OpAccessChain %f32ptr %ssboIN %zero %x %c_i32_4 %y\n"
3096 " %val3_f32 = OpLoad %f32 %f32src3\n"
3097 " %val3_f16 = OpFConvert %f16 %val3_f32\n"
3098 " %f16dst3 = OpAccessChain %f16ptr %ssboOUT %zero %x %c_i32_4 %y\n"
3099 " OpStore %f16dst3 %val3_f16\n"
3101 " %v4f32src2 = OpAccessChain %v4f32ptr %ssboIN %zero %x %c_i32_9 %y\n"
3102 " %val2_v4f32 = OpLoad %v4f32 %v4f32src2\n"
3103 " %val2_v4f16 = OpFConvert %v4f16 %val2_v4f32\n"
3104 " %v4f16dst2 = OpAccessChain %v4f16ptr %ssboOUT %zero %x %c_i32_9 %y\n"
3105 " OpStore %v4f16dst2 %val2_v4f16\n"
3106 "OpBranch %BlockIf\n"
3107 "%BlockIf = OpLabel\n"
3110 " OpFunctionEnd\n");
3113 vector<deFloat16> float16Data (getStructSize(SHADERTEMPLATE_STRIDE16BIT_STD430), 0u);
3115 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
3117 ComputeShaderSpec spec;
3118 map<string, string> specs;
3119 string testName = string(CAPABILITIES[capIdx].name);
3120 vector<float> float32DData = (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == CAPABILITIES[capIdx].dtype) ? data32bitStd430(rnd) : data32bitStd140(rnd);
3122 specs["capability"] = CAPABILITIES[capIdx].cap;
3123 specs["storage"] = CAPABILITIES[capIdx].decor;
3124 specs["strideF16"] = getStructShaderComponet(SHADERTEMPLATE_STRIDE16BIT_STD430);
3125 specs["strideF32"] = getStructShaderComponet((VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == CAPABILITIES[capIdx].dtype) ? SHADERTEMPLATE_STRIDE32BIT_STD430 : SHADERTEMPLATE_STRIDE32BIT_STD140);
3126 specs["types"] = getStructShaderComponet(SHADERTEMPLATE_TYPES);
3128 spec.assembly = shaderTemplate.specialize(specs);
3129 spec.numWorkGroups = IVec3(structData.structArraySize, structData.nestedArraySize, 1);
3130 spec.verifyIO = (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == CAPABILITIES[capIdx].dtype) ? computeCheckStruct<float, deFloat16, SHADERTEMPLATE_STRIDE32BIT_STD430, SHADERTEMPLATE_STRIDE16BIT_STD430> : computeCheckStruct<float, deFloat16, SHADERTEMPLATE_STRIDE32BIT_STD140, SHADERTEMPLATE_STRIDE16BIT_STD430>;
3132 spec.inputs.push_back(Resource(BufferSp(new Float32Buffer(float32DData)), CAPABILITIES[capIdx].dtype));
3133 spec.outputs.push_back(Resource(BufferSp(new Float16Buffer(float16Data))));
3134 spec.extensions.push_back("VK_KHR_16bit_storage");
3135 spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
3137 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
3142 void addCompute16bitStructMixedTypesGroup (tcu::TestCaseGroup* group)
3144 tcu::TestContext& testCtx = group->getTestContext();
3145 de::Random rnd (deStringHash(group->getName()));
3146 vector<deInt16> outData (getStructSize(SHADERTEMPLATE_STRIDEMIX_STD430), 0u);
3148 const StringTemplate shaderTemplate (
3149 "OpCapability Shader\n"
3150 "OpCapability StorageUniformBufferBlock16\n"
3152 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
3153 "OpExtension \"SPV_KHR_16bit_storage\"\n"
3154 "OpMemoryModel Logical GLSL450\n"
3155 "OpEntryPoint GLCompute %main \"main\" %id\n"
3156 "OpExecutionMode %main LocalSize 1 1 1\n"
3157 "OpDecorate %id BuiltIn GlobalInvocationId\n"
3161 "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
3162 "OpDecorate %ssboIN DescriptorSet 0\n"
3163 "OpDecorate %SSBO_IN ${storage}\n"
3164 "OpDecorate %SSBO_OUT BufferBlock\n"
3165 "OpDecorate %ssboIN Binding 0\n"
3167 "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
3168 "OpDecorate %ssboOUT DescriptorSet 0\n"
3169 "OpDecorate %ssboOUT Binding 1\n"
3171 "%void = OpTypeVoid\n"
3172 "%bool = OpTypeBool\n"
3173 "%i16 = OpTypeInt 16 1\n"
3174 "%v2i16 = OpTypeVector %i16 2\n"
3175 "%v3i16 = OpTypeVector %i16 3\n"
3176 "%v4i16 = OpTypeVector %i16 4\n"
3177 "%i32 = OpTypeInt 32 1\n"
3178 "%v2i32 = OpTypeVector %i32 2\n"
3179 "%v3i32 = OpTypeVector %i32 3\n"
3180 "%v4i32 = OpTypeVector %i32 4\n"
3181 "%u32 = OpTypeInt 32 0\n"
3182 "%uvec3 = OpTypeVector %u32 3\n"
3183 "%f32 = OpTypeFloat 32\n"
3184 "%v4f32 = OpTypeVector %f32 4\n"
3185 "%voidf = OpTypeFunction %void\n"
3187 "%zero = OpConstant %i32 0\n"
3188 "%c_i32_1 = OpConstant %i32 1\n"
3189 "%c_i32_2 = OpConstant %i32 2\n"
3190 "%c_i32_3 = OpConstant %i32 3\n"
3191 "%c_i32_4 = OpConstant %i32 4\n"
3192 "%c_i32_5 = OpConstant %i32 5\n"
3193 "%c_i32_6 = OpConstant %i32 6\n"
3194 "%c_i32_7 = OpConstant %i32 7\n"
3195 "%c_i32_8 = OpConstant %i32 8\n"
3196 "%c_i32_9 = OpConstant %i32 9\n"
3197 "%c_i32_10 = OpConstant %i32 10\n"
3198 "%c_i32_11 = OpConstant %i32 11\n"
3199 "%c_u32_1 = OpConstant %u32 1\n"
3200 "%c_u32_7 = OpConstant %u32 7\n"
3201 "%c_u32_11 = OpConstant %u32 11\n"
3202 "\n"//Arrays & Structs
3203 "%v2b16NestedArr11In = OpTypeArray %v2i16 %c_u32_11\n"
3204 "%b32NestedArr11In = OpTypeArray %i32 %c_u32_11\n"
3205 "%sb16Arr11In = OpTypeArray %i16 %c_u32_11\n"
3206 "%sb32Arr11In = OpTypeArray %i32 %c_u32_11\n"
3207 "%sNestedIn = OpTypeStruct %i16 %i32 %v2b16NestedArr11In %b32NestedArr11In\n"
3208 "%sNestedArr11In = OpTypeArray %sNestedIn %c_u32_11\n"
3209 "%structIn = OpTypeStruct %i16 %i32 %v2i16 %v2i32 %v3i16 %v3i32 %v4i16 %v4i32 %sNestedArr11In %sb16Arr11In %sb32Arr11In\n"
3210 "%structArr7In = OpTypeArray %structIn %c_u32_7\n"
3211 "%v2b16NestedArr11Out = OpTypeArray %v2i16 %c_u32_11\n"
3212 "%b32NestedArr11Out = OpTypeArray %i32 %c_u32_11\n"
3213 "%sb16Arr11Out = OpTypeArray %i16 %c_u32_11\n"
3214 "%sb32Arr11Out = OpTypeArray %i32 %c_u32_11\n"
3215 "%sNestedOut = OpTypeStruct %i16 %i32 %v2b16NestedArr11Out %b32NestedArr11Out\n"
3216 "%sNestedArr11Out = OpTypeArray %sNestedOut %c_u32_11\n"
3217 "%structOut = OpTypeStruct %i16 %i32 %v2i16 %v2i32 %v3i16 %v3i32 %v4i16 %v4i32 %sNestedArr11Out %sb16Arr11Out %sb32Arr11Out\n"
3218 "%structArr7Out = OpTypeArray %structOut %c_u32_7\n"
3220 "%i16outPtr = OpTypePointer Uniform %i16\n"
3221 "%v2i16outPtr = OpTypePointer Uniform %v2i16\n"
3222 "%v3i16outPtr = OpTypePointer Uniform %v3i16\n"
3223 "%v4i16outPtr = OpTypePointer Uniform %v4i16\n"
3224 "%i32outPtr = OpTypePointer Uniform %i32\n"
3225 "%v2i32outPtr = OpTypePointer Uniform %v2i32\n"
3226 "%v3i32outPtr = OpTypePointer Uniform %v3i32\n"
3227 "%v4i32outPtr = OpTypePointer Uniform %v4i32\n"
3228 "%fp_i32 = OpTypePointer Function %i32\n"
3229 "%uvec3ptr = OpTypePointer Input %uvec3\n"
3231 "%SSBO_IN = OpTypeStruct %structArr7In\n"
3232 "%up_SSBOIN = OpTypePointer Uniform %SSBO_IN\n"
3233 "%ssboIN = OpVariable %up_SSBOIN Uniform\n"
3235 "%SSBO_OUT = OpTypeStruct %structArr7Out\n"
3236 "%up_SSBOOUT = OpTypePointer Uniform %SSBO_OUT\n"
3237 "%ssboOUT = OpVariable %up_SSBOOUT Uniform\n"
3239 "%id = OpVariable %uvec3ptr Input\n"
3240 "%main = OpFunction %void None %voidf\n"
3241 "%label = OpLabel\n"
3242 "%ndxArrz = OpVariable %fp_i32 Function\n"
3243 "%idval = OpLoad %uvec3 %id\n"
3244 "%x = OpCompositeExtract %u32 %idval 0\n"
3245 "%y = OpCompositeExtract %u32 %idval 1\n"
3246 "\n"//strutOut.b16 = strutIn.b16
3247 "%inP1 = OpAccessChain %i16${inPtr} %ssboIN %zero %x %zero\n"
3248 "%inV1 = OpLoad %i16 %inP1\n"
3249 "%outP1 = OpAccessChain %i16outPtr %ssboOUT %zero %x %zero\n"
3250 "OpStore %outP1 %inV1\n"
3251 "\n"//strutOut.b32 = strutIn.b32
3252 "%inP2 = OpAccessChain %i32${inPtr} %ssboIN %zero %x %c_i32_1\n"
3253 "%inV2 = OpLoad %i32 %inP2\n"
3254 "%outP2 = OpAccessChain %i32outPtr %ssboOUT %zero %x %c_i32_1\n"
3255 "OpStore %outP2 %inV2\n"
3256 "\n"//strutOut.v2b16 = strutIn.v2b16
3257 "%inP3 = OpAccessChain %v2i16${inPtr} %ssboIN %zero %x %c_i32_2\n"
3258 "%inV3 = OpLoad %v2i16 %inP3\n"
3259 "%outP3 = OpAccessChain %v2i16outPtr %ssboOUT %zero %x %c_i32_2\n"
3260 "OpStore %outP3 %inV3\n"
3261 "\n"//strutOut.v2b32 = strutIn.v2b32
3262 "%inP4 = OpAccessChain %v2i32${inPtr} %ssboIN %zero %x %c_i32_3\n"
3263 "%inV4 = OpLoad %v2i32 %inP4\n"
3264 "%outP4 = OpAccessChain %v2i32outPtr %ssboOUT %zero %x %c_i32_3\n"
3265 "OpStore %outP4 %inV4\n"
3266 "\n"//strutOut.v3b16 = strutIn.v3b16
3267 "%inP5 = OpAccessChain %v3i16${inPtr} %ssboIN %zero %x %c_i32_4\n"
3268 "%inV5 = OpLoad %v3i16 %inP5\n"
3269 "%outP5 = OpAccessChain %v3i16outPtr %ssboOUT %zero %x %c_i32_4\n"
3270 "OpStore %outP5 %inV5\n"
3271 "\n"//strutOut.v3b32 = strutIn.v3b32
3272 "%inP6 = OpAccessChain %v3i32${inPtr} %ssboIN %zero %x %c_i32_5\n"
3273 "%inV6 = OpLoad %v3i32 %inP6\n"
3274 "%outP6 = OpAccessChain %v3i32outPtr %ssboOUT %zero %x %c_i32_5\n"
3275 "OpStore %outP6 %inV6\n"
3276 "\n"//strutOut.v4b16 = strutIn.v4b16
3277 "%inP7 = OpAccessChain %v4i16${inPtr} %ssboIN %zero %x %c_i32_6\n"
3278 "%inV7 = OpLoad %v4i16 %inP7\n"
3279 "%outP7 = OpAccessChain %v4i16outPtr %ssboOUT %zero %x %c_i32_6\n"
3280 "OpStore %outP7 %inV7\n"
3281 "\n"//strutOut.v4b32 = strutIn.v4b32
3282 "%inP8 = OpAccessChain %v4i32${inPtr} %ssboIN %zero %x %c_i32_7\n"
3283 "%inV8 = OpLoad %v4i32 %inP8\n"
3284 "%outP8 = OpAccessChain %v4i32outPtr %ssboOUT %zero %x %c_i32_7\n"
3285 "OpStore %outP8 %inV8\n"
3286 "\n"//strutOut.b16[y] = strutIn.b16[y]
3287 "%inP9 = OpAccessChain %i16${inPtr} %ssboIN %zero %x %c_i32_9 %y\n"
3288 "%inV9 = OpLoad %i16 %inP9\n"
3289 "%outP9 = OpAccessChain %i16outPtr %ssboOUT %zero %x %c_i32_9 %y\n"
3290 "OpStore %outP9 %inV9\n"
3291 "\n"//strutOut.b32[y] = strutIn.b32[y]
3292 "%inP10 = OpAccessChain %i32${inPtr} %ssboIN %zero %x %c_i32_10 %y\n"
3293 "%inV10 = OpLoad %i32 %inP10\n"
3294 "%outP10 = OpAccessChain %i32outPtr %ssboOUT %zero %x %c_i32_10 %y\n"
3295 "OpStore %outP10 %inV10\n"
3296 "\n"//strutOut.strutNestedOut[y].b16 = strutIn.strutNestedIn[y].b16
3297 "%inP11 = OpAccessChain %i16${inPtr} %ssboIN %zero %x %c_i32_8 %y %zero\n"
3298 "%inV11 = OpLoad %i16 %inP11\n"
3299 "%outP11 = OpAccessChain %i16outPtr %ssboOUT %zero %x %c_i32_8 %y %zero\n"
3300 "OpStore %outP11 %inV11\n"
3301 "\n"//strutOut.strutNestedOut[y].b32 = strutIn.strutNestedIn[y].b32
3302 "%inP12 = OpAccessChain %i32${inPtr} %ssboIN %zero %x %c_i32_8 %y %c_i32_1\n"
3303 "%inV12 = OpLoad %i32 %inP12\n"
3304 "%outP12 = OpAccessChain %i32outPtr %ssboOUT %zero %x %c_i32_8 %y %c_i32_1\n"
3305 "OpStore %outP12 %inV12\n"
3308 "\n"//strutOut.strutNestedOut[y].v2b16[valNdx] = strutIn.strutNestedIn[y].v2b16[valNdx]
3309 "%inP13 = OpAccessChain %v2i16${inPtr} %ssboIN %zero %x %c_i32_8 %y %c_i32_2 %Valz\n"
3310 "%inV13 = OpLoad %v2i16 %inP13\n"
3311 "%outP13 = OpAccessChain %v2i16outPtr %ssboOUT %zero %x %c_i32_8 %y %c_i32_2 %Valz\n"
3312 "OpStore %outP13 %inV13\n"
3313 "\n"//strutOut.strutNestedOut[y].b32[valNdx] = strutIn.strutNestedIn[y].b32[valNdx]
3314 "%inP14 = OpAccessChain %i32${inPtr} %ssboIN %zero %x %c_i32_8 %y %c_i32_3 %Valz\n"
3315 "%inV14 = OpLoad %i32 %inP14\n"
3316 "%outP14 = OpAccessChain %i32outPtr %ssboOUT %zero %x %c_i32_8 %y %c_i32_3 %Valz\n"
3317 "OpStore %outP14 %inV14\n"
3319 "OpBranch %exitLabel\n"
3320 "%exitLabel = OpLabel\n"
3324 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
3326 const bool isUniform = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == CAPABILITIES[capIdx].dtype;
3327 vector<deInt16> inData = isUniform ? dataMixStd140(rnd) : dataMixStd430(rnd);
3328 ComputeShaderSpec spec;
3329 map<string, string> specsOffset;
3330 map<string, string> specsLoop;
3331 map<string, string> specs;
3332 string testName = string(CAPABILITIES[capIdx].name);
3334 specsLoop["exeCount"] = "c_i32_11";
3335 specsLoop["loopName"] = "z";
3336 specs["zBeginLoop"] = beginLoop(specsLoop);
3337 specs["zEndLoop"] = endLoop(specsLoop);
3338 specs["capability"] = isUniform ? "OpCapability " + string(CAPABILITIES[capIdx].cap) : " ";
3339 specs["inPtr"] = "outPtr";
3340 specs["storage"] = isUniform ? "Block" : "BufferBlock";
3341 specsOffset["InOut"] = "In";
3342 specs["InOffsets"] = StringTemplate(isUniform ? getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD140) : getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD430)).specialize(specsOffset);
3343 specsOffset["InOut"] = "Out";
3344 specs["OutOffsets"] = StringTemplate(getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD430)).specialize(specsOffset);
3346 spec.assembly = shaderTemplate.specialize(specs);
3347 spec.numWorkGroups = IVec3(structData.structArraySize, structData.nestedArraySize, 1);
3348 spec.verifyIO = isUniform ? computeCheckStruct<deInt16, deInt16, SHADERTEMPLATE_STRIDEMIX_STD140, SHADERTEMPLATE_STRIDEMIX_STD430> : computeCheckStruct<deInt16, deInt16, SHADERTEMPLATE_STRIDEMIX_STD430, SHADERTEMPLATE_STRIDEMIX_STD430>;
3349 spec.inputs.push_back (Resource(BufferSp(new Int16Buffer(inData)), CAPABILITIES[capIdx].dtype));
3350 spec.outputs.push_back (Resource(BufferSp(new Int16Buffer(outData))));
3351 spec.extensions.push_back ("VK_KHR_16bit_storage");
3352 spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
3354 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
3358 void addGraphics16BitStorageUniformFloat32To16Group (tcu::TestCaseGroup* testGroup)
3360 de::Random rnd (deStringHash(testGroup->getName()));
3361 map<string, string> fragments;
3362 vector<string> extensions;
3363 const deUint32 numDataPoints = 256;
3364 RGBA defaultColors[4];
3365 const vector<float> float32Data = getFloat32s(rnd, numDataPoints);
3366 vector<float> float32DataPadded;
3367 vector<deFloat16> float16DummyData (numDataPoints, 0);
3368 const StringTemplate capabilities ("OpCapability ${cap}\n");
3370 for (size_t dataIdx = 0; dataIdx < float32Data.size(); ++dataIdx)
3372 float32DataPadded.push_back(float32Data[dataIdx]);
3373 float32DataPadded.push_back(0.0f);
3374 float32DataPadded.push_back(0.0f);
3375 float32DataPadded.push_back(0.0f);
3378 extensions.push_back("VK_KHR_16bit_storage");
3379 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
3388 getDefaultColors(defaultColors);
3391 fragments["pre_main"] =
3392 " %f16 = OpTypeFloat 16\n"
3393 "%c_i32_256 = OpConstant %i32 256\n"
3394 " %up_f32 = OpTypePointer Uniform %f32\n"
3395 " %up_f16 = OpTypePointer Uniform %f16\n"
3396 " %ra_f32 = OpTypeArray %f32 %c_i32_256\n"
3397 " %ra_f16 = OpTypeArray %f16 %c_i32_256\n"
3398 " %SSBO32 = OpTypeStruct %ra_f32\n"
3399 " %SSBO16 = OpTypeStruct %ra_f16\n"
3400 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
3401 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
3402 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
3403 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n";
3405 const StringTemplate decoration (
3406 "OpDecorate %ra_f32 ArrayStride ${arraystride}\n"
3407 "OpDecorate %ra_f16 ArrayStride 2\n"
3408 "OpMemberDecorate %SSBO32 0 Offset 0\n"
3409 "OpMemberDecorate %SSBO16 0 Offset 0\n"
3410 "OpDecorate %SSBO32 ${indecor}\n"
3411 "OpDecorate %SSBO16 BufferBlock\n"
3412 "OpDecorate %ssbo32 DescriptorSet 0\n"
3413 "OpDecorate %ssbo16 DescriptorSet 0\n"
3414 "OpDecorate %ssbo32 Binding 0\n"
3415 "OpDecorate %ssbo16 Binding 1\n"
3418 fragments["testfun"] =
3419 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3420 " %param = OpFunctionParameter %v4f32\n"
3422 "%entry = OpLabel\n"
3423 " %i = OpVariable %fp_i32 Function\n"
3424 " OpStore %i %c_i32_0\n"
3427 " %loop = OpLabel\n"
3428 " %15 = OpLoad %i32 %i\n"
3429 " %lt = OpSLessThan %bool %15 %c_i32_256\n"
3430 " OpLoopMerge %merge %inc None\n"
3431 " OpBranchConditional %lt %write %merge\n"
3433 "%write = OpLabel\n"
3434 " %30 = OpLoad %i32 %i\n"
3435 " %src = OpAccessChain %up_f32 %ssbo32 %c_i32_0 %30\n"
3436 "%val32 = OpLoad %f32 %src\n"
3437 "%val16 = OpFConvert %f16 %val32\n"
3438 " %dst = OpAccessChain %up_f16 %ssbo16 %c_i32_0 %30\n"
3439 " OpStore %dst %val16\n"
3443 " %37 = OpLoad %i32 %i\n"
3444 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
3448 "%merge = OpLabel\n"
3449 " OpReturnValue %param\n"
3453 const RndMode rndModes[] =
3455 {"rtz", "OpDecorate %val16 FPRoundingMode RTZ", graphicsCheck16BitFloats<ROUNDINGMODE_RTZ>},
3456 {"rte", "OpDecorate %val16 FPRoundingMode RTE", graphicsCheck16BitFloats<ROUNDINGMODE_RTE>},
3457 {"unspecified_rnd_mode", "", graphicsCheck16BitFloats<RoundingModeFlags(ROUNDINGMODE_RTE | ROUNDINGMODE_RTZ)>},
3460 const deUint32 arrayStrides[] = {4, 16};
3462 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
3463 for (deUint32 rndModeIdx = 0; rndModeIdx < DE_LENGTH_OF_ARRAY(rndModes); ++rndModeIdx)
3465 map<string, string> specs;
3466 string testName = string(CAPABILITIES[capIdx].name) + "_scalar_float_" + rndModes[rndModeIdx].name;
3468 GraphicsResources resources;
3469 resources.inputs.push_back(Resource(BufferSp(new Float32Buffer(arrayStrides[capIdx] == 4 ? float32Data : float32DataPadded)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3470 // We use a custom verifyIO to check the result via computing directly from inputs; the contents in outputs do not matter.
3471 resources.outputs.push_back(Resource(BufferSp(new Float16Buffer(float16DummyData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3473 specs["cap"] = CAPABILITIES[capIdx].cap;
3474 specs["indecor"] = CAPABILITIES[capIdx].decor;
3475 specs["arraystride"] = de::toString(arrayStrides[capIdx]);
3476 specs["rounddecor"] = rndModes[rndModeIdx].decor;
3478 fragments["capability"] = capabilities.specialize(specs);
3479 fragments["decoration"] = decoration.specialize(specs);
3481 resources.inputs.back().setDescriptorType(CAPABILITIES[capIdx].dtype);
3482 resources.verifyIO = rndModes[rndModeIdx].f;
3483 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
3487 // Non-scalar cases can use the same resources.
3488 GraphicsResources resources;
3489 resources.inputs.push_back(Resource(BufferSp(new Float32Buffer(float32Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3490 // We use a custom verifyIO to check the result via computing directly from inputs; the contents in outputs do not matter.
3491 resources.outputs.push_back(Resource(BufferSp(new Float16Buffer(float16DummyData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3494 fragments["pre_main"] =
3495 " %f16 = OpTypeFloat 16\n"
3496 " %c_i32_64 = OpConstant %i32 64\n"
3497 " %v4f16 = OpTypeVector %f16 4\n"
3498 " %up_v4f32 = OpTypePointer Uniform %v4f32\n"
3499 " %up_v4f16 = OpTypePointer Uniform %v4f16\n"
3500 " %ra_v4f32 = OpTypeArray %v4f32 %c_i32_64\n"
3501 " %ra_v4f16 = OpTypeArray %v4f16 %c_i32_64\n"
3502 " %SSBO32 = OpTypeStruct %ra_v4f32\n"
3503 " %SSBO16 = OpTypeStruct %ra_v4f16\n"
3504 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
3505 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
3506 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
3507 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n";
3509 const StringTemplate decoration (
3510 "OpDecorate %ra_v4f32 ArrayStride 16\n"
3511 "OpDecorate %ra_v4f16 ArrayStride 8\n"
3512 "OpMemberDecorate %SSBO32 0 Offset 0\n"
3513 "OpMemberDecorate %SSBO16 0 Offset 0\n"
3514 "OpDecorate %SSBO32 ${indecor}\n"
3515 "OpDecorate %SSBO16 BufferBlock\n"
3516 "OpDecorate %ssbo32 DescriptorSet 0\n"
3517 "OpDecorate %ssbo16 DescriptorSet 0\n"
3518 "OpDecorate %ssbo32 Binding 0\n"
3519 "OpDecorate %ssbo16 Binding 1\n"
3522 // ssbo16[] <- convert ssbo32[] to 16bit float
3523 fragments["testfun"] =
3524 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3525 " %param = OpFunctionParameter %v4f32\n"
3527 "%entry = OpLabel\n"
3528 " %i = OpVariable %fp_i32 Function\n"
3529 " OpStore %i %c_i32_0\n"
3532 " %loop = OpLabel\n"
3533 " %15 = OpLoad %i32 %i\n"
3534 " %lt = OpSLessThan %bool %15 %c_i32_64\n"
3535 " OpLoopMerge %merge %inc None\n"
3536 " OpBranchConditional %lt %write %merge\n"
3538 "%write = OpLabel\n"
3539 " %30 = OpLoad %i32 %i\n"
3540 " %src = OpAccessChain %up_v4f32 %ssbo32 %c_i32_0 %30\n"
3541 "%val32 = OpLoad %v4f32 %src\n"
3542 "%val16 = OpFConvert %v4f16 %val32\n"
3543 " %dst = OpAccessChain %up_v4f16 %ssbo16 %c_i32_0 %30\n"
3544 " OpStore %dst %val16\n"
3548 " %37 = OpLoad %i32 %i\n"
3549 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
3553 "%merge = OpLabel\n"
3554 " OpReturnValue %param\n"
3558 const RndMode rndModes[] =
3560 {"rtz", "OpDecorate %val16 FPRoundingMode RTZ", graphicsCheck16BitFloats<ROUNDINGMODE_RTZ>},
3561 {"rte", "OpDecorate %val16 FPRoundingMode RTE", graphicsCheck16BitFloats<ROUNDINGMODE_RTE>},
3562 {"unspecified_rnd_mode", "", graphicsCheck16BitFloats<RoundingModeFlags(ROUNDINGMODE_RTE | ROUNDINGMODE_RTZ)>},
3565 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
3566 for (deUint32 rndModeIdx = 0; rndModeIdx < DE_LENGTH_OF_ARRAY(rndModes); ++rndModeIdx)
3568 map<string, string> specs;
3569 string testName = string(CAPABILITIES[capIdx].name) + "_vector_float_" + rndModes[rndModeIdx].name;
3571 specs["cap"] = CAPABILITIES[capIdx].cap;
3572 specs["indecor"] = CAPABILITIES[capIdx].decor;
3573 specs["rounddecor"] = rndModes[rndModeIdx].decor;
3575 fragments["capability"] = capabilities.specialize(specs);
3576 fragments["decoration"] = decoration.specialize(specs);
3578 resources.inputs.back().setDescriptorType(CAPABILITIES[capIdx].dtype);
3579 resources.verifyIO = rndModes[rndModeIdx].f;
3582 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
3587 fragments["pre_main"] =
3588 " %f16 = OpTypeFloat 16\n"
3589 " %c_i32_16 = OpConstant %i32 16\n"
3590 " %v4f16 = OpTypeVector %f16 4\n"
3591 " %m4x4f32 = OpTypeMatrix %v4f32 4\n"
3592 " %m4x4f16 = OpTypeMatrix %v4f16 4\n"
3593 " %up_v4f32 = OpTypePointer Uniform %v4f32\n"
3594 " %up_v4f16 = OpTypePointer Uniform %v4f16\n"
3595 "%a16m4x4f32 = OpTypeArray %m4x4f32 %c_i32_16\n"
3596 "%a16m4x4f16 = OpTypeArray %m4x4f16 %c_i32_16\n"
3597 " %SSBO32 = OpTypeStruct %a16m4x4f32\n"
3598 " %SSBO16 = OpTypeStruct %a16m4x4f16\n"
3599 " %up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
3600 " %up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
3601 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
3602 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n";
3604 const StringTemplate decoration (
3605 "OpDecorate %a16m4x4f32 ArrayStride 64\n"
3606 "OpDecorate %a16m4x4f16 ArrayStride 32\n"
3607 "OpMemberDecorate %SSBO32 0 Offset 0\n"
3608 "OpMemberDecorate %SSBO32 0 ColMajor\n"
3609 "OpMemberDecorate %SSBO32 0 MatrixStride 16\n"
3610 "OpMemberDecorate %SSBO16 0 Offset 0\n"
3611 "OpMemberDecorate %SSBO16 0 ColMajor\n"
3612 "OpMemberDecorate %SSBO16 0 MatrixStride 8\n"
3613 "OpDecorate %SSBO32 ${indecor}\n"
3614 "OpDecorate %SSBO16 BufferBlock\n"
3615 "OpDecorate %ssbo32 DescriptorSet 0\n"
3616 "OpDecorate %ssbo16 DescriptorSet 0\n"
3617 "OpDecorate %ssbo32 Binding 0\n"
3618 "OpDecorate %ssbo16 Binding 1\n"
3621 fragments["testfun"] =
3622 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3623 " %param = OpFunctionParameter %v4f32\n"
3625 "%entry = OpLabel\n"
3626 " %i = OpVariable %fp_i32 Function\n"
3627 " OpStore %i %c_i32_0\n"
3630 " %loop = OpLabel\n"
3631 " %15 = OpLoad %i32 %i\n"
3632 " %lt = OpSLessThan %bool %15 %c_i32_16\n"
3633 " OpLoopMerge %merge %inc None\n"
3634 " OpBranchConditional %lt %write %merge\n"
3636 " %write = OpLabel\n"
3637 " %30 = OpLoad %i32 %i\n"
3638 " %src_0 = OpAccessChain %up_v4f32 %ssbo32 %c_i32_0 %30 %c_i32_0\n"
3639 " %src_1 = OpAccessChain %up_v4f32 %ssbo32 %c_i32_0 %30 %c_i32_1\n"
3640 " %src_2 = OpAccessChain %up_v4f32 %ssbo32 %c_i32_0 %30 %c_i32_2\n"
3641 " %src_3 = OpAccessChain %up_v4f32 %ssbo32 %c_i32_0 %30 %c_i32_3\n"
3642 "%val32_0 = OpLoad %v4f32 %src_0\n"
3643 "%val32_1 = OpLoad %v4f32 %src_1\n"
3644 "%val32_2 = OpLoad %v4f32 %src_2\n"
3645 "%val32_3 = OpLoad %v4f32 %src_3\n"
3646 "%val16_0 = OpFConvert %v4f16 %val32_0\n"
3647 "%val16_1 = OpFConvert %v4f16 %val32_1\n"
3648 "%val16_2 = OpFConvert %v4f16 %val32_2\n"
3649 "%val16_3 = OpFConvert %v4f16 %val32_3\n"
3650 " %dst_0 = OpAccessChain %up_v4f16 %ssbo16 %c_i32_0 %30 %c_i32_0\n"
3651 " %dst_1 = OpAccessChain %up_v4f16 %ssbo16 %c_i32_0 %30 %c_i32_1\n"
3652 " %dst_2 = OpAccessChain %up_v4f16 %ssbo16 %c_i32_0 %30 %c_i32_2\n"
3653 " %dst_3 = OpAccessChain %up_v4f16 %ssbo16 %c_i32_0 %30 %c_i32_3\n"
3654 " OpStore %dst_0 %val16_0\n"
3655 " OpStore %dst_1 %val16_1\n"
3656 " OpStore %dst_2 %val16_2\n"
3657 " OpStore %dst_3 %val16_3\n"
3661 " %37 = OpLoad %i32 %i\n"
3662 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
3666 "%merge = OpLabel\n"
3667 " OpReturnValue %param\n"
3671 const RndMode rndModes[] =
3673 {"rte", "OpDecorate %val16_0 FPRoundingMode RTE\nOpDecorate %val16_1 FPRoundingMode RTE\nOpDecorate %val16_2 FPRoundingMode RTE\nOpDecorate %val16_3 FPRoundingMode RTE", graphicsCheck16BitFloats<ROUNDINGMODE_RTE>},
3674 {"rtz", "OpDecorate %val16_0 FPRoundingMode RTZ\nOpDecorate %val16_1 FPRoundingMode RTZ\nOpDecorate %val16_2 FPRoundingMode RTZ\nOpDecorate %val16_3 FPRoundingMode RTZ", graphicsCheck16BitFloats<ROUNDINGMODE_RTZ>},
3675 {"unspecified_rnd_mode", "", graphicsCheck16BitFloats<RoundingModeFlags(ROUNDINGMODE_RTE | ROUNDINGMODE_RTZ)>},
3678 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
3679 for (deUint32 rndModeIdx = 0; rndModeIdx < DE_LENGTH_OF_ARRAY(rndModes); ++rndModeIdx)
3681 map<string, string> specs;
3682 string testName = string(CAPABILITIES[capIdx].name) + "_matrix_float_" + rndModes[rndModeIdx].name;
3684 specs["cap"] = CAPABILITIES[capIdx].cap;
3685 specs["indecor"] = CAPABILITIES[capIdx].decor;
3686 specs["rounddecor"] = rndModes[rndModeIdx].decor;
3688 fragments["capability"] = capabilities.specialize(specs);
3689 fragments["decoration"] = decoration.specialize(specs);
3691 resources.inputs.back().setDescriptorType(CAPABILITIES[capIdx].dtype);
3692 resources.verifyIO = rndModes[rndModeIdx].f;
3695 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
3700 void addGraphics16BitStorageInputOutputFloat32To16Group (tcu::TestCaseGroup* testGroup)
3702 de::Random rnd (deStringHash(testGroup->getName()));
3703 RGBA defaultColors[4];
3704 vector<string> extensions;
3705 map<string, string> fragments = passthruFragments();
3706 const deUint32 numDataPoints = 64;
3707 vector<float> float32Data = getFloat32s(rnd, numDataPoints);
3709 extensions.push_back("VK_KHR_16bit_storage");
3711 fragments["capability"] = "OpCapability StorageInputOutput16\n";
3712 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
3714 getDefaultColors(defaultColors);
3720 const char* decor_tessc;
3721 RoundingModeFlags flags;
3724 const RndMode rndModes[] =
3727 "OpDecorate %ret0 FPRoundingMode RTZ\n",
3728 "OpDecorate %ret1 FPRoundingMode RTZ\n"
3729 "OpDecorate %ret2 FPRoundingMode RTZ\n",
3732 "OpDecorate %ret0 FPRoundingMode RTE\n",
3733 "OpDecorate %ret1 FPRoundingMode RTE\n"
3734 "OpDecorate %ret2 FPRoundingMode RTE\n",
3736 {"unspecified_rnd_mode", "", "", RoundingModeFlags(ROUNDINGMODE_RTE | ROUNDINGMODE_RTZ)},
3742 const char* interfaceOpFunc;
3743 const char* postInterfaceOp;
3744 const char* postInterfaceOpGeom;
3745 const char* postInterfaceOpTessc;
3746 const char* preMain;
3747 const char* inputType;
3748 const char* outputType;
3749 deUint32 numPerCase;
3750 deUint32 numElements;
3753 const Case cases[] =
3757 // Passthrough interface_op_func
3758 "%interface_op_func = OpFunction %f16 None %f16_f32_function\n"
3759 " %io_param1 = OpFunctionParameter %f32\n"
3760 " %entry = OpLabel\n"
3761 " OpReturnValue %f16_0\n"
3764 " %ret0 = OpFConvert %f16 %IF_input_val\n"
3765 " OpStore %IF_output %ret0\n",
3767 " %ret0 = OpFConvert %f16 %IF_input_val0\n"
3768 " OpStore %IF_output %ret0\n",
3770 " %ret0 = OpFConvert %f16 %IF_input_val0\n"
3771 " OpStore %IF_output_ptr0 %ret0\n"
3772 " %ret1 = OpFConvert %f16 %IF_input_val1\n"
3773 " OpStore %IF_output_ptr1 %ret1\n"
3774 " %ret2 = OpFConvert %f16 %IF_input_val2\n"
3775 " OpStore %IF_output_ptr2 %ret2\n",
3777 " %f16 = OpTypeFloat 16\n"
3778 " %op_f16 = OpTypePointer Output %f16\n"
3779 " %a3f16 = OpTypeArray %f16 %c_i32_3\n"
3780 " %op_a3f16 = OpTypePointer Output %a3f16\n"
3781 "%f16_f32_function = OpTypeFunction %f16 %f32\n"
3782 " %a3f32 = OpTypeArray %f32 %c_i32_3\n"
3783 " %ip_a3f32 = OpTypePointer Input %a3f32\n"
3784 " %f16_0 = OpConstant %f16 0\n",
3794 "%interface_op_func = OpFunction %v2f16 None %v2f16_v2f32_function\n"
3795 " %io_param1 = OpFunctionParameter %v2f32\n"
3796 " %entry = OpLabel\n"
3797 " OpReturnValue %v2f16_0\n"
3800 " %ret0 = OpFConvert %v2f16 %IF_input_val\n"
3801 " OpStore %IF_output %ret0\n",
3803 " %ret0 = OpFConvert %v2f16 %IF_input_val0\n"
3804 " OpStore %IF_output %ret0\n",
3806 " %ret0 = OpFConvert %v2f16 %IF_input_val0\n"
3807 " OpStore %IF_output_ptr0 %ret0\n"
3808 " %ret1 = OpFConvert %v2f16 %IF_input_val1\n"
3809 " OpStore %IF_output_ptr1 %ret1\n"
3810 " %ret2 = OpFConvert %v2f16 %IF_input_val2\n"
3811 " OpStore %IF_output_ptr2 %ret2\n",
3813 " %f16 = OpTypeFloat 16\n"
3814 " %v2f16 = OpTypeVector %f16 2\n"
3815 " %op_v2f16 = OpTypePointer Output %v2f16\n"
3816 " %a3v2f16 = OpTypeArray %v2f16 %c_i32_3\n"
3817 " %op_a3v2f16 = OpTypePointer Output %a3v2f16\n"
3818 "%v2f16_v2f32_function = OpTypeFunction %v2f16 %v2f32\n"
3819 " %a3v2f32 = OpTypeArray %v2f32 %c_i32_3\n"
3820 " %ip_a3v2f32 = OpTypePointer Input %a3v2f32\n"
3821 " %f16_0 = OpConstant %f16 0\n"
3822 " %v2f16_0 = OpConstantComposite %v2f16 %f16_0 %f16_0\n",
3831 VulkanFeatures requiredFeatures;
3832 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
3834 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
3835 for (deUint32 rndModeIdx = 0; rndModeIdx < DE_LENGTH_OF_ARRAY(rndModes); ++rndModeIdx)
3837 fragments["interface_op_func"] = cases[caseIdx].interfaceOpFunc;
3838 fragments["post_interface_op_frag"] = cases[caseIdx].postInterfaceOp;
3839 fragments["post_interface_op_vert"] = cases[caseIdx].postInterfaceOp;
3840 fragments["post_interface_op_geom"] = cases[caseIdx].postInterfaceOpGeom;
3841 fragments["post_interface_op_tesse"] = cases[caseIdx].postInterfaceOpGeom;
3842 fragments["post_interface_op_tessc"] = cases[caseIdx].postInterfaceOpTessc;
3843 fragments["pre_main"] = cases[caseIdx].preMain;
3844 fragments["decoration"] = rndModes[rndModeIdx].decor;
3845 fragments["decoration_tessc"] = rndModes[rndModeIdx].decor_tessc;
3847 fragments["input_type"] = cases[caseIdx].inputType;
3848 fragments["output_type"] = cases[caseIdx].outputType;
3850 GraphicsInterfaces interfaces;
3851 const deUint32 numPerCase = cases[caseIdx].numPerCase;
3852 vector<float> subInputs (numPerCase);
3853 vector<deFloat16> subOutputs (numPerCase);
3855 // The pipeline need this to call compare16BitFloat() when checking the result.
3856 interfaces.setRoundingMode(rndModes[rndModeIdx].flags);
3858 for (deUint32 caseNdx = 0; caseNdx < numDataPoints / numPerCase; ++caseNdx)
3860 string testName = string(cases[caseIdx].name) + numberToString(caseNdx) + "_" + rndModes[rndModeIdx].name;
3862 for (deUint32 numNdx = 0; numNdx < numPerCase; ++numNdx)
3864 subInputs[numNdx] = float32Data[caseNdx * numPerCase + numNdx];
3865 // We derive the expected result from inputs directly in the graphics pipeline.
3866 subOutputs[numNdx] = 0;
3868 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT32), BufferSp(new Float32Buffer(subInputs))),
3869 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT16), BufferSp(new Float16Buffer(subOutputs))));
3870 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
3875 void addGraphics16BitStorageInputOutputFloat16To32Group (tcu::TestCaseGroup* testGroup)
3877 de::Random rnd (deStringHash(testGroup->getName()));
3878 RGBA defaultColors[4];
3879 vector<string> extensions;
3880 map<string, string> fragments = passthruFragments();
3881 const deUint32 numDataPoints = 64;
3882 vector<deFloat16> float16Data (getFloat16s(rnd, numDataPoints));
3883 vector<float> float32Data;
3885 float32Data.reserve(numDataPoints);
3886 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
3887 float32Data.push_back(deFloat16To32(float16Data[numIdx]));
3889 extensions.push_back("VK_KHR_16bit_storage");
3891 fragments["capability"] = "OpCapability StorageInputOutput16\n";
3892 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
3894 getDefaultColors(defaultColors);
3899 const char* interfaceOpFunc;
3900 const char* preMain;
3901 const char* inputType;
3902 const char* outputType;
3903 deUint32 numPerCase;
3904 deUint32 numElements;
3912 "%interface_op_func = OpFunction %f32 None %f32_f16_function\n"
3913 " %io_param1 = OpFunctionParameter %f16\n"
3914 " %entry = OpLabel\n"
3915 " %ret = OpFConvert %f32 %io_param1\n"
3916 " OpReturnValue %ret\n"
3919 " %f16 = OpTypeFloat 16\n"
3920 " %ip_f16 = OpTypePointer Input %f16\n"
3921 " %a3f16 = OpTypeArray %f16 %c_i32_3\n"
3922 " %ip_a3f16 = OpTypePointer Input %a3f16\n"
3923 "%f32_f16_function = OpTypeFunction %f32 %f16\n"
3924 " %a3f32 = OpTypeArray %f32 %c_i32_3\n"
3925 " %op_a3f32 = OpTypePointer Output %a3f32\n",
3935 "%interface_op_func = OpFunction %v2f32 None %v2f32_v2f16_function\n"
3936 " %io_param1 = OpFunctionParameter %v2f16\n"
3937 " %entry = OpLabel\n"
3938 " %ret = OpFConvert %v2f32 %io_param1\n"
3939 " OpReturnValue %ret\n"
3942 " %f16 = OpTypeFloat 16\n"
3943 " %v2f16 = OpTypeVector %f16 2\n"
3944 " %ip_v2f16 = OpTypePointer Input %v2f16\n"
3945 " %a3v2f16 = OpTypeArray %v2f16 %c_i32_3\n"
3946 " %ip_a3v2f16 = OpTypePointer Input %a3v2f16\n"
3947 "%v2f32_v2f16_function = OpTypeFunction %v2f32 %v2f16\n"
3948 " %a3v2f32 = OpTypeArray %v2f32 %c_i32_3\n"
3949 " %op_a3v2f32 = OpTypePointer Output %a3v2f32\n",
3958 VulkanFeatures requiredFeatures;
3959 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
3961 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
3963 fragments["interface_op_func"] = cases[caseIdx].interfaceOpFunc;
3964 fragments["pre_main"] = cases[caseIdx].preMain;
3966 fragments["input_type"] = cases[caseIdx].inputType;
3967 fragments["output_type"] = cases[caseIdx].outputType;
3969 GraphicsInterfaces interfaces;
3970 const deUint32 numPerCase = cases[caseIdx].numPerCase;
3971 vector<deFloat16> subInputs (numPerCase);
3972 vector<float> subOutputs (numPerCase);
3974 for (deUint32 caseNdx = 0; caseNdx < numDataPoints / numPerCase; ++caseNdx)
3976 string testName = string(cases[caseIdx].name) + numberToString(caseNdx);
3978 for (deUint32 numNdx = 0; numNdx < numPerCase; ++numNdx)
3980 subInputs[numNdx] = float16Data[caseNdx * numPerCase + numNdx];
3981 subOutputs[numNdx] = float32Data[caseNdx * numPerCase + numNdx];
3983 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT16), BufferSp(new Float16Buffer(subInputs))),
3984 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT32), BufferSp(new Float32Buffer(subOutputs))));
3985 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
3990 void addGraphics16BitStorageInputOutputFloat16To16Group (tcu::TestCaseGroup* testGroup)
3992 de::Random rnd (deStringHash(testGroup->getName()));
3993 RGBA defaultColors[4];
3994 vector<string> extensions;
3995 map<string, string> fragments = passthruFragments();
3996 const deUint32 numDataPoints = 64;
3997 vector<deFloat16> float16Data (getFloat16s(rnd, numDataPoints));
3998 VulkanFeatures requiredFeatures;
4000 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
4001 extensions.push_back("VK_KHR_16bit_storage");
4003 fragments["capability"] = "OpCapability StorageInputOutput16\n";
4004 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
4006 getDefaultColors(defaultColors);
4011 const char* interfaceOpFunc;
4012 const char* preMain;
4013 const char* inputType;
4014 const char* outputType;
4015 deUint32 numPerCase;
4016 deUint32 numElements;
4024 "%interface_op_func = OpFunction %f16 None %f16_f16_function\n"
4025 " %io_param1 = OpFunctionParameter %f16\n"
4026 " %entry = OpLabel\n"
4027 " %ret = OpCopyObject %f16 %io_param1\n"
4028 " OpReturnValue %ret\n"
4031 " %f16 = OpTypeFloat 16\n"
4032 " %ip_f16 = OpTypePointer Input %f16\n"
4033 " %a3f16 = OpTypeArray %f16 %c_i32_3\n"
4034 " %ip_a3f16 = OpTypePointer Input %a3f16\n"
4035 "%f16_f16_function = OpTypeFunction %f16 %f16\n"
4036 " %op_f16 = OpTypePointer Output %f16\n"
4037 " %op_a3f16 = OpTypePointer Output %a3f16\n",
4047 "%interface_op_func = OpFunction %v2f16 None %v2f16_v2f16_function\n"
4048 " %io_param1 = OpFunctionParameter %v2f16\n"
4049 " %entry = OpLabel\n"
4050 " %ret = OpCopyObject %v2f16 %io_param1\n"
4051 " OpReturnValue %ret\n"
4054 " %f16 = OpTypeFloat 16\n"
4055 " %v2f16 = OpTypeVector %f16 2\n"
4056 " %ip_v2f16 = OpTypePointer Input %v2f16\n"
4057 " %a3v2f16 = OpTypeArray %v2f16 %c_i32_3\n"
4058 " %ip_a3v2f16 = OpTypePointer Input %a3v2f16\n"
4059 "%v2f16_v2f16_function = OpTypeFunction %v2f16 %v2f16\n"
4060 " %op_v2f16 = OpTypePointer Output %v2f16\n"
4061 " %op_a3v2f16 = OpTypePointer Output %a3v2f16\n",
4070 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
4072 fragments["interface_op_func"] = cases[caseIdx].interfaceOpFunc;
4073 fragments["pre_main"] = cases[caseIdx].preMain;
4075 fragments["input_type"] = cases[caseIdx].inputType;
4076 fragments["output_type"] = cases[caseIdx].outputType;
4078 GraphicsInterfaces interfaces;
4079 const deUint32 numPerCase = cases[caseIdx].numPerCase;
4080 vector<deFloat16> subInputsOutputs (numPerCase);
4082 for (deUint32 caseNdx = 0; caseNdx < numDataPoints / numPerCase; ++caseNdx)
4084 string testName = string(cases[caseIdx].name) + numberToString(caseNdx);
4086 for (deUint32 numNdx = 0; numNdx < numPerCase; ++numNdx)
4087 subInputsOutputs[numNdx] = float16Data[caseNdx * numPerCase + numNdx];
4089 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT16), BufferSp(new Float16Buffer(subInputsOutputs))),
4090 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT16), BufferSp(new Float16Buffer(subInputsOutputs))));
4092 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
4097 void addGraphics16BitStorageInputOutputInt32To16Group (tcu::TestCaseGroup* testGroup)
4099 de::Random rnd (deStringHash(testGroup->getName()));
4100 RGBA defaultColors[4];
4101 vector<string> extensions;
4102 map<string, string> fragments = passthruFragments();
4103 const deUint32 numDataPoints = 64;
4104 // inputs and outputs are declared to be vectors of signed integers.
4105 // However, depending on the test, they may be interpreted as unsiged
4106 // integers. That won't be a problem as long as we passed the bits
4107 // in faithfully to the pipeline.
4108 vector<deInt32> inputs = getInt32s(rnd, numDataPoints);
4109 vector<deInt16> outputs;
4111 outputs.reserve(inputs.size());
4112 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
4113 outputs.push_back(static_cast<deInt16>(0xffff & inputs[numNdx]));
4115 extensions.push_back("VK_KHR_16bit_storage");
4117 fragments["capability"] = "OpCapability StorageInputOutput16\n";
4118 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
4120 getDefaultColors(defaultColors);
4122 const StringTemplate scalarInterfaceOpFunc(
4123 "%interface_op_func = OpFunction %${type16} None %${type16}_${type32}_function\n"
4124 " %io_param1 = OpFunctionParameter %${type32}\n"
4125 " %entry = OpLabel\n"
4126 " %ret = ${convert} %${type16} %io_param1\n"
4127 " OpReturnValue %ret\n"
4128 " OpFunctionEnd\n");
4130 const StringTemplate scalarPreMain(
4131 " %${type16} = OpTypeInt 16 ${signed}\n"
4132 " %op_${type16} = OpTypePointer Output %${type16}\n"
4133 " %a3${type16} = OpTypeArray %${type16} %c_i32_3\n"
4134 " %op_a3${type16} = OpTypePointer Output %a3${type16}\n"
4135 "%${type16}_${type32}_function = OpTypeFunction %${type16} %${type32}\n"
4136 " %a3${type32} = OpTypeArray %${type32} %c_i32_3\n"
4137 " %ip_a3${type32} = OpTypePointer Input %a3${type32}\n");
4139 const StringTemplate vecInterfaceOpFunc(
4140 "%interface_op_func = OpFunction %${type16} None %${type16}_${type32}_function\n"
4141 " %io_param1 = OpFunctionParameter %${type32}\n"
4142 " %entry = OpLabel\n"
4143 " %ret = ${convert} %${type16} %io_param1\n"
4144 " OpReturnValue %ret\n"
4145 " OpFunctionEnd\n");
4147 const StringTemplate vecPreMain(
4148 " %i16 = OpTypeInt 16 1\n"
4149 " %u16 = OpTypeInt 16 0\n"
4150 " %v4i16 = OpTypeVector %i16 4\n"
4151 " %v4u16 = OpTypeVector %u16 4\n"
4152 " %op_${type16} = OpTypePointer Output %${type16}\n"
4153 " %a3${type16} = OpTypeArray %${type16} %c_i32_3\n"
4154 " %op_a3${type16} = OpTypePointer Output %a3${type16}\n"
4155 "%${type16}_${type32}_function = OpTypeFunction %${type16} %${type32}\n"
4156 " %a3${type32} = OpTypeArray %${type32} %c_i32_3\n"
4157 " %ip_a3${type32} = OpTypePointer Input %a3${type32}\n");
4162 const StringTemplate& interfaceOpFunc;
4163 const StringTemplate& preMain;
4168 deUint32 numPerCase;
4169 deUint32 numElements;
4174 {"scalar_sint", scalarInterfaceOpFunc, scalarPreMain, "i32", "i16", "1", "OpSConvert", 4, 1},
4175 {"scalar_uint", scalarInterfaceOpFunc, scalarPreMain, "u32", "u16", "0", "OpUConvert", 4, 1},
4176 {"vector_sint", vecInterfaceOpFunc, vecPreMain, "v4i32", "v4i16", "1", "OpSConvert", 4 * 4, 4},
4177 {"vector_uint", vecInterfaceOpFunc, vecPreMain, "v4u32", "v4u16", "0", "OpUConvert", 4 * 4, 4},
4180 VulkanFeatures requiredFeatures;
4181 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
4183 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
4185 map<string, string> specs;
4187 specs["type32"] = cases[caseIdx].type32;
4188 specs["type16"] = cases[caseIdx].type16;
4189 specs["signed"] = cases[caseIdx].sign;
4190 specs["convert"] = cases[caseIdx].opcode;
4192 fragments["pre_main"] = cases[caseIdx].preMain.specialize(specs);
4193 fragments["interface_op_func"] = cases[caseIdx].interfaceOpFunc.specialize(specs);
4194 fragments["input_type"] = cases[caseIdx].type32;
4195 fragments["output_type"] = cases[caseIdx].type16;
4197 GraphicsInterfaces interfaces;
4198 const deUint32 numPerCase = cases[caseIdx].numPerCase;
4199 vector<deInt32> subInputs (numPerCase);
4200 vector<deInt16> subOutputs (numPerCase);
4202 for (deUint32 caseNdx = 0; caseNdx < numDataPoints / numPerCase; ++caseNdx)
4204 string testName = string(cases[caseIdx].name) + numberToString(caseNdx);
4206 for (deUint32 numNdx = 0; numNdx < numPerCase; ++numNdx)
4208 subInputs[numNdx] = inputs[caseNdx * numPerCase + numNdx];
4209 subOutputs[numNdx] = outputs[caseNdx * numPerCase + numNdx];
4211 if (strcmp(cases[caseIdx].sign, "1") == 0)
4213 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_INT32), BufferSp(new Int32Buffer(subInputs))),
4214 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_INT16), BufferSp(new Int16Buffer(subOutputs))));
4218 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_UINT32), BufferSp(new Int32Buffer(subInputs))),
4219 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_UINT16), BufferSp(new Int16Buffer(subOutputs))));
4221 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
4226 void addGraphics16BitStorageInputOutputInt16To32Group (tcu::TestCaseGroup* testGroup)
4228 de::Random rnd (deStringHash(testGroup->getName()));
4229 RGBA defaultColors[4];
4230 vector<string> extensions;
4231 map<string, string> fragments = passthruFragments();
4232 const deUint32 numDataPoints = 64;
4233 // inputs and outputs are declared to be vectors of signed integers.
4234 // However, depending on the test, they may be interpreted as unsiged
4235 // integers. That won't be a problem as long as we passed the bits
4236 // in faithfully to the pipeline.
4237 vector<deInt16> inputs = getInt16s(rnd, numDataPoints);
4238 vector<deInt32> sOutputs;
4239 vector<deInt32> uOutputs;
4240 const deUint16 signBitMask = 0x8000;
4241 const deUint32 signExtendMask = 0xffff0000;
4243 sOutputs.reserve(inputs.size());
4244 uOutputs.reserve(inputs.size());
4246 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
4248 uOutputs.push_back(static_cast<deUint16>(inputs[numNdx]));
4249 if (inputs[numNdx] & signBitMask)
4250 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx] | signExtendMask));
4252 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx]));
4255 extensions.push_back("VK_KHR_16bit_storage");
4257 fragments["capability"] = "OpCapability StorageInputOutput16\n";
4258 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
4260 getDefaultColors(defaultColors);
4262 const StringTemplate scalarIfOpFunc (
4263 "%interface_op_func = OpFunction %${type32} None %${type32}_${type16}_function\n"
4264 " %io_param1 = OpFunctionParameter %${type16}\n"
4265 " %entry = OpLabel\n"
4266 " %ret = ${convert} %${type32} %io_param1\n"
4267 " OpReturnValue %ret\n"
4268 " OpFunctionEnd\n");
4270 const StringTemplate scalarPreMain (
4271 " %${type16} = OpTypeInt 16 ${signed}\n"
4272 " %ip_${type16} = OpTypePointer Input %${type16}\n"
4273 " %a3${type16} = OpTypeArray %${type16} %c_i32_3\n"
4274 " %ip_a3${type16} = OpTypePointer Input %a3${type16}\n"
4275 "%${type32}_${type16}_function = OpTypeFunction %${type32} %${type16}\n"
4276 " %a3${type32} = OpTypeArray %${type32} %c_i32_3\n"
4277 " %op_a3${type32} = OpTypePointer Output %a3${type32}\n");
4279 const StringTemplate vecIfOpFunc (
4280 "%interface_op_func = OpFunction %${type32} None %${type32}_${type16}_function\n"
4281 " %io_param1 = OpFunctionParameter %${type16}\n"
4282 " %entry = OpLabel\n"
4283 " %ret = ${convert} %${type32} %io_param1\n"
4284 " OpReturnValue %ret\n"
4285 " OpFunctionEnd\n");
4287 const StringTemplate vecPreMain (
4288 " %i16 = OpTypeInt 16 1\n"
4289 " %u16 = OpTypeInt 16 0\n"
4290 " %v4i16 = OpTypeVector %i16 4\n"
4291 " %v4u16 = OpTypeVector %u16 4\n"
4292 " %ip_${type16} = OpTypePointer Input %${type16}\n"
4293 " %a3${type16} = OpTypeArray %${type16} %c_i32_3\n"
4294 " %ip_a3${type16} = OpTypePointer Input %a3${type16}\n"
4295 "%${type32}_${type16}_function = OpTypeFunction %${type32} %${type16}\n"
4296 " %a3${type32} = OpTypeArray %${type32} %c_i32_3\n"
4297 " %op_a3${type32} = OpTypePointer Output %a3${type32}\n");
4302 const StringTemplate& interfaceOpFunc;
4303 const StringTemplate& preMain;
4308 deUint32 numPerCase;
4309 deUint32 numElements;
4314 {"scalar_sint", scalarIfOpFunc, scalarPreMain, "i32", "i16", "1", "OpSConvert", 4, 1},
4315 {"scalar_uint", scalarIfOpFunc, scalarPreMain, "u32", "u16", "0", "OpUConvert", 4, 1},
4316 {"vector_sint", vecIfOpFunc, vecPreMain, "v4i32", "v4i16", "1", "OpSConvert", 4 * 4, 4},
4317 {"vector_uint", vecIfOpFunc, vecPreMain, "v4u32", "v4u16", "0", "OpUConvert", 4 * 4, 4},
4320 VulkanFeatures requiredFeatures;
4321 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
4323 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
4325 map<string, string> specs;
4327 specs["type32"] = cases[caseIdx].type32;
4328 specs["type16"] = cases[caseIdx].type16;
4329 specs["signed"] = cases[caseIdx].sign;
4330 specs["convert"] = cases[caseIdx].opcode;
4332 fragments["pre_main"] = cases[caseIdx].preMain.specialize(specs);
4333 fragments["interface_op_func"] = cases[caseIdx].interfaceOpFunc.specialize(specs);
4334 fragments["input_type"] = cases[caseIdx].type16;
4335 fragments["output_type"] = cases[caseIdx].type32;
4337 GraphicsInterfaces interfaces;
4338 const deUint32 numPerCase = cases[caseIdx].numPerCase;
4339 vector<deInt16> subInputs (numPerCase);
4340 vector<deInt32> subOutputs (numPerCase);
4342 for (deUint32 caseNdx = 0; caseNdx < numDataPoints / numPerCase; ++caseNdx)
4344 string testName = string(cases[caseIdx].name) + numberToString(caseNdx);
4346 for (deUint32 numNdx = 0; numNdx < numPerCase; ++numNdx)
4348 subInputs[numNdx] = inputs[caseNdx * numPerCase + numNdx];
4349 if (cases[caseIdx].sign[0] == '1')
4350 subOutputs[numNdx] = sOutputs[caseNdx * numPerCase + numNdx];
4352 subOutputs[numNdx] = uOutputs[caseNdx * numPerCase + numNdx];
4354 if (strcmp(cases[caseIdx].sign, "1") == 0)
4356 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_INT16), BufferSp(new Int16Buffer(subInputs))),
4357 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_INT32), BufferSp(new Int32Buffer(subOutputs))));
4361 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_UINT16), BufferSp(new Int16Buffer(subInputs))),
4362 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_UINT32), BufferSp(new Int32Buffer(subOutputs))));
4364 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
4369 void addGraphics16BitStorageInputOutputInt16To16Group (tcu::TestCaseGroup* testGroup)
4371 de::Random rnd (deStringHash(testGroup->getName()));
4372 RGBA defaultColors[4];
4373 vector<string> extensions;
4374 map<string, string> fragments = passthruFragments();
4375 const deUint32 numDataPoints = 64;
4376 // inputs and outputs are declared to be vectors of signed integers.
4377 // However, depending on the test, they may be interpreted as unsiged
4378 // integers. That won't be a problem as long as we passed the bits
4379 // in faithfully to the pipeline.
4380 vector<deInt16> inputs = getInt16s(rnd, numDataPoints);
4381 VulkanFeatures requiredFeatures;
4383 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
4384 extensions.push_back("VK_KHR_16bit_storage");
4386 fragments["capability"] = "OpCapability StorageInputOutput16\n";
4387 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
4389 getDefaultColors(defaultColors);
4391 const StringTemplate scalarIfOpFunc (
4392 "%interface_op_func = OpFunction %${type16} None %${type16}_${type16}_function\n"
4393 " %io_param1 = OpFunctionParameter %${type16}\n"
4394 " %entry = OpLabel\n"
4395 " %ret = OpCopyObject %${type16} %io_param1\n"
4396 " OpReturnValue %ret\n"
4397 " OpFunctionEnd\n");
4399 const StringTemplate scalarPreMain (
4400 " %${type16} = OpTypeInt 16 ${signed}\n"
4401 " %ip_${type16} = OpTypePointer Input %${type16}\n"
4402 " %a3${type16} = OpTypeArray %${type16} %c_i32_3\n"
4403 " %ip_a3${type16} = OpTypePointer Input %a3${type16}\n"
4404 "%${type16}_${type16}_function = OpTypeFunction %${type16} %${type16}\n"
4405 " %op_${type16} = OpTypePointer Output %${type16}\n"
4406 " %op_a3${type16} = OpTypePointer Output %a3${type16}\n");
4408 const StringTemplate vecIfOpFunc (
4409 "%interface_op_func = OpFunction %${type16} None %${type16}_${type16}_function\n"
4410 " %io_param1 = OpFunctionParameter %${type16}\n"
4411 " %entry = OpLabel\n"
4412 " %ret = OpCopyObject %${type16} %io_param1\n"
4413 " OpReturnValue %ret\n"
4414 " OpFunctionEnd\n");
4416 const StringTemplate vecPreMain (
4417 " %i16 = OpTypeInt 16 1\n"
4418 " %u16 = OpTypeInt 16 0\n"
4419 " %v4i16 = OpTypeVector %i16 4\n"
4420 " %v4u16 = OpTypeVector %u16 4\n"
4421 " %ip_${type16} = OpTypePointer Input %${type16}\n"
4422 " %a3${type16} = OpTypeArray %${type16} %c_i32_3\n"
4423 " %ip_a3${type16} = OpTypePointer Input %a3${type16}\n"
4424 "%${type16}_${type16}_function = OpTypeFunction %${type16} %${type16}\n"
4425 " %op_${type16} = OpTypePointer Output %${type16}\n"
4426 " %op_a3${type16} = OpTypePointer Output %a3${type16}\n");
4431 const StringTemplate& interfaceOpFunc;
4432 const StringTemplate& preMain;
4435 deUint32 numPerCase;
4436 deUint32 numElements;
4441 {"scalar_sint", scalarIfOpFunc, scalarPreMain, "i16", "1", 4, 1},
4442 {"scalar_uint", scalarIfOpFunc, scalarPreMain, "u16", "0", 4, 1},
4443 {"vector_sint", vecIfOpFunc, vecPreMain, "v4i16", "1", 4 * 4, 4},
4444 {"vector_uint", vecIfOpFunc, vecPreMain, "v4u16", "0", 4 * 4, 4},
4447 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
4449 map<string, string> specs;
4451 specs["type16"] = cases[caseIdx].type16;
4452 specs["signed"] = cases[caseIdx].sign;
4454 fragments["pre_main"] = cases[caseIdx].preMain.specialize(specs);
4455 fragments["interface_op_func"] = cases[caseIdx].interfaceOpFunc.specialize(specs);
4456 fragments["input_type"] = cases[caseIdx].type16;
4457 fragments["output_type"] = cases[caseIdx].type16;
4459 GraphicsInterfaces interfaces;
4460 const deUint32 numPerCase = cases[caseIdx].numPerCase;
4461 vector<deInt16> subInputsOutputs (numPerCase);
4462 const NumberType numberType = strcmp(cases[caseIdx].sign, "1") == 0 ? NUMBERTYPE_INT16 : NUMBERTYPE_UINT16;
4464 for (deUint32 caseNdx = 0; caseNdx < numDataPoints / numPerCase; ++caseNdx)
4466 string testName = string(cases[caseIdx].name) + numberToString(caseNdx);
4468 for (deUint32 numNdx = 0; numNdx < numPerCase; ++numNdx)
4469 subInputsOutputs[numNdx] = inputs[caseNdx * numPerCase + numNdx];
4471 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, numberType), BufferSp(new Int16Buffer(subInputsOutputs))),
4472 std::make_pair(IFDataType(cases[caseIdx].numElements, numberType), BufferSp(new Int16Buffer(subInputsOutputs))));
4474 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
4479 void addGraphics16BitStoragePushConstantFloat16To32Group (tcu::TestCaseGroup* testGroup)
4481 de::Random rnd (deStringHash(testGroup->getName()));
4482 map<string, string> fragments;
4483 RGBA defaultColors[4];
4484 vector<string> extensions;
4485 GraphicsResources resources;
4487 const deUint32 numDataPoints = 64;
4488 vector<deFloat16> float16Data (getFloat16s(rnd, numDataPoints));
4489 vector<float> float32Data;
4490 VulkanFeatures requiredFeatures;
4492 struct ConstantIndex
4494 bool useConstantIndex;
4495 deUint32 constantIndex;
4498 ConstantIndex constantIndices[] =
4506 float32Data.reserve(numDataPoints);
4507 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
4508 float32Data.push_back(deFloat16To32(float16Data[numIdx]));
4510 extensions.push_back("VK_KHR_16bit_storage");
4511 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
4513 fragments["capability"] = "OpCapability StoragePushConstant16\n";
4514 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
4516 pcs.setPushConstant(BufferSp(new Float16Buffer(float16Data)));
4517 resources.verifyIO = check32BitFloats;
4519 getDefaultColors(defaultColors);
4521 const StringTemplate testFun (
4522 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
4523 " %param = OpFunctionParameter %v4f32\n"
4525 "%entry = OpLabel\n"
4526 " %i = OpVariable %fp_i32 Function\n"
4527 " OpStore %i %c_i32_0\n"
4530 " %loop = OpLabel\n"
4531 " %15 = OpLoad %i32 %i\n"
4532 " %lt = OpSLessThan %bool %15 ${count}\n"
4533 " OpLoopMerge %merge %inc None\n"
4534 " OpBranchConditional %lt %write %merge\n"
4536 "%write = OpLabel\n"
4537 " %30 = OpLoad %i32 %i\n"
4538 " %src = OpAccessChain ${pp_type16} %pc16 %c_i32_0 %${arrayindex} ${index0:opt}\n"
4539 "%val16 = OpLoad ${f_type16} %src\n"
4540 "%val32 = OpFConvert ${f_type32} %val16\n"
4541 " %dst = OpAccessChain ${up_type32} %ssbo32 %c_i32_0 %30 ${index0:opt}\n"
4542 " OpStore %dst %val32\n"
4549 " %37 = OpLoad %i32 %i\n"
4550 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
4554 "%merge = OpLabel\n"
4555 " OpReturnValue %param\n"
4560 const StringTemplate preMain (
4561 " %f16 = OpTypeFloat 16\n"
4562 " %c_i32_64 = OpConstant %i32 64\n"
4563 " %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
4564 " %a64f16 = OpTypeArray %f16 %c_i32_64\n"
4565 " %a64f32 = OpTypeArray %f32 %c_i32_64\n"
4566 " %pp_f16 = OpTypePointer PushConstant %f16\n"
4567 " %up_f32 = OpTypePointer Uniform %f32\n"
4568 " %SSBO32 = OpTypeStruct %a64f32\n"
4569 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
4570 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
4571 " %PC16 = OpTypeStruct %a64f16\n"
4572 " %pp_PC16 = OpTypePointer PushConstant %PC16\n"
4573 " %pc16 = OpVariable %pp_PC16 PushConstant\n");
4575 fragments["decoration"] =
4576 "OpDecorate %a64f16 ArrayStride 2\n"
4577 "OpDecorate %a64f32 ArrayStride 4\n"
4578 "OpDecorate %SSBO32 BufferBlock\n"
4579 "OpMemberDecorate %SSBO32 0 Offset 0\n"
4580 "OpDecorate %PC16 BufferBlock\n"
4581 "OpMemberDecorate %PC16 0 Offset 0\n"
4582 "OpDecorate %ssbo32 DescriptorSet 0\n"
4583 "OpDecorate %ssbo32 Binding 0\n";
4585 map<string, string> specs;
4587 specs["count"] = "%c_i32_64";
4588 specs["pp_type16"] = "%pp_f16";
4589 specs["f_type16"] = "%f16";
4590 specs["f_type32"] = "%f32";
4591 specs["up_type32"] = "%up_f32";
4593 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4595 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
4596 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
4597 string testName = "scalar";
4598 vector<float> float32ConstIdxData;
4602 float32ConstIdxData.reserve(numDataPoints);
4604 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
4605 float32ConstIdxData.push_back(float32Data[constIdx]);
4608 specs["constarrayidx"] = de::toString(constIdx);
4610 specs["arrayindex"] = "c_i32_ci";
4612 specs["arrayindex"] = "30";
4614 resources.outputs.clear();
4615 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(useConstIdx ? float32ConstIdxData : float32Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4617 fragments["pre_main"] = preMain.specialize(specs);
4618 fragments["testfun"] = testFun.specialize(specs);
4621 testName += string("_const_idx_") + de::toString(constIdx);
4623 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
4628 const StringTemplate preMain (
4629 " %f16 = OpTypeFloat 16\n"
4630 " %v4f16 = OpTypeVector %f16 4\n"
4631 " %c_i32_16 = OpConstant %i32 16\n"
4632 " %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
4633 " %a16v4f16 = OpTypeArray %v4f16 %c_i32_16\n"
4634 " %a16v4f32 = OpTypeArray %v4f32 %c_i32_16\n"
4635 " %pp_v4f16 = OpTypePointer PushConstant %v4f16\n"
4636 " %up_v4f32 = OpTypePointer Uniform %v4f32\n"
4637 " %SSBO32 = OpTypeStruct %a16v4f32\n"
4638 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
4639 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
4640 " %PC16 = OpTypeStruct %a16v4f16\n"
4641 " %pp_PC16 = OpTypePointer PushConstant %PC16\n"
4642 " %pc16 = OpVariable %pp_PC16 PushConstant\n");
4644 fragments["decoration"] =
4645 "OpDecorate %a16v4f16 ArrayStride 8\n"
4646 "OpDecorate %a16v4f32 ArrayStride 16\n"
4647 "OpDecorate %SSBO32 BufferBlock\n"
4648 "OpMemberDecorate %SSBO32 0 Offset 0\n"
4649 "OpDecorate %PC16 BufferBlock\n"
4650 "OpMemberDecorate %PC16 0 Offset 0\n"
4651 "OpDecorate %ssbo32 DescriptorSet 0\n"
4652 "OpDecorate %ssbo32 Binding 0\n";
4654 map<string, string> specs;
4656 specs["count"] = "%c_i32_16";
4657 specs["pp_type16"] = "%pp_v4f16";
4658 specs["f_type16"] = "%v4f16";
4659 specs["f_type32"] = "%v4f32";
4660 specs["up_type32"] = "%up_v4f32";
4662 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4664 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
4665 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
4666 string testName = "vector";
4667 vector<float> float32ConstIdxData;
4671 float32ConstIdxData.reserve(numDataPoints);
4673 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
4674 float32ConstIdxData.push_back(float32Data[constIdx * 4 + numIdx % 4]);
4677 specs["constarrayidx"] = de::toString(constIdx);
4679 specs["arrayindex"] = "c_i32_ci";
4681 specs["arrayindex"] = "30";
4683 resources.outputs.clear();
4684 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(useConstIdx ? float32ConstIdxData : float32Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4686 fragments["pre_main"] = preMain.specialize(specs);
4687 fragments["testfun"] = testFun.specialize(specs);
4690 testName += string("_const_idx_") + de::toString(constIdx);
4692 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
4697 const StringTemplate preMain (
4698 " %c_i32_8 = OpConstant %i32 8\n"
4699 " %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
4700 " %f16 = OpTypeFloat 16\n"
4701 " %v4f16 = OpTypeVector %f16 4\n"
4702 " %m2v4f16 = OpTypeMatrix %v4f16 2\n"
4703 " %m2v4f32 = OpTypeMatrix %v4f32 2\n"
4704 " %a8m2v4f16 = OpTypeArray %m2v4f16 %c_i32_8\n"
4705 " %a8m2v4f32 = OpTypeArray %m2v4f32 %c_i32_8\n"
4706 " %pp_v4f16 = OpTypePointer PushConstant %v4f16\n"
4707 " %up_v4f32 = OpTypePointer Uniform %v4f32\n"
4708 " %SSBO32 = OpTypeStruct %a8m2v4f32\n"
4709 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
4710 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
4711 " %PC16 = OpTypeStruct %a8m2v4f16\n"
4712 " %pp_PC16 = OpTypePointer PushConstant %PC16\n"
4713 " %pc16 = OpVariable %pp_PC16 PushConstant\n");
4715 fragments["decoration"] =
4716 "OpDecorate %a8m2v4f16 ArrayStride 16\n"
4717 "OpDecorate %a8m2v4f32 ArrayStride 32\n"
4718 "OpDecorate %SSBO32 BufferBlock\n"
4719 "OpMemberDecorate %SSBO32 0 Offset 0\n"
4720 "OpMemberDecorate %SSBO32 0 ColMajor\n"
4721 "OpMemberDecorate %SSBO32 0 MatrixStride 16\n"
4722 "OpDecorate %PC16 BufferBlock\n"
4723 "OpMemberDecorate %PC16 0 Offset 0\n"
4724 "OpMemberDecorate %PC16 0 ColMajor\n"
4725 "OpMemberDecorate %PC16 0 MatrixStride 8\n"
4726 "OpDecorate %ssbo32 DescriptorSet 0\n"
4727 "OpDecorate %ssbo32 Binding 0\n";
4729 map<string, string> specs;
4731 specs["count"] = "%c_i32_8";
4732 specs["pp_type16"] = "%pp_v4f16";
4733 specs["up_type32"] = "%up_v4f32";
4734 specs["f_type16"] = "%v4f16";
4735 specs["f_type32"] = "%v4f32";
4736 specs["index0"] = "%c_i32_0";
4738 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4740 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
4741 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
4742 string testName = "matrix";
4743 vector<float> float32ConstIdxData;
4744 const StringTemplate store (
4745 " %src_1 = OpAccessChain %pp_v4f16 %pc16 %c_i32_0 %${arrayindex} %c_i32_1\n"
4746 "%val16_1 = OpLoad %v4f16 %src_1\n"
4747 "%val32_1 = OpFConvert %v4f32 %val16_1\n"
4748 " %dst_1 = OpAccessChain %up_v4f32 %ssbo32 %c_i32_0 %30 %c_i32_1\n"
4749 " OpStore %dst_1 %val32_1\n");
4753 float32ConstIdxData.reserve(numDataPoints);
4755 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
4756 float32ConstIdxData.push_back(float32Data[constIdx * 8 + numIdx % 8]);
4759 specs["constarrayidx"] = de::toString(constIdx);
4761 specs["arrayindex"] = "c_i32_ci";
4763 specs["arrayindex"] = "30";
4765 specs["store"] = store.specialize(specs);
4767 resources.outputs.clear();
4768 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(useConstIdx ? float32ConstIdxData : float32Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4770 fragments["pre_main"] = preMain.specialize(specs);
4771 fragments["testfun"] = testFun.specialize(specs);
4774 testName += string("_const_idx_") + de::toString(constIdx);
4776 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
4781 void addGraphics16BitStoragePushConstantInt16To32Group (tcu::TestCaseGroup* testGroup)
4783 de::Random rnd (deStringHash(testGroup->getName()));
4784 map<string, string> fragments;
4785 RGBA defaultColors[4];
4786 const deUint32 numDataPoints = 64;
4787 vector<deInt16> inputs = getInt16s(rnd, numDataPoints);
4788 vector<deInt32> sOutputs;
4789 vector<deInt32> uOutputs;
4791 GraphicsResources resources;
4792 vector<string> extensions;
4793 const deUint16 signBitMask = 0x8000;
4794 const deUint32 signExtendMask = 0xffff0000;
4795 VulkanFeatures requiredFeatures;
4797 struct ConstantIndex
4799 bool useConstantIndex;
4800 deUint32 constantIndex;
4803 ConstantIndex constantIndices[] =
4811 sOutputs.reserve(inputs.size());
4812 uOutputs.reserve(inputs.size());
4814 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
4816 uOutputs.push_back(static_cast<deUint16>(inputs[numNdx]));
4817 if (inputs[numNdx] & signBitMask)
4818 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx] | signExtendMask));
4820 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx]));
4823 extensions.push_back("VK_KHR_16bit_storage");
4824 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
4826 fragments["capability"] = "OpCapability StoragePushConstant16\n";
4827 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
4829 pcs.setPushConstant(BufferSp(new Int16Buffer(inputs)));
4831 getDefaultColors(defaultColors);
4833 const StringTemplate testFun (
4834 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
4835 " %param = OpFunctionParameter %v4f32\n"
4837 "%entry = OpLabel\n"
4838 " %i = OpVariable %fp_i32 Function\n"
4839 " OpStore %i %c_i32_0\n"
4842 " %loop = OpLabel\n"
4843 " %15 = OpLoad %i32 %i\n"
4844 " %lt = OpSLessThan %bool %15 %c_i32_${count}\n"
4845 " OpLoopMerge %merge %inc None\n"
4846 " OpBranchConditional %lt %write %merge\n"
4848 "%write = OpLabel\n"
4849 " %30 = OpLoad %i32 %i\n"
4850 " %src = OpAccessChain %pp_${type16} %pc16 %c_i32_0 %${arrayindex}\n"
4851 "%val16 = OpLoad %${type16} %src\n"
4852 "%val32 = ${convert} %${type32} %val16\n"
4853 " %dst = OpAccessChain %up_${type32} %ssbo32 %c_i32_0 %30\n"
4854 " OpStore %dst %val32\n"
4858 " %37 = OpLoad %i32 %i\n"
4859 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
4863 "%merge = OpLabel\n"
4864 " OpReturnValue %param\n"
4869 const StringTemplate preMain (
4870 " %${type16} = OpTypeInt 16 ${signed}\n"
4871 " %c_i32_${count} = OpConstant %i32 ${count}\n" // Should be the same as numDataPoints
4872 " %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
4873 "%a${count}${type16} = OpTypeArray %${type16} %c_i32_${count}\n"
4874 "%a${count}${type32} = OpTypeArray %${type32} %c_i32_${count}\n"
4875 " %pp_${type16} = OpTypePointer PushConstant %${type16}\n"
4876 " %up_${type32} = OpTypePointer Uniform %${type32}\n"
4877 " %SSBO32 = OpTypeStruct %a${count}${type32}\n"
4878 " %up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
4879 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
4880 " %PC16 = OpTypeStruct %a${count}${type16}\n"
4881 " %pp_PC16 = OpTypePointer PushConstant %PC16\n"
4882 " %pc16 = OpVariable %pp_PC16 PushConstant\n");
4884 const StringTemplate decoration (
4885 "OpDecorate %a${count}${type16} ArrayStride 2\n"
4886 "OpDecorate %a${count}${type32} ArrayStride 4\n"
4887 "OpDecorate %SSBO32 BufferBlock\n"
4888 "OpMemberDecorate %SSBO32 0 Offset 0\n"
4889 "OpDecorate %PC16 BufferBlock\n"
4890 "OpMemberDecorate %PC16 0 Offset 0\n"
4891 "OpDecorate %ssbo32 DescriptorSet 0\n"
4892 "OpDecorate %ssbo32 Binding 0\n");
4895 map<string, string> specs;
4897 specs["type16"] = "i16";
4898 specs["type32"] = "i32";
4899 specs["signed"] = "1";
4900 specs["count"] = "64";
4901 specs["convert"] = "OpSConvert";
4903 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4905 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
4906 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
4907 string testName = "sint_scalar";
4908 vector<deInt32> constIdxData;
4912 constIdxData.reserve(numDataPoints);
4914 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
4915 constIdxData.push_back(sOutputs[constIdx]);
4918 specs["constarrayidx"] = de::toString(constIdx);
4920 specs["arrayindex"] = "c_i32_ci";
4922 specs["arrayindex"] = "30";
4925 testName += string("_const_idx_") + de::toString(constIdx);
4927 resources.outputs.clear();
4928 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(useConstIdx ? constIdxData : sOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4930 fragments["testfun"] = testFun.specialize(specs);
4931 fragments["pre_main"] = preMain.specialize(specs);
4932 fragments["decoration"] = decoration.specialize(specs);
4934 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
4938 map<string, string> specs;
4940 specs["type16"] = "u16";
4941 specs["type32"] = "u32";
4942 specs["signed"] = "0";
4943 specs["count"] = "64";
4944 specs["convert"] = "OpUConvert";
4946 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4948 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
4949 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
4950 string testName = "uint_scalar";
4951 vector<deInt32> constIdxData;
4955 constIdxData.reserve(numDataPoints);
4957 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
4958 constIdxData.push_back(uOutputs[constIdx]);
4961 specs["constarrayidx"] = de::toString(constIdx);
4963 specs["arrayindex"] = "c_i32_ci";
4965 specs["arrayindex"] = "30";
4968 testName += string("_const_idx_") + de::toString(constIdx);
4970 resources.outputs.clear();
4971 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(useConstIdx ? constIdxData : uOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4973 fragments["testfun"] = testFun.specialize(specs);
4974 fragments["pre_main"] = preMain.specialize(specs);
4975 fragments["decoration"] = decoration.specialize(specs);
4977 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
4983 const StringTemplate preMain (
4984 " %${base_type16} = OpTypeInt 16 ${signed}\n"
4985 " %${type16} = OpTypeVector %${base_type16} 2\n"
4986 " %c_i32_${count} = OpConstant %i32 ${count}\n"
4987 " %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
4988 "%a${count}${type16} = OpTypeArray %${type16} %c_i32_${count}\n"
4989 "%a${count}${type32} = OpTypeArray %${type32} %c_i32_${count}\n"
4990 " %pp_${type16} = OpTypePointer PushConstant %${type16}\n"
4991 " %up_${type32} = OpTypePointer Uniform %${type32}\n"
4992 " %SSBO32 = OpTypeStruct %a${count}${type32}\n"
4993 " %up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
4994 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
4995 " %PC16 = OpTypeStruct %a${count}${type16}\n"
4996 " %pp_PC16 = OpTypePointer PushConstant %PC16\n"
4997 " %pc16 = OpVariable %pp_PC16 PushConstant\n");
4999 const StringTemplate decoration (
5000 "OpDecorate %a${count}${type16} ArrayStride 4\n"
5001 "OpDecorate %a${count}${type32} ArrayStride 8\n"
5002 "OpDecorate %SSBO32 BufferBlock\n"
5003 "OpMemberDecorate %SSBO32 0 Offset 0\n"
5004 "OpDecorate %PC16 BufferBlock\n"
5005 "OpMemberDecorate %PC16 0 Offset 0\n"
5006 "OpDecorate %ssbo32 DescriptorSet 0\n"
5007 "OpDecorate %ssbo32 Binding 0\n");
5010 map<string, string> specs;
5012 specs["base_type16"] = "i16";
5013 specs["type16"] = "v2i16";
5014 specs["type32"] = "v2i32";
5015 specs["signed"] = "1";
5016 specs["count"] = "32";
5017 specs["convert"] = "OpSConvert";
5019 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
5021 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
5022 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
5023 string testName = "sint_vector";
5024 vector<deInt32> constIdxData;
5028 constIdxData.reserve(numDataPoints);
5030 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
5031 constIdxData.push_back(sOutputs[constIdx * 2 + numIdx % 2]);
5034 specs["constarrayidx"] = de::toString(constIdx);
5036 specs["arrayindex"] = "c_i32_ci";
5038 specs["arrayindex"] = "30";
5041 testName += string("_const_idx_") + de::toString(constIdx);
5043 resources.outputs.clear();
5044 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(useConstIdx ? constIdxData : sOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5046 fragments["testfun"] = testFun.specialize(specs);
5047 fragments["pre_main"] = preMain.specialize(specs);
5048 fragments["decoration"] = decoration.specialize(specs);
5050 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
5054 map<string, string> specs;
5056 specs["base_type16"] = "u16";
5057 specs["type16"] = "v2u16";
5058 specs["type32"] = "v2u32";
5059 specs["signed"] = "0";
5060 specs["count"] = "32";
5061 specs["convert"] = "OpUConvert";
5063 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
5065 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
5066 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
5067 string testName = "uint_vector";
5068 vector<deInt32> constIdxData;
5072 constIdxData.reserve(numDataPoints);
5074 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
5075 constIdxData.push_back(uOutputs[constIdx * 2 + numIdx % 2]);
5078 specs["constarrayidx"] = de::toString(constIdx);
5080 specs["arrayindex"] = "c_i32_ci";
5082 specs["arrayindex"] = "30";
5085 testName += string("_const_idx_") + de::toString(constIdx);
5087 resources.outputs.clear();
5088 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(useConstIdx ? constIdxData : uOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5090 fragments["testfun"] = testFun.specialize(specs);
5091 fragments["pre_main"] = preMain.specialize(specs);
5092 fragments["decoration"] = decoration.specialize(specs);
5094 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
5100 void addGraphics16BitStorageUniformInt16To32Group (tcu::TestCaseGroup* testGroup)
5102 de::Random rnd (deStringHash(testGroup->getName()));
5103 map<string, string> fragments;
5104 const deUint32 numDataPoints = 256;
5105 RGBA defaultColors[4];
5106 vector<deInt16> inputs = getInt16s(rnd, numDataPoints);
5107 vector<deInt32> sOutputs;
5108 vector<deInt32> uOutputs;
5109 vector<string> extensions;
5110 const deUint16 signBitMask = 0x8000;
5111 const deUint32 signExtendMask = 0xffff0000;
5112 const StringTemplate capabilities ("OpCapability ${cap}\n");
5114 sOutputs.reserve(inputs.size());
5115 uOutputs.reserve(inputs.size());
5117 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
5119 uOutputs.push_back(static_cast<deUint16>(inputs[numNdx]));
5120 if (inputs[numNdx] & signBitMask)
5121 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx] | signExtendMask));
5123 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx]));
5126 extensions.push_back("VK_KHR_16bit_storage");
5127 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
5129 getDefaultColors(defaultColors);
5140 const IntegerFacts intFacts[] =
5142 {"sint", "%i32", "%i16", "OpSConvert", true},
5143 {"uint", "%u32", "%u16", "OpUConvert", false},
5146 struct ConstantIndex
5148 bool useConstantIndex;
5149 deUint32 constantIndex;
5152 ConstantIndex constantIndices[] =
5160 const StringTemplate scalarPreMain (
5161 "${itype16} = OpTypeInt 16 ${signed}\n"
5162 "%c_i32_256 = OpConstant %i32 256\n"
5163 "%c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
5164 " %up_i32 = OpTypePointer Uniform ${itype32}\n"
5165 " %up_i16 = OpTypePointer Uniform ${itype16}\n"
5166 " %ra_i32 = OpTypeArray ${itype32} %c_i32_256\n"
5167 " %ra_i16 = OpTypeArray ${itype16} %c_i32_256\n"
5168 " %SSBO32 = OpTypeStruct %ra_i32\n"
5169 " %SSBO16 = OpTypeStruct %ra_i16\n"
5170 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
5171 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
5172 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
5173 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n");
5175 const StringTemplate scalarDecoration (
5176 "OpDecorate %ra_i32 ArrayStride 4\n"
5177 "OpDecorate %ra_i16 ArrayStride ${arraystride}\n"
5178 "OpMemberDecorate %SSBO32 0 Offset 0\n"
5179 "OpMemberDecorate %SSBO16 0 Offset 0\n"
5180 "OpDecorate %SSBO32 BufferBlock\n"
5181 "OpDecorate %SSBO16 ${indecor}\n"
5182 "OpDecorate %ssbo32 DescriptorSet 0\n"
5183 "OpDecorate %ssbo16 DescriptorSet 0\n"
5184 "OpDecorate %ssbo32 Binding 1\n"
5185 "OpDecorate %ssbo16 Binding 0\n");
5187 const StringTemplate scalarTestFunc (
5188 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
5189 " %param = OpFunctionParameter %v4f32\n"
5191 "%entry = OpLabel\n"
5192 " %i = OpVariable %fp_i32 Function\n"
5193 " OpStore %i %c_i32_0\n"
5196 " %loop = OpLabel\n"
5197 " %15 = OpLoad %i32 %i\n"
5198 " %lt = OpSLessThan %bool %15 %c_i32_256\n"
5199 " OpLoopMerge %merge %inc None\n"
5200 " OpBranchConditional %lt %write %merge\n"
5202 "%write = OpLabel\n"
5203 " %30 = OpLoad %i32 %i\n"
5204 " %src = OpAccessChain %up_i16 %ssbo16 %c_i32_0 %${arrayindex}\n"
5205 "%val16 = OpLoad ${itype16} %src\n"
5206 "%val32 = ${convert} ${itype32} %val16\n"
5207 " %dst = OpAccessChain %up_i32 %ssbo32 %c_i32_0 %30\n"
5208 " OpStore %dst %val32\n"
5212 " %37 = OpLoad %i32 %i\n"
5213 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
5216 "%merge = OpLabel\n"
5217 " OpReturnValue %param\n"
5221 const StringTemplate vecPreMain (
5222 "${itype16} = OpTypeInt 16 ${signed}\n"
5223 "%c_i32_128 = OpConstant %i32 128\n"
5224 "%c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
5225 "%v2itype16 = OpTypeVector ${itype16} 2\n"
5226 " %up_v2i32 = OpTypePointer Uniform ${v2itype32}\n"
5227 " %up_v2i16 = OpTypePointer Uniform %v2itype16\n"
5228 " %ra_v2i32 = OpTypeArray ${v2itype32} %c_i32_128\n"
5229 " %ra_v2i16 = OpTypeArray %v2itype16 %c_i32_128\n"
5230 " %SSBO32 = OpTypeStruct %ra_v2i32\n"
5231 " %SSBO16 = OpTypeStruct %ra_v2i16\n"
5232 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
5233 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
5234 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
5235 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n");
5237 const StringTemplate vecDecoration (
5238 "OpDecorate %ra_v2i32 ArrayStride 8\n"
5239 "OpDecorate %ra_v2i16 ArrayStride ${arraystride}\n"
5240 "OpMemberDecorate %SSBO32 0 Offset 0\n"
5241 "OpMemberDecorate %SSBO16 0 Offset 0\n"
5242 "OpDecorate %SSBO32 BufferBlock\n"
5243 "OpDecorate %SSBO16 ${indecor}\n"
5244 "OpDecorate %ssbo32 DescriptorSet 0\n"
5245 "OpDecorate %ssbo16 DescriptorSet 0\n"
5246 "OpDecorate %ssbo32 Binding 1\n"
5247 "OpDecorate %ssbo16 Binding 0\n");
5249 const StringTemplate vecTestFunc (
5250 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
5251 " %param = OpFunctionParameter %v4f32\n"
5253 "%entry = OpLabel\n"
5254 " %i = OpVariable %fp_i32 Function\n"
5255 " OpStore %i %c_i32_0\n"
5258 " %loop = OpLabel\n"
5259 " %15 = OpLoad %i32 %i\n"
5260 " %lt = OpSLessThan %bool %15 %c_i32_128\n"
5261 " OpLoopMerge %merge %inc None\n"
5262 " OpBranchConditional %lt %write %merge\n"
5264 "%write = OpLabel\n"
5265 " %30 = OpLoad %i32 %i\n"
5266 " %src = OpAccessChain %up_v2i16 %ssbo16 %c_i32_0 %${arrayindex}\n"
5267 "%val16 = OpLoad %v2itype16 %src\n"
5268 "%val32 = ${convert} ${v2itype32} %val16\n"
5269 " %dst = OpAccessChain %up_v2i32 %ssbo32 %c_i32_0 %30\n"
5270 " OpStore %dst %val32\n"
5274 " %37 = OpLoad %i32 %i\n"
5275 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
5278 "%merge = OpLabel\n"
5279 " OpReturnValue %param\n"
5286 const StringTemplate& preMain;
5287 const StringTemplate& decoration;
5288 const StringTemplate& testFunction;
5289 const deUint32 numElements;
5292 const Category categories[] =
5294 {"scalar", scalarPreMain, scalarDecoration, scalarTestFunc, 1},
5295 {"vector", vecPreMain, vecDecoration, vecTestFunc, 2},
5298 const deUint32 minArrayStride[] = {2, 16};
5300 for (deUint32 catIdx = 0; catIdx < DE_LENGTH_OF_ARRAY(categories); ++catIdx)
5301 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
5302 for (deUint32 factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
5303 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
5305 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
5306 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
5307 map<string, string> specs;
5308 string name = string(CAPABILITIES[capIdx].name) + "_" + categories[catIdx].name + "_" + intFacts[factIdx].name;
5309 const deUint32 numElements = categories[catIdx].numElements;
5310 const deUint32 arrayStride = de::max(numElements * 2, minArrayStride[capIdx]);
5312 specs["cap"] = CAPABILITIES[capIdx].cap;
5313 specs["indecor"] = CAPABILITIES[capIdx].decor;
5314 specs["arraystride"] = de::toString(arrayStride);
5315 specs["itype32"] = intFacts[factIdx].type32;
5316 specs["v2itype32"] = "%v2" + string(intFacts[factIdx].type32).substr(1);
5317 specs["v3itype32"] = "%v3" + string(intFacts[factIdx].type32).substr(1);
5318 specs["itype16"] = intFacts[factIdx].type16;
5319 if (intFacts[factIdx].isSigned)
5320 specs["signed"] = "1";
5322 specs["signed"] = "0";
5323 specs["convert"] = intFacts[factIdx].opcode;
5324 specs["constarrayidx"] = de::toString(constIdx);
5326 specs["arrayindex"] = "c_i32_ci";
5328 specs["arrayindex"] = "30";
5330 fragments["pre_main"] = categories[catIdx].preMain.specialize(specs);
5331 fragments["testfun"] = categories[catIdx].testFunction.specialize(specs);
5332 fragments["capability"] = capabilities.specialize(specs);
5333 fragments["decoration"] = categories[catIdx].decoration.specialize(specs);
5335 GraphicsResources resources;
5336 vector<deInt16> inputsPadded;
5337 for (size_t dataIdx = 0; dataIdx < inputs.size() / numElements; ++dataIdx)
5339 for (deUint32 elementIdx = 0; elementIdx < numElements; ++elementIdx)
5340 inputsPadded.push_back(inputs[dataIdx * numElements + elementIdx]);
5341 for (deUint32 padIdx = 0; padIdx < arrayStride / 2 - numElements; ++padIdx)
5342 inputsPadded.push_back(0);
5345 resources.inputs.push_back(Resource(BufferSp(new Int16Buffer(inputsPadded)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5347 vector<deInt32> constIdxOutputs;
5350 name += string("_const_idx_") + de::toString(constIdx);
5351 for (deUint32 i = 0; i < numDataPoints; i++)
5353 deUint32 idx = constIdx * numElements + i % numElements;
5354 constIdxOutputs.push_back(intFacts[factIdx].isSigned ? sOutputs[idx] : uOutputs[idx]);
5358 resources.inputs.back().setDescriptorType(CAPABILITIES[capIdx].dtype);
5359 resources.outputs.clear();
5361 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(constIdxOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5362 else if (intFacts[factIdx].isSigned)
5363 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(sOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5365 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(uOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5367 createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
5371 void addGraphics16BitStorageUniformFloat16To32Group (tcu::TestCaseGroup* testGroup)
5373 de::Random rnd (deStringHash(testGroup->getName()));
5374 map<string, string> fragments;
5375 vector<string> extensions;
5376 const deUint32 numDataPoints = 256;
5377 RGBA defaultColors[4];
5378 const StringTemplate capabilities ("OpCapability ${cap}\n");
5379 vector<deFloat16> float16Data = getFloat16s(rnd, numDataPoints);
5381 struct ConstantIndex
5383 bool useConstantIndex;
5384 deUint32 constantIndex;
5387 ConstantIndex constantIndices[] =
5395 extensions.push_back("VK_KHR_16bit_storage");
5396 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
5398 getDefaultColors(defaultColors);
5401 const StringTemplate preMain (
5402 " %f16 = OpTypeFloat 16\n"
5403 "%c_i32_256 = OpConstant %i32 256\n"
5404 " %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
5405 " %up_f32 = OpTypePointer Uniform %f32\n"
5406 " %up_f16 = OpTypePointer Uniform %f16\n"
5407 " %ra_f32 = OpTypeArray %f32 %c_i32_256\n"
5408 " %ra_f16 = OpTypeArray %f16 %c_i32_256\n"
5409 " %SSBO32 = OpTypeStruct %ra_f32\n"
5410 " %SSBO16 = OpTypeStruct %ra_f16\n"
5411 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
5412 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
5413 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
5414 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n");
5416 const StringTemplate decoration (
5417 "OpDecorate %ra_f32 ArrayStride 4\n"
5418 "OpDecorate %ra_f16 ArrayStride ${arraystride}\n"
5419 "OpMemberDecorate %SSBO32 0 Offset 0\n"
5420 "OpMemberDecorate %SSBO16 0 Offset 0\n"
5421 "OpDecorate %SSBO32 BufferBlock\n"
5422 "OpDecorate %SSBO16 ${indecor}\n"
5423 "OpDecorate %ssbo32 DescriptorSet 0\n"
5424 "OpDecorate %ssbo16 DescriptorSet 0\n"
5425 "OpDecorate %ssbo32 Binding 1\n"
5426 "OpDecorate %ssbo16 Binding 0\n");
5428 // ssbo32[] <- convert ssbo16[] to 32bit float
5429 const StringTemplate testFun (
5430 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
5431 " %param = OpFunctionParameter %v4f32\n"
5433 "%entry = OpLabel\n"
5434 " %i = OpVariable %fp_i32 Function\n"
5435 " OpStore %i %c_i32_0\n"
5438 " %loop = OpLabel\n"
5439 " %15 = OpLoad %i32 %i\n"
5440 " %lt = OpSLessThan %bool %15 %c_i32_256\n"
5441 " OpLoopMerge %merge %inc None\n"
5442 " OpBranchConditional %lt %write %merge\n"
5444 "%write = OpLabel\n"
5445 " %30 = OpLoad %i32 %i\n"
5446 " %src = OpAccessChain %up_f16 %ssbo16 %c_i32_0 %${arrayindex}\n"
5447 "%val16 = OpLoad %f16 %src\n"
5448 "%val32 = OpFConvert %f32 %val16\n"
5449 " %dst = OpAccessChain %up_f32 %ssbo32 %c_i32_0 %30\n"
5450 " OpStore %dst %val32\n"
5454 " %37 = OpLoad %i32 %i\n"
5455 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
5459 "%merge = OpLabel\n"
5460 " OpReturnValue %param\n"
5464 const deUint32 arrayStrides[] = {2, 16};
5466 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
5468 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
5470 GraphicsResources resources;
5471 map<string, string> specs;
5472 string testName = string(CAPABILITIES[capIdx].name) + "_scalar_float";
5473 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
5474 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
5476 specs["cap"] = CAPABILITIES[capIdx].cap;
5477 specs["indecor"] = CAPABILITIES[capIdx].decor;
5478 specs["arraystride"] = de::toString(arrayStrides[capIdx]);
5479 specs["constarrayidx"] = de::toString(constIdx);
5481 specs["arrayindex"] = "c_i32_ci";
5483 specs["arrayindex"] = "30";
5485 fragments["capability"] = capabilities.specialize(specs);
5486 fragments["decoration"] = decoration.specialize(specs);
5487 fragments["pre_main"] = preMain.specialize(specs);
5488 fragments["testfun"] = testFun.specialize(specs);
5490 vector<deFloat16> inputData;
5491 for (size_t dataIdx = 0; dataIdx < float16Data.size(); ++dataIdx)
5493 inputData.push_back(float16Data[dataIdx]);
5494 for (deUint32 padIdx = 0; padIdx < arrayStrides[capIdx] / 2 - 1; ++padIdx)
5495 inputData.push_back(deFloat16(0.0f));
5498 vector<float> float32Data;
5499 float32Data.reserve(numDataPoints);
5500 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
5501 float32Data.push_back(deFloat16To32(float16Data[useConstIdx ? constIdx : numIdx]));
5503 resources.inputs.push_back(Resource(BufferSp(new Float16Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5504 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(float32Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5505 resources.verifyIO = check32BitFloats;
5506 resources.inputs.back().setDescriptorType(CAPABILITIES[capIdx].dtype);
5509 testName += string("_const_idx_") + de::toString(constIdx);
5511 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
5517 const StringTemplate preMain (
5518 " %f16 = OpTypeFloat 16\n"
5519 "%c_i32_128 = OpConstant %i32 128\n"
5520 "%c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
5521 " %v2f16 = OpTypeVector %f16 2\n"
5522 " %up_v2f32 = OpTypePointer Uniform %v2f32\n"
5523 " %up_v2f16 = OpTypePointer Uniform %v2f16\n"
5524 " %ra_v2f32 = OpTypeArray %v2f32 %c_i32_128\n"
5525 " %ra_v2f16 = OpTypeArray %v2f16 %c_i32_128\n"
5526 " %SSBO32 = OpTypeStruct %ra_v2f32\n"
5527 " %SSBO16 = OpTypeStruct %ra_v2f16\n"
5528 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
5529 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
5530 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
5531 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n");
5533 const StringTemplate decoration (
5534 "OpDecorate %ra_v2f32 ArrayStride 8\n"
5535 "OpDecorate %ra_v2f16 ArrayStride ${arraystride}\n"
5536 "OpMemberDecorate %SSBO32 0 Offset 0\n"
5537 "OpMemberDecorate %SSBO16 0 Offset 0\n"
5538 "OpDecorate %SSBO32 BufferBlock\n"
5539 "OpDecorate %SSBO16 ${indecor}\n"
5540 "OpDecorate %ssbo32 DescriptorSet 0\n"
5541 "OpDecorate %ssbo16 DescriptorSet 0\n"
5542 "OpDecorate %ssbo32 Binding 1\n"
5543 "OpDecorate %ssbo16 Binding 0\n");
5545 // ssbo32[] <- convert ssbo16[] to 32bit float
5546 const StringTemplate testFun (
5547 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
5548 " %param = OpFunctionParameter %v4f32\n"
5550 "%entry = OpLabel\n"
5551 " %i = OpVariable %fp_i32 Function\n"
5552 " OpStore %i %c_i32_0\n"
5555 " %loop = OpLabel\n"
5556 " %15 = OpLoad %i32 %i\n"
5557 " %lt = OpSLessThan %bool %15 %c_i32_128\n"
5558 " OpLoopMerge %merge %inc None\n"
5559 " OpBranchConditional %lt %write %merge\n"
5561 "%write = OpLabel\n"
5562 " %30 = OpLoad %i32 %i\n"
5563 " %src = OpAccessChain %up_v2f16 %ssbo16 %c_i32_0 %${arrayindex}\n"
5564 "%val16 = OpLoad %v2f16 %src\n"
5565 "%val32 = OpFConvert %v2f32 %val16\n"
5566 " %dst = OpAccessChain %up_v2f32 %ssbo32 %c_i32_0 %30\n"
5567 " OpStore %dst %val32\n"
5571 " %37 = OpLoad %i32 %i\n"
5572 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
5576 "%merge = OpLabel\n"
5577 " OpReturnValue %param\n"
5581 const deUint32 arrayStrides[] = {4, 16};
5583 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
5585 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
5587 GraphicsResources resources;
5588 map<string, string> specs;
5589 string testName = string(CAPABILITIES[capIdx].name) + "_vector_float";
5590 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
5591 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
5593 specs["cap"] = CAPABILITIES[capIdx].cap;
5594 specs["indecor"] = CAPABILITIES[capIdx].decor;
5595 specs["arraystride"] = de::toString(arrayStrides[capIdx]);
5596 specs["constarrayidx"] = de::toString(constIdx);
5598 specs["arrayindex"] = "c_i32_ci";
5600 specs["arrayindex"] = "30";
5602 fragments["capability"] = capabilities.specialize(specs);
5603 fragments["decoration"] = decoration.specialize(specs);
5604 fragments["pre_main"] = preMain.specialize(specs);
5605 fragments["testfun"] = testFun.specialize(specs);
5607 vector<deFloat16> inputData;
5608 for (size_t dataIdx = 0; dataIdx < float16Data.size() / 2; ++dataIdx)
5610 inputData.push_back(float16Data[dataIdx * 2]);
5611 inputData.push_back(float16Data[dataIdx * 2 + 1]);
5612 for (deUint32 padIdx = 0; padIdx < arrayStrides[capIdx] / 2 - 2; ++padIdx)
5613 inputData.push_back(deFloat16(0.0f));
5616 vector<float> float32Data;
5617 float32Data.reserve(numDataPoints);
5618 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
5619 float32Data.push_back(deFloat16To32(float16Data[constantIndices[constIndexIdx].useConstantIndex ? (constantIndices[constIndexIdx].constantIndex * 2 + numIdx % 2) : numIdx]));
5621 resources.inputs.push_back(Resource(BufferSp(new Float16Buffer(inputData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5622 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(float32Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5623 resources.verifyIO = check32BitFloats;
5624 resources.inputs.back().setDescriptorType(CAPABILITIES[capIdx].dtype);
5626 if (constantIndices[constIndexIdx].useConstantIndex)
5627 testName += string("_const_idx_") + de::toString(constantIndices[constIndexIdx].constantIndex);
5629 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
5635 fragments["pre_main"] =
5636 " %c_i32_32 = OpConstant %i32 32\n"
5637 " %f16 = OpTypeFloat 16\n"
5638 " %v2f16 = OpTypeVector %f16 2\n"
5639 " %m4x2f32 = OpTypeMatrix %v2f32 4\n"
5640 " %m4x2f16 = OpTypeMatrix %v2f16 4\n"
5641 " %up_v2f32 = OpTypePointer Uniform %v2f32\n"
5642 " %up_v2f16 = OpTypePointer Uniform %v2f16\n"
5643 "%a8m4x2f32 = OpTypeArray %m4x2f32 %c_i32_32\n"
5644 "%a8m4x2f16 = OpTypeArray %m4x2f16 %c_i32_32\n"
5645 " %SSBO32 = OpTypeStruct %a8m4x2f32\n"
5646 " %SSBO16 = OpTypeStruct %a8m4x2f16\n"
5647 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
5648 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
5649 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
5650 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n";
5652 const StringTemplate decoration (
5653 "OpDecorate %a8m4x2f32 ArrayStride 32\n"
5654 "OpDecorate %a8m4x2f16 ArrayStride 16\n"
5655 "OpMemberDecorate %SSBO32 0 Offset 0\n"
5656 "OpMemberDecorate %SSBO32 0 ColMajor\n"
5657 "OpMemberDecorate %SSBO32 0 MatrixStride 8\n"
5658 "OpMemberDecorate %SSBO16 0 Offset 0\n"
5659 "OpMemberDecorate %SSBO16 0 ColMajor\n"
5660 "OpMemberDecorate %SSBO16 0 MatrixStride 4\n"
5661 "OpDecorate %SSBO32 BufferBlock\n"
5662 "OpDecorate %SSBO16 ${indecor}\n"
5663 "OpDecorate %ssbo32 DescriptorSet 0\n"
5664 "OpDecorate %ssbo16 DescriptorSet 0\n"
5665 "OpDecorate %ssbo32 Binding 1\n"
5666 "OpDecorate %ssbo16 Binding 0\n");
5668 fragments["testfun"] =
5669 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
5670 " %param = OpFunctionParameter %v4f32\n"
5672 "%entry = OpLabel\n"
5673 " %i = OpVariable %fp_i32 Function\n"
5674 " OpStore %i %c_i32_0\n"
5677 " %loop = OpLabel\n"
5678 " %15 = OpLoad %i32 %i\n"
5679 " %lt = OpSLessThan %bool %15 %c_i32_32\n"
5680 " OpLoopMerge %merge %inc None\n"
5681 " OpBranchConditional %lt %write %merge\n"
5683 " %write = OpLabel\n"
5684 " %30 = OpLoad %i32 %i\n"
5685 " %src_0 = OpAccessChain %up_v2f16 %ssbo16 %c_i32_0 %30 %c_i32_0\n"
5686 " %src_1 = OpAccessChain %up_v2f16 %ssbo16 %c_i32_0 %30 %c_i32_1\n"
5687 " %src_2 = OpAccessChain %up_v2f16 %ssbo16 %c_i32_0 %30 %c_i32_2\n"
5688 " %src_3 = OpAccessChain %up_v2f16 %ssbo16 %c_i32_0 %30 %c_i32_3\n"
5689 "%val16_0 = OpLoad %v2f16 %src_0\n"
5690 "%val16_1 = OpLoad %v2f16 %src_1\n"
5691 "%val16_2 = OpLoad %v2f16 %src_2\n"
5692 "%val16_3 = OpLoad %v2f16 %src_3\n"
5693 "%val32_0 = OpFConvert %v2f32 %val16_0\n"
5694 "%val32_1 = OpFConvert %v2f32 %val16_1\n"
5695 "%val32_2 = OpFConvert %v2f32 %val16_2\n"
5696 "%val32_3 = OpFConvert %v2f32 %val16_3\n"
5697 " %dst_0 = OpAccessChain %up_v2f32 %ssbo32 %c_i32_0 %30 %c_i32_0\n"
5698 " %dst_1 = OpAccessChain %up_v2f32 %ssbo32 %c_i32_0 %30 %c_i32_1\n"
5699 " %dst_2 = OpAccessChain %up_v2f32 %ssbo32 %c_i32_0 %30 %c_i32_2\n"
5700 " %dst_3 = OpAccessChain %up_v2f32 %ssbo32 %c_i32_0 %30 %c_i32_3\n"
5701 " OpStore %dst_0 %val32_0\n"
5702 " OpStore %dst_1 %val32_1\n"
5703 " OpStore %dst_2 %val32_2\n"
5704 " OpStore %dst_3 %val32_3\n"
5708 " %37 = OpLoad %i32 %i\n"
5709 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
5713 "%merge = OpLabel\n"
5714 " OpReturnValue %param\n"
5718 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
5720 GraphicsResources resources;
5721 map<string, string> specs;
5722 string testName = string(CAPABILITIES[capIdx].name) + "_matrix_float";
5724 specs["cap"] = CAPABILITIES[capIdx].cap;
5725 specs["indecor"] = CAPABILITIES[capIdx].decor;
5727 fragments["capability"] = capabilities.specialize(specs);
5728 fragments["decoration"] = decoration.specialize(specs);
5730 vector<float> float32Data;
5731 float32Data.reserve(numDataPoints);
5732 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
5733 float32Data.push_back(deFloat16To32(float16Data[numIdx]));
5735 resources.inputs.push_back(Resource(BufferSp(new Float16Buffer(float16Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5736 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(float32Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5737 resources.verifyIO = check32BitFloats;
5738 resources.inputs.back().setDescriptorType(CAPABILITIES[capIdx].dtype);
5740 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
5745 void addGraphics16BitStorageUniformStructFloat16To32Group (tcu::TestCaseGroup* testGroup)
5747 de::Random rnd (deStringHash(testGroup->getName()));
5748 map<string, string> fragments;
5749 vector<string> extensions;
5750 RGBA defaultColors[4];
5751 const StringTemplate capabilities ("OpCapability ${cap}\n");
5752 vector<float> float32Data (getStructSize(SHADERTEMPLATE_STRIDE32BIT_STD430), 0.0f);
5754 extensions.push_back("VK_KHR_16bit_storage");
5755 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
5757 getDefaultColors(defaultColors);
5759 const StringTemplate preMain (
5763 "%zero = OpConstant %i32 0\n"
5764 "%c_i32_5 = OpConstant %i32 5\n"
5765 "%c_i32_6 = OpConstant %i32 6\n"
5766 "%c_i32_7 = OpConstant %i32 7\n"
5767 "%c_i32_8 = OpConstant %i32 8\n"
5768 "%c_i32_9 = OpConstant %i32 9\n"
5769 "%c_i32_11 = OpConstant %i32 11\n"
5771 "%c_u32_7 = OpConstant %u32 7\n"
5772 "%c_u32_11 = OpConstant %u32 11\n"
5774 "%f16arr3 = OpTypeArray %f16 %c_u32_3\n"
5775 "%v2f16arr3 = OpTypeArray %v2f16 %c_u32_3\n"
5776 "%v2f16arr11 = OpTypeArray %v2f16 %c_u32_11\n"
5777 "%v3f16arr11 = OpTypeArray %v3f16 %c_u32_11\n"
5778 "%v4f16arr3 = OpTypeArray %v4f16 %c_u32_3\n"
5779 "%struct16 = OpTypeStruct %f16 %v2f16arr3\n"
5780 "%struct16arr11 = OpTypeArray %struct16 %c_u32_11\n"
5781 "%f16Struct = OpTypeStruct %f16 %v2f16 %v3f16 %v4f16 %f16arr3 %struct16arr11 %v2f16arr11 %f16 %v3f16arr11 %v4f16arr3\n"
5783 "%f32arr3 = OpTypeArray %f32 %c_u32_3\n"
5784 "%v2f32arr3 = OpTypeArray %v2f32 %c_u32_3\n"
5785 "%v2f32arr11 = OpTypeArray %v2f32 %c_u32_11\n"
5786 "%v3f32arr11 = OpTypeArray %v3f32 %c_u32_11\n"
5787 "%v4f32arr3 = OpTypeArray %v4f32 %c_u32_3\n"
5788 "%struct32 = OpTypeStruct %f32 %v2f32arr3\n"
5789 "%struct32arr11 = OpTypeArray %struct32 %c_u32_11\n"
5790 "%f32Struct = OpTypeStruct %f32 %v2f32 %v3f32 %v4f32 %f32arr3 %struct32arr11 %v2f32arr11 %f32 %v3f32arr11 %v4f32arr3\n"
5792 "%f16StructArr7 = OpTypeArray %f16Struct %c_u32_7\n"
5793 "%f32StructArr7 = OpTypeArray %f32Struct %c_u32_7\n"
5794 "%SSBO_IN = OpTypeStruct %f16StructArr7\n"
5795 "%SSBO_OUT = OpTypeStruct %f32StructArr7\n"
5796 "%up_SSBOIN = OpTypePointer Uniform %SSBO_IN\n"
5797 "%up_SSBOOUT = OpTypePointer Uniform %SSBO_OUT\n"
5798 "%ssboIN = OpVariable %up_SSBOIN Uniform\n"
5799 "%ssboOUT = OpVariable %up_SSBOOUT Uniform\n"
5802 const StringTemplate decoration (
5807 "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
5808 "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
5809 "OpDecorate %SSBO_IN ${indecor}\n"
5810 "OpDecorate %SSBO_OUT BufferBlock\n"
5811 "OpDecorate %ssboIN DescriptorSet 0\n"
5812 "OpDecorate %ssboOUT DescriptorSet 0\n"
5813 "OpDecorate %ssboIN Binding 0\n"
5814 "OpDecorate %ssboOUT Binding 1\n"
5817 fragments["testfun"] =
5818 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
5819 " %param = OpFunctionParameter %v4f32\n"
5820 "%label = OpLabel\n"
5821 "%loopNdx = OpVariable %fp_i32 Function\n"
5822 "%insideLoopNdx = OpVariable %fp_i32 Function\n"
5824 "OpStore %loopNdx %zero\n"
5827 "OpLoopMerge %merge %13 None\n"
5830 "%valLoopNdx = OpLoad %i32 %loopNdx\n"
5831 "%18 = OpSLessThan %bool %valLoopNdx %c_i32_7\n"
5832 "OpBranchConditional %18 %11 %merge\n"
5835 "%f16src = OpAccessChain %f16ptr %ssboIN %zero %valLoopNdx %zero\n"
5836 "%val_f16 = OpLoad %f16 %f16src\n"
5837 "%val_f32 = OpFConvert %f32 %val_f16\n"
5838 "%f32dst = OpAccessChain %f32ptr %ssboOUT %zero %valLoopNdx %zero\n"
5839 "OpStore %f32dst %val_f32\n"
5841 "%v2f16src = OpAccessChain %v2f16ptr %ssboIN %zero %valLoopNdx %c_i32_1\n"
5842 "%val_v2f16 = OpLoad %v2f16 %v2f16src\n"
5843 "%val_v2f32 = OpFConvert %v2f32 %val_v2f16\n"
5844 "%v2f32dst = OpAccessChain %v2f32ptr %ssboOUT %zero %valLoopNdx %c_i32_1\n"
5845 "OpStore %v2f32dst %val_v2f32\n"
5847 "%v3f16src = OpAccessChain %v3f16ptr %ssboIN %zero %valLoopNdx %c_i32_2\n"
5848 "%val_v3f16 = OpLoad %v3f16 %v3f16src\n"
5849 "%val_v3f32 = OpFConvert %v3f32 %val_v3f16\n"
5850 "%v3f32dst = OpAccessChain %v3f32ptr %ssboOUT %zero %valLoopNdx %c_i32_2\n"
5851 "OpStore %v3f32dst %val_v3f32\n"
5853 "%v4f16src = OpAccessChain %v4f16ptr %ssboIN %zero %valLoopNdx %c_i32_3\n"
5854 "%val_v4f16 = OpLoad %v4f16 %v4f16src\n"
5855 "%val_v4f32 = OpFConvert %v4f32 %val_v4f16\n"
5856 "%v4f32dst = OpAccessChain %v4f32ptr %ssboOUT %zero %valLoopNdx %c_i32_3\n"
5857 "OpStore %v4f32dst %val_v4f32\n"
5859 "%f16src2 = OpAccessChain %f16ptr %ssboIN %zero %valLoopNdx %c_i32_7\n"
5860 "%val2_f16 = OpLoad %f16 %f16src2\n"
5861 "%val2_f32 = OpFConvert %f32 %val2_f16\n"
5862 "%f32dst2 = OpAccessChain %f32ptr %ssboOUT %zero %valLoopNdx %c_i32_7\n"
5863 "OpStore %f32dst2 %val2_f32\n"
5865 "OpStore %insideLoopNdx %zero\n"
5866 "OpBranch %loopInside\n"
5867 "%loopInside = OpLabel\n"
5868 "OpLoopMerge %92 %93 None\n"
5871 "%valInsideLoopNdx = OpLoad %i32 %insideLoopNdx\n"
5872 "%96 = OpSLessThan %bool %valInsideLoopNdx %c_i32_11\n"
5873 "OpBranchConditional %96 %91 %92\n"
5877 "%v2f16src2 = OpAccessChain %v2f16ptr %ssboIN %zero %valLoopNdx %c_i32_6 %valInsideLoopNdx\n"
5878 "%val2_v2f16 = OpLoad %v2f16 %v2f16src2\n"
5879 "%val2_v2f32 = OpFConvert %v2f32 %val2_v2f16\n"
5880 "%v2f32dst2 = OpAccessChain %v2f32ptr %ssboOUT %zero %valLoopNdx %c_i32_6 %valInsideLoopNdx\n"
5881 "OpStore %v2f32dst2 %val2_v2f32\n"
5883 "%v3f16src2 = OpAccessChain %v3f16ptr %ssboIN %zero %valLoopNdx %c_i32_8 %valInsideLoopNdx\n"
5884 "%val2_v3f16 = OpLoad %v3f16 %v3f16src2\n"
5885 "%val2_v3f32 = OpFConvert %v3f32 %val2_v3f16\n"
5886 "%v3f32dst2 = OpAccessChain %v3f32ptr %ssboOUT %zero %valLoopNdx %c_i32_8 %valInsideLoopNdx\n"
5887 "OpStore %v3f32dst2 %val2_v3f32\n"
5889 //struct {f16, v2f16[3]}
5890 "%Sf16src = OpAccessChain %f16ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %zero\n"
5891 "%Sval_f16 = OpLoad %f16 %Sf16src\n"
5892 "%Sval_f32 = OpFConvert %f32 %Sval_f16\n"
5893 "%Sf32dst2 = OpAccessChain %f32ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %zero\n"
5894 "OpStore %Sf32dst2 %Sval_f32\n"
5896 "%Sv2f16src0 = OpAccessChain %v2f16ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %zero\n"
5897 "%Sv2f16_0 = OpLoad %v2f16 %Sv2f16src0\n"
5898 "%Sv2f32_0 = OpFConvert %v2f32 %Sv2f16_0\n"
5899 "%Sv2f32dst_0 = OpAccessChain %v2f32ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %zero\n"
5900 "OpStore %Sv2f32dst_0 %Sv2f32_0\n"
5902 "%Sv2f16src1 = OpAccessChain %v2f16ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_1\n"
5903 "%Sv2f16_1 = OpLoad %v2f16 %Sv2f16src1\n"
5904 "%Sv2f32_1 = OpFConvert %v2f32 %Sv2f16_1\n"
5905 "%Sv2f32dst_1 = OpAccessChain %v2f32ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_1\n"
5906 "OpStore %Sv2f32dst_1 %Sv2f32_1\n"
5908 "%Sv2f16src2 = OpAccessChain %v2f16ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_2\n"
5909 "%Sv2f16_2 = OpLoad %v2f16 %Sv2f16src2\n"
5910 "%Sv2f32_2 = OpFConvert %v2f32 %Sv2f16_2\n"
5911 "%Sv2f32dst_2 = OpAccessChain %v2f32ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_2\n"
5912 "OpStore %Sv2f32dst_2 %Sv2f32_2\n"
5914 //Array with 3 elements
5915 "%LessThan3 = OpSLessThan %bool %valInsideLoopNdx %c_i32_3\n"
5916 "OpSelectionMerge %BlockIf None\n"
5917 "OpBranchConditional %LessThan3 %LabelIf %BlockIf\n"
5918 "%LabelIf = OpLabel\n"
5919 " %f16src3 = OpAccessChain %f16ptr %ssboIN %zero %valLoopNdx %c_i32_4 %valInsideLoopNdx\n"
5920 " %val3_f16 = OpLoad %f16 %f16src3\n"
5921 " %val3_f32 = OpFConvert %f32 %val3_f16\n"
5922 " %f32dst3 = OpAccessChain %f32ptr %ssboOUT %zero %valLoopNdx %c_i32_4 %valInsideLoopNdx\n"
5923 " OpStore %f32dst3 %val3_f32\n"
5925 " %v4f16src2 = OpAccessChain %v4f16ptr %ssboIN %zero %valLoopNdx %c_i32_9 %valInsideLoopNdx\n"
5926 " %val2_v4f16 = OpLoad %v4f16 %v4f16src2\n"
5927 " %val2_v4f32 = OpFConvert %v4f32 %val2_v4f16\n"
5928 " %v4f32dst2 = OpAccessChain %v4f32ptr %ssboOUT %zero %valLoopNdx %c_i32_9 %valInsideLoopNdx\n"
5929 " OpStore %v4f32dst2 %val2_v4f32\n"
5930 "OpBranch %BlockIf\n"
5931 "%BlockIf = OpLabel\n"
5935 "%132 = OpLoad %i32 %insideLoopNdx\n"
5936 "%133 = OpIAdd %i32 %132 %c_i32_1\n"
5937 "OpStore %insideLoopNdx %133\n"
5938 "OpBranch %loopInside\n"
5943 "%134 = OpLoad %i32 %loopNdx\n"
5944 "%135 = OpIAdd %i32 %134 %c_i32_1\n"
5945 "OpStore %loopNdx %135\n"
5948 "%merge = OpLabel\n"
5949 " OpReturnValue %param\n"
5952 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
5954 vector<deFloat16> float16Data = (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == CAPABILITIES[capIdx].dtype) ? data16bitStd430(rnd) : data16bitStd140(rnd);
5955 GraphicsResources resources;
5956 map<string, string> specs;
5957 string testName = string(CAPABILITIES[capIdx].name);
5959 specs["cap"] = CAPABILITIES[capIdx].cap;
5960 specs["indecor"] = CAPABILITIES[capIdx].decor;
5961 specs["strideF16"] = getStructShaderComponet((VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == CAPABILITIES[capIdx].dtype) ? SHADERTEMPLATE_STRIDE16BIT_STD430 : SHADERTEMPLATE_STRIDE16BIT_STD140);
5962 specs["strideF32"] = getStructShaderComponet(SHADERTEMPLATE_STRIDE32BIT_STD430);
5963 specs["types"] = getStructShaderComponet(SHADERTEMPLATE_TYPES);
5965 fragments["capability"] = capabilities.specialize(specs);
5966 fragments["decoration"] = decoration.specialize(specs);
5967 fragments["pre_main"] = preMain.specialize(specs);
5969 resources.inputs.push_back(Resource(BufferSp(new Float16Buffer(float16Data)), CAPABILITIES[capIdx].dtype));
5970 resources.outputs.push_back(Resource(BufferSp(new Float32Buffer(float32Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
5971 resources.verifyIO = (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == CAPABILITIES[capIdx].dtype) ? graphicsCheckStruct<deFloat16, float, SHADERTEMPLATE_STRIDE16BIT_STD430, SHADERTEMPLATE_STRIDE32BIT_STD430> : graphicsCheckStruct<deFloat16, float, SHADERTEMPLATE_STRIDE16BIT_STD140, SHADERTEMPLATE_STRIDE32BIT_STD430>;
5973 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
5977 void addGraphics16BitStorageUniformStructFloat32To16Group (tcu::TestCaseGroup* testGroup)
5979 de::Random rnd (deStringHash(testGroup->getName()));
5980 map<string, string> fragments;
5981 vector<string> extensions;
5982 RGBA defaultColors[4];
5983 const StringTemplate capabilities ("OpCapability ${cap}\n");
5984 vector<deUint16> float16Data (getStructSize(SHADERTEMPLATE_STRIDE16BIT_STD430), 0u);
5986 extensions.push_back("VK_KHR_16bit_storage");
5987 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
5989 getDefaultColors(defaultColors);
5991 const StringTemplate preMain (
5995 "%zero = OpConstant %i32 0\n"
5996 "%c_i32_5 = OpConstant %i32 5\n"
5997 "%c_i32_6 = OpConstant %i32 6\n"
5998 "%c_i32_7 = OpConstant %i32 7\n"
5999 "%c_i32_8 = OpConstant %i32 8\n"
6000 "%c_i32_9 = OpConstant %i32 9\n"
6001 "%c_i32_11 = OpConstant %i32 11\n"
6003 "%c_u32_7 = OpConstant %u32 7\n"
6004 "%c_u32_11 = OpConstant %u32 11\n"
6006 "%f16arr3 = OpTypeArray %f16 %c_u32_3\n"
6007 "%v2f16arr3 = OpTypeArray %v2f16 %c_u32_3\n"
6008 "%v2f16arr11 = OpTypeArray %v2f16 %c_u32_11\n"
6009 "%v3f16arr11 = OpTypeArray %v3f16 %c_u32_11\n"
6010 "%v4f16arr3 = OpTypeArray %v4f16 %c_u32_3\n"
6011 "%struct16 = OpTypeStruct %f16 %v2f16arr3\n"
6012 "%struct16arr11 = OpTypeArray %struct16 %c_u32_11\n"
6013 "%f16Struct = OpTypeStruct %f16 %v2f16 %v3f16 %v4f16 %f16arr3 %struct16arr11 %v2f16arr11 %f16 %v3f16arr11 %v4f16arr3\n"
6015 "%f32arr3 = OpTypeArray %f32 %c_u32_3\n"
6016 "%v2f32arr3 = OpTypeArray %v2f32 %c_u32_3\n"
6017 "%v2f32arr11 = OpTypeArray %v2f32 %c_u32_11\n"
6018 "%v3f32arr11 = OpTypeArray %v3f32 %c_u32_11\n"
6019 "%v4f32arr3 = OpTypeArray %v4f32 %c_u32_3\n"
6020 "%struct32 = OpTypeStruct %f32 %v2f32arr3\n"
6021 "%struct32arr11 = OpTypeArray %struct32 %c_u32_11\n"
6022 "%f32Struct = OpTypeStruct %f32 %v2f32 %v3f32 %v4f32 %f32arr3 %struct32arr11 %v2f32arr11 %f32 %v3f32arr11 %v4f32arr3\n"
6024 "%f16StructArr7 = OpTypeArray %f16Struct %c_u32_7\n"
6025 "%f32StructArr7 = OpTypeArray %f32Struct %c_u32_7\n"
6026 "%SSBO_IN = OpTypeStruct %f32StructArr7\n"
6027 "%SSBO_OUT = OpTypeStruct %f16StructArr7\n"
6028 "%up_SSBOIN = OpTypePointer Uniform %SSBO_IN\n"
6029 "%up_SSBOOUT = OpTypePointer Uniform %SSBO_OUT\n"
6030 "%ssboIN = OpVariable %up_SSBOIN Uniform\n"
6031 "%ssboOUT = OpVariable %up_SSBOOUT Uniform\n"
6034 const StringTemplate decoration (
6039 "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
6040 "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
6041 "OpDecorate %SSBO_IN ${indecor}\n"
6042 "OpDecorate %SSBO_OUT BufferBlock\n"
6043 "OpDecorate %ssboIN DescriptorSet 0\n"
6044 "OpDecorate %ssboOUT DescriptorSet 0\n"
6045 "OpDecorate %ssboIN Binding 0\n"
6046 "OpDecorate %ssboOUT Binding 1\n"
6049 fragments["testfun"] =
6050 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
6051 "%param = OpFunctionParameter %v4f32\n"
6052 "%label = OpLabel\n"
6053 "%loopNdx = OpVariable %fp_i32 Function\n"
6054 "%insideLoopNdx = OpVariable %fp_i32 Function\n"
6056 "OpStore %loopNdx %zero\n"
6059 "OpLoopMerge %merge %13 None\n"
6062 "%valLoopNdx = OpLoad %i32 %loopNdx\n"
6063 "%18 = OpSLessThan %bool %valLoopNdx %c_i32_7\n"
6064 "OpBranchConditional %18 %11 %merge\n"
6067 "%f32src = OpAccessChain %f32ptr %ssboIN %zero %valLoopNdx %zero\n"
6068 "%val_f32 = OpLoad %f32 %f32src\n"
6069 "%val_f16 = OpFConvert %f16 %val_f32\n"
6070 "%f16dst = OpAccessChain %f16ptr %ssboOUT %zero %valLoopNdx %zero\n"
6071 "OpStore %f16dst %val_f16\n"
6073 "%v2f32src = OpAccessChain %v2f32ptr %ssboIN %zero %valLoopNdx %c_i32_1\n"
6074 "%val_v2f32 = OpLoad %v2f32 %v2f32src\n"
6075 "%val_v2f16 = OpFConvert %v2f16 %val_v2f32\n"
6076 "%v2f16dst = OpAccessChain %v2f16ptr %ssboOUT %zero %valLoopNdx %c_i32_1\n"
6077 "OpStore %v2f16dst %val_v2f16\n"
6079 "%v3f32src = OpAccessChain %v3f32ptr %ssboIN %zero %valLoopNdx %c_i32_2\n"
6080 "%val_v3f32 = OpLoad %v3f32 %v3f32src\n"
6081 "%val_v3f16 = OpFConvert %v3f16 %val_v3f32\n"
6082 "%v3f16dst = OpAccessChain %v3f16ptr %ssboOUT %zero %valLoopNdx %c_i32_2\n"
6083 "OpStore %v3f16dst %val_v3f16\n"
6085 "%v4f32src = OpAccessChain %v4f32ptr %ssboIN %zero %valLoopNdx %c_i32_3\n"
6086 "%val_v4f32 = OpLoad %v4f32 %v4f32src\n"
6087 "%val_v4f16 = OpFConvert %v4f16 %val_v4f32\n"
6088 "%v4f16dst = OpAccessChain %v4f16ptr %ssboOUT %zero %valLoopNdx %c_i32_3\n"
6089 "OpStore %v4f16dst %val_v4f16\n"
6091 "%f32src2 = OpAccessChain %f32ptr %ssboIN %zero %valLoopNdx %c_i32_7\n"
6092 "%val2_f32 = OpLoad %f32 %f32src2\n"
6093 "%val2_f16 = OpFConvert %f16 %val2_f32\n"
6094 "%f16dst2 = OpAccessChain %f16ptr %ssboOUT %zero %valLoopNdx %c_i32_7\n"
6095 "OpStore %f16dst2 %val2_f16\n"
6097 "OpStore %insideLoopNdx %zero\n"
6098 "OpBranch %loopInside\n"
6099 "%loopInside = OpLabel\n"
6100 "OpLoopMerge %92 %93 None\n"
6103 "%valInsideLoopNdx = OpLoad %i32 %insideLoopNdx\n"
6104 "%96 = OpSLessThan %bool %valInsideLoopNdx %c_i32_11\n"
6105 "OpBranchConditional %96 %91 %92\n"
6109 //struct {f16, v2f16[3]}
6110 "%Sf32src = OpAccessChain %f32ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %zero\n"
6111 "%Sval_f32 = OpLoad %f32 %Sf32src\n"
6112 "%Sval_f16 = OpFConvert %f16 %Sval_f32\n"
6113 "%Sf16dst2 = OpAccessChain %f16ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %zero\n"
6114 "OpStore %Sf16dst2 %Sval_f16\n"
6116 "%Sv2f32src0 = OpAccessChain %v2f32ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %zero\n"
6117 "%Sv2f32_0 = OpLoad %v2f32 %Sv2f32src0\n"
6118 "%Sv2f16_0 = OpFConvert %v2f16 %Sv2f32_0\n"
6119 "%Sv2f16dst_0 = OpAccessChain %v2f16ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %zero\n"
6120 "OpStore %Sv2f16dst_0 %Sv2f16_0\n"
6122 "%Sv2f32src1 = OpAccessChain %v2f32ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_1\n"
6123 "%Sv2f32_1 = OpLoad %v2f32 %Sv2f32src1\n"
6124 "%Sv2f16_1 = OpFConvert %v2f16 %Sv2f32_1\n"
6125 "%Sv2f16dst_1 = OpAccessChain %v2f16ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_1\n"
6126 "OpStore %Sv2f16dst_1 %Sv2f16_1\n"
6128 "%Sv2f32src2 = OpAccessChain %v2f32ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_2\n"
6129 "%Sv2f32_2 = OpLoad %v2f32 %Sv2f32src2\n"
6130 "%Sv2f16_2 = OpFConvert %v2f16 %Sv2f32_2\n"
6131 "%Sv2f16dst_2 = OpAccessChain %v2f16ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_2\n"
6132 "OpStore %Sv2f16dst_2 %Sv2f16_2\n"
6135 "%v2f32src2 = OpAccessChain %v2f32ptr %ssboIN %zero %valLoopNdx %c_i32_6 %valInsideLoopNdx\n"
6136 "%val2_v2f32 = OpLoad %v2f32 %v2f32src2\n"
6137 "%val2_v2f16 = OpFConvert %v2f16 %val2_v2f32\n"
6138 "%v2f16dst2 = OpAccessChain %v2f16ptr %ssboOUT %zero %valLoopNdx %c_i32_6 %valInsideLoopNdx\n"
6139 "OpStore %v2f16dst2 %val2_v2f16\n"
6141 "%v3f32src2 = OpAccessChain %v3f32ptr %ssboIN %zero %valLoopNdx %c_i32_8 %valInsideLoopNdx\n"
6142 "%val2_v3f32 = OpLoad %v3f32 %v3f32src2\n"
6143 "%val2_v3f16 = OpFConvert %v3f16 %val2_v3f32\n"
6144 "%v3f16dst2 = OpAccessChain %v3f16ptr %ssboOUT %zero %valLoopNdx %c_i32_8 %valInsideLoopNdx\n"
6145 "OpStore %v3f16dst2 %val2_v3f16\n"
6148 //Array with 3 elements
6149 "%LessThan3 = OpSLessThan %bool %valInsideLoopNdx %c_i32_3\n"
6150 "OpSelectionMerge %BlockIf None\n"
6151 "OpBranchConditional %LessThan3 %LabelIf %BlockIf\n"
6152 " %LabelIf = OpLabel\n"
6153 " %f32src3 = OpAccessChain %f32ptr %ssboIN %zero %valLoopNdx %c_i32_4 %valInsideLoopNdx\n"
6154 " %val3_f32 = OpLoad %f32 %f32src3\n"
6155 " %val3_f16 = OpFConvert %f16 %val3_f32\n"
6156 " %f16dst3 = OpAccessChain %f16ptr %ssboOUT %zero %valLoopNdx %c_i32_4 %valInsideLoopNdx\n"
6157 " OpStore %f16dst3 %val3_f16\n"
6159 " %v4f32src2 = OpAccessChain %v4f32ptr %ssboIN %zero %valLoopNdx %c_i32_9 %valInsideLoopNdx\n"
6160 " %val2_v4f32 = OpLoad %v4f32 %v4f32src2\n"
6161 " %val2_v4f16 = OpFConvert %v4f16 %val2_v4f32\n"
6162 " %v4f16dst2 = OpAccessChain %v4f16ptr %ssboOUT %zero %valLoopNdx %c_i32_9 %valInsideLoopNdx\n"
6163 " OpStore %v4f16dst2 %val2_v4f16\n"
6164 "OpBranch %BlockIf\n"
6165 "%BlockIf = OpLabel\n"
6169 "%132 = OpLoad %i32 %insideLoopNdx\n"
6170 "%133 = OpIAdd %i32 %132 %c_i32_1\n"
6171 "OpStore %insideLoopNdx %133\n"
6172 "OpBranch %loopInside\n"
6177 "%134 = OpLoad %i32 %loopNdx\n"
6178 "%135 = OpIAdd %i32 %134 %c_i32_1\n"
6179 "OpStore %loopNdx %135\n"
6182 "%merge = OpLabel\n"
6183 " OpReturnValue %param\n"
6186 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
6188 map<string, string> specs;
6189 string testName = string(CAPABILITIES[capIdx].name);
6190 vector<float> float32Data = (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == CAPABILITIES[capIdx].dtype) ? data32bitStd430(rnd) : data32bitStd140(rnd);
6191 GraphicsResources resources;
6193 specs["cap"] = "StorageUniformBufferBlock16";
6194 specs["indecor"] = CAPABILITIES[capIdx].decor;
6195 specs["strideF16"] = getStructShaderComponet(SHADERTEMPLATE_STRIDE16BIT_STD430);
6196 specs["strideF32"] = getStructShaderComponet((VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == CAPABILITIES[capIdx].dtype) ? SHADERTEMPLATE_STRIDE32BIT_STD430 : SHADERTEMPLATE_STRIDE32BIT_STD140);
6197 specs["types"] = getStructShaderComponet(SHADERTEMPLATE_TYPES);
6199 fragments["capability"] = capabilities.specialize(specs);
6200 fragments["decoration"] = decoration.specialize(specs);
6201 fragments["pre_main"] = preMain.specialize(specs);
6203 resources.inputs.push_back(Resource(BufferSp(new Float32Buffer(float32Data)), CAPABILITIES[capIdx].dtype));
6204 resources.outputs.push_back(Resource(BufferSp(new Float16Buffer(float16Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
6205 resources.verifyIO = (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER == CAPABILITIES[capIdx].dtype) ? graphicsCheckStruct<float, deFloat16, SHADERTEMPLATE_STRIDE32BIT_STD430, SHADERTEMPLATE_STRIDE16BIT_STD430> : graphicsCheckStruct<float, deFloat16, SHADERTEMPLATE_STRIDE32BIT_STD140, SHADERTEMPLATE_STRIDE16BIT_STD430>;
6207 VulkanFeatures features;
6208 features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
6210 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, features);
6214 void addGraphics16bitStructMixedTypesGroup (tcu::TestCaseGroup* group)
6216 de::Random rnd (deStringHash(group->getName()));
6217 map<string, string> fragments;
6218 vector<string> extensions;
6219 RGBA defaultColors[4];
6220 const StringTemplate capabilities ("OpCapability StorageUniformBufferBlock16\n"
6222 vector<deInt16> outData (getStructSize(SHADERTEMPLATE_STRIDEMIX_STD430), 0u);
6224 extensions.push_back("VK_KHR_16bit_storage");
6225 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
6227 getDefaultColors(defaultColors);
6229 const StringTemplate preMain (
6231 "%i16 = OpTypeInt 16 1\n"
6232 "%v2i16 = OpTypeVector %i16 2\n"
6233 "%v3i16 = OpTypeVector %i16 3\n"
6234 "%v4i16 = OpTypeVector %i16 4\n"
6236 "%zero = OpConstant %i32 0\n"
6237 "%c_i32_5 = OpConstant %i32 5\n"
6238 "%c_i32_6 = OpConstant %i32 6\n"
6239 "%c_i32_7 = OpConstant %i32 7\n"
6240 "%c_i32_8 = OpConstant %i32 8\n"
6241 "%c_i32_9 = OpConstant %i32 9\n"
6242 "%c_i32_10 = OpConstant %i32 10\n"
6243 "%c_i32_11 = OpConstant %i32 11\n"
6244 "%c_u32_7 = OpConstant %u32 7\n"
6245 "%c_u32_11 = OpConstant %u32 11\n"
6246 "\n"//Arrays & Structs
6247 "%v2b16NestedArr11In = OpTypeArray %v2i16 %c_u32_11\n"
6248 "%b32NestedArr11In = OpTypeArray %i32 %c_u32_11\n"
6249 "%sb16Arr11In = OpTypeArray %i16 %c_u32_11\n"
6250 "%sb32Arr11In = OpTypeArray %i32 %c_u32_11\n"
6251 "%sNestedIn = OpTypeStruct %i16 %i32 %v2b16NestedArr11In %b32NestedArr11In\n"
6252 "%sNestedArr11In = OpTypeArray %sNestedIn %c_u32_11\n"
6253 "%structIn = OpTypeStruct %i16 %i32 %v2i16 %v2i32 %v3i16 %v3i32 %v4i16 %v4i32 %sNestedArr11In %sb16Arr11In %sb32Arr11In\n"
6254 "%structArr7In = OpTypeArray %structIn %c_u32_7\n"
6255 "%v2b16NestedArr11Out = OpTypeArray %v2i16 %c_u32_11\n"
6256 "%b32NestedArr11Out = OpTypeArray %i32 %c_u32_11\n"
6257 "%sb16Arr11Out = OpTypeArray %i16 %c_u32_11\n"
6258 "%sb32Arr11Out = OpTypeArray %i32 %c_u32_11\n"
6259 "%sNestedOut = OpTypeStruct %i16 %i32 %v2b16NestedArr11Out %b32NestedArr11Out\n"
6260 "%sNestedArr11Out = OpTypeArray %sNestedOut %c_u32_11\n"
6261 "%structOut = OpTypeStruct %i16 %i32 %v2i16 %v2i32 %v3i16 %v3i32 %v4i16 %v4i32 %sNestedArr11Out %sb16Arr11Out %sb32Arr11Out\n"
6262 "%structArr7Out = OpTypeArray %structOut %c_u32_7\n"
6264 "%i16outPtr = OpTypePointer Uniform %i16\n"
6265 "%v2i16outPtr = OpTypePointer Uniform %v2i16\n"
6266 "%v3i16outPtr = OpTypePointer Uniform %v3i16\n"
6267 "%v4i16outPtr = OpTypePointer Uniform %v4i16\n"
6268 "%i32outPtr = OpTypePointer Uniform %i32\n"
6269 "%v2i32outPtr = OpTypePointer Uniform %v2i32\n"
6270 "%v3i32outPtr = OpTypePointer Uniform %v3i32\n"
6271 "%v4i32outPtr = OpTypePointer Uniform %v4i32\n"
6272 "%uvec3ptr = OpTypePointer Input %v3u32\n"
6274 "%SSBO_IN = OpTypeStruct %structArr7In\n"
6275 "%up_SSBOIN = OpTypePointer Uniform %SSBO_IN\n"
6276 "%ssboIN = OpVariable %up_SSBOIN Uniform\n"
6278 "%SSBO_OUT = OpTypeStruct %structArr7Out\n"
6279 "%up_SSBOOUT = OpTypePointer Uniform %SSBO_OUT\n"
6280 "%ssboOUT = OpVariable %up_SSBOOUT Uniform\n");
6282 const StringTemplate decoration (
6286 "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
6287 "OpDecorate %ssboIN DescriptorSet 0\n"
6288 "OpDecorate %SSBO_IN ${storage}\n"
6289 "OpDecorate %SSBO_OUT BufferBlock\n"
6290 "OpDecorate %ssboIN Binding 0\n"
6292 "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
6293 "OpDecorate %ssboOUT DescriptorSet 0\n"
6294 "OpDecorate %ssboOUT Binding 1\n");
6296 const StringTemplate testFun (
6297 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
6298 "%param = OpFunctionParameter %v4f32\n"
6299 "%label = OpLabel\n"
6300 "%ndxArrx = OpVariable %fp_i32 Function\n"
6301 "%ndxArry = OpVariable %fp_i32 Function\n"
6302 "%ndxArrz = OpVariable %fp_i32 Function\n"
6304 "\n"//strutOut.b16 = strutIn.b16
6305 "%inP1 = OpAccessChain %i16${inPtr} %ssboIN %zero %Valx %zero\n"
6306 "%inV1 = OpLoad %i16 %inP1\n"
6307 "%outP1 = OpAccessChain %i16outPtr %ssboOUT %zero %Valx %zero\n"
6308 "OpStore %outP1 %inV1\n"
6309 "\n"//strutOut.b32 = strutIn.b32
6310 "%inP2 = OpAccessChain %i32${inPtr} %ssboIN %zero %Valx %c_i32_1\n"
6311 "%inV2 = OpLoad %i32 %inP2\n"
6312 "%outP2 = OpAccessChain %i32outPtr %ssboOUT %zero %Valx %c_i32_1\n"
6313 "OpStore %outP2 %inV2\n"
6314 "\n"//strutOut.v2b16 = strutIn.v2b16
6315 "%inP3 = OpAccessChain %v2i16${inPtr} %ssboIN %zero %Valx %c_i32_2\n"
6316 "%inV3 = OpLoad %v2i16 %inP3\n"
6317 "%outP3 = OpAccessChain %v2i16outPtr %ssboOUT %zero %Valx %c_i32_2\n"
6318 "OpStore %outP3 %inV3\n"
6319 "\n"//strutOut.v2b32 = strutIn.v2b32
6320 "%inP4 = OpAccessChain %v2i32${inPtr} %ssboIN %zero %Valx %c_i32_3\n"
6321 "%inV4 = OpLoad %v2i32 %inP4\n"
6322 "%outP4 = OpAccessChain %v2i32outPtr %ssboOUT %zero %Valx %c_i32_3\n"
6323 "OpStore %outP4 %inV4\n"
6324 "\n"//strutOut.v3b16 = strutIn.v3b16
6325 "%inP5 = OpAccessChain %v3i16${inPtr} %ssboIN %zero %Valx %c_i32_4\n"
6326 "%inV5 = OpLoad %v3i16 %inP5\n"
6327 "%outP5 = OpAccessChain %v3i16outPtr %ssboOUT %zero %Valx %c_i32_4\n"
6328 "OpStore %outP5 %inV5\n"
6329 "\n"//strutOut.v3b32 = strutIn.v3b32
6330 "%inP6 = OpAccessChain %v3i32${inPtr} %ssboIN %zero %Valx %c_i32_5\n"
6331 "%inV6 = OpLoad %v3i32 %inP6\n"
6332 "%outP6 = OpAccessChain %v3i32outPtr %ssboOUT %zero %Valx %c_i32_5\n"
6333 "OpStore %outP6 %inV6\n"
6334 "\n"//strutOut.v4b16 = strutIn.v4b16
6335 "%inP7 = OpAccessChain %v4i16${inPtr} %ssboIN %zero %Valx %c_i32_6\n"
6336 "%inV7 = OpLoad %v4i16 %inP7\n"
6337 "%outP7 = OpAccessChain %v4i16outPtr %ssboOUT %zero %Valx %c_i32_6\n"
6338 "OpStore %outP7 %inV7\n"
6339 "\n"//strutOut.v4b32 = strutIn.v4b32
6340 "%inP8 = OpAccessChain %v4i32${inPtr} %ssboIN %zero %Valx %c_i32_7\n"
6341 "%inV8 = OpLoad %v4i32 %inP8\n"
6342 "%outP8 = OpAccessChain %v4i32outPtr %ssboOUT %zero %Valx %c_i32_7\n"
6343 "OpStore %outP8 %inV8\n"
6345 "\n"//strutOut.b16[y] = strutIn.b16[y]
6346 "%inP9 = OpAccessChain %i16${inPtr} %ssboIN %zero %Valx %c_i32_9 %Valy\n"
6347 "%inV9 = OpLoad %i16 %inP9\n"
6348 "%outP9 = OpAccessChain %i16outPtr %ssboOUT %zero %Valx %c_i32_9 %Valy\n"
6349 "OpStore %outP9 %inV9\n"
6350 "\n"//strutOut.b32[y] = strutIn.b32[y]
6351 "%inP10 = OpAccessChain %i32${inPtr} %ssboIN %zero %Valx %c_i32_10 %Valy\n"
6352 "%inV10 = OpLoad %i32 %inP10\n"
6353 "%outP10 = OpAccessChain %i32outPtr %ssboOUT %zero %Valx %c_i32_10 %Valy\n"
6354 "OpStore %outP10 %inV10\n"
6355 "\n"//strutOut.strutNestedOut[y].b16 = strutIn.strutNestedIn[y].b16
6356 "%inP11 = OpAccessChain %i16${inPtr} %ssboIN %zero %Valx %c_i32_8 %Valy %zero\n"
6357 "%inV11 = OpLoad %i16 %inP11\n"
6358 "%outP11 = OpAccessChain %i16outPtr %ssboOUT %zero %Valx %c_i32_8 %Valy %zero\n"
6359 "OpStore %outP11 %inV11\n"
6360 "\n"//strutOut.strutNestedOut[y].b32 = strutIn.strutNestedIn[y].b32
6361 "%inP12 = OpAccessChain %i32${inPtr} %ssboIN %zero %Valx %c_i32_8 %Valy %c_i32_1\n"
6362 "%inV12 = OpLoad %i32 %inP12\n"
6363 "%outP12 = OpAccessChain %i32outPtr %ssboOUT %zero %Valx %c_i32_8 %Valy %c_i32_1\n"
6364 "OpStore %outP12 %inV12\n"
6366 "\n"//strutOut.strutNestedOut[y].v2b16[valNdx] = strutIn.strutNestedIn[y].v2b16[valNdx]
6367 "%inP13 = OpAccessChain %v2i16${inPtr} %ssboIN %zero %Valx %c_i32_8 %Valy %c_i32_2 %Valz\n"
6368 "%inV13 = OpLoad %v2i16 %inP13\n"
6369 "%outP13 = OpAccessChain %v2i16outPtr %ssboOUT %zero %Valx %c_i32_8 %Valy %c_i32_2 %Valz\n"
6370 "OpStore %outP13 %inV13\n"
6371 "\n"//strutOut.strutNestedOut[y].b32[valNdx] = strutIn.strutNestedIn[y].b32[valNdx]
6372 "%inP14 = OpAccessChain %i32${inPtr} %ssboIN %zero %Valx %c_i32_8 %Valy %c_i32_3 %Valz\n"
6373 "%inV14 = OpLoad %i32 %inP14\n"
6374 "%outP14 = OpAccessChain %i32outPtr %ssboOUT %zero %Valx %c_i32_8 %Valy %c_i32_3 %Valz\n"
6375 "OpStore %outP14 %inV14\n"
6380 "OpBranch %ExitLabel\n"
6381 "%ExitLabel = OpLabel\n"
6382 "OpReturnValue %param\n"
6385 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
6387 const bool isUniform = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == CAPABILITIES[capIdx].dtype;
6388 vector<deInt16> inData = isUniform ? dataMixStd140(rnd) : dataMixStd430(rnd);
6389 GraphicsResources resources;
6390 map<string, string> specsLoop;
6391 map<string, string> specsOffset;
6392 map<string, string> specs;
6393 string testName = string(CAPABILITIES[capIdx].name);
6395 specsLoop["exeCount"] = "c_i32_7";
6396 specsLoop["loopName"] = "x";
6397 specs["xBeginLoop"] = beginLoop(specsLoop);
6398 specs["xEndLoop"] = endLoop(specsLoop);
6400 specsLoop["exeCount"] = "c_i32_11";
6401 specsLoop["loopName"] = "y";
6402 specs["yBeginLoop"] = beginLoop(specsLoop);
6403 specs["yEndLoop"] = endLoop(specsLoop);
6405 specsLoop["exeCount"] = "c_i32_11";
6406 specsLoop["loopName"] = "z";
6407 specs["zBeginLoop"] = beginLoop(specsLoop);
6408 specs["zEndLoop"] = endLoop(specsLoop);
6410 specs["storage"] = isUniform ? "Block" : "BufferBlock";
6411 specs["cap"] = isUniform ?"OpCapability " + string( CAPABILITIES[capIdx].cap) : "";
6412 specs["inPtr"] = "outPtr";
6413 specsOffset["InOut"] = "In";
6414 specs["InOffsets"] = StringTemplate(isUniform ? getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD140) : getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD430)).specialize(specsOffset);
6415 specsOffset["InOut"] = "Out";
6416 specs["OutOffsets"] = StringTemplate(getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD430)).specialize(specsOffset);
6418 fragments["capability"] = capabilities.specialize(specs);
6419 fragments["decoration"] = decoration.specialize(specs);
6420 fragments["pre_main"] = preMain.specialize(specs);
6421 fragments["testfun"] = testFun.specialize(specs);
6423 resources.verifyIO = isUniform ? graphicsCheckStruct<deInt16, deInt16, SHADERTEMPLATE_STRIDEMIX_STD140, SHADERTEMPLATE_STRIDEMIX_STD430> : graphicsCheckStruct<deInt16, deInt16, SHADERTEMPLATE_STRIDEMIX_STD430, SHADERTEMPLATE_STRIDEMIX_STD430>;
6424 resources.inputs.push_back(Resource(BufferSp(new Int16Buffer(inData)), CAPABILITIES[capIdx].dtype));
6425 resources.outputs.push_back(Resource(BufferSp(new Int16Buffer(outData)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
6427 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, group, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
6433 tcu::TestCaseGroup* create16BitStorageComputeGroup (tcu::TestContext& testCtx)
6435 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "16bit_storage", "Compute tests for VK_KHR_16bit_storage extension"));
6436 addTestGroup(group.get(), "uniform_32_to_16", "32bit floats/ints to 16bit tests under capability StorageUniform{|BufferBlock}", addCompute16bitStorageUniform32To16Group);
6437 addTestGroup(group.get(), "uniform_16_to_32", "16bit floats/ints to 32bit tests under capability StorageUniform{|BufferBlock}", addCompute16bitStorageUniform16To32Group);
6438 addTestGroup(group.get(), "push_constant_16_to_32", "16bit floats/ints to 32bit tests under capability StoragePushConstant16", addCompute16bitStoragePushConstant16To32Group);
6439 addTestGroup(group.get(), "uniform_16struct_to_32struct", "16bit floats struct to 32bit tests under capability StorageUniform{|BufferBlock}", addCompute16bitStorageUniform16StructTo32StructGroup);
6440 addTestGroup(group.get(), "uniform_32struct_to_16struct", "32bit floats struct to 16bit tests under capability StorageUniform{|BufferBlock}", addCompute16bitStorageUniform32StructTo16StructGroup);
6441 addTestGroup(group.get(), "struct_mixed_types", "mixed type of 8bit and 32bit struct", addCompute16bitStructMixedTypesGroup);
6442 addTestGroup(group.get(), "uniform_16_to_16", "16bit floats/ints to 16bit tests under capability StorageUniformBufferBlock16", addCompute16bitStorageUniform16To16Group);
6443 addTestGroup(group.get(), "uniform_16_to_32_chainaccess", "chain access 16bit floats/ints to 32bit tests under capability StorageUniform{|BufferBlock}", addCompute16bitStorageUniform16To32ChainAccessGroup);
6445 return group.release();
6448 tcu::TestCaseGroup* create16BitStorageGraphicsGroup (tcu::TestContext& testCtx)
6450 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "16bit_storage", "Graphics tests for VK_KHR_16bit_storage extension"));
6452 addTestGroup(group.get(), "uniform_float_32_to_16", "32-bit floats into 16-bit tests under capability StorageUniform{|BufferBlock}16", addGraphics16BitStorageUniformFloat32To16Group);
6453 addTestGroup(group.get(), "uniform_float_16_to_32", "16-bit floats into 32-bit testsunder capability StorageUniform{|BufferBlock}16", addGraphics16BitStorageUniformFloat16To32Group);
6454 addTestGroup(group.get(), "uniform_int_32_to_16", "32-bit int into 16-bit tests under capability StorageUniform{|BufferBlock}16", addGraphics16BitStorageUniformInt32To16Group);
6455 addTestGroup(group.get(), "uniform_int_16_to_32", "16-bit int into 32-bit tests under capability StorageUniform{|BufferBlock}16", addGraphics16BitStorageUniformInt16To32Group);
6456 addTestGroup(group.get(), "input_output_float_32_to_16", "32-bit floats into 16-bit tests under capability StorageInputOutput16", addGraphics16BitStorageInputOutputFloat32To16Group);
6457 addTestGroup(group.get(), "input_output_float_16_to_32", "16-bit floats into 32-bit tests under capability StorageInputOutput16", addGraphics16BitStorageInputOutputFloat16To32Group);
6458 addTestGroup(group.get(), "input_output_float_16_to_16", "16-bit floats pass-through tests under capability StorageInputOutput16", addGraphics16BitStorageInputOutputFloat16To16Group);
6459 addTestGroup(group.get(), "input_output_int_32_to_16", "32-bit int into 16-bit tests under capability StorageInputOutput16", addGraphics16BitStorageInputOutputInt32To16Group);
6460 addTestGroup(group.get(), "input_output_int_16_to_32", "16-bit int into 32-bit tests under capability StorageInputOutput16", addGraphics16BitStorageInputOutputInt16To32Group);
6461 addTestGroup(group.get(), "input_output_int_16_to_16", "16-bit int into 16-bit tests under capability StorageInputOutput16", addGraphics16BitStorageInputOutputInt16To16Group);
6462 addTestGroup(group.get(), "push_constant_float_16_to_32", "16-bit floats into 32-bit tests under capability StoragePushConstant16", addGraphics16BitStoragePushConstantFloat16To32Group);
6463 addTestGroup(group.get(), "push_constant_int_16_to_32", "16-bit int into 32-bit tests under capability StoragePushConstant16", addGraphics16BitStoragePushConstantInt16To32Group);
6464 addTestGroup(group.get(), "uniform_16struct_to_32struct", "16-bit float struct into 32-bit tests under capability StorageUniform{|BufferBlock}16", addGraphics16BitStorageUniformStructFloat16To32Group);
6465 addTestGroup(group.get(), "uniform_32struct_to_16struct", "32-bit float struct into 16-bit tests under capability StorageUniform{|BufferBlock}16", addGraphics16BitStorageUniformStructFloat32To16Group);
6466 addTestGroup(group.get(), "struct_mixed_types", "mixed type of 8bit and 32bit struct", addGraphics16bitStructMixedTypesGroup);
6468 return group.release();