1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2018 The Khronos Group 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_8bit_storage
22 *//*--------------------------------------------------------------------*/
25 #include "vktSpvAsm8bitStorageTests.hpp"
27 #include "tcuFloat.hpp"
28 #include "tcuRGBA.hpp"
29 #include "tcuStringTemplate.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuVectorUtil.hpp"
34 #include "vkDeviceUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkPlatform.hpp"
37 #include "vkPrograms.hpp"
38 #include "vkQueryUtil.hpp"
40 #include "vkRefUtil.hpp"
41 #include "vkStrUtil.hpp"
42 #include "vkTypeUtil.hpp"
44 #include "deRandom.hpp"
45 #include "deStringUtil.hpp"
46 #include "deUniquePtr.hpp"
49 #include "vktSpvAsmComputeShaderCase.hpp"
50 #include "vktSpvAsmComputeShaderTestUtil.hpp"
51 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
52 #include "vktTestCaseUtil.hpp"
53 #include "vktTestGroupUtil.hpp"
63 namespace SpirVAssembly
74 using tcu::TestStatus;
77 using tcu::StringTemplate;
82 static const deUint32 arrayStrideInBytesUniform = 16u; // from the spec
86 SHADERTEMPLATE_STRIDE8BIT_STD140 = 0,
87 SHADERTEMPLATE_STRIDE32BIT_STD140,
88 SHADERTEMPLATE_STRIDEMIX_STD140,
89 SHADERTEMPLATE_STRIDE8BIT_STD430,
90 SHADERTEMPLATE_STRIDE32BIT_STD430,
91 SHADERTEMPLATE_STRIDEMIX_STD430
96 const int structArraySize; //Size of Struct Array
97 const int nestedArraySize; //Max size of any nested arrays
105 vk::VkDescriptorType dtype;
110 STORAGE_BUFFER_TEST = 0,
111 UNIFORM_AND_STORAGEBUFFER_TEST
114 static const Capability CAPABILITIES[] =
116 {"storage_buffer", "StorageBuffer8BitAccess", "StorageBuffer", VK_DESCRIPTOR_TYPE_STORAGE_BUFFER},
117 {"uniform", "UniformAndStorageBuffer8BitAccess", "Block", VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER},
120 static const StructTestData structData = {7, 11};
122 int getStructSize(const ShaderTemplate shaderTemplate)
124 switch (shaderTemplate)
126 case SHADERTEMPLATE_STRIDE8BIT_STD140:
127 return 1184 * structData.structArraySize; //size of struct in 8b with offsets
128 case SHADERTEMPLATE_STRIDE32BIT_STD140:
129 return 304 * structData.structArraySize; //size of struct in 32b with offsets
130 case SHADERTEMPLATE_STRIDEMIX_STD140:
131 return 4480 * structData.structArraySize; //size of struct in 8b with offsets
132 case SHADERTEMPLATE_STRIDE8BIT_STD430:
133 return 224 * structData.structArraySize; //size of struct in 8b with offset
134 case SHADERTEMPLATE_STRIDE32BIT_STD430:
135 return 184 * structData.structArraySize; //size of struct in 32b with offset
136 case SHADERTEMPLATE_STRIDEMIX_STD430:
137 return 976 * structData.structArraySize; //size of struct in 8b with offset
144 VulkanFeatures get8BitStorageFeatures (const char* cap)
146 VulkanFeatures features;
147 if (string(cap) == "storage_buffer")
148 features.ext8BitStorage = EXT8BITSTORAGEFEATURES_STORAGE_BUFFER;
149 else if (string(cap) == "uniform")
150 features.ext8BitStorage = EXT8BITSTORAGEFEATURES_UNIFORM_STORAGE_BUFFER;
151 else if (string(cap) == "push_constant")
152 features.ext8BitStorage = EXT8BITSTORAGEFEATURES_PUSH_CONSTANT;
154 DE_ASSERT(false && "not supported");
159 bool computeCheckBuffers (const std::vector<Resource>& originalInts,
160 const vector<AllocationSp>& outputAllocs,
161 const std::vector<Resource>& /*expectedOutputs*/,
162 tcu::TestLog& /*log*/)
164 std::vector<deUint8> result;
165 originalInts.front().getBytes(result);
166 return deMemCmp(&result[0], outputAllocs.front()->getHostPtr(), result.size()) == 0;
169 void addInfo(vector<bool>& info, int& ndx, const int count, const bool isData)
171 for (int index = 0; index < count; ++index)
172 info[ndx++] = isData;
175 vector<deInt8> data8bit (const ShaderTemplate std, de::Random& rnd, const bool isData = true)
177 const int size = getStructSize(std);
179 return vector<deInt8>(size, 0);
180 return getInt8s(rnd, size);
183 vector<deInt32> data32bit (const ShaderTemplate std, de::Random& rnd, const bool isData = true)
185 const int size = getStructSize(std);
187 return vector<deInt32>(size, 0);
188 return getInt32s(rnd, size);
191 vector<bool> info8bitStd140 (void)
194 vector<bool> infoData (getStructSize(SHADERTEMPLATE_STRIDE8BIT_STD140));
196 for(int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
198 infoData[ndx++] = true; //i8
199 infoData[ndx++] = false; //offset
201 infoData[ndx++] = true; //v2i8
202 infoData[ndx++] = true; //v2i8
204 addInfo(infoData, ndx, 3, true); //v3i8
205 infoData[ndx++] = false; //offset
207 addInfo(infoData, ndx, 4, true); //v4i8
208 addInfo(infoData, ndx, 4, false); //offset
211 for (int i = 0; i < 3; ++i)
213 infoData[ndx++] = true; //i8[i];
214 addInfo(infoData, ndx, 15, false); //offset
217 //struct {i8, v2i8[3]} [11]
218 for (int i = 0; i < 11; ++i)
221 infoData[ndx++] = true; //i8
222 addInfo(infoData, ndx, 15, false); //offset
224 for (int j = 0; j < 3; ++j)
226 infoData[ndx++] = true; //v2i8
227 infoData[ndx++] = true; //v2i8
228 addInfo(infoData, ndx, 14, false); //offset
233 for (int i = 0; i < 11; ++i)
235 infoData[ndx++] = true; //v2i8
236 infoData[ndx++] = true; //v2i8
237 addInfo(infoData, ndx, 14, false); //offset
241 infoData[ndx++] = true; //i8
242 addInfo(infoData, ndx, 15, false); //offset
245 for (int i = 0; i < 11; ++i)
247 addInfo(infoData, ndx, 3, true); //v3i8
248 addInfo(infoData, ndx, 13, false); //offset
252 for (int i = 0; i < 3; ++i)
254 addInfo(infoData, ndx, 4, true); //v4i8
255 addInfo(infoData, ndx, 12, false); //offset
259 //Please check the data and offset
260 DE_ASSERT(ndx == static_cast<int>(infoData.size()));
265 vector<bool> info8bitStd430 (void)
268 vector<bool> infoData (getStructSize(SHADERTEMPLATE_STRIDE8BIT_STD430));
270 for(int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
272 infoData[ndx++] = true; //i8
273 infoData[ndx++] = false; //offset
275 infoData[ndx++] = true; //v2i8
276 infoData[ndx++] = true; //v2i8
278 addInfo(infoData, ndx, 3, true); //v3i8
279 infoData[ndx++] = false; //offset
281 addInfo(infoData, ndx, 4, true); //v4i8
282 addInfo(infoData, ndx, 4, false); //offset
285 for (int i = 0; i < 3; ++i)
287 infoData[ndx++] = true; //i8;
289 addInfo(infoData, ndx, 13, false); //offset
291 //struct {i8, v2i8[3]} [11]
292 for (int i = 0; i < 11; ++i)
295 infoData[ndx++] = true; //i8
296 infoData[ndx++] = false; //offset
298 for (int j = 0; j < 3; ++j)
300 infoData[ndx++] = true; //v2i8
301 infoData[ndx++] = true; //v2i8
304 addInfo(infoData, ndx, 8, false); //offset
307 for (int i = 0; i < 11; ++i)
309 infoData[ndx++] = true; //v2i8
310 infoData[ndx++] = true; //v2i8
314 infoData[ndx++] = true; //i8
315 addInfo(infoData, ndx, 9, false); //offset
318 for (int i = 0; i < 11; ++i)
320 addInfo(infoData, ndx, 3, true); //v3i8
321 infoData[ndx++] = false; //offset
323 addInfo(infoData, ndx, 4, false); //offset
326 for (int i = 0; i < 3; ++i)
328 addInfo(infoData, ndx, 4, true); //v4i8
330 addInfo(infoData, ndx, 4, false); //offset
333 //Please check the data and offset
334 DE_ASSERT(ndx == static_cast<int>(infoData.size()));
338 vector<bool> info32bitStd140 (void)
341 vector<bool> infoData (getStructSize(SHADERTEMPLATE_STRIDE32BIT_STD140));
343 for(int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
345 infoData[ndx++] = true; //i32
346 infoData[ndx++] = false; //offset
348 infoData[ndx++] = true; //v2i32
349 infoData[ndx++] = true; //v2i32
351 addInfo(infoData, ndx, 3, true); //v3i32
352 infoData[ndx++] = false; //offset
354 addInfo(infoData, ndx, 4, true); //v4i32
357 for (int i = 0; i < 3; ++i)
359 infoData[ndx++] = true; //i32;
360 addInfo(infoData, ndx, 3, false); //offset
363 //struct {i32, v2i32[3]} [11]
364 for (int i = 0; i < 11; ++i)
367 infoData[ndx++] = true; //i32
368 addInfo(infoData, ndx, 3, false); //offset
369 //struct.f32.v2f16[3]
370 for (int j = 0; j < 3; ++j)
372 infoData[ndx++] = true; //v2i32
373 infoData[ndx++] = true; //v2i32
374 infoData[ndx++] = false; //offset
375 infoData[ndx++] = false; //offset
380 for (int i = 0; i < 11; ++i)
382 infoData[ndx++] = true; //v2i32
383 infoData[ndx++] = true; //v2i32
384 infoData[ndx++] = false; //offset
385 infoData[ndx++] = false; //offset
389 infoData[ndx++] = true; //i32
390 addInfo(infoData, ndx, 3, false); //offset
393 for (int i = 0; i < 11; ++i)
395 addInfo(infoData, ndx, 3, true); //v3i32
396 infoData[ndx++] = false; //offset
400 for (int i = 0; i < 3; ++i)
402 addInfo(infoData, ndx, 4, true); //v4i32
406 //Please check the data and offset
407 DE_ASSERT(ndx == static_cast<int>(infoData.size()));
411 vector<bool> info32bitStd430 (void)
414 vector<bool> infoData (getStructSize(SHADERTEMPLATE_STRIDE32BIT_STD430));
416 for(int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
418 infoData[ndx++] = true; //i32
419 infoData[ndx++] = false; //offset
421 addInfo(infoData, ndx, 2, true); //v2i32
423 addInfo(infoData, ndx, 3, true); //v3i32
424 infoData[ndx++] = false; //offset
426 addInfo(infoData, ndx, 4, true); //v4i32
428 addInfo(infoData, ndx, 3, true); //i32[3];
429 infoData[ndx++] = false; //offset
431 //struct {i32, v2i32[3]} [11]
432 for (int i = 0; i < 11; ++i)
435 infoData[ndx++] = true; //i32
436 infoData[ndx++] = false; //offset
437 addInfo(infoData, ndx, 6, true); //v2i32[3]
440 addInfo(infoData, ndx, 22, true); //v2i32[11];
443 infoData[ndx++] = true; //i32
444 infoData[ndx++] = false; //offset
447 for (int i = 0; i < 11; ++i)
449 addInfo(infoData, ndx, 3, true); //v3i32
450 infoData[ndx++] = false; //offset
453 addInfo(infoData, ndx, 12, true); //v4i32[3]
456 //Please check the data and offset
457 DE_ASSERT(ndx == static_cast<int>(infoData.size()));
461 vector<bool> infoMixStd140 (void)
464 vector<bool> infoData (getStructSize(SHADERTEMPLATE_STRIDEMIX_STD140));
465 for(int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
467 infoData[ndx++] = true; //8b
468 addInfo(infoData, ndx, 3, false); //offset
470 addInfo(infoData, ndx, 4, true); //32b
472 addInfo(infoData, ndx, 2, true); //v2b8
473 addInfo(infoData, ndx, 6, false); //offset
475 addInfo(infoData, ndx, 8, true); //v2b32
477 addInfo(infoData, ndx, 3, true); //v3b8
478 addInfo(infoData, ndx, 5, false); //offset
480 addInfo(infoData, ndx, 12, true); //v3b32
481 addInfo(infoData, ndx, 4, false); //offset
483 addInfo(infoData, ndx, 4, true); //v4b8
484 addInfo(infoData, ndx, 12, false); //offset
486 addInfo(infoData, ndx, 16, true); //v4b32
488 //strut {b8, b32, v2b8[11], b32[11]}
489 for (int i = 0; i < structData.nestedArraySize; ++i)
491 infoData[ndx++] = true; //8b
492 addInfo(infoData, ndx, 3, false); //offset
494 addInfo(infoData, ndx, 4, true); //32b
495 addInfo(infoData, ndx, 8, false); //offset
497 for (int j = 0; j < structData.nestedArraySize; ++j)
499 addInfo(infoData, ndx, 2, true); //v2b8[11]
500 addInfo(infoData, ndx, 14, false); //offset
503 for (int j = 0; j < structData.nestedArraySize; ++j)
505 addInfo(infoData, ndx, 4, true); //b32[11]
506 addInfo(infoData, ndx, 12, false); //offset
510 for (int i = 0; i < structData.nestedArraySize; ++i)
512 infoData[ndx++] = true; //8b[11]
513 addInfo(infoData, ndx, 15, false); //offset
516 for (int i = 0; i < structData.nestedArraySize; ++i)
518 addInfo(infoData, ndx, 4, true); //b32bIn[11]
519 addInfo(infoData, ndx, 12, false); //offset
523 //Please check the data and offset
524 DE_ASSERT(ndx == static_cast<int>(infoData.size()));
528 vector<bool> infoMixStd430 (void)
531 vector<bool> infoData (getStructSize(SHADERTEMPLATE_STRIDEMIX_STD430));
532 for(int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
534 infoData[ndx++] = true; //8b
535 addInfo(infoData, ndx, 3, false); //offset
537 addInfo(infoData, ndx, 4, true); //32b
539 addInfo(infoData, ndx, 2, true); //v2b8
540 addInfo(infoData, ndx, 6, false); //offset
542 addInfo(infoData, ndx, 8, true); //v2b32
544 addInfo(infoData, ndx, 3, true); //v3b8
545 addInfo(infoData, ndx, 5, false); //offset
547 addInfo(infoData, ndx, 12, true); //v3b32
548 addInfo(infoData, ndx, 4, false); //offset
550 addInfo(infoData, ndx, 4, true); //v4b8
551 addInfo(infoData, ndx, 12, false); //offset
553 addInfo(infoData, ndx, 16, true); //v4b32
555 //strut {b8, b32, v2b8[11], b32[11]}
556 for (int i = 0; i < structData.nestedArraySize; ++i)
558 infoData[ndx++] = true; //8b
559 addInfo(infoData, ndx, 3, false); //offset
561 addInfo(infoData, ndx, 4, true); //32b
563 addInfo(infoData, ndx, 22, true); //v2b8[11]
564 addInfo(infoData, ndx, 2, false); //offset
566 addInfo(infoData, ndx, 44, true); //b32[11]
569 addInfo(infoData, ndx, 11, true); //8b[11]
570 infoData[ndx++] = false; //offset
572 addInfo(infoData, ndx, 44, true); //32b[11]
573 addInfo(infoData, ndx, 4, false); //offset
576 //Please check the data and offset
577 DE_ASSERT(ndx == static_cast<int>(infoData.size()));
581 template<typename originType, typename resultType, ShaderTemplate funcOrigin, ShaderTemplate funcResult>
582 bool compareStruct(const resultType* returned, const originType* original)
584 vector<bool> resultInfo;
585 vector<bool> originInfo;
586 vector<resultType > resultToCompare;
587 vector<originType > originToCompare;
591 case SHADERTEMPLATE_STRIDE8BIT_STD140:
592 originInfo = info8bitStd140();
594 case SHADERTEMPLATE_STRIDE8BIT_STD430:
595 originInfo = info8bitStd430();
597 case SHADERTEMPLATE_STRIDE32BIT_STD140:
598 originInfo = info32bitStd140();
600 case SHADERTEMPLATE_STRIDE32BIT_STD430:
601 originInfo = info32bitStd430();
603 case SHADERTEMPLATE_STRIDEMIX_STD140:
604 originInfo = infoMixStd140();
606 case SHADERTEMPLATE_STRIDEMIX_STD430:
607 originInfo = infoMixStd430();
615 case SHADERTEMPLATE_STRIDE8BIT_STD140:
616 resultInfo = info8bitStd140();
618 case SHADERTEMPLATE_STRIDE8BIT_STD430:
619 resultInfo = info8bitStd430();
621 case SHADERTEMPLATE_STRIDE32BIT_STD140:
622 resultInfo = info32bitStd140();
624 case SHADERTEMPLATE_STRIDE32BIT_STD430:
625 resultInfo = info32bitStd430();
627 case SHADERTEMPLATE_STRIDEMIX_STD140:
628 resultInfo = infoMixStd140();
630 case SHADERTEMPLATE_STRIDEMIX_STD430:
631 resultInfo = infoMixStd430();
637 for (int ndx = 0; ndx < static_cast<int>(resultInfo.size()); ++ndx)
640 resultToCompare.push_back(returned[ndx]);
643 for (int ndx = 0; ndx < static_cast<int>(originInfo.size()); ++ndx)
646 originToCompare.push_back(original[ndx]);
649 //Different offset but that same amount of data
650 DE_ASSERT(originToCompare.size() == resultToCompare.size());
652 for (int ndx = 0; ndx < static_cast<int>(originToCompare.size()); ++ndx)
654 if (static_cast<deInt8>(originToCompare[ndx]) != static_cast<deInt8>(resultToCompare[ndx]))
660 template<typename originType, typename resultType, ShaderTemplate funcOrigin, ShaderTemplate funcResult>
661 bool checkStruct (const std::vector<Resource>& originalFloats,
662 const vector<AllocationSp>& outputAllocs,
663 const std::vector<Resource>& /* expectedOutputs */,
664 tcu::TestLog& /* log */)
666 for (deUint32 outputNdx = 0; outputNdx < outputAllocs.size(); ++outputNdx)
668 vector<deUint8> originalBytes;
669 originalFloats[outputNdx].getBytes(originalBytes);
671 const resultType* returned = static_cast<const resultType*>(outputAllocs[outputNdx]->getHostPtr());
672 const originType* original = reinterpret_cast<const originType*>(&originalBytes.front());
674 if(!compareStruct<originType, resultType, funcOrigin, funcResult>(returned, original))
680 template<typename originType, typename resultType, deUint32 compositCount>
681 bool checkUniformsArray (const std::vector<Resource>& originalFloats,
682 const vector<AllocationSp>& outputAllocs,
683 const std::vector<Resource>& /* expectedOutputs */,
684 tcu::TestLog& /* log */)
686 const deUint32 originTypeSize = static_cast<deUint32>(sizeof(originType));
688 DE_ASSERT((originTypeSize * compositCount) <= arrayStrideInBytesUniform); // one element of array can't be bigger then 16B
690 for (deUint32 outputNdx = 0; outputNdx < static_cast<deUint32>(outputAllocs.size()); ++outputNdx)
692 vector<deUint8> originalBytes;
693 originalFloats[outputNdx].getBytes(originalBytes);
694 const int elemntsNumber = (static_cast<int>(originalBytes.size()) / arrayStrideInBytesUniform) / compositCount;
696 const resultType* returned = static_cast<const resultType*>(outputAllocs[outputNdx]->getHostPtr());
697 const originType* original = reinterpret_cast<const originType*>(&originalBytes.front());
699 for (int ndx = 0; ndx < elemntsNumber; ++ndx)
701 for (deUint32 ndxData = 0u; ndxData < compositCount; ++ndxData)
703 if (static_cast<deInt8>(*original) != static_cast<deInt8>(*returned))
708 original += arrayStrideInBytesUniform / originTypeSize - compositCount;
714 template<typename originType, typename resultType, int compositCount, int ndxConts>
715 bool checkUniformsArrayConstNdx (const std::vector<Resource>& originalFloats,
716 const vector<AllocationSp>& outputAllocs,
717 const std::vector<Resource>& /* expectedOutputs */,
718 tcu::TestLog& /* log */)
720 const deUint32 originTypeSize = static_cast<deUint32>(sizeof(originType));
722 DE_ASSERT((originTypeSize * compositCount) <= arrayStrideInBytesUniform); // one element of array can't be bigger then 16B
724 for (deUint32 outputNdx = 0; outputNdx < static_cast<deUint32>(outputAllocs.size()); ++outputNdx)
726 vector<deUint8> originalBytes;
727 originalFloats[outputNdx].getBytes(originalBytes);
728 const int elemntsNumber = (static_cast<int>(originalBytes.size()) / arrayStrideInBytesUniform) / compositCount;
730 const resultType* returned = static_cast<const resultType*>(outputAllocs[outputNdx]->getHostPtr());
731 const originType* original = reinterpret_cast<const originType*>(&originalBytes.front());
733 deUint32 idx = (arrayStrideInBytesUniform / originTypeSize) * ndxConts;
735 for (int ndx = 0; ndx < elemntsNumber; ++ndx)
737 for (int ndxData = 0; ndxData < compositCount; ++ndxData)
739 if (static_cast<deInt8>(original[idx + ndxData]) != static_cast<deInt8>(*returned))
749 string getStructShaderComponet (const ShaderTemplate component)
753 case SHADERTEMPLATE_STRIDE8BIT_STD140:
755 //struct {i8, v2i8[3]} [11]
756 "OpDecorate %v2i8arr3 ArrayStride 16\n"
757 "OpMemberDecorate %struct8 0 Offset 0\n"
758 "OpMemberDecorate %struct8 1 Offset 16\n"
759 "OpDecorate %struct8arr11 ArrayStride 64\n"
761 "OpDecorate %i8arr3 ArrayStride 16\n"
762 "OpDecorate %v2i8arr11 ArrayStride 16\n"
763 "OpDecorate %v3i8arr11 ArrayStride 16\n"
764 "OpDecorate %v4i8arr3 ArrayStride 16\n"
765 "OpDecorate %i8StructArr7 ArrayStride 1184\n"
767 "OpMemberDecorate %i8Struct 0 Offset 0\n" //i8
768 "OpMemberDecorate %i8Struct 1 Offset 2\n" //v2i8
769 "OpMemberDecorate %i8Struct 2 Offset 4\n" //v3i8
770 "OpMemberDecorate %i8Struct 3 Offset 8\n" //v4i8
771 "OpMemberDecorate %i8Struct 4 Offset 16\n" //i8[3]
772 "OpMemberDecorate %i8Struct 5 Offset 64\n" //struct {i8, v2i8[3]} [11]
773 "OpMemberDecorate %i8Struct 6 Offset 768\n" //v2i8[11]
774 "OpMemberDecorate %i8Struct 7 Offset 944\n" //i8
775 "OpMemberDecorate %i8Struct 8 Offset 960\n" //v3i8[11]
776 "OpMemberDecorate %i8Struct 9 Offset 1136\n"); //v4i8[3]
777 case SHADERTEMPLATE_STRIDE8BIT_STD430:
779 //struct {i8, v2i8[3]} [11]
780 "OpDecorate %v2i8arr3 ArrayStride 2\n"
781 "OpMemberDecorate %struct8 0 Offset 0\n"
782 "OpMemberDecorate %struct8 1 Offset 2\n"
783 "OpDecorate %struct8arr11 ArrayStride 8\n"
785 "OpDecorate %i8arr3 ArrayStride 1\n"
786 "OpDecorate %v2i8arr11 ArrayStride 2\n"
787 "OpDecorate %v3i8arr11 ArrayStride 4\n"
788 "OpDecorate %v4i8arr3 ArrayStride 4\n"
789 "OpDecorate %i8StructArr7 ArrayStride 224\n"
791 "OpMemberDecorate %i8Struct 0 Offset 0\n" //i8
792 "OpMemberDecorate %i8Struct 1 Offset 2\n" //v2i8
793 "OpMemberDecorate %i8Struct 2 Offset 4\n" //v3i8
794 "OpMemberDecorate %i8Struct 3 Offset 8\n" //v4i8
795 "OpMemberDecorate %i8Struct 4 Offset 16\n" //i8[3]
796 "OpMemberDecorate %i8Struct 5 Offset 32\n" //struct {i8, v2i8[3]} [11]
797 "OpMemberDecorate %i8Struct 6 Offset 128\n" //v2i8[11]
798 "OpMemberDecorate %i8Struct 7 Offset 150\n" //i8
799 "OpMemberDecorate %i8Struct 8 Offset 160\n" //v3i8[11]
800 "OpMemberDecorate %i8Struct 9 Offset 208\n"); //v4i8[3]
801 case SHADERTEMPLATE_STRIDE32BIT_STD140:
803 //struct {i32, v2i32[3]} [11]
804 "OpDecorate %v2i32arr3 ArrayStride 16\n"
805 "OpMemberDecorate %struct32 0 Offset 0\n"
806 "OpMemberDecorate %struct32 1 Offset 16\n"
807 "OpDecorate %struct32arr11 ArrayStride 64\n"
809 "OpDecorate %i32arr3 ArrayStride 16\n"
810 "OpDecorate %v2i32arr11 ArrayStride 16\n"
811 "OpDecorate %v3i32arr11 ArrayStride 16\n"
812 "OpDecorate %v4i32arr3 ArrayStride 16\n"
813 "OpDecorate %i32StructArr7 ArrayStride 1216\n"
815 "OpMemberDecorate %i32Struct 0 Offset 0\n" //i32
816 "OpMemberDecorate %i32Struct 1 Offset 8\n" //v2i32
817 "OpMemberDecorate %i32Struct 2 Offset 16\n" //v3i32
818 "OpMemberDecorate %i32Struct 3 Offset 32\n" //v4i32
819 "OpMemberDecorate %i32Struct 4 Offset 48\n" //i32[3]
820 "OpMemberDecorate %i32Struct 5 Offset 96\n" //struct {i32, v2i32[3]} [11]
821 "OpMemberDecorate %i32Struct 6 Offset 800\n" //v2i32[11]
822 "OpMemberDecorate %i32Struct 7 Offset 976\n" //i32
823 "OpMemberDecorate %i32Struct 8 Offset 992\n" //v3i32[11]
824 "OpMemberDecorate %i32Struct 9 Offset 1168\n"); //v4i32[3]
825 case SHADERTEMPLATE_STRIDE32BIT_STD430:
827 //struct {i32, v2i32[3]} [11]
828 "OpDecorate %v2i32arr3 ArrayStride 8\n"
829 "OpMemberDecorate %struct32 0 Offset 0\n"
830 "OpMemberDecorate %struct32 1 Offset 8\n"
831 "OpDecorate %struct32arr11 ArrayStride 32\n"
833 "OpDecorate %i32arr3 ArrayStride 4\n"
834 "OpDecorate %v2i32arr11 ArrayStride 8\n"
835 "OpDecorate %v3i32arr11 ArrayStride 16\n"
836 "OpDecorate %v4i32arr3 ArrayStride 16\n"
837 "OpDecorate %i32StructArr7 ArrayStride 736\n"
839 "OpMemberDecorate %i32Struct 0 Offset 0\n" //i32
840 "OpMemberDecorate %i32Struct 1 Offset 8\n" //v2i32
841 "OpMemberDecorate %i32Struct 2 Offset 16\n" //v3i32
842 "OpMemberDecorate %i32Struct 3 Offset 32\n" //v4i32
843 "OpMemberDecorate %i32Struct 4 Offset 48\n" //i32[3]
844 "OpMemberDecorate %i32Struct 5 Offset 64\n" //struct {i32, v2i32[3]}[11]
845 "OpMemberDecorate %i32Struct 6 Offset 416\n" //v2i32[11]
846 "OpMemberDecorate %i32Struct 7 Offset 504\n" //i32
847 "OpMemberDecorate %i32Struct 8 Offset 512\n" //v3i32[11]
848 "OpMemberDecorate %i32Struct 9 Offset 688\n"); //v4i32[3]
849 case SHADERTEMPLATE_STRIDEMIX_STD140:
851 "\n"//strutNestedIn {b8, b32, v2b8[11], b32[11]}
852 "OpDecorate %v2b8NestedArr11${InOut} ArrayStride 16\n" //v2b8[11]
853 "OpDecorate %b32NestedArr11${InOut} ArrayStride 16\n" //b32[11]
854 "OpMemberDecorate %sNested${InOut} 0 Offset 0\n" //b8
855 "OpMemberDecorate %sNested${InOut} 1 Offset 4\n" //b32
856 "OpMemberDecorate %sNested${InOut} 2 Offset 16\n" //v2b8[11]
857 "OpMemberDecorate %sNested${InOut} 3 Offset 192\n" //b32[11]
858 "OpDecorate %sNestedArr11${InOut} ArrayStride 368\n" //strutNestedIn[11]
859 "\n"//strutIn {b8, b32, v2b8, v2b32, v3b8, v3b32, v4b8, v4b32, strutNestedIn[11], b8In[11], b32bIn[11]}
860 "OpDecorate %sb8Arr11${InOut} ArrayStride 16\n" //b8In[11]
861 "OpDecorate %sb32Arr11${InOut} ArrayStride 16\n" //b32bIn[11]
862 "OpMemberDecorate %struct${InOut} 0 Offset 0\n" //b8
863 "OpMemberDecorate %struct${InOut} 1 Offset 4\n" //b32
864 "OpMemberDecorate %struct${InOut} 2 Offset 8\n" //v2b8
865 "OpMemberDecorate %struct${InOut} 3 Offset 16\n" //v2b32
866 "OpMemberDecorate %struct${InOut} 4 Offset 24\n" //v3b8
867 "OpMemberDecorate %struct${InOut} 5 Offset 32\n" //v3b32
868 "OpMemberDecorate %struct${InOut} 6 Offset 48\n" //v4b8
869 "OpMemberDecorate %struct${InOut} 7 Offset 64\n" //v4b32
870 "OpMemberDecorate %struct${InOut} 8 Offset 80\n" //strutNestedIn[11]
871 "OpMemberDecorate %struct${InOut} 9 Offset 4128\n" //b8In[11]
872 "OpMemberDecorate %struct${InOut} 10 Offset 4304\n" //b32bIn[11]
873 "OpDecorate %structArr7${InOut} ArrayStride 4480\n"); //strutIn[7]
874 case SHADERTEMPLATE_STRIDEMIX_STD430:
876 "\n"//strutNestedOut {b8, b32, v2b8[11], b32[11]}
877 "OpDecorate %v2b8NestedArr11${InOut} ArrayStride 2\n" //v2b8[11]
878 "OpDecorate %b32NestedArr11${InOut} ArrayStride 4\n" //b32[11]
879 "OpMemberDecorate %sNested${InOut} 0 Offset 0\n" //b8
880 "OpMemberDecorate %sNested${InOut} 1 Offset 4\n" //b32
881 "OpMemberDecorate %sNested${InOut} 2 Offset 8\n" //v2b8[11]
882 "OpMemberDecorate %sNested${InOut} 3 Offset 32\n" //b32[11]
883 "OpDecorate %sNestedArr11${InOut} ArrayStride 76\n" //strutNestedOut[11]
884 "\n"//strutOut {b8, b32, v2b8, v2b32, v3b8, v3b32, v4b8, v4b32, strutNestedOut[11], b8Out[11], b32bOut[11]}
885 "OpDecorate %sb8Arr11${InOut} ArrayStride 1\n" //b8Out[11]
886 "OpDecorate %sb32Arr11${InOut} ArrayStride 4\n" //b32bOut[11]
887 "OpMemberDecorate %struct${InOut} 0 Offset 0\n" //b8
888 "OpMemberDecorate %struct${InOut} 1 Offset 4\n" //b32
889 "OpMemberDecorate %struct${InOut} 2 Offset 8\n" //v2b8
890 "OpMemberDecorate %struct${InOut} 3 Offset 16\n" //v2b32
891 "OpMemberDecorate %struct${InOut} 4 Offset 24\n" //v3b8
892 "OpMemberDecorate %struct${InOut} 5 Offset 32\n" //v3b32
893 "OpMemberDecorate %struct${InOut} 6 Offset 48\n" //v4b8
894 "OpMemberDecorate %struct${InOut} 7 Offset 64\n" //v4b32
895 "OpMemberDecorate %struct${InOut} 8 Offset 80\n" //strutNestedOut[11]
896 "OpMemberDecorate %struct${InOut} 9 Offset 916\n" //b8Out[11]
897 "OpMemberDecorate %struct${InOut} 10 Offset 928\n" //b32bOut[11]
898 "OpDecorate %structArr7${InOut} ArrayStride 976\n"); //strutOut[7]
904 /*Return string contains spirv loop begin.
905 the spec should contains "exeCount" - with name of const i32, it is number of executions
906 the spec should contains "loopName" - suffix for all local names
907 %Val${loopName} - index which can be used inside loop
908 "%ndxArr${loopName} = OpVariable %fp_i32 Function\n" - has to be defined outside
909 The function should be always use with endLoop function*/
910 std::string beginLoop(const std::map<std::string, std::string>& spec)
912 const tcu::StringTemplate loopBegin (
913 "OpStore %ndxArr${loopName} %zero\n"
914 "OpBranch %Loop${loopName}\n"
915 "%Loop${loopName} = OpLabel\n"
916 "OpLoopMerge %MergeLabel1${loopName} %MergeLabel2${loopName} None\n"
917 "OpBranch %Label1${loopName}\n"
918 "%Label1${loopName} = OpLabel\n"
919 "%Val${loopName} = OpLoad %i32 %ndxArr${loopName}\n"
920 "%LessThan${loopName} = OpSLessThan %bool %Val${loopName} %${exeCount}\n"
921 "OpBranchConditional %LessThan${loopName} %ifLabel${loopName} %MergeLabel1${loopName}\n"
922 "%ifLabel${loopName} = OpLabel\n");
923 return loopBegin.specialize(spec);
925 /*Return string contains spirv loop end.
926 the spec should contains "loopName" - suffix for all local names, suffix should be the same in beginLoop
927 The function should be always use with beginLoop function*/
928 std::string endLoop(const std::map<std::string, std::string>& spec)
930 const tcu::StringTemplate loopEnd (
931 "OpBranch %MergeLabel2${loopName}\n"
932 "%MergeLabel2${loopName} = OpLabel\n"
933 "%plusOne${loopName} = OpIAdd %i32 %Val${loopName} %c_i32_1\n"
934 "OpStore %ndxArr${loopName} %plusOne${loopName}\n"
935 "OpBranch %Loop${loopName}\n"
936 "%MergeLabel1${loopName} = OpLabel\n");
937 return loopEnd.specialize(spec);
940 void addCompute8bitStorage32To8Group (tcu::TestCaseGroup* group)
942 tcu::TestContext& testCtx = group->getTestContext();
943 de::Random rnd (deStringHash(group->getName()));
944 const int numElements = 128;
946 const StringTemplate shaderTemplate (
947 "OpCapability Shader\n"
948 "OpCapability ${capability}\n"
949 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
950 "OpExtension \"SPV_KHR_8bit_storage\"\n"
951 "OpMemoryModel Logical GLSL450\n"
952 "OpEntryPoint GLCompute %main \"main\" %id\n"
953 "OpExecutionMode %main LocalSize 1 1 1\n"
954 "OpDecorate %id BuiltIn GlobalInvocationId\n"
958 "OpDecorate %SSBO32 Block\n"
959 "OpDecorate %SSBO8 Block\n"
960 "OpMemberDecorate %SSBO32 0 Offset 0\n"
961 "OpMemberDecorate %SSBO8 0 Offset 0\n"
962 "OpDecorate %ssbo32 DescriptorSet 0\n"
963 "OpDecorate %ssbo8 DescriptorSet 0\n"
964 "OpDecorate %ssbo32 Binding 0\n"
965 "OpDecorate %ssbo8 Binding 1\n"
967 "${matrix_decor:opt}\n"
971 "%bool = OpTypeBool\n"
972 "%void = OpTypeVoid\n"
973 "%voidf = OpTypeFunction %void\n"
974 "%u32 = OpTypeInt 32 0\n"
975 "%i32 = OpTypeInt 32 1\n"
976 "%f32 = OpTypeFloat 32\n"
977 "%uvec3 = OpTypeVector %u32 3\n"
978 "%fvec3 = OpTypeVector %f32 3\n"
979 "%uvec3ptr = OpTypePointer Input %uvec3\n"
980 "%i32ptr = OpTypePointer StorageBuffer %i32\n"
981 "%f32ptr = OpTypePointer StorageBuffer %f32\n"
983 "%zero = OpConstant %i32 0\n"
984 "%c_i32_1 = OpConstant %i32 1\n"
985 "%c_i32_16 = OpConstant %i32 16\n"
986 "%c_i32_32 = OpConstant %i32 32\n"
987 "%c_i32_64 = OpConstant %i32 64\n"
988 "%c_i32_128 = OpConstant %i32 128\n"
990 "%i32arr = OpTypeArray %i32 %c_i32_128\n"
991 "%f32arr = OpTypeArray %f32 %c_i32_128\n"
994 "${matrix_types:opt}\n"
996 "%SSBO32 = OpTypeStruct %${matrix_prefix:opt}${base32}arr\n"
997 "%SSBO8 = OpTypeStruct %${matrix_prefix:opt}${base8}arr\n"
998 "%up_SSBO32 = OpTypePointer ${storage} %SSBO32\n"
999 "%up_SSBO8 = OpTypePointer ${storage} %SSBO8\n"
1000 "%ssbo32 = OpVariable %up_SSBO32 ${storage}\n"
1001 "%ssbo8 = OpVariable %up_SSBO8 ${storage}\n"
1003 "%id = OpVariable %uvec3ptr Input\n"
1005 "%main = OpFunction %void None %voidf\n"
1006 "%label = OpLabel\n"
1007 "%idval = OpLoad %uvec3 %id\n"
1008 "%x = OpCompositeExtract %u32 %idval 0\n"
1009 "%inloc = OpAccessChain %${base32}ptr %ssbo32 %zero %x ${index0:opt}\n"
1010 "%val32 = OpLoad %${base32} %inloc\n"
1011 "%val8 = ${convert} %${base8} %val32\n"
1012 "%outloc = OpAccessChain %${base8}ptr %ssbo8 %zero %x ${index0:opt}\n"
1013 " OpStore %outloc %val8\n"
1014 "${matrix_store:opt}\n"
1016 " OpFunctionEnd\n");
1019 const char sintTypes[] =
1020 "%i8 = OpTypeInt 8 1\n"
1021 "%i8ptr = OpTypePointer StorageBuffer %i8\n"
1022 "%i8arr = OpTypeArray %i8 %c_i32_128\n"
1023 "%v2i8 = OpTypeVector %i8 2\n"
1024 "%v4i8 = OpTypeVector %i8 4\n"
1025 "%v2i32 = OpTypeVector %i32 2\n"
1026 "%v4i32 = OpTypeVector %i32 4\n"
1027 "%v2i8ptr = OpTypePointer StorageBuffer %v2i8\n"
1028 "%v2i32ptr = OpTypePointer StorageBuffer %v2i32\n"
1029 "%v2i8arr = OpTypeArray %v2i8 %c_i32_64\n"
1030 "%v2i32arr = OpTypeArray %v2i32 %c_i32_64\n";
1032 const char uintTypes[] =
1033 "%u8 = OpTypeInt 8 0\n"
1034 "%u8ptr = OpTypePointer StorageBuffer %u8\n"
1035 "%u32ptr = OpTypePointer StorageBuffer %u32\n"
1036 "%u8arr = OpTypeArray %u8 %c_i32_128\n"
1037 "%u32arr = OpTypeArray %u32 %c_i32_128\n"
1038 "%v2u8 = OpTypeVector %u8 2\n"
1039 "%v2u32 = OpTypeVector %u32 2\n"
1040 "%v4u32 = OpTypeVector %u32 4\n"
1041 "%v2u8ptr = OpTypePointer StorageBuffer %v2u8\n"
1042 "%v2u32ptr = OpTypePointer StorageBuffer %v2u32\n"
1043 "%v2u8arr = OpTypeArray %v2u8 %c_i32_64\n"
1044 "%v2u32arr = OpTypeArray %v2u32 %c_i32_64\n";
1046 struct CompositeType
1057 const CompositeType cTypes[] =
1059 {"scalar_sint", sintTypes, "i32", "i8", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i8arr ArrayStride 1\n", numElements},
1060 {"scalar_uint", uintTypes, "u32", "u8", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u8arr ArrayStride 1\n", numElements},
1061 {"vector_sint", sintTypes, "v2i32", "v2i8", "OpSConvert", "OpDecorate %v2i32arr ArrayStride 8\nOpDecorate %v2i8arr ArrayStride 2\n", numElements / 2},
1062 {"vector_uint", uintTypes, "v2u32", "v2u8", "OpUConvert", "OpDecorate %v2u32arr ArrayStride 8\nOpDecorate %v2u8arr ArrayStride 2\n", numElements / 2},
1065 vector<deInt32> inputs = getInt32s(rnd, numElements);
1066 vector<deInt8> outputs (inputs.size());
1068 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
1069 outputs[numNdx] = (static_cast<deInt8>(0xff & inputs[numNdx]));
1071 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1073 ComputeShaderSpec spec;
1074 map<string, string> specs;
1075 string testName = string(CAPABILITIES[STORAGE_BUFFER_TEST].name) + "_" + cTypes[tyIdx].name;
1077 specs["capability"] = CAPABILITIES[STORAGE_BUFFER_TEST].cap;
1078 specs["storage"] = CAPABILITIES[STORAGE_BUFFER_TEST].decor;
1079 specs["stride"] = cTypes[tyIdx].stride;
1080 specs["base32"] = cTypes[tyIdx].base32;
1081 specs["base8"] = cTypes[tyIdx].base8;
1082 specs["types"] = cTypes[tyIdx].types;
1083 specs["convert"] = cTypes[tyIdx].opcode;
1085 spec.assembly = shaderTemplate.specialize(specs);
1086 spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
1088 spec.inputs.push_back(Resource(BufferSp(new Int32Buffer(inputs)), CAPABILITIES[STORAGE_BUFFER_TEST].dtype));
1089 spec.outputs.push_back(Resource(BufferSp(new Int8Buffer(outputs))));
1090 spec.extensions.push_back("VK_KHR_8bit_storage");
1091 spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1092 spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[STORAGE_BUFFER_TEST].name);
1094 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
1099 void addCompute8bitUniform8To32Group (tcu::TestCaseGroup* group)
1101 tcu::TestContext& testCtx = group->getTestContext();
1102 de::Random rnd (deStringHash(group->getName()));
1103 const int numElements = 128;
1105 const StringTemplate shaderTemplate (
1106 "OpCapability Shader\n"
1107 "OpCapability ${capability}\n"
1108 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1109 "OpExtension \"SPV_KHR_8bit_storage\"\n"
1110 "OpMemoryModel Logical GLSL450\n"
1111 "OpEntryPoint GLCompute %main \"main\" %id\n"
1112 "OpExecutionMode %main LocalSize 1 1 1\n"
1113 "OpDecorate %id BuiltIn GlobalInvocationId\n"
1117 "OpDecorate %SSBO32 Block\n"
1118 "OpDecorate %SSBO8 Block\n"
1119 "OpMemberDecorate %SSBO32 0 Offset 0\n"
1120 "OpMemberDecorate %SSBO8 0 Offset 0\n"
1121 "OpDecorate %SSBO8 ${storage}\n"
1122 "OpDecorate %ssbo32 DescriptorSet 0\n"
1123 "OpDecorate %ssbo8 DescriptorSet 0\n"
1124 "OpDecorate %ssbo32 Binding 1\n"
1125 "OpDecorate %ssbo8 Binding 0\n"
1127 "${matrix_decor:opt}\n"
1129 "%bool = OpTypeBool\n"
1130 "%void = OpTypeVoid\n"
1131 "%voidf = OpTypeFunction %void\n"
1132 "%u32 = OpTypeInt 32 0\n"
1133 "%i32 = OpTypeInt 32 1\n"
1134 "%uvec3 = OpTypeVector %u32 3\n"
1135 "%uvec3ptr = OpTypePointer Input %uvec3\n"
1136 "%i32ptr = OpTypePointer StorageBuffer %i32\n"
1138 "%zero = OpConstant %i32 0\n"
1139 "%c_i32_1 = OpConstant %i32 1\n"
1140 "%c_i32_2 = OpConstant %i32 2\n"
1141 "%c_i32_3 = OpConstant %i32 3\n"
1142 "%c_i32_16 = OpConstant %i32 16\n"
1143 "%c_i32_32 = OpConstant %i32 32\n"
1144 "%c_i32_64 = OpConstant %i32 64\n"
1145 "%c_i32_128 = OpConstant %i32 128\n"
1147 "%i32arr = OpTypeArray %i32 %c_i32_128\n"
1150 "${matrix_types:opt}\n"
1152 "%SSBO32 = OpTypeStruct %${matrix_prefix:opt}${base32}arr\n"
1153 "%SSBO8 = OpTypeStruct %${matrix_prefix:opt}${base8}arr\n"
1154 "%up_SSBO32 = OpTypePointer StorageBuffer %SSBO32\n"
1155 "%up_SSBO8 = OpTypePointer Uniform %SSBO8\n"
1156 "%ssbo32 = OpVariable %up_SSBO32 StorageBuffer\n"
1157 "%ssbo8 = OpVariable %up_SSBO8 Uniform\n"
1159 "%id = OpVariable %uvec3ptr Input\n"
1161 "%main = OpFunction %void None %voidf\n"
1162 "%label = OpLabel\n"
1163 "%idval = OpLoad %uvec3 %id\n"
1164 "%x = OpCompositeExtract %u32 %idval 0\n"
1165 "%inloc = OpAccessChain %${base8}ptr %ssbo8 %zero %x ${index0:opt}\n"
1166 "%val8 = OpLoad %${base8} %inloc\n"
1167 "%val32 = ${convert} %${base32} %val8\n"
1168 "%outloc = OpAccessChain %${base32}ptr %ssbo32 %zero %x ${index0:opt}\n"
1169 " OpStore %outloc %val32\n"
1170 "${matrix_store:opt}\n"
1172 " OpFunctionEnd\n");
1176 const char sintTypes[] =
1177 "%i8 = OpTypeInt 8 1\n"
1178 "%i8ptr = OpTypePointer Uniform %i8\n"
1179 "%i8arr = OpTypeArray %i8 %c_i32_128\n"
1180 "%v4i8 = OpTypeVector %i8 4\n"
1181 "%v4i32 = OpTypeVector %i32 4\n"
1182 "%v4i8ptr = OpTypePointer Uniform %v4i8\n"
1183 "%v4i32ptr = OpTypePointer StorageBuffer %v4i32\n"
1184 "%v4i8arr = OpTypeArray %v4i8 %c_i32_32\n"
1185 "%v4i32arr = OpTypeArray %v4i32 %c_i32_32\n";
1187 const char uintTypes[] =
1188 "%u8 = OpTypeInt 8 0\n"
1189 "%u8ptr = OpTypePointer Uniform %u8\n"
1190 "%u32ptr = OpTypePointer StorageBuffer %u32\n"
1191 "%u8arr = OpTypeArray %u8 %c_i32_128\n"
1192 "%u32arr = OpTypeArray %u32 %c_i32_128\n"
1193 "%v4u8 = OpTypeVector %u8 4\n"
1194 "%v4u32 = OpTypeVector %u32 4\n"
1195 "%v4u8ptr = OpTypePointer Uniform %v4u8\n"
1196 "%v4u32ptr = OpTypePointer StorageBuffer %v4u32\n"
1197 "%v4u8arr = OpTypeArray %v4u8 %c_i32_32\n"
1198 "%v4u32arr = OpTypeArray %v4u32 %c_i32_32\n";
1200 struct CompositeType
1208 const int componentsCount;
1211 const CompositeType cTypes[] =
1213 {"scalar_sint", sintTypes, "i32", "i8", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i8arr ArrayStride 16\n", 1},
1214 {"scalar_uint", uintTypes, "u32", "u8", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u8arr ArrayStride 16\n", 1},
1215 {"vector_sint", sintTypes, "v4i32", "v4i8", "OpSConvert", "OpDecorate %v4i32arr ArrayStride 16\nOpDecorate %v4i8arr ArrayStride 16\n", 4},
1216 {"vector_uint", uintTypes, "v4u32", "v4u8", "OpUConvert", "OpDecorate %v4u32arr ArrayStride 16\nOpDecorate %v4u8arr ArrayStride 16\n", 4},
1219 vector<deInt32> outputs(numElements);
1221 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1223 ComputeShaderSpec spec;
1224 map<string, string> specs;
1225 string testName = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name) + "_" + cTypes[tyIdx].name;
1227 vector<deInt8> inputs = getInt8s(rnd, (arrayStrideInBytesUniform / static_cast<deUint32>(sizeof(deInt8))) * (numElements / cTypes[tyIdx].componentsCount));
1229 specs["capability"] = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
1230 specs["storage"] = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].decor;
1231 specs["stride"] = cTypes[tyIdx].stride;
1232 specs["base32"] = cTypes[tyIdx].base32;
1233 specs["base8"] = cTypes[tyIdx].base8;
1234 specs["types"] = cTypes[tyIdx].types;
1235 specs["convert"] = cTypes[tyIdx].opcode;
1237 spec.assembly = shaderTemplate.specialize(specs);
1238 spec.numWorkGroups = IVec3(numElements / cTypes[tyIdx].componentsCount, 1, 1);
1240 spec.inputs.push_back(Resource(BufferSp(new Int8Buffer(inputs)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
1241 spec.outputs.push_back(Resource(BufferSp(new Int32Buffer(outputs))));
1243 spec.extensions.push_back("VK_KHR_8bit_storage");
1244 spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1245 spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
1247 if (cTypes[tyIdx].componentsCount == 4)
1248 spec.verifyIO = checkUniformsArray<deInt8, deInt32, 4>;
1250 spec.verifyIO = checkUniformsArray<deInt8, deInt32, 1>;
1252 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
1257 void addCompute8bitStoragePushConstant8To32Group (tcu::TestCaseGroup* group)
1259 tcu::TestContext& testCtx = group->getTestContext();
1260 de::Random rnd (deStringHash(group->getName()));
1261 const int numElements = 64;
1263 const StringTemplate shaderTemplate (
1264 "OpCapability Shader\n"
1265 "OpCapability StoragePushConstant8\n"
1266 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1267 "OpExtension \"SPV_KHR_8bit_storage\"\n"
1268 "OpMemoryModel Logical GLSL450\n"
1269 "OpEntryPoint GLCompute %main \"main\" %id\n"
1270 "OpExecutionMode %main LocalSize 1 1 1\n"
1271 "OpDecorate %id BuiltIn GlobalInvocationId\n"
1275 "OpDecorate %PC8 Block\n"
1276 "OpDecorate %SSBO32 Block\n"
1277 "OpMemberDecorate %PC8 0 Offset 0\n"
1278 "OpMemberDecorate %SSBO32 0 Offset 0\n"
1279 "OpDecorate %ssbo32 DescriptorSet 0\n"
1280 "OpDecorate %ssbo32 Binding 0\n"
1282 "${matrix_decor:opt}\n"
1284 "%bool = OpTypeBool\n"
1285 "%void = OpTypeVoid\n"
1286 "%voidf = OpTypeFunction %void\n"
1287 "%u32 = OpTypeInt 32 0\n"
1288 "%i32 = OpTypeInt 32 1\n"
1289 "%uvec3 = OpTypeVector %u32 3\n"
1290 "%uvec3ptr = OpTypePointer Input %uvec3\n"
1291 "%i32ptr = OpTypePointer StorageBuffer %i32\n"
1293 "%zero = OpConstant %i32 0\n"
1294 "%c_i32_1 = OpConstant %i32 1\n"
1295 "%c_i32_8 = OpConstant %i32 8\n"
1296 "%c_i32_16 = OpConstant %i32 16\n"
1297 "%c_i32_32 = OpConstant %i32 32\n"
1298 "%c_i32_64 = OpConstant %i32 64\n"
1300 "%i32arr = OpTypeArray %i32 %c_i32_64\n"
1303 "${matrix_types:opt}\n"
1305 "%PC8 = OpTypeStruct %${matrix_prefix:opt}${base8}arr\n"
1306 "%pp_PC8 = OpTypePointer PushConstant %PC8\n"
1307 "%pc8 = OpVariable %pp_PC8 PushConstant\n"
1308 "%SSBO32 = OpTypeStruct %${matrix_prefix:opt}${base32}arr\n"
1309 "%up_SSBO32 = OpTypePointer StorageBuffer %SSBO32\n"
1310 "%ssbo32 = OpVariable %up_SSBO32 StorageBuffer\n"
1312 "%id = OpVariable %uvec3ptr Input\n"
1314 "%main = OpFunction %void None %voidf\n"
1315 "%label = OpLabel\n"
1316 "%idval = OpLoad %uvec3 %id\n"
1317 "%x = OpCompositeExtract %u32 %idval 0\n"
1318 "%inloc = OpAccessChain %${base8}ptr %pc8 %zero %x ${index0:opt}\n"
1319 "%val8 = OpLoad %${base8} %inloc\n"
1320 "%val32 = ${convert} %${base32} %val8\n"
1321 "%outloc = OpAccessChain %${base32}ptr %ssbo32 %zero %x ${index0:opt}\n"
1322 " OpStore %outloc %val32\n"
1323 "${matrix_store:opt}\n"
1325 " OpFunctionEnd\n");
1328 const char sintTypes[] =
1329 "%i8 = OpTypeInt 8 1\n"
1330 "%i8ptr = OpTypePointer PushConstant %i8\n"
1331 "%i8arr = OpTypeArray %i8 %c_i32_64\n"
1332 "%v2i8 = OpTypeVector %i8 2\n"
1333 "%v2i32 = OpTypeVector %i32 2\n"
1334 "%v2i8ptr = OpTypePointer PushConstant %v2i8\n"
1335 "%v2i32ptr = OpTypePointer StorageBuffer %v2i32\n"
1336 "%v2i8arr = OpTypeArray %v2i8 %c_i32_32\n"
1337 "%v2i32arr = OpTypeArray %v2i32 %c_i32_32\n";
1339 const char uintTypes[] =
1340 "%u8 = OpTypeInt 8 0\n"
1341 "%u8ptr = OpTypePointer PushConstant %u8\n"
1342 "%u32ptr = OpTypePointer StorageBuffer %u32\n"
1343 "%u8arr = OpTypeArray %u8 %c_i32_64\n"
1344 "%u32arr = OpTypeArray %u32 %c_i32_64\n"
1345 "%v2u8 = OpTypeVector %u8 2\n"
1346 "%v2u32 = OpTypeVector %u32 2\n"
1347 "%v2u8ptr = OpTypePointer PushConstant %v2u8\n"
1348 "%v2u32ptr = OpTypePointer StorageBuffer %v2u32\n"
1349 "%v2u8arr = OpTypeArray %v2u8 %c_i32_32\n"
1350 "%v2u32arr = OpTypeArray %v2u32 %c_i32_32\n";
1352 struct CompositeType
1364 const CompositeType cTypes[] =
1366 {"scalar_sint", true, sintTypes, "i32", "i8", "OpSConvert", "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i8arr ArrayStride 1\n", numElements},
1367 {"scalar_uint", false, uintTypes, "u32", "u8", "OpUConvert", "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u8arr ArrayStride 1\n", numElements},
1368 {"vector_sint", true, sintTypes, "v2i32", "v2i8", "OpSConvert", "OpDecorate %v2i32arr ArrayStride 8\nOpDecorate %v2i8arr ArrayStride 2\n", numElements / 2},
1369 {"vector_uint", false, uintTypes, "v2u32", "v2u8", "OpUConvert", "OpDecorate %v2u32arr ArrayStride 8\nOpDecorate %v2u8arr ArrayStride 2\n", numElements / 2},
1372 vector<deInt8> inputs = getInt8s(rnd, numElements);
1373 vector<deInt32> sOutputs;
1374 vector<deInt32> uOutputs;
1375 const deUint8 signBitMask = 0x80;
1376 const deUint32 signExtendMask = 0xffff0000;
1378 sOutputs.reserve(inputs.size());
1379 uOutputs.reserve(inputs.size());
1381 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
1383 uOutputs.push_back(static_cast<deUint8>(inputs[numNdx]));
1384 if (inputs[numNdx] & signBitMask)
1385 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx] | signExtendMask));
1387 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx]));
1390 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1392 ComputeShaderSpec spec;
1393 map<string, string> specs;
1394 const char* testName = cTypes[tyIdx].name;
1396 specs["stride"] = cTypes[tyIdx].stride;
1397 specs["base32"] = cTypes[tyIdx].base32;
1398 specs["base8"] = cTypes[tyIdx].base8;
1399 specs["types"] = cTypes[tyIdx].types;
1400 specs["convert"] = cTypes[tyIdx].opcode;
1402 spec.assembly = shaderTemplate.specialize(specs);
1403 spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
1404 spec.pushConstants = BufferSp(new Int8Buffer(inputs));
1406 if (cTypes[tyIdx].isSigned)
1407 spec.outputs.push_back(BufferSp(new Int32Buffer(sOutputs)));
1409 spec.outputs.push_back(BufferSp(new Int32Buffer(uOutputs)));
1410 spec.extensions.push_back("VK_KHR_8bit_storage");
1411 spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1412 spec.requestedVulkanFeatures.ext8BitStorage = EXT8BITSTORAGEFEATURES_PUSH_CONSTANT;
1414 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName, testName, spec));
1419 void addCompute8bitStorage16To8Group (tcu::TestCaseGroup* group)
1421 tcu::TestContext& testCtx = group->getTestContext();
1422 de::Random rnd (deStringHash(group->getName()));
1423 const int numElements = 128;
1425 const StringTemplate shaderTemplate (
1426 "OpCapability Shader\n"
1427 "OpCapability ${capability}\n"
1428 "OpCapability StorageUniform16\n"
1429 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1430 "OpExtension \"SPV_KHR_8bit_storage\"\n"
1431 "OpExtension \"SPV_KHR_16bit_storage\"\n"
1432 "OpMemoryModel Logical GLSL450\n"
1433 "OpEntryPoint GLCompute %main \"main\" %id\n"
1434 "OpExecutionMode %main LocalSize 1 1 1\n"
1435 "OpDecorate %id BuiltIn GlobalInvocationId\n"
1439 "OpDecorate %SSBO16 Block\n"
1440 "OpDecorate %SSBO8 Block\n"
1441 "OpMemberDecorate %SSBO16 0 Offset 0\n"
1442 "OpMemberDecorate %SSBO8 0 Offset 0\n"
1443 "OpDecorate %ssbo16 DescriptorSet 0\n"
1444 "OpDecorate %ssbo8 DescriptorSet 0\n"
1445 "OpDecorate %ssbo16 Binding 0\n"
1446 "OpDecorate %ssbo8 Binding 1\n"
1448 "${matrix_decor:opt}\n"
1452 "%bool = OpTypeBool\n"
1453 "%void = OpTypeVoid\n"
1454 "%voidf = OpTypeFunction %void\n"
1455 "%i32 = OpTypeInt 32 1\n"
1456 "%u32 = OpTypeInt 32 0\n"
1457 "%uvec3 = OpTypeVector %u32 3\n"
1458 "%uvec3ptr = OpTypePointer Input %uvec3\n"
1460 "%zero = OpConstant %i32 0\n"
1461 "%c_i32_1 = OpConstant %i32 1\n"
1462 "%c_i32_16 = OpConstant %i32 16\n"
1463 "%c_i32_32 = OpConstant %i32 32\n"
1464 "%c_i32_64 = OpConstant %i32 64\n"
1465 "%c_i32_128 = OpConstant %i32 128\n"
1468 "${matrix_types:opt}\n"
1470 "%SSBO16 = OpTypeStruct %${matrix_prefix:opt}${base16}arr\n"
1471 "%SSBO8 = OpTypeStruct %${matrix_prefix:opt}${base8}arr\n"
1472 "%up_SSBO16 = OpTypePointer ${storage} %SSBO16\n"
1473 "%up_SSBO8 = OpTypePointer ${storage} %SSBO8\n"
1474 "%ssbo16 = OpVariable %up_SSBO16 ${storage}\n"
1475 "%ssbo8 = OpVariable %up_SSBO8 ${storage}\n"
1477 "%id = OpVariable %uvec3ptr Input\n"
1479 "%main = OpFunction %void None %voidf\n"
1480 "%label = OpLabel\n"
1481 "%idval = OpLoad %uvec3 %id\n"
1482 "%x = OpCompositeExtract %u32 %idval 0\n"
1483 "%inloc = OpAccessChain %${base16}ptr %ssbo16 %zero %x ${index0:opt}\n"
1484 "%val16 = OpLoad %${base16} %inloc\n"
1485 "%val8 = ${convert} %${base8} %val16\n"
1486 "%outloc = OpAccessChain %${base8}ptr %ssbo8 %zero %x ${index0:opt}\n"
1487 " OpStore %outloc %val8\n"
1488 "${matrix_store:opt}\n"
1490 " OpFunctionEnd\n");
1493 const char sintTypes[] =
1494 "%i8 = OpTypeInt 8 1\n"
1495 "%i16 = OpTypeInt 16 1\n"
1496 "%i8ptr = OpTypePointer StorageBuffer %i8\n"
1497 "%i8arr = OpTypeArray %i8 %c_i32_128\n"
1498 "%i16arr = OpTypeArray %i16 %c_i32_128\n"
1499 "%v2i8 = OpTypeVector %i8 2\n"
1500 "%v2i16 = OpTypeVector %i16 2\n"
1501 "%v2i8ptr = OpTypePointer StorageBuffer %v2i8\n"
1502 "%v2i16ptr = OpTypePointer StorageBuffer %v2i16\n"
1503 "%v2i8arr = OpTypeArray %v2i8 %c_i32_64\n"
1504 "%v2i16arr = OpTypeArray %v2i16 %c_i32_64\n"
1505 "%i16ptr = OpTypePointer StorageBuffer %i16\n";
1507 const char uintTypes[] =
1508 "%u8 = OpTypeInt 8 0\n"
1509 "%u16 = OpTypeInt 16 0\n"
1510 "%u8ptr = OpTypePointer StorageBuffer %u8\n"
1511 "%u16ptr = OpTypePointer StorageBuffer %u16\n"
1512 "%u8arr = OpTypeArray %u8 %c_i32_128\n"
1513 "%u16arr = OpTypeArray %u16 %c_i32_128\n"
1514 "%v2u8 = OpTypeVector %u8 2\n"
1515 "%v2u16 = OpTypeVector %u16 2\n"
1516 "%v2u8ptr = OpTypePointer StorageBuffer %v2u8\n"
1517 "%v2u16ptr = OpTypePointer StorageBuffer %v2u16\n"
1518 "%v2u8arr = OpTypeArray %v2u8 %c_i32_64\n"
1519 "%v2u16arr = OpTypeArray %v2u16 %c_i32_64\n";
1521 struct CompositeType
1532 const CompositeType cTypes[] =
1534 {"scalar_sint", sintTypes, "i16", "i8", "OpSConvert", "OpDecorate %i16arr ArrayStride 2\nOpDecorate %i8arr ArrayStride 1\n", numElements},
1535 {"scalar_uint", uintTypes, "u16", "u8", "OpUConvert", "OpDecorate %u16arr ArrayStride 2\nOpDecorate %u8arr ArrayStride 1\n", numElements},
1536 {"vector_sint", sintTypes, "v2i16", "v2i8", "OpSConvert", "OpDecorate %v2i16arr ArrayStride 4\nOpDecorate %v2i8arr ArrayStride 2\n", numElements / 2},
1537 {"vector_uint", uintTypes, "v2u16", "v2u8", "OpUConvert", "OpDecorate %v2u16arr ArrayStride 4\nOpDecorate %v2u8arr ArrayStride 2\n", numElements / 2},
1540 vector<deInt16> inputs = getInt16s(rnd, numElements);
1541 vector<deInt8> outputs;
1543 outputs.reserve(inputs.size());
1544 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
1545 outputs.push_back(static_cast<deInt8>(0xff & inputs[numNdx]));
1547 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1549 ComputeShaderSpec spec;
1550 map<string, string> specs;
1551 string testName = string(CAPABILITIES[STORAGE_BUFFER_TEST].name) + "_" + cTypes[tyIdx].name;
1553 specs["capability"] = CAPABILITIES[STORAGE_BUFFER_TEST].cap;
1554 specs["storage"] = CAPABILITIES[STORAGE_BUFFER_TEST].decor;
1555 specs["stride"] = cTypes[tyIdx].stride;
1556 specs["base16"] = cTypes[tyIdx].base16;
1557 specs["base8"] = cTypes[tyIdx].base8;
1558 specs["types"] = cTypes[tyIdx].types;
1559 specs["convert"] = cTypes[tyIdx].opcode;
1561 spec.assembly = shaderTemplate.specialize(specs);
1562 spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
1564 spec.inputs.push_back(Resource(BufferSp(new Int16Buffer(inputs)), CAPABILITIES[STORAGE_BUFFER_TEST].dtype));
1565 spec.outputs.push_back(Resource(BufferSp(new Int8Buffer(outputs))));
1566 spec.extensions.push_back("VK_KHR_16bit_storage");
1567 spec.extensions.push_back("VK_KHR_8bit_storage");
1568 spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1569 spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[STORAGE_BUFFER_TEST].name);
1570 spec.requestedVulkanFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM;
1572 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
1577 void addCompute8bitUniform8To16Group (tcu::TestCaseGroup* group)
1579 tcu::TestContext& testCtx = group->getTestContext();
1580 de::Random rnd (deStringHash(group->getName()));
1581 const int numElements = 128;
1583 const StringTemplate shaderTemplate (
1584 "OpCapability Shader\n"
1585 "OpCapability ${capability}\n"
1586 "OpCapability StorageUniform16\n"
1587 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1588 "OpExtension \"SPV_KHR_8bit_storage\"\n"
1589 "OpExtension \"SPV_KHR_16bit_storage\"\n"
1590 "OpMemoryModel Logical GLSL450\n"
1591 "OpEntryPoint GLCompute %main \"main\" %id\n"
1592 "OpExecutionMode %main LocalSize 1 1 1\n"
1593 "OpDecorate %id BuiltIn GlobalInvocationId\n"
1597 "OpDecorate %SSBO16 Block\n"
1598 "OpDecorate %SSBO8 Block\n"
1599 "OpMemberDecorate %SSBO16 0 Offset 0\n"
1600 "OpMemberDecorate %SSBO8 0 Offset 0\n"
1601 "OpDecorate %SSBO8 ${storage}\n"
1602 "OpDecorate %ssbo16 DescriptorSet 0\n"
1603 "OpDecorate %ssbo8 DescriptorSet 0\n"
1604 "OpDecorate %ssbo16 Binding 1\n"
1605 "OpDecorate %ssbo8 Binding 0\n"
1607 "${matrix_decor:opt}\n"
1609 "%bool = OpTypeBool\n"
1610 "%void = OpTypeVoid\n"
1611 "%voidf = OpTypeFunction %void\n"
1613 "%i32 = OpTypeInt 32 1\n"
1614 "%u32 = OpTypeInt 32 0\n"
1615 "%uvec3 = OpTypeVector %u32 3\n"
1616 "%uvec3ptr = OpTypePointer Input %uvec3\n"
1618 "%zero = OpConstant %i32 0\n"
1619 "%c_i32_1 = OpConstant %i32 1\n"
1620 "%c_i32_2 = OpConstant %i32 2\n"
1621 "%c_i32_3 = OpConstant %i32 3\n"
1622 "%c_i32_16 = OpConstant %i32 16\n"
1623 "%c_i32_32 = OpConstant %i32 32\n"
1624 "%c_i32_64 = OpConstant %i32 64\n"
1625 "%c_i32_128 = OpConstant %i32 128\n"
1628 "${matrix_types:opt}\n"
1630 "%SSBO16 = OpTypeStruct %${matrix_prefix:opt}${base16}arr\n"
1631 "%SSBO8 = OpTypeStruct %${matrix_prefix:opt}${base8}arr\n"
1632 "%up_SSBO16 = OpTypePointer StorageBuffer %SSBO16\n"
1633 "%up_SSBO8 = OpTypePointer Uniform %SSBO8\n"
1634 "%ssbo16 = OpVariable %up_SSBO16 StorageBuffer\n"
1635 "%ssbo8 = OpVariable %up_SSBO8 Uniform\n"
1637 "%id = OpVariable %uvec3ptr Input\n"
1639 "%main = OpFunction %void None %voidf\n"
1640 "%label = OpLabel\n"
1641 "%idval = OpLoad %uvec3 %id\n"
1642 "%x = OpCompositeExtract %u32 %idval 0\n"
1643 "%inloc = OpAccessChain %${base8}ptr %ssbo8 %zero %x ${index0:opt}\n"
1644 "%val8 = OpLoad %${base8} %inloc\n"
1645 "%val16 = ${convert} %${base16} %val8\n"
1646 "%outloc = OpAccessChain %${base16}ptr %ssbo16 %zero %x ${index0:opt}\n"
1647 " OpStore %outloc %val16\n"
1648 "${matrix_store:opt}\n"
1650 " OpFunctionEnd\n");
1654 const char sintTypes[] =
1655 "%i8 = OpTypeInt 8 1\n"
1656 "%i16 = OpTypeInt 16 1\n"
1657 "%i8ptr = OpTypePointer Uniform %i8\n"
1658 "%i8arr = OpTypeArray %i8 %c_i32_128\n"
1659 "%i16arr = OpTypeArray %i16 %c_i32_128\n"
1660 "%i16ptr = OpTypePointer StorageBuffer %i16\n"
1661 "%v4i8 = OpTypeVector %i8 4\n"
1662 "%v4i16 = OpTypeVector %i16 4\n"
1663 "%v4i8ptr = OpTypePointer Uniform %v4i8\n"
1664 "%v4i16ptr = OpTypePointer StorageBuffer %v4i16\n"
1665 "%v4i8arr = OpTypeArray %v4i8 %c_i32_32\n"
1666 "%v4i16arr = OpTypeArray %v4i16 %c_i32_32\n";
1668 const char uintTypes[] =
1669 "%u8 = OpTypeInt 8 0\n"
1670 "%u16 = OpTypeInt 16 0\n"
1671 "%u8ptr = OpTypePointer Uniform %u8\n"
1672 "%u16ptr = OpTypePointer StorageBuffer %u16\n"
1673 "%u8arr = OpTypeArray %u8 %c_i32_128\n"
1674 "%u16arr = OpTypeArray %u16 %c_i32_128\n"
1675 "%v4u8 = OpTypeVector %u8 4\n"
1676 "%v4u16 = OpTypeVector %u16 4\n"
1677 "%v4u8ptr = OpTypePointer Uniform %v4u8\n"
1678 "%v4u16ptr = OpTypePointer StorageBuffer %v4u16\n"
1679 "%v4u8arr = OpTypeArray %v4u8 %c_i32_32\n"
1680 "%v4u16arr = OpTypeArray %v4u16 %c_i32_32\n";
1682 struct CompositeType
1690 const int componentsCount;
1693 const CompositeType cTypes[] =
1695 {"scalar_sint", sintTypes, "i16", "i8", "OpSConvert", "OpDecorate %i16arr ArrayStride 2\nOpDecorate %i8arr ArrayStride 16\n", 1},
1696 {"scalar_uint", uintTypes, "u16", "u8", "OpUConvert", "OpDecorate %u16arr ArrayStride 2\nOpDecorate %u8arr ArrayStride 16\n", 1},
1697 {"vector_sint", sintTypes, "v4i16", "v4i8", "OpSConvert", "OpDecorate %v4i16arr ArrayStride 8\nOpDecorate %v4i8arr ArrayStride 16\n", 4},
1698 {"vector_uint", uintTypes, "v4u16", "v4u8", "OpUConvert", "OpDecorate %v4u16arr ArrayStride 8\nOpDecorate %v4u8arr ArrayStride 16\n", 4},
1701 vector<deInt16> outputs(numElements);
1703 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1705 ComputeShaderSpec spec;
1706 map<string, string> specs;
1707 string testName = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name) + "_" + cTypes[tyIdx].name;
1709 vector<deInt8> inputs = getInt8s(rnd, (arrayStrideInBytesUniform / static_cast<deUint32>(sizeof(deInt8))) * (numElements / cTypes[tyIdx].componentsCount));
1711 specs["capability"] = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
1712 specs["storage"] = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].decor;
1713 specs["stride"] = cTypes[tyIdx].stride;
1714 specs["base16"] = cTypes[tyIdx].base16;
1715 specs["base8"] = cTypes[tyIdx].base8;
1716 specs["types"] = cTypes[tyIdx].types;
1717 specs["convert"] = cTypes[tyIdx].opcode;
1719 spec.assembly = shaderTemplate.specialize(specs);
1720 spec.numWorkGroups = IVec3(numElements / cTypes[tyIdx].componentsCount, 1, 1);
1722 spec.inputs.push_back(Resource(BufferSp(new Int8Buffer(inputs)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
1723 spec.outputs.push_back(Resource(BufferSp(new Int16Buffer(outputs))));
1724 spec.extensions.push_back("VK_KHR_8bit_storage");
1725 spec.extensions.push_back("VK_KHR_16bit_storage");
1726 spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1727 spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
1728 spec.requestedVulkanFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM;
1730 if (cTypes[tyIdx].componentsCount == 4)
1731 spec.verifyIO = checkUniformsArray<deInt8, deInt16, 4>;
1733 spec.verifyIO = checkUniformsArray<deInt8, deInt16, 1>;
1735 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
1740 void addCompute8bitStoragePushConstant8To16Group (tcu::TestCaseGroup* group)
1742 tcu::TestContext& testCtx = group->getTestContext();
1743 de::Random rnd (deStringHash(group->getName()));
1744 const int numElements = 64;
1746 const StringTemplate shaderTemplate (
1747 "OpCapability Shader\n"
1748 "OpCapability StorageUniform16\n"
1749 "OpCapability StoragePushConstant8\n"
1750 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1751 "OpExtension \"SPV_KHR_8bit_storage\"\n"
1752 "OpExtension \"SPV_KHR_16bit_storage\"\n"
1753 "OpMemoryModel Logical GLSL450\n"
1754 "OpEntryPoint GLCompute %main \"main\" %id\n"
1755 "OpExecutionMode %main LocalSize 1 1 1\n"
1756 "OpDecorate %id BuiltIn GlobalInvocationId\n"
1760 "OpDecorate %PC8 Block\n"
1761 "OpDecorate %SSBO16 Block\n"
1762 "OpMemberDecorate %PC8 0 Offset 0\n"
1763 "OpMemberDecorate %SSBO16 0 Offset 0\n"
1764 "OpDecorate %ssbo16 DescriptorSet 0\n"
1765 "OpDecorate %ssbo16 Binding 0\n"
1767 "${matrix_decor:opt}\n"
1769 "%bool = OpTypeBool\n"
1770 "%void = OpTypeVoid\n"
1771 "%voidf = OpTypeFunction %void\n"
1772 "%i32 = OpTypeInt 32 1\n"
1773 "%u32 = OpTypeInt 32 0\n"
1774 "%uvec3 = OpTypeVector %u32 3\n"
1775 "%uvec3ptr = OpTypePointer Input %uvec3\n"
1777 "%zero = OpConstant %i32 0\n"
1778 "%c_i32_1 = OpConstant %i32 1\n"
1779 "%c_i32_8 = OpConstant %i32 8\n"
1780 "%c_i32_16 = OpConstant %i32 16\n"
1781 "%c_i32_32 = OpConstant %i32 32\n"
1782 "%c_i32_64 = OpConstant %i32 64\n"
1785 "${matrix_types:opt}\n"
1787 "%PC8 = OpTypeStruct %${matrix_prefix:opt}${base8}arr\n"
1788 "%pp_PC8 = OpTypePointer PushConstant %PC8\n"
1789 "%pc8 = OpVariable %pp_PC8 PushConstant\n"
1790 "%SSBO16 = OpTypeStruct %${matrix_prefix:opt}${base16}arr\n"
1791 "%up_SSBO16 = OpTypePointer StorageBuffer %SSBO16\n"
1792 "%ssbo16 = OpVariable %up_SSBO16 StorageBuffer\n"
1794 "%id = OpVariable %uvec3ptr Input\n"
1796 "%main = OpFunction %void None %voidf\n"
1797 "%label = OpLabel\n"
1798 "%idval = OpLoad %uvec3 %id\n"
1799 "%x = OpCompositeExtract %u32 %idval 0\n"
1800 "%inloc = OpAccessChain %${base8}ptr %pc8 %zero %x ${index0:opt}\n"
1801 "%val8 = OpLoad %${base8} %inloc\n"
1802 "%val16 = ${convert} %${base16} %val8\n"
1803 "%outloc = OpAccessChain %${base16}ptr %ssbo16 %zero %x ${index0:opt}\n"
1804 " OpStore %outloc %val16\n"
1805 "${matrix_store:opt}\n"
1807 " OpFunctionEnd\n");
1810 const char sintTypes[] =
1811 "%i8 = OpTypeInt 8 1\n"
1812 "%i16 = OpTypeInt 16 1\n"
1813 "%i8ptr = OpTypePointer PushConstant %i8\n"
1814 "%i16ptr = OpTypePointer StorageBuffer %i16\n"
1815 "%i8arr = OpTypeArray %i8 %c_i32_64\n"
1816 "%i16arr = OpTypeArray %i16 %c_i32_64\n"
1817 "%v2i8 = OpTypeVector %i8 2\n"
1818 "%v2i16 = OpTypeVector %i16 2\n"
1819 "%v2i8ptr = OpTypePointer PushConstant %v2i8\n"
1820 "%v2i16ptr = OpTypePointer StorageBuffer %v2i16\n"
1821 "%v2i8arr = OpTypeArray %v2i8 %c_i32_32\n"
1822 "%v2i16arr = OpTypeArray %v2i16 %c_i32_32\n";
1824 const char uintTypes[] =
1825 "%u8 = OpTypeInt 8 0\n"
1826 "%u16 = OpTypeInt 16 0\n"
1827 "%u8ptr = OpTypePointer PushConstant %u8\n"
1828 "%u16ptr = OpTypePointer StorageBuffer %u16\n"
1829 "%u8arr = OpTypeArray %u8 %c_i32_64\n"
1830 "%u16arr = OpTypeArray %u16 %c_i32_64\n"
1831 "%v2u8 = OpTypeVector %u8 2\n"
1832 "%v2u16 = OpTypeVector %u16 2\n"
1833 "%v2u8ptr = OpTypePointer PushConstant %v2u8\n"
1834 "%v2u16ptr = OpTypePointer StorageBuffer %v2u16\n"
1835 "%v2u8arr = OpTypeArray %v2u8 %c_i32_32\n"
1836 "%v2u16arr = OpTypeArray %v2u16 %c_i32_32\n";
1838 struct CompositeType
1850 const CompositeType cTypes[] =
1852 {"scalar_sint", true, sintTypes, "i16", "i8", "OpSConvert", "OpDecorate %i16arr ArrayStride 2\nOpDecorate %i8arr ArrayStride 1\n", numElements},
1853 {"scalar_uint", false, uintTypes, "u16", "u8", "OpUConvert", "OpDecorate %u16arr ArrayStride 2\nOpDecorate %u8arr ArrayStride 1\n", numElements},
1854 {"vector_sint", true, sintTypes, "v2i16", "v2i8", "OpSConvert", "OpDecorate %v2i16arr ArrayStride 4\nOpDecorate %v2i8arr ArrayStride 2\n", numElements / 2},
1855 {"vector_uint", false, uintTypes, "v2u16", "v2u8", "OpUConvert", "OpDecorate %v2u16arr ArrayStride 4\nOpDecorate %v2u8arr ArrayStride 2\n", numElements / 2},
1858 vector<deInt8> inputs = getInt8s(rnd, numElements);
1859 vector<deInt16> sOutputs;
1860 vector<deInt16> uOutputs;
1861 const deUint8 signBitMask = 0x80;
1862 const deUint16 signExtendMask = 0xff00;
1864 sOutputs.reserve(inputs.size());
1865 uOutputs.reserve(inputs.size());
1867 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
1869 uOutputs.push_back(static_cast<deUint8>(inputs[numNdx]));
1870 if (inputs[numNdx] & signBitMask)
1871 sOutputs.push_back(static_cast<deInt16>(inputs[numNdx] | signExtendMask));
1873 sOutputs.push_back(static_cast<deInt16>(inputs[numNdx]));
1876 for (deUint32 tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1878 ComputeShaderSpec spec;
1879 map<string, string> specs;
1880 const char* testName = cTypes[tyIdx].name;
1882 specs["stride"] = cTypes[tyIdx].stride;
1883 specs["base16"] = cTypes[tyIdx].base16;
1884 specs["base8"] = cTypes[tyIdx].base8;
1885 specs["types"] = cTypes[tyIdx].types;
1886 specs["convert"] = cTypes[tyIdx].opcode;
1888 spec.assembly = shaderTemplate.specialize(specs);
1889 spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
1890 spec.pushConstants = BufferSp(new Int8Buffer(inputs));
1892 if (cTypes[tyIdx].isSigned)
1893 spec.outputs.push_back(BufferSp(new Int16Buffer(sOutputs)));
1895 spec.outputs.push_back(BufferSp(new Int16Buffer(uOutputs)));
1896 spec.extensions.push_back("VK_KHR_8bit_storage");
1897 spec.extensions.push_back("VK_KHR_16bit_storage");
1898 spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1899 spec.requestedVulkanFeatures.ext8BitStorage = EXT8BITSTORAGEFEATURES_PUSH_CONSTANT;
1900 spec.requestedVulkanFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM;
1902 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName, testName, spec));
1907 void addCompute8bitStorageBuffer8To8Group (tcu::TestCaseGroup* group)
1909 tcu::TestContext& testCtx = group->getTestContext();
1910 de::Random rnd (deStringHash(group->getName()));
1911 const int numElements = 128;
1912 const vector<deInt8> int8Data = getInt8s(rnd, numElements);
1913 const vector<deInt8> int8UnusedData (numElements, 0);
1914 ComputeShaderSpec spec;
1915 std::ostringstream shaderTemplate;
1916 shaderTemplate<<"OpCapability Shader\n"
1917 << "OpCapability StorageBuffer8BitAccess \n"
1918 << "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1919 << "OpExtension \"SPV_KHR_8bit_storage\"\n"
1920 << "OpMemoryModel Logical GLSL450\n"
1921 << "OpEntryPoint GLCompute %main \"main\" %id\n"
1922 << "OpExecutionMode %main LocalSize 1 1 1\n"
1923 << "OpDecorate %id BuiltIn GlobalInvocationId\n"
1924 << "OpDecorate %i8arr ArrayStride 1\n"
1925 << "OpDecorate %SSBO_IN Block\n"
1926 << "OpDecorate %SSBO_OUT Block\n"
1927 << "OpMemberDecorate %SSBO_IN 0 Coherent\n"
1928 << "OpMemberDecorate %SSBO_OUT 0 Coherent\n"
1929 << "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
1930 << "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
1931 << "OpDecorate %ssboIN DescriptorSet 0\n"
1932 << "OpDecorate %ssboOUT DescriptorSet 0\n"
1933 << "OpDecorate %ssboIN Binding 0\n"
1934 << "OpDecorate %ssboOUT Binding 1\n"
1936 << "%bool = OpTypeBool\n"
1937 << "%void = OpTypeVoid\n"
1938 << "%voidf = OpTypeFunction %void\n"
1939 << "%u32 = OpTypeInt 32 0\n"
1940 << "%i32 = OpTypeInt 32 1\n"
1941 << "%uvec3 = OpTypeVector %u32 3\n"
1942 << "%uvec3ptr = OpTypePointer Input %uvec3\n"
1943 << "%i8 = OpTypeInt 8 1\n"
1944 << "%i8ptr = OpTypePointer StorageBuffer %i8\n"
1946 << "%zero = OpConstant %i32 0\n"
1947 << "%c_size = OpConstant %i32 " << numElements << "\n"
1949 << "%i8arr = OpTypeArray %i8 %c_size\n"
1950 << "%SSBO_IN = OpTypeStruct %i8arr\n"
1951 << "%SSBO_OUT = OpTypeStruct %i8arr\n"
1952 << "%up_SSBOIN = OpTypePointer StorageBuffer %SSBO_IN\n"
1953 << "%up_SSBOOUT = OpTypePointer StorageBuffer %SSBO_OUT\n"
1954 << "%ssboIN = OpVariable %up_SSBOIN StorageBuffer\n"
1955 << "%ssboOUT = OpVariable %up_SSBOOUT StorageBuffer\n"
1957 << "%id = OpVariable %uvec3ptr Input\n"
1958 << "%main = OpFunction %void None %voidf\n"
1959 << "%label = OpLabel\n"
1960 << "%idval = OpLoad %uvec3 %id\n"
1961 << "%x = OpCompositeExtract %u32 %idval 0\n"
1962 << "%y = OpCompositeExtract %u32 %idval 1\n"
1964 << "%inlocx = OpAccessChain %i8ptr %ssboIN %zero %x \n"
1965 << "%valx = OpLoad %i8 %inlocx\n"
1966 << "%outlocx = OpAccessChain %i8ptr %ssboOUT %zero %x \n"
1967 << " OpStore %outlocx %valx\n"
1969 << "%inlocy = OpAccessChain %i8ptr %ssboIN %zero %y \n"
1970 << "%valy = OpLoad %i8 %inlocy\n"
1971 << "%outlocy = OpAccessChain %i8ptr %ssboOUT %zero %y \n"
1972 << " OpStore %outlocy %valy\n"
1975 << " OpFunctionEnd\n";
1977 spec.assembly = shaderTemplate.str();
1978 spec.numWorkGroups = IVec3(numElements, numElements, 1);
1979 spec.verifyIO = computeCheckBuffers;
1980 spec.coherentMemory = true;
1981 spec.inputs.push_back(BufferSp(new Int8Buffer(int8Data)));
1982 spec.outputs.push_back(BufferSp(new Int8Buffer(int8UnusedData)));
1983 spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1984 spec.extensions.push_back("VK_KHR_8bit_storage");
1985 spec.requestedVulkanFeatures.ext8BitStorage = EXT8BITSTORAGEFEATURES_STORAGE_BUFFER;
1987 group->addChild(new SpvAsmComputeShaderCase(testCtx, "stress_test", "Granularity stress test", spec));
1990 void addCompute8bitStorageUniform8StructTo32StructGroup (tcu::TestCaseGroup* group)
1992 tcu::TestContext& testCtx = group->getTestContext();
1993 de::Random rnd (deStringHash(group->getName()));
1994 const StringTemplate shaderTemplate (
1995 "OpCapability Shader\n"
1996 "OpCapability ${capability}\n"
1997 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1998 "OpExtension \"SPV_KHR_8bit_storage\"\n"
1999 "OpMemoryModel Logical GLSL450\n"
2000 "OpEntryPoint GLCompute %main \"main\" %id\n"
2001 "OpExecutionMode %main LocalSize 1 1 1\n"
2002 "OpDecorate %id BuiltIn GlobalInvocationId\n"
2008 "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
2009 "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
2010 "OpDecorate %SSBO_IN Block\n"
2011 "OpDecorate %SSBO_OUT Block\n"
2012 "OpDecorate %ssboIN DescriptorSet 0\n"
2013 "OpDecorate %ssboOUT DescriptorSet 0\n"
2014 "OpDecorate %ssboIN Binding 0\n"
2015 "OpDecorate %ssboOUT Binding 1\n"
2017 "%bool = OpTypeBool\n"
2018 "%void = OpTypeVoid\n"
2019 "%voidf = OpTypeFunction %void\n"
2020 "%u32 = OpTypeInt 32 0\n"
2021 "%uvec3 = OpTypeVector %u32 3\n"
2022 "%uvec3ptr = OpTypePointer Input %uvec3\n"
2024 "%i32 = OpTypeInt 32 1\n"
2025 "%v2i32 = OpTypeVector %i32 2\n"
2026 "%v3i32 = OpTypeVector %i32 3\n"
2027 "%v4i32 = OpTypeVector %i32 4\n"
2029 "%i8 = OpTypeInt 8 1\n"
2030 "%v2i8 = OpTypeVector %i8 2\n"
2031 "%v3i8 = OpTypeVector %i8 3\n"
2032 "%v4i8 = OpTypeVector %i8 4\n"
2033 "%i8ptr = OpTypePointer ${8Storage} %i8\n"
2034 "%v2i8ptr = OpTypePointer ${8Storage} %v2i8\n"
2035 "%v3i8ptr = OpTypePointer ${8Storage} %v3i8\n"
2036 "%v4i8ptr = OpTypePointer ${8Storage} %v4i8\n"
2038 "%i32ptr = OpTypePointer ${32Storage} %i32\n"
2039 "%v2i32ptr = OpTypePointer ${32Storage} %v2i32\n"
2040 "%v3i32ptr = OpTypePointer ${32Storage} %v3i32\n"
2041 "%v4i32ptr = OpTypePointer ${32Storage} %v4i32\n"
2043 "%zero = OpConstant %i32 0\n"
2044 "%c_i32_1 = OpConstant %i32 1\n"
2045 "%c_i32_2 = OpConstant %i32 2\n"
2046 "%c_i32_3 = OpConstant %i32 3\n"
2047 "%c_i32_4 = OpConstant %i32 4\n"
2048 "%c_i32_5 = OpConstant %i32 5\n"
2049 "%c_i32_6 = OpConstant %i32 6\n"
2050 "%c_i32_7 = OpConstant %i32 7\n"
2051 "%c_i32_8 = OpConstant %i32 8\n"
2052 "%c_i32_9 = OpConstant %i32 9\n"
2054 "%c_u32_1 = OpConstant %u32 1\n"
2055 "%c_u32_3 = OpConstant %u32 3\n"
2056 "%c_u32_7 = OpConstant %u32 7\n"
2057 "%c_u32_11 = OpConstant %u32 11\n"
2059 "%i8arr3 = OpTypeArray %i8 %c_u32_3\n"
2060 "%v2i8arr3 = OpTypeArray %v2i8 %c_u32_3\n"
2061 "%v2i8arr11 = OpTypeArray %v2i8 %c_u32_11\n"
2062 "%v3i8arr11 = OpTypeArray %v3i8 %c_u32_11\n"
2063 "%v4i8arr3 = OpTypeArray %v4i8 %c_u32_3\n"
2064 "%struct8 = OpTypeStruct %i8 %v2i8arr3\n"
2065 "%struct8arr11 = OpTypeArray %struct8 %c_u32_11\n"
2066 "%i8Struct = OpTypeStruct %i8 %v2i8 %v3i8 %v4i8 %i8arr3 %struct8arr11 %v2i8arr11 %i8 %v3i8arr11 %v4i8arr3\n"
2068 "%i32arr3 = OpTypeArray %i32 %c_u32_3\n"
2069 "%v2i32arr3 = OpTypeArray %v2i32 %c_u32_3\n"
2070 "%v2i32arr11 = OpTypeArray %v2i32 %c_u32_11\n"
2071 "%v3i32arr11 = OpTypeArray %v3i32 %c_u32_11\n"
2072 "%v4i32arr3 = OpTypeArray %v4i32 %c_u32_3\n"
2073 "%struct32 = OpTypeStruct %i32 %v2i32arr3\n"
2074 "%struct32arr11 = OpTypeArray %struct32 %c_u32_11\n"
2075 "%i32Struct = OpTypeStruct %i32 %v2i32 %v3i32 %v4i32 %i32arr3 %struct32arr11 %v2i32arr11 %i32 %v3i32arr11 %v4i32arr3\n"
2077 "%i8StructArr7 = OpTypeArray %i8Struct %c_u32_7\n"
2078 "%i32StructArr7 = OpTypeArray %i32Struct %c_u32_7\n"
2079 "%SSBO_IN = OpTypeStruct %i8StructArr7\n"
2080 "%SSBO_OUT = OpTypeStruct %i32StructArr7\n"
2081 "%up_SSBOIN = OpTypePointer Uniform %SSBO_IN\n"
2082 "%up_SSBOOUT = OpTypePointer StorageBuffer %SSBO_OUT\n"
2083 "%ssboIN = OpVariable %up_SSBOIN Uniform\n"
2084 "%ssboOUT = OpVariable %up_SSBOOUT StorageBuffer\n"
2086 "%id = OpVariable %uvec3ptr Input\n"
2087 "%main = OpFunction %void None %voidf\n"
2088 "%label = OpLabel\n"
2090 "%idval = OpLoad %uvec3 %id\n"
2091 "%x = OpCompositeExtract %u32 %idval 0\n"
2092 "%y = OpCompositeExtract %u32 %idval 1\n"
2094 "%i8src = OpAccessChain %i8ptr %ssboIN %zero %x %zero\n"
2095 "%val_i8 = OpLoad %i8 %i8src\n"
2096 "%val_i32 = OpSConvert %i32 %val_i8\n"
2097 "%i32dst = OpAccessChain %i32ptr %ssboOUT %zero %x %zero\n"
2098 "OpStore %i32dst %val_i32\n"
2100 "%v2i8src = OpAccessChain %v2i8ptr %ssboIN %zero %x %c_i32_1\n"
2101 "%val_v2i8 = OpLoad %v2i8 %v2i8src\n"
2102 "%val_v2i32 = OpSConvert %v2i32 %val_v2i8\n"
2103 "%v2i32dst = OpAccessChain %v2i32ptr %ssboOUT %zero %x %c_i32_1\n"
2104 "OpStore %v2i32dst %val_v2i32\n"
2106 "%v3i8src = OpAccessChain %v3i8ptr %ssboIN %zero %x %c_i32_2\n"
2107 "%val_v3i8 = OpLoad %v3i8 %v3i8src\n"
2108 "%val_v3i32 = OpSConvert %v3i32 %val_v3i8\n"
2109 "%v3i32dst = OpAccessChain %v3i32ptr %ssboOUT %zero %x %c_i32_2\n"
2110 "OpStore %v3i32dst %val_v3i32\n"
2112 "%v4i8src = OpAccessChain %v4i8ptr %ssboIN %zero %x %c_i32_3\n"
2113 "%val_v4i8 = OpLoad %v4i8 %v4i8src\n"
2114 "%val_v4i32 = OpSConvert %v4i32 %val_v4i8\n"
2115 "%v4i32dst = OpAccessChain %v4i32ptr %ssboOUT %zero %x %c_i32_3\n"
2116 "OpStore %v4i32dst %val_v4i32\n"
2118 //struct {i8, v2i8[3]}
2119 "%Si8src = OpAccessChain %i8ptr %ssboIN %zero %x %c_i32_5 %y %zero\n"
2120 "%Sval_i8 = OpLoad %i8 %Si8src\n"
2121 "%Sval_i32 = OpSConvert %i32 %Sval_i8\n"
2122 "%Si32dst2 = OpAccessChain %i32ptr %ssboOUT %zero %x %c_i32_5 %y %zero\n"
2123 "OpStore %Si32dst2 %Sval_i32\n"
2125 "%Sv2i8src0 = OpAccessChain %v2i8ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %zero\n"
2126 "%Sv2i8_0 = OpLoad %v2i8 %Sv2i8src0\n"
2127 "%Sv2i32_0 = OpSConvert %v2i32 %Sv2i8_0\n"
2128 "%Sv2i32dst_0 = OpAccessChain %v2i32ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %zero\n"
2129 "OpStore %Sv2i32dst_0 %Sv2i32_0\n"
2131 "%Sv2i8src1 = OpAccessChain %v2i8ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %c_i32_1\n"
2132 "%Sv2i8_1 = OpLoad %v2i8 %Sv2i8src1\n"
2133 "%Sv2i32_1 = OpSConvert %v2i32 %Sv2i8_1\n"
2134 "%Sv2i32dst_1 = OpAccessChain %v2i32ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %c_i32_1\n"
2135 "OpStore %Sv2i32dst_1 %Sv2i32_1\n"
2137 "%Sv2i8src2 = OpAccessChain %v2i8ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %c_i32_2\n"
2138 "%Sv2i8_2 = OpLoad %v2i8 %Sv2i8src2\n"
2139 "%Sv2i32_2 = OpSConvert %v2i32 %Sv2i8_2\n"
2140 "%Sv2i32dst_2 = OpAccessChain %v2i32ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %c_i32_2\n"
2141 "OpStore %Sv2i32dst_2 %Sv2i32_2\n"
2143 "%v2i8src2 = OpAccessChain %v2i8ptr %ssboIN %zero %x %c_i32_6 %y\n"
2144 "%val2_v2i8 = OpLoad %v2i8 %v2i8src2\n"
2145 "%val2_v2i32 = OpSConvert %v2i32 %val2_v2i8\n"
2146 "%v2i32dst2 = OpAccessChain %v2i32ptr %ssboOUT %zero %x %c_i32_6 %y\n"
2147 "OpStore %v2i32dst2 %val2_v2i32\n"
2149 "%i8src2 = OpAccessChain %i8ptr %ssboIN %zero %x %c_i32_7\n"
2150 "%val2_i8 = OpLoad %i8 %i8src2\n"
2151 "%val2_i32 = OpSConvert %i32 %val2_i8\n"
2152 "%i32dst2 = OpAccessChain %i32ptr %ssboOUT %zero %x %c_i32_7\n"
2153 "OpStore %i32dst2 %val2_i32\n"
2155 "%v3i8src2 = OpAccessChain %v3i8ptr %ssboIN %zero %x %c_i32_8 %y\n"
2156 "%val2_v3i8 = OpLoad %v3i8 %v3i8src2\n"
2157 "%val2_v3i32 = OpSConvert %v3i32 %val2_v3i8\n"
2158 "%v3i32dst2 = OpAccessChain %v3i32ptr %ssboOUT %zero %x %c_i32_8 %y\n"
2159 "OpStore %v3i32dst2 %val2_v3i32\n"
2161 //Array with 3 elements
2162 "%LessThan3 = OpSLessThan %bool %y %c_i32_3\n"
2163 "OpSelectionMerge %BlockIf None\n"
2164 "OpBranchConditional %LessThan3 %LabelIf %BlockIf\n"
2165 "%LabelIf = OpLabel\n"
2166 " %i8src3 = OpAccessChain %i8ptr %ssboIN %zero %x %c_i32_4 %y\n"
2167 " %val3_i8 = OpLoad %i8 %i8src3\n"
2168 " %val3_i32 = OpSConvert %i32 %val3_i8\n"
2169 " %i32dst3 = OpAccessChain %i32ptr %ssboOUT %zero %x %c_i32_4 %y\n"
2170 " OpStore %i32dst3 %val3_i32\n"
2172 " %v4i8src2 = OpAccessChain %v4i8ptr %ssboIN %zero %x %c_i32_9 %y\n"
2173 " %val2_v4i8 = OpLoad %v4i8 %v4i8src2\n"
2174 " %val2_v4i32 = OpSConvert %v4i32 %val2_v4i8\n"
2175 " %v4i32dst2 = OpAccessChain %v4i32ptr %ssboOUT %zero %x %c_i32_9 %y\n"
2176 " OpStore %v4i32dst2 %val2_v4i32\n"
2177 "OpBranch %BlockIf\n"
2178 "%BlockIf = OpLabel\n"
2181 " OpFunctionEnd\n");
2184 vector<deInt32> int32Data = data32bit(SHADERTEMPLATE_STRIDE32BIT_STD430, rnd, false);
2186 vector<deInt8> in8DData = data8bit(SHADERTEMPLATE_STRIDE8BIT_STD140, rnd);
2187 ComputeShaderSpec spec;
2188 map<string, string> specs;
2189 string testName = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
2191 specs["capability"] = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
2192 specs["stridei8"] = getStructShaderComponet(SHADERTEMPLATE_STRIDE8BIT_STD140);
2193 specs["stridei32"] = getStructShaderComponet(SHADERTEMPLATE_STRIDE32BIT_STD430);
2194 specs["32Storage"] = "StorageBuffer";
2195 specs["8Storage"] = "Uniform";
2197 spec.assembly = shaderTemplate.specialize(specs);
2198 spec.numWorkGroups = IVec3(structData.structArraySize, structData.nestedArraySize, 1);
2199 spec.verifyIO = checkStruct<deInt8, deInt32, SHADERTEMPLATE_STRIDE8BIT_STD140, SHADERTEMPLATE_STRIDE32BIT_STD430>;
2200 spec.inputs.push_back(Resource(BufferSp(new Int8Buffer(in8DData)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
2201 spec.outputs.push_back(Resource(BufferSp(new Int32Buffer(int32Data))));
2202 spec.extensions.push_back("VK_KHR_8bit_storage");
2203 spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
2205 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
2209 void addCompute8bitStorageUniform32StructTo8StructGroup (tcu::TestCaseGroup* group)
2211 tcu::TestContext& testCtx = group->getTestContext();
2212 de::Random rnd (deStringHash(group->getName()));
2214 const StringTemplate shaderTemplate (
2215 "OpCapability Shader\n"
2216 "OpCapability ${capability}\n"
2217 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
2218 "OpExtension \"SPV_KHR_8bit_storage\"\n"
2219 "OpMemoryModel Logical GLSL450\n"
2220 "OpEntryPoint GLCompute %main \"main\" %id\n"
2221 "OpExecutionMode %main LocalSize 1 1 1\n"
2222 "OpDecorate %id BuiltIn GlobalInvocationId\n"
2228 "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
2229 "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
2230 "OpDecorate %SSBO_IN Block\n"
2231 "OpDecorate %SSBO_OUT Block\n"
2232 "OpDecorate %ssboIN DescriptorSet 0\n"
2233 "OpDecorate %ssboOUT DescriptorSet 0\n"
2234 "OpDecorate %ssboIN Binding 0\n"
2235 "OpDecorate %ssboOUT Binding 1\n"
2237 "%bool = OpTypeBool\n"
2238 "%void = OpTypeVoid\n"
2239 "%voidf = OpTypeFunction %void\n"
2240 "%u32 = OpTypeInt 32 0\n"
2241 "%uvec3 = OpTypeVector %u32 3\n"
2242 "%uvec3ptr = OpTypePointer Input %uvec3\n"
2244 "%i32 = OpTypeInt 32 1\n"
2245 "%v2i32 = OpTypeVector %i32 2\n"
2246 "%v3i32 = OpTypeVector %i32 3\n"
2247 "%v4i32 = OpTypeVector %i32 4\n"
2249 "%i8 = OpTypeInt 8 1\n"
2250 "%v2i8 = OpTypeVector %i8 2\n"
2251 "%v3i8 = OpTypeVector %i8 3\n"
2252 "%v4i8 = OpTypeVector %i8 4\n"
2253 "%i8ptr = OpTypePointer ${8Storage} %i8\n"
2254 "%v2i8ptr = OpTypePointer ${8Storage} %v2i8\n"
2255 "%v3i8ptr = OpTypePointer ${8Storage} %v3i8\n"
2256 "%v4i8ptr = OpTypePointer ${8Storage} %v4i8\n"
2258 "%i32ptr = OpTypePointer ${32Storage} %i32\n"
2259 "%v2i32ptr = OpTypePointer ${32Storage} %v2i32\n"
2260 "%v3i32ptr = OpTypePointer ${32Storage} %v3i32\n"
2261 "%v4i32ptr = OpTypePointer ${32Storage} %v4i32\n"
2263 "%zero = OpConstant %i32 0\n"
2264 "%c_i32_1 = OpConstant %i32 1\n"
2265 "%c_i32_2 = OpConstant %i32 2\n"
2266 "%c_i32_3 = OpConstant %i32 3\n"
2267 "%c_i32_4 = OpConstant %i32 4\n"
2268 "%c_i32_5 = OpConstant %i32 5\n"
2269 "%c_i32_6 = OpConstant %i32 6\n"
2270 "%c_i32_7 = OpConstant %i32 7\n"
2271 "%c_i32_8 = OpConstant %i32 8\n"
2272 "%c_i32_9 = OpConstant %i32 9\n"
2274 "%c_u32_1 = OpConstant %u32 1\n"
2275 "%c_u32_3 = OpConstant %u32 3\n"
2276 "%c_u32_7 = OpConstant %u32 7\n"
2277 "%c_u32_11 = OpConstant %u32 11\n"
2279 "%i8arr3 = OpTypeArray %i8 %c_u32_3\n"
2280 "%v2i8arr3 = OpTypeArray %v2i8 %c_u32_3\n"
2281 "%v2i8arr11 = OpTypeArray %v2i8 %c_u32_11\n"
2282 "%v3i8arr11 = OpTypeArray %v3i8 %c_u32_11\n"
2283 "%v4i8arr3 = OpTypeArray %v4i8 %c_u32_3\n"
2284 "%struct8 = OpTypeStruct %i8 %v2i8arr3\n"
2285 "%struct8arr11 = OpTypeArray %struct8 %c_u32_11\n"
2286 "%i8Struct = OpTypeStruct %i8 %v2i8 %v3i8 %v4i8 %i8arr3 %struct8arr11 %v2i8arr11 %i8 %v3i8arr11 %v4i8arr3\n"
2288 "%i32arr3 = OpTypeArray %i32 %c_u32_3\n"
2289 "%v2i32arr3 = OpTypeArray %v2i32 %c_u32_3\n"
2290 "%v2i32arr11 = OpTypeArray %v2i32 %c_u32_11\n"
2291 "%v3i32arr11 = OpTypeArray %v3i32 %c_u32_11\n"
2292 "%v4i32arr3 = OpTypeArray %v4i32 %c_u32_3\n"
2293 "%struct32 = OpTypeStruct %i32 %v2i32arr3\n"
2294 "%struct32arr11 = OpTypeArray %struct32 %c_u32_11\n"
2295 "%i32Struct = OpTypeStruct %i32 %v2i32 %v3i32 %v4i32 %i32arr3 %struct32arr11 %v2i32arr11 %i32 %v3i32arr11 %v4i32arr3\n"
2297 "%i8StructArr7 = OpTypeArray %i8Struct %c_u32_7\n"
2298 "%i32StructArr7 = OpTypeArray %i32Struct %c_u32_7\n"
2299 "%SSBO_IN = OpTypeStruct %i32StructArr7\n"
2300 "%SSBO_OUT = OpTypeStruct %i8StructArr7\n"
2301 "%up_SSBOIN = OpTypePointer Uniform %SSBO_IN\n"
2302 "%up_SSBOOUT = OpTypePointer ${storage} %SSBO_OUT\n"
2303 "%ssboIN = OpVariable %up_SSBOIN Uniform\n"
2304 "%ssboOUT = OpVariable %up_SSBOOUT ${storage}\n"
2306 "%id = OpVariable %uvec3ptr Input\n"
2307 "%main = OpFunction %void None %voidf\n"
2308 "%label = OpLabel\n"
2310 "%idval = OpLoad %uvec3 %id\n"
2311 "%x = OpCompositeExtract %u32 %idval 0\n"
2312 "%y = OpCompositeExtract %u32 %idval 1\n"
2314 "%i32src = OpAccessChain %i32ptr %ssboIN %zero %x %zero\n"
2315 "%val_i32 = OpLoad %i32 %i32src\n"
2316 "%val_i8 = OpSConvert %i8 %val_i32\n"
2317 "%i8dst = OpAccessChain %i8ptr %ssboOUT %zero %x %zero\n"
2318 "OpStore %i8dst %val_i8\n"
2320 "%v2i32src = OpAccessChain %v2i32ptr %ssboIN %zero %x %c_i32_1\n"
2321 "%val_v2i32 = OpLoad %v2i32 %v2i32src\n"
2322 "%val_v2i8 = OpSConvert %v2i8 %val_v2i32\n"
2323 "%v2i8dst = OpAccessChain %v2i8ptr %ssboOUT %zero %x %c_i32_1\n"
2324 "OpStore %v2i8dst %val_v2i8\n"
2326 "%v3i32src = OpAccessChain %v3i32ptr %ssboIN %zero %x %c_i32_2\n"
2327 "%val_v3i32 = OpLoad %v3i32 %v3i32src\n"
2328 "%val_v3i8 = OpSConvert %v3i8 %val_v3i32\n"
2329 "%v3i8dst = OpAccessChain %v3i8ptr %ssboOUT %zero %x %c_i32_2\n"
2330 "OpStore %v3i8dst %val_v3i8\n"
2332 "%v4i32src = OpAccessChain %v4i32ptr %ssboIN %zero %x %c_i32_3\n"
2333 "%val_v4i32 = OpLoad %v4i32 %v4i32src\n"
2334 "%val_v4i8 = OpSConvert %v4i8 %val_v4i32\n"
2335 "%v4i8dst = OpAccessChain %v4i8ptr %ssboOUT %zero %x %c_i32_3\n"
2336 "OpStore %v4i8dst %val_v4i8\n"
2339 //struct {i8, v2i8[3]}
2340 "%Si32src = OpAccessChain %i32ptr %ssboIN %zero %x %c_i32_5 %y %zero\n"
2341 "%Sval_i32 = OpLoad %i32 %Si32src\n"
2342 "%Sval_i8 = OpSConvert %i8 %Sval_i32\n"
2343 "%Si8dst2 = OpAccessChain %i8ptr %ssboOUT %zero %x %c_i32_5 %y %zero\n"
2344 "OpStore %Si8dst2 %Sval_i8\n"
2346 "%Sv2i32src0 = OpAccessChain %v2i32ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %zero\n"
2347 "%Sv2i32_0 = OpLoad %v2i32 %Sv2i32src0\n"
2348 "%Sv2i8_0 = OpSConvert %v2i8 %Sv2i32_0\n"
2349 "%Sv2i8dst_0 = OpAccessChain %v2i8ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %zero\n"
2350 "OpStore %Sv2i8dst_0 %Sv2i8_0\n"
2352 "%Sv2i32src1 = OpAccessChain %v2i32ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %c_i32_1\n"
2353 "%Sv2i32_1 = OpLoad %v2i32 %Sv2i32src1\n"
2354 "%Sv2i8_1 = OpSConvert %v2i8 %Sv2i32_1\n"
2355 "%Sv2i8dst_1 = OpAccessChain %v2i8ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %c_i32_1\n"
2356 "OpStore %Sv2i8dst_1 %Sv2i8_1\n"
2358 "%Sv2i32src2 = OpAccessChain %v2i32ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %c_i32_2\n"
2359 "%Sv2i32_2 = OpLoad %v2i32 %Sv2i32src2\n"
2360 "%Sv2i8_2 = OpSConvert %v2i8 %Sv2i32_2\n"
2361 "%Sv2i8dst_2 = OpAccessChain %v2i8ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %c_i32_2\n"
2362 "OpStore %Sv2i8dst_2 %Sv2i8_2\n"
2365 "%v2i32src2 = OpAccessChain %v2i32ptr %ssboIN %zero %x %c_i32_6 %y\n"
2366 "%val2_v2i32 = OpLoad %v2i32 %v2i32src2\n"
2367 "%val2_v2i8 = OpSConvert %v2i8 %val2_v2i32\n"
2368 "%v2i8dst2 = OpAccessChain %v2i8ptr %ssboOUT %zero %x %c_i32_6 %y\n"
2369 "OpStore %v2i8dst2 %val2_v2i8\n"
2371 "%i32src2 = OpAccessChain %i32ptr %ssboIN %zero %x %c_i32_7\n"
2372 "%val2_i32 = OpLoad %i32 %i32src2\n"
2373 "%val2_i8 = OpSConvert %i8 %val2_i32\n"
2374 "%i8dst2 = OpAccessChain %i8ptr %ssboOUT %zero %x %c_i32_7\n"
2375 "OpStore %i8dst2 %val2_i8\n"
2377 "%v3i32src2 = OpAccessChain %v3i32ptr %ssboIN %zero %x %c_i32_8 %y\n"
2378 "%val2_v3i32 = OpLoad %v3i32 %v3i32src2\n"
2379 "%val2_v3i8 = OpSConvert %v3i8 %val2_v3i32\n"
2380 "%v3i8dst2 = OpAccessChain %v3i8ptr %ssboOUT %zero %x %c_i32_8 %y\n"
2381 "OpStore %v3i8dst2 %val2_v3i8\n"
2384 //Array with 3 elements
2385 "%LessThan3 = OpSLessThan %bool %y %c_i32_3\n"
2386 "OpSelectionMerge %BlockIf None\n"
2387 "OpBranchConditional %LessThan3 %LabelIf %BlockIf\n"
2388 " %LabelIf = OpLabel\n"
2389 " %i32src3 = OpAccessChain %i32ptr %ssboIN %zero %x %c_i32_4 %y\n"
2390 " %val3_i32 = OpLoad %i32 %i32src3\n"
2391 " %val3_i8 = OpSConvert %i8 %val3_i32\n"
2392 " %i8dst3 = OpAccessChain %i8ptr %ssboOUT %zero %x %c_i32_4 %y\n"
2393 " OpStore %i8dst3 %val3_i8\n"
2395 " %v4i32src2 = OpAccessChain %v4i32ptr %ssboIN %zero %x %c_i32_9 %y\n"
2396 " %val2_v4i32 = OpLoad %v4i32 %v4i32src2\n"
2397 " %val2_v4i8 = OpSConvert %v4i8 %val2_v4i32\n"
2398 " %v4i8dst2 = OpAccessChain %v4i8ptr %ssboOUT %zero %x %c_i32_9 %y\n"
2399 " OpStore %v4i8dst2 %val2_v4i8\n"
2400 "OpBranch %BlockIf\n"
2401 "%BlockIf = OpLabel\n"
2404 " OpFunctionEnd\n");
2407 vector<deInt8> int8Data = data8bit(SHADERTEMPLATE_STRIDE8BIT_STD430, rnd, false);
2409 ComputeShaderSpec spec;
2410 map<string, string> specs;
2411 string testName = string(CAPABILITIES[STORAGE_BUFFER_TEST].name);
2412 vector<deInt32> int32DData = data32bit(SHADERTEMPLATE_STRIDE32BIT_STD140, rnd);
2414 specs["capability"] = CAPABILITIES[STORAGE_BUFFER_TEST].cap;
2415 specs["storage"] = CAPABILITIES[STORAGE_BUFFER_TEST].decor;
2416 specs["stridei8"] = getStructShaderComponet(SHADERTEMPLATE_STRIDE8BIT_STD430);
2417 specs["stridei32"] = getStructShaderComponet(SHADERTEMPLATE_STRIDE32BIT_STD140);
2418 specs["8Storage"] = "StorageBuffer";
2419 specs["32Storage"] = "Uniform";
2421 spec.assembly = shaderTemplate.specialize(specs);
2422 spec.numWorkGroups = IVec3(structData.structArraySize, structData.nestedArraySize, 1);
2423 spec.verifyIO = checkStruct<deInt32, deInt8, SHADERTEMPLATE_STRIDE32BIT_STD140, SHADERTEMPLATE_STRIDE8BIT_STD430>;
2425 spec.inputs.push_back(Resource(BufferSp(new Int32Buffer(int32DData)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
2426 spec.outputs.push_back(Resource(BufferSp(new Int8Buffer(int8Data))));
2427 spec.extensions.push_back("VK_KHR_8bit_storage");
2428 spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
2429 spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[STORAGE_BUFFER_TEST].name);
2431 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
2435 void addCompute8bitStorage8bitStructMixedTypesGroup (tcu::TestCaseGroup* group)
2437 tcu::TestContext& testCtx = group->getTestContext();
2438 de::Random rnd (deStringHash(group->getName()));
2439 vector<deInt8> outData = data8bit(SHADERTEMPLATE_STRIDEMIX_STD430, rnd, false);
2441 const StringTemplate shaderTemplate (
2442 "OpCapability Shader\n"
2443 "OpCapability StorageBuffer8BitAccess\n"
2445 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
2446 "OpExtension \"SPV_KHR_8bit_storage\"\n"
2447 "OpMemoryModel Logical GLSL450\n"
2448 "OpEntryPoint GLCompute %main \"main\" %id\n"
2449 "OpExecutionMode %main LocalSize 1 1 1\n"
2450 "OpDecorate %id BuiltIn GlobalInvocationId\n"
2454 "OpDecorate %SSBO_IN Block\n"
2455 "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
2456 "OpDecorate %ssboIN DescriptorSet 0\n"
2457 "OpDecorate %ssboIN Binding 0\n"
2459 "OpDecorate %SSBO_OUT Block\n"
2460 "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
2461 "OpDecorate %ssboOUT DescriptorSet 0\n"
2462 "OpDecorate %ssboOUT Binding 1\n"
2464 "%void = OpTypeVoid\n"
2465 "%bool = OpTypeBool\n"
2466 "%i8 = OpTypeInt 8 1\n"
2467 "%v2i8 = OpTypeVector %i8 2\n"
2468 "%v3i8 = OpTypeVector %i8 3\n"
2469 "%v4i8 = OpTypeVector %i8 4\n"
2470 "%i32 = OpTypeInt 32 1\n"
2471 "%v2i32 = OpTypeVector %i32 2\n"
2472 "%v3i32 = OpTypeVector %i32 3\n"
2473 "%v4i32 = OpTypeVector %i32 4\n"
2474 "%u32 = OpTypeInt 32 0\n"
2475 "%uvec3 = OpTypeVector %u32 3\n"
2476 "%f32 = OpTypeFloat 32\n"
2477 "%v4f32 = OpTypeVector %f32 4\n"
2478 "%voidf = OpTypeFunction %void\n"
2480 "%zero = OpConstant %i32 0\n"
2481 "%c_i32_1 = OpConstant %i32 1\n"
2482 "%c_i32_2 = OpConstant %i32 2\n"
2483 "%c_i32_3 = OpConstant %i32 3\n"
2484 "%c_i32_4 = OpConstant %i32 4\n"
2485 "%c_i32_5 = OpConstant %i32 5\n"
2486 "%c_i32_6 = OpConstant %i32 6\n"
2487 "%c_i32_7 = OpConstant %i32 7\n"
2488 "%c_i32_8 = OpConstant %i32 8\n"
2489 "%c_i32_9 = OpConstant %i32 9\n"
2490 "%c_i32_10 = OpConstant %i32 10\n"
2491 "%c_i32_11 = OpConstant %i32 11\n"
2492 "%c_u32_1 = OpConstant %u32 1\n"
2493 "%c_u32_7 = OpConstant %u32 7\n"
2494 "%c_u32_11 = OpConstant %u32 11\n"
2495 "\n"//Arrays & Structs
2496 "%v2b8NestedArr11In = OpTypeArray %v2i8 %c_u32_11\n"
2497 "%b32NestedArr11In = OpTypeArray %i32 %c_u32_11\n"
2498 "%sb8Arr11In = OpTypeArray %i8 %c_u32_11\n"
2499 "%sb32Arr11In = OpTypeArray %i32 %c_u32_11\n"
2500 "%sNestedIn = OpTypeStruct %i8 %i32 %v2b8NestedArr11In %b32NestedArr11In\n"
2501 "%sNestedArr11In = OpTypeArray %sNestedIn %c_u32_11\n"
2502 "%structIn = OpTypeStruct %i8 %i32 %v2i8 %v2i32 %v3i8 %v3i32 %v4i8 %v4i32 %sNestedArr11In %sb8Arr11In %sb32Arr11In\n"
2503 "%structArr7In = OpTypeArray %structIn %c_u32_7\n"
2504 "%v2b8NestedArr11Out = OpTypeArray %v2i8 %c_u32_11\n"
2505 "%b32NestedArr11Out = OpTypeArray %i32 %c_u32_11\n"
2506 "%sb8Arr11Out = OpTypeArray %i8 %c_u32_11\n"
2507 "%sb32Arr11Out = OpTypeArray %i32 %c_u32_11\n"
2508 "%sNestedOut = OpTypeStruct %i8 %i32 %v2b8NestedArr11Out %b32NestedArr11Out\n"
2509 "%sNestedArr11Out = OpTypeArray %sNestedOut %c_u32_11\n"
2510 "%structOut = OpTypeStruct %i8 %i32 %v2i8 %v2i32 %v3i8 %v3i32 %v4i8 %v4i32 %sNestedArr11Out %sb8Arr11Out %sb32Arr11Out\n"
2511 "%structArr7Out = OpTypeArray %structOut %c_u32_7\n"
2514 "%i8outPtr = OpTypePointer StorageBuffer %i8\n"
2515 "%v2i8outPtr = OpTypePointer StorageBuffer %v2i8\n"
2516 "%v3i8outPtr = OpTypePointer StorageBuffer %v3i8\n"
2517 "%v4i8outPtr = OpTypePointer StorageBuffer %v4i8\n"
2518 "%i32outPtr = OpTypePointer StorageBuffer %i32\n"
2519 "%v2i32outPtr = OpTypePointer StorageBuffer %v2i32\n"
2520 "%v3i32outPtr = OpTypePointer StorageBuffer %v3i32\n"
2521 "%v4i32outPtr = OpTypePointer StorageBuffer %v4i32\n"
2522 "%fp_i32 = OpTypePointer Function %i32\n"
2523 "%uvec3ptr = OpTypePointer Input %uvec3\n"
2525 "%SSBO_IN = OpTypeStruct %structArr7In\n"
2526 "%up_SSBOIN = OpTypePointer ${inStorage} %SSBO_IN\n"
2527 "%ssboIN = OpVariable %up_SSBOIN ${inStorage}\n"
2529 "%SSBO_OUT = OpTypeStruct %structArr7Out\n"
2530 "%up_SSBOOUT = OpTypePointer StorageBuffer %SSBO_OUT\n"
2531 "%ssboOUT = OpVariable %up_SSBOOUT StorageBuffer\n"
2533 "%id = OpVariable %uvec3ptr Input\n"
2534 "%main = OpFunction %void None %voidf\n"
2535 "%label = OpLabel\n"
2536 "%ndxArrz = OpVariable %fp_i32 Function\n"
2537 "%idval = OpLoad %uvec3 %id\n"
2538 "%x = OpCompositeExtract %u32 %idval 0\n"
2539 "%y = OpCompositeExtract %u32 %idval 1\n"
2540 "\n"//strutOut.b8 = strutIn.b8
2541 "%inP1 = OpAccessChain %i8${inPtr} %ssboIN %zero %x %zero\n"
2542 "%inV1 = OpLoad %i8 %inP1\n"
2543 "%outP1 = OpAccessChain %i8outPtr %ssboOUT %zero %x %zero\n"
2544 "OpStore %outP1 %inV1\n"
2545 "\n"//strutOut.b32 = strutIn.b32
2546 "%inP2 = OpAccessChain %i32${inPtr} %ssboIN %zero %x %c_i32_1\n"
2547 "%inV2 = OpLoad %i32 %inP2\n"
2548 "%outP2 = OpAccessChain %i32outPtr %ssboOUT %zero %x %c_i32_1\n"
2549 "OpStore %outP2 %inV2\n"
2550 "\n"//strutOut.v2b8 = strutIn.v2b8
2551 "%inP3 = OpAccessChain %v2i8${inPtr} %ssboIN %zero %x %c_i32_2\n"
2552 "%inV3 = OpLoad %v2i8 %inP3\n"
2553 "%outP3 = OpAccessChain %v2i8outPtr %ssboOUT %zero %x %c_i32_2\n"
2554 "OpStore %outP3 %inV3\n"
2555 "\n"//strutOut.v2b32 = strutIn.v2b32
2556 "%inP4 = OpAccessChain %v2i32${inPtr} %ssboIN %zero %x %c_i32_3\n"
2557 "%inV4 = OpLoad %v2i32 %inP4\n"
2558 "%outP4 = OpAccessChain %v2i32outPtr %ssboOUT %zero %x %c_i32_3\n"
2559 "OpStore %outP4 %inV4\n"
2560 "\n"//strutOut.v3b8 = strutIn.v3b8
2561 "%inP5 = OpAccessChain %v3i8${inPtr} %ssboIN %zero %x %c_i32_4\n"
2562 "%inV5 = OpLoad %v3i8 %inP5\n"
2563 "%outP5 = OpAccessChain %v3i8outPtr %ssboOUT %zero %x %c_i32_4\n"
2564 "OpStore %outP5 %inV5\n"
2565 "\n"//strutOut.v3b32 = strutIn.v3b32
2566 "%inP6 = OpAccessChain %v3i32${inPtr} %ssboIN %zero %x %c_i32_5\n"
2567 "%inV6 = OpLoad %v3i32 %inP6\n"
2568 "%outP6 = OpAccessChain %v3i32outPtr %ssboOUT %zero %x %c_i32_5\n"
2569 "OpStore %outP6 %inV6\n"
2570 "\n"//strutOut.v4b8 = strutIn.v4b8
2571 "%inP7 = OpAccessChain %v4i8${inPtr} %ssboIN %zero %x %c_i32_6\n"
2572 "%inV7 = OpLoad %v4i8 %inP7\n"
2573 "%outP7 = OpAccessChain %v4i8outPtr %ssboOUT %zero %x %c_i32_6\n"
2574 "OpStore %outP7 %inV7\n"
2575 "\n"//strutOut.v4b32 = strutIn.v4b32
2576 "%inP8 = OpAccessChain %v4i32${inPtr} %ssboIN %zero %x %c_i32_7\n"
2577 "%inV8 = OpLoad %v4i32 %inP8\n"
2578 "%outP8 = OpAccessChain %v4i32outPtr %ssboOUT %zero %x %c_i32_7\n"
2579 "OpStore %outP8 %inV8\n"
2580 "\n"//strutOut.b8[y] = strutIn.b8[y]
2581 "%inP9 = OpAccessChain %i8${inPtr} %ssboIN %zero %x %c_i32_9 %y\n"
2582 "%inV9 = OpLoad %i8 %inP9\n"
2583 "%outP9 = OpAccessChain %i8outPtr %ssboOUT %zero %x %c_i32_9 %y\n"
2584 "OpStore %outP9 %inV9\n"
2585 "\n"//strutOut.b32[y] = strutIn.b32[y]
2586 "%inP10 = OpAccessChain %i32${inPtr} %ssboIN %zero %x %c_i32_10 %y\n"
2587 "%inV10 = OpLoad %i32 %inP10\n"
2588 "%outP10 = OpAccessChain %i32outPtr %ssboOUT %zero %x %c_i32_10 %y\n"
2589 "OpStore %outP10 %inV10\n"
2590 "\n"//strutOut.strutNestedOut[y].b8 = strutIn.strutNestedIn[y].b8
2591 "%inP11 = OpAccessChain %i8${inPtr} %ssboIN %zero %x %c_i32_8 %y %zero\n"
2592 "%inV11 = OpLoad %i8 %inP11\n"
2593 "%outP11 = OpAccessChain %i8outPtr %ssboOUT %zero %x %c_i32_8 %y %zero\n"
2594 "OpStore %outP11 %inV11\n"
2595 "\n"//strutOut.strutNestedOut[y].b32 = strutIn.strutNestedIn[y].b32
2596 "%inP12 = OpAccessChain %i32${inPtr} %ssboIN %zero %x %c_i32_8 %y %c_i32_1\n"
2597 "%inV12 = OpLoad %i32 %inP12\n"
2598 "%outP12 = OpAccessChain %i32outPtr %ssboOUT %zero %x %c_i32_8 %y %c_i32_1\n"
2599 "OpStore %outP12 %inV12\n"
2602 "\n"//strutOut.strutNestedOut[y].v2b8[valNdx] = strutIn.strutNestedIn[y].v2b8[valNdx]
2603 "%inP13 = OpAccessChain %v2i8${inPtr} %ssboIN %zero %x %c_i32_8 %y %c_i32_2 %Valz\n"
2604 "%inV13 = OpLoad %v2i8 %inP13\n"
2605 "%outP13 = OpAccessChain %v2i8outPtr %ssboOUT %zero %x %c_i32_8 %y %c_i32_2 %Valz\n"
2606 "OpStore %outP13 %inV13\n"
2607 "\n"//strutOut.strutNestedOut[y].b32[valNdx] = strutIn.strutNestedIn[y].b32[valNdx]
2608 "%inP14 = OpAccessChain %i32${inPtr} %ssboIN %zero %x %c_i32_8 %y %c_i32_3 %Valz\n"
2609 "%inV14 = OpLoad %i32 %inP14\n"
2610 "%outP14 = OpAccessChain %i32outPtr %ssboOUT %zero %x %c_i32_8 %y %c_i32_3 %Valz\n"
2611 "OpStore %outP14 %inV14\n"
2613 "OpBranch %exitLabel\n"
2614 "%exitLabel = OpLabel\n"
2618 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
2620 const bool isUniform = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == CAPABILITIES[capIdx].dtype;
2621 vector<deInt8> inData = isUniform ? data8bit(SHADERTEMPLATE_STRIDEMIX_STD140, rnd) : data8bit(SHADERTEMPLATE_STRIDEMIX_STD430, rnd);
2622 ComputeShaderSpec spec;
2623 map<string, string> specsOffset;
2624 map<string, string> specsLoop;
2625 map<string, string> specs;
2626 string testName = string(CAPABILITIES[capIdx].name);
2628 specsLoop["exeCount"] = "c_i32_11";
2629 specsLoop["loopName"] = "z";
2630 specs["zBeginLoop"] = beginLoop(specsLoop);
2631 specs["zEndLoop"] = endLoop(specsLoop);
2632 specs["inStorage"] = isUniform ? "Uniform" : "StorageBuffer";
2633 specs["capability"] = "";
2634 specs["uniformPtr"] = isUniform ?
2635 "%i8inPtr = OpTypePointer Uniform %i8\n"
2636 "%v2i8inPtr = OpTypePointer Uniform %v2i8\n"
2637 "%v3i8inPtr = OpTypePointer Uniform %v3i8\n"
2638 "%v4i8inPtr = OpTypePointer Uniform %v4i8\n"
2639 "%i32inPtr = OpTypePointer Uniform %i32\n"
2640 "%v2i32inPtr = OpTypePointer Uniform %v2i32\n"
2641 "%v3i32inPtr = OpTypePointer Uniform %v3i32\n"
2642 "%v4i32inPtr = OpTypePointer Uniform %v4i32\n" :
2644 specs["inPtr"] = isUniform ? "inPtr" : "outPtr";
2645 specsOffset["InOut"] = "In";
2646 specs["InOffsets"] = StringTemplate(isUniform ? getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD140) : getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD430)).specialize(specsOffset);
2647 specsOffset["InOut"] = "Out";
2648 specs["OutOffsets"] = StringTemplate(getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD430)).specialize(specsOffset);
2651 specs["capability"] = "OpCapability " + string(CAPABILITIES[capIdx].cap);
2654 spec.assembly = shaderTemplate.specialize(specs);
2655 spec.numWorkGroups = IVec3(structData.structArraySize, structData.nestedArraySize, 1);
2656 spec.verifyIO = isUniform ? checkStruct<deInt8, deInt8, SHADERTEMPLATE_STRIDEMIX_STD140, SHADERTEMPLATE_STRIDEMIX_STD430> : checkStruct<deInt8, deInt8, SHADERTEMPLATE_STRIDEMIX_STD430, SHADERTEMPLATE_STRIDEMIX_STD430>;
2657 spec.inputs.push_back (Resource(BufferSp(new Int8Buffer(inData)), CAPABILITIES[capIdx].dtype));
2658 spec.outputs.push_back (Resource(BufferSp(new Int8Buffer(outData))));
2659 spec.extensions.push_back ("VK_KHR_8bit_storage");
2660 spec.extensions.push_back ("VK_KHR_storage_buffer_storage_class");
2661 spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[capIdx].name);
2663 group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), testName.c_str(), spec));
2667 void addGraphics8BitStorageUniformInt32To8Group (tcu::TestCaseGroup* testGroup)
2669 de::Random rnd (deStringHash(testGroup->getName()));
2670 map<string, string> fragments;
2671 const deUint32 numDataPoints = 256u;
2672 RGBA defaultColors[4];
2673 GraphicsResources resources;
2674 vector<string> extensions;
2675 const StringTemplate capabilities ("OpCapability ${cap}\n");
2676 vector<deInt8> outputs (numDataPoints);
2678 extensions.push_back("VK_KHR_8bit_storage");
2679 fragments["extension"] =
2680 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
2681 "OpExtension \"SPV_KHR_8bit_storage\"";
2683 getDefaultColors(defaultColors);
2691 const char* isSigned;
2694 const IntegerFacts intFacts[] =
2696 {"sint", "%i32", "%i8", "OpSConvert", "1"},
2697 {"uint", "%u32", "%u8", "OpUConvert", "0"},
2700 const StringTemplate scalarPreMain(
2701 "${itype8} = OpTypeInt 8 ${signed}\n"
2702 "%c_i32_256 = OpConstant %i32 256\n"
2703 " %up_i32 = OpTypePointer Uniform ${itype32}\n"
2704 " %up_i8 = OpTypePointer StorageBuffer ${itype8}\n"
2705 " %ra_i32 = OpTypeArray ${itype32} %c_i32_256\n"
2706 " %ra_i8 = OpTypeArray ${itype8} %c_i32_256\n"
2707 " %SSBO32 = OpTypeStruct %ra_i32\n"
2708 " %SSBO8 = OpTypeStruct %ra_i8\n"
2709 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2710 "%up_SSBO8 = OpTypePointer StorageBuffer %SSBO8\n"
2711 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2712 " %ssbo8 = OpVariable %up_SSBO8 StorageBuffer\n");
2714 const StringTemplate scalarDecoration(
2715 "OpDecorate %ra_i32 ArrayStride 16\n"
2716 "OpDecorate %ra_i8 ArrayStride 1\n"
2717 "OpDecorate %SSBO32 Block\n"
2718 "OpDecorate %SSBO8 Block\n"
2719 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2720 "OpMemberDecorate %SSBO8 0 Offset 0\n"
2721 "OpDecorate %ssbo32 DescriptorSet 0\n"
2722 "OpDecorate %ssbo8 DescriptorSet 0\n"
2723 "OpDecorate %ssbo32 Binding 0\n"
2724 "OpDecorate %ssbo8 Binding 1\n");
2726 const StringTemplate scalarTestFunc(
2727 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
2728 " %param = OpFunctionParameter %v4f32\n"
2730 "%entry = OpLabel\n"
2731 " %i = OpVariable %fp_i32 Function\n"
2732 " OpStore %i %c_i32_0\n"
2735 " %loop = OpLabel\n"
2736 " %15 = OpLoad %i32 %i\n"
2737 " %lt = OpSLessThan %bool %15 %c_i32_256\n"
2738 " OpLoopMerge %merge %inc None\n"
2739 " OpBranchConditional %lt %write %merge\n"
2741 "%write = OpLabel\n"
2742 " %30 = OpLoad %i32 %i\n"
2743 " %src = OpAccessChain %up_i32 %ssbo32 %c_i32_0 %30\n"
2744 "%val32 = OpLoad ${itype32} %src\n"
2745 "%val8 = ${convert} ${itype8} %val32\n"
2746 " %dst = OpAccessChain %up_i8 %ssbo8 %c_i32_0 %30\n"
2747 " OpStore %dst %val8\n"
2751 " %37 = OpLoad %i32 %i\n"
2752 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
2756 "%merge = OpLabel\n"
2757 " OpReturnValue %param\n"
2761 const StringTemplate vecPreMain(
2762 "${itype8} = OpTypeInt 8 ${signed}\n"
2763 " %c_i32_64 = OpConstant %i32 64\n"
2764 "%v4itype8 = OpTypeVector ${itype8} 4\n"
2765 " %up_v4i32 = OpTypePointer Uniform ${v4itype32}\n"
2766 " %up_v4i8 = OpTypePointer StorageBuffer %v4itype8\n"
2767 " %ra_v4i32 = OpTypeArray ${v4itype32} %c_i32_64\n"
2768 " %ra_v4i8 = OpTypeArray %v4itype8 %c_i32_64\n"
2769 " %SSBO32 = OpTypeStruct %ra_v4i32\n"
2770 " %SSBO8 = OpTypeStruct %ra_v4i8\n"
2771 "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2772 "%up_SSBO8 = OpTypePointer StorageBuffer %SSBO8\n"
2773 " %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2774 " %ssbo8 = OpVariable %up_SSBO8 StorageBuffer\n");
2776 const StringTemplate vecDecoration(
2777 "OpDecorate %ra_v4i32 ArrayStride 16\n"
2778 "OpDecorate %ra_v4i8 ArrayStride 4\n"
2779 "OpDecorate %SSBO32 Block\n"
2780 "OpDecorate %SSBO8 Block\n"
2781 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2782 "OpMemberDecorate %SSBO8 0 Offset 0\n"
2783 "OpDecorate %ssbo32 DescriptorSet 0\n"
2784 "OpDecorate %ssbo8 DescriptorSet 0\n"
2785 "OpDecorate %ssbo32 Binding 0\n"
2786 "OpDecorate %ssbo8 Binding 1\n");
2788 const StringTemplate vecTestFunc(
2789 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
2790 " %param = OpFunctionParameter %v4f32\n"
2792 "%entry = OpLabel\n"
2793 " %i = OpVariable %fp_i32 Function\n"
2794 " OpStore %i %c_i32_0\n"
2797 " %loop = OpLabel\n"
2798 " %15 = OpLoad %i32 %i\n"
2799 " %lt = OpSLessThan %bool %15 %c_i32_64\n"
2800 " OpLoopMerge %merge %inc None\n"
2801 " OpBranchConditional %lt %write %merge\n"
2803 "%write = OpLabel\n"
2804 " %30 = OpLoad %i32 %i\n"
2805 " %src = OpAccessChain %up_v4i32 %ssbo32 %c_i32_0 %30\n"
2806 "%val32 = OpLoad ${v4itype32} %src\n"
2807 "%val8 = ${convert} %v4itype8 %val32\n"
2808 " %dst = OpAccessChain %up_v4i8 %ssbo8 %c_i32_0 %30\n"
2809 " OpStore %dst %val8\n"
2813 " %37 = OpLoad %i32 %i\n"
2814 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
2818 "%merge = OpLabel\n"
2819 " OpReturnValue %param\n"
2826 const StringTemplate& preMain;
2827 const StringTemplate& decoration;
2828 const StringTemplate& testFunction;
2829 const deUint32 numElements;
2832 const Category categories[] =
2834 {"scalar", scalarPreMain, scalarDecoration, scalarTestFunc, 1},
2835 {"vector", vecPreMain, vecDecoration, vecTestFunc, 4},
2839 for (deUint32 catIdx = 0; catIdx < DE_LENGTH_OF_ARRAY(categories); ++catIdx)
2841 resources.inputs.clear();
2842 resources.outputs.clear();
2843 vector<deInt32> inputs = getInt32s(rnd, ((arrayStrideInBytesUniform / static_cast<deUint32>(sizeof(deInt32))) * numDataPoints) / categories[catIdx].numElements);
2845 if ( 0 != (arrayStrideInBytesUniform - static_cast<deUint32>(sizeof(deInt32)) * categories[catIdx].numElements))
2846 resources.verifyIO = checkUniformsArray<deInt32, deInt8, 1>;
2849 resources.verifyIO = DE_NULL;
2850 for (deUint32 numNdx = 0; numNdx < numDataPoints; ++numNdx)
2851 outputs[numNdx] = static_cast<deInt8>(0xffff & inputs[numNdx]);
2854 resources.inputs.push_back(Resource(BufferSp(new Int32Buffer(inputs)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
2855 resources.outputs.push_back(Resource(BufferSp(new Int8Buffer(outputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
2857 for (deUint32 factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
2859 map<string, string> specs;
2860 VulkanFeatures features;
2861 string name = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name) + "_" + categories[catIdx].name + "_" + intFacts[factIdx].name;
2863 specs["cap"] = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
2864 specs["itype32"] = intFacts[factIdx].type32;
2865 specs["v4itype32"] = "%v4" + string(intFacts[factIdx].type32).substr(1);
2866 specs["itype8"] = intFacts[factIdx].type8;
2867 specs["signed"] = intFacts[factIdx].isSigned;
2868 specs["convert"] = intFacts[factIdx].opcode;
2870 fragments["pre_main"] = categories[catIdx].preMain.specialize(specs);
2871 fragments["testfun"] = categories[catIdx].testFunction.specialize(specs);
2872 fragments["capability"] = capabilities.specialize(specs);
2873 fragments["decoration"] = categories[catIdx].decoration.specialize(specs);
2875 features = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
2876 features.coreFeatures.vertexPipelineStoresAndAtomics = true;
2877 features.coreFeatures.fragmentStoresAndAtomics = true;
2879 createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup, features);
2884 void addGraphics8BitStorageUniformInt8To32Group (tcu::TestCaseGroup* testGroup)
2886 de::Random rnd (deStringHash(testGroup->getName()));
2887 map<string, string> fragments;
2888 const deUint32 numDataPoints = 256;
2889 RGBA defaultColors[4];
2890 vector<deInt32> outputs (numDataPoints);
2891 GraphicsResources resources;
2892 vector<string> extensions;
2893 const StringTemplate capabilities ("OpCapability ${cap}\n");
2895 extensions.push_back("VK_KHR_8bit_storage");
2896 fragments["extension"] =
2897 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
2898 "OpExtension \"SPV_KHR_8bit_storage\"";
2900 getDefaultColors(defaultColors);
2911 const IntegerFacts intFacts[] =
2913 {"sint", "%i32", "%i8", "OpSConvert", true},
2914 {"uint", "%u32", "%u8", "OpUConvert", false},
2917 struct ConstantIndex
2919 bool useConstantIndex;
2920 deUint32 constantIndex;
2923 ConstantIndex constantIndices[] =
2931 const StringTemplate scalarPreMain (
2932 "${itype8} = OpTypeInt 8 ${signed}\n"
2933 " %c_i32_256 = OpConstant %i32 256\n"
2934 "%c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
2935 " %up_i32 = OpTypePointer StorageBuffer ${itype32}\n"
2936 " %up_i8 = OpTypePointer Uniform ${itype8}\n"
2937 " %ra_i32 = OpTypeArray ${itype32} %c_i32_256\n"
2938 " %ra_i8 = OpTypeArray ${itype8} %c_i32_256\n"
2939 " %SSBO32 = OpTypeStruct %ra_i32\n"
2940 " %SSBO8 = OpTypeStruct %ra_i8\n"
2941 "%up_SSBO32 = OpTypePointer StorageBuffer %SSBO32\n"
2942 "%up_SSBO8 = OpTypePointer Uniform %SSBO8\n"
2943 " %ssbo32 = OpVariable %up_SSBO32 StorageBuffer\n"
2944 " %ssbo8 = OpVariable %up_SSBO8 Uniform\n");
2946 const StringTemplate scalarDecoration (
2947 "OpDecorate %ra_i32 ArrayStride 4\n"
2948 "OpDecorate %ra_i8 ArrayStride 16\n"
2949 "OpDecorate %SSBO32 Block\n"
2950 "OpDecorate %SSBO8 Block\n"
2951 "OpMemberDecorate %SSBO32 0 Offset 0\n"
2952 "OpMemberDecorate %SSBO8 0 Offset 0\n"
2953 "OpDecorate %ssbo32 DescriptorSet 0\n"
2954 "OpDecorate %ssbo8 DescriptorSet 0\n"
2955 "OpDecorate %ssbo32 Binding 1\n"
2956 "OpDecorate %ssbo8 Binding 0\n");
2958 const StringTemplate scalarTestFunc (
2959 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
2960 " %param = OpFunctionParameter %v4f32\n"
2962 "%entry = OpLabel\n"
2963 " %i = OpVariable %fp_i32 Function\n"
2964 " OpStore %i %c_i32_0\n"
2967 " %loop = OpLabel\n"
2968 " %15 = OpLoad %i32 %i\n"
2969 " %lt = OpSLessThan %bool %15 %c_i32_256\n"
2970 " OpLoopMerge %merge %inc None\n"
2971 " OpBranchConditional %lt %write %merge\n"
2973 "%write = OpLabel\n"
2974 " %30 = OpLoad %i32 %i\n"
2975 " %src = OpAccessChain %up_i8 %ssbo8 %c_i32_0 %${arrayindex}\n"
2976 "%val8 = OpLoad ${itype8} %src\n"
2977 "%val32 = ${convert} ${itype32} %val8\n"
2978 " %dst = OpAccessChain %up_i32 %ssbo32 %c_i32_0 %30\n"
2979 " OpStore %dst %val32\n"
2983 " %37 = OpLoad %i32 %i\n"
2984 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
2987 "%merge = OpLabel\n"
2988 " OpReturnValue %param\n"
2992 const StringTemplate vecPreMain (
2993 "${itype8} = OpTypeInt 8 ${signed}\n"
2994 "%c_i32_128 = OpConstant %i32 128\n"
2995 "%c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
2996 "%v2itype8 = OpTypeVector ${itype8} 2\n"
2997 " %up_v2i32 = OpTypePointer StorageBuffer ${v2itype32}\n"
2998 " %up_v2i8 = OpTypePointer Uniform %v2itype8\n"
2999 " %ra_v2i32 = OpTypeArray ${v2itype32} %c_i32_128\n"
3000 " %ra_v2i8 = OpTypeArray %v2itype8 %c_i32_128\n"
3001 " %SSBO32 = OpTypeStruct %ra_v2i32\n"
3002 " %SSBO8 = OpTypeStruct %ra_v2i8\n"
3003 "%up_SSBO32 = OpTypePointer StorageBuffer %SSBO32\n"
3004 "%up_SSBO8 = OpTypePointer Uniform %SSBO8\n"
3005 " %ssbo32 = OpVariable %up_SSBO32 StorageBuffer\n"
3006 " %ssbo8 = OpVariable %up_SSBO8 Uniform\n");
3008 const StringTemplate vecDecoration (
3009 "OpDecorate %ra_v2i32 ArrayStride 8\n"
3010 "OpDecorate %ra_v2i8 ArrayStride 16\n"
3011 "OpDecorate %SSBO32 Block\n"
3012 "OpDecorate %SSBO8 Block\n"
3013 "OpMemberDecorate %SSBO32 0 Offset 0\n"
3014 "OpMemberDecorate %SSBO8 0 Offset 0\n"
3015 "OpDecorate %ssbo32 DescriptorSet 0\n"
3016 "OpDecorate %ssbo8 DescriptorSet 0\n"
3017 "OpDecorate %ssbo32 Binding 1\n"
3018 "OpDecorate %ssbo8 Binding 0\n");
3020 const StringTemplate vecTestFunc (
3021 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3022 " %param = OpFunctionParameter %v4f32\n"
3024 "%entry = OpLabel\n"
3025 " %i = OpVariable %fp_i32 Function\n"
3026 " OpStore %i %c_i32_0\n"
3029 " %loop = OpLabel\n"
3030 " %15 = OpLoad %i32 %i\n"
3031 " %lt = OpSLessThan %bool %15 %c_i32_128\n"
3032 " OpLoopMerge %merge %inc None\n"
3033 " OpBranchConditional %lt %write %merge\n"
3035 "%write = OpLabel\n"
3036 " %30 = OpLoad %i32 %i\n"
3037 " %src = OpAccessChain %up_v2i8 %ssbo8 %c_i32_0 %${arrayindex}\n"
3038 "%val8 = OpLoad %v2itype8 %src\n"
3039 "%val32 = ${convert} ${v2itype32} %val8\n"
3040 " %dst = OpAccessChain %up_v2i32 %ssbo32 %c_i32_0 %30\n"
3041 " OpStore %dst %val32\n"
3045 " %37 = OpLoad %i32 %i\n"
3046 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
3049 "%merge = OpLabel\n"
3050 " OpReturnValue %param\n"
3057 const StringTemplate& preMain;
3058 const StringTemplate& decoration;
3059 const StringTemplate& testFunction;
3060 const deUint32 numElements;
3063 const Category categories[] =
3065 {"scalar", scalarPreMain, scalarDecoration, scalarTestFunc, 1},
3066 {"vector", vecPreMain, vecDecoration, vecTestFunc, 2},
3069 for (deUint32 catIdx = 0; catIdx < DE_LENGTH_OF_ARRAY(categories); ++catIdx)
3071 resources.inputs.clear();
3072 vector<deInt8> inputs = getInt8s(rnd, (arrayStrideInBytesUniform / static_cast<deUint32>(sizeof(deInt8))) * (numDataPoints / categories[catIdx].numElements));
3073 resources.inputs.push_back(Resource(BufferSp(new Int8Buffer(inputs)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
3074 for (deUint32 factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
3075 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
3077 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
3078 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
3079 map<string, string> specs;
3080 VulkanFeatures features;
3081 string name = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name) + "_" + categories[catIdx].name + "_" + intFacts[factIdx].name;
3083 specs["cap"] = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
3084 specs["itype32"] = intFacts[factIdx].type32;
3085 specs["v2itype32"] = "%v2" + string(intFacts[factIdx].type32).substr(1);
3086 specs["itype8"] = intFacts[factIdx].type8;
3087 if (intFacts[factIdx].isSigned)
3088 specs["signed"] = "1";
3090 specs["signed"] = "0";
3091 specs["convert"] = intFacts[factIdx].opcode;
3092 specs["constarrayidx"] = de::toString(constIdx);
3094 specs["arrayindex"] = "c_i32_ci";
3096 specs["arrayindex"] = "30";
3098 fragments["pre_main"] = categories[catIdx].preMain.specialize(specs);
3099 fragments["testfun"] = categories[catIdx].testFunction.specialize(specs);
3100 fragments["capability"] = capabilities.specialize(specs);
3101 fragments["decoration"] = categories[catIdx].decoration.specialize(specs);
3104 name += string("_const_idx_") + de::toString(constIdx);
3106 resources.outputs.clear();
3107 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(outputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3110 switch(constantIndices[constIndexIdx].constantIndex)
3113 if (categories[catIdx].numElements == 2)
3114 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt32, 2, 0>;
3116 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt32, 1, 0>;
3119 if (categories[catIdx].numElements == 2)
3120 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt32, 2, 4>;
3122 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt32, 1, 4>;
3125 if (categories[catIdx].numElements == 2)
3126 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt32, 2, 5>;
3128 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt32, 1, 5>;
3131 if (categories[catIdx].numElements == 2)
3132 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt32, 2, 6>;
3134 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt32, 1, 6>;
3137 DE_FATAL("Impossible");
3143 if (categories[catIdx].numElements == 2)
3144 resources.verifyIO = checkUniformsArray<deInt8, deInt32, 2>;
3146 resources.verifyIO = checkUniformsArray<deInt8, deInt32, 1>;
3149 features = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
3150 features.coreFeatures.vertexPipelineStoresAndAtomics = true;
3151 features.coreFeatures.fragmentStoresAndAtomics = true;
3153 createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup, features);
3158 void addGraphics8BitStoragePushConstantInt8To32Group (tcu::TestCaseGroup* testGroup)
3160 de::Random rnd (deStringHash(testGroup->getName()));
3161 map<string, string> fragments;
3162 RGBA defaultColors[4];
3163 const deUint32 numDataPoints = 64;
3164 vector<deInt8> inputs = getInt8s(rnd, numDataPoints);
3165 vector<deInt32> sOutputs;
3166 vector<deInt32> uOutputs;
3168 GraphicsResources resources;
3169 vector<string> extensions;
3170 const deUint8 signBitMask = 0x80;
3171 const deUint32 signExtendMask = 0xffff0000;
3172 VulkanFeatures requiredFeatures;
3174 struct ConstantIndex
3176 bool useConstantIndex;
3177 deUint32 constantIndex;
3180 ConstantIndex constantIndices[] =
3188 sOutputs.reserve(inputs.size());
3189 uOutputs.reserve(inputs.size());
3191 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
3193 uOutputs.push_back(static_cast<deUint8>(inputs[numNdx]));
3194 if (inputs[numNdx] & signBitMask)
3195 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx] | signExtendMask));
3197 sOutputs.push_back(static_cast<deInt32>(inputs[numNdx]));
3200 extensions.push_back("VK_KHR_8bit_storage");
3202 requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = true;
3203 requiredFeatures.coreFeatures.fragmentStoresAndAtomics = true;
3204 requiredFeatures.ext8BitStorage = EXT8BITSTORAGEFEATURES_PUSH_CONSTANT;
3206 fragments["capability"] = "OpCapability StoragePushConstant8\n";
3207 fragments["extension"] = "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
3208 "OpExtension \"SPV_KHR_8bit_storage\"";
3210 pcs.setPushConstant(BufferSp(new Int8Buffer(inputs)));
3212 getDefaultColors(defaultColors);
3214 const StringTemplate testFun (
3215 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3216 " %param = OpFunctionParameter %v4f32\n"
3218 "%entry = OpLabel\n"
3219 " %i = OpVariable %fp_i32 Function\n"
3220 " OpStore %i %c_i32_0\n"
3223 " %loop = OpLabel\n"
3224 " %15 = OpLoad %i32 %i\n"
3225 " %lt = OpSLessThan %bool %15 %c_i32_${count}\n"
3226 " OpLoopMerge %merge %inc None\n"
3227 " OpBranchConditional %lt %write %merge\n"
3229 "%write = OpLabel\n"
3230 " %30 = OpLoad %i32 %i\n"
3231 " %src = OpAccessChain %pp_${type8} %pc8 %c_i32_0 %${arrayindex}\n"
3232 "%val8 = OpLoad %${type8} %src\n"
3233 "%val32 = ${convert} %${type32} %val8\n"
3234 " %dst = OpAccessChain %up_${type32} %ssbo32 %c_i32_0 %30\n"
3235 " OpStore %dst %val32\n"
3239 " %37 = OpLoad %i32 %i\n"
3240 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
3244 "%merge = OpLabel\n"
3245 " OpReturnValue %param\n"
3250 const StringTemplate preMain (
3251 " %${type8} = OpTypeInt 8 ${signed}\n"
3252 " %c_i32_${count} = OpConstant %i32 ${count}\n" // Should be the same as numDataPoints
3253 " %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
3254 "%a${count}${type8} = OpTypeArray %${type8} %c_i32_${count}\n"
3255 "%a${count}${type32} = OpTypeArray %${type32} %c_i32_${count}\n"
3256 " %pp_${type8} = OpTypePointer PushConstant %${type8}\n"
3257 " %up_${type32} = OpTypePointer StorageBuffer %${type32}\n"
3258 " %SSBO32 = OpTypeStruct %a${count}${type32}\n"
3259 " %up_SSBO32 = OpTypePointer StorageBuffer %SSBO32\n"
3260 " %ssbo32 = OpVariable %up_SSBO32 StorageBuffer\n"
3261 " %PC8 = OpTypeStruct %a${count}${type8}\n"
3262 " %pp_PC8 = OpTypePointer PushConstant %PC8\n"
3263 " %pc8 = OpVariable %pp_PC8 PushConstant\n");
3265 const StringTemplate decoration (
3266 "OpDecorate %a${count}${type8} ArrayStride 1\n"
3267 "OpDecorate %a${count}${type32} ArrayStride 4\n"
3268 "OpDecorate %SSBO32 Block\n"
3269 "OpMemberDecorate %SSBO32 0 Offset 0\n"
3270 "OpDecorate %PC8 Block\n"
3271 "OpMemberDecorate %PC8 0 Offset 0\n"
3272 "OpDecorate %ssbo32 DescriptorSet 0\n"
3273 "OpDecorate %ssbo32 Binding 0\n");
3276 map<string, string> specs;
3278 specs["type8"] = "i8";
3279 specs["type32"] = "i32";
3280 specs["signed"] = "1";
3281 specs["count"] = "64";
3282 specs["convert"] = "OpSConvert";
3284 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
3286 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
3287 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
3288 string testName = "sint_scalar";
3289 vector<deInt32> constIdxData;
3293 constIdxData.reserve(numDataPoints);
3295 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
3296 constIdxData.push_back(sOutputs[constIdx]);
3299 specs["constarrayidx"] = de::toString(constIdx);
3301 specs["arrayindex"] = "c_i32_ci";
3303 specs["arrayindex"] = "30";
3306 testName += string("_const_idx_") + de::toString(constIdx);
3308 resources.outputs.clear();
3309 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(useConstIdx ? constIdxData : sOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3311 fragments["testfun"] = testFun.specialize(specs);
3312 fragments["pre_main"] = preMain.specialize(specs);
3313 fragments["decoration"] = decoration.specialize(specs);
3315 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
3319 map<string, string> specs;
3321 specs["type8"] = "u8";
3322 specs["type32"] = "u32";
3323 specs["signed"] = "0";
3324 specs["count"] = "64";
3325 specs["convert"] = "OpUConvert";
3327 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
3329 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
3330 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
3331 string testName = "uint_scalar";
3332 vector<deInt32> constIdxData;
3336 constIdxData.reserve(numDataPoints);
3338 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
3339 constIdxData.push_back(uOutputs[constIdx]);
3342 specs["constarrayidx"] = de::toString(constIdx);
3344 specs["arrayindex"] = "c_i32_ci";
3346 specs["arrayindex"] = "30";
3349 testName += string("_const_idx_") + de::toString(constIdx);
3351 resources.outputs.clear();
3352 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(useConstIdx ? constIdxData : uOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3354 fragments["testfun"] = testFun.specialize(specs);
3355 fragments["pre_main"] = preMain.specialize(specs);
3356 fragments["decoration"] = decoration.specialize(specs);
3358 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
3364 const StringTemplate preMain (
3365 " %${base_type8} = OpTypeInt 8 ${signed}\n"
3366 " %${type8} = OpTypeVector %${base_type8} 2\n"
3367 " %c_i32_${count} = OpConstant %i32 ${count}\n"
3368 " %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
3369 "%a${count}${type8} = OpTypeArray %${type8} %c_i32_${count}\n"
3370 "%a${count}${type32} = OpTypeArray %${type32} %c_i32_${count}\n"
3371 " %pp_${type8} = OpTypePointer PushConstant %${type8}\n"
3372 " %up_${type32} = OpTypePointer StorageBuffer %${type32}\n"
3373 " %SSBO32 = OpTypeStruct %a${count}${type32}\n"
3374 " %up_SSBO32 = OpTypePointer StorageBuffer %SSBO32\n"
3375 " %ssbo32 = OpVariable %up_SSBO32 StorageBuffer\n"
3376 " %PC8 = OpTypeStruct %a${count}${type8}\n"
3377 " %pp_PC8 = OpTypePointer PushConstant %PC8\n"
3378 " %pc8 = OpVariable %pp_PC8 PushConstant\n");
3380 const StringTemplate decoration (
3381 "OpDecorate %a${count}${type8} ArrayStride 2\n"
3382 "OpDecorate %a${count}${type32} ArrayStride 8\n"
3383 "OpDecorate %SSBO32 Block\n"
3384 "OpMemberDecorate %SSBO32 0 Offset 0\n"
3385 "OpDecorate %PC8 Block\n"
3386 "OpMemberDecorate %PC8 0 Offset 0\n"
3387 "OpDecorate %ssbo32 DescriptorSet 0\n"
3388 "OpDecorate %ssbo32 Binding 0\n");
3391 map<string, string> specs;
3393 specs["base_type8"] = "i8";
3394 specs["type8"] = "v2i8";
3395 specs["type32"] = "v2i32";
3396 specs["signed"] = "1";
3397 specs["count"] = "32"; // 64 / 2
3398 specs["convert"] = "OpSConvert";
3400 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
3402 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
3403 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
3404 string testName = "sint_vector";
3405 vector<deInt32> constIdxData;
3409 constIdxData.reserve(numDataPoints);
3411 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
3412 constIdxData.push_back(sOutputs[constIdx * 2 + numIdx % 2]);
3415 specs["constarrayidx"] = de::toString(constIdx);
3417 specs["arrayindex"] = "c_i32_ci";
3419 specs["arrayindex"] = "30";
3422 testName += string("_const_idx_") + de::toString(constIdx);
3424 resources.outputs.clear();
3425 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(useConstIdx ? constIdxData : sOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3427 fragments["testfun"] = testFun.specialize(specs);
3428 fragments["pre_main"] = preMain.specialize(specs);
3429 fragments["decoration"] = decoration.specialize(specs);
3431 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
3435 map<string, string> specs;
3437 specs["base_type8"] = "u8";
3438 specs["type8"] = "v2u8";
3439 specs["type32"] = "v2u32";
3440 specs["signed"] = "0";
3441 specs["count"] = "32";
3442 specs["convert"] = "OpUConvert";
3444 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
3446 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
3447 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
3448 string testName = "uint_vector";
3449 vector<deInt32> constIdxData;
3453 constIdxData.reserve(numDataPoints);
3455 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
3456 constIdxData.push_back(uOutputs[constIdx * 2 + numIdx % 2]);
3459 specs["constarrayidx"] = de::toString(constIdx);
3461 specs["arrayindex"] = "c_i32_ci";
3463 specs["arrayindex"] = "30";
3466 testName += string("_const_idx_") + de::toString(constIdx);
3468 resources.outputs.clear();
3469 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(useConstIdx ? constIdxData : uOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3471 fragments["testfun"] = testFun.specialize(specs);
3472 fragments["pre_main"] = preMain.specialize(specs);
3473 fragments["decoration"] = decoration.specialize(specs);
3475 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
3481 void addGraphics8BitStorageUniformInt16To8Group (tcu::TestCaseGroup* testGroup)
3483 de::Random rnd (deStringHash(testGroup->getName()));
3484 map<string, string> fragments;
3485 const deUint32 numDataPoints = 256;
3486 RGBA defaultColors[4];
3487 GraphicsResources resources;
3488 vector<string> extensions;
3489 const StringTemplate capabilities ("OpCapability ${cap}\n");
3491 extensions.push_back("VK_KHR_8bit_storage");
3492 extensions.push_back("VK_KHR_16bit_storage");
3493 fragments["extension"] =
3494 "OpCapability StorageUniform16\n"
3495 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
3496 "OpExtension \"SPV_KHR_8bit_storage\"\n"
3497 "OpExtension \"SPV_KHR_16bit_storage\"\n";
3499 getDefaultColors(defaultColors);
3507 const char* isSigned;
3510 const IntegerFacts intFacts[] =
3512 {"sint", "%i16", "%i8", "OpSConvert", "1"},
3513 {"uint", "%u16", "%u8", "OpUConvert", "0"},
3516 const StringTemplate scalarPreMain(
3517 "${itype8} = OpTypeInt 8 ${signed}\n"
3518 "${itype16} = OpTypeInt 16 ${signed}\n"
3519 "%c_i32_256 = OpConstant %i32 256\n"
3520 " %up_i16 = OpTypePointer Uniform ${itype16}\n"
3521 " %up_i8 = OpTypePointer StorageBuffer ${itype8}\n"
3522 " %ra_i16 = OpTypeArray ${itype16} %c_i32_256\n"
3523 " %ra_i8 = OpTypeArray ${itype8} %c_i32_256\n"
3524 " %SSBO16 = OpTypeStruct %ra_i16\n"
3525 " %SSBO8 = OpTypeStruct %ra_i8\n"
3526 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
3527 "%up_SSBO8 = OpTypePointer StorageBuffer %SSBO8\n"
3528 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n"
3529 " %ssbo8 = OpVariable %up_SSBO8 StorageBuffer\n");
3531 const StringTemplate scalarDecoration(
3532 "OpDecorate %ra_i16 ArrayStride 16\n"
3533 "OpDecorate %ra_i8 ArrayStride 1\n"
3534 "OpDecorate %SSBO16 Block\n"
3535 "OpDecorate %SSBO8 Block\n"
3536 "OpMemberDecorate %SSBO16 0 Offset 0\n"
3537 "OpMemberDecorate %SSBO8 0 Offset 0\n"
3538 "OpDecorate %ssbo16 DescriptorSet 0\n"
3539 "OpDecorate %ssbo8 DescriptorSet 0\n"
3540 "OpDecorate %ssbo16 Binding 0\n"
3541 "OpDecorate %ssbo8 Binding 1\n");
3543 const StringTemplate scalarTestFunc(
3544 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3545 " %param = OpFunctionParameter %v4f32\n"
3547 "%entry = OpLabel\n"
3548 " %i = OpVariable %fp_i32 Function\n"
3549 " OpStore %i %c_i32_0\n"
3552 " %loop = OpLabel\n"
3553 " %15 = OpLoad %i32 %i\n"
3554 " %lt = OpSLessThan %bool %15 %c_i32_256\n"
3555 " OpLoopMerge %merge %inc None\n"
3556 " OpBranchConditional %lt %write %merge\n"
3558 "%write = OpLabel\n"
3559 " %30 = OpLoad %i32 %i\n"
3560 " %src = OpAccessChain %up_i16 %ssbo16 %c_i32_0 %30\n"
3561 "%val16 = OpLoad ${itype16} %src\n"
3562 "%val8 = ${convert} ${itype8} %val16\n"
3563 " %dst = OpAccessChain %up_i8 %ssbo8 %c_i32_0 %30\n"
3564 " OpStore %dst %val8\n"
3568 " %37 = OpLoad %i32 %i\n"
3569 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
3573 "%merge = OpLabel\n"
3574 " OpReturnValue %param\n"
3578 const StringTemplate vecPreMain(
3579 "${itype8} = OpTypeInt 8 ${signed}\n"
3580 "${itype16} = OpTypeInt 16 ${signed}\n"
3581 "${v4itype16} = OpTypeVector ${itype16} 4\n"
3582 "%c_i32_64 = OpConstant %i32 64\n"
3583 "%v4itype8 = OpTypeVector ${itype8} 4\n"
3584 " %up_v4i16 = OpTypePointer Uniform ${v4itype16}\n"
3585 " %up_v4i8 = OpTypePointer StorageBuffer %v4itype8\n"
3586 " %ra_v4i16 = OpTypeArray ${v4itype16} %c_i32_64\n"
3587 " %ra_v4i8 = OpTypeArray %v4itype8 %c_i32_64\n"
3588 " %SSBO16 = OpTypeStruct %ra_v4i16\n"
3589 " %SSBO8 = OpTypeStruct %ra_v4i8\n"
3590 "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
3591 "%up_SSBO8 = OpTypePointer StorageBuffer %SSBO8\n"
3592 " %ssbo16 = OpVariable %up_SSBO16 Uniform\n"
3593 " %ssbo8 = OpVariable %up_SSBO8 StorageBuffer\n");
3595 const StringTemplate vecDecoration(
3596 "OpDecorate %ra_v4i16 ArrayStride 16\n"
3597 "OpDecorate %ra_v4i8 ArrayStride 4\n"
3598 "OpDecorate %SSBO16 Block\n"
3599 "OpDecorate %SSBO8 Block\n"
3600 "OpMemberDecorate %SSBO16 0 Offset 0\n"
3601 "OpMemberDecorate %SSBO8 0 Offset 0\n"
3602 "OpDecorate %ssbo16 DescriptorSet 0\n"
3603 "OpDecorate %ssbo8 DescriptorSet 0\n"
3604 "OpDecorate %ssbo16 Binding 0\n"
3605 "OpDecorate %ssbo8 Binding 1\n");
3607 const StringTemplate vecTestFunc(
3608 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3609 " %param = OpFunctionParameter %v4f32\n"
3611 "%entry = OpLabel\n"
3612 " %i = OpVariable %fp_i32 Function\n"
3613 " OpStore %i %c_i32_0\n"
3616 " %loop = OpLabel\n"
3617 " %15 = OpLoad %i32 %i\n"
3618 " %lt = OpSLessThan %bool %15 %c_i32_64\n"
3619 " OpLoopMerge %merge %inc None\n"
3620 " OpBranchConditional %lt %write %merge\n"
3622 "%write = OpLabel\n"
3623 " %30 = OpLoad %i32 %i\n"
3624 " %src = OpAccessChain %up_v4i16 %ssbo16 %c_i32_0 %30\n"
3625 "%val16 = OpLoad ${v4itype16} %src\n"
3626 "%val8 = ${convert} %v4itype8 %val16\n"
3627 " %dst = OpAccessChain %up_v4i8 %ssbo8 %c_i32_0 %30\n"
3628 " OpStore %dst %val8\n"
3632 " %37 = OpLoad %i32 %i\n"
3633 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
3637 "%merge = OpLabel\n"
3638 " OpReturnValue %param\n"
3645 const StringTemplate& preMain;
3646 const StringTemplate& decoration;
3647 const StringTemplate& testFunction;
3648 const deUint32 numElements;
3651 const Category categories[] =
3653 {"scalar", scalarPreMain, scalarDecoration, scalarTestFunc, 1},
3654 {"vector", vecPreMain, vecDecoration, vecTestFunc, 4},
3657 for (deUint32 catIdx = 0; catIdx < DE_LENGTH_OF_ARRAY(categories); ++catIdx)
3659 resources.inputs.clear();
3660 resources.outputs.clear();
3661 vector<deInt16> inputs = getInt16s(rnd, ((arrayStrideInBytesUniform / static_cast<deUint32>(sizeof(deInt16))) * numDataPoints) / categories[catIdx].numElements);
3662 vector<deInt8> outputs (numDataPoints/ categories[catIdx].numElements);
3664 switch (categories[catIdx].numElements)
3667 resources.verifyIO = checkUniformsArray<deInt16, deInt8, 1>;
3670 resources.verifyIO = checkUniformsArray<deInt16, deInt8, 4>;
3673 DE_FATAL("Impossible");
3677 resources.inputs.push_back(Resource(BufferSp(new Int16Buffer(inputs)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
3678 resources.outputs.push_back(Resource(BufferSp(new Int8Buffer(outputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3680 for (deUint32 factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
3682 map<string, string> specs;
3683 VulkanFeatures features;
3684 string name = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name) + "_" + categories[catIdx].name + "_" + intFacts[factIdx].name;
3686 specs["cap"] = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
3687 specs["itype16"] = intFacts[factIdx].type16;
3688 specs["v4itype16"] = "%v4" + string(intFacts[factIdx].type16).substr(1);
3689 specs["itype8"] = intFacts[factIdx].type8;
3690 specs["signed"] = intFacts[factIdx].isSigned;
3691 specs["convert"] = intFacts[factIdx].opcode;
3693 fragments["pre_main"] = categories[catIdx].preMain.specialize(specs);
3694 fragments["testfun"] = categories[catIdx].testFunction.specialize(specs);
3695 fragments["capability"] = capabilities.specialize(specs);
3696 fragments["decoration"] = categories[catIdx].decoration.specialize(specs);
3698 features = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
3699 features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM;
3700 features.coreFeatures.vertexPipelineStoresAndAtomics = true;
3701 features.coreFeatures.fragmentStoresAndAtomics = true;
3703 createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup, features);
3708 void addGraphics8BitStorageUniformInt8To16Group (tcu::TestCaseGroup* testGroup)
3710 de::Random rnd (deStringHash(testGroup->getName()));
3711 map<string, string> fragments;
3712 const deUint32 numDataPoints = 256;
3713 vector<deInt16> outputs (numDataPoints);
3714 RGBA defaultColors[4];
3715 GraphicsResources resources;
3716 vector<string> extensions;
3717 const StringTemplate capabilities ("OpCapability ${cap}\n");
3719 extensions.push_back("VK_KHR_8bit_storage");
3720 extensions.push_back("VK_KHR_16bit_storage");
3721 fragments["extension"] =
3722 "OpCapability StorageUniform16\n"
3723 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
3724 "OpExtension \"SPV_KHR_8bit_storage\"\n"
3725 "OpExtension \"SPV_KHR_16bit_storage\"\n";
3727 getDefaultColors(defaultColors);
3738 const IntegerFacts intFacts[] =
3740 {"sint", "%i16", "%i8", "OpSConvert", true},
3741 {"uint", "%u16", "%u8", "OpUConvert", false},
3744 struct ConstantIndex
3746 bool useConstantIndex;
3747 deUint32 constantIndex;
3750 ConstantIndex constantIndices[] =
3758 const StringTemplate scalarPreMain (
3759 "${itype8} = OpTypeInt 8 ${signed}\n"
3760 "${itype16} = OpTypeInt 16 ${signed}\n"
3761 " %c_i32_256 = OpConstant %i32 256\n"
3762 "%c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
3763 " %up_i16 = OpTypePointer StorageBuffer ${itype16}\n"
3764 " %up_i8 = OpTypePointer Uniform ${itype8}\n"
3765 " %ra_i16 = OpTypeArray ${itype16} %c_i32_256\n"
3766 " %ra_i8 = OpTypeArray ${itype8} %c_i32_256\n"
3767 " %SSBO16 = OpTypeStruct %ra_i16\n"
3768 " %SSBO8 = OpTypeStruct %ra_i8\n"
3769 "%up_SSBO16 = OpTypePointer StorageBuffer %SSBO16\n"
3770 "%up_SSBO8 = OpTypePointer Uniform %SSBO8\n"
3771 " %ssbo16 = OpVariable %up_SSBO16 StorageBuffer\n"
3772 " %ssbo8 = OpVariable %up_SSBO8 Uniform\n");
3774 const StringTemplate scalarDecoration (
3775 "OpDecorate %ra_i16 ArrayStride 2\n"
3776 "OpDecorate %ra_i8 ArrayStride 16\n"
3777 "OpDecorate %SSBO16 Block\n"
3778 "OpDecorate %SSBO8 Block\n"
3779 "OpMemberDecorate %SSBO16 0 Offset 0\n"
3780 "OpMemberDecorate %SSBO8 0 Offset 0\n"
3781 "OpDecorate %ssbo16 DescriptorSet 0\n"
3782 "OpDecorate %ssbo8 DescriptorSet 0\n"
3783 "OpDecorate %ssbo16 Binding 1\n"
3784 "OpDecorate %ssbo8 Binding 0\n");
3786 const StringTemplate scalarTestFunc (
3787 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3788 " %param = OpFunctionParameter %v4f32\n"
3790 "%entry = OpLabel\n"
3791 " %i = OpVariable %fp_i32 Function\n"
3792 " OpStore %i %c_i32_0\n"
3795 " %loop = OpLabel\n"
3796 " %15 = OpLoad %i32 %i\n"
3797 " %lt = OpSLessThan %bool %15 %c_i32_256\n"
3798 " OpLoopMerge %merge %inc None\n"
3799 " OpBranchConditional %lt %write %merge\n"
3801 "%write = OpLabel\n"
3802 " %30 = OpLoad %i32 %i\n"
3803 " %src = OpAccessChain %up_i8 %ssbo8 %c_i32_0 %${arrayindex}\n"
3804 "%val8 = OpLoad ${itype8} %src\n"
3805 "%val16 = ${convert} ${itype16} %val8\n"
3806 " %dst = OpAccessChain %up_i16 %ssbo16 %c_i32_0 %30\n"
3807 " OpStore %dst %val16\n"
3811 " %37 = OpLoad %i32 %i\n"
3812 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
3815 "%merge = OpLabel\n"
3816 " OpReturnValue %param\n"
3820 const StringTemplate vecPreMain (
3821 "${itype8} = OpTypeInt 8 ${signed}\n"
3822 "${itype16} = OpTypeInt 16 ${signed}\n"
3823 "${v2itype16} = OpTypeVector ${itype16} 2\n"
3824 "%c_i32_128 = OpConstant %i32 128\n"
3825 "%c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
3826 "%v2itype8 = OpTypeVector ${itype8} 2\n"
3827 " %up_v2i16 = OpTypePointer StorageBuffer ${v2itype16}\n"
3828 " %up_v2i8 = OpTypePointer Uniform %v2itype8\n"
3829 " %ra_v2i16 = OpTypeArray ${v2itype16} %c_i32_128\n"
3830 " %ra_v2i8 = OpTypeArray %v2itype8 %c_i32_128\n"
3831 " %SSBO16 = OpTypeStruct %ra_v2i16\n"
3832 " %SSBO8 = OpTypeStruct %ra_v2i8\n"
3833 "%up_SSBO16 = OpTypePointer StorageBuffer %SSBO16\n"
3834 "%up_SSBO8 = OpTypePointer Uniform %SSBO8\n"
3835 " %ssbo16 = OpVariable %up_SSBO16 StorageBuffer\n"
3836 " %ssbo8 = OpVariable %up_SSBO8 Uniform\n");
3838 const StringTemplate vecDecoration (
3839 "OpDecorate %ra_v2i16 ArrayStride 4\n"
3840 "OpDecorate %ra_v2i8 ArrayStride 16\n"
3841 "OpDecorate %SSBO16 Block\n"
3842 "OpDecorate %SSBO8 Block\n"
3843 "OpMemberDecorate %SSBO16 0 Offset 0\n"
3844 "OpMemberDecorate %SSBO8 0 Offset 0\n"
3845 "OpDecorate %ssbo16 DescriptorSet 0\n"
3846 "OpDecorate %ssbo8 DescriptorSet 0\n"
3847 "OpDecorate %ssbo16 Binding 1\n"
3848 "OpDecorate %ssbo8 Binding 0\n");
3850 const StringTemplate vecTestFunc (
3851 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3852 " %param = OpFunctionParameter %v4f32\n"
3854 "%entry = OpLabel\n"
3855 " %i = OpVariable %fp_i32 Function\n"
3856 " OpStore %i %c_i32_0\n"
3859 " %loop = OpLabel\n"
3860 " %15 = OpLoad %i32 %i\n"
3861 " %lt = OpSLessThan %bool %15 %c_i32_128\n"
3862 " OpLoopMerge %merge %inc None\n"
3863 " OpBranchConditional %lt %write %merge\n"
3865 "%write = OpLabel\n"
3866 " %30 = OpLoad %i32 %i\n"
3867 " %src = OpAccessChain %up_v2i8 %ssbo8 %c_i32_0 %${arrayindex}\n"
3868 "%val8 = OpLoad %v2itype8 %src\n"
3869 "%val16 = ${convert} ${v2itype16} %val8\n"
3870 " %dst = OpAccessChain %up_v2i16 %ssbo16 %c_i32_0 %30\n"
3871 " OpStore %dst %val16\n"
3875 " %37 = OpLoad %i32 %i\n"
3876 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
3879 "%merge = OpLabel\n"
3880 " OpReturnValue %param\n"
3887 const StringTemplate& preMain;
3888 const StringTemplate& decoration;
3889 const StringTemplate& testFunction;
3890 const deUint32 numElements;
3893 const Category categories[] =
3895 {"scalar", scalarPreMain, scalarDecoration, scalarTestFunc, 1},
3896 {"vector", vecPreMain, vecDecoration, vecTestFunc, 2},
3899 for (deUint32 catIdx = 0; catIdx < DE_LENGTH_OF_ARRAY(categories); ++catIdx)
3901 resources.inputs.clear();
3902 vector<deInt8> inputs = getInt8s(rnd, (arrayStrideInBytesUniform / static_cast<deUint32>(sizeof(deInt8))) * (numDataPoints / categories[catIdx].numElements));
3903 resources.inputs.push_back(Resource(BufferSp(new Int8Buffer(inputs)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
3904 for (deUint32 factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
3905 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
3907 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
3908 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
3909 map<string, string> specs;
3910 VulkanFeatures features;
3911 string name = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name) + "_" + categories[catIdx].name + "_" + intFacts[factIdx].name;
3913 specs["cap"] = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
3914 specs["itype16"] = intFacts[factIdx].type16;
3915 specs["v2itype16"] = "%v2" + string(intFacts[factIdx].type16).substr(1);
3916 specs["itype8"] = intFacts[factIdx].type8;
3917 if (intFacts[factIdx].isSigned)
3918 specs["signed"] = "1";
3920 specs["signed"] = "0";
3921 specs["convert"] = intFacts[factIdx].opcode;
3922 specs["constarrayidx"] = de::toString(constIdx);
3924 specs["arrayindex"] = "c_i32_ci";
3926 specs["arrayindex"] = "30";
3928 fragments["pre_main"] = categories[catIdx].preMain.specialize(specs);
3929 fragments["testfun"] = categories[catIdx].testFunction.specialize(specs);
3930 fragments["capability"] = capabilities.specialize(specs);
3931 fragments["decoration"] = categories[catIdx].decoration.specialize(specs);
3934 name += string("_const_idx_") + de::toString(constIdx);
3936 resources.outputs.clear();
3937 resources.outputs.push_back(Resource(BufferSp(new Int16Buffer(outputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3940 switch (constantIndices[constIndexIdx].constantIndex)
3943 if (categories[catIdx].numElements == 2)
3944 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt16, 2, 0>;
3946 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt16, 1, 0>;
3949 if (categories[catIdx].numElements == 2)
3950 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt16, 2, 4>;
3952 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt16, 1, 4>;
3955 if (categories[catIdx].numElements == 2)
3956 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt16, 2, 5>;
3958 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt16, 1, 5>;
3961 if (categories[catIdx].numElements == 2)
3962 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt16, 2, 6>;
3964 resources.verifyIO = checkUniformsArrayConstNdx<deInt8, deInt16, 1, 6>;
3967 DE_FATAL("Impossible");
3973 if (categories[catIdx].numElements == 2)
3974 resources.verifyIO = checkUniformsArray<deInt8, deInt16, 2>;
3976 resources.verifyIO = checkUniformsArray<deInt8, deInt16, 1>;
3979 features = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
3980 features.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM;
3981 features.coreFeatures.vertexPipelineStoresAndAtomics = true;
3982 features.coreFeatures.fragmentStoresAndAtomics = true;
3984 createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup, features);
3989 void addGraphics8BitStoragePushConstantInt8To16Group (tcu::TestCaseGroup* testGroup)
3991 de::Random rnd (deStringHash(testGroup->getName()));
3992 map<string, string> fragments;
3993 RGBA defaultColors[4];
3994 const deUint32 numDataPoints = 64;
3995 vector<deInt8> inputs = getInt8s(rnd, numDataPoints);
3996 vector<deInt16> sOutputs;
3997 vector<deInt16> uOutputs;
3999 GraphicsResources resources;
4000 vector<string> extensions;
4001 const deUint8 signBitMask = 0x80;
4002 const deUint16 signExtendMask = 0xff00;
4003 VulkanFeatures requiredFeatures;
4005 struct ConstantIndex
4007 bool useConstantIndex;
4008 deUint32 constantIndex;
4011 ConstantIndex constantIndices[] =
4019 sOutputs.reserve(inputs.size());
4020 uOutputs.reserve(inputs.size());
4022 for (deUint32 numNdx = 0; numNdx < inputs.size(); ++numNdx)
4024 uOutputs.push_back(static_cast<deUint8>(inputs[numNdx]));
4025 if (inputs[numNdx] & signBitMask)
4026 sOutputs.push_back(static_cast<deInt16>(inputs[numNdx] | signExtendMask));
4028 sOutputs.push_back(static_cast<deInt16>(inputs[numNdx]));
4031 extensions.push_back("VK_KHR_8bit_storage");
4032 extensions.push_back("VK_KHR_16bit_storage");
4034 requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = true;
4035 requiredFeatures.coreFeatures.fragmentStoresAndAtomics = true;
4036 requiredFeatures.ext8BitStorage = EXT8BITSTORAGEFEATURES_PUSH_CONSTANT;
4037 requiredFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM;
4039 fragments["capability"] = "OpCapability StoragePushConstant8\n"
4040 "OpCapability StorageUniform16\n";
4041 fragments["extension"] = "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
4042 "OpExtension \"SPV_KHR_8bit_storage\"\n"
4043 "OpExtension \"SPV_KHR_16bit_storage\"\n";
4045 pcs.setPushConstant(BufferSp(new Int8Buffer(inputs)));
4047 getDefaultColors(defaultColors);
4049 const StringTemplate testFun (
4050 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
4051 " %param = OpFunctionParameter %v4f32\n"
4053 "%entry = OpLabel\n"
4054 " %i = OpVariable %fp_i32 Function\n"
4055 " OpStore %i %c_i32_0\n"
4058 " %loop = OpLabel\n"
4059 " %15 = OpLoad %i32 %i\n"
4060 " %lt = OpSLessThan %bool %15 %c_i32_${count}\n"
4061 " OpLoopMerge %merge %inc None\n"
4062 " OpBranchConditional %lt %write %merge\n"
4064 "%write = OpLabel\n"
4065 " %30 = OpLoad %i32 %i\n"
4066 " %src = OpAccessChain %pp_${type8} %pc8 %c_i32_0 %${arrayindex}\n"
4067 "%val8 = OpLoad %${type8} %src\n"
4068 "%val16 = ${convert} %${type16} %val8\n"
4069 " %dst = OpAccessChain %up_${type16} %ssbo16 %c_i32_0 %30\n"
4070 " OpStore %dst %val16\n"
4074 " %37 = OpLoad %i32 %i\n"
4075 " %39 = OpIAdd %i32 %37 %c_i32_1\n"
4079 "%merge = OpLabel\n"
4080 " OpReturnValue %param\n"
4085 const StringTemplate preMain (
4086 " %${type8} = OpTypeInt 8 ${signed}\n"
4087 " %${type16} = OpTypeInt 16 ${signed}\n"
4088 " %c_i32_${count} = OpConstant %i32 ${count}\n" // Should be the same as numDataPoints
4089 " %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
4090 "%a${count}${type8} = OpTypeArray %${type8} %c_i32_${count}\n"
4091 "%a${count}${type16} = OpTypeArray %${type16} %c_i32_${count}\n"
4092 " %pp_${type8} = OpTypePointer PushConstant %${type8}\n"
4093 " %up_${type16} = OpTypePointer StorageBuffer %${type16}\n"
4094 " %SSBO16 = OpTypeStruct %a${count}${type16}\n"
4095 " %up_SSBO16 = OpTypePointer StorageBuffer %SSBO16\n"
4096 " %ssbo16 = OpVariable %up_SSBO16 StorageBuffer\n"
4097 " %PC8 = OpTypeStruct %a${count}${type8}\n"
4098 " %pp_PC8 = OpTypePointer PushConstant %PC8\n"
4099 " %pc8 = OpVariable %pp_PC8 PushConstant\n");
4101 const StringTemplate decoration (
4102 "OpDecorate %a${count}${type8} ArrayStride 1\n"
4103 "OpDecorate %a${count}${type16} ArrayStride 2\n"
4104 "OpDecorate %SSBO16 Block\n"
4105 "OpMemberDecorate %SSBO16 0 Offset 0\n"
4106 "OpDecorate %PC8 Block\n"
4107 "OpMemberDecorate %PC8 0 Offset 0\n"
4108 "OpDecorate %ssbo16 DescriptorSet 0\n"
4109 "OpDecorate %ssbo16 Binding 0\n");
4112 map<string, string> specs;
4114 specs["type8"] = "i8";
4115 specs["type16"] = "i16";
4116 specs["signed"] = "1";
4117 specs["count"] = "64";
4118 specs["convert"] = "OpSConvert";
4120 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4122 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
4123 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
4124 string testName = "sint_scalar";
4125 vector<deInt16> constIdxData;
4129 constIdxData.reserve(numDataPoints);
4131 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
4132 constIdxData.push_back(sOutputs[constIdx]);
4135 specs["constarrayidx"] = de::toString(constIdx);
4137 specs["arrayindex"] = "c_i32_ci";
4139 specs["arrayindex"] = "30";
4142 testName += string("_const_idx_") + de::toString(constIdx);
4144 resources.outputs.clear();
4145 resources.outputs.push_back(Resource(BufferSp(new Int16Buffer(useConstIdx ? constIdxData : sOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4147 fragments["testfun"] = testFun.specialize(specs);
4148 fragments["pre_main"] = preMain.specialize(specs);
4149 fragments["decoration"] = decoration.specialize(specs);
4151 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
4155 map<string, string> specs;
4157 specs["type8"] = "u8";
4158 specs["type16"] = "u16";
4159 specs["signed"] = "0";
4160 specs["count"] = "64";
4161 specs["convert"] = "OpUConvert";
4163 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4165 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
4166 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
4167 string testName = "uint_scalar";
4168 vector<deInt16> constIdxData;
4172 constIdxData.reserve(numDataPoints);
4174 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
4175 constIdxData.push_back(uOutputs[constIdx]);
4178 specs["constarrayidx"] = de::toString(constIdx);
4180 specs["arrayindex"] = "c_i32_ci";
4182 specs["arrayindex"] = "30";
4185 testName += string("_const_idx_") + de::toString(constIdx);
4187 resources.outputs.clear();
4188 resources.outputs.push_back(Resource(BufferSp(new Int16Buffer(useConstIdx ? constIdxData : uOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4190 fragments["testfun"] = testFun.specialize(specs);
4191 fragments["pre_main"] = preMain.specialize(specs);
4192 fragments["decoration"] = decoration.specialize(specs);
4194 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
4200 const StringTemplate preMain (
4201 " %${base_type8} = OpTypeInt 8 ${signed}\n"
4202 " %${type8} = OpTypeVector %${base_type8} 2\n"
4203 " %${base_type16} = OpTypeInt 16 ${signed}\n"
4204 " %${type16} = OpTypeVector %${base_type16} 2\n"
4205 " %c_i32_${count} = OpConstant %i32 ${count}\n"
4206 " %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
4207 "%a${count}${type8} = OpTypeArray %${type8} %c_i32_${count}\n"
4208 "%a${count}${type16} = OpTypeArray %${type16} %c_i32_${count}\n"
4209 " %pp_${type8} = OpTypePointer PushConstant %${type8}\n"
4210 " %up_${type16} = OpTypePointer StorageBuffer %${type16}\n"
4211 " %SSBO16 = OpTypeStruct %a${count}${type16}\n"
4212 " %up_SSBO16 = OpTypePointer StorageBuffer %SSBO16\n"
4213 " %ssbo16 = OpVariable %up_SSBO16 StorageBuffer\n"
4214 " %PC8 = OpTypeStruct %a${count}${type8}\n"
4215 " %pp_PC8 = OpTypePointer PushConstant %PC8\n"
4216 " %pc8 = OpVariable %pp_PC8 PushConstant\n");
4218 const StringTemplate decoration (
4219 "OpDecorate %a${count}${type8} ArrayStride 2\n"
4220 "OpDecorate %a${count}${type16} ArrayStride 4\n"
4221 "OpDecorate %SSBO16 Block\n"
4222 "OpMemberDecorate %SSBO16 0 Offset 0\n"
4223 "OpDecorate %PC8 Block\n"
4224 "OpMemberDecorate %PC8 0 Offset 0\n"
4225 "OpDecorate %ssbo16 DescriptorSet 0\n"
4226 "OpDecorate %ssbo16 Binding 0\n");
4229 map<string, string> specs;
4231 specs["base_type8"] = "i8";
4232 specs["base_type16"] = "i16";
4233 specs["type8"] = "v2i8";
4234 specs["type16"] = "v2i16";
4235 specs["signed"] = "1";
4236 specs["count"] = "32"; // 64 / 2
4237 specs["convert"] = "OpSConvert";
4239 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4241 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
4242 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
4243 string testName = "sint_vector";
4244 vector<deInt16> constIdxData;
4248 constIdxData.reserve(numDataPoints);
4250 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
4251 constIdxData.push_back(sOutputs[constIdx * 2 + numIdx % 2]);
4254 specs["constarrayidx"] = de::toString(constIdx);
4256 specs["arrayindex"] = "c_i32_ci";
4258 specs["arrayindex"] = "30";
4261 testName += string("_const_idx_") + de::toString(constIdx);
4263 resources.outputs.clear();
4264 resources.outputs.push_back(Resource(BufferSp(new Int16Buffer(useConstIdx ? constIdxData : sOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4266 fragments["testfun"] = testFun.specialize(specs);
4267 fragments["pre_main"] = preMain.specialize(specs);
4268 fragments["decoration"] = decoration.specialize(specs);
4270 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
4274 map<string, string> specs;
4276 specs["base_type8"] = "u8";
4277 specs["base_type16"] = "u16";
4278 specs["type8"] = "v2u8";
4279 specs["type16"] = "v2u16";
4280 specs["signed"] = "0";
4281 specs["count"] = "32";
4282 specs["convert"] = "OpUConvert";
4284 for (deUint32 constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4286 bool useConstIdx = constantIndices[constIndexIdx].useConstantIndex;
4287 deUint32 constIdx = constantIndices[constIndexIdx].constantIndex;
4288 string testName = "uint_vector";
4289 vector<deInt16> constIdxData;
4293 constIdxData.reserve(numDataPoints);
4295 for (deUint32 numIdx = 0; numIdx < numDataPoints; ++numIdx)
4296 constIdxData.push_back(uOutputs[constIdx * 2 + numIdx % 2]);
4299 specs["constarrayidx"] = de::toString(constIdx);
4301 specs["arrayindex"] = "c_i32_ci";
4303 specs["arrayindex"] = "30";
4306 testName += string("_const_idx_") + de::toString(constIdx);
4308 resources.outputs.clear();
4309 resources.outputs.push_back(Resource(BufferSp(new Int16Buffer(useConstIdx ? constIdxData : uOutputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4311 fragments["testfun"] = testFun.specialize(specs);
4312 fragments["pre_main"] = preMain.specialize(specs);
4313 fragments["decoration"] = decoration.specialize(specs);
4315 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources, extensions, testGroup, requiredFeatures);
4321 void addGraphics8BitStorageUniformStruct8To32Group (tcu::TestCaseGroup* testGroup)
4323 de::Random rnd (deStringHash(testGroup->getName()));
4324 map<string, string> fragments;
4325 vector<string> extensions;
4326 RGBA defaultColors[4];
4327 const StringTemplate capabilities ("OpCapability ${cap}\n");
4328 vector<deInt32> i32Data = data32bit(SHADERTEMPLATE_STRIDE32BIT_STD430, rnd, false);
4330 extensions.push_back("VK_KHR_8bit_storage");
4331 fragments["extension"] = "OpExtension \"SPV_KHR_8bit_storage\"\n"
4332 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
4334 getDefaultColors(defaultColors);
4336 const StringTemplate preMain (
4338 "%i8 = OpTypeInt 8 ${signed}\n"
4339 "%v2i8 = OpTypeVector %i8 2\n"
4340 "%v3i8 = OpTypeVector %i8 3\n"
4341 "%v4i8 = OpTypeVector %i8 4\n"
4342 "%i8ptr = OpTypePointer ${8Storage} %i8\n"
4343 "%v2i8ptr = OpTypePointer ${8Storage} %v2i8\n"
4344 "%v3i8ptr = OpTypePointer ${8Storage} %v3i8\n"
4345 "%v4i8ptr = OpTypePointer ${8Storage} %v4i8\n"
4347 "%i32ptr = OpTypePointer ${32Storage} %${32type}\n"
4348 "%v2i32ptr = OpTypePointer ${32Storage} %v2${32type}\n"
4349 "%v3i32ptr = OpTypePointer ${32Storage} %v3${32type}\n"
4350 "%v4i32ptr = OpTypePointer ${32Storage} %v4${32type}\n"
4352 "%zero = OpConstant %i32 0\n"
4353 "%c_i32_5 = OpConstant %i32 5\n"
4354 "%c_i32_6 = OpConstant %i32 6\n"
4355 "%c_i32_7 = OpConstant %i32 7\n"
4356 "%c_i32_8 = OpConstant %i32 8\n"
4357 "%c_i32_9 = OpConstant %i32 9\n"
4358 "%c_i32_11 = OpConstant %i32 11\n"
4360 "%c_u32_7 = OpConstant %u32 7\n"
4361 "%c_u32_11 = OpConstant %u32 11\n"
4363 "%i8arr3 = OpTypeArray %i8 %c_u32_3\n"
4364 "%v2i8arr3 = OpTypeArray %v2i8 %c_u32_3\n"
4365 "%v2i8arr11 = OpTypeArray %v2i8 %c_u32_11\n"
4366 "%v3i8arr11 = OpTypeArray %v3i8 %c_u32_11\n"
4367 "%v4i8arr3 = OpTypeArray %v4i8 %c_u32_3\n"
4368 "%struct8 = OpTypeStruct %i8 %v2i8arr3\n"
4369 "%struct8arr11 = OpTypeArray %struct8 %c_u32_11\n"
4370 "%i8Struct = OpTypeStruct %i8 %v2i8 %v3i8 %v4i8 %i8arr3 %struct8arr11 %v2i8arr11 %i8 %v3i8arr11 %v4i8arr3\n"
4372 "%i32arr3 = OpTypeArray %${32type} %c_u32_3\n"
4373 "%v2i32arr3 = OpTypeArray %v2${32type} %c_u32_3\n"
4374 "%v2i32arr11 = OpTypeArray %v2${32type} %c_u32_11\n"
4375 "%v3i32arr11 = OpTypeArray %v3${32type} %c_u32_11\n"
4376 "%v4i32arr3 = OpTypeArray %v4${32type} %c_u32_3\n"
4377 "%struct32 = OpTypeStruct %${32type} %v2i32arr3\n"
4378 "%struct32arr11 = OpTypeArray %struct32 %c_u32_11\n"
4379 "%i32Struct = OpTypeStruct %${32type} %v2${32type} %v3${32type} %v4${32type} %i32arr3 %struct32arr11 %v2i32arr11 %${32type} %v3i32arr11 %v4i32arr3\n"
4381 "%i8StructArr7 = OpTypeArray %i8Struct %c_u32_7\n"
4382 "%i32StructArr7 = OpTypeArray %i32Struct %c_u32_7\n"
4383 "%SSBO_IN = OpTypeStruct %i8StructArr7\n"
4384 "%SSBO_OUT = OpTypeStruct %i32StructArr7\n"
4385 "%up_SSBOIN = OpTypePointer ${8Storage} %SSBO_IN\n"
4386 "%up_SSBOOUT = OpTypePointer ${32Storage} %SSBO_OUT\n"
4387 "%ssboIN = OpVariable %up_SSBOIN ${8Storage}\n"
4388 "%ssboOUT = OpVariable %up_SSBOOUT ${32Storage}\n"
4391 const StringTemplate decoration (
4396 "OpDecorate %SSBO_IN Block\n"
4397 "OpDecorate %SSBO_OUT Block\n"
4398 "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
4399 "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
4400 "OpDecorate %ssboIN DescriptorSet 0\n"
4401 "OpDecorate %ssboOUT DescriptorSet 0\n"
4402 "OpDecorate %ssboIN Binding 0\n"
4403 "OpDecorate %ssboOUT Binding 1\n"
4406 const StringTemplate testFun (
4407 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
4408 " %param = OpFunctionParameter %v4f32\n"
4409 "%label = OpLabel\n"
4410 "%loopNdx = OpVariable %fp_i32 Function\n"
4411 "%insideLoopNdx = OpVariable %fp_i32 Function\n"
4413 "OpStore %loopNdx %zero\n"
4416 "OpLoopMerge %merge %13 None\n"
4419 "%valLoopNdx = OpLoad %i32 %loopNdx\n"
4420 "%18 = OpSLessThan %bool %valLoopNdx %c_i32_7\n"
4421 "OpBranchConditional %18 %11 %merge\n"
4424 "%i8src = OpAccessChain %i8ptr %ssboIN %zero %valLoopNdx %zero\n"
4425 "%val_i8 = OpLoad %i8 %i8src\n"
4426 "%val_i32 = ${convert} %${32type} %val_i8\n"
4427 "%i32dst = OpAccessChain %i32ptr %ssboOUT %zero %valLoopNdx %zero\n"
4428 "OpStore %i32dst %val_i32\n"
4430 "%v2i8src = OpAccessChain %v2i8ptr %ssboIN %zero %valLoopNdx %c_i32_1\n"
4431 "%val_v2i8 = OpLoad %v2i8 %v2i8src\n"
4432 "%val_v2i32 = ${convert} %v2${32type} %val_v2i8\n"
4433 "%v2i32dst = OpAccessChain %v2i32ptr %ssboOUT %zero %valLoopNdx %c_i32_1\n"
4434 "OpStore %v2i32dst %val_v2i32\n"
4436 "%v3i8src = OpAccessChain %v3i8ptr %ssboIN %zero %valLoopNdx %c_i32_2\n"
4437 "%val_v3i8 = OpLoad %v3i8 %v3i8src\n"
4438 "%val_v3i32 = ${convert} %v3${32type} %val_v3i8\n"
4439 "%v3i32dst = OpAccessChain %v3i32ptr %ssboOUT %zero %valLoopNdx %c_i32_2\n"
4440 "OpStore %v3i32dst %val_v3i32\n"
4442 "%v4i8src = OpAccessChain %v4i8ptr %ssboIN %zero %valLoopNdx %c_i32_3\n"
4443 "%val_v4i8 = OpLoad %v4i8 %v4i8src\n"
4444 "%val_v4i32 = ${convert} %v4${32type} %val_v4i8\n"
4445 "%v4i32dst = OpAccessChain %v4i32ptr %ssboOUT %zero %valLoopNdx %c_i32_3\n"
4446 "OpStore %v4i32dst %val_v4i32\n"
4448 "%i8src2 = OpAccessChain %i8ptr %ssboIN %zero %valLoopNdx %c_i32_7\n"
4449 "%val2_i8 = OpLoad %i8 %i8src2\n"
4450 "%val2_i32 = ${convert} %${32type} %val2_i8\n"
4451 "%i32dst2 = OpAccessChain %i32ptr %ssboOUT %zero %valLoopNdx %c_i32_7\n"
4452 "OpStore %i32dst2 %val2_i32\n"
4454 "OpStore %insideLoopNdx %zero\n"
4455 "OpBranch %loopInside\n"
4456 "%loopInside = OpLabel\n"
4457 "OpLoopMerge %92 %93 None\n"
4460 "%valInsideLoopNdx = OpLoad %i32 %insideLoopNdx\n"
4461 "%96 = OpSLessThan %bool %valInsideLoopNdx %c_i32_11\n"
4462 "OpBranchConditional %96 %91 %92\n"
4466 "%v2i8src2 = OpAccessChain %v2i8ptr %ssboIN %zero %valLoopNdx %c_i32_6 %valInsideLoopNdx\n"
4467 "%val2_v2i8 = OpLoad %v2i8 %v2i8src2\n"
4468 "%val2_v2i32 = ${convert} %v2${32type} %val2_v2i8\n"
4469 "%v2i32dst2 = OpAccessChain %v2i32ptr %ssboOUT %zero %valLoopNdx %c_i32_6 %valInsideLoopNdx\n"
4470 "OpStore %v2i32dst2 %val2_v2i32\n"
4472 "%v3i8src2 = OpAccessChain %v3i8ptr %ssboIN %zero %valLoopNdx %c_i32_8 %valInsideLoopNdx\n"
4473 "%val2_v3i8 = OpLoad %v3i8 %v3i8src2\n"
4474 "%val2_v3i32 = ${convert} %v3${32type} %val2_v3i8\n"
4475 "%v3i32dst2 = OpAccessChain %v3i32ptr %ssboOUT %zero %valLoopNdx %c_i32_8 %valInsideLoopNdx\n"
4476 "OpStore %v3i32dst2 %val2_v3i32\n"
4478 //struct {i8, v2i8[3]}
4479 "%Si8src = OpAccessChain %i8ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %zero\n"
4480 "%Sval_i8 = OpLoad %i8 %Si8src\n"
4481 "%Sval_i32 = ${convert} %${32type} %Sval_i8\n"
4482 "%Si32dst2 = OpAccessChain %i32ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %zero\n"
4483 "OpStore %Si32dst2 %Sval_i32\n"
4485 "%Sv2i8src0 = OpAccessChain %v2i8ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %zero\n"
4486 "%Sv2i8_0 = OpLoad %v2i8 %Sv2i8src0\n"
4487 "%Sv2i32_0 = ${convert} %v2${32type} %Sv2i8_0\n"
4488 "%Sv2i32dst_0 = OpAccessChain %v2i32ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %zero\n"
4489 "OpStore %Sv2i32dst_0 %Sv2i32_0\n"
4491 "%Sv2i8src1 = OpAccessChain %v2i8ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_1\n"
4492 "%Sv2i8_1 = OpLoad %v2i8 %Sv2i8src1\n"
4493 "%Sv2i32_1 = ${convert} %v2${32type} %Sv2i8_1\n"
4494 "%Sv2i32dst_1 = OpAccessChain %v2i32ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_1\n"
4495 "OpStore %Sv2i32dst_1 %Sv2i32_1\n"
4497 "%Sv2i8src2 = OpAccessChain %v2i8ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_2\n"
4498 "%Sv2i8_2 = OpLoad %v2i8 %Sv2i8src2\n"
4499 "%Sv2i32_2 = ${convert} %v2${32type} %Sv2i8_2\n"
4500 "%Sv2i32dst_2 = OpAccessChain %v2i32ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_2\n"
4501 "OpStore %Sv2i32dst_2 %Sv2i32_2\n"
4503 //Array with 3 elements
4504 "%LessThan3 = OpSLessThan %bool %valInsideLoopNdx %c_i32_3\n"
4505 "OpSelectionMerge %BlockIf None\n"
4506 "OpBranchConditional %LessThan3 %LabelIf %BlockIf\n"
4507 "%LabelIf = OpLabel\n"
4508 " %i8src3 = OpAccessChain %i8ptr %ssboIN %zero %valLoopNdx %c_i32_4 %valInsideLoopNdx\n"
4509 " %val3_i8 = OpLoad %i8 %i8src3\n"
4510 " %val3_i32 = ${convert} %${32type} %val3_i8\n"
4511 " %i32dst3 = OpAccessChain %i32ptr %ssboOUT %zero %valLoopNdx %c_i32_4 %valInsideLoopNdx\n"
4512 " OpStore %i32dst3 %val3_i32\n"
4514 " %v4i8src2 = OpAccessChain %v4i8ptr %ssboIN %zero %valLoopNdx %c_i32_9 %valInsideLoopNdx\n"
4515 " %val2_v4i8 = OpLoad %v4i8 %v4i8src2\n"
4516 " %val2_v4i32 = ${convert} %v4${32type} %val2_v4i8\n"
4517 " %v4i32dst2 = OpAccessChain %v4i32ptr %ssboOUT %zero %valLoopNdx %c_i32_9 %valInsideLoopNdx\n"
4518 " OpStore %v4i32dst2 %val2_v4i32\n"
4519 "OpBranch %BlockIf\n"
4520 "%BlockIf = OpLabel\n"
4524 "%132 = OpLoad %i32 %insideLoopNdx\n"
4525 "%133 = OpIAdd %i32 %132 %c_i32_1\n"
4526 "OpStore %insideLoopNdx %133\n"
4527 "OpBranch %loopInside\n"
4532 "%134 = OpLoad %i32 %loopNdx\n"
4533 "%135 = OpIAdd %i32 %134 %c_i32_1\n"
4534 "OpStore %loopNdx %135\n"
4537 "%merge = OpLabel\n"
4538 " OpReturnValue %param\n"
4539 " OpFunctionEnd\n");
4545 const char* signedInt;
4549 const IntegerFacts intFacts[] =
4551 {"sint", "OpSConvert", "1", "i32"},
4552 {"uint", "OpUConvert", "0", "u32"},
4555 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
4556 for (deUint32 intFactsNdx = 0; intFactsNdx < DE_LENGTH_OF_ARRAY(intFacts); ++intFactsNdx)
4558 const bool isUniform = (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == CAPABILITIES[capIdx].dtype);
4559 vector<deInt8> i8Data = isUniform ? data8bit(SHADERTEMPLATE_STRIDE8BIT_STD140, rnd) : data8bit(SHADERTEMPLATE_STRIDE8BIT_STD430, rnd);
4560 GraphicsResources resources;
4561 map<string, string> specs;
4562 VulkanFeatures features;
4563 const string testName = string(CAPABILITIES[capIdx].name) + "_" + intFacts[intFactsNdx].name;
4565 specs["cap"] = CAPABILITIES[capIdx].cap;
4566 specs["stridei8"] = getStructShaderComponet(isUniform ? SHADERTEMPLATE_STRIDE8BIT_STD140 : SHADERTEMPLATE_STRIDE8BIT_STD430);
4567 specs["stridei32"] = getStructShaderComponet(SHADERTEMPLATE_STRIDE32BIT_STD430);
4568 specs["32Storage"] = "StorageBuffer";
4569 specs["8Storage"] = isUniform ? "Uniform" : "StorageBuffer";
4570 specs["signed"] = intFacts[intFactsNdx].signedInt;
4571 specs["convert"] = intFacts[intFactsNdx].opcode;
4572 specs["32type"] = intFacts[intFactsNdx].type32;
4574 fragments["capability"] = capabilities.specialize(specs);
4575 fragments["decoration"] = decoration.specialize(specs);
4576 fragments["pre_main"] = preMain.specialize(specs);
4577 fragments["testfun"] = testFun.specialize(specs);
4579 resources.inputs.push_back(Resource(BufferSp(new Int8Buffer(i8Data)), CAPABILITIES[capIdx].dtype));
4580 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(i32Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4582 resources.verifyIO = checkStruct<deInt8, deInt32, SHADERTEMPLATE_STRIDE8BIT_STD140, SHADERTEMPLATE_STRIDE32BIT_STD430>;
4584 resources.verifyIO = checkStruct<deInt8, deInt32, SHADERTEMPLATE_STRIDE8BIT_STD430, SHADERTEMPLATE_STRIDE32BIT_STD430>;
4586 features = get8BitStorageFeatures(CAPABILITIES[capIdx].name);
4587 features.coreFeatures.vertexPipelineStoresAndAtomics = true;
4588 features.coreFeatures.fragmentStoresAndAtomics = true;
4590 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, features);
4594 void addGraphics8BitStorageUniformStruct32To8Group (tcu::TestCaseGroup* testGroup)
4596 de::Random rnd (deStringHash(testGroup->getName()));
4597 map<string, string> fragments;
4598 vector<string> extensions;
4599 RGBA defaultColors[4];
4600 const StringTemplate capabilities ("OpCapability ${cap}\n");
4601 vector<deInt8> i8Data = data8bit(SHADERTEMPLATE_STRIDE8BIT_STD430, rnd, false);
4603 extensions.push_back("VK_KHR_8bit_storage");
4604 fragments["extension"] = "OpExtension \"SPV_KHR_8bit_storage\"\n"
4605 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
4607 getDefaultColors(defaultColors);
4609 const StringTemplate preMain (
4611 "%i8 = OpTypeInt 8 ${signed}\n"
4612 "%v2i8 = OpTypeVector %i8 2\n"
4613 "%v3i8 = OpTypeVector %i8 3\n"
4614 "%v4i8 = OpTypeVector %i8 4\n"
4615 "%i8ptr = OpTypePointer ${8Storage} %i8\n"
4616 "%v2i8ptr = OpTypePointer ${8Storage} %v2i8\n"
4617 "%v3i8ptr = OpTypePointer ${8Storage} %v3i8\n"
4618 "%v4i8ptr = OpTypePointer ${8Storage} %v4i8\n"
4620 "%i32ptr = OpTypePointer ${32Storage} %${32type}\n"
4621 "%v2i32ptr = OpTypePointer ${32Storage} %v2${32type}\n"
4622 "%v3i32ptr = OpTypePointer ${32Storage} %v3${32type}\n"
4623 "%v4i32ptr = OpTypePointer ${32Storage} %v4${32type}\n"
4625 "%zero = OpConstant %i32 0\n"
4626 "%c_i32_5 = OpConstant %i32 5\n"
4627 "%c_i32_6 = OpConstant %i32 6\n"
4628 "%c_i32_7 = OpConstant %i32 7\n"
4629 "%c_i32_8 = OpConstant %i32 8\n"
4630 "%c_i32_9 = OpConstant %i32 9\n"
4631 "%c_i32_11 = OpConstant %i32 11\n"
4633 "%c_u32_7 = OpConstant %u32 7\n"
4634 "%c_u32_11 = OpConstant %u32 11\n"
4636 "%i8arr3 = OpTypeArray %i8 %c_u32_3\n"
4637 "%v2i8arr3 = OpTypeArray %v2i8 %c_u32_3\n"
4638 "%v2i8arr11 = OpTypeArray %v2i8 %c_u32_11\n"
4639 "%v3i8arr11 = OpTypeArray %v3i8 %c_u32_11\n"
4640 "%v4i8arr3 = OpTypeArray %v4i8 %c_u32_3\n"
4641 "%struct8 = OpTypeStruct %i8 %v2i8arr3\n"
4642 "%struct8arr11 = OpTypeArray %struct8 %c_u32_11\n"
4643 "%i8Struct = OpTypeStruct %i8 %v2i8 %v3i8 %v4i8 %i8arr3 %struct8arr11 %v2i8arr11 %i8 %v3i8arr11 %v4i8arr3\n"
4645 "%i32arr3 = OpTypeArray %${32type} %c_u32_3\n"
4646 "%v2i32arr3 = OpTypeArray %v2${32type} %c_u32_3\n"
4647 "%v2i32arr11 = OpTypeArray %v2${32type} %c_u32_11\n"
4648 "%v3i32arr11 = OpTypeArray %v3${32type} %c_u32_11\n"
4649 "%v4i32arr3 = OpTypeArray %v4${32type} %c_u32_3\n"
4650 "%struct32 = OpTypeStruct %${32type} %v2i32arr3\n"
4651 "%struct32arr11 = OpTypeArray %struct32 %c_u32_11\n"
4652 "%i32Struct = OpTypeStruct %${32type} %v2${32type} %v3${32type} %v4${32type} %i32arr3 %struct32arr11 %v2i32arr11 %${32type} %v3i32arr11 %v4i32arr3\n"
4654 "%i8StructArr7 = OpTypeArray %i8Struct %c_u32_7\n"
4655 "%i32StructArr7 = OpTypeArray %i32Struct %c_u32_7\n"
4656 "%SSBO_IN = OpTypeStruct %i32StructArr7\n"
4657 "%SSBO_OUT = OpTypeStruct %i8StructArr7\n"
4658 "%up_SSBOIN = OpTypePointer ${32Storage} %SSBO_IN\n"
4659 "%up_SSBOOUT = OpTypePointer ${8Storage} %SSBO_OUT\n"
4660 "%ssboIN = OpVariable %up_SSBOIN ${32Storage}\n"
4661 "%ssboOUT = OpVariable %up_SSBOOUT ${8Storage}\n"
4664 const StringTemplate decoration (
4669 "OpDecorate %SSBO_IN Block\n"
4670 "OpDecorate %SSBO_OUT Block\n"
4671 "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
4672 "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
4673 "OpDecorate %ssboIN DescriptorSet 0\n"
4674 "OpDecorate %ssboOUT DescriptorSet 0\n"
4675 "OpDecorate %ssboIN Binding 0\n"
4676 "OpDecorate %ssboOUT Binding 1\n"
4679 const StringTemplate testFun (
4680 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
4681 "%param = OpFunctionParameter %v4f32\n"
4682 "%label = OpLabel\n"
4683 "%loopNdx = OpVariable %fp_i32 Function\n"
4684 "%insideLoopNdx = OpVariable %fp_i32 Function\n"
4686 "OpStore %loopNdx %zero\n"
4689 "OpLoopMerge %merge %13 None\n"
4692 "%valLoopNdx = OpLoad %i32 %loopNdx\n"
4693 "%18 = OpSLessThan %bool %valLoopNdx %c_i32_7\n"
4694 "OpBranchConditional %18 %11 %merge\n"
4697 "%i32src = OpAccessChain %i32ptr %ssboIN %zero %valLoopNdx %zero\n"
4698 "%val_i32 = OpLoad %${32type} %i32src\n"
4699 "%val_i8 = ${convert} %i8 %val_i32\n"
4700 "%i8dst = OpAccessChain %i8ptr %ssboOUT %zero %valLoopNdx %zero\n"
4701 "OpStore %i8dst %val_i8\n"
4703 "%v2i32src = OpAccessChain %v2i32ptr %ssboIN %zero %valLoopNdx %c_i32_1\n"
4704 "%val_v2i32 = OpLoad %v2${32type} %v2i32src\n"
4705 "%val_v2i8 = ${convert} %v2i8 %val_v2i32\n"
4706 "%v2i8dst = OpAccessChain %v2i8ptr %ssboOUT %zero %valLoopNdx %c_i32_1\n"
4707 "OpStore %v2i8dst %val_v2i8\n"
4709 "%v3i32src = OpAccessChain %v3i32ptr %ssboIN %zero %valLoopNdx %c_i32_2\n"
4710 "%val_v3i32 = OpLoad %v3${32type} %v3i32src\n"
4711 "%val_v3i8 = ${convert} %v3i8 %val_v3i32\n"
4712 "%v3i8dst = OpAccessChain %v3i8ptr %ssboOUT %zero %valLoopNdx %c_i32_2\n"
4713 "OpStore %v3i8dst %val_v3i8\n"
4715 "%v4i32src = OpAccessChain %v4i32ptr %ssboIN %zero %valLoopNdx %c_i32_3\n"
4716 "%val_v4i32 = OpLoad %v4${32type} %v4i32src\n"
4717 "%val_v4i8 = ${convert} %v4i8 %val_v4i32\n"
4718 "%v4i8dst = OpAccessChain %v4i8ptr %ssboOUT %zero %valLoopNdx %c_i32_3\n"
4719 "OpStore %v4i8dst %val_v4i8\n"
4721 "%i32src2 = OpAccessChain %i32ptr %ssboIN %zero %valLoopNdx %c_i32_7\n"
4722 "%val2_i32 = OpLoad %${32type} %i32src2\n"
4723 "%val2_i8 = ${convert} %i8 %val2_i32\n"
4724 "%i8dst2 = OpAccessChain %i8ptr %ssboOUT %zero %valLoopNdx %c_i32_7\n"
4725 "OpStore %i8dst2 %val2_i8\n"
4727 "OpStore %insideLoopNdx %zero\n"
4728 "OpBranch %loopInside\n"
4729 "%loopInside = OpLabel\n"
4730 "OpLoopMerge %92 %93 None\n"
4733 "%valInsideLoopNdx = OpLoad %i32 %insideLoopNdx\n"
4734 "%96 = OpSLessThan %bool %valInsideLoopNdx %c_i32_11\n"
4735 "OpBranchConditional %96 %91 %92\n"
4739 //struct {i8, v2i8[3]}
4740 "%Si32src = OpAccessChain %i32ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %zero\n"
4741 "%Sval_i32 = OpLoad %${32type} %Si32src\n"
4742 "%Sval_i8 = ${convert} %i8 %Sval_i32\n"
4743 "%Si8dst2 = OpAccessChain %i8ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %zero\n"
4744 "OpStore %Si8dst2 %Sval_i8\n"
4746 "%Sv2i32src0 = OpAccessChain %v2i32ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %zero\n"
4747 "%Sv2i32_0 = OpLoad %v2${32type} %Sv2i32src0\n"
4748 "%Sv2i8_0 = ${convert} %v2i8 %Sv2i32_0\n"
4749 "%Sv2i8dst_0 = OpAccessChain %v2i8ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %zero\n"
4750 "OpStore %Sv2i8dst_0 %Sv2i8_0\n"
4752 "%Sv2i32src1 = OpAccessChain %v2i32ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_1\n"
4753 "%Sv2i32_1 = OpLoad %v2${32type} %Sv2i32src1\n"
4754 "%Sv2i8_1 = ${convert} %v2i8 %Sv2i32_1\n"
4755 "%Sv2i8dst_1 = OpAccessChain %v2i8ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_1\n"
4756 "OpStore %Sv2i8dst_1 %Sv2i8_1\n"
4758 "%Sv2i32src2 = OpAccessChain %v2i32ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_2\n"
4759 "%Sv2i32_2 = OpLoad %v2${32type} %Sv2i32src2\n"
4760 "%Sv2i8_2 = ${convert} %v2i8 %Sv2i32_2\n"
4761 "%Sv2i8dst_2 = OpAccessChain %v2i8ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_2\n"
4762 "OpStore %Sv2i8dst_2 %Sv2i8_2\n"
4765 "%v2i32src2 = OpAccessChain %v2i32ptr %ssboIN %zero %valLoopNdx %c_i32_6 %valInsideLoopNdx\n"
4766 "%val2_v2i32 = OpLoad %v2${32type} %v2i32src2\n"
4767 "%val2_v2i8 = ${convert} %v2i8 %val2_v2i32\n"
4768 "%v2i8dst2 = OpAccessChain %v2i8ptr %ssboOUT %zero %valLoopNdx %c_i32_6 %valInsideLoopNdx\n"
4769 "OpStore %v2i8dst2 %val2_v2i8\n"
4771 "%v3i32src2 = OpAccessChain %v3i32ptr %ssboIN %zero %valLoopNdx %c_i32_8 %valInsideLoopNdx\n"
4772 "%val2_v3i32 = OpLoad %v3${32type} %v3i32src2\n"
4773 "%val2_v3i8 = ${convert} %v3i8 %val2_v3i32\n"
4774 "%v3i8dst2 = OpAccessChain %v3i8ptr %ssboOUT %zero %valLoopNdx %c_i32_8 %valInsideLoopNdx\n"
4775 "OpStore %v3i8dst2 %val2_v3i8\n"
4778 //Array with 3 elements
4779 "%LessThan3 = OpSLessThan %bool %valInsideLoopNdx %c_i32_3\n"
4780 "OpSelectionMerge %BlockIf None\n"
4781 "OpBranchConditional %LessThan3 %LabelIf %BlockIf\n"
4782 " %LabelIf = OpLabel\n"
4783 " %i32src3 = OpAccessChain %i32ptr %ssboIN %zero %valLoopNdx %c_i32_4 %valInsideLoopNdx\n"
4784 " %val3_i32 = OpLoad %${32type} %i32src3\n"
4785 " %val3_i8 = ${convert} %i8 %val3_i32\n"
4786 " %i8dst3 = OpAccessChain %i8ptr %ssboOUT %zero %valLoopNdx %c_i32_4 %valInsideLoopNdx\n"
4787 " OpStore %i8dst3 %val3_i8\n"
4789 " %v4i32src2 = OpAccessChain %v4i32ptr %ssboIN %zero %valLoopNdx %c_i32_9 %valInsideLoopNdx\n"
4790 " %val2_v4i32 = OpLoad %v4${32type} %v4i32src2\n"
4791 " %val2_v4i8 = ${convert} %v4i8 %val2_v4i32\n"
4792 " %v4i8dst2 = OpAccessChain %v4i8ptr %ssboOUT %zero %valLoopNdx %c_i32_9 %valInsideLoopNdx\n"
4793 " OpStore %v4i8dst2 %val2_v4i8\n"
4794 "OpBranch %BlockIf\n"
4795 "%BlockIf = OpLabel\n"
4799 "%132 = OpLoad %i32 %insideLoopNdx\n"
4800 "%133 = OpIAdd %i32 %132 %c_i32_1\n"
4801 "OpStore %insideLoopNdx %133\n"
4802 "OpBranch %loopInside\n"
4807 "%134 = OpLoad %i32 %loopNdx\n"
4808 "%135 = OpIAdd %i32 %134 %c_i32_1\n"
4809 "OpStore %loopNdx %135\n"
4812 "%merge = OpLabel\n"
4813 " OpReturnValue %param\n"
4814 " OpFunctionEnd\n");
4820 const char* signedInt;
4824 const IntegerFacts intFacts[] =
4826 {"sint", "OpSConvert", "1", "i32"},
4827 {"uint", "OpUConvert", "0", "u32"},
4830 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
4831 for (deUint32 intFactsNdx = 0; intFactsNdx < DE_LENGTH_OF_ARRAY(intFacts); ++intFactsNdx)
4833 const bool isUniform = (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == CAPABILITIES[capIdx].dtype);
4834 map<string, string> specs;
4835 string testName = string(CAPABILITIES[capIdx].name) + "_" + intFacts[intFactsNdx].name;
4836 vector<deInt32> i32Data = isUniform ? data32bit(SHADERTEMPLATE_STRIDE32BIT_STD140, rnd) : data32bit(SHADERTEMPLATE_STRIDE32BIT_STD430, rnd);
4837 GraphicsResources resources;
4838 VulkanFeatures features;
4840 specs["cap"] = CAPABILITIES[STORAGE_BUFFER_TEST].cap;
4841 specs["stridei8"] = getStructShaderComponet(SHADERTEMPLATE_STRIDE8BIT_STD430);
4842 specs["stridei32"] = getStructShaderComponet(isUniform ? SHADERTEMPLATE_STRIDE32BIT_STD140 : SHADERTEMPLATE_STRIDE32BIT_STD430);
4843 specs["8Storage"] = "StorageBuffer";
4844 specs["32Storage"] = isUniform ? "Uniform" : "StorageBuffer";
4845 specs["signed"] = intFacts[intFactsNdx].signedInt;
4846 specs["convert"] = intFacts[intFactsNdx].opcode;
4847 specs["32type"] = intFacts[intFactsNdx].type32;
4849 fragments["capability"] = capabilities.specialize(specs);
4850 fragments["decoration"] = decoration.specialize(specs);
4851 fragments["pre_main"] = preMain.specialize(specs);
4852 fragments["testfun"] = testFun.specialize(specs);
4854 resources.inputs.push_back(Resource(BufferSp(new Int32Buffer(i32Data)), CAPABILITIES[capIdx].dtype));
4855 resources.outputs.push_back(Resource(BufferSp(new Int8Buffer(i8Data)), CAPABILITIES[STORAGE_BUFFER_TEST].dtype));
4857 resources.verifyIO = checkStruct<deInt32, deInt8, SHADERTEMPLATE_STRIDE32BIT_STD140, SHADERTEMPLATE_STRIDE8BIT_STD430>;
4859 resources.verifyIO = checkStruct<deInt32, deInt8, SHADERTEMPLATE_STRIDE32BIT_STD430, SHADERTEMPLATE_STRIDE8BIT_STD430>;
4861 features = get8BitStorageFeatures(CAPABILITIES[STORAGE_BUFFER_TEST].name);
4862 features.coreFeatures.vertexPipelineStoresAndAtomics = true;
4863 features.coreFeatures.fragmentStoresAndAtomics = true;
4865 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup, features);
4869 void addGraphics8bitStorage8bitStructMixedTypesGroup (tcu::TestCaseGroup* group)
4871 de::Random rnd (deStringHash(group->getName()));
4872 map<string, string> fragments;
4873 vector<string> extensions;
4874 RGBA defaultColors[4];
4875 const StringTemplate capabilities ("OpCapability StorageBuffer8BitAccess\n"
4877 vector<deInt8> outData = data8bit(SHADERTEMPLATE_STRIDEMIX_STD430, rnd, false);
4879 extensions.push_back("VK_KHR_8bit_storage");
4880 fragments["extension"] = "OpExtension \"SPV_KHR_8bit_storage\"\n"
4881 "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
4883 getDefaultColors(defaultColors);
4885 const StringTemplate preMain (
4887 "%i8 = OpTypeInt 8 1\n"
4888 "%v2i8 = OpTypeVector %i8 2\n"
4889 "%v3i8 = OpTypeVector %i8 3\n"
4890 "%v4i8 = OpTypeVector %i8 4\n"
4892 "%zero = OpConstant %i32 0\n"
4893 "%c_i32_5 = OpConstant %i32 5\n"
4894 "%c_i32_6 = OpConstant %i32 6\n"
4895 "%c_i32_7 = OpConstant %i32 7\n"
4896 "%c_i32_8 = OpConstant %i32 8\n"
4897 "%c_i32_9 = OpConstant %i32 9\n"
4898 "%c_i32_10 = OpConstant %i32 10\n"
4899 "%c_i32_11 = OpConstant %i32 11\n"
4900 "%c_u32_7 = OpConstant %u32 7\n"
4901 "%c_u32_11 = OpConstant %u32 11\n"
4902 "\n"//Arrays & Structs
4903 "%v2b8NestedArr11In = OpTypeArray %v2i8 %c_u32_11\n"
4904 "%b32NestedArr11In = OpTypeArray %i32 %c_u32_11\n"
4905 "%sb8Arr11In = OpTypeArray %i8 %c_u32_11\n"
4906 "%sb32Arr11In = OpTypeArray %i32 %c_u32_11\n"
4907 "%sNestedIn = OpTypeStruct %i8 %i32 %v2b8NestedArr11In %b32NestedArr11In\n"
4908 "%sNestedArr11In = OpTypeArray %sNestedIn %c_u32_11\n"
4909 "%structIn = OpTypeStruct %i8 %i32 %v2i8 %v2i32 %v3i8 %v3i32 %v4i8 %v4i32 %sNestedArr11In %sb8Arr11In %sb32Arr11In\n"
4910 "%structArr7In = OpTypeArray %structIn %c_u32_7\n"
4911 "%v2b8NestedArr11Out = OpTypeArray %v2i8 %c_u32_11\n"
4912 "%b32NestedArr11Out = OpTypeArray %i32 %c_u32_11\n"
4913 "%sb8Arr11Out = OpTypeArray %i8 %c_u32_11\n"
4914 "%sb32Arr11Out = OpTypeArray %i32 %c_u32_11\n"
4915 "%sNestedOut = OpTypeStruct %i8 %i32 %v2b8NestedArr11Out %b32NestedArr11Out\n"
4916 "%sNestedArr11Out = OpTypeArray %sNestedOut %c_u32_11\n"
4917 "%structOut = OpTypeStruct %i8 %i32 %v2i8 %v2i32 %v3i8 %v3i32 %v4i8 %v4i32 %sNestedArr11Out %sb8Arr11Out %sb32Arr11Out\n"
4918 "%structArr7Out = OpTypeArray %structOut %c_u32_7\n"
4921 "%i8outPtr = OpTypePointer StorageBuffer %i8\n"
4922 "%v2i8outPtr = OpTypePointer StorageBuffer %v2i8\n"
4923 "%v3i8outPtr = OpTypePointer StorageBuffer %v3i8\n"
4924 "%v4i8outPtr = OpTypePointer StorageBuffer %v4i8\n"
4925 "%i32outPtr = OpTypePointer StorageBuffer %i32\n"
4926 "%v2i32outPtr = OpTypePointer StorageBuffer %v2i32\n"
4927 "%v3i32outPtr = OpTypePointer StorageBuffer %v3i32\n"
4928 "%v4i32outPtr = OpTypePointer StorageBuffer %v4i32\n"
4929 "%uvec3ptr = OpTypePointer Input %v3u32\n"
4931 "%SSBO_IN = OpTypeStruct %structArr7In\n"
4932 "%up_SSBOIN = OpTypePointer ${inStorage} %SSBO_IN\n"
4933 "%ssboIN = OpVariable %up_SSBOIN ${inStorage}\n"
4935 "%SSBO_OUT = OpTypeStruct %structArr7Out\n"
4936 "%up_SSBOOUT = OpTypePointer StorageBuffer %SSBO_OUT\n"
4937 "%ssboOUT = OpVariable %up_SSBOOUT StorageBuffer\n");
4939 const StringTemplate decoration (
4943 "OpDecorate %SSBO_IN Block\n"
4944 "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
4945 "OpDecorate %ssboIN DescriptorSet 0\n"
4946 "OpDecorate %ssboIN Binding 0\n"
4948 "OpDecorate %SSBO_OUT Block\n"
4949 "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
4950 "OpDecorate %ssboOUT DescriptorSet 0\n"
4951 "OpDecorate %ssboOUT Binding 1\n");
4953 const StringTemplate testFun (
4954 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
4955 "%param = OpFunctionParameter %v4f32\n"
4956 "%label = OpLabel\n"
4957 "%ndxArrx = OpVariable %fp_i32 Function\n"
4958 "%ndxArry = OpVariable %fp_i32 Function\n"
4959 "%ndxArrz = OpVariable %fp_i32 Function\n"
4961 "\n"//strutOut.b8 = strutIn.b8
4962 "%inP1 = OpAccessChain %i8${inPtr} %ssboIN %zero %Valx %zero\n"
4963 "%inV1 = OpLoad %i8 %inP1\n"
4964 "%outP1 = OpAccessChain %i8outPtr %ssboOUT %zero %Valx %zero\n"
4965 "OpStore %outP1 %inV1\n"
4966 "\n"//strutOut.b32 = strutIn.b32
4967 "%inP2 = OpAccessChain %i32${inPtr} %ssboIN %zero %Valx %c_i32_1\n"
4968 "%inV2 = OpLoad %i32 %inP2\n"
4969 "%outP2 = OpAccessChain %i32outPtr %ssboOUT %zero %Valx %c_i32_1\n"
4970 "OpStore %outP2 %inV2\n"
4971 "\n"//strutOut.v2b8 = strutIn.v2b8
4972 "%inP3 = OpAccessChain %v2i8${inPtr} %ssboIN %zero %Valx %c_i32_2\n"
4973 "%inV3 = OpLoad %v2i8 %inP3\n"
4974 "%outP3 = OpAccessChain %v2i8outPtr %ssboOUT %zero %Valx %c_i32_2\n"
4975 "OpStore %outP3 %inV3\n"
4976 "\n"//strutOut.v2b32 = strutIn.v2b32
4977 "%inP4 = OpAccessChain %v2i32${inPtr} %ssboIN %zero %Valx %c_i32_3\n"
4978 "%inV4 = OpLoad %v2i32 %inP4\n"
4979 "%outP4 = OpAccessChain %v2i32outPtr %ssboOUT %zero %Valx %c_i32_3\n"
4980 "OpStore %outP4 %inV4\n"
4981 "\n"//strutOut.v3b8 = strutIn.v3b8
4982 "%inP5 = OpAccessChain %v3i8${inPtr} %ssboIN %zero %Valx %c_i32_4\n"
4983 "%inV5 = OpLoad %v3i8 %inP5\n"
4984 "%outP5 = OpAccessChain %v3i8outPtr %ssboOUT %zero %Valx %c_i32_4\n"
4985 "OpStore %outP5 %inV5\n"
4986 "\n"//strutOut.v3b32 = strutIn.v3b32
4987 "%inP6 = OpAccessChain %v3i32${inPtr} %ssboIN %zero %Valx %c_i32_5\n"
4988 "%inV6 = OpLoad %v3i32 %inP6\n"
4989 "%outP6 = OpAccessChain %v3i32outPtr %ssboOUT %zero %Valx %c_i32_5\n"
4990 "OpStore %outP6 %inV6\n"
4991 "\n"//strutOut.v4b8 = strutIn.v4b8
4992 "%inP7 = OpAccessChain %v4i8${inPtr} %ssboIN %zero %Valx %c_i32_6\n"
4993 "%inV7 = OpLoad %v4i8 %inP7\n"
4994 "%outP7 = OpAccessChain %v4i8outPtr %ssboOUT %zero %Valx %c_i32_6\n"
4995 "OpStore %outP7 %inV7\n"
4996 "\n"//strutOut.v4b32 = strutIn.v4b32
4997 "%inP8 = OpAccessChain %v4i32${inPtr} %ssboIN %zero %Valx %c_i32_7\n"
4998 "%inV8 = OpLoad %v4i32 %inP8\n"
4999 "%outP8 = OpAccessChain %v4i32outPtr %ssboOUT %zero %Valx %c_i32_7\n"
5000 "OpStore %outP8 %inV8\n"
5002 "\n"//strutOut.b8[y] = strutIn.b8[y]
5003 "%inP9 = OpAccessChain %i8${inPtr} %ssboIN %zero %Valx %c_i32_9 %Valy\n"
5004 "%inV9 = OpLoad %i8 %inP9\n"
5005 "%outP9 = OpAccessChain %i8outPtr %ssboOUT %zero %Valx %c_i32_9 %Valy\n"
5006 "OpStore %outP9 %inV9\n"
5007 "\n"//strutOut.b32[y] = strutIn.b32[y]
5008 "%inP10 = OpAccessChain %i32${inPtr} %ssboIN %zero %Valx %c_i32_10 %Valy\n"
5009 "%inV10 = OpLoad %i32 %inP10\n"
5010 "%outP10 = OpAccessChain %i32outPtr %ssboOUT %zero %Valx %c_i32_10 %Valy\n"
5011 "OpStore %outP10 %inV10\n"
5012 "\n"//strutOut.strutNestedOut[y].b8 = strutIn.strutNestedIn[y].b8
5013 "%inP11 = OpAccessChain %i8${inPtr} %ssboIN %zero %Valx %c_i32_8 %Valy %zero\n"
5014 "%inV11 = OpLoad %i8 %inP11\n"
5015 "%outP11 = OpAccessChain %i8outPtr %ssboOUT %zero %Valx %c_i32_8 %Valy %zero\n"
5016 "OpStore %outP11 %inV11\n"
5017 "\n"//strutOut.strutNestedOut[y].b32 = strutIn.strutNestedIn[y].b32
5018 "%inP12 = OpAccessChain %i32${inPtr} %ssboIN %zero %Valx %c_i32_8 %Valy %c_i32_1\n"
5019 "%inV12 = OpLoad %i32 %inP12\n"
5020 "%outP12 = OpAccessChain %i32outPtr %ssboOUT %zero %Valx %c_i32_8 %Valy %c_i32_1\n"
5021 "OpStore %outP12 %inV12\n"
5023 "\n"//strutOut.strutNestedOut[y].v2b8[valNdx] = strutIn.strutNestedIn[y].v2b8[valNdx]
5024 "%inP13 = OpAccessChain %v2i8${inPtr} %ssboIN %zero %Valx %c_i32_8 %Valy %c_i32_2 %Valz\n"
5025 "%inV13 = OpLoad %v2i8 %inP13\n"
5026 "%outP13 = OpAccessChain %v2i8outPtr %ssboOUT %zero %Valx %c_i32_8 %Valy %c_i32_2 %Valz\n"
5027 "OpStore %outP13 %inV13\n"
5028 "\n"//strutOut.strutNestedOut[y].b32[valNdx] = strutIn.strutNestedIn[y].b32[valNdx]
5029 "%inP14 = OpAccessChain %i32${inPtr} %ssboIN %zero %Valx %c_i32_8 %Valy %c_i32_3 %Valz\n"
5030 "%inV14 = OpLoad %i32 %inP14\n"
5031 "%outP14 = OpAccessChain %i32outPtr %ssboOUT %zero %Valx %c_i32_8 %Valy %c_i32_3 %Valz\n"
5032 "OpStore %outP14 %inV14\n"
5037 "OpBranch %ExitLabel\n"
5038 "%ExitLabel = OpLabel\n"
5039 "OpReturnValue %param\n"
5042 for (deUint32 capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
5044 const bool isUniform = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == CAPABILITIES[capIdx].dtype;
5045 vector<deInt8> inData = isUniform ? data8bit(SHADERTEMPLATE_STRIDEMIX_STD140, rnd) : data8bit(SHADERTEMPLATE_STRIDEMIX_STD430, rnd);
5046 GraphicsResources resources;
5047 map<string, string> specsLoop;
5048 map<string, string> specsOffset;
5049 map<string, string> specs;
5050 VulkanFeatures features;
5051 string testName = string(CAPABILITIES[capIdx].name);
5053 specsLoop["exeCount"] = "c_i32_7";
5054 specsLoop["loopName"] = "x";
5055 specs["xBeginLoop"] = beginLoop(specsLoop);
5056 specs["xEndLoop"] = endLoop(specsLoop);
5058 specsLoop["exeCount"] = "c_i32_11";
5059 specsLoop["loopName"] = "y";
5060 specs["yBeginLoop"] = beginLoop(specsLoop);
5061 specs["yEndLoop"] = endLoop(specsLoop);
5063 specsLoop["exeCount"] = "c_i32_11";
5064 specsLoop["loopName"] = "z";
5065 specs["zBeginLoop"] = beginLoop(specsLoop);
5066 specs["zEndLoop"] = endLoop(specsLoop);
5068 specs["inStorage"] = isUniform ? "Uniform" : "StorageBuffer";
5069 specs["cap"] = isUniform ?"OpCapability " + string( CAPABILITIES[capIdx].cap) : "";
5070 specs["uniformPtr"] = isUniform ?
5071 "%i8inPtr = OpTypePointer Uniform %i8\n"
5072 "%v2i8inPtr = OpTypePointer Uniform %v2i8\n"
5073 "%v3i8inPtr = OpTypePointer Uniform %v3i8\n"
5074 "%v4i8inPtr = OpTypePointer Uniform %v4i8\n"
5075 "%i32inPtr = OpTypePointer Uniform %i32\n"
5076 "%v2i32inPtr = OpTypePointer Uniform %v2i32\n"
5077 "%v3i32inPtr = OpTypePointer Uniform %v3i32\n"
5078 "%v4i32inPtr = OpTypePointer Uniform %v4i32\n" :
5080 specs["inPtr"] = isUniform ? "inPtr" : "outPtr";
5081 specsOffset["InOut"] = "In";
5082 specs["InOffsets"] = StringTemplate(isUniform ? getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD140) : getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD430)).specialize(specsOffset);
5083 specsOffset["InOut"] = "Out";
5084 specs["OutOffsets"] = StringTemplate(getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD430)).specialize(specsOffset);
5086 fragments["capability"] = capabilities.specialize(specs);
5087 fragments["decoration"] = decoration.specialize(specs);
5088 fragments["pre_main"] = preMain.specialize(specs);
5089 fragments["testfun"] = testFun.specialize(specs);
5091 resources.verifyIO = isUniform ? checkStruct<deInt8, deInt8, SHADERTEMPLATE_STRIDEMIX_STD140, SHADERTEMPLATE_STRIDEMIX_STD430> : checkStruct<deInt8, deInt8, SHADERTEMPLATE_STRIDEMIX_STD430, SHADERTEMPLATE_STRIDEMIX_STD430>;
5092 resources.inputs.push_back(Resource(BufferSp(new Int8Buffer(inData)), CAPABILITIES[capIdx].dtype));
5093 resources.outputs.push_back(Resource(BufferSp(new Int8Buffer(outData)), CAPABILITIES[STORAGE_BUFFER_TEST].dtype));
5095 features = get8BitStorageFeatures(CAPABILITIES[capIdx].name);
5096 features.coreFeatures.vertexPipelineStoresAndAtomics = true;
5097 features.coreFeatures.fragmentStoresAndAtomics = true;
5099 createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, group, features);
5105 tcu::TestCaseGroup* create8BitStorageComputeGroup (tcu::TestContext& testCtx)
5107 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "8bit_storage", "Compute tests for VK_KHR_8bit_storage extension"));
5109 addTestGroup(group.get(), "storagebuffer_32_to_8", "32bit ints to 8bit tests under capability StorageBuffer8BitAccess", addCompute8bitStorage32To8Group);
5110 addTestGroup(group.get(), "uniform_8_to_32", "8bit ints to 32bit tests under capability UniformAndStorageBuffer8BitAccess", addCompute8bitUniform8To32Group);
5111 addTestGroup(group.get(), "push_constant_8_to_32", "8bit ints to 32bit tests under capability StoragePushConstant8", addCompute8bitStoragePushConstant8To32Group);
5113 addTestGroup(group.get(), "storagebuffer_16_to_8", "16bit ints to 8bit tests under capability StorageBuffer8BitAccess", addCompute8bitStorage16To8Group);
5114 addTestGroup(group.get(), "uniform_8_to_16", "8bit ints to 16bit tests under capability UniformAndStorageBuffer8BitAccess", addCompute8bitUniform8To16Group);
5115 addTestGroup(group.get(), "push_constant_8_to_16", "8bit ints to 16bit tests under capability StoragePushConstant8", addCompute8bitStoragePushConstant8To16Group);
5117 addTestGroup(group.get(), "uniform_8_to_8", "8bit ints to 8bit tests under capability UniformAndStorageBuffer8BitAccess", addCompute8bitStorageBuffer8To8Group);
5119 addTestGroup(group.get(), "uniform_8struct_to_32struct", "8bit floats struct to 32bit tests under capability UniformAndStorageBuffer8BitAccess", addCompute8bitStorageUniform8StructTo32StructGroup);
5120 addTestGroup(group.get(), "storagebuffer_32struct_to_8struct", "32bit floats struct to 8bit tests under capability StorageBuffer8BitAccess", addCompute8bitStorageUniform32StructTo8StructGroup);
5121 addTestGroup(group.get(), "struct_mixed_types", "mixed type of 8bit and 32bit struct", addCompute8bitStorage8bitStructMixedTypesGroup);
5123 return group.release();
5126 tcu::TestCaseGroup* create8BitStorageGraphicsGroup (tcu::TestContext& testCtx)
5128 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "8bit_storage", "Graphics tests for VK_KHR_8bit_storage extension"));
5130 addTestGroup(group.get(), "storagebuffer_int_32_to_8", "32-bit int into 8-bit tests under capability StorageBuffer8BitAccess", addGraphics8BitStorageUniformInt32To8Group);
5131 addTestGroup(group.get(), "uniform_int_8_to_32", "8-bit int into 32-bit tests under capability UniformAndStorageBuffer8BitAccess", addGraphics8BitStorageUniformInt8To32Group);
5132 addTestGroup(group.get(), "push_constant_int_8_to_32", "8-bit int into 32-bit tests under capability StoragePushConstant8", addGraphics8BitStoragePushConstantInt8To32Group);
5134 addTestGroup(group.get(), "storagebuffer_int_16_to_8", "16-bit int into 8-bit tests under capability StorageBuffer8BitAccess", addGraphics8BitStorageUniformInt16To8Group);
5135 addTestGroup(group.get(), "uniform_int_8_to_16", "8-bit int into 16-bit tests under capability UniformAndStorageBuffer8BitAccess", addGraphics8BitStorageUniformInt8To16Group);
5136 addTestGroup(group.get(), "push_constant_int_8_to_16", "8-bit int into 16-bit tests under capability StoragePushConstant8", addGraphics8BitStoragePushConstantInt8To16Group);
5138 addTestGroup(group.get(), "8struct_to_32struct", "8bit floats struct to 32bit tests ", addGraphics8BitStorageUniformStruct8To32Group);
5139 addTestGroup(group.get(), "32struct_to_8struct", "32bit floats struct to 8bit tests ", addGraphics8BitStorageUniformStruct32To8Group);
5140 addTestGroup(group.get(), "struct_mixed_types", "mixed type of 8bit and 32bit struc", addGraphics8bitStorage8bitStructMixedTypesGroup);
5142 return group.release();