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 OpAccessChain with subword types
29 // * For newly enabled types T:
30 // * For composite types: vector, matrix, structures, array over T:
31 // 1. Use OpAccessChain to form a pointer to a subword type.
32 // 2. Load the subword value X16.
33 // 3. Convert X16 to X32.
34 // 4. Store X32 to BufferBlock.
35 // 5. Host inspects X32.
36 // * Test {StorageInputOutput16} 16-to-16:
37 // * For newly enabled types T:
38 // 1. Host creates X16 stream values of type T.
39 // 2. Shaders have corresponding capability.
40 // 3. For each viable shader stage:
41 // 3a. Load X16 Input variable.
42 // 3b. Store X16 to Output variable.
43 // 4. Host inspects resulting values.
44 // * Test {StorageInputOutput16} 16-to-16 one value to two:
45 // Like the previous test, but write X16 to two different output variables.
46 // (Checks that the 16-bit intermediate value can be used twice.)
48 #include "vktSpvAsm16bitStorageTests.hpp"
50 #include "tcuFloat.hpp"
51 #include "tcuRGBA.hpp"
52 #include "tcuStringTemplate.hpp"
53 #include "tcuTestLog.hpp"
54 #include "tcuVectorUtil.hpp"
57 #include "vkDeviceUtil.hpp"
58 #include "vkMemUtil.hpp"
59 #include "vkPlatform.hpp"
60 #include "vkPrograms.hpp"
61 #include "vkQueryUtil.hpp"
63 #include "vkRefUtil.hpp"
64 #include "vkStrUtil.hpp"
65 #include "vkTypeUtil.hpp"
67 #include "deRandom.hpp"
68 #include "deStringUtil.hpp"
69 #include "deUniquePtr.hpp"
72 #include "vktSpvAsmComputeShaderCase.hpp"
73 #include "vktSpvAsmComputeShaderTestUtil.hpp"
74 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
75 #include "vktTestCaseUtil.hpp"
76 #include "vktTestGroupUtil.hpp"
86 namespace SpirVAssembly
97 using tcu::TestStatus;
100 using tcu::StringTemplate;
111 vk::VkDescriptorType dtype;
114 static const Capability CAPABILITIES[] =
116 {"uniform_buffer_block", "StorageUniformBufferBlock16", "BufferBlock", VK_DESCRIPTOR_TYPE_STORAGE_BUFFER},
117 {"uniform", "StorageUniform16", "Block", VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER},
120 VulkanFeatures get16BitStorageFeatures (const char* cap)
122 VulkanFeatures features;
123 if (string(cap) == "uniform_buffer_block")
124 features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
125 else if (string(cap) == "uniform")
126 features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM;
128 DE_ASSERT(false && "not supported");
134 // Batch function to check arrays of 16-bit floats.
136 // For comparing 16-bit floats, we need to consider both RTZ and RTE. So we can only recalculate
137 // the expected values here instead of get the expected values directly from the test case.
138 // Thus we need original floats here but not expected outputs.
139 template<RoundingModeFlags RoundingMode>
140 bool graphicsCheck16BitFloats (const std::vector<Resource>& originalFloats,
141 const vector<AllocationSp>& outputAllocs,
142 const std::vector<Resource>& /* expectedOutputs */,
145 if (outputAllocs.size() != originalFloats.size())
148 for (deUint32 outputNdx = 0; outputNdx < outputAllocs.size(); ++outputNdx)
150 vector<deUint8> originalBytes;
151 originalFloats[outputNdx].second->getBytes(originalBytes);
153 const deUint16* returned = static_cast<const deUint16*>(outputAllocs[outputNdx]->getHostPtr());
154 const float* original = reinterpret_cast<const float*>(&originalBytes.front());
155 const deUint32 count = static_cast<deUint32>(originalBytes.size() / sizeof(float));
157 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
158 if (!compare16BitFloat(original[numNdx], returned[numNdx], RoundingMode, log))
165 template<RoundingModeFlags RoundingMode>
166 bool computeCheck16BitFloats (const std::vector<BufferSp>& originalFloats,
167 const vector<AllocationSp>& outputAllocs,
168 const std::vector<BufferSp>& /* expectedOutputs */,
171 if (outputAllocs.size() != originalFloats.size())
174 for (deUint32 outputNdx = 0; outputNdx < outputAllocs.size(); ++outputNdx)
176 vector<deUint8> originalBytes;
177 originalFloats[outputNdx]->getBytes(originalBytes);
179 const deUint16* returned = static_cast<const deUint16*>(outputAllocs[outputNdx]->getHostPtr());
180 const float* original = reinterpret_cast<const float*>(&originalBytes.front());
181 const deUint32 count = static_cast<deUint32>(originalBytes.size() / sizeof(float));
183 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
184 if (!compare16BitFloat(original[numNdx], returned[numNdx], RoundingMode, log))
192 // Batch function to check arrays of 32-bit floats.
194 // For comparing 32-bit floats, we just need the expected value precomputed in the test case.
195 // So we need expected outputs here but not original floats.
196 bool check32BitFloats (const std::vector<Resource>& /* originalFloats */,
197 const std::vector<AllocationSp>& outputAllocs,
198 const std::vector<Resource>& expectedOutputs,
201 if (outputAllocs.size() != expectedOutputs.size())
204 for (deUint32 outputNdx = 0; outputNdx < outputAllocs.size(); ++outputNdx)
206 vector<deUint8> expectedBytes;
207 expectedOutputs[outputNdx].second->getBytes(expectedBytes);
209 const float* returnedAsFloat = static_cast<const float*>(outputAllocs[outputNdx]->getHostPtr());
210 const float* expectedAsFloat = reinterpret_cast<const float*>(&expectedBytes.front());
211 const deUint32 count = static_cast<deUint32>(expectedBytes.size() / sizeof(float));
213 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
214 if (!compare32BitFloat(expectedAsFloat[numNdx], returnedAsFloat[numNdx], log))
221 // Overload for compute pipeline
222 bool check32BitFloats (const std::vector<BufferSp>& /* originalFloats */,
223 const std::vector<AllocationSp>& outputAllocs,
224 const std::vector<BufferSp>& expectedOutputs,
227 if (outputAllocs.size() != expectedOutputs.size())
230 for (deUint32 outputNdx = 0; outputNdx < outputAllocs.size(); ++outputNdx)
232 vector<deUint8> expectedBytes;
233 expectedOutputs[outputNdx]->getBytes(expectedBytes);
235 const float* returnedAsFloat = static_cast<const float*>(outputAllocs[outputNdx]->getHostPtr());
236 const float* expectedAsFloat = reinterpret_cast<const float*>(&expectedBytes.front());
237 const deUint32 count = static_cast<deUint32>(expectedBytes.size() / sizeof(float));
239 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
240 if (!compare32BitFloat(expectedAsFloat[numNdx], returnedAsFloat[numNdx], log))
247 // Generate and return 32-bit integers.
249 // Expected count to be at least 16.
250 vector<deInt32> getInt32s (de::Random& rnd, const deUint32 count)
252 vector<deInt32> data;
256 // Make sure we have boundary numbers.
257 data.push_back(deInt32(0x00000000)); // 0
258 data.push_back(deInt32(0x00000001)); // 1
259 data.push_back(deInt32(0x0000002a)); // 42
260 data.push_back(deInt32(0x00007fff)); // 32767
261 data.push_back(deInt32(0x00008000)); // 32768
262 data.push_back(deInt32(0x0000ffff)); // 65535
263 data.push_back(deInt32(0x00010000)); // 65536
264 data.push_back(deInt32(0x7fffffff)); // 2147483647
265 data.push_back(deInt32(0x80000000)); // -2147483648
266 data.push_back(deInt32(0x80000001)); // -2147483647
267 data.push_back(deInt32(0xffff0000)); // -65536
268 data.push_back(deInt32(0xffff0001)); // -65535
269 data.push_back(deInt32(0xffff8000)); // -32768
270 data.push_back(deInt32(0xffff8001)); // -32767
271 data.push_back(deInt32(0xffffffd6)); // -42
272 data.push_back(deInt32(0xffffffff)); // -1
274 DE_ASSERT(count >= data.size());
276 for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
277 data.push_back(static_cast<deInt32>(rnd.getUint32()));
282 // Generate and return 16-bit integers.
284 // Expected count to be at least 8.
285 vector<deInt16> getInt16s (de::Random& rnd, const deUint32 count)
287 vector<deInt16> data;
291 // Make sure we have boundary numbers.
292 data.push_back(deInt16(0x0000)); // 0
293 data.push_back(deInt16(0x0001)); // 1
294 data.push_back(deInt16(0x002a)); // 42
295 data.push_back(deInt16(0x7fff)); // 32767
296 data.push_back(deInt16(0x8000)); // -32868
297 data.push_back(deInt16(0x8001)); // -32767
298 data.push_back(deInt16(0xffd6)); // -42
299 data.push_back(deInt16(0xffff)); // -1
301 DE_ASSERT(count >= data.size());
303 for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
304 data.push_back(static_cast<deInt16>(rnd.getUint16()));
309 // IEEE-754 floating point numbers:
310 // +--------+------+----------+-------------+
311 // | binary | sign | exponent | significand |
312 // +--------+------+----------+-------------+
313 // | 16-bit | 1 | 5 | 10 |
314 // +--------+------+----------+-------------+
315 // | 32-bit | 1 | 8 | 23 |
316 // +--------+------+----------+-------------+
320 // 0 000 00 00 0000 0001 (0x0001: 2e-24: minimum positive denormalized)
321 // 0 000 00 11 1111 1111 (0x03ff: 2e-14 - 2e-24: maximum positive denormalized)
322 // 0 000 01 00 0000 0000 (0x0400: 2e-14: minimum positive normalized)
326 // 0 011 1110 1 001 0000 0000 0000 0000 0000 (0x3e900000: 0.28125: with exact match in 16-bit normalized)
327 // 0 011 1000 1 000 0000 0011 0000 0000 0000 (0x38803000: exact half way within two 16-bit normalized; round to zero: 0x0401)
328 // 1 011 1000 1 000 0000 0011 0000 0000 0000 (0xb8803000: exact half way within two 16-bit normalized; round to zero: 0x8402)
329 // 0 011 1000 1 000 0000 1111 1111 0000 0000 (0x3880ff00: not exact half way within two 16-bit normalized; round to zero: 0x0403)
330 // 1 011 1000 1 000 0000 1111 1111 0000 0000 (0xb880ff00: not exact half way within two 16-bit normalized; round to zero: 0x8404)
333 // Generate and return 32-bit floats
335 // The first 24 number pairs are manually picked, while the rest are randomly generated.
336 // Expected count to be at least 24 (numPicks).
337 vector<float> getFloat32s (de::Random& rnd, deUint32 count)
339 vector<float> float32;
341 float32.reserve(count);
344 float32.push_back(0.f);
345 float32.push_back(-0.f);
347 float32.push_back(std::numeric_limits<float>::infinity());
348 float32.push_back(-std::numeric_limits<float>::infinity());
350 float32.push_back(std::numeric_limits<float>::signaling_NaN());
351 float32.push_back(-std::numeric_limits<float>::signaling_NaN());
353 float32.push_back(std::numeric_limits<float>::quiet_NaN());
354 float32.push_back(-std::numeric_limits<float>::quiet_NaN());
356 // Denormalized 32-bit float matching 0 in 16-bit
357 float32.push_back(deFloatLdExp(1.f, -127));
358 float32.push_back(-deFloatLdExp(1.f, -127));
360 // Normalized 32-bit float matching 0 in 16-bit
361 float32.push_back(deFloatLdExp(1.f, -100));
362 float32.push_back(-deFloatLdExp(1.f, -100));
363 // Normalized 32-bit float with exact denormalized match in 16-bit
364 float32.push_back(deFloatLdExp(1.f, -24)); // 2e-24: minimum 16-bit positive denormalized
365 float32.push_back(-deFloatLdExp(1.f, -24)); // 2e-24: maximum 16-bit negative denormalized
366 // Normalized 32-bit float with exact normalized match in 16-bit
367 float32.push_back(deFloatLdExp(1.f, -14)); // 2e-14: minimum 16-bit positive normalized
368 float32.push_back(-deFloatLdExp(1.f, -14)); // 2e-14: maximum 16-bit negative normalized
369 // Normalized 32-bit float falling above half way within two 16-bit normalized
370 float32.push_back(bitwiseCast<float>(deUint32(0x3880ff00)));
371 float32.push_back(bitwiseCast<float>(deUint32(0xb880ff00)));
372 // Normalized 32-bit float falling exact half way within two 16-bit normalized
373 float32.push_back(bitwiseCast<float>(deUint32(0x38803000)));
374 float32.push_back(bitwiseCast<float>(deUint32(0xb8803000)));
376 float32.push_back(0.28125f);
377 float32.push_back(-0.28125f);
378 // Normalized 32-bit float matching infinity in 16-bit
379 float32.push_back(deFloatLdExp(1.f, 100));
380 float32.push_back(-deFloatLdExp(1.f, 100));
382 const deUint32 numPicks = static_cast<deUint32>(float32.size());
384 DE_ASSERT(count >= numPicks);
387 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
388 float32.push_back(rnd.getFloat());
393 // IEEE-754 floating point numbers:
394 // +--------+------+----------+-------------+
395 // | binary | sign | exponent | significand |
396 // +--------+------+----------+-------------+
397 // | 16-bit | 1 | 5 | 10 |
398 // +--------+------+----------+-------------+
399 // | 32-bit | 1 | 8 | 23 |
400 // +--------+------+----------+-------------+
404 // 0 000 00 00 0000 0001 (0x0001: 2e-24: minimum positive denormalized)
405 // 0 000 00 11 1111 1111 (0x03ff: 2e-14 - 2e-24: maximum positive denormalized)
406 // 0 000 01 00 0000 0000 (0x0400: 2e-14: minimum positive normalized)
408 // 0 000 00 00 0000 0000 (0x0000: +0)
409 // 0 111 11 00 0000 0000 (0x7c00: +Inf)
410 // 0 000 00 11 1111 0000 (0x03f0: +Denorm)
411 // 0 000 01 00 0000 0001 (0x0401: +Norm)
412 // 0 111 11 00 0000 1111 (0x7c0f: +SNaN)
413 // 0 111 11 00 1111 0000 (0x7c0f: +QNaN)
416 // Generate and return 16-bit floats and their corresponding 32-bit values.
418 // The first 14 number pairs are manually picked, while the rest are randomly generated.
419 // Expected count to be at least 14 (numPicks).
420 vector<deFloat16> getFloat16s (de::Random& rnd, deUint32 count)
422 vector<deFloat16> float16;
424 float16.reserve(count);
427 float16.push_back(deUint16(0x0000));
428 float16.push_back(deUint16(0x8000));
430 float16.push_back(deUint16(0x7c00));
431 float16.push_back(deUint16(0xfc00));
433 float16.push_back(deUint16(0x7c0f));
434 float16.push_back(deUint16(0xfc0f));
436 float16.push_back(deUint16(0x7cf0));
437 float16.push_back(deUint16(0xfcf0));
440 float16.push_back(deUint16(0x03f0));
441 float16.push_back(deUint16(0x83f0));
443 float16.push_back(deUint16(0x0401));
444 float16.push_back(deUint16(0x8401));
445 // Some normal number
446 float16.push_back(deUint16(0x14cb));
447 float16.push_back(deUint16(0x94cb));
449 const deUint32 numPicks = static_cast<deUint32>(float16.size());
451 DE_ASSERT(count >= numPicks);
454 for (deUint32 numIdx = 0; numIdx < count; ++numIdx)
455 float16.push_back(rnd.getUint16());
460 void addCompute16bitStorageUniform16To32Group (tcu::TestCaseGroup* group)
462 tcu::TestContext& testCtx = group->getTestContext();
463 de::Random rnd (deStringHash(group->getName()));
464 const int numElements = 128;
466 const StringTemplate shaderTemplate (
467 "OpCapability Shader\n"
468 "OpCapability ${capability}\n"
469 "OpExtension \"SPV_KHR_16bit_storage\"\n"
470 "OpMemoryModel Logical GLSL450\n"
471 "OpEntryPoint GLCompute %main \"main\" %id\n"
472 "OpExecutionMode %main LocalSize 1 1 1\n"
473 "OpDecorate %id BuiltIn GlobalInvocationId\n"
477 "OpMemberDecorate %SSBO32 0 Offset 0\n"
478 "OpMemberDecorate %SSBO16 0 Offset 0\n"
479 "OpDecorate %SSBO32 BufferBlock\n"
480 "OpDecorate %SSBO16 ${storage}\n"
481 "OpDecorate %ssbo32 DescriptorSet 0\n"
482 "OpDecorate %ssbo16 DescriptorSet 0\n"
483 "OpDecorate %ssbo32 Binding 1\n"
484 "OpDecorate %ssbo16 Binding 0\n"
486 "${matrix_decor:opt}\n"
488 "%bool = OpTypeBool\n"
489 "%void = OpTypeVoid\n"
490 "%voidf = OpTypeFunction %void\n"
491 "%u32 = OpTypeInt 32 0\n"
492 "%i32 = OpTypeInt 32 1\n"
493 "%f32 = OpTypeFloat 32\n"
494 "%uvec3 = OpTypeVector %u32 3\n"
495 "%fvec3 = OpTypeVector %f32 3\n"
496 "%uvec3ptr = OpTypePointer Input %uvec3\n"
497 "%i32ptr = OpTypePointer Uniform %i32\n"
498 "%f32ptr = OpTypePointer Uniform %f32\n"
500 "%zero = OpConstant %i32 0\n"
501 "%c_i32_1 = OpConstant %i32 1\n"
502 "%c_i32_2 = OpConstant %i32 2\n"
503 "%c_i32_3 = OpConstant %i32 3\n"
504 "%c_i32_16 = OpConstant %i32 16\n"
505 "%c_i32_32 = OpConstant %i32 32\n"
506 "%c_i32_64 = OpConstant %i32 64\n"
507 "%c_i32_128 = OpConstant %i32 128\n"
509 "%i32arr = OpTypeArray %i32 %c_i32_128\n"
510 "%f32arr = OpTypeArray %f32 %c_i32_128\n"
513 "${matrix_types:opt}\n"
515 "%SSBO32 = OpTypeStruct %${matrix_prefix:opt}${base32}arr\n"
516 "%SSBO16 = OpTypeStruct %${matrix_prefix:opt}${base16}arr\n"
517 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
518 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
519 "%ssbo32 = OpVariable %up_SSBO32 Uniform\n"
520 "%ssbo16 = OpVariable %up_SSBO16 Uniform\n"
522 "%id = OpVariable %uvec3ptr Input\n"
524 "%main = OpFunction %void None %voidf\n"
526 "%idval = OpLoad %uvec3 %id\n"
527 "%x = OpCompositeExtract %u32 %idval 0\n"
528 "%inloc = OpAccessChain %${base16}ptr %ssbo16 %zero %x ${index0:opt}\n"
529 "%val16 = OpLoad %${base16} %inloc\n"
530 "%val32 = ${convert} %${base32} %val16\n"
531 "%outloc = OpAccessChain %${base32}ptr %ssbo32 %zero %x ${index0:opt}\n"
532 " OpStore %outloc %val32\n"
533 "${matrix_store:opt}\n"
538 const char floatTypes[] =
539 "%f16 = OpTypeFloat 16\n"
540 "%f16ptr = OpTypePointer Uniform %f16\n"
541 "%f16arr = OpTypeArray %f16 %c_i32_128\n"
542 "%v2f16 = OpTypeVector %f16 2\n"
543 "%v2f32 = OpTypeVector %f32 2\n"
544 "%v2f16ptr = OpTypePointer Uniform %v2f16\n"
545 "%v2f32ptr = OpTypePointer Uniform %v2f32\n"
546 "%v2f16arr = OpTypeArray %v2f16 %c_i32_64\n"
547 "%v2f32arr = OpTypeArray %v2f32 %c_i32_64\n";
558 const CompositeType cTypes[] =
560 {"scalar", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 2\n", numElements},
561 {"vector", "v2f32", "v2f16", "OpDecorate %v2f32arr ArrayStride 8\nOpDecorate %v2f16arr ArrayStride 4\n", numElements / 2},
562 {"matrix", "v2f32", "v2f16", "OpDecorate %m4v2f32arr ArrayStride 32\nOpDecorate %m4v2f16arr ArrayStride 16\n", numElements / 8},
565 vector<deFloat16> float16Data = getFloat16s(rnd, numElements);
566 vector<float> float32Data;
568 float32Data.reserve(numElements);
569 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
570 float32Data.push_back(deFloat16To32(float16Data[numIdx]));
572 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
573 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
575 ComputeShaderSpec spec;
576 map<string, string> specs;
577 string testName = string(CAPABILITIES[capIdx].name) + "_" + cTypes[tyIdx].name + "_float";
579 specs["capability"] = CAPABILITIES[capIdx].cap;
580 specs["storage"] = CAPABILITIES[capIdx].decor;
581 specs["stride"] = cTypes[tyIdx].stride;
582 specs["base32"] = cTypes[tyIdx].base32;
583 specs["base16"] = cTypes[tyIdx].base16;
584 specs["types"] = floatTypes;
585 specs["convert"] = "OpFConvert";
587 if (strcmp(cTypes[tyIdx].name, "matrix") == 0)
589 specs["index0"] = "%zero";
590 specs["matrix_prefix"] = "m4";
591 specs["matrix_types"] =
592 "%m4v2f16 = OpTypeMatrix %v2f16 4\n"
593 "%m4v2f32 = OpTypeMatrix %v2f32 4\n"
594 "%m4v2f16arr = OpTypeArray %m4v2f16 %c_i32_16\n"
595 "%m4v2f32arr = OpTypeArray %m4v2f32 %c_i32_16\n";
596 specs["matrix_decor"] =
597 "OpMemberDecorate %SSBO32 0 ColMajor\n"
598 "OpMemberDecorate %SSBO32 0 MatrixStride 8\n"
599 "OpMemberDecorate %SSBO16 0 ColMajor\n"
600 "OpMemberDecorate %SSBO16 0 MatrixStride 4\n";
601 specs["matrix_store"] =
602 "%inloc_1 = OpAccessChain %v2f16ptr %ssbo16 %zero %x %c_i32_1\n"
603 "%val16_1 = OpLoad %v2f16 %inloc_1\n"
604 "%val32_1 = OpFConvert %v2f32 %val16_1\n"
605 "%outloc_1 = OpAccessChain %v2f32ptr %ssbo32 %zero %x %c_i32_1\n"
606 " OpStore %outloc_1 %val32_1\n"
608 "%inloc_2 = OpAccessChain %v2f16ptr %ssbo16 %zero %x %c_i32_2\n"
609 "%val16_2 = OpLoad %v2f16 %inloc_2\n"
610 "%val32_2 = OpFConvert %v2f32 %val16_2\n"
611 "%outloc_2 = OpAccessChain %v2f32ptr %ssbo32 %zero %x %c_i32_2\n"
612 " OpStore %outloc_2 %val32_2\n"
614 "%inloc_3 = OpAccessChain %v2f16ptr %ssbo16 %zero %x %c_i32_3\n"
615 "%val16_3 = OpLoad %v2f16 %inloc_3\n"
616 "%val32_3 = OpFConvert %v2f32 %val16_3\n"
617 "%outloc_3 = OpAccessChain %v2f32ptr %ssbo32 %zero %x %c_i32_3\n"
618 " OpStore %outloc_3 %val32_3\n";
621 spec.assembly = shaderTemplate.specialize(specs);
622 spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
623 spec.verifyIO = check32BitFloats;
624 spec.inputTypes[0] = CAPABILITIES[capIdx].dtype;
626 spec.inputs.push_back(BufferSp(new Float16Buffer(float16Data)));
627 spec.outputs.push_back(BufferSp(new Float32Buffer(float32Data)));
628 spec.extensions.push_back("VK_KHR_16bit_storage");
629 spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
631 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
636 const char sintTypes[] =
637 "%i16 = OpTypeInt 16 1\n"
638 "%i16ptr = OpTypePointer Uniform %i16\n"
639 "%i16arr = OpTypeArray %i16 %c_i32_128\n"
640 "%v4i16 = OpTypeVector %i16 4\n"
641 "%v4i32 = OpTypeVector %i32 4\n"
642 "%v4i16ptr = OpTypePointer Uniform %v4i16\n"
643 "%v4i32ptr = OpTypePointer Uniform %v4i32\n"
644 "%v4i16arr = OpTypeArray %v4i16 %c_i32_32\n"
645 "%v4i32arr = OpTypeArray %v4i32 %c_i32_32\n";
647 const char uintTypes[] =
648 "%u16 = OpTypeInt 16 0\n"
649 "%u16ptr = OpTypePointer Uniform %u16\n"
650 "%u32ptr = OpTypePointer Uniform %u32\n"
651 "%u16arr = OpTypeArray %u16 %c_i32_128\n"
652 "%u32arr = OpTypeArray %u32 %c_i32_128\n"
653 "%v4u16 = OpTypeVector %u16 4\n"
654 "%v4u32 = OpTypeVector %u32 4\n"
655 "%v4u16ptr = OpTypePointer Uniform %v4u16\n"
656 "%v4u32ptr = OpTypePointer Uniform %v4u32\n"
657 "%v4u16arr = OpTypeArray %v4u16 %c_i32_32\n"
658 "%v4u32arr = OpTypeArray %v4u32 %c_i32_32\n";
672 const CompositeType cTypes[] =
674 {"scalar_sint", true, sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 2\n", numElements},
675 {"scalar_uint", false, uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 2\n", numElements},
676 {"vector_sint", true, sintTypes, "v4i32", "v4i16", "OpSConvert", "OpDecorate %v4i32arr ArrayStride 16\nOpDecorate %v4i16arr ArrayStride 8\n", numElements / 4},
677 {"vector_uint", false, uintTypes, "v4u32", "v4u16", "OpUConvert", "OpDecorate %v4u32arr ArrayStride 16\nOpDecorate %v4u16arr ArrayStride 8\n", numElements / 4},
680 vector<deInt16> inputs = getInt16s(rnd, numElements);
681 vector<deInt32> sOutputs;
682 vector<deInt32> uOutputs;
683 const deUint16 signBitMask = 0x8000;
684 const deUint32 signExtendMask = 0xffff0000;
686 sOutputs.reserve(inputs.size());
687 uOutputs.reserve(inputs.size());
689 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
691 uOutputs.push_back(static_cast<deUint16>(inputs[numNdx]));
692 if (inputs[numNdx] & signBitMask)
693 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx] | signExtendMask));
695 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx]));
698 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
699 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
701 ComputeShaderSpec spec;
702 map<string, string> specs;
703 string testName = string(CAPABILITIES[capIdx].name) + "_" + cTypes[tyIdx].name;
705 specs["capability"] = CAPABILITIES[capIdx].cap;
706 specs["storage"] = CAPABILITIES[capIdx].decor;
707 specs["stride"] = cTypes[tyIdx].stride;
708 specs["base32"] = cTypes[tyIdx].base32;
709 specs["base16"] = cTypes[tyIdx].base16;
710 specs["types"] = cTypes[tyIdx].types;
711 specs["convert"] = cTypes[tyIdx].opcode;
713 spec.assembly = shaderTemplate.specialize(specs);
714 spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
715 spec.inputTypes[0] = CAPABILITIES[capIdx].dtype;
717 spec.inputs.push_back(BufferSp(new Int16Buffer(inputs)));
718 if (cTypes[tyIdx].isSigned)
719 spec.outputs.push_back(BufferSp(new Int32Buffer(sOutputs)));
721 spec.outputs.push_back(BufferSp(new Int32Buffer(uOutputs)));
722 spec.extensions.push_back("VK_KHR_16bit_storage");
723 spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
725 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
730 void addCompute16bitStoragePushConstant16To32Group (tcu::TestCaseGroup* group)
732 tcu::TestContext& testCtx = group->getTestContext();
733 de::Random rnd (deStringHash(group->getName()));
734 const int numElements = 64;
736 const StringTemplate shaderTemplate (
737 "OpCapability Shader\n"
738 "OpCapability StoragePushConstant16\n"
739 "OpExtension \"SPV_KHR_16bit_storage\"\n"
740 "OpMemoryModel Logical GLSL450\n"
741 "OpEntryPoint GLCompute %main \"main\" %id\n"
742 "OpExecutionMode %main LocalSize 1 1 1\n"
743 "OpDecorate %id BuiltIn GlobalInvocationId\n"
747 "OpDecorate %PC16 Block\n"
748 "OpMemberDecorate %PC16 0 Offset 0\n"
749 "OpMemberDecorate %SSBO32 0 Offset 0\n"
750 "OpDecorate %SSBO32 BufferBlock\n"
751 "OpDecorate %ssbo32 DescriptorSet 0\n"
752 "OpDecorate %ssbo32 Binding 0\n"
754 "${matrix_decor:opt}\n"
756 "%bool = OpTypeBool\n"
757 "%void = OpTypeVoid\n"
758 "%voidf = OpTypeFunction %void\n"
759 "%u32 = OpTypeInt 32 0\n"
760 "%i32 = OpTypeInt 32 1\n"
761 "%f32 = OpTypeFloat 32\n"
762 "%uvec3 = OpTypeVector %u32 3\n"
763 "%fvec3 = OpTypeVector %f32 3\n"
764 "%uvec3ptr = OpTypePointer Input %uvec3\n"
765 "%i32ptr = OpTypePointer Uniform %i32\n"
766 "%f32ptr = OpTypePointer Uniform %f32\n"
768 "%zero = OpConstant %i32 0\n"
769 "%c_i32_1 = OpConstant %i32 1\n"
770 "%c_i32_8 = OpConstant %i32 8\n"
771 "%c_i32_16 = OpConstant %i32 16\n"
772 "%c_i32_32 = OpConstant %i32 32\n"
773 "%c_i32_64 = OpConstant %i32 64\n"
775 "%i32arr = OpTypeArray %i32 %c_i32_64\n"
776 "%f32arr = OpTypeArray %f32 %c_i32_64\n"
779 "${matrix_types:opt}\n"
781 "%PC16 = OpTypeStruct %${matrix_prefix:opt}${base16}arr\n"
782 "%pp_PC16 = OpTypePointer PushConstant %PC16\n"
783 "%pc16 = OpVariable %pp_PC16 PushConstant\n"
784 "%SSBO32 = OpTypeStruct %${matrix_prefix:opt}${base32}arr\n"
785 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
786 "%ssbo32 = OpVariable %up_SSBO32 Uniform\n"
788 "%id = OpVariable %uvec3ptr Input\n"
790 "%main = OpFunction %void None %voidf\n"
792 "%idval = OpLoad %uvec3 %id\n"
793 "%x = OpCompositeExtract %u32 %idval 0\n"
794 "%inloc = OpAccessChain %${base16}ptr %pc16 %zero %x ${index0:opt}\n"
795 "%val16 = OpLoad %${base16} %inloc\n"
796 "%val32 = ${convert} %${base32} %val16\n"
797 "%outloc = OpAccessChain %${base32}ptr %ssbo32 %zero %x ${index0:opt}\n"
798 " OpStore %outloc %val32\n"
799 "${matrix_store:opt}\n"
804 const char floatTypes[] =
805 "%f16 = OpTypeFloat 16\n"
806 "%f16ptr = OpTypePointer PushConstant %f16\n"
807 "%f16arr = OpTypeArray %f16 %c_i32_64\n"
808 "%v4f16 = OpTypeVector %f16 4\n"
809 "%v4f32 = OpTypeVector %f32 4\n"
810 "%v4f16ptr = OpTypePointer PushConstant %v4f16\n"
811 "%v4f32ptr = OpTypePointer Uniform %v4f32\n"
812 "%v4f16arr = OpTypeArray %v4f16 %c_i32_16\n"
813 "%v4f32arr = OpTypeArray %v4f32 %c_i32_16\n";
824 const CompositeType cTypes[] =
826 {"scalar", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 2\n", numElements},
827 {"vector", "v4f32", "v4f16", "OpDecorate %v4f32arr ArrayStride 16\nOpDecorate %v4f16arr ArrayStride 8\n", numElements / 4},
828 {"matrix", "v4f32", "v4f16", "OpDecorate %m2v4f32arr ArrayStride 32\nOpDecorate %m2v4f16arr ArrayStride 16\n", numElements / 8},
831 vector<deFloat16> float16Data = getFloat16s(rnd, numElements);
832 vector<float> float32Data;
834 float32Data.reserve(numElements);
835 for (deUint32 numIdx = 0; numIdx < numElements; ++numIdx)
836 float32Data.push_back(deFloat16To32(float16Data[numIdx]));
838 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
840 ComputeShaderSpec spec;
841 map<string, string> specs;
842 string testName = string(cTypes[tyIdx].name) + "_float";
844 specs["stride"] = cTypes[tyIdx].stride;
845 specs["base32"] = cTypes[tyIdx].base32;
846 specs["base16"] = cTypes[tyIdx].base16;
847 specs["types"] = floatTypes;
848 specs["convert"] = "OpFConvert";
850 if (strcmp(cTypes[tyIdx].name, "matrix") == 0)
852 specs["index0"] = "%zero";
853 specs["matrix_prefix"] = "m2";
854 specs["matrix_types"] =
855 "%m2v4f16 = OpTypeMatrix %v4f16 2\n"
856 "%m2v4f32 = OpTypeMatrix %v4f32 2\n"
857 "%m2v4f16arr = OpTypeArray %m2v4f16 %c_i32_8\n"
858 "%m2v4f32arr = OpTypeArray %m2v4f32 %c_i32_8\n";
859 specs["matrix_decor"] =
860 "OpMemberDecorate %SSBO32 0 ColMajor\n"
861 "OpMemberDecorate %SSBO32 0 MatrixStride 16\n"
862 "OpMemberDecorate %PC16 0 ColMajor\n"
863 "OpMemberDecorate %PC16 0 MatrixStride 8\n";
864 specs["matrix_store"] =
865 "%inloc_1 = OpAccessChain %v4f16ptr %pc16 %zero %x %c_i32_1\n"
866 "%val16_1 = OpLoad %v4f16 %inloc_1\n"
867 "%val32_1 = OpFConvert %v4f32 %val16_1\n"
868 "%outloc_1 = OpAccessChain %v4f32ptr %ssbo32 %zero %x %c_i32_1\n"
869 " OpStore %outloc_1 %val32_1\n";
872 spec.assembly = shaderTemplate.specialize(specs);
873 spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
874 spec.verifyIO = check32BitFloats;
875 spec.pushConstants = BufferSp(new Float16Buffer(float16Data));
877 spec.outputs.push_back(BufferSp(new Float32Buffer(float32Data)));
878 spec.extensions.push_back("VK_KHR_16bit_storage");
879 spec.requestedVulkanFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
881 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
885 const char sintTypes[] =
886 "%i16 = OpTypeInt 16 1\n"
887 "%i16ptr = OpTypePointer PushConstant %i16\n"
888 "%i16arr = OpTypeArray %i16 %c_i32_64\n"
889 "%v2i16 = OpTypeVector %i16 2\n"
890 "%v2i32 = OpTypeVector %i32 2\n"
891 "%v2i16ptr = OpTypePointer PushConstant %v2i16\n"
892 "%v2i32ptr = OpTypePointer Uniform %v2i32\n"
893 "%v2i16arr = OpTypeArray %v2i16 %c_i32_32\n"
894 "%v2i32arr = OpTypeArray %v2i32 %c_i32_32\n";
896 const char uintTypes[] =
897 "%u16 = OpTypeInt 16 0\n"
898 "%u16ptr = OpTypePointer PushConstant %u16\n"
899 "%u32ptr = OpTypePointer Uniform %u32\n"
900 "%u16arr = OpTypeArray %u16 %c_i32_64\n"
901 "%u32arr = OpTypeArray %u32 %c_i32_64\n"
902 "%v2u16 = OpTypeVector %u16 2\n"
903 "%v2u32 = OpTypeVector %u32 2\n"
904 "%v2u16ptr = OpTypePointer PushConstant %v2u16\n"
905 "%v2u32ptr = OpTypePointer Uniform %v2u32\n"
906 "%v2u16arr = OpTypeArray %v2u16 %c_i32_32\n"
907 "%v2u32arr = OpTypeArray %v2u32 %c_i32_32\n";
921 const CompositeType cTypes[] =
923 {"scalar_sint", true, sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 2\n", numElements},
924 {"scalar_uint", false, uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 2\n", numElements},
925 {"vector_sint", true, sintTypes, "v2i32", "v2i16", "OpSConvert", "OpDecorate %v2i32arr ArrayStride 8\nOpDecorate %v2i16arr ArrayStride 4\n", numElements / 2},
926 {"vector_uint", false, uintTypes, "v2u32", "v2u16", "OpUConvert", "OpDecorate %v2u32arr ArrayStride 8\nOpDecorate %v2u16arr ArrayStride 4\n", numElements / 2},
929 vector<deInt16> inputs = getInt16s(rnd, numElements);
930 vector<deInt32> sOutputs;
931 vector<deInt32> uOutputs;
932 const deUint16 signBitMask = 0x8000;
933 const deUint32 signExtendMask = 0xffff0000;
935 sOutputs.reserve(inputs.size());
936 uOutputs.reserve(inputs.size());
938 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
940 uOutputs.push_back(static_cast<deUint16>(inputs[numNdx]));
941 if (inputs[numNdx] & signBitMask)
942 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx] | signExtendMask));
944 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx]));
947 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
949 ComputeShaderSpec spec;
950 map<string, string> specs;
951 const char* testName = cTypes[tyIdx].name;
953 specs["stride"] = cTypes[tyIdx].stride;
954 specs["base32"] = cTypes[tyIdx].base32;
955 specs["base16"] = cTypes[tyIdx].base16;
956 specs["types"] = cTypes[tyIdx].types;
957 specs["convert"] = cTypes[tyIdx].opcode;
959 spec.assembly = shaderTemplate.specialize(specs);
960 spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
961 spec.pushConstants = BufferSp(new Int16Buffer(inputs));
963 if (cTypes[tyIdx].isSigned)
964 spec.outputs.push_back(BufferSp(new Int32Buffer(sOutputs)));
966 spec.outputs.push_back(BufferSp(new Int32Buffer(uOutputs)));
967 spec.extensions.push_back("VK_KHR_16bit_storage");
968 spec.requestedVulkanFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
970 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName, testName, spec));
975 void addGraphics16BitStorageUniformInt32To16Group (tcu::TestCaseGroup* testGroup)
977 de::Random rnd (deStringHash(testGroup->getName()));
978 map<string, string> fragments;
979 const deUint32 numDataPoints = 256;
980 RGBA defaultColors[4];
981 GraphicsResources resources;
982 vector<string> extensions;
983 const StringTemplate capabilities ("OpCapability ${cap}\n");
984 // inputs and outputs are declared to be vectors of signed integers.
985 // However, depending on the test, they may be interpreted as unsiged
986 // integers. That won't be a problem as long as we passed the bits
987 // in faithfully to the pipeline.
988 vector<deInt32> inputs = getInt32s(rnd, numDataPoints);
989 vector<deInt16> outputs;
991 outputs.reserve(inputs.size());
992 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
993 outputs.push_back(static_cast<deInt16>(0xffff & inputs[numNdx]));
995 resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int32Buffer(inputs))));
996 resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int16Buffer(outputs))));
998 extensions.push_back("VK_KHR_16bit_storage");
999 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
1001 getDefaultColors(defaultColors);
1009 const char* isSigned;
1012 const IntegerFacts intFacts[] =
1014 {"sint", "%i32", "%i16", "OpSConvert", "1"},
1015 {"uint", "%u32", "%u16", "OpUConvert", "0"},
1018 const StringTemplate scalarPreMain(
1019 "${itype16} = OpTypeInt 16 ${signed}\n"
1020 "%c_i32_256 = OpConstant %i32 256\n"
1021 " %up_i32 = OpTypePointer Uniform ${itype32}\n"
1022 " %up_i16 = OpTypePointer Uniform ${itype16}\n"
1023 " %ra_i32 = OpTypeArray ${itype32} %c_i32_256\n"
1024 " %ra_i16 = OpTypeArray ${itype16} %c_i32_256\n"
1025 " %SSBO32 = OpTypeStruct %ra_i32\n"
1026 " %SSBO16 = OpTypeStruct %ra_i16\n"
1027 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
1028 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
1029 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
1030 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n");
1032 const StringTemplate scalarDecoration(
1033 "OpDecorate %ra_i32 ArrayStride 4\n"
1034 "OpDecorate %ra_i16 ArrayStride 2\n"
1035 "OpMemberDecorate %SSBO32 0 Offset 0\n"
1036 "OpMemberDecorate %SSBO16 0 Offset 0\n"
1037 "OpDecorate %SSBO32 ${indecor}\n"
1038 "OpDecorate %SSBO16 BufferBlock\n"
1039 "OpDecorate %ssbo32 DescriptorSet 0\n"
1040 "OpDecorate %ssbo16 DescriptorSet 0\n"
1041 "OpDecorate %ssbo32 Binding 0\n"
1042 "OpDecorate %ssbo16 Binding 1\n");
1044 const StringTemplate scalarTestFunc(
1045 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
1046 " %param = OpFunctionParameter %v4f32\n"
1048 "%entry = OpLabel\n"
1049 " %i = OpVariable %fp_i32 Function\n"
1050 " OpStore %i %c_i32_0\n"
1053 " %loop = OpLabel\n"
1054 " %15 = OpLoad %i32 %i\n"
1055 " %lt = OpSLessThan %bool %15 %c_i32_256\n"
1056 " OpLoopMerge %merge %inc None\n"
1057 " OpBranchConditional %lt %write %merge\n"
1059 "%write = OpLabel\n"
1060 " %30 = OpLoad %i32 %i\n"
1061 " %src = OpAccessChain %up_i32 %ssbo32 %c_i32_0 %30\n"
1062 "%val32 = OpLoad ${itype32} %src\n"
1063 "%val16 = ${convert} ${itype16} %val32\n"
1064 " %dst = OpAccessChain %up_i16 %ssbo16 %c_i32_0 %30\n"
1065 " OpStore %dst %val16\n"
1069 " %37 = OpLoad %i32 %i\n"
1070 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
1074 "%merge = OpLabel\n"
1075 " OpReturnValue %param\n"
1079 const StringTemplate vecPreMain(
1080 "${itype16} = OpTypeInt 16 ${signed}\n"
1081 " %c_i32_64 = OpConstant %i32 64\n"
1082 "%v4itype16 = OpTypeVector ${itype16} 4\n"
1083 " %up_v4i32 = OpTypePointer Uniform ${v4itype32}\n"
1084 " %up_v4i16 = OpTypePointer Uniform %v4itype16\n"
1085 " %ra_v4i32 = OpTypeArray ${v4itype32} %c_i32_64\n"
1086 " %ra_v4i16 = OpTypeArray %v4itype16 %c_i32_64\n"
1087 " %SSBO32 = OpTypeStruct %ra_v4i32\n"
1088 " %SSBO16 = OpTypeStruct %ra_v4i16\n"
1089 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
1090 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
1091 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
1092 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n");
1094 const StringTemplate vecDecoration(
1095 "OpDecorate %ra_v4i32 ArrayStride 16\n"
1096 "OpDecorate %ra_v4i16 ArrayStride 8\n"
1097 "OpMemberDecorate %SSBO32 0 Offset 0\n"
1098 "OpMemberDecorate %SSBO16 0 Offset 0\n"
1099 "OpDecorate %SSBO32 ${indecor}\n"
1100 "OpDecorate %SSBO16 BufferBlock\n"
1101 "OpDecorate %ssbo32 DescriptorSet 0\n"
1102 "OpDecorate %ssbo16 DescriptorSet 0\n"
1103 "OpDecorate %ssbo32 Binding 0\n"
1104 "OpDecorate %ssbo16 Binding 1\n");
1106 const StringTemplate vecTestFunc(
1107 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
1108 " %param = OpFunctionParameter %v4f32\n"
1110 "%entry = OpLabel\n"
1111 " %i = OpVariable %fp_i32 Function\n"
1112 " OpStore %i %c_i32_0\n"
1115 " %loop = OpLabel\n"
1116 " %15 = OpLoad %i32 %i\n"
1117 " %lt = OpSLessThan %bool %15 %c_i32_64\n"
1118 " OpLoopMerge %merge %inc None\n"
1119 " OpBranchConditional %lt %write %merge\n"
1121 "%write = OpLabel\n"
1122 " %30 = OpLoad %i32 %i\n"
1123 " %src = OpAccessChain %up_v4i32 %ssbo32 %c_i32_0 %30\n"
1124 "%val32 = OpLoad ${v4itype32} %src\n"
1125 "%val16 = ${convert} %v4itype16 %val32\n"
1126 " %dst = OpAccessChain %up_v4i16 %ssbo16 %c_i32_0 %30\n"
1127 " OpStore %dst %val16\n"
1131 " %37 = OpLoad %i32 %i\n"
1132 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
1136 "%merge = OpLabel\n"
1137 " OpReturnValue %param\n"
1144 const StringTemplate& preMain;
1145 const StringTemplate& decoration;
1146 const StringTemplate& testFunction;
1149 const Category categories[] =
1151 {"scalar", scalarPreMain, scalarDecoration, scalarTestFunc},
1152 {"vector", vecPreMain, vecDecoration, vecTestFunc},
1155 for (deUint32 catIdx = 0; catIdx < DE_LENGTH_OF_ARRAY(categories); ++catIdx)
1156 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
1157 for (deUint32 factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
1159 map<string, string> specs;
1160 string name = string(CAPABILITIES[capIdx].name) + "_" + categories[catIdx].name + "_" + intFacts[factIdx].name;
1162 specs["cap"] = CAPABILITIES[capIdx].cap;
1163 specs["indecor"] = CAPABILITIES[capIdx].decor;
1164 specs["itype32"] = intFacts[factIdx].type32;
1165 specs["v4itype32"] = "%v4" + string(intFacts[factIdx].type32).substr(1);
1166 specs["itype16"] = intFacts[factIdx].type16;
1167 specs["signed"] = intFacts[factIdx].isSigned;
1168 specs["convert"] = intFacts[factIdx].opcode;
1170 fragments["pre_main"] = categories[catIdx].preMain.specialize(specs);
1171 fragments["testfun"] = categories[catIdx].testFunction.specialize(specs);
1172 fragments["capability"] = capabilities.specialize(specs);
1173 fragments["decoration"] = categories[catIdx].decoration.specialize(specs);
1175 resources.inputs.back().first = CAPABILITIES[capIdx].dtype;
1177 createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
1181 void addCompute16bitStorageUniform32To16Group (tcu::TestCaseGroup* group)
1183 tcu::TestContext& testCtx = group->getTestContext();
1184 de::Random rnd (deStringHash(group->getName()));
1185 const int numElements = 128;
1187 const StringTemplate shaderTemplate (
1188 "OpCapability Shader\n"
1189 "OpCapability ${capability}\n"
1190 "OpExtension \"SPV_KHR_16bit_storage\"\n"
1191 "OpMemoryModel Logical GLSL450\n"
1192 "OpEntryPoint GLCompute %main \"main\" %id\n"
1193 "OpExecutionMode %main LocalSize 1 1 1\n"
1194 "OpDecorate %id BuiltIn GlobalInvocationId\n"
1198 "OpMemberDecorate %SSBO32 0 Offset 0\n"
1199 "OpMemberDecorate %SSBO16 0 Offset 0\n"
1200 "OpDecorate %SSBO32 ${storage}\n"
1201 "OpDecorate %SSBO16 BufferBlock\n"
1202 "OpDecorate %ssbo32 DescriptorSet 0\n"
1203 "OpDecorate %ssbo16 DescriptorSet 0\n"
1204 "OpDecorate %ssbo32 Binding 0\n"
1205 "OpDecorate %ssbo16 Binding 1\n"
1207 "${matrix_decor:opt}\n"
1211 "%bool = OpTypeBool\n"
1212 "%void = OpTypeVoid\n"
1213 "%voidf = OpTypeFunction %void\n"
1214 "%u32 = OpTypeInt 32 0\n"
1215 "%i32 = OpTypeInt 32 1\n"
1216 "%f32 = OpTypeFloat 32\n"
1217 "%uvec3 = OpTypeVector %u32 3\n"
1218 "%fvec3 = OpTypeVector %f32 3\n"
1219 "%uvec3ptr = OpTypePointer Input %uvec3\n"
1220 "%i32ptr = OpTypePointer Uniform %i32\n"
1221 "%f32ptr = OpTypePointer Uniform %f32\n"
1223 "%zero = OpConstant %i32 0\n"
1224 "%c_i32_1 = OpConstant %i32 1\n"
1225 "%c_i32_16 = OpConstant %i32 16\n"
1226 "%c_i32_32 = OpConstant %i32 32\n"
1227 "%c_i32_64 = OpConstant %i32 64\n"
1228 "%c_i32_128 = OpConstant %i32 128\n"
1230 "%i32arr = OpTypeArray %i32 %c_i32_128\n"
1231 "%f32arr = OpTypeArray %f32 %c_i32_128\n"
1234 "${matrix_types:opt}\n"
1236 "%SSBO32 = OpTypeStruct %${matrix_prefix:opt}${base32}arr\n"
1237 "%SSBO16 = OpTypeStruct %${matrix_prefix:opt}${base16}arr\n"
1238 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
1239 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
1240 "%ssbo32 = OpVariable %up_SSBO32 Uniform\n"
1241 "%ssbo16 = OpVariable %up_SSBO16 Uniform\n"
1243 "%id = OpVariable %uvec3ptr Input\n"
1245 "%main = OpFunction %void None %voidf\n"
1246 "%label = OpLabel\n"
1247 "%idval = OpLoad %uvec3 %id\n"
1248 "%x = OpCompositeExtract %u32 %idval 0\n"
1249 "%inloc = OpAccessChain %${base32}ptr %ssbo32 %zero %x ${index0:opt}\n"
1250 "%val32 = OpLoad %${base32} %inloc\n"
1251 "%val16 = ${convert} %${base16} %val32\n"
1252 "%outloc = OpAccessChain %${base16}ptr %ssbo16 %zero %x ${index0:opt}\n"
1253 " OpStore %outloc %val16\n"
1254 "${matrix_store:opt}\n"
1256 " OpFunctionEnd\n");
1259 const char floatTypes[] =
1260 "%f16 = OpTypeFloat 16\n"
1261 "%f16ptr = OpTypePointer Uniform %f16\n"
1262 "%f16arr = OpTypeArray %f16 %c_i32_128\n"
1263 "%v4f16 = OpTypeVector %f16 4\n"
1264 "%v4f32 = OpTypeVector %f32 4\n"
1265 "%v4f16ptr = OpTypePointer Uniform %v4f16\n"
1266 "%v4f32ptr = OpTypePointer Uniform %v4f32\n"
1267 "%v4f16arr = OpTypeArray %v4f16 %c_i32_32\n"
1268 "%v4f32arr = OpTypeArray %v4f32 %c_i32_32\n";
1274 ComputeVerifyIOFunc func;
1277 const RndMode rndModes[] =
1279 {"rtz", "OpDecorate %val16 FPRoundingMode RTZ", computeCheck16BitFloats<ROUNDINGMODE_RTZ>},
1280 {"rte", "OpDecorate %val16 FPRoundingMode RTE", computeCheck16BitFloats<ROUNDINGMODE_RTE>},
1281 {"unspecified_rnd_mode", "", computeCheck16BitFloats<RoundingModeFlags(ROUNDINGMODE_RTE | ROUNDINGMODE_RTZ)>},
1284 struct CompositeType
1293 const CompositeType cTypes[] =
1295 {"scalar", "f32", "f16", "OpDecorate %f32arr ArrayStride 4\nOpDecorate %f16arr ArrayStride 2\n", numElements},
1296 {"vector", "v4f32", "v4f16", "OpDecorate %v4f32arr ArrayStride 16\nOpDecorate %v4f16arr ArrayStride 8\n", numElements / 4},
1297 {"matrix", "v4f32", "v4f16", "OpDecorate %m2v4f32arr ArrayStride 32\nOpDecorate %m2v4f16arr ArrayStride 16\n", numElements / 8},
1300 vector<float> float32Data = getFloat32s(rnd, numElements);
1301 vector<deFloat16> float16DummyData (numElements, 0);
1303 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
1304 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1305 for (deUint32 rndModeIdx = 0; rndModeIdx < DE_LENGTH_OF_ARRAY(rndModes); ++rndModeIdx)
1307 ComputeShaderSpec spec;
1308 map<string, string> specs;
1309 string testName = string(CAPABILITIES[capIdx].name) + "_" + cTypes[tyIdx].name + "_float_" + rndModes[rndModeIdx].name;
1311 specs["capability"] = CAPABILITIES[capIdx].cap;
1312 specs["storage"] = CAPABILITIES[capIdx].decor;
1313 specs["stride"] = cTypes[tyIdx].stride;
1314 specs["base32"] = cTypes[tyIdx].base32;
1315 specs["base16"] = cTypes[tyIdx].base16;
1316 specs["rounding"] = rndModes[rndModeIdx].decor;
1317 specs["types"] = floatTypes;
1318 specs["convert"] = "OpFConvert";
1320 if (strcmp(cTypes[tyIdx].name, "matrix") == 0)
1322 if (strcmp(rndModes[rndModeIdx].name, "rtz") == 0)
1323 specs["rounding"] += "\nOpDecorate %val16_1 FPRoundingMode RTZ\n";
1324 else if (strcmp(rndModes[rndModeIdx].name, "rte") == 0)
1325 specs["rounding"] += "\nOpDecorate %val16_1 FPRoundingMode RTE\n";
1327 specs["index0"] = "%zero";
1328 specs["matrix_prefix"] = "m2";
1329 specs["matrix_types"] =
1330 "%m2v4f16 = OpTypeMatrix %v4f16 2\n"
1331 "%m2v4f32 = OpTypeMatrix %v4f32 2\n"
1332 "%m2v4f16arr = OpTypeArray %m2v4f16 %c_i32_16\n"
1333 "%m2v4f32arr = OpTypeArray %m2v4f32 %c_i32_16\n";
1334 specs["matrix_decor"] =
1335 "OpMemberDecorate %SSBO32 0 ColMajor\n"
1336 "OpMemberDecorate %SSBO32 0 MatrixStride 16\n"
1337 "OpMemberDecorate %SSBO16 0 ColMajor\n"
1338 "OpMemberDecorate %SSBO16 0 MatrixStride 8\n";
1339 specs["matrix_store"] =
1340 "%inloc_1 = OpAccessChain %v4f32ptr %ssbo32 %zero %x %c_i32_1\n"
1341 "%val32_1 = OpLoad %v4f32 %inloc_1\n"
1342 "%val16_1 = OpFConvert %v4f16 %val32_1\n"
1343 "%outloc_1 = OpAccessChain %v4f16ptr %ssbo16 %zero %x %c_i32_1\n"
1344 " OpStore %outloc_1 %val16_1\n";
1347 spec.assembly = shaderTemplate.specialize(specs);
1348 spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
1349 spec.verifyIO = rndModes[rndModeIdx].func;
1350 spec.inputTypes[0] = CAPABILITIES[capIdx].dtype;
1352 spec.inputs.push_back(BufferSp(new Float32Buffer(float32Data)));
1353 // We provided a custom verifyIO in the above in which inputs will be used for checking.
1354 // So put dummy data in the expected values.
1355 spec.outputs.push_back(BufferSp(new Float16Buffer(float16DummyData)));
1356 spec.extensions.push_back("VK_KHR_16bit_storage");
1357 spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
1359 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
1364 const char sintTypes[] =
1365 "%i16 = OpTypeInt 16 1\n"
1366 "%i16ptr = OpTypePointer Uniform %i16\n"
1367 "%i16arr = OpTypeArray %i16 %c_i32_128\n"
1368 "%v2i16 = OpTypeVector %i16 2\n"
1369 "%v2i32 = OpTypeVector %i32 2\n"
1370 "%v2i16ptr = OpTypePointer Uniform %v2i16\n"
1371 "%v2i32ptr = OpTypePointer Uniform %v2i32\n"
1372 "%v2i16arr = OpTypeArray %v2i16 %c_i32_64\n"
1373 "%v2i32arr = OpTypeArray %v2i32 %c_i32_64\n";
1375 const char uintTypes[] =
1376 "%u16 = OpTypeInt 16 0\n"
1377 "%u16ptr = OpTypePointer Uniform %u16\n"
1378 "%u32ptr = OpTypePointer Uniform %u32\n"
1379 "%u16arr = OpTypeArray %u16 %c_i32_128\n"
1380 "%u32arr = OpTypeArray %u32 %c_i32_128\n"
1381 "%v2u16 = OpTypeVector %u16 2\n"
1382 "%v2u32 = OpTypeVector %u32 2\n"
1383 "%v2u16ptr = OpTypePointer Uniform %v2u16\n"
1384 "%v2u32ptr = OpTypePointer Uniform %v2u32\n"
1385 "%v2u16arr = OpTypeArray %v2u16 %c_i32_64\n"
1386 "%v2u32arr = OpTypeArray %v2u32 %c_i32_64\n";
1388 struct CompositeType
1399 const CompositeType cTypes[] =
1401 {"scalar_sint", sintTypes, "i32", "i16", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i16arr ArrayStride 2\n", numElements},
1402 {"scalar_uint", uintTypes, "u32", "u16", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u16arr ArrayStride 2\n", numElements},
1403 {"vector_sint", sintTypes, "v2i32", "v2i16", "OpSConvert", "OpDecorate %v2i32arr ArrayStride 8\nOpDecorate %v2i16arr ArrayStride 4\n", numElements / 2},
1404 {"vector_uint", uintTypes, "v2u32", "v2u16", "OpUConvert", "OpDecorate %v2u32arr ArrayStride 8\nOpDecorate %v2u16arr ArrayStride 4\n", numElements / 2},
1407 vector<deInt32> inputs = getInt32s(rnd, numElements);
1408 vector<deInt16> outputs;
1410 outputs.reserve(inputs.size());
1411 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
1412 outputs.push_back(static_cast<deInt16>(0xffff & inputs[numNdx]));
1414 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
1415 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1417 ComputeShaderSpec spec;
1418 map<string, string> specs;
1419 string testName = string(CAPABILITIES[capIdx].name) + "_" + cTypes[tyIdx].name;
1421 specs["capability"] = CAPABILITIES[capIdx].cap;
1422 specs["storage"] = CAPABILITIES[capIdx].decor;
1423 specs["stride"] = cTypes[tyIdx].stride;
1424 specs["base32"] = cTypes[tyIdx].base32;
1425 specs["base16"] = cTypes[tyIdx].base16;
1426 specs["types"] = cTypes[tyIdx].types;
1427 specs["convert"] = cTypes[tyIdx].opcode;
1429 spec.assembly = shaderTemplate.specialize(specs);
1430 spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
1431 spec.inputTypes[0] = CAPABILITIES[capIdx].dtype;
1433 spec.inputs.push_back(BufferSp(new Int32Buffer(inputs)));
1434 spec.outputs.push_back(BufferSp(new Int16Buffer(outputs)));
1435 spec.extensions.push_back("VK_KHR_16bit_storage");
1436 spec.requestedVulkanFeatures = get16BitStorageFeatures(CAPABILITIES[capIdx].name);
1438 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
1443 void addGraphics16BitStorageUniformFloat32To16Group (tcu::TestCaseGroup* testGroup)
1445 de::Random rnd (deStringHash(testGroup->getName()));
1446 map<string, string> fragments;
1447 GraphicsResources resources;
1448 vector<string> extensions;
1449 const deUint32 numDataPoints = 256;
1450 RGBA defaultColors[4];
1451 vector<float> float32Data = getFloat32s(rnd, numDataPoints);
1452 vector<deFloat16> float16DummyData (numDataPoints, 0);
1453 const StringTemplate capabilities ("OpCapability ${cap}\n");
1455 resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(float32Data))));
1456 // We use a custom verifyIO to check the result via computing directly from inputs; the contents in outputs do not matter.
1457 resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float16Buffer(float16DummyData))));
1459 extensions.push_back("VK_KHR_16bit_storage");
1460 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
1466 GraphicsVerifyIOFunc f;
1469 getDefaultColors(defaultColors);
1472 fragments["pre_main"] =
1473 " %f16 = OpTypeFloat 16\n"
1474 "%c_i32_256 = OpConstant %i32 256\n"
1475 " %up_f32 = OpTypePointer Uniform %f32\n"
1476 " %up_f16 = OpTypePointer Uniform %f16\n"
1477 " %ra_f32 = OpTypeArray %f32 %c_i32_256\n"
1478 " %ra_f16 = OpTypeArray %f16 %c_i32_256\n"
1479 " %SSBO32 = OpTypeStruct %ra_f32\n"
1480 " %SSBO16 = OpTypeStruct %ra_f16\n"
1481 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
1482 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
1483 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
1484 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n";
1486 const StringTemplate decoration (
1487 "OpDecorate %ra_f32 ArrayStride 4\n"
1488 "OpDecorate %ra_f16 ArrayStride 2\n"
1489 "OpMemberDecorate %SSBO32 0 Offset 0\n"
1490 "OpMemberDecorate %SSBO16 0 Offset 0\n"
1491 "OpDecorate %SSBO32 ${indecor}\n"
1492 "OpDecorate %SSBO16 BufferBlock\n"
1493 "OpDecorate %ssbo32 DescriptorSet 0\n"
1494 "OpDecorate %ssbo16 DescriptorSet 0\n"
1495 "OpDecorate %ssbo32 Binding 0\n"
1496 "OpDecorate %ssbo16 Binding 1\n"
1499 fragments["testfun"] =
1500 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
1501 " %param = OpFunctionParameter %v4f32\n"
1503 "%entry = OpLabel\n"
1504 " %i = OpVariable %fp_i32 Function\n"
1505 " OpStore %i %c_i32_0\n"
1508 " %loop = OpLabel\n"
1509 " %15 = OpLoad %i32 %i\n"
1510 " %lt = OpSLessThan %bool %15 %c_i32_256\n"
1511 " OpLoopMerge %merge %inc None\n"
1512 " OpBranchConditional %lt %write %merge\n"
1514 "%write = OpLabel\n"
1515 " %30 = OpLoad %i32 %i\n"
1516 " %src = OpAccessChain %up_f32 %ssbo32 %c_i32_0 %30\n"
1517 "%val32 = OpLoad %f32 %src\n"
1518 "%val16 = OpFConvert %f16 %val32\n"
1519 " %dst = OpAccessChain %up_f16 %ssbo16 %c_i32_0 %30\n"
1520 " OpStore %dst %val16\n"
1524 " %37 = OpLoad %i32 %i\n"
1525 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
1529 "%merge = OpLabel\n"
1530 " OpReturnValue %param\n"
1534 const RndMode rndModes[] =
1536 {"rtz", "OpDecorate %val16 FPRoundingMode RTZ", graphicsCheck16BitFloats<ROUNDINGMODE_RTZ>},
1537 {"rte", "OpDecorate %val16 FPRoundingMode RTE", graphicsCheck16BitFloats<ROUNDINGMODE_RTE>},
1538 {"unspecified_rnd_mode", "", graphicsCheck16BitFloats<RoundingModeFlags(ROUNDINGMODE_RTE | ROUNDINGMODE_RTZ)>},
1541 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
1542 for (deUint32 rndModeIdx = 0; rndModeIdx < DE_LENGTH_OF_ARRAY(rndModes); ++rndModeIdx)
1544 map<string, string> specs;
1545 string testName = string(CAPABILITIES[capIdx].name) + "_scalar_float_" + rndModes[rndModeIdx].name;
1547 specs["cap"] = CAPABILITIES[capIdx].cap;
1548 specs["indecor"] = CAPABILITIES[capIdx].decor;
1549 specs["rounddecor"] = rndModes[rndModeIdx].decor;
1551 fragments["capability"] = capabilities.specialize(specs);
1552 fragments["decoration"] = decoration.specialize(specs);
1554 resources.inputs.back().first = CAPABILITIES[capIdx].dtype;
1555 resources.verifyIO = rndModes[rndModeIdx].f;
1558 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
1563 fragments["pre_main"] =
1564 " %f16 = OpTypeFloat 16\n"
1565 " %c_i32_64 = OpConstant %i32 64\n"
1566 " %v4f16 = OpTypeVector %f16 4\n"
1567 " %up_v4f32 = OpTypePointer Uniform %v4f32\n"
1568 " %up_v4f16 = OpTypePointer Uniform %v4f16\n"
1569 " %ra_v4f32 = OpTypeArray %v4f32 %c_i32_64\n"
1570 " %ra_v4f16 = OpTypeArray %v4f16 %c_i32_64\n"
1571 " %SSBO32 = OpTypeStruct %ra_v4f32\n"
1572 " %SSBO16 = OpTypeStruct %ra_v4f16\n"
1573 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
1574 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
1575 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
1576 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n";
1578 const StringTemplate decoration (
1579 "OpDecorate %ra_v4f32 ArrayStride 16\n"
1580 "OpDecorate %ra_v4f16 ArrayStride 8\n"
1581 "OpMemberDecorate %SSBO32 0 Offset 0\n"
1582 "OpMemberDecorate %SSBO16 0 Offset 0\n"
1583 "OpDecorate %SSBO32 ${indecor}\n"
1584 "OpDecorate %SSBO16 BufferBlock\n"
1585 "OpDecorate %ssbo32 DescriptorSet 0\n"
1586 "OpDecorate %ssbo16 DescriptorSet 0\n"
1587 "OpDecorate %ssbo32 Binding 0\n"
1588 "OpDecorate %ssbo16 Binding 1\n"
1591 // ssbo16[] <- convert ssbo32[] to 16bit float
1592 fragments["testfun"] =
1593 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
1594 " %param = OpFunctionParameter %v4f32\n"
1596 "%entry = OpLabel\n"
1597 " %i = OpVariable %fp_i32 Function\n"
1598 " OpStore %i %c_i32_0\n"
1601 " %loop = OpLabel\n"
1602 " %15 = OpLoad %i32 %i\n"
1603 " %lt = OpSLessThan %bool %15 %c_i32_64\n"
1604 " OpLoopMerge %merge %inc None\n"
1605 " OpBranchConditional %lt %write %merge\n"
1607 "%write = OpLabel\n"
1608 " %30 = OpLoad %i32 %i\n"
1609 " %src = OpAccessChain %up_v4f32 %ssbo32 %c_i32_0 %30\n"
1610 "%val32 = OpLoad %v4f32 %src\n"
1611 "%val16 = OpFConvert %v4f16 %val32\n"
1612 " %dst = OpAccessChain %up_v4f16 %ssbo16 %c_i32_0 %30\n"
1613 " OpStore %dst %val16\n"
1617 " %37 = OpLoad %i32 %i\n"
1618 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
1622 "%merge = OpLabel\n"
1623 " OpReturnValue %param\n"
1627 const RndMode rndModes[] =
1629 {"rtz", "OpDecorate %val16 FPRoundingMode RTZ", graphicsCheck16BitFloats<ROUNDINGMODE_RTZ>},
1630 {"rte", "OpDecorate %val16 FPRoundingMode RTE", graphicsCheck16BitFloats<ROUNDINGMODE_RTE>},
1631 {"unspecified_rnd_mode", "", graphicsCheck16BitFloats<RoundingModeFlags(ROUNDINGMODE_RTE | ROUNDINGMODE_RTZ)>},
1634 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
1635 for (deUint32 rndModeIdx = 0; rndModeIdx < DE_LENGTH_OF_ARRAY(rndModes); ++rndModeIdx)
1637 map<string, string> specs;
1638 string testName = string(CAPABILITIES[capIdx].name) + "_vector_float_" + rndModes[rndModeIdx].name;
1640 specs["cap"] = CAPABILITIES[capIdx].cap;
1641 specs["indecor"] = CAPABILITIES[capIdx].decor;
1642 specs["rounddecor"] = rndModes[rndModeIdx].decor;
1644 fragments["capability"] = capabilities.specialize(specs);
1645 fragments["decoration"] = decoration.specialize(specs);
1647 resources.inputs.back().first = CAPABILITIES[capIdx].dtype;
1648 resources.verifyIO = rndModes[rndModeIdx].f;
1651 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
1656 fragments["pre_main"] =
1657 " %f16 = OpTypeFloat 16\n"
1658 " %c_i32_16 = OpConstant %i32 16\n"
1659 " %v4f16 = OpTypeVector %f16 4\n"
1660 " %m4x4f32 = OpTypeMatrix %v4f32 4\n"
1661 " %m4x4f16 = OpTypeMatrix %v4f16 4\n"
1662 " %up_v4f32 = OpTypePointer Uniform %v4f32\n"
1663 " %up_v4f16 = OpTypePointer Uniform %v4f16\n"
1664 "%a16m4x4f32 = OpTypeArray %m4x4f32 %c_i32_16\n"
1665 "%a16m4x4f16 = OpTypeArray %m4x4f16 %c_i32_16\n"
1666 " %SSBO32 = OpTypeStruct %a16m4x4f32\n"
1667 " %SSBO16 = OpTypeStruct %a16m4x4f16\n"
1668 " %up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
1669 " %up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
1670 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
1671 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n";
1673 const StringTemplate decoration (
1674 "OpDecorate %a16m4x4f32 ArrayStride 64\n"
1675 "OpDecorate %a16m4x4f16 ArrayStride 32\n"
1676 "OpMemberDecorate %SSBO32 0 Offset 0\n"
1677 "OpMemberDecorate %SSBO32 0 ColMajor\n"
1678 "OpMemberDecorate %SSBO32 0 MatrixStride 16\n"
1679 "OpMemberDecorate %SSBO16 0 Offset 0\n"
1680 "OpMemberDecorate %SSBO16 0 ColMajor\n"
1681 "OpMemberDecorate %SSBO16 0 MatrixStride 8\n"
1682 "OpDecorate %SSBO32 ${indecor}\n"
1683 "OpDecorate %SSBO16 BufferBlock\n"
1684 "OpDecorate %ssbo32 DescriptorSet 0\n"
1685 "OpDecorate %ssbo16 DescriptorSet 0\n"
1686 "OpDecorate %ssbo32 Binding 0\n"
1687 "OpDecorate %ssbo16 Binding 1\n"
1690 fragments["testfun"] =
1691 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
1692 " %param = OpFunctionParameter %v4f32\n"
1694 "%entry = OpLabel\n"
1695 " %i = OpVariable %fp_i32 Function\n"
1696 " OpStore %i %c_i32_0\n"
1699 " %loop = OpLabel\n"
1700 " %15 = OpLoad %i32 %i\n"
1701 " %lt = OpSLessThan %bool %15 %c_i32_16\n"
1702 " OpLoopMerge %merge %inc None\n"
1703 " OpBranchConditional %lt %write %merge\n"
1705 " %write = OpLabel\n"
1706 " %30 = OpLoad %i32 %i\n"
1707 " %src_0 = OpAccessChain %up_v4f32 %ssbo32 %c_i32_0 %30 %c_i32_0\n"
1708 " %src_1 = OpAccessChain %up_v4f32 %ssbo32 %c_i32_0 %30 %c_i32_1\n"
1709 " %src_2 = OpAccessChain %up_v4f32 %ssbo32 %c_i32_0 %30 %c_i32_2\n"
1710 " %src_3 = OpAccessChain %up_v4f32 %ssbo32 %c_i32_0 %30 %c_i32_3\n"
1711 "%val32_0 = OpLoad %v4f32 %src_0\n"
1712 "%val32_1 = OpLoad %v4f32 %src_1\n"
1713 "%val32_2 = OpLoad %v4f32 %src_2\n"
1714 "%val32_3 = OpLoad %v4f32 %src_3\n"
1715 "%val16_0 = OpFConvert %v4f16 %val32_0\n"
1716 "%val16_1 = OpFConvert %v4f16 %val32_1\n"
1717 "%val16_2 = OpFConvert %v4f16 %val32_2\n"
1718 "%val16_3 = OpFConvert %v4f16 %val32_3\n"
1719 " %dst_0 = OpAccessChain %up_v4f16 %ssbo16 %c_i32_0 %30 %c_i32_0\n"
1720 " %dst_1 = OpAccessChain %up_v4f16 %ssbo16 %c_i32_0 %30 %c_i32_1\n"
1721 " %dst_2 = OpAccessChain %up_v4f16 %ssbo16 %c_i32_0 %30 %c_i32_2\n"
1722 " %dst_3 = OpAccessChain %up_v4f16 %ssbo16 %c_i32_0 %30 %c_i32_3\n"
1723 " OpStore %dst_0 %val16_0\n"
1724 " OpStore %dst_1 %val16_1\n"
1725 " OpStore %dst_2 %val16_2\n"
1726 " OpStore %dst_3 %val16_3\n"
1730 " %37 = OpLoad %i32 %i\n"
1731 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
1735 "%merge = OpLabel\n"
1736 " OpReturnValue %param\n"
1740 const RndMode rndModes[] =
1742 {"rte", "OpDecorate %val16_0 FPRoundingMode RTE\nOpDecorate %val16_1 FPRoundingMode RTE\nOpDecorate %val16_2 FPRoundingMode RTE\nOpDecorate %val16_3 FPRoundingMode RTE", graphicsCheck16BitFloats<ROUNDINGMODE_RTE>},
1743 {"rtz", "OpDecorate %val16_0 FPRoundingMode RTZ\nOpDecorate %val16_1 FPRoundingMode RTZ\nOpDecorate %val16_2 FPRoundingMode RTZ\nOpDecorate %val16_3 FPRoundingMode RTZ", graphicsCheck16BitFloats<ROUNDINGMODE_RTZ>},
1744 {"unspecified_rnd_mode", "", graphicsCheck16BitFloats<RoundingModeFlags(ROUNDINGMODE_RTE | ROUNDINGMODE_RTZ)>},
1747 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
1748 for (deUint32 rndModeIdx = 0; rndModeIdx < DE_LENGTH_OF_ARRAY(rndModes); ++rndModeIdx)
1750 map<string, string> specs;
1751 string testName = string(CAPABILITIES[capIdx].name) + "_matrix_float_" + rndModes[rndModeIdx].name;
1753 specs["cap"] = CAPABILITIES[capIdx].cap;
1754 specs["indecor"] = CAPABILITIES[capIdx].decor;
1755 specs["rounddecor"] = rndModes[rndModeIdx].decor;
1757 fragments["capability"] = capabilities.specialize(specs);
1758 fragments["decoration"] = decoration.specialize(specs);
1760 resources.inputs.back().first = CAPABILITIES[capIdx].dtype;
1761 resources.verifyIO = rndModes[rndModeIdx].f;
1764 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
1769 void addGraphics16BitStorageInputOutputFloat32To16Group (tcu::TestCaseGroup* testGroup)
1771 de::Random rnd (deStringHash(testGroup->getName()));
1772 RGBA defaultColors[4];
1773 vector<string> extensions;
1774 map<string, string> fragments = passthruFragments();
1775 const deUint32 numDataPoints = 64;
1776 vector<float> float32Data = getFloat32s(rnd, numDataPoints);
1778 extensions.push_back("VK_KHR_16bit_storage");
1780 fragments["capability"] = "OpCapability StorageInputOutput16\n";
1781 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
1783 getDefaultColors(defaultColors);
1789 RoundingModeFlags flags;
1792 const RndMode rndModes[] =
1794 {"rtz", "OpDecorate %ret FPRoundingMode RTZ", ROUNDINGMODE_RTZ},
1795 {"rte", "OpDecorate %ret FPRoundingMode RTE", ROUNDINGMODE_RTE},
1796 {"unspecified_rnd_mode", "", RoundingModeFlags(ROUNDINGMODE_RTE | ROUNDINGMODE_RTZ)},
1802 const char* interfaceOpFunc;
1803 const char* preMain;
1804 const char* inputType;
1805 const char* outputType;
1806 deUint32 numPerCase;
1807 deUint32 numElements;
1810 const Case cases[] =
1815 "%interface_op_func = OpFunction %f16 None %f16_f32_function\n"
1816 " %io_param1 = OpFunctionParameter %f32\n"
1817 " %entry = OpLabel\n"
1818 " %ret = OpFConvert %f16 %io_param1\n"
1819 " OpReturnValue %ret\n"
1822 " %f16 = OpTypeFloat 16\n"
1823 " %op_f16 = OpTypePointer Output %f16\n"
1824 " %a3f16 = OpTypeArray %f16 %c_i32_3\n"
1825 " %op_a3f16 = OpTypePointer Output %a3f16\n"
1826 "%f16_f32_function = OpTypeFunction %f16 %f32\n"
1827 " %a3f32 = OpTypeArray %f32 %c_i32_3\n"
1828 " %ip_a3f32 = OpTypePointer Input %a3f32\n",
1838 "%interface_op_func = OpFunction %v2f16 None %v2f16_v2f32_function\n"
1839 " %io_param1 = OpFunctionParameter %v2f32\n"
1840 " %entry = OpLabel\n"
1841 " %ret = OpFConvert %v2f16 %io_param1\n"
1842 " OpReturnValue %ret\n"
1845 " %f16 = OpTypeFloat 16\n"
1846 " %v2f16 = OpTypeVector %f16 2\n"
1847 " %op_v2f16 = OpTypePointer Output %v2f16\n"
1848 " %a3v2f16 = OpTypeArray %v2f16 %c_i32_3\n"
1849 " %op_a3v2f16 = OpTypePointer Output %a3v2f16\n"
1850 "%v2f16_v2f32_function = OpTypeFunction %v2f16 %v2f32\n"
1851 " %a3v2f32 = OpTypeArray %v2f32 %c_i32_3\n"
1852 " %ip_a3v2f32 = OpTypePointer Input %a3v2f32\n",
1861 VulkanFeatures requiredFeatures;
1862 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
1864 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
1865 for (deUint32 rndModeIdx = 0; rndModeIdx < DE_LENGTH_OF_ARRAY(rndModes); ++rndModeIdx)
1867 fragments["interface_op_func"] = cases[caseIdx].interfaceOpFunc;
1868 fragments["pre_main"] = cases[caseIdx].preMain;
1869 fragments["decoration"] = rndModes[rndModeIdx].decor;
1871 fragments["input_type"] = cases[caseIdx].inputType;
1872 fragments["output_type"] = cases[caseIdx].outputType;
1874 GraphicsInterfaces interfaces;
1875 const deUint32 numPerCase = cases[caseIdx].numPerCase;
1876 vector<float> subInputs (numPerCase);
1877 vector<deFloat16> subOutputs (numPerCase);
1879 // The pipeline need this to call compare16BitFloat() when checking the result.
1880 interfaces.setRoundingMode(rndModes[rndModeIdx].flags);
1882 for (deUint32 caseNdx = 0; caseNdx < numDataPoints / numPerCase; ++caseNdx)
1884 string testName = string(cases[caseIdx].name) + numberToString(caseNdx) + "_" + rndModes[rndModeIdx].name;
1886 for (deUint32 numNdx = 0; numNdx < numPerCase; ++numNdx)
1888 subInputs[numNdx] = float32Data[caseNdx * numPerCase + numNdx];
1889 // We derive the expected result from inputs directly in the graphics pipeline.
1890 subOutputs[numNdx] = 0;
1892 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT32), BufferSp(new Float32Buffer(subInputs))),
1893 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT16), BufferSp(new Float16Buffer(subOutputs))));
1894 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
1899 void addGraphics16BitStorageInputOutputFloat16To32Group (tcu::TestCaseGroup* testGroup)
1901 de::Random rnd (deStringHash(testGroup->getName()));
1902 RGBA defaultColors[4];
1903 vector<string> extensions;
1904 map<string, string> fragments = passthruFragments();
1905 const deUint32 numDataPoints = 64;
1906 vector<deFloat16> float16Data (getFloat16s(rnd, numDataPoints));
1907 vector<float> float32Data;
1909 float32Data.reserve(numDataPoints);
1910 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
1911 float32Data.push_back(deFloat16To32(float16Data[numIdx]));
1913 extensions.push_back("VK_KHR_16bit_storage");
1915 fragments["capability"] = "OpCapability StorageInputOutput16\n";
1916 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
1918 getDefaultColors(defaultColors);
1923 const char* interfaceOpFunc;
1924 const char* preMain;
1925 const char* inputType;
1926 const char* outputType;
1927 deUint32 numPerCase;
1928 deUint32 numElements;
1936 "%interface_op_func = OpFunction %f32 None %f32_f16_function\n"
1937 " %io_param1 = OpFunctionParameter %f16\n"
1938 " %entry = OpLabel\n"
1939 " %ret = OpFConvert %f32 %io_param1\n"
1940 " OpReturnValue %ret\n"
1943 " %f16 = OpTypeFloat 16\n"
1944 " %ip_f16 = OpTypePointer Input %f16\n"
1945 " %a3f16 = OpTypeArray %f16 %c_i32_3\n"
1946 " %ip_a3f16 = OpTypePointer Input %a3f16\n"
1947 "%f32_f16_function = OpTypeFunction %f32 %f16\n"
1948 " %a3f32 = OpTypeArray %f32 %c_i32_3\n"
1949 " %op_a3f32 = OpTypePointer Output %a3f32\n",
1959 "%interface_op_func = OpFunction %v2f32 None %v2f32_v2f16_function\n"
1960 " %io_param1 = OpFunctionParameter %v2f16\n"
1961 " %entry = OpLabel\n"
1962 " %ret = OpFConvert %v2f32 %io_param1\n"
1963 " OpReturnValue %ret\n"
1966 " %f16 = OpTypeFloat 16\n"
1967 " %v2f16 = OpTypeVector %f16 2\n"
1968 " %ip_v2f16 = OpTypePointer Input %v2f16\n"
1969 " %a3v2f16 = OpTypeArray %v2f16 %c_i32_3\n"
1970 " %ip_a3v2f16 = OpTypePointer Input %a3v2f16\n"
1971 "%v2f32_v2f16_function = OpTypeFunction %v2f32 %v2f16\n"
1972 " %a3v2f32 = OpTypeArray %v2f32 %c_i32_3\n"
1973 " %op_a3v2f32 = OpTypePointer Output %a3v2f32\n",
1982 VulkanFeatures requiredFeatures;
1983 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
1985 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
1987 fragments["interface_op_func"] = cases[caseIdx].interfaceOpFunc;
1988 fragments["pre_main"] = cases[caseIdx].preMain;
1990 fragments["input_type"] = cases[caseIdx].inputType;
1991 fragments["output_type"] = cases[caseIdx].outputType;
1993 GraphicsInterfaces interfaces;
1994 const deUint32 numPerCase = cases[caseIdx].numPerCase;
1995 vector<deFloat16> subInputs (numPerCase);
1996 vector<float> subOutputs (numPerCase);
1998 for (deUint32 caseNdx = 0; caseNdx < numDataPoints / numPerCase; ++caseNdx)
2000 string testName = string(cases[caseIdx].name) + numberToString(caseNdx);
2002 for (deUint32 numNdx = 0; numNdx < numPerCase; ++numNdx)
2004 subInputs[numNdx] = float16Data[caseNdx * numPerCase + numNdx];
2005 subOutputs[numNdx] = float32Data[caseNdx * numPerCase + numNdx];
2007 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT16), BufferSp(new Float16Buffer(subInputs))),
2008 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_FLOAT32), BufferSp(new Float32Buffer(subOutputs))));
2009 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
2014 void addGraphics16BitStorageInputOutputInt32To16Group (tcu::TestCaseGroup* testGroup)
2016 de::Random rnd (deStringHash(testGroup->getName()));
2017 RGBA defaultColors[4];
2018 vector<string> extensions;
2019 map<string, string> fragments = passthruFragments();
2020 const deUint32 numDataPoints = 64;
2021 // inputs and outputs are declared to be vectors of signed integers.
2022 // However, depending on the test, they may be interpreted as unsiged
2023 // integers. That won't be a problem as long as we passed the bits
2024 // in faithfully to the pipeline.
2025 vector<deInt32> inputs = getInt32s(rnd, numDataPoints);
2026 vector<deInt16> outputs;
2028 outputs.reserve(inputs.size());
2029 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
2030 outputs.push_back(static_cast<deInt16>(0xffff & inputs[numNdx]));
2032 extensions.push_back("VK_KHR_16bit_storage");
2034 fragments["capability"] = "OpCapability StorageInputOutput16\n";
2035 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
2037 getDefaultColors(defaultColors);
2039 const StringTemplate scalarInterfaceOpFunc(
2040 "%interface_op_func = OpFunction %${type16} None %${type16}_${type32}_function\n"
2041 " %io_param1 = OpFunctionParameter %${type32}\n"
2042 " %entry = OpLabel\n"
2043 " %ret = ${convert} %${type16} %io_param1\n"
2044 " OpReturnValue %ret\n"
2045 " OpFunctionEnd\n");
2047 const StringTemplate scalarPreMain(
2048 " %${type16} = OpTypeInt 16 ${signed}\n"
2049 " %op_${type16} = OpTypePointer Output %${type16}\n"
2050 " %a3${type16} = OpTypeArray %${type16} %c_i32_3\n"
2051 " %op_a3${type16} = OpTypePointer Output %a3${type16}\n"
2052 "%${type16}_${type32}_function = OpTypeFunction %${type16} %${type32}\n"
2053 " %a3${type32} = OpTypeArray %${type32} %c_i32_3\n"
2054 " %ip_a3${type32} = OpTypePointer Input %a3${type32}\n");
2056 const StringTemplate vecInterfaceOpFunc(
2057 "%interface_op_func = OpFunction %${type16} None %${type16}_${type32}_function\n"
2058 " %io_param1 = OpFunctionParameter %${type32}\n"
2059 " %entry = OpLabel\n"
2060 " %ret = ${convert} %${type16} %io_param1\n"
2061 " OpReturnValue %ret\n"
2062 " OpFunctionEnd\n");
2064 const StringTemplate vecPreMain(
2065 " %i16 = OpTypeInt 16 1\n"
2066 " %u16 = OpTypeInt 16 0\n"
2067 " %v4i16 = OpTypeVector %i16 4\n"
2068 " %v4u16 = OpTypeVector %u16 4\n"
2069 " %op_${type16} = OpTypePointer Output %${type16}\n"
2070 " %a3${type16} = OpTypeArray %${type16} %c_i32_3\n"
2071 " %op_a3${type16} = OpTypePointer Output %a3${type16}\n"
2072 "%${type16}_${type32}_function = OpTypeFunction %${type16} %${type32}\n"
2073 " %a3${type32} = OpTypeArray %${type32} %c_i32_3\n"
2074 " %ip_a3${type32} = OpTypePointer Input %a3${type32}\n");
2079 const StringTemplate& interfaceOpFunc;
2080 const StringTemplate& preMain;
2085 deUint32 numPerCase;
2086 deUint32 numElements;
2091 {"scalar_sint", scalarInterfaceOpFunc, scalarPreMain, "i32", "i16", "1", "OpSConvert", 4, 1},
2092 {"scalar_uint", scalarInterfaceOpFunc, scalarPreMain, "u32", "u16", "0", "OpUConvert", 4, 1},
2093 {"vector_sint", vecInterfaceOpFunc, vecPreMain, "v4i32", "v4i16", "1", "OpSConvert", 4 * 4, 4},
2094 {"vector_uint", vecInterfaceOpFunc, vecPreMain, "v4u32", "v4u16", "0", "OpUConvert", 4 * 4, 4},
2097 VulkanFeatures requiredFeatures;
2098 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
2100 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
2102 map<string, string> specs;
2104 specs["type32"] = cases[caseIdx].type32;
2105 specs["type16"] = cases[caseIdx].type16;
2106 specs["signed"] = cases[caseIdx].sign;
2107 specs["convert"] = cases[caseIdx].opcode;
2109 fragments["pre_main"] = cases[caseIdx].preMain.specialize(specs);
2110 fragments["interface_op_func"] = cases[caseIdx].interfaceOpFunc.specialize(specs);
2111 fragments["input_type"] = cases[caseIdx].type32;
2112 fragments["output_type"] = cases[caseIdx].type16;
2114 GraphicsInterfaces interfaces;
2115 const deUint32 numPerCase = cases[caseIdx].numPerCase;
2116 vector<deInt32> subInputs (numPerCase);
2117 vector<deInt16> subOutputs (numPerCase);
2119 for (deUint32 caseNdx = 0; caseNdx < numDataPoints / numPerCase; ++caseNdx)
2121 string testName = string(cases[caseIdx].name) + numberToString(caseNdx);
2123 for (deUint32 numNdx = 0; numNdx < numPerCase; ++numNdx)
2125 subInputs[numNdx] = inputs[caseNdx * numPerCase + numNdx];
2126 subOutputs[numNdx] = outputs[caseNdx * numPerCase + numNdx];
2128 if (strcmp(cases[caseIdx].sign, "1") == 0)
2130 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_INT32), BufferSp(new Int32Buffer(subInputs))),
2131 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_INT16), BufferSp(new Int16Buffer(subOutputs))));
2135 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_UINT32), BufferSp(new Int32Buffer(subInputs))),
2136 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_UINT16), BufferSp(new Int16Buffer(subOutputs))));
2138 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
2143 void addGraphics16BitStorageInputOutputInt16To32Group (tcu::TestCaseGroup* testGroup)
2145 de::Random rnd (deStringHash(testGroup->getName()));
2146 RGBA defaultColors[4];
2147 vector<string> extensions;
2148 map<string, string> fragments = passthruFragments();
2149 const deUint32 numDataPoints = 64;
2150 // inputs and outputs are declared to be vectors of signed integers.
2151 // However, depending on the test, they may be interpreted as unsiged
2152 // integers. That won't be a problem as long as we passed the bits
2153 // in faithfully to the pipeline.
2154 vector<deInt16> inputs = getInt16s(rnd, numDataPoints);
2155 vector<deInt32> sOutputs;
2156 vector<deInt32> uOutputs;
2157 const deUint16 signBitMask = 0x8000;
2158 const deUint32 signExtendMask = 0xffff0000;
2160 sOutputs.reserve(inputs.size());
2161 uOutputs.reserve(inputs.size());
2163 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
2165 uOutputs.push_back(static_cast<deUint16>(inputs[numNdx]));
2166 if (inputs[numNdx] & signBitMask)
2167 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx] | signExtendMask));
2169 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx]));
2172 extensions.push_back("VK_KHR_16bit_storage");
2174 fragments["capability"] = "OpCapability StorageInputOutput16\n";
2175 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
2177 getDefaultColors(defaultColors);
2179 const StringTemplate scalarIfOpFunc (
2180 "%interface_op_func = OpFunction %${type32} None %${type32}_${type16}_function\n"
2181 " %io_param1 = OpFunctionParameter %${type16}\n"
2182 " %entry = OpLabel\n"
2183 " %ret = ${convert} %${type32} %io_param1\n"
2184 " OpReturnValue %ret\n"
2185 " OpFunctionEnd\n");
2187 const StringTemplate scalarPreMain (
2188 " %${type16} = OpTypeInt 16 ${signed}\n"
2189 " %ip_${type16} = OpTypePointer Input %${type16}\n"
2190 " %a3${type16} = OpTypeArray %${type16} %c_i32_3\n"
2191 " %ip_a3${type16} = OpTypePointer Input %a3${type16}\n"
2192 "%${type32}_${type16}_function = OpTypeFunction %${type32} %${type16}\n"
2193 " %a3${type32} = OpTypeArray %${type32} %c_i32_3\n"
2194 " %op_a3${type32} = OpTypePointer Output %a3${type32}\n");
2196 const StringTemplate vecIfOpFunc (
2197 "%interface_op_func = OpFunction %${type32} None %${type32}_${type16}_function\n"
2198 " %io_param1 = OpFunctionParameter %${type16}\n"
2199 " %entry = OpLabel\n"
2200 " %ret = ${convert} %${type32} %io_param1\n"
2201 " OpReturnValue %ret\n"
2202 " OpFunctionEnd\n");
2204 const StringTemplate vecPreMain (
2205 " %i16 = OpTypeInt 16 1\n"
2206 " %u16 = OpTypeInt 16 0\n"
2207 " %v4i16 = OpTypeVector %i16 4\n"
2208 " %v4u16 = OpTypeVector %u16 4\n"
2209 " %ip_${type16} = OpTypePointer Input %${type16}\n"
2210 " %a3${type16} = OpTypeArray %${type16} %c_i32_3\n"
2211 " %ip_a3${type16} = OpTypePointer Input %a3${type16}\n"
2212 "%${type32}_${type16}_function = OpTypeFunction %${type32} %${type16}\n"
2213 " %a3${type32} = OpTypeArray %${type32} %c_i32_3\n"
2214 " %op_a3${type32} = OpTypePointer Output %a3${type32}\n");
2219 const StringTemplate& interfaceOpFunc;
2220 const StringTemplate& preMain;
2225 deUint32 numPerCase;
2226 deUint32 numElements;
2231 {"scalar_sint", scalarIfOpFunc, scalarPreMain, "i32", "i16", "1", "OpSConvert", 4, 1},
2232 {"scalar_uint", scalarIfOpFunc, scalarPreMain, "u32", "u16", "0", "OpUConvert", 4, 1},
2233 {"vector_sint", vecIfOpFunc, vecPreMain, "v4i32", "v4i16", "1", "OpSConvert", 4 * 4, 4},
2234 {"vector_uint", vecIfOpFunc, vecPreMain, "v4u32", "v4u16", "0", "OpUConvert", 4 * 4, 4},
2237 VulkanFeatures requiredFeatures;
2238 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_INPUT_OUTPUT;
2240 for (deUint32 caseIdx = 0; caseIdx < DE_LENGTH_OF_ARRAY(cases); ++caseIdx)
2242 map<string, string> specs;
2244 specs["type32"] = cases[caseIdx].type32;
2245 specs["type16"] = cases[caseIdx].type16;
2246 specs["signed"] = cases[caseIdx].sign;
2247 specs["convert"] = cases[caseIdx].opcode;
2249 fragments["pre_main"] = cases[caseIdx].preMain.specialize(specs);
2250 fragments["interface_op_func"] = cases[caseIdx].interfaceOpFunc.specialize(specs);
2251 fragments["input_type"] = cases[caseIdx].type16;
2252 fragments["output_type"] = cases[caseIdx].type32;
2254 GraphicsInterfaces interfaces;
2255 const deUint32 numPerCase = cases[caseIdx].numPerCase;
2256 vector<deInt16> subInputs (numPerCase);
2257 vector<deInt32> subOutputs (numPerCase);
2259 for (deUint32 caseNdx = 0; caseNdx < numDataPoints / numPerCase; ++caseNdx)
2261 string testName = string(cases[caseIdx].name) + numberToString(caseNdx);
2263 for (deUint32 numNdx = 0; numNdx < numPerCase; ++numNdx)
2265 subInputs[numNdx] = inputs[caseNdx * numPerCase + numNdx];
2266 if (cases[caseIdx].sign[0] == '1')
2267 subOutputs[numNdx] = sOutputs[caseNdx * numPerCase + numNdx];
2269 subOutputs[numNdx] = uOutputs[caseNdx * numPerCase + numNdx];
2271 if (strcmp(cases[caseIdx].sign, "1") == 0)
2273 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_INT16), BufferSp(new Int16Buffer(subInputs))),
2274 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_INT32), BufferSp(new Int32Buffer(subOutputs))));
2278 interfaces.setInputOutput(std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_UINT16), BufferSp(new Int16Buffer(subInputs))),
2279 std::make_pair(IFDataType(cases[caseIdx].numElements, NUMBERTYPE_UINT32), BufferSp(new Int32Buffer(subOutputs))));
2281 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, interfaces, extensions, testGroup, requiredFeatures);
2286 void addGraphics16BitStoragePushConstantFloat16To32Group (tcu::TestCaseGroup* testGroup)
2288 de::Random rnd (deStringHash(testGroup->getName()));
2289 map<string, string> fragments;
2290 RGBA defaultColors[4];
2291 vector<string> extensions;
2292 GraphicsResources resources;
2294 const deUint32 numDataPoints = 64;
2295 vector<deFloat16> float16Data (getFloat16s(rnd, numDataPoints));
2296 vector<float> float32Data;
2297 VulkanFeatures requiredFeatures;
2299 float32Data.reserve(numDataPoints);
2300 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
2301 float32Data.push_back(deFloat16To32(float16Data[numIdx]));
2303 extensions.push_back("VK_KHR_16bit_storage");
2304 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
2306 fragments["capability"] = "OpCapability StoragePushConstant16\n";
2307 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
2309 pcs.setPushConstant(BufferSp(new Float16Buffer(float16Data)));
2310 resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(float32Data))));
2311 resources.verifyIO = check32BitFloats;
2313 getDefaultColors(defaultColors);
2315 const StringTemplate testFun (
2316 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
2317 " %param = OpFunctionParameter %v4f32\n"
2319 "%entry = OpLabel\n"
2320 " %i = OpVariable %fp_i32 Function\n"
2321 " OpStore %i %c_i32_0\n"
2324 " %loop = OpLabel\n"
2325 " %15 = OpLoad %i32 %i\n"
2326 " %lt = OpSLessThan %bool %15 ${count}\n"
2327 " OpLoopMerge %merge %inc None\n"
2328 " OpBranchConditional %lt %write %merge\n"
2330 "%write = OpLabel\n"
2331 " %30 = OpLoad %i32 %i\n"
2332 " %src = OpAccessChain ${pp_type16} %pc16 %c_i32_0 %30 ${index0:opt}\n"
2333 "%val16 = OpLoad ${f_type16} %src\n"
2334 "%val32 = OpFConvert ${f_type32} %val16\n"
2335 " %dst = OpAccessChain ${up_type32} %ssbo32 %c_i32_0 %30 ${index0:opt}\n"
2336 " OpStore %dst %val32\n"
2343 " %37 = OpLoad %i32 %i\n"
2344 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
2348 "%merge = OpLabel\n"
2349 " OpReturnValue %param\n"
2354 fragments["pre_main"] =
2355 " %f16 = OpTypeFloat 16\n"
2356 " %c_i32_64 = OpConstant %i32 64\n" // Should be the same as numDataPoints
2357 " %a64f16 = OpTypeArray %f16 %c_i32_64\n"
2358 " %a64f32 = OpTypeArray %f32 %c_i32_64\n"
2359 " %pp_f16 = OpTypePointer PushConstant %f16\n"
2360 " %up_f32 = OpTypePointer Uniform %f32\n"
2361 " %SSBO32 = OpTypeStruct %a64f32\n"
2362 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2363 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2364 " %PC16 = OpTypeStruct %a64f16\n"
2365 " %pp_PC16 = OpTypePointer PushConstant %PC16\n"
2366 " %pc16 = OpVariable %pp_PC16 PushConstant\n";
2368 fragments["decoration"] =
2369 "OpDecorate %a64f16 ArrayStride 2\n"
2370 "OpDecorate %a64f32 ArrayStride 4\n"
2371 "OpDecorate %SSBO32 BufferBlock\n"
2372 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2373 "OpDecorate %PC16 Block\n"
2374 "OpMemberDecorate %PC16 0 Offset 0\n"
2375 "OpDecorate %ssbo32 DescriptorSet 0\n"
2376 "OpDecorate %ssbo32 Binding 0\n";
2378 map<string, string> specs;
2380 specs["count"] = "%c_i32_64";
2381 specs["pp_type16"] = "%pp_f16";
2382 specs["f_type16"] = "%f16";
2383 specs["f_type32"] = "%f32";
2384 specs["up_type32"] = "%up_f32";
2386 fragments["testfun"] = testFun.specialize(specs);
2388 createTestsForAllStages("scalar", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
2392 fragments["pre_main"] =
2393 " %f16 = OpTypeFloat 16\n"
2394 " %v4f16 = OpTypeVector %f16 4\n"
2395 " %c_i32_16 = OpConstant %i32 16\n"
2396 " %a16v4f16 = OpTypeArray %v4f16 %c_i32_16\n"
2397 " %a16v4f32 = OpTypeArray %v4f32 %c_i32_16\n"
2398 " %pp_v4f16 = OpTypePointer PushConstant %v4f16\n"
2399 " %up_v4f32 = OpTypePointer Uniform %v4f32\n"
2400 " %SSBO32 = OpTypeStruct %a16v4f32\n"
2401 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2402 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2403 " %PC16 = OpTypeStruct %a16v4f16\n"
2404 " %pp_PC16 = OpTypePointer PushConstant %PC16\n"
2405 " %pc16 = OpVariable %pp_PC16 PushConstant\n";
2407 fragments["decoration"] =
2408 "OpDecorate %a16v4f16 ArrayStride 8\n"
2409 "OpDecorate %a16v4f32 ArrayStride 16\n"
2410 "OpDecorate %SSBO32 BufferBlock\n"
2411 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2412 "OpDecorate %PC16 Block\n"
2413 "OpMemberDecorate %PC16 0 Offset 0\n"
2414 "OpDecorate %ssbo32 DescriptorSet 0\n"
2415 "OpDecorate %ssbo32 Binding 0\n";
2417 map<string, string> specs;
2419 specs["count"] = "%c_i32_16";
2420 specs["pp_type16"] = "%pp_v4f16";
2421 specs["f_type16"] = "%v4f16";
2422 specs["f_type32"] = "%v4f32";
2423 specs["up_type32"] = "%up_v4f32";
2425 fragments["testfun"] = testFun.specialize(specs);
2427 createTestsForAllStages("vector", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
2431 fragments["pre_main"] =
2432 " %c_i32_8 = OpConstant %i32 8\n"
2433 " %f16 = OpTypeFloat 16\n"
2434 " %v4f16 = OpTypeVector %f16 4\n"
2435 " %m2v4f16 = OpTypeMatrix %v4f16 2\n"
2436 " %m2v4f32 = OpTypeMatrix %v4f32 2\n"
2437 "%a8m2v4f16 = OpTypeArray %m2v4f16 %c_i32_8\n"
2438 "%a8m2v4f32 = OpTypeArray %m2v4f32 %c_i32_8\n"
2439 " %pp_v4f16 = OpTypePointer PushConstant %v4f16\n"
2440 " %up_v4f32 = OpTypePointer Uniform %v4f32\n"
2441 " %SSBO32 = OpTypeStruct %a8m2v4f32\n"
2442 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2443 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2444 " %PC16 = OpTypeStruct %a8m2v4f16\n"
2445 " %pp_PC16 = OpTypePointer PushConstant %PC16\n"
2446 " %pc16 = OpVariable %pp_PC16 PushConstant\n";
2448 fragments["decoration"] =
2449 "OpDecorate %a8m2v4f16 ArrayStride 16\n"
2450 "OpDecorate %a8m2v4f32 ArrayStride 32\n"
2451 "OpDecorate %SSBO32 BufferBlock\n"
2452 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2453 "OpMemberDecorate %SSBO32 0 ColMajor\n"
2454 "OpMemberDecorate %SSBO32 0 MatrixStride 16\n"
2455 "OpDecorate %PC16 Block\n"
2456 "OpMemberDecorate %PC16 0 Offset 0\n"
2457 "OpMemberDecorate %PC16 0 ColMajor\n"
2458 "OpMemberDecorate %PC16 0 MatrixStride 8\n"
2459 "OpDecorate %ssbo32 DescriptorSet 0\n"
2460 "OpDecorate %ssbo32 Binding 0\n";
2462 map<string, string> specs;
2464 specs["count"] = "%c_i32_8";
2465 specs["pp_type16"] = "%pp_v4f16";
2466 specs["up_type32"] = "%up_v4f32";
2467 specs["f_type16"] = "%v4f16";
2468 specs["f_type32"] = "%v4f32";
2469 specs["index0"] = "%c_i32_0";
2471 " %src_1 = OpAccessChain %pp_v4f16 %pc16 %c_i32_0 %30 %c_i32_1\n"
2472 "%val16_1 = OpLoad %v4f16 %src_1\n"
2473 "%val32_1 = OpFConvert %v4f32 %val16_1\n"
2474 " %dst_1 = OpAccessChain %up_v4f32 %ssbo32 %c_i32_0 %30 %c_i32_1\n"
2475 " OpStore %dst_1 %val32_1\n";
2477 fragments["testfun"] = testFun.specialize(specs);
2479 createTestsForAllStages("matrix", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
2483 void addGraphics16BitStoragePushConstantInt16To32Group (tcu::TestCaseGroup* testGroup)
2485 de::Random rnd (deStringHash(testGroup->getName()));
2486 map<string, string> fragments;
2487 RGBA defaultColors[4];
2488 const deUint32 numDataPoints = 64;
2489 vector<deInt16> inputs = getInt16s(rnd, numDataPoints);
2490 vector<deInt32> sOutputs;
2491 vector<deInt32> uOutputs;
2493 GraphicsResources resources;
2494 vector<string> extensions;
2495 const deUint16 signBitMask = 0x8000;
2496 const deUint32 signExtendMask = 0xffff0000;
2497 VulkanFeatures requiredFeatures;
2499 sOutputs.reserve(inputs.size());
2500 uOutputs.reserve(inputs.size());
2502 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
2504 uOutputs.push_back(static_cast<deUint16>(inputs[numNdx]));
2505 if (inputs[numNdx] & signBitMask)
2506 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx] | signExtendMask));
2508 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx]));
2511 extensions.push_back("VK_KHR_16bit_storage");
2512 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_PUSH_CONSTANT;
2514 fragments["capability"] = "OpCapability StoragePushConstant16\n";
2515 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
2517 pcs.setPushConstant(BufferSp(new Int16Buffer(inputs)));
2519 getDefaultColors(defaultColors);
2521 const StringTemplate testFun (
2522 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
2523 " %param = OpFunctionParameter %v4f32\n"
2525 "%entry = OpLabel\n"
2526 " %i = OpVariable %fp_i32 Function\n"
2527 " OpStore %i %c_i32_0\n"
2530 " %loop = OpLabel\n"
2531 " %15 = OpLoad %i32 %i\n"
2532 " %lt = OpSLessThan %bool %15 %c_i32_${count}\n"
2533 " OpLoopMerge %merge %inc None\n"
2534 " OpBranchConditional %lt %write %merge\n"
2536 "%write = OpLabel\n"
2537 " %30 = OpLoad %i32 %i\n"
2538 " %src = OpAccessChain %pp_${type16} %pc16 %c_i32_0 %30\n"
2539 "%val16 = OpLoad %${type16} %src\n"
2540 "%val32 = ${convert} %${type32} %val16\n"
2541 " %dst = OpAccessChain %up_${type32} %ssbo32 %c_i32_0 %30\n"
2542 " OpStore %dst %val32\n"
2546 " %37 = OpLoad %i32 %i\n"
2547 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
2551 "%merge = OpLabel\n"
2552 " OpReturnValue %param\n"
2557 const StringTemplate preMain (
2558 " %${type16} = OpTypeInt 16 ${signed}\n"
2559 " %c_i32_${count} = OpConstant %i32 ${count}\n" // Should be the same as numDataPoints
2560 "%a${count}${type16} = OpTypeArray %${type16} %c_i32_${count}\n"
2561 "%a${count}${type32} = OpTypeArray %${type32} %c_i32_${count}\n"
2562 " %pp_${type16} = OpTypePointer PushConstant %${type16}\n"
2563 " %up_${type32} = OpTypePointer Uniform %${type32}\n"
2564 " %SSBO32 = OpTypeStruct %a${count}${type32}\n"
2565 " %up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2566 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2567 " %PC16 = OpTypeStruct %a${count}${type16}\n"
2568 " %pp_PC16 = OpTypePointer PushConstant %PC16\n"
2569 " %pc16 = OpVariable %pp_PC16 PushConstant\n");
2571 const StringTemplate decoration (
2572 "OpDecorate %a${count}${type16} ArrayStride 2\n"
2573 "OpDecorate %a${count}${type32} ArrayStride 4\n"
2574 "OpDecorate %SSBO32 BufferBlock\n"
2575 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2576 "OpDecorate %PC16 Block\n"
2577 "OpMemberDecorate %PC16 0 Offset 0\n"
2578 "OpDecorate %ssbo32 DescriptorSet 0\n"
2579 "OpDecorate %ssbo32 Binding 0\n");
2582 map<string, string> specs;
2584 specs["type16"] = "i16";
2585 specs["type32"] = "i32";
2586 specs["signed"] = "1";
2587 specs["count"] = "64";
2588 specs["convert"] = "OpSConvert";
2590 fragments["testfun"] = testFun.specialize(specs);
2591 fragments["pre_main"] = preMain.specialize(specs);
2592 fragments["decoration"] = decoration.specialize(specs);
2594 resources.outputs.clear();
2595 resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int32Buffer(sOutputs))));
2596 createTestsForAllStages("sint_scalar", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
2599 map<string, string> specs;
2601 specs["type16"] = "u16";
2602 specs["type32"] = "u32";
2603 specs["signed"] = "0";
2604 specs["count"] = "64";
2605 specs["convert"] = "OpUConvert";
2607 fragments["testfun"] = testFun.specialize(specs);
2608 fragments["pre_main"] = preMain.specialize(specs);
2609 fragments["decoration"] = decoration.specialize(specs);
2611 resources.outputs.clear();
2612 resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int32Buffer(uOutputs))));
2613 createTestsForAllStages("uint_scalar", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
2618 const StringTemplate preMain (
2619 " %${base_type16} = OpTypeInt 16 ${signed}\n"
2620 " %${type16} = OpTypeVector %${base_type16} 2\n"
2621 " %c_i32_${count} = OpConstant %i32 ${count}\n"
2622 "%a${count}${type16} = OpTypeArray %${type16} %c_i32_${count}\n"
2623 "%a${count}${type32} = OpTypeArray %${type32} %c_i32_${count}\n"
2624 " %pp_${type16} = OpTypePointer PushConstant %${type16}\n"
2625 " %up_${type32} = OpTypePointer Uniform %${type32}\n"
2626 " %SSBO32 = OpTypeStruct %a${count}${type32}\n"
2627 " %up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2628 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2629 " %PC16 = OpTypeStruct %a${count}${type16}\n"
2630 " %pp_PC16 = OpTypePointer PushConstant %PC16\n"
2631 " %pc16 = OpVariable %pp_PC16 PushConstant\n");
2633 const StringTemplate decoration (
2634 "OpDecorate %a${count}${type16} ArrayStride 4\n"
2635 "OpDecorate %a${count}${type32} ArrayStride 8\n"
2636 "OpDecorate %SSBO32 BufferBlock\n"
2637 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2638 "OpDecorate %PC16 Block\n"
2639 "OpMemberDecorate %PC16 0 Offset 0\n"
2640 "OpDecorate %ssbo32 DescriptorSet 0\n"
2641 "OpDecorate %ssbo32 Binding 0\n");
2644 map<string, string> specs;
2646 specs["base_type16"] = "i16";
2647 specs["type16"] = "v2i16";
2648 specs["type32"] = "v2i32";
2649 specs["signed"] = "1";
2650 specs["count"] = "32"; // 64 / 2
2651 specs["convert"] = "OpSConvert";
2653 fragments["testfun"] = testFun.specialize(specs);
2654 fragments["pre_main"] = preMain.specialize(specs);
2655 fragments["decoration"] = decoration.specialize(specs);
2657 resources.outputs.clear();
2658 resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int32Buffer(sOutputs))));
2659 createTestsForAllStages("sint_vector", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
2662 map<string, string> specs;
2664 specs["base_type16"] = "u16";
2665 specs["type16"] = "v2u16";
2666 specs["type32"] = "v2u32";
2667 specs["signed"] = "0";
2668 specs["count"] = "32";
2669 specs["convert"] = "OpUConvert";
2671 fragments["testfun"] = testFun.specialize(specs);
2672 fragments["pre_main"] = preMain.specialize(specs);
2673 fragments["decoration"] = decoration.specialize(specs);
2675 resources.outputs.clear();
2676 resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int32Buffer(uOutputs))));
2677 createTestsForAllStages("uint_vector", defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
2682 void addGraphics16BitStorageUniformInt16To32Group (tcu::TestCaseGroup* testGroup)
2684 de::Random rnd (deStringHash(testGroup->getName()));
2685 map<string, string> fragments;
2686 const deUint32 numDataPoints = 256;
2687 RGBA defaultColors[4];
2688 vector<deInt16> inputs = getInt16s(rnd, numDataPoints);
2689 vector<deInt32> sOutputs;
2690 vector<deInt32> uOutputs;
2691 GraphicsResources resources;
2692 vector<string> extensions;
2693 const deUint16 signBitMask = 0x8000;
2694 const deUint32 signExtendMask = 0xffff0000;
2695 const StringTemplate capabilities ("OpCapability ${cap}\n");
2697 sOutputs.reserve(inputs.size());
2698 uOutputs.reserve(inputs.size());
2700 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
2702 uOutputs.push_back(static_cast<deUint16>(inputs[numNdx]));
2703 if (inputs[numNdx] & signBitMask)
2704 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx] | signExtendMask));
2706 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx]));
2709 resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int16Buffer(inputs))));
2711 extensions.push_back("VK_KHR_16bit_storage");
2712 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
2714 getDefaultColors(defaultColors);
2725 const IntegerFacts intFacts[] =
2727 {"sint", "%i32", "%i16", "OpSConvert", true},
2728 {"uint", "%u32", "%u16", "OpUConvert", false},
2731 const StringTemplate scalarPreMain (
2732 "${itype16} = OpTypeInt 16 ${signed}\n"
2733 " %c_i32_256 = OpConstant %i32 256\n"
2734 " %up_i32 = OpTypePointer Uniform ${itype32}\n"
2735 " %up_i16 = OpTypePointer Uniform ${itype16}\n"
2736 " %ra_i32 = OpTypeArray ${itype32} %c_i32_256\n"
2737 " %ra_i16 = OpTypeArray ${itype16} %c_i32_256\n"
2738 " %SSBO32 = OpTypeStruct %ra_i32\n"
2739 " %SSBO16 = OpTypeStruct %ra_i16\n"
2740 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2741 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
2742 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2743 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n");
2745 const StringTemplate scalarDecoration (
2746 "OpDecorate %ra_i32 ArrayStride 4\n"
2747 "OpDecorate %ra_i16 ArrayStride 2\n"
2748 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2749 "OpMemberDecorate %SSBO16 0 Offset 0\n"
2750 "OpDecorate %SSBO32 BufferBlock\n"
2751 "OpDecorate %SSBO16 ${indecor}\n"
2752 "OpDecorate %ssbo32 DescriptorSet 0\n"
2753 "OpDecorate %ssbo16 DescriptorSet 0\n"
2754 "OpDecorate %ssbo32 Binding 1\n"
2755 "OpDecorate %ssbo16 Binding 0\n");
2757 const StringTemplate scalarTestFunc (
2758 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
2759 " %param = OpFunctionParameter %v4f32\n"
2761 "%entry = OpLabel\n"
2762 " %i = OpVariable %fp_i32 Function\n"
2763 " OpStore %i %c_i32_0\n"
2766 " %loop = OpLabel\n"
2767 " %15 = OpLoad %i32 %i\n"
2768 " %lt = OpSLessThan %bool %15 %c_i32_256\n"
2769 " OpLoopMerge %merge %inc None\n"
2770 " OpBranchConditional %lt %write %merge\n"
2772 "%write = OpLabel\n"
2773 " %30 = OpLoad %i32 %i\n"
2774 " %src = OpAccessChain %up_i16 %ssbo16 %c_i32_0 %30\n"
2775 "%val16 = OpLoad ${itype16} %src\n"
2776 "%val32 = ${convert} ${itype32} %val16\n"
2777 " %dst = OpAccessChain %up_i32 %ssbo32 %c_i32_0 %30\n"
2778 " OpStore %dst %val32\n"
2782 " %37 = OpLoad %i32 %i\n"
2783 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
2786 "%merge = OpLabel\n"
2787 " OpReturnValue %param\n"
2791 const StringTemplate vecPreMain (
2792 "${itype16} = OpTypeInt 16 ${signed}\n"
2793 "%c_i32_128 = OpConstant %i32 128\n"
2794 "%v2itype16 = OpTypeVector ${itype16} 2\n"
2795 " %up_v2i32 = OpTypePointer Uniform ${v2itype32}\n"
2796 " %up_v2i16 = OpTypePointer Uniform %v2itype16\n"
2797 " %ra_v2i32 = OpTypeArray ${v2itype32} %c_i32_128\n"
2798 " %ra_v2i16 = OpTypeArray %v2itype16 %c_i32_128\n"
2799 " %SSBO32 = OpTypeStruct %ra_v2i32\n"
2800 " %SSBO16 = OpTypeStruct %ra_v2i16\n"
2801 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2802 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
2803 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2804 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n");
2806 const StringTemplate vecDecoration (
2807 "OpDecorate %ra_v2i32 ArrayStride 8\n"
2808 "OpDecorate %ra_v2i16 ArrayStride 4\n"
2809 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2810 "OpMemberDecorate %SSBO16 0 Offset 0\n"
2811 "OpDecorate %SSBO32 BufferBlock\n"
2812 "OpDecorate %SSBO16 ${indecor}\n"
2813 "OpDecorate %ssbo32 DescriptorSet 0\n"
2814 "OpDecorate %ssbo16 DescriptorSet 0\n"
2815 "OpDecorate %ssbo32 Binding 1\n"
2816 "OpDecorate %ssbo16 Binding 0\n");
2818 const StringTemplate vecTestFunc (
2819 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
2820 " %param = OpFunctionParameter %v4f32\n"
2822 "%entry = OpLabel\n"
2823 " %i = OpVariable %fp_i32 Function\n"
2824 " OpStore %i %c_i32_0\n"
2827 " %loop = OpLabel\n"
2828 " %15 = OpLoad %i32 %i\n"
2829 " %lt = OpSLessThan %bool %15 %c_i32_128\n"
2830 " OpLoopMerge %merge %inc None\n"
2831 " OpBranchConditional %lt %write %merge\n"
2833 "%write = OpLabel\n"
2834 " %30 = OpLoad %i32 %i\n"
2835 " %src = OpAccessChain %up_v2i16 %ssbo16 %c_i32_0 %30\n"
2836 "%val16 = OpLoad %v2itype16 %src\n"
2837 "%val32 = ${convert} ${v2itype32} %val16\n"
2838 " %dst = OpAccessChain %up_v2i32 %ssbo32 %c_i32_0 %30\n"
2839 " OpStore %dst %val32\n"
2843 " %37 = OpLoad %i32 %i\n"
2844 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
2847 "%merge = OpLabel\n"
2848 " OpReturnValue %param\n"
2855 const StringTemplate& preMain;
2856 const StringTemplate& decoration;
2857 const StringTemplate& testFunction;
2860 const Category categories[] =
2862 {"scalar", scalarPreMain, scalarDecoration, scalarTestFunc},
2863 {"vector", vecPreMain, vecDecoration, vecTestFunc},
2866 for (deUint32 catIdx = 0; catIdx < DE_LENGTH_OF_ARRAY(categories); ++catIdx)
2867 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
2868 for (deUint32 factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
2870 map<string, string> specs;
2871 string name = string(CAPABILITIES[capIdx].name) + "_" + categories[catIdx].name + "_" + intFacts[factIdx].name;
2873 specs["cap"] = CAPABILITIES[capIdx].cap;
2874 specs["indecor"] = CAPABILITIES[capIdx].decor;
2875 specs["itype32"] = intFacts[factIdx].type32;
2876 specs["v2itype32"] = "%v2" + string(intFacts[factIdx].type32).substr(1);
2877 specs["itype16"] = intFacts[factIdx].type16;
2878 if (intFacts[factIdx].isSigned)
2879 specs["signed"] = "1";
2881 specs["signed"] = "0";
2882 specs["convert"] = intFacts[factIdx].opcode;
2884 fragments["pre_main"] = categories[catIdx].preMain.specialize(specs);
2885 fragments["testfun"] = categories[catIdx].testFunction.specialize(specs);
2886 fragments["capability"] = capabilities.specialize(specs);
2887 fragments["decoration"] = categories[catIdx].decoration.specialize(specs);
2889 resources.inputs.back().first = CAPABILITIES[capIdx].dtype;
2890 resources.outputs.clear();
2891 if (intFacts[factIdx].isSigned)
2892 resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int32Buffer(sOutputs))));
2894 resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Int32Buffer(uOutputs))));
2896 createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
2900 void addGraphics16BitStorageUniformFloat16To32Group (tcu::TestCaseGroup* testGroup)
2902 de::Random rnd (deStringHash(testGroup->getName()));
2903 map<string, string> fragments;
2904 GraphicsResources resources;
2905 vector<string> extensions;
2906 const deUint32 numDataPoints = 256;
2907 RGBA defaultColors[4];
2908 const StringTemplate capabilities ("OpCapability ${cap}\n");
2909 vector<deFloat16> float16Data = getFloat16s(rnd, numDataPoints);
2910 vector<float> float32Data;
2912 float32Data.reserve(numDataPoints);
2913 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
2914 float32Data.push_back(deFloat16To32(float16Data[numIdx]));
2916 resources.inputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float16Buffer(float16Data))));
2917 resources.outputs.push_back(std::make_pair(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, BufferSp(new Float32Buffer(float32Data))));
2918 resources.verifyIO = check32BitFloats;
2920 extensions.push_back("VK_KHR_16bit_storage");
2921 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"";
2923 getDefaultColors(defaultColors);
2926 fragments["pre_main"] =
2927 " %f16 = OpTypeFloat 16\n"
2928 "%c_i32_256 = OpConstant %i32 256\n"
2929 " %up_f32 = OpTypePointer Uniform %f32\n"
2930 " %up_f16 = OpTypePointer Uniform %f16\n"
2931 " %ra_f32 = OpTypeArray %f32 %c_i32_256\n"
2932 " %ra_f16 = OpTypeArray %f16 %c_i32_256\n"
2933 " %SSBO32 = OpTypeStruct %ra_f32\n"
2934 " %SSBO16 = OpTypeStruct %ra_f16\n"
2935 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2936 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
2937 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2938 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n";
2940 const StringTemplate decoration (
2941 "OpDecorate %ra_f32 ArrayStride 4\n"
2942 "OpDecorate %ra_f16 ArrayStride 2\n"
2943 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2944 "OpMemberDecorate %SSBO16 0 Offset 0\n"
2945 "OpDecorate %SSBO32 BufferBlock\n"
2946 "OpDecorate %SSBO16 ${indecor}\n"
2947 "OpDecorate %ssbo32 DescriptorSet 0\n"
2948 "OpDecorate %ssbo16 DescriptorSet 0\n"
2949 "OpDecorate %ssbo32 Binding 1\n"
2950 "OpDecorate %ssbo16 Binding 0\n");
2952 // ssbo32[] <- convert ssbo16[] to 32bit float
2953 fragments["testfun"] =
2954 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
2955 " %param = OpFunctionParameter %v4f32\n"
2957 "%entry = OpLabel\n"
2958 " %i = OpVariable %fp_i32 Function\n"
2959 " OpStore %i %c_i32_0\n"
2962 " %loop = OpLabel\n"
2963 " %15 = OpLoad %i32 %i\n"
2964 " %lt = OpSLessThan %bool %15 %c_i32_256\n"
2965 " OpLoopMerge %merge %inc None\n"
2966 " OpBranchConditional %lt %write %merge\n"
2968 "%write = OpLabel\n"
2969 " %30 = OpLoad %i32 %i\n"
2970 " %src = OpAccessChain %up_f16 %ssbo16 %c_i32_0 %30\n"
2971 "%val16 = OpLoad %f16 %src\n"
2972 "%val32 = OpFConvert %f32 %val16\n"
2973 " %dst = OpAccessChain %up_f32 %ssbo32 %c_i32_0 %30\n"
2974 " OpStore %dst %val32\n"
2978 " %37 = OpLoad %i32 %i\n"
2979 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
2983 "%merge = OpLabel\n"
2984 " OpReturnValue %param\n"
2988 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
2990 map<string, string> specs;
2991 string testName = string(CAPABILITIES[capIdx].name) + "_scalar_float";
2993 specs["cap"] = CAPABILITIES[capIdx].cap;
2994 specs["indecor"] = CAPABILITIES[capIdx].decor;
2996 fragments["capability"] = capabilities.specialize(specs);
2997 fragments["decoration"] = decoration.specialize(specs);
2999 resources.inputs.back().first = CAPABILITIES[capIdx].dtype;
3001 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
3006 fragments["pre_main"] =
3007 " %f16 = OpTypeFloat 16\n"
3008 "%c_i32_128 = OpConstant %i32 128\n"
3009 " %v2f16 = OpTypeVector %f16 2\n"
3010 " %up_v2f32 = OpTypePointer Uniform %v2f32\n"
3011 " %up_v2f16 = OpTypePointer Uniform %v2f16\n"
3012 " %ra_v2f32 = OpTypeArray %v2f32 %c_i32_128\n"
3013 " %ra_v2f16 = OpTypeArray %v2f16 %c_i32_128\n"
3014 " %SSBO32 = OpTypeStruct %ra_v2f32\n"
3015 " %SSBO16 = OpTypeStruct %ra_v2f16\n"
3016 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
3017 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
3018 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
3019 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n";
3021 const StringTemplate decoration (
3022 "OpDecorate %ra_v2f32 ArrayStride 8\n"
3023 "OpDecorate %ra_v2f16 ArrayStride 4\n"
3024 "OpMemberDecorate %SSBO32 0 Offset 0\n"
3025 "OpMemberDecorate %SSBO16 0 Offset 0\n"
3026 "OpDecorate %SSBO32 BufferBlock\n"
3027 "OpDecorate %SSBO16 ${indecor}\n"
3028 "OpDecorate %ssbo32 DescriptorSet 0\n"
3029 "OpDecorate %ssbo16 DescriptorSet 0\n"
3030 "OpDecorate %ssbo32 Binding 1\n"
3031 "OpDecorate %ssbo16 Binding 0\n");
3033 // ssbo32[] <- convert ssbo16[] to 32bit float
3034 fragments["testfun"] =
3035 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
3036 " %param = OpFunctionParameter %v4f32\n"
3038 "%entry = OpLabel\n"
3039 " %i = OpVariable %fp_i32 Function\n"
3040 " OpStore %i %c_i32_0\n"
3043 " %loop = OpLabel\n"
3044 " %15 = OpLoad %i32 %i\n"
3045 " %lt = OpSLessThan %bool %15 %c_i32_128\n"
3046 " OpLoopMerge %merge %inc None\n"
3047 " OpBranchConditional %lt %write %merge\n"
3049 "%write = OpLabel\n"
3050 " %30 = OpLoad %i32 %i\n"
3051 " %src = OpAccessChain %up_v2f16 %ssbo16 %c_i32_0 %30\n"
3052 "%val16 = OpLoad %v2f16 %src\n"
3053 "%val32 = OpFConvert %v2f32 %val16\n"
3054 " %dst = OpAccessChain %up_v2f32 %ssbo32 %c_i32_0 %30\n"
3055 " OpStore %dst %val32\n"
3059 " %37 = OpLoad %i32 %i\n"
3060 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
3064 "%merge = OpLabel\n"
3065 " OpReturnValue %param\n"
3069 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
3071 map<string, string> specs;
3072 string testName = string(CAPABILITIES[capIdx].name) + "_vector_float";
3074 specs["cap"] = CAPABILITIES[capIdx].cap;
3075 specs["indecor"] = CAPABILITIES[capIdx].decor;
3077 fragments["capability"] = capabilities.specialize(specs);
3078 fragments["decoration"] = decoration.specialize(specs);
3080 resources.inputs.back().first = CAPABILITIES[capIdx].dtype;
3082 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
3087 fragments["pre_main"] =
3088 " %c_i32_32 = OpConstant %i32 32\n"
3089 " %f16 = OpTypeFloat 16\n"
3090 " %v2f16 = OpTypeVector %f16 2\n"
3091 " %m4x2f32 = OpTypeMatrix %v2f32 4\n"
3092 " %m4x2f16 = OpTypeMatrix %v2f16 4\n"
3093 " %up_v2f32 = OpTypePointer Uniform %v2f32\n"
3094 " %up_v2f16 = OpTypePointer Uniform %v2f16\n"
3095 "%a8m4x2f32 = OpTypeArray %m4x2f32 %c_i32_32\n"
3096 "%a8m4x2f16 = OpTypeArray %m4x2f16 %c_i32_32\n"
3097 " %SSBO32 = OpTypeStruct %a8m4x2f32\n"
3098 " %SSBO16 = OpTypeStruct %a8m4x2f16\n"
3099 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
3100 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
3101 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
3102 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n";
3104 const StringTemplate decoration (
3105 "OpDecorate %a8m4x2f32 ArrayStride 32\n"
3106 "OpDecorate %a8m4x2f16 ArrayStride 16\n"
3107 "OpMemberDecorate %SSBO32 0 Offset 0\n"
3108 "OpMemberDecorate %SSBO32 0 ColMajor\n"
3109 "OpMemberDecorate %SSBO32 0 MatrixStride 8\n"
3110 "OpMemberDecorate %SSBO16 0 Offset 0\n"
3111 "OpMemberDecorate %SSBO16 0 ColMajor\n"
3112 "OpMemberDecorate %SSBO16 0 MatrixStride 4\n"
3113 "OpDecorate %SSBO32 BufferBlock\n"
3114 "OpDecorate %SSBO16 ${indecor}\n"
3115 "OpDecorate %ssbo32 DescriptorSet 0\n"
3116 "OpDecorate %ssbo16 DescriptorSet 0\n"
3117 "OpDecorate %ssbo32 Binding 1\n"
3118 "OpDecorate %ssbo16 Binding 0\n");
3120 fragments["testfun"] =
3121 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
3122 " %param = OpFunctionParameter %v4f32\n"
3124 "%entry = OpLabel\n"
3125 " %i = OpVariable %fp_i32 Function\n"
3126 " OpStore %i %c_i32_0\n"
3129 " %loop = OpLabel\n"
3130 " %15 = OpLoad %i32 %i\n"
3131 " %lt = OpSLessThan %bool %15 %c_i32_32\n"
3132 " OpLoopMerge %merge %inc None\n"
3133 " OpBranchConditional %lt %write %merge\n"
3135 " %write = OpLabel\n"
3136 " %30 = OpLoad %i32 %i\n"
3137 " %src_0 = OpAccessChain %up_v2f16 %ssbo16 %c_i32_0 %30 %c_i32_0\n"
3138 " %src_1 = OpAccessChain %up_v2f16 %ssbo16 %c_i32_0 %30 %c_i32_1\n"
3139 " %src_2 = OpAccessChain %up_v2f16 %ssbo16 %c_i32_0 %30 %c_i32_2\n"
3140 " %src_3 = OpAccessChain %up_v2f16 %ssbo16 %c_i32_0 %30 %c_i32_3\n"
3141 "%val16_0 = OpLoad %v2f16 %src_0\n"
3142 "%val16_1 = OpLoad %v2f16 %src_1\n"
3143 "%val16_2 = OpLoad %v2f16 %src_2\n"
3144 "%val16_3 = OpLoad %v2f16 %src_3\n"
3145 "%val32_0 = OpFConvert %v2f32 %val16_0\n"
3146 "%val32_1 = OpFConvert %v2f32 %val16_1\n"
3147 "%val32_2 = OpFConvert %v2f32 %val16_2\n"
3148 "%val32_3 = OpFConvert %v2f32 %val16_3\n"
3149 " %dst_0 = OpAccessChain %up_v2f32 %ssbo32 %c_i32_0 %30 %c_i32_0\n"
3150 " %dst_1 = OpAccessChain %up_v2f32 %ssbo32 %c_i32_0 %30 %c_i32_1\n"
3151 " %dst_2 = OpAccessChain %up_v2f32 %ssbo32 %c_i32_0 %30 %c_i32_2\n"
3152 " %dst_3 = OpAccessChain %up_v2f32 %ssbo32 %c_i32_0 %30 %c_i32_3\n"
3153 " OpStore %dst_0 %val32_0\n"
3154 " OpStore %dst_1 %val32_1\n"
3155 " OpStore %dst_2 %val32_2\n"
3156 " OpStore %dst_3 %val32_3\n"
3160 " %37 = OpLoad %i32 %i\n"
3161 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
3165 "%merge = OpLabel\n"
3166 " OpReturnValue %param\n"
3170 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
3172 map<string, string> specs;
3173 string testName = string(CAPABILITIES[capIdx].name) + "_matrix_float";
3175 specs["cap"] = CAPABILITIES[capIdx].cap;
3176 specs["indecor"] = CAPABILITIES[capIdx].decor;
3178 fragments["capability"] = capabilities.specialize(specs);
3179 fragments["decoration"] = decoration.specialize(specs);
3181 resources.inputs.back().first = CAPABILITIES[capIdx].dtype;
3183 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, get16BitStorageFeatures(CAPABILITIES[capIdx].name));
3190 tcu::TestCaseGroup* create16BitStorageComputeGroup (tcu::TestContext& testCtx)
3192 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "16bit_storage", "Compute tests for VK_KHR_16bit_storage extension"));
3193 addTestGroup(group.get(), "uniform_32_to_16", "32bit floats/ints to 16bit tests under capability StorageUniform{|BufferBlock}", addCompute16bitStorageUniform32To16Group);
3194 addTestGroup(group.get(), "uniform_16_to_32", "16bit floats/ints to 32bit tests under capability StorageUniform{|BufferBlock}", addCompute16bitStorageUniform16To32Group);
3195 addTestGroup(group.get(), "push_constant_16_to_32", "16bit floats/ints to 32bit tests under capability StoragePushConstant16", addCompute16bitStoragePushConstant16To32Group);
3197 return group.release();
3200 tcu::TestCaseGroup* create16BitStorageGraphicsGroup (tcu::TestContext& testCtx)
3202 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "16bit_storage", "Graphics tests for VK_KHR_16bit_storage extension"));
3204 addTestGroup(group.get(), "uniform_float_32_to_16", "32-bit floats into 16-bit tests under capability StorageUniform{|BufferBlock}16", addGraphics16BitStorageUniformFloat32To16Group);
3205 addTestGroup(group.get(), "uniform_float_16_to_32", "16-bit floats into 32-bit testsunder capability StorageUniform{|BufferBlock}16", addGraphics16BitStorageUniformFloat16To32Group);
3206 addTestGroup(group.get(), "uniform_int_32_to_16", "32-bit int into 16-bit tests under capability StorageUniform{|BufferBlock}16", addGraphics16BitStorageUniformInt32To16Group);
3207 addTestGroup(group.get(), "uniform_int_16_to_32", "16-bit int into 32-bit tests under capability StorageUniform{|BufferBlock}16", addGraphics16BitStorageUniformInt16To32Group);
3208 addTestGroup(group.get(), "input_output_float_32_to_16", "32-bit floats into 16-bit tests under capability StorageInputOutput16", addGraphics16BitStorageInputOutputFloat32To16Group);
3209 addTestGroup(group.get(), "input_output_float_16_to_32", "16-bit floats into 32-bit tests under capability StorageInputOutput16", addGraphics16BitStorageInputOutputFloat16To32Group);
3210 addTestGroup(group.get(), "input_output_int_32_to_16", "32-bit int into 16-bit tests under capability StorageInputOutput16", addGraphics16BitStorageInputOutputInt32To16Group);
3211 addTestGroup(group.get(), "input_output_int_16_to_32", "16-bit int into 32-bit tests under capability StorageInputOutput16", addGraphics16BitStorageInputOutputInt16To32Group);
3212 addTestGroup(group.get(), "push_constant_float_16_to_32", "16-bit floats into 32-bit tests under capability StoragePushConstant16", addGraphics16BitStoragePushConstantFloat16To32Group);
3213 addTestGroup(group.get(), "push_constant_int_16_to_32", "16-bit int into 32-bit tests under capability StoragePushConstant16", addGraphics16BitStoragePushConstantInt16To32Group);
3215 return group.release();