1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief SPIR-V Assembly Tests for the VK_KHR_8bit_storage
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSpvAsm8bitStorageTests.hpp"
25 
26 #include "tcuFloat.hpp"
27 #include "tcuRGBA.hpp"
28 #include "tcuStringTemplate.hpp"
29 #include "tcuTestLog.hpp"
30 #include "tcuVectorUtil.hpp"
31 
32 #include "vkDefs.hpp"
33 #include "vkDeviceUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkPlatform.hpp"
36 #include "vkPrograms.hpp"
37 #include "vkQueryUtil.hpp"
38 #include "vkRef.hpp"
39 #include "vkRefUtil.hpp"
40 #include "vkStrUtil.hpp"
41 #include "vkTypeUtil.hpp"
42 
43 #include "deRandom.hpp"
44 #include "deStringUtil.hpp"
45 #include "deUniquePtr.hpp"
46 #include "deMath.h"
47 
48 #include "vktSpvAsmComputeShaderCase.hpp"
49 #include "vktSpvAsmComputeShaderTestUtil.hpp"
50 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
51 #include "vktTestCaseUtil.hpp"
52 #include "vktTestGroupUtil.hpp"
53 
54 #include <limits>
55 #include <map>
56 #include <string>
57 #include <sstream>
58 #include <utility>
59 
60 namespace vkt
61 {
62 namespace SpirVAssembly
63 {
64 
65 using namespace vk;
66 using de::UniquePtr;
67 using std::map;
68 using std::string;
69 using std::vector;
70 using tcu::IVec3;
71 using tcu::IVec4;
72 using tcu::RGBA;
73 using tcu::StringTemplate;
74 using tcu::TestLog;
75 using tcu::TestStatus;
76 using tcu::Vec4;
77 
78 namespace
79 {
80 static const uint32_t arrayStrideInBytesUniform = 16u; // from the spec
81 
82 enum ShaderTemplate
83 {
84     SHADERTEMPLATE_STRIDE8BIT_STD140 = 0,
85     SHADERTEMPLATE_STRIDE32BIT_STD140,
86     SHADERTEMPLATE_STRIDEMIX_STD140,
87     SHADERTEMPLATE_STRIDE8BIT_STD430,
88     SHADERTEMPLATE_STRIDE32BIT_STD430,
89     SHADERTEMPLATE_STRIDEMIX_STD430
90 };
91 
92 struct StructTestData
93 {
94     const int structArraySize; //Size of Struct Array
95     const int nestedArraySize; //Max size of any nested arrays
96 };
97 
98 struct Capability
99 {
100     const char *name;
101     const char *cap;
102     const char *decor;
103     vk::VkDescriptorType dtype;
104 };
105 
106 enum
107 {
108     STORAGE_BUFFER_TEST = 0,
109     UNIFORM_AND_STORAGEBUFFER_TEST
110 };
111 
112 static const Capability CAPABILITIES[] = {
113     {"storage_buffer", "StorageBuffer8BitAccess", "StorageBuffer", VK_DESCRIPTOR_TYPE_STORAGE_BUFFER},
114     {"uniform", "UniformAndStorageBuffer8BitAccess", "Block", VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER},
115 };
116 
117 static const StructTestData structData = {7, 11};
118 
getStructSize(const ShaderTemplate shaderTemplate)119 int getStructSize(const ShaderTemplate shaderTemplate)
120 {
121     switch (shaderTemplate)
122     {
123     case SHADERTEMPLATE_STRIDE8BIT_STD140:
124         return 1184 * structData.structArraySize; //size of struct in 8b with offsets
125     case SHADERTEMPLATE_STRIDE32BIT_STD140:
126         return 304 * structData.structArraySize; //size of struct in 32b with offsets
127     case SHADERTEMPLATE_STRIDEMIX_STD140:
128         return 4480 * structData.structArraySize; //size of struct in 8b with offsets
129     case SHADERTEMPLATE_STRIDE8BIT_STD430:
130         return 224 * structData.structArraySize; //size of struct in 8b with offset
131     case SHADERTEMPLATE_STRIDE32BIT_STD430:
132         return 184 * structData.structArraySize; //size of struct in 32b with offset
133     case SHADERTEMPLATE_STRIDEMIX_STD430:
134         return 976 * structData.structArraySize; //size of struct in 8b with offset
135     default:
136         DE_ASSERT(0);
137     }
138     return 0;
139 }
140 
get8BitStorageFeatures(const char * cap)141 VulkanFeatures get8BitStorageFeatures(const char *cap)
142 {
143     VulkanFeatures features;
144     if (string(cap) == "storage_buffer")
145         features.ext8BitStorage.storageBuffer8BitAccess = true;
146     else if (string(cap) == "uniform")
147         features.ext8BitStorage.uniformAndStorageBuffer8BitAccess = true;
148     else if (string(cap) == "push_constant")
149         features.ext8BitStorage.storagePushConstant8 = true;
150     else
151         DE_ASSERT(false && "not supported");
152 
153     return features;
154 }
155 
computeCheckBuffers(const std::vector<Resource> & originalInts,const vector<AllocationSp> & outputAllocs,const std::vector<Resource> &,tcu::TestLog &)156 bool computeCheckBuffers(const std::vector<Resource> &originalInts, const vector<AllocationSp> &outputAllocs,
157                          const std::vector<Resource> & /*expectedOutputs*/, tcu::TestLog & /*log*/)
158 {
159     std::vector<uint8_t> result;
160     originalInts.front().getBytes(result);
161     return deMemCmp(&result[0], outputAllocs.front()->getHostPtr(), result.size()) == 0;
162 }
163 
addInfo(vector<bool> & info,int & ndx,const int count,const bool isData)164 void addInfo(vector<bool> &info, int &ndx, const int count, const bool isData)
165 {
166     for (int index = 0; index < count; ++index)
167         info[ndx++] = isData;
168 }
169 
data8bit(const ShaderTemplate std,de::Random & rnd,const bool isData=true)170 vector<int8_t> data8bit(const ShaderTemplate std, de::Random &rnd, const bool isData = true)
171 {
172     const int size = getStructSize(std);
173     if (!isData)
174         return vector<int8_t>(size, 0);
175     return getInt8s(rnd, size);
176 }
177 
data32bit(const ShaderTemplate std,de::Random & rnd,const bool isData=true)178 vector<int32_t> data32bit(const ShaderTemplate std, de::Random &rnd, const bool isData = true)
179 {
180     const int size = getStructSize(std);
181     if (!isData)
182         return vector<int32_t>(size, 0);
183     return getInt32s(rnd, size);
184 }
185 
info8bitStd140(void)186 vector<bool> info8bitStd140(void)
187 {
188     int ndx = 0u;
189     vector<bool> infoData(getStructSize(SHADERTEMPLATE_STRIDE8BIT_STD140));
190 
191     for (int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
192     {
193         infoData[ndx++] = true;  //i8
194         infoData[ndx++] = false; //offset
195 
196         infoData[ndx++] = true; //v2i8
197         infoData[ndx++] = true; //v2i8
198 
199         addInfo(infoData, ndx, 3, true); //v3i8
200         infoData[ndx++] = false;         //offset
201 
202         addInfo(infoData, ndx, 4, true);  //v4i8
203         addInfo(infoData, ndx, 4, false); //offset
204 
205         //i8[3];
206         for (int i = 0; i < 3; ++i)
207         {
208             infoData[ndx++] = true;            //i8[i];
209             addInfo(infoData, ndx, 15, false); //offset
210         }
211 
212         //struct {i8, v2i8[3]} [11]
213         for (int i = 0; i < 11; ++i)
214         {
215             //struct.i8
216             infoData[ndx++] = true;            //i8
217             addInfo(infoData, ndx, 15, false); //offset
218             //struct.v2i8[3]
219             for (int j = 0; j < 3; ++j)
220             {
221                 infoData[ndx++] = true;            //v2i8
222                 infoData[ndx++] = true;            //v2i8
223                 addInfo(infoData, ndx, 14, false); //offset
224             }
225         }
226 
227         //v2i8[11];
228         for (int i = 0; i < 11; ++i)
229         {
230             infoData[ndx++] = true;            //v2i8
231             infoData[ndx++] = true;            //v2i8
232             addInfo(infoData, ndx, 14, false); //offset
233         }
234 
235         //i8
236         infoData[ndx++] = true;            //i8
237         addInfo(infoData, ndx, 15, false); //offset
238 
239         //v3i8[11]
240         for (int i = 0; i < 11; ++i)
241         {
242             addInfo(infoData, ndx, 3, true);   //v3i8
243             addInfo(infoData, ndx, 13, false); //offset
244         }
245 
246         //v4i8[3]
247         for (int i = 0; i < 3; ++i)
248         {
249             addInfo(infoData, ndx, 4, true);   //v4i8
250             addInfo(infoData, ndx, 12, false); //offset
251         }
252     }
253 
254     //Please check the data and offset
255     DE_ASSERT(ndx == static_cast<int>(infoData.size()));
256 
257     return infoData;
258 }
259 
info8bitStd430(void)260 vector<bool> info8bitStd430(void)
261 {
262     int ndx = 0u;
263     vector<bool> infoData(getStructSize(SHADERTEMPLATE_STRIDE8BIT_STD430));
264 
265     for (int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
266     {
267         infoData[ndx++] = true;  //i8
268         infoData[ndx++] = false; //offset
269 
270         infoData[ndx++] = true; //v2i8
271         infoData[ndx++] = true; //v2i8
272 
273         addInfo(infoData, ndx, 3, true); //v3i8
274         infoData[ndx++] = false;         //offset
275 
276         addInfo(infoData, ndx, 4, true);  //v4i8
277         addInfo(infoData, ndx, 4, false); //offset
278 
279         //i8[3];
280         for (int i = 0; i < 3; ++i)
281         {
282             infoData[ndx++] = true; //i8;
283         }
284         addInfo(infoData, ndx, 13, false); //offset
285 
286         //struct {i8, v2i8[3]} [11]
287         for (int i = 0; i < 11; ++i)
288         {
289             //struct.i8
290             infoData[ndx++] = true;  //i8
291             infoData[ndx++] = false; //offset
292             //struct.v2i8[3]
293             for (int j = 0; j < 3; ++j)
294             {
295                 infoData[ndx++] = true; //v2i8
296                 infoData[ndx++] = true; //v2i8
297             }
298         }
299         addInfo(infoData, ndx, 8, false); //offset
300 
301         //vec2[11];
302         for (int i = 0; i < 11; ++i)
303         {
304             infoData[ndx++] = true; //v2i8
305             infoData[ndx++] = true; //v2i8
306         }
307 
308         //i8
309         infoData[ndx++] = true;           //i8
310         addInfo(infoData, ndx, 9, false); //offset
311 
312         //v3i8[11]
313         for (int i = 0; i < 11; ++i)
314         {
315             addInfo(infoData, ndx, 3, true); //v3i8
316             infoData[ndx++] = false;         //offset
317         }
318         addInfo(infoData, ndx, 4, false); //offset
319 
320         //v4i8[3]
321         for (int i = 0; i < 3; ++i)
322         {
323             addInfo(infoData, ndx, 4, true); //v4i8
324         }
325         addInfo(infoData, ndx, 4, false); //offset
326     }
327 
328     //Please check the data and offset
329     DE_ASSERT(ndx == static_cast<int>(infoData.size()));
330     return infoData;
331 }
332 
info32bitStd140(void)333 vector<bool> info32bitStd140(void)
334 {
335     int ndx = 0u;
336     vector<bool> infoData(getStructSize(SHADERTEMPLATE_STRIDE32BIT_STD140));
337 
338     for (int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
339     {
340         infoData[ndx++] = true;  //i32
341         infoData[ndx++] = false; //offset
342 
343         infoData[ndx++] = true; //v2i32
344         infoData[ndx++] = true; //v2i32
345 
346         addInfo(infoData, ndx, 3, true); //v3i32
347         infoData[ndx++] = false;         //offset
348 
349         addInfo(infoData, ndx, 4, true); //v4i32
350 
351         //i32[3];
352         for (int i = 0; i < 3; ++i)
353         {
354             infoData[ndx++] = true;           //i32;
355             addInfo(infoData, ndx, 3, false); //offset
356         }
357 
358         //struct {i32, v2i32[3]} [11]
359         for (int i = 0; i < 11; ++i)
360         {
361             //struct.f32
362             infoData[ndx++] = true;           //i32
363             addInfo(infoData, ndx, 3, false); //offset
364             //struct.f32.v2f16[3]
365             for (int j = 0; j < 3; ++j)
366             {
367                 infoData[ndx++] = true;  //v2i32
368                 infoData[ndx++] = true;  //v2i32
369                 infoData[ndx++] = false; //offset
370                 infoData[ndx++] = false; //offset
371             }
372         }
373 
374         //v2f32[11];
375         for (int i = 0; i < 11; ++i)
376         {
377             infoData[ndx++] = true;  //v2i32
378             infoData[ndx++] = true;  //v2i32
379             infoData[ndx++] = false; //offset
380             infoData[ndx++] = false; //offset
381         }
382 
383         //i32
384         infoData[ndx++] = true;           //i32
385         addInfo(infoData, ndx, 3, false); //offset
386 
387         //v3i32[11]
388         for (int i = 0; i < 11; ++i)
389         {
390             addInfo(infoData, ndx, 3, true); //v3i32
391             infoData[ndx++] = false;         //offset
392         }
393 
394         //v4i32[3]
395         for (int i = 0; i < 3; ++i)
396         {
397             addInfo(infoData, ndx, 4, true); //v4i32
398         }
399     }
400 
401     //Please check the data and offset
402     DE_ASSERT(ndx == static_cast<int>(infoData.size()));
403     return infoData;
404 }
405 
info32bitStd430(void)406 vector<bool> info32bitStd430(void)
407 {
408     int ndx = 0u;
409     vector<bool> infoData(getStructSize(SHADERTEMPLATE_STRIDE32BIT_STD430));
410 
411     for (int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
412     {
413         infoData[ndx++] = true;  //i32
414         infoData[ndx++] = false; //offset
415 
416         addInfo(infoData, ndx, 2, true); //v2i32
417 
418         addInfo(infoData, ndx, 3, true); //v3i32
419         infoData[ndx++] = false;         //offset
420 
421         addInfo(infoData, ndx, 4, true); //v4i32
422 
423         addInfo(infoData, ndx, 3, true); //i32[3];
424         infoData[ndx++] = false;         //offset
425 
426         //struct {i32, v2i32[3]} [11]
427         for (int i = 0; i < 11; ++i)
428         {
429             //struct.i32
430             infoData[ndx++] = true;          //i32
431             infoData[ndx++] = false;         //offset
432             addInfo(infoData, ndx, 6, true); //v2i32[3]
433         }
434 
435         addInfo(infoData, ndx, 22, true); //v2i32[11];
436 
437         //i32
438         infoData[ndx++] = true;  //i32
439         infoData[ndx++] = false; //offset
440 
441         //v3i32[11]
442         for (int i = 0; i < 11; ++i)
443         {
444             addInfo(infoData, ndx, 3, true); //v3i32
445             infoData[ndx++] = false;         //offset
446         }
447 
448         addInfo(infoData, ndx, 12, true); //v4i32[3]
449     }
450 
451     //Please check the data and offset
452     DE_ASSERT(ndx == static_cast<int>(infoData.size()));
453     return infoData;
454 }
455 
infoMixStd140(void)456 vector<bool> infoMixStd140(void)
457 {
458     int ndx = 0u;
459     vector<bool> infoData(getStructSize(SHADERTEMPLATE_STRIDEMIX_STD140));
460     for (int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
461     {
462         infoData[ndx++] = true;           //8b
463         addInfo(infoData, ndx, 3, false); //offset
464 
465         addInfo(infoData, ndx, 4, true); //32b
466 
467         addInfo(infoData, ndx, 2, true);  //v2b8
468         addInfo(infoData, ndx, 6, false); //offset
469 
470         addInfo(infoData, ndx, 8, true); //v2b32
471 
472         addInfo(infoData, ndx, 3, true);  //v3b8
473         addInfo(infoData, ndx, 5, false); //offset
474 
475         addInfo(infoData, ndx, 12, true); //v3b32
476         addInfo(infoData, ndx, 4, false); //offset
477 
478         addInfo(infoData, ndx, 4, true);   //v4b8
479         addInfo(infoData, ndx, 12, false); //offset
480 
481         addInfo(infoData, ndx, 16, true); //v4b32
482 
483         //strut {b8, b32, v2b8[11], b32[11]}
484         for (int i = 0; i < structData.nestedArraySize; ++i)
485         {
486             infoData[ndx++] = true;           //8b
487             addInfo(infoData, ndx, 3, false); //offset
488 
489             addInfo(infoData, ndx, 4, true);  //32b
490             addInfo(infoData, ndx, 8, false); //offset
491 
492             for (int j = 0; j < structData.nestedArraySize; ++j)
493             {
494                 addInfo(infoData, ndx, 2, true);   //v2b8[11]
495                 addInfo(infoData, ndx, 14, false); //offset
496             }
497 
498             for (int j = 0; j < structData.nestedArraySize; ++j)
499             {
500                 addInfo(infoData, ndx, 4, true);   //b32[11]
501                 addInfo(infoData, ndx, 12, false); //offset
502             }
503         }
504 
505         for (int i = 0; i < structData.nestedArraySize; ++i)
506         {
507             infoData[ndx++] = true;            //8b[11]
508             addInfo(infoData, ndx, 15, false); //offset
509         }
510 
511         for (int i = 0; i < structData.nestedArraySize; ++i)
512         {
513             addInfo(infoData, ndx, 4, true);   //b32bIn[11]
514             addInfo(infoData, ndx, 12, false); //offset
515         }
516     }
517 
518     //Please check the data and offset
519     DE_ASSERT(ndx == static_cast<int>(infoData.size()));
520     return infoData;
521 }
522 
infoMixStd430(void)523 vector<bool> infoMixStd430(void)
524 {
525     int ndx = 0u;
526     vector<bool> infoData(getStructSize(SHADERTEMPLATE_STRIDEMIX_STD430));
527     for (int elementNdx = 0; elementNdx < structData.structArraySize; ++elementNdx)
528     {
529         infoData[ndx++] = true;           //8b
530         addInfo(infoData, ndx, 3, false); //offset
531 
532         addInfo(infoData, ndx, 4, true); //32b
533 
534         addInfo(infoData, ndx, 2, true);  //v2b8
535         addInfo(infoData, ndx, 6, false); //offset
536 
537         addInfo(infoData, ndx, 8, true); //v2b32
538 
539         addInfo(infoData, ndx, 3, true);  //v3b8
540         addInfo(infoData, ndx, 5, false); //offset
541 
542         addInfo(infoData, ndx, 12, true); //v3b32
543         addInfo(infoData, ndx, 4, false); //offset
544 
545         addInfo(infoData, ndx, 4, true);   //v4b8
546         addInfo(infoData, ndx, 12, false); //offset
547 
548         addInfo(infoData, ndx, 16, true); //v4b32
549 
550         //strut {b8, b32, v2b8[11], b32[11]}
551         for (int i = 0; i < structData.nestedArraySize; ++i)
552         {
553             infoData[ndx++] = true;           //8b
554             addInfo(infoData, ndx, 3, false); //offset
555 
556             addInfo(infoData, ndx, 4, true); //32b
557 
558             addInfo(infoData, ndx, 22, true); //v2b8[11]
559             addInfo(infoData, ndx, 2, false); //offset
560 
561             addInfo(infoData, ndx, 44, true); //b32[11]
562         }
563 
564         addInfo(infoData, ndx, 11, true); //8b[11]
565         infoData[ndx++] = false;          //offset
566 
567         addInfo(infoData, ndx, 44, true); //32b[11]
568         addInfo(infoData, ndx, 4, false); //offset
569     }
570 
571     //Please check the data and offset
572     DE_ASSERT(ndx == static_cast<int>(infoData.size()));
573     return infoData;
574 }
575 
576 template <typename originType, typename resultType, ShaderTemplate funcOrigin, ShaderTemplate funcResult>
compareStruct(const resultType * returned,const originType * original)577 bool compareStruct(const resultType *returned, const originType *original)
578 {
579     vector<bool> resultInfo;
580     vector<bool> originInfo;
581     vector<resultType> resultToCompare;
582     vector<originType> originToCompare;
583 
584     switch (funcOrigin)
585     {
586     case SHADERTEMPLATE_STRIDE8BIT_STD140:
587         originInfo = info8bitStd140();
588         break;
589     case SHADERTEMPLATE_STRIDE8BIT_STD430:
590         originInfo = info8bitStd430();
591         break;
592     case SHADERTEMPLATE_STRIDE32BIT_STD140:
593         originInfo = info32bitStd140();
594         break;
595     case SHADERTEMPLATE_STRIDE32BIT_STD430:
596         originInfo = info32bitStd430();
597         break;
598     case SHADERTEMPLATE_STRIDEMIX_STD140:
599         originInfo = infoMixStd140();
600         break;
601     case SHADERTEMPLATE_STRIDEMIX_STD430:
602         originInfo = infoMixStd430();
603         break;
604     default:
605         DE_ASSERT(0);
606     }
607 
608     switch (funcResult)
609     {
610     case SHADERTEMPLATE_STRIDE8BIT_STD140:
611         resultInfo = info8bitStd140();
612         break;
613     case SHADERTEMPLATE_STRIDE8BIT_STD430:
614         resultInfo = info8bitStd430();
615         break;
616     case SHADERTEMPLATE_STRIDE32BIT_STD140:
617         resultInfo = info32bitStd140();
618         break;
619     case SHADERTEMPLATE_STRIDE32BIT_STD430:
620         resultInfo = info32bitStd430();
621         break;
622     case SHADERTEMPLATE_STRIDEMIX_STD140:
623         resultInfo = infoMixStd140();
624         break;
625     case SHADERTEMPLATE_STRIDEMIX_STD430:
626         resultInfo = infoMixStd430();
627         break;
628     default:
629         DE_ASSERT(0);
630     }
631 
632     for (int ndx = 0; ndx < static_cast<int>(resultInfo.size()); ++ndx)
633     {
634         if (resultInfo[ndx])
635             resultToCompare.push_back(returned[ndx]);
636     }
637 
638     for (int ndx = 0; ndx < static_cast<int>(originInfo.size()); ++ndx)
639     {
640         if (originInfo[ndx])
641             originToCompare.push_back(original[ndx]);
642     }
643 
644     //Different offset but that same amount of data
645     DE_ASSERT(originToCompare.size() == resultToCompare.size());
646 
647     for (int ndx = 0; ndx < static_cast<int>(originToCompare.size()); ++ndx)
648     {
649         if (static_cast<int8_t>(originToCompare[ndx]) != static_cast<int8_t>(resultToCompare[ndx]))
650             return false;
651     }
652     return true;
653 }
654 
655 template <typename originType, typename resultType, ShaderTemplate funcOrigin, ShaderTemplate funcResult>
checkStruct(const std::vector<Resource> & originalFloats,const vector<AllocationSp> & outputAllocs,const std::vector<Resource> &,tcu::TestLog &)656 bool checkStruct(const std::vector<Resource> &originalFloats, const vector<AllocationSp> &outputAllocs,
657                  const std::vector<Resource> & /* expectedOutputs */, tcu::TestLog & /* log */)
658 {
659     for (uint32_t outputNdx = 0; outputNdx < outputAllocs.size(); ++outputNdx)
660     {
661         vector<uint8_t> originalBytes;
662         originalFloats[outputNdx].getBytes(originalBytes);
663 
664         const resultType *returned = static_cast<const resultType *>(outputAllocs[outputNdx]->getHostPtr());
665         const originType *original = reinterpret_cast<const originType *>(&originalBytes.front());
666 
667         if (!compareStruct<originType, resultType, funcOrigin, funcResult>(returned, original))
668             return false;
669     }
670     return true;
671 }
672 
673 template <typename originType, typename resultType, uint32_t compositCount>
checkUniformsArray(const std::vector<Resource> & originalFloats,const vector<AllocationSp> & outputAllocs,const std::vector<Resource> &,tcu::TestLog &)674 bool checkUniformsArray(const std::vector<Resource> &originalFloats, const vector<AllocationSp> &outputAllocs,
675                         const std::vector<Resource> & /* expectedOutputs */, tcu::TestLog & /* log */)
676 {
677     const uint32_t originTypeSize = static_cast<uint32_t>(sizeof(originType));
678 
679     DE_ASSERT((originTypeSize * compositCount) <=
680               arrayStrideInBytesUniform); // one element of array can't be bigger then 16B
681 
682     for (uint32_t outputNdx = 0; outputNdx < static_cast<uint32_t>(outputAllocs.size()); ++outputNdx)
683     {
684         vector<uint8_t> originalBytes;
685         originalFloats[outputNdx].getBytes(originalBytes);
686         const int elemntsNumber = (static_cast<int>(originalBytes.size()) / arrayStrideInBytesUniform) / compositCount;
687 
688         const resultType *returned = static_cast<const resultType *>(outputAllocs[outputNdx]->getHostPtr());
689         const originType *original = reinterpret_cast<const originType *>(&originalBytes.front());
690 
691         for (int ndx = 0; ndx < elemntsNumber; ++ndx)
692         {
693             for (uint32_t ndxData = 0u; ndxData < compositCount; ++ndxData)
694             {
695                 if (static_cast<int8_t>(*original) != static_cast<int8_t>(*returned))
696                     return false;
697                 original++;
698                 returned++;
699             }
700             original += arrayStrideInBytesUniform / originTypeSize - compositCount;
701         }
702     }
703     return true;
704 }
705 
706 template <typename originType, typename resultType, int compositCount, int ndxConts>
checkUniformsArrayConstNdx(const std::vector<Resource> & originalFloats,const vector<AllocationSp> & outputAllocs,const std::vector<Resource> &,tcu::TestLog &)707 bool checkUniformsArrayConstNdx(const std::vector<Resource> &originalFloats, const vector<AllocationSp> &outputAllocs,
708                                 const std::vector<Resource> & /* expectedOutputs */, tcu::TestLog & /* log */)
709 {
710     const uint32_t originTypeSize = static_cast<uint32_t>(sizeof(originType));
711 
712     DE_ASSERT((originTypeSize * compositCount) <=
713               arrayStrideInBytesUniform); // one element of array can't be bigger then 16B
714 
715     for (uint32_t outputNdx = 0; outputNdx < static_cast<uint32_t>(outputAllocs.size()); ++outputNdx)
716     {
717         vector<uint8_t> originalBytes;
718         originalFloats[outputNdx].getBytes(originalBytes);
719         const int elemntsNumber = (static_cast<int>(originalBytes.size()) / arrayStrideInBytesUniform) / compositCount;
720 
721         const resultType *returned = static_cast<const resultType *>(outputAllocs[outputNdx]->getHostPtr());
722         const originType *original = reinterpret_cast<const originType *>(&originalBytes.front());
723 
724         uint32_t idx = (arrayStrideInBytesUniform / originTypeSize) * ndxConts;
725 
726         for (int ndx = 0; ndx < elemntsNumber; ++ndx)
727         {
728             for (int ndxData = 0; ndxData < compositCount; ++ndxData)
729             {
730                 if (static_cast<int8_t>(original[idx + ndxData]) != static_cast<int8_t>(*returned))
731                     return false;
732                 returned++;
733             }
734         }
735     }
736     return true;
737 }
738 
getStructShaderComponet(const ShaderTemplate component)739 string getStructShaderComponet(const ShaderTemplate component)
740 {
741     switch (component)
742     {
743     case SHADERTEMPLATE_STRIDE8BIT_STD140:
744         return string(
745             //struct {i8, v2i8[3]} [11]
746             "OpDecorate %v2i8arr3 ArrayStride 16\n"
747             "OpMemberDecorate %struct8 0 Offset 0\n"
748             "OpMemberDecorate %struct8 1 Offset 16\n"
749             "OpDecorate %struct8arr11 ArrayStride 64\n"
750             "\n"
751             "OpDecorate %i8arr3       ArrayStride 16\n"
752             "OpDecorate %v2i8arr11    ArrayStride 16\n"
753             "OpDecorate %v3i8arr11    ArrayStride 16\n"
754             "OpDecorate %v4i8arr3     ArrayStride 16\n"
755             "OpDecorate %i8StructArr7 ArrayStride 1184\n"
756             "\n"
757             "OpMemberDecorate %i8Struct 0 Offset 0\n"      //i8
758             "OpMemberDecorate %i8Struct 1 Offset 2\n"      //v2i8
759             "OpMemberDecorate %i8Struct 2 Offset 4\n"      //v3i8
760             "OpMemberDecorate %i8Struct 3 Offset 8\n"      //v4i8
761             "OpMemberDecorate %i8Struct 4 Offset 16\n"     //i8[3]
762             "OpMemberDecorate %i8Struct 5 Offset 64\n"     //struct {i8, v2i8[3]} [11]
763             "OpMemberDecorate %i8Struct 6 Offset 768\n"    //v2i8[11]
764             "OpMemberDecorate %i8Struct 7 Offset 944\n"    //i8
765             "OpMemberDecorate %i8Struct 8 Offset 960\n"    //v3i8[11]
766             "OpMemberDecorate %i8Struct 9 Offset 1136\n"); //v4i8[3]
767     case SHADERTEMPLATE_STRIDE8BIT_STD430:
768         return string(
769             //struct {i8, v2i8[3]} [11]
770             "OpDecorate %v2i8arr3     ArrayStride 2\n"
771             "OpMemberDecorate %struct8 0 Offset 0\n"
772             "OpMemberDecorate %struct8 1 Offset 2\n"
773             "OpDecorate %struct8arr11 ArrayStride 8\n"
774             "\n"
775             "OpDecorate %i8arr3    ArrayStride 1\n"
776             "OpDecorate %v2i8arr11 ArrayStride 2\n"
777             "OpDecorate %v3i8arr11 ArrayStride 4\n"
778             "OpDecorate %v4i8arr3  ArrayStride 4\n"
779             "OpDecorate %i8StructArr7 ArrayStride 224\n"
780             "\n"
781             "OpMemberDecorate %i8Struct 0 Offset 0\n"     //i8
782             "OpMemberDecorate %i8Struct 1 Offset 2\n"     //v2i8
783             "OpMemberDecorate %i8Struct 2 Offset 4\n"     //v3i8
784             "OpMemberDecorate %i8Struct 3 Offset 8\n"     //v4i8
785             "OpMemberDecorate %i8Struct 4 Offset 16\n"    //i8[3]
786             "OpMemberDecorate %i8Struct 5 Offset 32\n"    //struct {i8, v2i8[3]} [11]
787             "OpMemberDecorate %i8Struct 6 Offset 128\n"   //v2i8[11]
788             "OpMemberDecorate %i8Struct 7 Offset 150\n"   //i8
789             "OpMemberDecorate %i8Struct 8 Offset 160\n"   //v3i8[11]
790             "OpMemberDecorate %i8Struct 9 Offset 208\n"); //v4i8[3]
791     case SHADERTEMPLATE_STRIDE32BIT_STD140:
792         return string(
793             //struct {i32, v2i32[3]} [11]
794             "OpDecorate %v2i32arr3 ArrayStride 16\n"
795             "OpMemberDecorate %struct32 0 Offset 0\n"
796             "OpMemberDecorate %struct32 1 Offset 16\n"
797             "OpDecorate %struct32arr11 ArrayStride 64\n"
798             "\n"
799             "OpDecorate %i32arr3   ArrayStride 16\n"
800             "OpDecorate %v2i32arr11 ArrayStride 16\n"
801             "OpDecorate %v3i32arr11 ArrayStride 16\n"
802             "OpDecorate %v4i32arr3 ArrayStride 16\n"
803             "OpDecorate %i32StructArr7 ArrayStride 1216\n"
804             "\n"
805             "OpMemberDecorate %i32Struct 0 Offset 0\n"      //i32
806             "OpMemberDecorate %i32Struct 1 Offset 8\n"      //v2i32
807             "OpMemberDecorate %i32Struct 2 Offset 16\n"     //v3i32
808             "OpMemberDecorate %i32Struct 3 Offset 32\n"     //v4i32
809             "OpMemberDecorate %i32Struct 4 Offset 48\n"     //i32[3]
810             "OpMemberDecorate %i32Struct 5 Offset 96\n"     //struct {i32, v2i32[3]} [11]
811             "OpMemberDecorate %i32Struct 6 Offset 800\n"    //v2i32[11]
812             "OpMemberDecorate %i32Struct 7 Offset 976\n"    //i32
813             "OpMemberDecorate %i32Struct 8 Offset 992\n"    //v3i32[11]
814             "OpMemberDecorate %i32Struct 9 Offset 1168\n"); //v4i32[3]
815     case SHADERTEMPLATE_STRIDE32BIT_STD430:
816         return string(
817             //struct {i32, v2i32[3]} [11]
818             "OpDecorate %v2i32arr3 ArrayStride 8\n"
819             "OpMemberDecorate %struct32 0 Offset 0\n"
820             "OpMemberDecorate %struct32 1 Offset 8\n"
821             "OpDecorate %struct32arr11 ArrayStride 32\n"
822             "\n"
823             "OpDecorate %i32arr3    ArrayStride 4\n"
824             "OpDecorate %v2i32arr11 ArrayStride 8\n"
825             "OpDecorate %v3i32arr11 ArrayStride 16\n"
826             "OpDecorate %v4i32arr3  ArrayStride 16\n"
827             "OpDecorate %i32StructArr7 ArrayStride 736\n"
828             "\n"
829             "OpMemberDecorate %i32Struct 0 Offset 0\n"     //i32
830             "OpMemberDecorate %i32Struct 1 Offset 8\n"     //v2i32
831             "OpMemberDecorate %i32Struct 2 Offset 16\n"    //v3i32
832             "OpMemberDecorate %i32Struct 3 Offset 32\n"    //v4i32
833             "OpMemberDecorate %i32Struct 4 Offset 48\n"    //i32[3]
834             "OpMemberDecorate %i32Struct 5 Offset 64\n"    //struct {i32, v2i32[3]}[11]
835             "OpMemberDecorate %i32Struct 6 Offset 416\n"   //v2i32[11]
836             "OpMemberDecorate %i32Struct 7 Offset 504\n"   //i32
837             "OpMemberDecorate %i32Struct 8 Offset 512\n"   //v3i32[11]
838             "OpMemberDecorate %i32Struct 9 Offset 688\n"); //v4i32[3]
839     case SHADERTEMPLATE_STRIDEMIX_STD140:
840         return string(
841             "\n"                                                   //strutNestedIn {b8, b32, v2b8[11], b32[11]}
842             "OpDecorate %v2b8NestedArr11${InOut} ArrayStride 16\n" //v2b8[11]
843             "OpDecorate %b32NestedArr11${InOut} ArrayStride 16\n"  //b32[11]
844             "OpMemberDecorate %sNested${InOut} 0 Offset 0\n"       //b8
845             "OpMemberDecorate %sNested${InOut} 1 Offset 4\n"       //b32
846             "OpMemberDecorate %sNested${InOut} 2 Offset 16\n"      //v2b8[11]
847             "OpMemberDecorate %sNested${InOut} 3 Offset 192\n"     //b32[11]
848             "OpDecorate %sNestedArr11${InOut} ArrayStride 368\n"   //strutNestedIn[11]
849             "\n" //strutIn {b8, b32, v2b8, v2b32, v3b8, v3b32, v4b8, v4b32, strutNestedIn[11], b8In[11], b32bIn[11]}
850             "OpDecorate %sb8Arr11${InOut} ArrayStride 16\n"       //b8In[11]
851             "OpDecorate %sb32Arr11${InOut} ArrayStride 16\n"      //b32bIn[11]
852             "OpMemberDecorate %struct${InOut} 0 Offset 0\n"       //b8
853             "OpMemberDecorate %struct${InOut} 1 Offset 4\n"       //b32
854             "OpMemberDecorate %struct${InOut} 2 Offset 8\n"       //v2b8
855             "OpMemberDecorate %struct${InOut} 3 Offset 16\n"      //v2b32
856             "OpMemberDecorate %struct${InOut} 4 Offset 24\n"      //v3b8
857             "OpMemberDecorate %struct${InOut} 5 Offset 32\n"      //v3b32
858             "OpMemberDecorate %struct${InOut} 6 Offset 48\n"      //v4b8
859             "OpMemberDecorate %struct${InOut} 7 Offset 64\n"      //v4b32
860             "OpMemberDecorate %struct${InOut} 8 Offset 80\n"      //strutNestedIn[11]
861             "OpMemberDecorate %struct${InOut} 9 Offset 4128\n"    //b8In[11]
862             "OpMemberDecorate %struct${InOut} 10 Offset 4304\n"   //b32bIn[11]
863             "OpDecorate %structArr7${InOut} ArrayStride 4480\n"); //strutIn[7]
864     case SHADERTEMPLATE_STRIDEMIX_STD430:
865         return string(
866             "\n"                                                  //strutNestedOut {b8, b32, v2b8[11], b32[11]}
867             "OpDecorate %v2b8NestedArr11${InOut} ArrayStride 2\n" //v2b8[11]
868             "OpDecorate %b32NestedArr11${InOut}  ArrayStride 4\n" //b32[11]
869             "OpMemberDecorate %sNested${InOut} 0 Offset 0\n"      //b8
870             "OpMemberDecorate %sNested${InOut} 1 Offset 4\n"      //b32
871             "OpMemberDecorate %sNested${InOut} 2 Offset 8\n"      //v2b8[11]
872             "OpMemberDecorate %sNested${InOut} 3 Offset 32\n"     //b32[11]
873             "OpDecorate %sNestedArr11${InOut} ArrayStride 76\n"   //strutNestedOut[11]
874             "\n" //strutOut {b8, b32, v2b8, v2b32, v3b8, v3b32, v4b8, v4b32, strutNestedOut[11], b8Out[11], b32bOut[11]}
875             "OpDecorate %sb8Arr11${InOut} ArrayStride 1\n"       //b8Out[11]
876             "OpDecorate %sb32Arr11${InOut} ArrayStride 4\n"      //b32bOut[11]
877             "OpMemberDecorate %struct${InOut} 0 Offset 0\n"      //b8
878             "OpMemberDecorate %struct${InOut} 1 Offset 4\n"      //b32
879             "OpMemberDecorate %struct${InOut} 2 Offset 8\n"      //v2b8
880             "OpMemberDecorate %struct${InOut} 3 Offset 16\n"     //v2b32
881             "OpMemberDecorate %struct${InOut} 4 Offset 24\n"     //v3b8
882             "OpMemberDecorate %struct${InOut} 5 Offset 32\n"     //v3b32
883             "OpMemberDecorate %struct${InOut} 6 Offset 48\n"     //v4b8
884             "OpMemberDecorate %struct${InOut} 7 Offset 64\n"     //v4b32
885             "OpMemberDecorate %struct${InOut} 8 Offset 80\n"     //strutNestedOut[11]
886             "OpMemberDecorate %struct${InOut} 9 Offset 916\n"    //b8Out[11]
887             "OpMemberDecorate %struct${InOut} 10 Offset 928\n"   //b32bOut[11]
888             "OpDecorate %structArr7${InOut} ArrayStride 976\n"); //strutOut[7]
889     default:
890         DE_ASSERT(0);
891         return string("");
892     }
893 }
894 /*Return string contains spirv loop begin.
895  the spec should contains "exeCount" - with name of const i32, it is number of executions
896  the spec should contains "loopName" - suffix for all local names
897  %Val${loopName} - index which can be used inside loop
898  "%ndxArr${loopName}   = OpVariable %fp_i32  Function\n" - has to be defined outside
899  The function should be always use with endLoop function*/
beginLoop(const std::map<std::string,std::string> & spec)900 std::string beginLoop(const std::map<std::string, std::string> &spec)
901 {
902     const tcu::StringTemplate loopBegin(
903         "OpStore %ndxArr${loopName} %zero\n"
904         "OpBranch %Loop${loopName}\n"
905         "%Loop${loopName} = OpLabel\n"
906         "OpLoopMerge %MergeLabel1${loopName} %MergeLabel2${loopName} None\n"
907         "OpBranch %Label1${loopName}\n"
908         "%Label1${loopName} = OpLabel\n"
909         "%Val${loopName} = OpLoad %i32 %ndxArr${loopName}\n"
910         "%LessThan${loopName} = OpSLessThan %bool %Val${loopName} %${exeCount}\n"
911         "OpBranchConditional %LessThan${loopName} %ifLabel${loopName} %MergeLabel1${loopName}\n"
912         "%ifLabel${loopName} = OpLabel\n");
913     return loopBegin.specialize(spec);
914 }
915 /*Return string contains spirv loop end.
916  the spec should contains "loopName" - suffix for all local names, suffix should be the same in beginLoop
917 The function should be always use with beginLoop function*/
endLoop(const std::map<std::string,std::string> & spec)918 std::string endLoop(const std::map<std::string, std::string> &spec)
919 {
920     const tcu::StringTemplate loopEnd("OpBranch %MergeLabel2${loopName}\n"
921                                       "%MergeLabel2${loopName} = OpLabel\n"
922                                       "%plusOne${loopName} = OpIAdd %i32 %Val${loopName} %c_i32_1\n"
923                                       "OpStore %ndxArr${loopName} %plusOne${loopName}\n"
924                                       "OpBranch %Loop${loopName}\n"
925                                       "%MergeLabel1${loopName} = OpLabel\n");
926     return loopEnd.specialize(spec);
927 }
928 
addCompute8bitStorage32To8Group(tcu::TestCaseGroup * group)929 void addCompute8bitStorage32To8Group(tcu::TestCaseGroup *group)
930 {
931     tcu::TestContext &testCtx = group->getTestContext();
932     de::Random rnd(deStringHash(group->getName()));
933     const int numElements = 128;
934 
935     const StringTemplate shaderTemplate("OpCapability Shader\n"
936                                         "OpCapability ${capability}\n"
937                                         "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
938                                         "OpExtension \"SPV_KHR_8bit_storage\"\n"
939                                         "OpMemoryModel Logical GLSL450\n"
940                                         "OpEntryPoint GLCompute %main \"main\" %id\n"
941                                         "OpExecutionMode %main LocalSize 1 1 1\n"
942                                         "OpDecorate %id BuiltIn GlobalInvocationId\n"
943 
944                                         "${stride}"
945 
946                                         "OpDecorate %SSBO32 Block\n"
947                                         "OpDecorate %SSBO8 Block\n"
948                                         "OpMemberDecorate %SSBO32 0 Offset 0\n"
949                                         "OpMemberDecorate %SSBO8 0 Offset 0\n"
950                                         "OpDecorate %ssbo32 DescriptorSet 0\n"
951                                         "OpDecorate %ssbo8 DescriptorSet 0\n"
952                                         "OpDecorate %ssbo32 Binding 0\n"
953                                         "OpDecorate %ssbo8 Binding 1\n"
954 
955                                         "${matrix_decor:opt}\n"
956 
957                                         "${rounding:opt}\n"
958 
959                                         "%bool      = OpTypeBool\n"
960                                         "%void      = OpTypeVoid\n"
961                                         "%voidf     = OpTypeFunction %void\n"
962                                         "%u32       = OpTypeInt 32 0\n"
963                                         "%i32       = OpTypeInt 32 1\n"
964                                         "%f32       = OpTypeFloat 32\n"
965                                         "%uvec3     = OpTypeVector %u32 3\n"
966                                         "%fvec3     = OpTypeVector %f32 3\n"
967                                         "%uvec3ptr  = OpTypePointer Input %uvec3\n"
968                                         "%i32ptr    = OpTypePointer StorageBuffer %i32\n"
969                                         "%f32ptr    = OpTypePointer StorageBuffer %f32\n"
970 
971                                         "%zero      = OpConstant %i32 0\n"
972                                         "%c_i32_1   = OpConstant %i32 1\n"
973                                         "%c_i32_16  = OpConstant %i32 16\n"
974                                         "%c_i32_32  = OpConstant %i32 32\n"
975                                         "%c_i32_64  = OpConstant %i32 64\n"
976                                         "%c_i32_128 = OpConstant %i32 128\n"
977 
978                                         "%i32arr    = OpTypeArray %i32 %c_i32_128\n"
979                                         "%f32arr    = OpTypeArray %f32 %c_i32_128\n"
980 
981                                         "${types}\n"
982                                         "${matrix_types:opt}\n"
983 
984                                         "%SSBO32    = OpTypeStruct %${matrix_prefix:opt}${base32}arr\n"
985                                         "%SSBO8    = OpTypeStruct %${matrix_prefix:opt}${base8}arr\n"
986                                         "%up_SSBO32 = OpTypePointer ${storage} %SSBO32\n"
987                                         "%up_SSBO8 = OpTypePointer ${storage} %SSBO8\n"
988                                         "%ssbo32    = OpVariable %up_SSBO32 ${storage}\n"
989                                         "%ssbo8    = OpVariable %up_SSBO8 ${storage}\n"
990 
991                                         "%id        = OpVariable %uvec3ptr Input\n"
992 
993                                         "%main      = OpFunction %void None %voidf\n"
994                                         "%label     = OpLabel\n"
995                                         "%idval     = OpLoad %uvec3 %id\n"
996                                         "%x         = OpCompositeExtract %u32 %idval 0\n"
997                                         "%inloc     = OpAccessChain %${base32}ptr %ssbo32 %zero %x ${index0:opt}\n"
998                                         "%val32     = OpLoad %${base32} %inloc\n"
999                                         "%val8     = ${convert} %${base8} %val32\n"
1000                                         "%outloc    = OpAccessChain %${base8}ptr %ssbo8 %zero %x ${index0:opt}\n"
1001                                         "             OpStore %outloc %val8\n"
1002                                         "${matrix_store:opt}\n"
1003                                         "             OpReturn\n"
1004                                         "             OpFunctionEnd\n");
1005 
1006     { // Integers
1007         const char sintTypes[] = "%i8       = OpTypeInt 8 1\n"
1008                                  "%i8ptr    = OpTypePointer StorageBuffer %i8\n"
1009                                  "%i8arr    = OpTypeArray %i8 %c_i32_128\n"
1010                                  "%v2i8     = OpTypeVector %i8 2\n"
1011                                  "%v4i8     = OpTypeVector %i8 4\n"
1012                                  "%v2i32    = OpTypeVector %i32 2\n"
1013                                  "%v4i32    = OpTypeVector %i32 4\n"
1014                                  "%v2i8ptr  = OpTypePointer StorageBuffer %v2i8\n"
1015                                  "%v2i32ptr = OpTypePointer StorageBuffer %v2i32\n"
1016                                  "%v2i8arr  = OpTypeArray %v2i8 %c_i32_64\n"
1017                                  "%v2i32arr = OpTypeArray %v2i32 %c_i32_64\n";
1018 
1019         const char uintTypes[] = "%u8       = OpTypeInt 8 0\n"
1020                                  "%u8ptr    = OpTypePointer StorageBuffer %u8\n"
1021                                  "%u32ptr   = OpTypePointer StorageBuffer %u32\n"
1022                                  "%u8arr    = OpTypeArray %u8 %c_i32_128\n"
1023                                  "%u32arr   = OpTypeArray %u32 %c_i32_128\n"
1024                                  "%v2u8     = OpTypeVector %u8 2\n"
1025                                  "%v2u32    = OpTypeVector %u32 2\n"
1026                                  "%v4u32    = OpTypeVector %u32 4\n"
1027                                  "%v2u8ptr  = OpTypePointer StorageBuffer %v2u8\n"
1028                                  "%v2u32ptr = OpTypePointer StorageBuffer %v2u32\n"
1029                                  "%v2u8arr  = OpTypeArray %v2u8 %c_i32_64\n"
1030                                  "%v2u32arr = OpTypeArray %v2u32 %c_i32_64\n";
1031 
1032         struct CompositeType
1033         {
1034             const char *name;
1035             const char *types;
1036             const char *base32;
1037             const char *base8;
1038             const char *opcode;
1039             const char *stride;
1040             unsigned count;
1041         };
1042 
1043         const CompositeType cTypes[] = {
1044             {"scalar_sint", sintTypes, "i32", "i8", "OpSConvert",
1045              "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i8arr ArrayStride 1\n", numElements},
1046             {"scalar_uint", uintTypes, "u32", "u8", "OpUConvert",
1047              "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u8arr ArrayStride 1\n", numElements},
1048             {"vector_sint", sintTypes, "v2i32", "v2i8", "OpSConvert",
1049              "OpDecorate %v2i32arr ArrayStride 8\nOpDecorate %v2i8arr ArrayStride 2\n", numElements / 2},
1050             {"vector_uint", uintTypes, "v2u32", "v2u8", "OpUConvert",
1051              "OpDecorate %v2u32arr ArrayStride 8\nOpDecorate %v2u8arr ArrayStride 2\n", numElements / 2},
1052         };
1053 
1054         vector<int32_t> inputs = getInt32s(rnd, numElements);
1055         vector<int8_t> outputs(inputs.size());
1056 
1057         for (uint32_t numNdx = 0; numNdx < inputs.size(); ++numNdx)
1058             outputs[numNdx] = (static_cast<int8_t>(0xff & inputs[numNdx]));
1059 
1060         for (uint32_t tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1061         {
1062             ComputeShaderSpec spec;
1063             map<string, string> specs;
1064             string testName = string(CAPABILITIES[STORAGE_BUFFER_TEST].name) + "_" + cTypes[tyIdx].name;
1065 
1066             specs["capability"] = CAPABILITIES[STORAGE_BUFFER_TEST].cap;
1067             specs["storage"]    = CAPABILITIES[STORAGE_BUFFER_TEST].decor;
1068             specs["stride"]     = cTypes[tyIdx].stride;
1069             specs["base32"]     = cTypes[tyIdx].base32;
1070             specs["base8"]      = cTypes[tyIdx].base8;
1071             specs["types"]      = cTypes[tyIdx].types;
1072             specs["convert"]    = cTypes[tyIdx].opcode;
1073 
1074             spec.assembly      = shaderTemplate.specialize(specs);
1075             spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
1076 
1077             spec.inputs.push_back(Resource(BufferSp(new Int32Buffer(inputs)), CAPABILITIES[STORAGE_BUFFER_TEST].dtype));
1078             spec.outputs.push_back(Resource(BufferSp(new Int8Buffer(outputs))));
1079             spec.extensions.push_back("VK_KHR_8bit_storage");
1080             spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1081             spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[STORAGE_BUFFER_TEST].name);
1082 
1083             group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), spec));
1084         }
1085     }
1086 }
1087 
addCompute8bitUniform8To32Group(tcu::TestCaseGroup * group)1088 void addCompute8bitUniform8To32Group(tcu::TestCaseGroup *group)
1089 {
1090     tcu::TestContext &testCtx = group->getTestContext();
1091     de::Random rnd(deStringHash(group->getName()));
1092     const int numElements = 128;
1093 
1094     const StringTemplate shaderTemplate("OpCapability Shader\n"
1095                                         "OpCapability ${capability}\n"
1096                                         "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1097                                         "OpExtension \"SPV_KHR_8bit_storage\"\n"
1098                                         "OpMemoryModel Logical GLSL450\n"
1099                                         "OpEntryPoint GLCompute %main \"main\" %id\n"
1100                                         "OpExecutionMode %main LocalSize 1 1 1\n"
1101                                         "OpDecorate %id BuiltIn GlobalInvocationId\n"
1102 
1103                                         "${stride}"
1104 
1105                                         "OpDecorate %SSBO32 Block\n"
1106                                         "OpDecorate %SSBO8 Block\n"
1107                                         "OpMemberDecorate %SSBO32 0 Offset 0\n"
1108                                         "OpMemberDecorate %SSBO8 0 Offset 0\n"
1109                                         "OpDecorate %SSBO8 ${storage}\n"
1110                                         "OpDecorate %ssbo32 DescriptorSet 0\n"
1111                                         "OpDecorate %ssbo8 DescriptorSet 0\n"
1112                                         "OpDecorate %ssbo32 Binding 1\n"
1113                                         "OpDecorate %ssbo8 Binding 0\n"
1114 
1115                                         "${matrix_decor:opt}\n"
1116 
1117                                         "%bool      = OpTypeBool\n"
1118                                         "%void      = OpTypeVoid\n"
1119                                         "%voidf     = OpTypeFunction %void\n"
1120                                         "%u32       = OpTypeInt 32 0\n"
1121                                         "%i32       = OpTypeInt 32 1\n"
1122                                         "%uvec3     = OpTypeVector %u32 3\n"
1123                                         "%uvec3ptr  = OpTypePointer Input %uvec3\n"
1124                                         "%i32ptr    = OpTypePointer StorageBuffer %i32\n"
1125 
1126                                         "%zero      = OpConstant %i32 0\n"
1127                                         "%c_i32_1   = OpConstant %i32 1\n"
1128                                         "%c_i32_2   = OpConstant %i32 2\n"
1129                                         "%c_i32_3   = OpConstant %i32 3\n"
1130                                         "%c_i32_16  = OpConstant %i32 16\n"
1131                                         "%c_i32_32  = OpConstant %i32 32\n"
1132                                         "%c_i32_64  = OpConstant %i32 64\n"
1133                                         "%c_i32_128 = OpConstant %i32 128\n"
1134 
1135                                         "%i32arr    = OpTypeArray %i32 %c_i32_128\n"
1136 
1137                                         "${types}\n"
1138                                         "${matrix_types:opt}\n"
1139 
1140                                         "%SSBO32    = OpTypeStruct %${matrix_prefix:opt}${base32}arr\n"
1141                                         "%SSBO8    = OpTypeStruct %${matrix_prefix:opt}${base8}arr\n"
1142                                         "%up_SSBO32 = OpTypePointer StorageBuffer %SSBO32\n"
1143                                         "%up_SSBO8 = OpTypePointer Uniform %SSBO8\n"
1144                                         "%ssbo32    = OpVariable %up_SSBO32 StorageBuffer\n"
1145                                         "%ssbo8    = OpVariable %up_SSBO8 Uniform\n"
1146 
1147                                         "%id        = OpVariable %uvec3ptr Input\n"
1148 
1149                                         "%main      = OpFunction %void None %voidf\n"
1150                                         "%label     = OpLabel\n"
1151                                         "%idval     = OpLoad %uvec3 %id\n"
1152                                         "%x         = OpCompositeExtract %u32 %idval 0\n"
1153                                         "%inloc     = OpAccessChain %${base8}ptr %ssbo8 %zero %x ${index0:opt}\n"
1154                                         "%val8     = OpLoad %${base8} %inloc\n"
1155                                         "%val32     = ${convert} %${base32} %val8\n"
1156                                         "%outloc    = OpAccessChain %${base32}ptr %ssbo32 %zero %x ${index0:opt}\n"
1157                                         "             OpStore %outloc %val32\n"
1158                                         "${matrix_store:opt}\n"
1159                                         "             OpReturn\n"
1160                                         "             OpFunctionEnd\n");
1161 
1162     { // Integers
1163         const char sintTypes[] = "%i8       = OpTypeInt 8 1\n"
1164                                  "%i8ptr    = OpTypePointer Uniform %i8\n"
1165                                  "%i8arr    = OpTypeArray %i8 %c_i32_128\n"
1166                                  "%v4i8     = OpTypeVector %i8 4\n"
1167                                  "%v4i32     = OpTypeVector %i32 4\n"
1168                                  "%v4i8ptr  = OpTypePointer Uniform %v4i8\n"
1169                                  "%v4i32ptr  = OpTypePointer StorageBuffer %v4i32\n"
1170                                  "%v4i8arr  = OpTypeArray %v4i8 %c_i32_32\n"
1171                                  "%v4i32arr  = OpTypeArray %v4i32 %c_i32_32\n";
1172 
1173         const char uintTypes[] = "%u8       = OpTypeInt 8 0\n"
1174                                  "%u8ptr    = OpTypePointer Uniform %u8\n"
1175                                  "%u32ptr    = OpTypePointer StorageBuffer %u32\n"
1176                                  "%u8arr    = OpTypeArray %u8 %c_i32_128\n"
1177                                  "%u32arr    = OpTypeArray %u32 %c_i32_128\n"
1178                                  "%v4u8     = OpTypeVector %u8 4\n"
1179                                  "%v4u32     = OpTypeVector %u32 4\n"
1180                                  "%v4u8ptr  = OpTypePointer Uniform %v4u8\n"
1181                                  "%v4u32ptr  = OpTypePointer StorageBuffer %v4u32\n"
1182                                  "%v4u8arr  = OpTypeArray %v4u8 %c_i32_32\n"
1183                                  "%v4u32arr  = OpTypeArray %v4u32 %c_i32_32\n";
1184 
1185         struct CompositeType
1186         {
1187             const char *name;
1188             const char *types;
1189             const char *base32;
1190             const char *base8;
1191             const char *opcode;
1192             const char *stride;
1193             const int componentsCount;
1194         };
1195 
1196         const CompositeType cTypes[] = {
1197             {"scalar_sint", sintTypes, "i32", "i8", "OpSConvert",
1198              "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i8arr ArrayStride 16\n", 1},
1199             {"scalar_uint", uintTypes, "u32", "u8", "OpUConvert",
1200              "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u8arr ArrayStride 16\n", 1},
1201             {"vector_sint", sintTypes, "v4i32", "v4i8", "OpSConvert",
1202              "OpDecorate %v4i32arr ArrayStride 16\nOpDecorate %v4i8arr ArrayStride 16\n", 4},
1203             {"vector_uint", uintTypes, "v4u32", "v4u8", "OpUConvert",
1204              "OpDecorate %v4u32arr ArrayStride 16\nOpDecorate %v4u8arr ArrayStride 16\n", 4},
1205         };
1206 
1207         vector<int32_t> outputs(numElements);
1208 
1209         for (uint32_t tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1210         {
1211             ComputeShaderSpec spec;
1212             map<string, string> specs;
1213             string testName = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name) + "_" + cTypes[tyIdx].name;
1214 
1215             vector<int8_t> inputs = getInt8s(rnd, (arrayStrideInBytesUniform / static_cast<uint32_t>(sizeof(int8_t))) *
1216                                                       (numElements / cTypes[tyIdx].componentsCount));
1217 
1218             specs["capability"] = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
1219             specs["storage"]    = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].decor;
1220             specs["stride"]     = cTypes[tyIdx].stride;
1221             specs["base32"]     = cTypes[tyIdx].base32;
1222             specs["base8"]      = cTypes[tyIdx].base8;
1223             specs["types"]      = cTypes[tyIdx].types;
1224             specs["convert"]    = cTypes[tyIdx].opcode;
1225 
1226             spec.assembly      = shaderTemplate.specialize(specs);
1227             spec.numWorkGroups = IVec3(numElements / cTypes[tyIdx].componentsCount, 1, 1);
1228 
1229             spec.inputs.push_back(
1230                 Resource(BufferSp(new Int8Buffer(inputs)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
1231             spec.outputs.push_back(Resource(BufferSp(new Int32Buffer(outputs))));
1232 
1233             spec.extensions.push_back("VK_KHR_8bit_storage");
1234             spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1235             spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
1236 
1237             if (cTypes[tyIdx].componentsCount == 4)
1238                 spec.verifyIO = checkUniformsArray<int8_t, int32_t, 4>;
1239             else
1240                 spec.verifyIO = checkUniformsArray<int8_t, int32_t, 1>;
1241 
1242             group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), spec));
1243         }
1244     }
1245 }
1246 
addCompute8bitStoragePushConstant8To32Group(tcu::TestCaseGroup * group)1247 void addCompute8bitStoragePushConstant8To32Group(tcu::TestCaseGroup *group)
1248 {
1249     tcu::TestContext &testCtx = group->getTestContext();
1250     de::Random rnd(deStringHash(group->getName()));
1251     const int numElements = 64;
1252 
1253     const StringTemplate shaderTemplate("OpCapability Shader\n"
1254                                         "OpCapability StoragePushConstant8\n"
1255                                         "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1256                                         "OpExtension \"SPV_KHR_8bit_storage\"\n"
1257                                         "OpMemoryModel Logical GLSL450\n"
1258                                         "OpEntryPoint GLCompute %main \"main\" %id\n"
1259                                         "OpExecutionMode %main LocalSize 1 1 1\n"
1260                                         "OpDecorate %id BuiltIn GlobalInvocationId\n"
1261 
1262                                         "${stride}"
1263 
1264                                         "OpDecorate %PC8 Block\n"
1265                                         "OpDecorate %SSBO32 Block\n"
1266                                         "OpMemberDecorate %PC8 0 Offset 0\n"
1267                                         "OpMemberDecorate %SSBO32 0 Offset 0\n"
1268                                         "OpDecorate %ssbo32 DescriptorSet 0\n"
1269                                         "OpDecorate %ssbo32 Binding 0\n"
1270 
1271                                         "${matrix_decor:opt}\n"
1272 
1273                                         "%bool      = OpTypeBool\n"
1274                                         "%void      = OpTypeVoid\n"
1275                                         "%voidf     = OpTypeFunction %void\n"
1276                                         "%u32       = OpTypeInt 32 0\n"
1277                                         "%i32       = OpTypeInt 32 1\n"
1278                                         "%uvec3     = OpTypeVector %u32 3\n"
1279                                         "%uvec3ptr  = OpTypePointer Input %uvec3\n"
1280                                         "%i32ptr    = OpTypePointer StorageBuffer %i32\n"
1281 
1282                                         "%zero      = OpConstant %i32 0\n"
1283                                         "%c_i32_1   = OpConstant %i32 1\n"
1284                                         "%c_i32_8   = OpConstant %i32 8\n"
1285                                         "%c_i32_16  = OpConstant %i32 16\n"
1286                                         "%c_i32_32  = OpConstant %i32 32\n"
1287                                         "%c_i32_64  = OpConstant %i32 64\n"
1288 
1289                                         "%i32arr    = OpTypeArray %i32 %c_i32_64\n"
1290 
1291                                         "${types}\n"
1292                                         "${matrix_types:opt}\n"
1293 
1294                                         "%PC8      = OpTypeStruct %${matrix_prefix:opt}${base8}arr\n"
1295                                         "%pp_PC8   = OpTypePointer PushConstant %PC8\n"
1296                                         "%pc8      = OpVariable %pp_PC8 PushConstant\n"
1297                                         "%SSBO32    = OpTypeStruct %${matrix_prefix:opt}${base32}arr\n"
1298                                         "%up_SSBO32 = OpTypePointer StorageBuffer %SSBO32\n"
1299                                         "%ssbo32    = OpVariable %up_SSBO32 StorageBuffer\n"
1300 
1301                                         "%id        = OpVariable %uvec3ptr Input\n"
1302 
1303                                         "%main      = OpFunction %void None %voidf\n"
1304                                         "%label     = OpLabel\n"
1305                                         "%idval     = OpLoad %uvec3 %id\n"
1306                                         "%x         = OpCompositeExtract %u32 %idval 0\n"
1307                                         "%inloc     = OpAccessChain %${base8}ptr %pc8 %zero %x ${index0:opt}\n"
1308                                         "%val8     = OpLoad %${base8} %inloc\n"
1309                                         "%val32     = ${convert} %${base32} %val8\n"
1310                                         "%outloc    = OpAccessChain %${base32}ptr %ssbo32 %zero %x ${index0:opt}\n"
1311                                         "             OpStore %outloc %val32\n"
1312                                         "${matrix_store:opt}\n"
1313                                         "             OpReturn\n"
1314                                         "             OpFunctionEnd\n");
1315 
1316     { // integers
1317         const char sintTypes[] = "%i8       = OpTypeInt 8 1\n"
1318                                  "%i8ptr    = OpTypePointer PushConstant %i8\n"
1319                                  "%i8arr    = OpTypeArray %i8 %c_i32_64\n"
1320                                  "%v2i8     = OpTypeVector %i8 2\n"
1321                                  "%v2i32     = OpTypeVector %i32 2\n"
1322                                  "%v2i8ptr  = OpTypePointer PushConstant %v2i8\n"
1323                                  "%v2i32ptr  = OpTypePointer StorageBuffer %v2i32\n"
1324                                  "%v2i8arr  = OpTypeArray %v2i8 %c_i32_32\n"
1325                                  "%v2i32arr  = OpTypeArray %v2i32 %c_i32_32\n";
1326 
1327         const char uintTypes[] = "%u8       = OpTypeInt 8 0\n"
1328                                  "%u8ptr    = OpTypePointer PushConstant %u8\n"
1329                                  "%u32ptr    = OpTypePointer StorageBuffer %u32\n"
1330                                  "%u8arr    = OpTypeArray %u8 %c_i32_64\n"
1331                                  "%u32arr    = OpTypeArray %u32 %c_i32_64\n"
1332                                  "%v2u8     = OpTypeVector %u8 2\n"
1333                                  "%v2u32     = OpTypeVector %u32 2\n"
1334                                  "%v2u8ptr  = OpTypePointer PushConstant %v2u8\n"
1335                                  "%v2u32ptr  = OpTypePointer StorageBuffer %v2u32\n"
1336                                  "%v2u8arr  = OpTypeArray %v2u8 %c_i32_32\n"
1337                                  "%v2u32arr  = OpTypeArray %v2u32 %c_i32_32\n";
1338 
1339         struct CompositeType
1340         {
1341             const char *name;
1342             bool isSigned;
1343             const char *types;
1344             const char *base32;
1345             const char *base8;
1346             const char *opcode;
1347             const char *stride;
1348             unsigned count;
1349         };
1350 
1351         const CompositeType cTypes[] = {
1352             {"scalar_sint", true, sintTypes, "i32", "i8", "OpSConvert",
1353              "OpDecorate %i32arr ArrayStride 4\nOpDecorate %i8arr ArrayStride 1\n", numElements},
1354             {"scalar_uint", false, uintTypes, "u32", "u8", "OpUConvert",
1355              "OpDecorate %u32arr ArrayStride 4\nOpDecorate %u8arr ArrayStride 1\n", numElements},
1356             {"vector_sint", true, sintTypes, "v2i32", "v2i8", "OpSConvert",
1357              "OpDecorate %v2i32arr ArrayStride 8\nOpDecorate %v2i8arr ArrayStride 2\n", numElements / 2},
1358             {"vector_uint", false, uintTypes, "v2u32", "v2u8", "OpUConvert",
1359              "OpDecorate %v2u32arr ArrayStride 8\nOpDecorate %v2u8arr ArrayStride 2\n", numElements / 2},
1360         };
1361 
1362         vector<int8_t> inputs = getInt8s(rnd, numElements);
1363         vector<int32_t> sOutputs;
1364         vector<int32_t> uOutputs;
1365         const uint8_t signBitMask     = 0x80;
1366         const uint32_t signExtendMask = 0xffff0000;
1367 
1368         sOutputs.reserve(inputs.size());
1369         uOutputs.reserve(inputs.size());
1370 
1371         for (uint32_t numNdx = 0; numNdx < inputs.size(); ++numNdx)
1372         {
1373             uOutputs.push_back(static_cast<uint8_t>(inputs[numNdx]));
1374             if (inputs[numNdx] & signBitMask)
1375                 sOutputs.push_back(static_cast<int32_t>(inputs[numNdx] | signExtendMask));
1376             else
1377                 sOutputs.push_back(static_cast<int32_t>(inputs[numNdx]));
1378         }
1379 
1380         for (uint32_t tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1381         {
1382             ComputeShaderSpec spec;
1383             map<string, string> specs;
1384             const char *testName = cTypes[tyIdx].name;
1385 
1386             specs["stride"]  = cTypes[tyIdx].stride;
1387             specs["base32"]  = cTypes[tyIdx].base32;
1388             specs["base8"]   = cTypes[tyIdx].base8;
1389             specs["types"]   = cTypes[tyIdx].types;
1390             specs["convert"] = cTypes[tyIdx].opcode;
1391 
1392             spec.assembly      = shaderTemplate.specialize(specs);
1393             spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
1394             spec.pushConstants = BufferSp(new Int8Buffer(inputs));
1395 
1396             if (cTypes[tyIdx].isSigned)
1397                 spec.outputs.push_back(BufferSp(new Int32Buffer(sOutputs)));
1398             else
1399                 spec.outputs.push_back(BufferSp(new Int32Buffer(uOutputs)));
1400             spec.extensions.push_back("VK_KHR_8bit_storage");
1401             spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1402             spec.requestedVulkanFeatures.ext8BitStorage.storagePushConstant8 = true;
1403 
1404             group->addChild(new SpvAsmComputeShaderCase(testCtx, testName, spec));
1405         }
1406     }
1407 }
1408 
addCompute8bitStorage16To8Group(tcu::TestCaseGroup * group)1409 void addCompute8bitStorage16To8Group(tcu::TestCaseGroup *group)
1410 {
1411     tcu::TestContext &testCtx = group->getTestContext();
1412     de::Random rnd(deStringHash(group->getName()));
1413     const int numElements = 128;
1414 
1415     const StringTemplate shaderTemplate("OpCapability Shader\n"
1416                                         "OpCapability ${capability}\n"
1417                                         "OpCapability StorageUniform16\n"
1418                                         "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1419                                         "OpExtension \"SPV_KHR_8bit_storage\"\n"
1420                                         "OpExtension \"SPV_KHR_16bit_storage\"\n"
1421                                         "OpMemoryModel Logical GLSL450\n"
1422                                         "OpEntryPoint GLCompute %main \"main\" %id\n"
1423                                         "OpExecutionMode %main LocalSize 1 1 1\n"
1424                                         "OpDecorate %id BuiltIn GlobalInvocationId\n"
1425 
1426                                         "${stride}"
1427 
1428                                         "OpDecorate %SSBO16 Block\n"
1429                                         "OpDecorate %SSBO8 Block\n"
1430                                         "OpMemberDecorate %SSBO16 0 Offset 0\n"
1431                                         "OpMemberDecorate %SSBO8 0 Offset 0\n"
1432                                         "OpDecorate %ssbo16 DescriptorSet 0\n"
1433                                         "OpDecorate %ssbo8 DescriptorSet 0\n"
1434                                         "OpDecorate %ssbo16 Binding 0\n"
1435                                         "OpDecorate %ssbo8 Binding 1\n"
1436 
1437                                         "${matrix_decor:opt}\n"
1438 
1439                                         "${rounding:opt}\n"
1440 
1441                                         "%bool      = OpTypeBool\n"
1442                                         "%void      = OpTypeVoid\n"
1443                                         "%voidf     = OpTypeFunction %void\n"
1444                                         "%i32       = OpTypeInt 32 1\n"
1445                                         "%u32       = OpTypeInt 32 0\n"
1446                                         "%uvec3     = OpTypeVector %u32 3\n"
1447                                         "%uvec3ptr  = OpTypePointer Input %uvec3\n"
1448 
1449                                         "%zero      = OpConstant %i32 0\n"
1450                                         "%c_i32_1   = OpConstant %i32 1\n"
1451                                         "%c_i32_16  = OpConstant %i32 16\n"
1452                                         "%c_i32_32  = OpConstant %i32 32\n"
1453                                         "%c_i32_64  = OpConstant %i32 64\n"
1454                                         "%c_i32_128 = OpConstant %i32 128\n"
1455 
1456                                         "${types}\n"
1457                                         "${matrix_types:opt}\n"
1458 
1459                                         "%SSBO16    = OpTypeStruct %${matrix_prefix:opt}${base16}arr\n"
1460                                         "%SSBO8     = OpTypeStruct %${matrix_prefix:opt}${base8}arr\n"
1461                                         "%up_SSBO16 = OpTypePointer ${storage} %SSBO16\n"
1462                                         "%up_SSBO8  = OpTypePointer ${storage} %SSBO8\n"
1463                                         "%ssbo16    = OpVariable %up_SSBO16 ${storage}\n"
1464                                         "%ssbo8     = OpVariable %up_SSBO8 ${storage}\n"
1465 
1466                                         "%id        = OpVariable %uvec3ptr Input\n"
1467 
1468                                         "%main      = OpFunction %void None %voidf\n"
1469                                         "%label     = OpLabel\n"
1470                                         "%idval     = OpLoad %uvec3 %id\n"
1471                                         "%x         = OpCompositeExtract %u32 %idval 0\n"
1472                                         "%inloc     = OpAccessChain %${base16}ptr %ssbo16 %zero %x ${index0:opt}\n"
1473                                         "%val16     = OpLoad %${base16} %inloc\n"
1474                                         "%val8      = ${convert} %${base8} %val16\n"
1475                                         "%outloc    = OpAccessChain %${base8}ptr %ssbo8 %zero %x ${index0:opt}\n"
1476                                         "             OpStore %outloc %val8\n"
1477                                         "${matrix_store:opt}\n"
1478                                         "             OpReturn\n"
1479                                         "             OpFunctionEnd\n");
1480 
1481     { // Integers
1482         const char sintTypes[] = "%i8       = OpTypeInt 8 1\n"
1483                                  "%i16      = OpTypeInt 16 1\n"
1484                                  "%i8ptr    = OpTypePointer StorageBuffer %i8\n"
1485                                  "%i8arr    = OpTypeArray %i8 %c_i32_128\n"
1486                                  "%i16arr   = OpTypeArray %i16 %c_i32_128\n"
1487                                  "%v2i8     = OpTypeVector %i8 2\n"
1488                                  "%v2i16    = OpTypeVector %i16 2\n"
1489                                  "%v2i8ptr  = OpTypePointer StorageBuffer %v2i8\n"
1490                                  "%v2i16ptr = OpTypePointer StorageBuffer %v2i16\n"
1491                                  "%v2i8arr  = OpTypeArray %v2i8 %c_i32_64\n"
1492                                  "%v2i16arr = OpTypeArray %v2i16 %c_i32_64\n"
1493                                  "%i16ptr   = OpTypePointer StorageBuffer %i16\n";
1494 
1495         const char uintTypes[] = "%u8       = OpTypeInt 8 0\n"
1496                                  "%u16      = OpTypeInt 16 0\n"
1497                                  "%u8ptr    = OpTypePointer StorageBuffer %u8\n"
1498                                  "%u16ptr   = OpTypePointer StorageBuffer %u16\n"
1499                                  "%u8arr    = OpTypeArray %u8 %c_i32_128\n"
1500                                  "%u16arr   = OpTypeArray %u16 %c_i32_128\n"
1501                                  "%v2u8     = OpTypeVector %u8 2\n"
1502                                  "%v2u16    = OpTypeVector %u16 2\n"
1503                                  "%v2u8ptr  = OpTypePointer StorageBuffer %v2u8\n"
1504                                  "%v2u16ptr = OpTypePointer StorageBuffer %v2u16\n"
1505                                  "%v2u8arr  = OpTypeArray %v2u8 %c_i32_64\n"
1506                                  "%v2u16arr = OpTypeArray %v2u16 %c_i32_64\n";
1507 
1508         struct CompositeType
1509         {
1510             const char *name;
1511             const char *types;
1512             const char *base16;
1513             const char *base8;
1514             const char *opcode;
1515             const char *stride;
1516             unsigned count;
1517         };
1518 
1519         const CompositeType cTypes[] = {
1520             {"scalar_sint", sintTypes, "i16", "i8", "OpSConvert",
1521              "OpDecorate %i16arr ArrayStride 2\nOpDecorate %i8arr ArrayStride 1\n", numElements},
1522             {"scalar_uint", uintTypes, "u16", "u8", "OpUConvert",
1523              "OpDecorate %u16arr ArrayStride 2\nOpDecorate %u8arr ArrayStride 1\n", numElements},
1524             {"vector_sint", sintTypes, "v2i16", "v2i8", "OpSConvert",
1525              "OpDecorate %v2i16arr ArrayStride 4\nOpDecorate %v2i8arr ArrayStride 2\n", numElements / 2},
1526             {"vector_uint", uintTypes, "v2u16", "v2u8", "OpUConvert",
1527              "OpDecorate %v2u16arr ArrayStride 4\nOpDecorate %v2u8arr ArrayStride 2\n", numElements / 2},
1528         };
1529 
1530         vector<int16_t> inputs = getInt16s(rnd, numElements);
1531         vector<int8_t> outputs;
1532 
1533         outputs.reserve(inputs.size());
1534         for (uint32_t numNdx = 0; numNdx < inputs.size(); ++numNdx)
1535             outputs.push_back(static_cast<int8_t>(0xff & inputs[numNdx]));
1536 
1537         for (uint32_t tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1538         {
1539             ComputeShaderSpec spec;
1540             map<string, string> specs;
1541             string testName = string(CAPABILITIES[STORAGE_BUFFER_TEST].name) + "_" + cTypes[tyIdx].name;
1542 
1543             specs["capability"] = CAPABILITIES[STORAGE_BUFFER_TEST].cap;
1544             specs["storage"]    = CAPABILITIES[STORAGE_BUFFER_TEST].decor;
1545             specs["stride"]     = cTypes[tyIdx].stride;
1546             specs["base16"]     = cTypes[tyIdx].base16;
1547             specs["base8"]      = cTypes[tyIdx].base8;
1548             specs["types"]      = cTypes[tyIdx].types;
1549             specs["convert"]    = cTypes[tyIdx].opcode;
1550 
1551             spec.assembly      = shaderTemplate.specialize(specs);
1552             spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
1553 
1554             spec.inputs.push_back(Resource(BufferSp(new Int16Buffer(inputs)), CAPABILITIES[STORAGE_BUFFER_TEST].dtype));
1555             spec.outputs.push_back(Resource(BufferSp(new Int8Buffer(outputs))));
1556             spec.extensions.push_back("VK_KHR_16bit_storage");
1557             spec.extensions.push_back("VK_KHR_8bit_storage");
1558             spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1559             spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[STORAGE_BUFFER_TEST].name);
1560             spec.requestedVulkanFeatures.ext16BitStorage.uniformAndStorageBuffer16BitAccess = true;
1561 
1562             group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), spec));
1563         }
1564     }
1565 }
1566 
addCompute8bitUniform8To16Group(tcu::TestCaseGroup * group)1567 void addCompute8bitUniform8To16Group(tcu::TestCaseGroup *group)
1568 {
1569     tcu::TestContext &testCtx = group->getTestContext();
1570     de::Random rnd(deStringHash(group->getName()));
1571     const int numElements = 128;
1572 
1573     const StringTemplate shaderTemplate("OpCapability Shader\n"
1574                                         "OpCapability ${capability}\n"
1575                                         "OpCapability StorageUniform16\n"
1576                                         "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1577                                         "OpExtension \"SPV_KHR_8bit_storage\"\n"
1578                                         "OpExtension \"SPV_KHR_16bit_storage\"\n"
1579                                         "OpMemoryModel Logical GLSL450\n"
1580                                         "OpEntryPoint GLCompute %main \"main\" %id\n"
1581                                         "OpExecutionMode %main LocalSize 1 1 1\n"
1582                                         "OpDecorate %id BuiltIn GlobalInvocationId\n"
1583 
1584                                         "${stride}"
1585 
1586                                         "OpDecorate %SSBO16 Block\n"
1587                                         "OpDecorate %SSBO8 Block\n"
1588                                         "OpMemberDecorate %SSBO16 0 Offset 0\n"
1589                                         "OpMemberDecorate %SSBO8 0 Offset 0\n"
1590                                         "OpDecorate %SSBO8 ${storage}\n"
1591                                         "OpDecorate %ssbo16 DescriptorSet 0\n"
1592                                         "OpDecorate %ssbo8 DescriptorSet 0\n"
1593                                         "OpDecorate %ssbo16 Binding 1\n"
1594                                         "OpDecorate %ssbo8 Binding 0\n"
1595 
1596                                         "${matrix_decor:opt}\n"
1597 
1598                                         "%bool      = OpTypeBool\n"
1599                                         "%void      = OpTypeVoid\n"
1600                                         "%voidf     = OpTypeFunction %void\n"
1601 
1602                                         "%i32       = OpTypeInt 32 1\n"
1603                                         "%u32       = OpTypeInt 32 0\n"
1604                                         "%uvec3     = OpTypeVector %u32 3\n"
1605                                         "%uvec3ptr  = OpTypePointer Input %uvec3\n"
1606 
1607                                         "%zero      = OpConstant %i32 0\n"
1608                                         "%c_i32_1   = OpConstant %i32 1\n"
1609                                         "%c_i32_2   = OpConstant %i32 2\n"
1610                                         "%c_i32_3   = OpConstant %i32 3\n"
1611                                         "%c_i32_16  = OpConstant %i32 16\n"
1612                                         "%c_i32_32  = OpConstant %i32 32\n"
1613                                         "%c_i32_64  = OpConstant %i32 64\n"
1614                                         "%c_i32_128 = OpConstant %i32 128\n"
1615 
1616                                         "${types}\n"
1617                                         "${matrix_types:opt}\n"
1618 
1619                                         "%SSBO16    = OpTypeStruct %${matrix_prefix:opt}${base16}arr\n"
1620                                         "%SSBO8    = OpTypeStruct %${matrix_prefix:opt}${base8}arr\n"
1621                                         "%up_SSBO16 = OpTypePointer StorageBuffer %SSBO16\n"
1622                                         "%up_SSBO8 = OpTypePointer Uniform %SSBO8\n"
1623                                         "%ssbo16    = OpVariable %up_SSBO16 StorageBuffer\n"
1624                                         "%ssbo8    = OpVariable %up_SSBO8 Uniform\n"
1625 
1626                                         "%id        = OpVariable %uvec3ptr Input\n"
1627 
1628                                         "%main      = OpFunction %void None %voidf\n"
1629                                         "%label     = OpLabel\n"
1630                                         "%idval     = OpLoad %uvec3 %id\n"
1631                                         "%x         = OpCompositeExtract %u32 %idval 0\n"
1632                                         "%inloc     = OpAccessChain %${base8}ptr %ssbo8 %zero %x ${index0:opt}\n"
1633                                         "%val8     = OpLoad %${base8} %inloc\n"
1634                                         "%val16     = ${convert} %${base16} %val8\n"
1635                                         "%outloc    = OpAccessChain %${base16}ptr %ssbo16 %zero %x ${index0:opt}\n"
1636                                         "             OpStore %outloc %val16\n"
1637                                         "${matrix_store:opt}\n"
1638                                         "             OpReturn\n"
1639                                         "             OpFunctionEnd\n");
1640 
1641     { // Integers
1642         const char sintTypes[] = "%i8       = OpTypeInt 8 1\n"
1643                                  "%i16      = OpTypeInt 16 1\n"
1644                                  "%i8ptr    = OpTypePointer Uniform %i8\n"
1645                                  "%i8arr    = OpTypeArray %i8 %c_i32_128\n"
1646                                  "%i16arr    = OpTypeArray %i16 %c_i32_128\n"
1647                                  "%i16ptr   = OpTypePointer StorageBuffer %i16\n"
1648                                  "%v4i8     = OpTypeVector %i8 4\n"
1649                                  "%v4i16    = OpTypeVector %i16 4\n"
1650                                  "%v4i8ptr  = OpTypePointer Uniform %v4i8\n"
1651                                  "%v4i16ptr = OpTypePointer StorageBuffer %v4i16\n"
1652                                  "%v4i8arr  = OpTypeArray %v4i8 %c_i32_32\n"
1653                                  "%v4i16arr = OpTypeArray %v4i16 %c_i32_32\n";
1654 
1655         const char uintTypes[] = "%u8       = OpTypeInt 8 0\n"
1656                                  "%u16      = OpTypeInt 16 0\n"
1657                                  "%u8ptr    = OpTypePointer Uniform %u8\n"
1658                                  "%u16ptr   = OpTypePointer StorageBuffer %u16\n"
1659                                  "%u8arr    = OpTypeArray %u8 %c_i32_128\n"
1660                                  "%u16arr   = OpTypeArray %u16 %c_i32_128\n"
1661                                  "%v4u8     = OpTypeVector %u8 4\n"
1662                                  "%v4u16    = OpTypeVector %u16 4\n"
1663                                  "%v4u8ptr  = OpTypePointer Uniform %v4u8\n"
1664                                  "%v4u16ptr = OpTypePointer StorageBuffer %v4u16\n"
1665                                  "%v4u8arr  = OpTypeArray %v4u8 %c_i32_32\n"
1666                                  "%v4u16arr = OpTypeArray %v4u16 %c_i32_32\n";
1667 
1668         struct CompositeType
1669         {
1670             const char *name;
1671             const char *types;
1672             const char *base16;
1673             const char *base8;
1674             const char *opcode;
1675             const char *stride;
1676             const int componentsCount;
1677         };
1678 
1679         const CompositeType cTypes[] = {
1680             {"scalar_sint", sintTypes, "i16", "i8", "OpSConvert",
1681              "OpDecorate %i16arr ArrayStride 2\nOpDecorate %i8arr ArrayStride 16\n", 1},
1682             {"scalar_uint", uintTypes, "u16", "u8", "OpUConvert",
1683              "OpDecorate %u16arr ArrayStride 2\nOpDecorate %u8arr ArrayStride 16\n", 1},
1684             {"vector_sint", sintTypes, "v4i16", "v4i8", "OpSConvert",
1685              "OpDecorate %v4i16arr ArrayStride 8\nOpDecorate %v4i8arr ArrayStride 16\n", 4},
1686             {"vector_uint", uintTypes, "v4u16", "v4u8", "OpUConvert",
1687              "OpDecorate %v4u16arr ArrayStride 8\nOpDecorate %v4u8arr ArrayStride 16\n", 4},
1688         };
1689 
1690         vector<int16_t> outputs(numElements);
1691 
1692         for (uint32_t tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1693         {
1694             ComputeShaderSpec spec;
1695             map<string, string> specs;
1696             string testName = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name) + "_" + cTypes[tyIdx].name;
1697 
1698             vector<int8_t> inputs = getInt8s(rnd, (arrayStrideInBytesUniform / static_cast<uint32_t>(sizeof(int8_t))) *
1699                                                       (numElements / cTypes[tyIdx].componentsCount));
1700 
1701             specs["capability"] = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
1702             specs["storage"]    = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].decor;
1703             specs["stride"]     = cTypes[tyIdx].stride;
1704             specs["base16"]     = cTypes[tyIdx].base16;
1705             specs["base8"]      = cTypes[tyIdx].base8;
1706             specs["types"]      = cTypes[tyIdx].types;
1707             specs["convert"]    = cTypes[tyIdx].opcode;
1708 
1709             spec.assembly      = shaderTemplate.specialize(specs);
1710             spec.numWorkGroups = IVec3(numElements / cTypes[tyIdx].componentsCount, 1, 1);
1711 
1712             spec.inputs.push_back(
1713                 Resource(BufferSp(new Int8Buffer(inputs)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
1714             spec.outputs.push_back(Resource(BufferSp(new Int16Buffer(outputs))));
1715             spec.extensions.push_back("VK_KHR_8bit_storage");
1716             spec.extensions.push_back("VK_KHR_16bit_storage");
1717             spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1718             spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
1719             spec.requestedVulkanFeatures.ext16BitStorage.uniformAndStorageBuffer16BitAccess = true;
1720 
1721             if (cTypes[tyIdx].componentsCount == 4)
1722                 spec.verifyIO = checkUniformsArray<int8_t, int16_t, 4>;
1723             else
1724                 spec.verifyIO = checkUniformsArray<int8_t, int16_t, 1>;
1725 
1726             group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), spec));
1727         }
1728     }
1729 }
1730 
addCompute8bitStoragePushConstant8To16Group(tcu::TestCaseGroup * group)1731 void addCompute8bitStoragePushConstant8To16Group(tcu::TestCaseGroup *group)
1732 {
1733     tcu::TestContext &testCtx = group->getTestContext();
1734     de::Random rnd(deStringHash(group->getName()));
1735     const int numElements = 64;
1736 
1737     const StringTemplate shaderTemplate("OpCapability Shader\n"
1738                                         "OpCapability StorageUniform16\n"
1739                                         "OpCapability StoragePushConstant8\n"
1740                                         "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1741                                         "OpExtension \"SPV_KHR_8bit_storage\"\n"
1742                                         "OpExtension \"SPV_KHR_16bit_storage\"\n"
1743                                         "OpMemoryModel Logical GLSL450\n"
1744                                         "OpEntryPoint GLCompute %main \"main\" %id\n"
1745                                         "OpExecutionMode %main LocalSize 1 1 1\n"
1746                                         "OpDecorate %id BuiltIn GlobalInvocationId\n"
1747 
1748                                         "${stride}"
1749 
1750                                         "OpDecorate %PC8 Block\n"
1751                                         "OpDecorate %SSBO16 Block\n"
1752                                         "OpMemberDecorate %PC8 0 Offset 0\n"
1753                                         "OpMemberDecorate %SSBO16 0 Offset 0\n"
1754                                         "OpDecorate %ssbo16 DescriptorSet 0\n"
1755                                         "OpDecorate %ssbo16 Binding 0\n"
1756 
1757                                         "${matrix_decor:opt}\n"
1758 
1759                                         "%bool      = OpTypeBool\n"
1760                                         "%void      = OpTypeVoid\n"
1761                                         "%voidf     = OpTypeFunction %void\n"
1762                                         "%i32       = OpTypeInt 32 1\n"
1763                                         "%u32       = OpTypeInt 32 0\n"
1764                                         "%uvec3     = OpTypeVector %u32 3\n"
1765                                         "%uvec3ptr  = OpTypePointer Input %uvec3\n"
1766 
1767                                         "%zero      = OpConstant %i32 0\n"
1768                                         "%c_i32_1   = OpConstant %i32 1\n"
1769                                         "%c_i32_8   = OpConstant %i32 8\n"
1770                                         "%c_i32_16  = OpConstant %i32 16\n"
1771                                         "%c_i32_32  = OpConstant %i32 32\n"
1772                                         "%c_i32_64  = OpConstant %i32 64\n"
1773 
1774                                         "${types}\n"
1775                                         "${matrix_types:opt}\n"
1776 
1777                                         "%PC8       = OpTypeStruct %${matrix_prefix:opt}${base8}arr\n"
1778                                         "%pp_PC8    = OpTypePointer PushConstant %PC8\n"
1779                                         "%pc8       = OpVariable %pp_PC8 PushConstant\n"
1780                                         "%SSBO16    = OpTypeStruct %${matrix_prefix:opt}${base16}arr\n"
1781                                         "%up_SSBO16 = OpTypePointer StorageBuffer %SSBO16\n"
1782                                         "%ssbo16    = OpVariable %up_SSBO16 StorageBuffer\n"
1783 
1784                                         "%id        = OpVariable %uvec3ptr Input\n"
1785 
1786                                         "%main      = OpFunction %void None %voidf\n"
1787                                         "%label     = OpLabel\n"
1788                                         "%idval     = OpLoad %uvec3 %id\n"
1789                                         "%x         = OpCompositeExtract %u32 %idval 0\n"
1790                                         "%inloc     = OpAccessChain %${base8}ptr %pc8 %zero %x ${index0:opt}\n"
1791                                         "%val8      = OpLoad %${base8} %inloc\n"
1792                                         "%val16     = ${convert} %${base16} %val8\n"
1793                                         "%outloc    = OpAccessChain %${base16}ptr %ssbo16 %zero %x ${index0:opt}\n"
1794                                         "             OpStore %outloc %val16\n"
1795                                         "${matrix_store:opt}\n"
1796                                         "             OpReturn\n"
1797                                         "             OpFunctionEnd\n");
1798 
1799     { // integers
1800         const char sintTypes[] = "%i8       = OpTypeInt 8 1\n"
1801                                  "%i16      = OpTypeInt 16 1\n"
1802                                  "%i8ptr    = OpTypePointer PushConstant %i8\n"
1803                                  "%i16ptr   = OpTypePointer StorageBuffer %i16\n"
1804                                  "%i8arr    = OpTypeArray %i8 %c_i32_64\n"
1805                                  "%i16arr   = OpTypeArray %i16 %c_i32_64\n"
1806                                  "%v2i8     = OpTypeVector %i8 2\n"
1807                                  "%v2i16    = OpTypeVector %i16 2\n"
1808                                  "%v2i8ptr  = OpTypePointer PushConstant %v2i8\n"
1809                                  "%v2i16ptr = OpTypePointer StorageBuffer %v2i16\n"
1810                                  "%v2i8arr  = OpTypeArray %v2i8 %c_i32_32\n"
1811                                  "%v2i16arr = OpTypeArray %v2i16 %c_i32_32\n";
1812 
1813         const char uintTypes[] = "%u8       = OpTypeInt 8 0\n"
1814                                  "%u16      = OpTypeInt 16 0\n"
1815                                  "%u8ptr    = OpTypePointer PushConstant %u8\n"
1816                                  "%u16ptr   = OpTypePointer StorageBuffer %u16\n"
1817                                  "%u8arr    = OpTypeArray %u8 %c_i32_64\n"
1818                                  "%u16arr   = OpTypeArray %u16 %c_i32_64\n"
1819                                  "%v2u8     = OpTypeVector %u8 2\n"
1820                                  "%v2u16    = OpTypeVector %u16 2\n"
1821                                  "%v2u8ptr  = OpTypePointer PushConstant %v2u8\n"
1822                                  "%v2u16ptr = OpTypePointer StorageBuffer %v2u16\n"
1823                                  "%v2u8arr  = OpTypeArray %v2u8 %c_i32_32\n"
1824                                  "%v2u16arr = OpTypeArray %v2u16 %c_i32_32\n";
1825 
1826         struct CompositeType
1827         {
1828             const char *name;
1829             bool isSigned;
1830             const char *types;
1831             const char *base16;
1832             const char *base8;
1833             const char *opcode;
1834             const char *stride;
1835             unsigned count;
1836         };
1837 
1838         const CompositeType cTypes[] = {
1839             {"scalar_sint", true, sintTypes, "i16", "i8", "OpSConvert",
1840              "OpDecorate %i16arr ArrayStride 2\nOpDecorate %i8arr ArrayStride 1\n", numElements},
1841             {"scalar_uint", false, uintTypes, "u16", "u8", "OpUConvert",
1842              "OpDecorate %u16arr ArrayStride 2\nOpDecorate %u8arr ArrayStride 1\n", numElements},
1843             {"vector_sint", true, sintTypes, "v2i16", "v2i8", "OpSConvert",
1844              "OpDecorate %v2i16arr ArrayStride 4\nOpDecorate %v2i8arr ArrayStride 2\n", numElements / 2},
1845             {"vector_uint", false, uintTypes, "v2u16", "v2u8", "OpUConvert",
1846              "OpDecorate %v2u16arr ArrayStride 4\nOpDecorate %v2u8arr ArrayStride 2\n", numElements / 2},
1847         };
1848 
1849         vector<int8_t> inputs = getInt8s(rnd, numElements);
1850         vector<int16_t> sOutputs;
1851         vector<int16_t> uOutputs;
1852         const uint8_t signBitMask     = 0x80;
1853         const uint16_t signExtendMask = 0xff00;
1854 
1855         sOutputs.reserve(inputs.size());
1856         uOutputs.reserve(inputs.size());
1857 
1858         for (uint32_t numNdx = 0; numNdx < inputs.size(); ++numNdx)
1859         {
1860             uOutputs.push_back(static_cast<uint8_t>(inputs[numNdx]));
1861             if (inputs[numNdx] & signBitMask)
1862                 sOutputs.push_back(static_cast<int16_t>(inputs[numNdx] | signExtendMask));
1863             else
1864                 sOutputs.push_back(static_cast<int16_t>(inputs[numNdx]));
1865         }
1866 
1867         for (uint32_t tyIdx = 0; tyIdx < DE_LENGTH_OF_ARRAY(cTypes); ++tyIdx)
1868         {
1869             ComputeShaderSpec spec;
1870             map<string, string> specs;
1871             const char *testName = cTypes[tyIdx].name;
1872 
1873             specs["stride"]  = cTypes[tyIdx].stride;
1874             specs["base16"]  = cTypes[tyIdx].base16;
1875             specs["base8"]   = cTypes[tyIdx].base8;
1876             specs["types"]   = cTypes[tyIdx].types;
1877             specs["convert"] = cTypes[tyIdx].opcode;
1878 
1879             spec.assembly      = shaderTemplate.specialize(specs);
1880             spec.numWorkGroups = IVec3(cTypes[tyIdx].count, 1, 1);
1881             spec.pushConstants = BufferSp(new Int8Buffer(inputs));
1882 
1883             if (cTypes[tyIdx].isSigned)
1884                 spec.outputs.push_back(BufferSp(new Int16Buffer(sOutputs)));
1885             else
1886                 spec.outputs.push_back(BufferSp(new Int16Buffer(uOutputs)));
1887             spec.extensions.push_back("VK_KHR_8bit_storage");
1888             spec.extensions.push_back("VK_KHR_16bit_storage");
1889             spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1890             spec.requestedVulkanFeatures.ext8BitStorage.storagePushConstant8                = true;
1891             spec.requestedVulkanFeatures.ext16BitStorage.uniformAndStorageBuffer16BitAccess = true;
1892 
1893             group->addChild(new SpvAsmComputeShaderCase(testCtx, testName, spec));
1894         }
1895     }
1896 }
1897 
addCompute8bitStorageBuffer8To8Group(tcu::TestCaseGroup * group)1898 void addCompute8bitStorageBuffer8To8Group(tcu::TestCaseGroup *group)
1899 {
1900     tcu::TestContext &testCtx = group->getTestContext();
1901     de::Random rnd(deStringHash(group->getName()));
1902     const int numElements         = 128;
1903     const vector<int8_t> int8Data = getInt8s(rnd, numElements);
1904     const vector<int8_t> int8UnusedData(numElements, 0);
1905     ComputeShaderSpec spec;
1906     std::ostringstream shaderTemplate;
1907     shaderTemplate << "OpCapability Shader\n"
1908                    << "OpCapability StorageBuffer8BitAccess \n"
1909                    << "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1910                    << "OpExtension \"SPV_KHR_8bit_storage\"\n"
1911                    << "OpMemoryModel Logical GLSL450\n"
1912                    << "OpEntryPoint GLCompute %main \"main\" %id\n"
1913                    << "OpExecutionMode %main LocalSize 1 1 1\n"
1914                    << "OpDecorate %id BuiltIn GlobalInvocationId\n"
1915                    << "OpDecorate %i8arr ArrayStride 1\n"
1916                    << "OpDecorate %SSBO_IN Block\n"
1917                    << "OpDecorate %SSBO_OUT Block\n"
1918                    << "OpMemberDecorate %SSBO_IN 0 Coherent\n"
1919                    << "OpMemberDecorate %SSBO_OUT 0 Coherent\n"
1920                    << "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
1921                    << "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
1922                    << "OpDecorate %ssboIN DescriptorSet 0\n"
1923                    << "OpDecorate %ssboOUT DescriptorSet 0\n"
1924                    << "OpDecorate %ssboIN Binding 0\n"
1925                    << "OpDecorate %ssboOUT Binding 1\n"
1926                    << "\n"
1927                    << "%bool      = OpTypeBool\n"
1928                    << "%void      = OpTypeVoid\n"
1929                    << "%voidf     = OpTypeFunction %void\n"
1930                    << "%u32       = OpTypeInt 32 0\n"
1931                    << "%i32       = OpTypeInt 32 1\n"
1932                    << "%uvec3     = OpTypeVector %u32 3\n"
1933                    << "%uvec3ptr  = OpTypePointer Input %uvec3\n"
1934                    << "%i8        = OpTypeInt 8 1\n"
1935                    << "%i8ptr     = OpTypePointer StorageBuffer %i8\n"
1936                    << "\n"
1937                    << "%zero      = OpConstant %i32 0\n"
1938                    << "%c_size    = OpConstant %i32 " << numElements << "\n"
1939                    << "\n"
1940                    << "%i8arr     = OpTypeArray %i8 %c_size\n"
1941                    << "%SSBO_IN   = OpTypeStruct %i8arr\n"
1942                    << "%SSBO_OUT  = OpTypeStruct %i8arr\n"
1943                    << "%up_SSBOIN = OpTypePointer StorageBuffer %SSBO_IN\n"
1944                    << "%up_SSBOOUT = OpTypePointer StorageBuffer %SSBO_OUT\n"
1945                    << "%ssboIN    = OpVariable %up_SSBOIN StorageBuffer\n"
1946                    << "%ssboOUT   = OpVariable %up_SSBOOUT StorageBuffer\n"
1947                    << "\n"
1948                    << "%id        = OpVariable %uvec3ptr Input\n"
1949                    << "%main      = OpFunction %void None %voidf\n"
1950                    << "%label     = OpLabel\n"
1951                    << "%idval     = OpLoad %uvec3 %id\n"
1952                    << "%x         = OpCompositeExtract %u32 %idval 0\n"
1953                    << "%y         = OpCompositeExtract %u32 %idval 1\n"
1954                    << "\n"
1955                    << "%inlocx     = OpAccessChain %i8ptr %ssboIN %zero %x \n"
1956                    << "%valx       = OpLoad %i8 %inlocx\n"
1957                    << "%outlocx    = OpAccessChain %i8ptr %ssboOUT %zero %x \n"
1958                    << "             OpStore %outlocx %valx\n"
1959 
1960                    << "%inlocy    = OpAccessChain %i8ptr %ssboIN %zero %y \n"
1961                    << "%valy      = OpLoad %i8 %inlocy\n"
1962                    << "%outlocy   = OpAccessChain %i8ptr %ssboOUT %zero %y \n"
1963                    << "             OpStore %outlocy %valy\n"
1964                    << "\n"
1965                    << "             OpReturn\n"
1966                    << "             OpFunctionEnd\n";
1967 
1968     spec.assembly       = shaderTemplate.str();
1969     spec.numWorkGroups  = IVec3(numElements, numElements, 1);
1970     spec.verifyIO       = computeCheckBuffers;
1971     spec.coherentMemory = true;
1972     spec.inputs.push_back(BufferSp(new Int8Buffer(int8Data)));
1973     spec.outputs.push_back(BufferSp(new Int8Buffer(int8UnusedData)));
1974     spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
1975     spec.extensions.push_back("VK_KHR_8bit_storage");
1976     spec.requestedVulkanFeatures.ext8BitStorage.storageBuffer8BitAccess = true;
1977 
1978     group->addChild(new SpvAsmComputeShaderCase(testCtx, "stress_test", spec));
1979 }
1980 
addCompute8bitStorageUniform8StructTo32StructGroup(tcu::TestCaseGroup * group)1981 void addCompute8bitStorageUniform8StructTo32StructGroup(tcu::TestCaseGroup *group)
1982 {
1983     tcu::TestContext &testCtx = group->getTestContext();
1984     de::Random rnd(deStringHash(group->getName()));
1985     const StringTemplate shaderTemplate(
1986         "OpCapability Shader\n"
1987         "OpCapability ${capability}\n"
1988         "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
1989         "OpExtension \"SPV_KHR_8bit_storage\"\n"
1990         "OpMemoryModel Logical GLSL450\n"
1991         "OpEntryPoint GLCompute %main \"main\" %id\n"
1992         "OpExecutionMode %main LocalSize 1 1 1\n"
1993         "OpDecorate %id BuiltIn GlobalInvocationId\n"
1994         "\n"
1995         "${stridei8}"
1996         "\n"
1997         "${stridei32}"
1998         "\n"
1999         "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
2000         "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
2001         "OpDecorate %SSBO_IN Block\n"
2002         "OpDecorate %SSBO_OUT Block\n"
2003         "OpDecorate %ssboIN DescriptorSet 0\n"
2004         "OpDecorate %ssboOUT DescriptorSet 0\n"
2005         "OpDecorate %ssboIN Binding 0\n"
2006         "OpDecorate %ssboOUT Binding 1\n"
2007         "\n"
2008         "%bool     = OpTypeBool\n"
2009         "%void     = OpTypeVoid\n"
2010         "%voidf    = OpTypeFunction %void\n"
2011         "%u32      = OpTypeInt 32 0\n"
2012         "%uvec3    = OpTypeVector %u32 3\n"
2013         "%uvec3ptr = OpTypePointer Input %uvec3\n"
2014         "\n"
2015         "%i32      = OpTypeInt 32 1\n"
2016         "%v2i32    = OpTypeVector %i32 2\n"
2017         "%v3i32    = OpTypeVector %i32 3\n"
2018         "%v4i32    = OpTypeVector %i32 4\n"
2019         "\n"
2020         "%i8       = OpTypeInt 8 1\n"
2021         "%v2i8     = OpTypeVector %i8 2\n"
2022         "%v3i8     = OpTypeVector %i8 3\n"
2023         "%v4i8     = OpTypeVector %i8 4\n"
2024         "%i8ptr    = OpTypePointer ${8Storage} %i8\n"
2025         "%v2i8ptr  = OpTypePointer ${8Storage} %v2i8\n"
2026         "%v3i8ptr  = OpTypePointer ${8Storage} %v3i8\n"
2027         "%v4i8ptr  = OpTypePointer ${8Storage} %v4i8\n"
2028         "\n"
2029         "%i32ptr   = OpTypePointer ${32Storage} %i32\n"
2030         "%v2i32ptr = OpTypePointer ${32Storage} %v2i32\n"
2031         "%v3i32ptr = OpTypePointer ${32Storage} %v3i32\n"
2032         "%v4i32ptr = OpTypePointer ${32Storage} %v4i32\n"
2033         "\n"
2034         "%zero = OpConstant %i32 0\n"
2035         "%c_i32_1 = OpConstant %i32 1\n"
2036         "%c_i32_2 = OpConstant %i32 2\n"
2037         "%c_i32_3 = OpConstant %i32 3\n"
2038         "%c_i32_4 = OpConstant %i32 4\n"
2039         "%c_i32_5 = OpConstant %i32 5\n"
2040         "%c_i32_6 = OpConstant %i32 6\n"
2041         "%c_i32_7 = OpConstant %i32 7\n"
2042         "%c_i32_8 = OpConstant %i32 8\n"
2043         "%c_i32_9 = OpConstant %i32 9\n"
2044         "\n"
2045         "%c_u32_1 = OpConstant %u32 1\n"
2046         "%c_u32_3 = OpConstant %u32 3\n"
2047         "%c_u32_7 = OpConstant %u32 7\n"
2048         "%c_u32_11 = OpConstant %u32 11\n"
2049         "\n"
2050         "%i8arr3       = OpTypeArray %i8 %c_u32_3\n"
2051         "%v2i8arr3     = OpTypeArray %v2i8 %c_u32_3\n"
2052         "%v2i8arr11    = OpTypeArray %v2i8 %c_u32_11\n"
2053         "%v3i8arr11    = OpTypeArray %v3i8 %c_u32_11\n"
2054         "%v4i8arr3     = OpTypeArray %v4i8 %c_u32_3\n"
2055         "%struct8      = OpTypeStruct %i8 %v2i8arr3\n"
2056         "%struct8arr11 = OpTypeArray %struct8 %c_u32_11\n"
2057         "%i8Struct = OpTypeStruct %i8 %v2i8 %v3i8 %v4i8 %i8arr3 %struct8arr11 %v2i8arr11 %i8 %v3i8arr11 %v4i8arr3\n"
2058         "\n"
2059         "%i32arr3       = OpTypeArray %i32 %c_u32_3\n"
2060         "%v2i32arr3     = OpTypeArray %v2i32 %c_u32_3\n"
2061         "%v2i32arr11    = OpTypeArray %v2i32 %c_u32_11\n"
2062         "%v3i32arr11    = OpTypeArray %v3i32 %c_u32_11\n"
2063         "%v4i32arr3     = OpTypeArray %v4i32 %c_u32_3\n"
2064         "%struct32      = OpTypeStruct %i32 %v2i32arr3\n"
2065         "%struct32arr11 = OpTypeArray %struct32 %c_u32_11\n"
2066         "%i32Struct = OpTypeStruct %i32 %v2i32 %v3i32 %v4i32 %i32arr3 %struct32arr11 %v2i32arr11 %i32 %v3i32arr11 "
2067         "%v4i32arr3\n"
2068         "\n"
2069         "%i8StructArr7  = OpTypeArray %i8Struct %c_u32_7\n"
2070         "%i32StructArr7 = OpTypeArray %i32Struct %c_u32_7\n"
2071         "%SSBO_IN       = OpTypeStruct %i8StructArr7\n"
2072         "%SSBO_OUT      = OpTypeStruct %i32StructArr7\n"
2073         "%up_SSBOIN     = OpTypePointer Uniform %SSBO_IN\n"
2074         "%up_SSBOOUT    = OpTypePointer StorageBuffer %SSBO_OUT\n"
2075         "%ssboIN        = OpVariable %up_SSBOIN Uniform\n"
2076         "%ssboOUT       = OpVariable %up_SSBOOUT StorageBuffer\n"
2077         "\n"
2078         "%id        = OpVariable %uvec3ptr Input\n"
2079         "%main      = OpFunction %void None %voidf\n"
2080         "%label     = OpLabel\n"
2081         "\n"
2082         "%idval     = OpLoad %uvec3 %id\n"
2083         "%x         = OpCompositeExtract %u32 %idval 0\n"
2084         "%y         = OpCompositeExtract %u32 %idval 1\n"
2085         "\n"
2086         "%i8src  = OpAccessChain %i8ptr %ssboIN %zero %x %zero\n"
2087         "%val_i8 = OpLoad %i8 %i8src\n"
2088         "%val_i32 = OpSConvert %i32 %val_i8\n"
2089         "%i32dst  = OpAccessChain %i32ptr %ssboOUT %zero %x %zero\n"
2090         "OpStore %i32dst %val_i32\n"
2091         "\n"
2092         "%v2i8src  = OpAccessChain %v2i8ptr %ssboIN %zero %x %c_i32_1\n"
2093         "%val_v2i8 = OpLoad %v2i8 %v2i8src\n"
2094         "%val_v2i32 = OpSConvert %v2i32 %val_v2i8\n"
2095         "%v2i32dst  = OpAccessChain %v2i32ptr %ssboOUT %zero %x %c_i32_1\n"
2096         "OpStore %v2i32dst %val_v2i32\n"
2097         "\n"
2098         "%v3i8src  = OpAccessChain %v3i8ptr %ssboIN %zero %x %c_i32_2\n"
2099         "%val_v3i8 = OpLoad %v3i8 %v3i8src\n"
2100         "%val_v3i32 = OpSConvert %v3i32 %val_v3i8\n"
2101         "%v3i32dst  = OpAccessChain %v3i32ptr %ssboOUT %zero %x %c_i32_2\n"
2102         "OpStore %v3i32dst %val_v3i32\n"
2103         "\n"
2104         "%v4i8src  = OpAccessChain %v4i8ptr %ssboIN %zero %x %c_i32_3\n"
2105         "%val_v4i8 = OpLoad %v4i8 %v4i8src\n"
2106         "%val_v4i32 = OpSConvert %v4i32 %val_v4i8\n"
2107         "%v4i32dst  = OpAccessChain %v4i32ptr %ssboOUT %zero %x %c_i32_3\n"
2108         "OpStore %v4i32dst %val_v4i32\n"
2109         "\n"
2110         //struct {i8, v2i8[3]}
2111         "%Si8src  = OpAccessChain %i8ptr %ssboIN %zero %x %c_i32_5 %y %zero\n"
2112         "%Sval_i8 = OpLoad %i8 %Si8src\n"
2113         "%Sval_i32 = OpSConvert %i32 %Sval_i8\n"
2114         "%Si32dst2  = OpAccessChain %i32ptr %ssboOUT %zero %x %c_i32_5 %y %zero\n"
2115         "OpStore %Si32dst2 %Sval_i32\n"
2116         "\n"
2117         "%Sv2i8src0   = OpAccessChain %v2i8ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %zero\n"
2118         "%Sv2i8_0     = OpLoad %v2i8 %Sv2i8src0\n"
2119         "%Sv2i32_0     = OpSConvert %v2i32 %Sv2i8_0\n"
2120         "%Sv2i32dst_0  = OpAccessChain %v2i32ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %zero\n"
2121         "OpStore %Sv2i32dst_0 %Sv2i32_0\n"
2122         "\n"
2123         "%Sv2i8src1  = OpAccessChain %v2i8ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %c_i32_1\n"
2124         "%Sv2i8_1 = OpLoad %v2i8 %Sv2i8src1\n"
2125         "%Sv2i32_1 = OpSConvert %v2i32 %Sv2i8_1\n"
2126         "%Sv2i32dst_1  = OpAccessChain %v2i32ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %c_i32_1\n"
2127         "OpStore %Sv2i32dst_1 %Sv2i32_1\n"
2128         "\n"
2129         "%Sv2i8src2  = OpAccessChain %v2i8ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %c_i32_2\n"
2130         "%Sv2i8_2 = OpLoad %v2i8 %Sv2i8src2\n"
2131         "%Sv2i32_2 = OpSConvert %v2i32 %Sv2i8_2\n"
2132         "%Sv2i32dst_2  = OpAccessChain %v2i32ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %c_i32_2\n"
2133         "OpStore %Sv2i32dst_2 %Sv2i32_2\n"
2134         "\n"
2135         "%v2i8src2  = OpAccessChain %v2i8ptr %ssboIN %zero %x %c_i32_6 %y\n"
2136         "%val2_v2i8 = OpLoad %v2i8 %v2i8src2\n"
2137         "%val2_v2i32 = OpSConvert %v2i32 %val2_v2i8\n"
2138         "%v2i32dst2  = OpAccessChain %v2i32ptr %ssboOUT %zero %x %c_i32_6 %y\n"
2139         "OpStore %v2i32dst2 %val2_v2i32\n"
2140         "\n"
2141         "%i8src2  = OpAccessChain %i8ptr %ssboIN %zero %x %c_i32_7\n"
2142         "%val2_i8 = OpLoad %i8 %i8src2\n"
2143         "%val2_i32 = OpSConvert %i32 %val2_i8\n"
2144         "%i32dst2  = OpAccessChain %i32ptr %ssboOUT %zero %x %c_i32_7\n"
2145         "OpStore %i32dst2 %val2_i32\n"
2146         "\n"
2147         "%v3i8src2  = OpAccessChain %v3i8ptr %ssboIN %zero %x %c_i32_8 %y\n"
2148         "%val2_v3i8 = OpLoad %v3i8 %v3i8src2\n"
2149         "%val2_v3i32 = OpSConvert %v3i32 %val2_v3i8\n"
2150         "%v3i32dst2  = OpAccessChain %v3i32ptr %ssboOUT %zero %x %c_i32_8 %y\n"
2151         "OpStore %v3i32dst2 %val2_v3i32\n"
2152         "\n"
2153         //Array with 3 elements
2154         "%LessThan3 = OpSLessThan %bool %y %c_i32_3\n"
2155         "OpSelectionMerge %BlockIf None\n"
2156         "OpBranchConditional %LessThan3 %LabelIf %BlockIf\n"
2157         "%LabelIf = OpLabel\n"
2158         "  %i8src3  = OpAccessChain %i8ptr %ssboIN %zero %x %c_i32_4 %y\n"
2159         "  %val3_i8 = OpLoad %i8 %i8src3\n"
2160         "  %val3_i32 = OpSConvert %i32 %val3_i8\n"
2161         "  %i32dst3  = OpAccessChain %i32ptr %ssboOUT %zero %x %c_i32_4 %y\n"
2162         "  OpStore %i32dst3 %val3_i32\n"
2163         "\n"
2164         "  %v4i8src2  = OpAccessChain %v4i8ptr %ssboIN %zero %x %c_i32_9 %y\n"
2165         "  %val2_v4i8 = OpLoad %v4i8 %v4i8src2\n"
2166         "  %val2_v4i32 = OpSConvert %v4i32 %val2_v4i8\n"
2167         "  %v4i32dst2  = OpAccessChain %v4i32ptr %ssboOUT %zero %x %c_i32_9 %y\n"
2168         "  OpStore %v4i32dst2 %val2_v4i32\n"
2169         "OpBranch %BlockIf\n"
2170         "%BlockIf = OpLabel\n"
2171 
2172         "   OpReturn\n"
2173         "   OpFunctionEnd\n");
2174 
2175     { // int
2176         vector<int32_t> int32Data = data32bit(SHADERTEMPLATE_STRIDE32BIT_STD430, rnd, false);
2177 
2178         vector<int8_t> in8DData = data8bit(SHADERTEMPLATE_STRIDE8BIT_STD140, rnd);
2179         ComputeShaderSpec spec;
2180         map<string, string> specs;
2181         string testName = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
2182 
2183         specs["capability"] = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
2184         specs["stridei8"]   = getStructShaderComponet(SHADERTEMPLATE_STRIDE8BIT_STD140);
2185         specs["stridei32"]  = getStructShaderComponet(SHADERTEMPLATE_STRIDE32BIT_STD430);
2186         specs["32Storage"]  = "StorageBuffer";
2187         specs["8Storage"]   = "Uniform";
2188 
2189         spec.assembly      = shaderTemplate.specialize(specs);
2190         spec.numWorkGroups = IVec3(structData.structArraySize, structData.nestedArraySize, 1);
2191         spec.verifyIO =
2192             checkStruct<int8_t, int32_t, SHADERTEMPLATE_STRIDE8BIT_STD140, SHADERTEMPLATE_STRIDE32BIT_STD430>;
2193         spec.inputs.push_back(
2194             Resource(BufferSp(new Int8Buffer(in8DData)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
2195         spec.outputs.push_back(Resource(BufferSp(new Int32Buffer(int32Data))));
2196         spec.extensions.push_back("VK_KHR_8bit_storage");
2197         spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
2198 
2199         group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), spec));
2200     }
2201 }
2202 
addCompute8bitStorageUniform32StructTo8StructGroup(tcu::TestCaseGroup * group)2203 void addCompute8bitStorageUniform32StructTo8StructGroup(tcu::TestCaseGroup *group)
2204 {
2205     tcu::TestContext &testCtx = group->getTestContext();
2206     de::Random rnd(deStringHash(group->getName()));
2207 
2208     const StringTemplate shaderTemplate(
2209         "OpCapability Shader\n"
2210         "OpCapability ${capability}\n"
2211         "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
2212         "OpExtension \"SPV_KHR_8bit_storage\"\n"
2213         "OpMemoryModel Logical GLSL450\n"
2214         "OpEntryPoint GLCompute %main \"main\" %id\n"
2215         "OpExecutionMode %main LocalSize 1 1 1\n"
2216         "OpDecorate %id BuiltIn GlobalInvocationId\n"
2217         "\n"
2218         "${stridei8}"
2219         "\n"
2220         "${stridei32}"
2221         "\n"
2222         "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
2223         "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
2224         "OpDecorate %SSBO_IN Block\n"
2225         "OpDecorate %SSBO_OUT Block\n"
2226         "OpDecorate %ssboIN DescriptorSet 0\n"
2227         "OpDecorate %ssboOUT DescriptorSet 0\n"
2228         "OpDecorate %ssboIN Binding 0\n"
2229         "OpDecorate %ssboOUT Binding 1\n"
2230         "\n"
2231         "%bool     = OpTypeBool\n"
2232         "%void     = OpTypeVoid\n"
2233         "%voidf    = OpTypeFunction %void\n"
2234         "%u32      = OpTypeInt 32 0\n"
2235         "%uvec3    = OpTypeVector %u32 3\n"
2236         "%uvec3ptr = OpTypePointer Input %uvec3\n"
2237         "\n"
2238         "%i32      = OpTypeInt 32 1\n"
2239         "%v2i32    = OpTypeVector %i32 2\n"
2240         "%v3i32    = OpTypeVector %i32 3\n"
2241         "%v4i32    = OpTypeVector %i32 4\n"
2242         "\n"
2243         "%i8       = OpTypeInt 8 1\n"
2244         "%v2i8     = OpTypeVector %i8 2\n"
2245         "%v3i8     = OpTypeVector %i8 3\n"
2246         "%v4i8     = OpTypeVector %i8 4\n"
2247         "%i8ptr    = OpTypePointer ${8Storage} %i8\n"
2248         "%v2i8ptr  = OpTypePointer ${8Storage} %v2i8\n"
2249         "%v3i8ptr  = OpTypePointer ${8Storage} %v3i8\n"
2250         "%v4i8ptr  = OpTypePointer ${8Storage} %v4i8\n"
2251         "\n"
2252         "%i32ptr   = OpTypePointer ${32Storage} %i32\n"
2253         "%v2i32ptr = OpTypePointer ${32Storage} %v2i32\n"
2254         "%v3i32ptr = OpTypePointer ${32Storage} %v3i32\n"
2255         "%v4i32ptr = OpTypePointer ${32Storage} %v4i32\n"
2256         "\n"
2257         "%zero = OpConstant %i32 0\n"
2258         "%c_i32_1 = OpConstant %i32 1\n"
2259         "%c_i32_2 = OpConstant %i32 2\n"
2260         "%c_i32_3 = OpConstant %i32 3\n"
2261         "%c_i32_4 = OpConstant %i32 4\n"
2262         "%c_i32_5 = OpConstant %i32 5\n"
2263         "%c_i32_6 = OpConstant %i32 6\n"
2264         "%c_i32_7 = OpConstant %i32 7\n"
2265         "%c_i32_8 = OpConstant %i32 8\n"
2266         "%c_i32_9 = OpConstant %i32 9\n"
2267         "\n"
2268         "%c_u32_1 = OpConstant %u32 1\n"
2269         "%c_u32_3 = OpConstant %u32 3\n"
2270         "%c_u32_7 = OpConstant %u32 7\n"
2271         "%c_u32_11 = OpConstant %u32 11\n"
2272         "\n"
2273         "%i8arr3      = OpTypeArray %i8 %c_u32_3\n"
2274         "%v2i8arr3     = OpTypeArray %v2i8 %c_u32_3\n"
2275         "%v2i8arr11    = OpTypeArray %v2i8 %c_u32_11\n"
2276         "%v3i8arr11    = OpTypeArray %v3i8 %c_u32_11\n"
2277         "%v4i8arr3     = OpTypeArray %v4i8 %c_u32_3\n"
2278         "%struct8       = OpTypeStruct %i8 %v2i8arr3\n"
2279         "%struct8arr11 = OpTypeArray %struct8 %c_u32_11\n"
2280         "%i8Struct = OpTypeStruct %i8 %v2i8 %v3i8 %v4i8 %i8arr3 %struct8arr11 %v2i8arr11 %i8 %v3i8arr11 %v4i8arr3\n"
2281         "\n"
2282         "%i32arr3       = OpTypeArray %i32 %c_u32_3\n"
2283         "%v2i32arr3     = OpTypeArray %v2i32 %c_u32_3\n"
2284         "%v2i32arr11    = OpTypeArray %v2i32 %c_u32_11\n"
2285         "%v3i32arr11    = OpTypeArray %v3i32 %c_u32_11\n"
2286         "%v4i32arr3     = OpTypeArray %v4i32 %c_u32_3\n"
2287         "%struct32      = OpTypeStruct %i32 %v2i32arr3\n"
2288         "%struct32arr11 = OpTypeArray %struct32 %c_u32_11\n"
2289         "%i32Struct = OpTypeStruct %i32 %v2i32 %v3i32 %v4i32 %i32arr3 %struct32arr11 %v2i32arr11 %i32 %v3i32arr11 "
2290         "%v4i32arr3\n"
2291         "\n"
2292         "%i8StructArr7  = OpTypeArray %i8Struct %c_u32_7\n"
2293         "%i32StructArr7 = OpTypeArray %i32Struct %c_u32_7\n"
2294         "%SSBO_IN       = OpTypeStruct %i32StructArr7\n"
2295         "%SSBO_OUT      = OpTypeStruct %i8StructArr7\n"
2296         "%up_SSBOIN     = OpTypePointer Uniform %SSBO_IN\n"
2297         "%up_SSBOOUT    = OpTypePointer ${storage} %SSBO_OUT\n"
2298         "%ssboIN        = OpVariable %up_SSBOIN Uniform\n"
2299         "%ssboOUT       = OpVariable %up_SSBOOUT ${storage}\n"
2300         "\n"
2301         "%id        = OpVariable %uvec3ptr Input\n"
2302         "%main      = OpFunction %void None %voidf\n"
2303         "%label     = OpLabel\n"
2304         "\n"
2305         "%idval     = OpLoad %uvec3 %id\n"
2306         "%x         = OpCompositeExtract %u32 %idval 0\n"
2307         "%y         = OpCompositeExtract %u32 %idval 1\n"
2308         "\n"
2309         "%i32src  = OpAccessChain %i32ptr %ssboIN %zero %x %zero\n"
2310         "%val_i32 = OpLoad %i32 %i32src\n"
2311         "%val_i8 = OpSConvert %i8 %val_i32\n"
2312         "%i8dst  = OpAccessChain %i8ptr %ssboOUT %zero %x %zero\n"
2313         "OpStore %i8dst %val_i8\n"
2314         "\n"
2315         "%v2i32src  = OpAccessChain %v2i32ptr %ssboIN %zero %x %c_i32_1\n"
2316         "%val_v2i32 = OpLoad %v2i32 %v2i32src\n"
2317         "%val_v2i8 = OpSConvert %v2i8 %val_v2i32\n"
2318         "%v2i8dst  = OpAccessChain %v2i8ptr %ssboOUT %zero %x %c_i32_1\n"
2319         "OpStore %v2i8dst %val_v2i8\n"
2320         "\n"
2321         "%v3i32src  = OpAccessChain %v3i32ptr %ssboIN %zero %x %c_i32_2\n"
2322         "%val_v3i32 = OpLoad %v3i32 %v3i32src\n"
2323         "%val_v3i8 = OpSConvert %v3i8 %val_v3i32\n"
2324         "%v3i8dst  = OpAccessChain %v3i8ptr %ssboOUT %zero %x %c_i32_2\n"
2325         "OpStore %v3i8dst %val_v3i8\n"
2326         "\n"
2327         "%v4i32src  = OpAccessChain %v4i32ptr %ssboIN %zero %x %c_i32_3\n"
2328         "%val_v4i32 = OpLoad %v4i32 %v4i32src\n"
2329         "%val_v4i8 = OpSConvert %v4i8 %val_v4i32\n"
2330         "%v4i8dst  = OpAccessChain %v4i8ptr %ssboOUT %zero %x %c_i32_3\n"
2331         "OpStore %v4i8dst %val_v4i8\n"
2332         "\n"
2333 
2334         //struct {i8, v2i8[3]}
2335         "%Si32src  = OpAccessChain %i32ptr %ssboIN %zero %x %c_i32_5 %y %zero\n"
2336         "%Sval_i32 = OpLoad %i32 %Si32src\n"
2337         "%Sval_i8 = OpSConvert %i8 %Sval_i32\n"
2338         "%Si8dst2  = OpAccessChain %i8ptr %ssboOUT %zero %x %c_i32_5 %y %zero\n"
2339         "OpStore %Si8dst2 %Sval_i8\n"
2340         "\n"
2341         "%Sv2i32src0   = OpAccessChain %v2i32ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %zero\n"
2342         "%Sv2i32_0     = OpLoad %v2i32 %Sv2i32src0\n"
2343         "%Sv2i8_0     = OpSConvert %v2i8 %Sv2i32_0\n"
2344         "%Sv2i8dst_0  = OpAccessChain %v2i8ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %zero\n"
2345         "OpStore %Sv2i8dst_0 %Sv2i8_0\n"
2346         "\n"
2347         "%Sv2i32src1  = OpAccessChain %v2i32ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %c_i32_1\n"
2348         "%Sv2i32_1 = OpLoad %v2i32 %Sv2i32src1\n"
2349         "%Sv2i8_1 = OpSConvert %v2i8 %Sv2i32_1\n"
2350         "%Sv2i8dst_1  = OpAccessChain %v2i8ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %c_i32_1\n"
2351         "OpStore %Sv2i8dst_1 %Sv2i8_1\n"
2352         "\n"
2353         "%Sv2i32src2  = OpAccessChain %v2i32ptr %ssboIN %zero %x %c_i32_5 %y %c_i32_1 %c_i32_2\n"
2354         "%Sv2i32_2 = OpLoad %v2i32 %Sv2i32src2\n"
2355         "%Sv2i8_2 = OpSConvert %v2i8 %Sv2i32_2\n"
2356         "%Sv2i8dst_2  = OpAccessChain %v2i8ptr %ssboOUT %zero %x %c_i32_5 %y %c_i32_1 %c_i32_2\n"
2357         "OpStore %Sv2i8dst_2 %Sv2i8_2\n"
2358         "\n"
2359 
2360         "%v2i32src2  = OpAccessChain %v2i32ptr %ssboIN %zero %x %c_i32_6 %y\n"
2361         "%val2_v2i32 = OpLoad %v2i32 %v2i32src2\n"
2362         "%val2_v2i8 = OpSConvert %v2i8 %val2_v2i32\n"
2363         "%v2i8dst2  = OpAccessChain %v2i8ptr %ssboOUT %zero %x %c_i32_6 %y\n"
2364         "OpStore %v2i8dst2 %val2_v2i8\n"
2365         "\n"
2366         "%i32src2  = OpAccessChain %i32ptr %ssboIN %zero %x %c_i32_7\n"
2367         "%val2_i32 = OpLoad %i32 %i32src2\n"
2368         "%val2_i8 = OpSConvert %i8 %val2_i32\n"
2369         "%i8dst2  = OpAccessChain %i8ptr %ssboOUT %zero %x %c_i32_7\n"
2370         "OpStore %i8dst2 %val2_i8\n"
2371         "\n"
2372         "%v3i32src2  = OpAccessChain %v3i32ptr %ssboIN %zero %x %c_i32_8 %y\n"
2373         "%val2_v3i32 = OpLoad %v3i32 %v3i32src2\n"
2374         "%val2_v3i8 = OpSConvert %v3i8 %val2_v3i32\n"
2375         "%v3i8dst2  = OpAccessChain %v3i8ptr %ssboOUT %zero %x %c_i32_8 %y\n"
2376         "OpStore %v3i8dst2 %val2_v3i8\n"
2377         "\n"
2378 
2379         //Array with 3 elements
2380         "%LessThan3 = OpSLessThan %bool %y %c_i32_3\n"
2381         "OpSelectionMerge %BlockIf None\n"
2382         "OpBranchConditional %LessThan3 %LabelIf %BlockIf\n"
2383         "  %LabelIf = OpLabel\n"
2384         "  %i32src3  = OpAccessChain %i32ptr %ssboIN %zero %x %c_i32_4 %y\n"
2385         "  %val3_i32 = OpLoad %i32 %i32src3\n"
2386         "  %val3_i8 = OpSConvert %i8 %val3_i32\n"
2387         "  %i8dst3  = OpAccessChain %i8ptr %ssboOUT %zero %x %c_i32_4 %y\n"
2388         "  OpStore %i8dst3 %val3_i8\n"
2389         "\n"
2390         "  %v4i32src2  = OpAccessChain %v4i32ptr %ssboIN %zero %x %c_i32_9 %y\n"
2391         "  %val2_v4i32 = OpLoad %v4i32 %v4i32src2\n"
2392         "  %val2_v4i8 = OpSConvert %v4i8 %val2_v4i32\n"
2393         "  %v4i8dst2  = OpAccessChain %v4i8ptr %ssboOUT %zero %x %c_i32_9 %y\n"
2394         "  OpStore %v4i8dst2 %val2_v4i8\n"
2395         "OpBranch %BlockIf\n"
2396         "%BlockIf = OpLabel\n"
2397 
2398         "   OpReturn\n"
2399         "   OpFunctionEnd\n");
2400 
2401     { // Int
2402         vector<int8_t> int8Data = data8bit(SHADERTEMPLATE_STRIDE8BIT_STD430, rnd, false);
2403 
2404         ComputeShaderSpec spec;
2405         map<string, string> specs;
2406         string testName            = string(CAPABILITIES[STORAGE_BUFFER_TEST].name);
2407         vector<int32_t> int32DData = data32bit(SHADERTEMPLATE_STRIDE32BIT_STD140, rnd);
2408 
2409         specs["capability"] = CAPABILITIES[STORAGE_BUFFER_TEST].cap;
2410         specs["storage"]    = CAPABILITIES[STORAGE_BUFFER_TEST].decor;
2411         specs["stridei8"]   = getStructShaderComponet(SHADERTEMPLATE_STRIDE8BIT_STD430);
2412         specs["stridei32"]  = getStructShaderComponet(SHADERTEMPLATE_STRIDE32BIT_STD140);
2413         specs["8Storage"]   = "StorageBuffer";
2414         specs["32Storage"]  = "Uniform";
2415 
2416         spec.assembly      = shaderTemplate.specialize(specs);
2417         spec.numWorkGroups = IVec3(structData.structArraySize, structData.nestedArraySize, 1);
2418         spec.verifyIO =
2419             checkStruct<int32_t, int8_t, SHADERTEMPLATE_STRIDE32BIT_STD140, SHADERTEMPLATE_STRIDE8BIT_STD430>;
2420 
2421         spec.inputs.push_back(
2422             Resource(BufferSp(new Int32Buffer(int32DData)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
2423         spec.outputs.push_back(Resource(BufferSp(new Int8Buffer(int8Data))));
2424         spec.extensions.push_back("VK_KHR_8bit_storage");
2425         spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
2426         spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[STORAGE_BUFFER_TEST].name);
2427 
2428         group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), spec));
2429     }
2430 }
2431 
addCompute8bitStorage8bitStructMixedTypesGroup(tcu::TestCaseGroup * group)2432 void addCompute8bitStorage8bitStructMixedTypesGroup(tcu::TestCaseGroup *group)
2433 {
2434     tcu::TestContext &testCtx = group->getTestContext();
2435     de::Random rnd(deStringHash(group->getName()));
2436     vector<int8_t> outData = data8bit(SHADERTEMPLATE_STRIDEMIX_STD430, rnd, false);
2437 
2438     const StringTemplate shaderTemplate(
2439         "OpCapability Shader\n"
2440         "OpCapability StorageBuffer8BitAccess\n"
2441         "${capability}\n"
2442         "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
2443         "OpExtension \"SPV_KHR_8bit_storage\"\n"
2444         "OpMemoryModel Logical GLSL450\n"
2445         "OpEntryPoint GLCompute %main \"main\" %id\n"
2446         "OpExecutionMode %main LocalSize 1 1 1\n"
2447         "OpDecorate %id BuiltIn GlobalInvocationId\n"
2448         "${OutOffsets}"
2449         "${InOffsets}"
2450         "\n" //SSBO IN
2451         "OpDecorate %SSBO_IN Block\n"
2452         "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
2453         "OpDecorate %ssboIN DescriptorSet 0\n"
2454         "OpDecorate %ssboIN Binding 0\n"
2455         "\n" //SSBO OUT
2456         "OpDecorate %SSBO_OUT Block\n"
2457         "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
2458         "OpDecorate %ssboOUT DescriptorSet 0\n"
2459         "OpDecorate %ssboOUT Binding 1\n"
2460         "\n" //Types
2461         "%void  = OpTypeVoid\n"
2462         "%bool  = OpTypeBool\n"
2463         "%i8    = OpTypeInt 8 1\n"
2464         "%v2i8  = OpTypeVector %i8 2\n"
2465         "%v3i8  = OpTypeVector %i8 3\n"
2466         "%v4i8  = OpTypeVector %i8 4\n"
2467         "%i32   = OpTypeInt 32 1\n"
2468         "%v2i32 = OpTypeVector %i32 2\n"
2469         "%v3i32 = OpTypeVector %i32 3\n"
2470         "%v4i32 = OpTypeVector %i32 4\n"
2471         "%u32   = OpTypeInt 32 0\n"
2472         "%uvec3 = OpTypeVector %u32 3\n"
2473         "%f32   = OpTypeFloat 32\n"
2474         "%v4f32 = OpTypeVector %f32  4\n"
2475         "%voidf = OpTypeFunction %void\n"
2476         "\n" //Consta value
2477         "%zero     = OpConstant %i32 0\n"
2478         "%c_i32_1  = OpConstant %i32 1\n"
2479         "%c_i32_2  = OpConstant %i32 2\n"
2480         "%c_i32_3  = OpConstant %i32 3\n"
2481         "%c_i32_4  = OpConstant %i32 4\n"
2482         "%c_i32_5  = OpConstant %i32 5\n"
2483         "%c_i32_6  = OpConstant %i32 6\n"
2484         "%c_i32_7  = OpConstant %i32 7\n"
2485         "%c_i32_8  = OpConstant %i32 8\n"
2486         "%c_i32_9  = OpConstant %i32 9\n"
2487         "%c_i32_10 = OpConstant %i32 10\n"
2488         "%c_i32_11 = OpConstant %i32 11\n"
2489         "%c_u32_1  = OpConstant %u32 1\n"
2490         "%c_u32_7  = OpConstant %u32 7\n"
2491         "%c_u32_11 = OpConstant %u32 11\n"
2492         "\n" //Arrays & Structs
2493         "%v2b8NestedArr11In  = OpTypeArray %v2i8 %c_u32_11\n"
2494         "%b32NestedArr11In   = OpTypeArray %i32 %c_u32_11\n"
2495         "%sb8Arr11In         = OpTypeArray %i8 %c_u32_11\n"
2496         "%sb32Arr11In        = OpTypeArray %i32 %c_u32_11\n"
2497         "%sNestedIn          = OpTypeStruct %i8 %i32 %v2b8NestedArr11In %b32NestedArr11In\n"
2498         "%sNestedArr11In     = OpTypeArray %sNestedIn %c_u32_11\n"
2499         "%structIn           = OpTypeStruct %i8 %i32 %v2i8 %v2i32 %v3i8 %v3i32 %v4i8 %v4i32 %sNestedArr11In "
2500         "%sb8Arr11In %sb32Arr11In\n"
2501         "%structArr7In       = OpTypeArray %structIn %c_u32_7\n"
2502         "%v2b8NestedArr11Out = OpTypeArray %v2i8 %c_u32_11\n"
2503         "%b32NestedArr11Out  = OpTypeArray %i32 %c_u32_11\n"
2504         "%sb8Arr11Out        = OpTypeArray %i8 %c_u32_11\n"
2505         "%sb32Arr11Out       = OpTypeArray %i32 %c_u32_11\n"
2506         "%sNestedOut         = OpTypeStruct %i8 %i32 %v2b8NestedArr11Out %b32NestedArr11Out\n"
2507         "%sNestedArr11Out    = OpTypeArray %sNestedOut %c_u32_11\n"
2508         "%structOut          = OpTypeStruct %i8 %i32 %v2i8 %v2i32 %v3i8 %v3i32 %v4i8 %v4i32 %sNestedArr11Out "
2509         "%sb8Arr11Out %sb32Arr11Out\n"
2510         "%structArr7Out      = OpTypeArray %structOut %c_u32_7\n"
2511         "\n" //Pointers
2512         "${uniformPtr}"
2513         "%i8outPtr    = OpTypePointer StorageBuffer %i8\n"
2514         "%v2i8outPtr  = OpTypePointer StorageBuffer %v2i8\n"
2515         "%v3i8outPtr  = OpTypePointer StorageBuffer %v3i8\n"
2516         "%v4i8outPtr  = OpTypePointer StorageBuffer %v4i8\n"
2517         "%i32outPtr   = OpTypePointer StorageBuffer %i32\n"
2518         "%v2i32outPtr = OpTypePointer StorageBuffer %v2i32\n"
2519         "%v3i32outPtr = OpTypePointer StorageBuffer %v3i32\n"
2520         "%v4i32outPtr = OpTypePointer StorageBuffer %v4i32\n"
2521         "%fp_i32      = OpTypePointer Function %i32\n"
2522         "%uvec3ptr = OpTypePointer Input %uvec3\n"
2523         "\n" //SSBO IN
2524         "%SSBO_IN    = OpTypeStruct %structArr7In\n"
2525         "%up_SSBOIN  = OpTypePointer ${inStorage} %SSBO_IN\n"
2526         "%ssboIN     = OpVariable %up_SSBOIN ${inStorage}\n"
2527         "\n" //SSBO OUT
2528         "%SSBO_OUT   = OpTypeStruct %structArr7Out\n"
2529         "%up_SSBOOUT = OpTypePointer StorageBuffer %SSBO_OUT\n"
2530         "%ssboOUT    = OpVariable %up_SSBOOUT StorageBuffer\n"
2531         "\n" //MAIN
2532         "%id                = OpVariable %uvec3ptr Input\n"
2533         "%main              = OpFunction %void None %voidf\n"
2534         "%label             = OpLabel\n"
2535         "%ndxArrz           = OpVariable %fp_i32  Function\n"
2536         "%idval             = OpLoad %uvec3 %id\n"
2537         "%x                 = OpCompositeExtract %u32 %idval 0\n"
2538         "%y                 = OpCompositeExtract %u32 %idval 1\n"
2539         "\n" //strutOut.b8 = strutIn.b8
2540         "%inP1  = OpAccessChain %i8${inPtr} %ssboIN %zero %x %zero\n"
2541         "%inV1  = OpLoad %i8 %inP1\n"
2542         "%outP1 = OpAccessChain %i8outPtr %ssboOUT %zero %x %zero\n"
2543         "OpStore %outP1 %inV1\n"
2544         "\n" //strutOut.b32 = strutIn.b32
2545         "%inP2  = OpAccessChain %i32${inPtr} %ssboIN %zero %x %c_i32_1\n"
2546         "%inV2  = OpLoad %i32 %inP2\n"
2547         "%outP2 = OpAccessChain %i32outPtr %ssboOUT %zero %x %c_i32_1\n"
2548         "OpStore %outP2 %inV2\n"
2549         "\n" //strutOut.v2b8 = strutIn.v2b8
2550         "%inP3  = OpAccessChain %v2i8${inPtr} %ssboIN %zero %x %c_i32_2\n"
2551         "%inV3  = OpLoad %v2i8 %inP3\n"
2552         "%outP3 = OpAccessChain %v2i8outPtr %ssboOUT %zero %x %c_i32_2\n"
2553         "OpStore %outP3 %inV3\n"
2554         "\n" //strutOut.v2b32 = strutIn.v2b32
2555         "%inP4  = OpAccessChain %v2i32${inPtr} %ssboIN %zero %x %c_i32_3\n"
2556         "%inV4  = OpLoad %v2i32 %inP4\n"
2557         "%outP4 = OpAccessChain %v2i32outPtr %ssboOUT %zero %x %c_i32_3\n"
2558         "OpStore %outP4 %inV4\n"
2559         "\n" //strutOut.v3b8 = strutIn.v3b8
2560         "%inP5  = OpAccessChain %v3i8${inPtr} %ssboIN %zero %x %c_i32_4\n"
2561         "%inV5  = OpLoad %v3i8 %inP5\n"
2562         "%outP5 = OpAccessChain %v3i8outPtr %ssboOUT %zero %x %c_i32_4\n"
2563         "OpStore %outP5 %inV5\n"
2564         "\n" //strutOut.v3b32 = strutIn.v3b32
2565         "%inP6  = OpAccessChain %v3i32${inPtr} %ssboIN %zero %x %c_i32_5\n"
2566         "%inV6  = OpLoad %v3i32 %inP6\n"
2567         "%outP6 = OpAccessChain %v3i32outPtr %ssboOUT %zero %x %c_i32_5\n"
2568         "OpStore %outP6 %inV6\n"
2569         "\n" //strutOut.v4b8 = strutIn.v4b8
2570         "%inP7  = OpAccessChain %v4i8${inPtr} %ssboIN %zero %x %c_i32_6\n"
2571         "%inV7  = OpLoad %v4i8 %inP7\n"
2572         "%outP7 = OpAccessChain %v4i8outPtr %ssboOUT %zero %x %c_i32_6\n"
2573         "OpStore %outP7 %inV7\n"
2574         "\n" //strutOut.v4b32 = strutIn.v4b32
2575         "%inP8  = OpAccessChain %v4i32${inPtr} %ssboIN %zero %x %c_i32_7\n"
2576         "%inV8  = OpLoad %v4i32 %inP8\n"
2577         "%outP8 = OpAccessChain %v4i32outPtr %ssboOUT %zero %x %c_i32_7\n"
2578         "OpStore %outP8 %inV8\n"
2579         "\n" //strutOut.b8[y] = strutIn.b8[y]
2580         "%inP9  = OpAccessChain %i8${inPtr} %ssboIN %zero %x %c_i32_9 %y\n"
2581         "%inV9  = OpLoad %i8 %inP9\n"
2582         "%outP9 = OpAccessChain %i8outPtr %ssboOUT %zero %x %c_i32_9 %y\n"
2583         "OpStore %outP9 %inV9\n"
2584         "\n" //strutOut.b32[y] = strutIn.b32[y]
2585         "%inP10  = OpAccessChain %i32${inPtr} %ssboIN %zero %x %c_i32_10 %y\n"
2586         "%inV10  = OpLoad %i32 %inP10\n"
2587         "%outP10 = OpAccessChain %i32outPtr %ssboOUT %zero %x %c_i32_10 %y\n"
2588         "OpStore %outP10 %inV10\n"
2589         "\n" //strutOut.strutNestedOut[y].b8 = strutIn.strutNestedIn[y].b8
2590         "%inP11 = OpAccessChain %i8${inPtr} %ssboIN %zero %x %c_i32_8 %y %zero\n"
2591         "%inV11 = OpLoad %i8 %inP11\n"
2592         "%outP11 = OpAccessChain %i8outPtr %ssboOUT %zero %x %c_i32_8 %y %zero\n"
2593         "OpStore %outP11 %inV11\n"
2594         "\n" //strutOut.strutNestedOut[y].b32 = strutIn.strutNestedIn[y].b32
2595         "%inP12 = OpAccessChain %i32${inPtr} %ssboIN %zero %x %c_i32_8 %y %c_i32_1\n"
2596         "%inV12 = OpLoad %i32 %inP12\n"
2597         "%outP12 = OpAccessChain %i32outPtr %ssboOUT %zero %x %c_i32_8 %y %c_i32_1\n"
2598         "OpStore %outP12 %inV12\n"
2599         "\n"
2600         "${zBeginLoop}"
2601         "\n" //strutOut.strutNestedOut[y].v2b8[valNdx] = strutIn.strutNestedIn[y].v2b8[valNdx]
2602         "%inP13  = OpAccessChain %v2i8${inPtr} %ssboIN %zero %x %c_i32_8 %y %c_i32_2 %Valz\n"
2603         "%inV13  = OpLoad %v2i8 %inP13\n"
2604         "%outP13 = OpAccessChain %v2i8outPtr %ssboOUT %zero %x %c_i32_8 %y %c_i32_2 %Valz\n"
2605         "OpStore %outP13 %inV13\n"
2606         "\n" //strutOut.strutNestedOut[y].b32[valNdx] = strutIn.strutNestedIn[y].b32[valNdx]
2607         "%inP14  = OpAccessChain %i32${inPtr} %ssboIN %zero %x %c_i32_8 %y %c_i32_3 %Valz\n"
2608         "%inV14  = OpLoad %i32 %inP14\n"
2609         "%outP14 = OpAccessChain %i32outPtr %ssboOUT %zero %x %c_i32_8 %y %c_i32_3 %Valz\n"
2610         "OpStore %outP14 %inV14\n"
2611         "\n${zEndLoop}\n"
2612         "OpBranch %exitLabel\n"
2613         "%exitLabel = OpLabel\n"
2614         "OpReturn\n"
2615         "OpFunctionEnd\n");
2616 
2617     for (uint32_t capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
2618     { // int
2619         const bool isUniform = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == CAPABILITIES[capIdx].dtype;
2620         vector<int8_t> inData =
2621             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);
2627 
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 ? "%i8inPtr     = OpTypePointer Uniform %i8\n"
2635                                             "%v2i8inPtr   = OpTypePointer Uniform %v2i8\n"
2636                                             "%v3i8inPtr   = OpTypePointer Uniform %v3i8\n"
2637                                             "%v4i8inPtr   = OpTypePointer Uniform %v4i8\n"
2638                                             "%i32inPtr    = OpTypePointer Uniform %i32\n"
2639                                             "%v2i32inPtr  = OpTypePointer Uniform %v2i32\n"
2640                                             "%v3i32inPtr  = OpTypePointer Uniform %v3i32\n"
2641                                             "%v4i32inPtr  = OpTypePointer Uniform %v4i32\n" :
2642                                             "";
2643         specs["inPtr"]        = isUniform ? "inPtr" : "outPtr";
2644         specsOffset["InOut"]  = "In";
2645         specs["InOffsets"]    = StringTemplate(isUniform ? getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD140) :
2646                                                            getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD430))
2647                                  .specialize(specsOffset);
2648         specsOffset["InOut"] = "Out";
2649         specs["OutOffsets"] =
2650             StringTemplate(getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD430)).specialize(specsOffset);
2651         if (isUniform)
2652         {
2653             specs["capability"] = "OpCapability " + string(CAPABILITIES[capIdx].cap);
2654         }
2655 
2656         spec.assembly      = shaderTemplate.specialize(specs);
2657         spec.numWorkGroups = IVec3(structData.structArraySize, structData.nestedArraySize, 1);
2658         spec.verifyIO =
2659             isUniform ? checkStruct<int8_t, int8_t, SHADERTEMPLATE_STRIDEMIX_STD140, SHADERTEMPLATE_STRIDEMIX_STD430> :
2660                         checkStruct<int8_t, int8_t, SHADERTEMPLATE_STRIDEMIX_STD430, SHADERTEMPLATE_STRIDEMIX_STD430>;
2661         spec.inputs.push_back(Resource(BufferSp(new Int8Buffer(inData)), CAPABILITIES[capIdx].dtype));
2662         spec.outputs.push_back(Resource(BufferSp(new Int8Buffer(outData))));
2663         spec.extensions.push_back("VK_KHR_8bit_storage");
2664         spec.extensions.push_back("VK_KHR_storage_buffer_storage_class");
2665         spec.requestedVulkanFeatures = get8BitStorageFeatures(CAPABILITIES[capIdx].name);
2666 
2667         group->addChild(new SpvAsmComputeShaderCase(testCtx, testName.c_str(), spec));
2668     }
2669 }
2670 
addGraphics8BitStorageUniformInt32To8Group(tcu::TestCaseGroup * testGroup)2671 void addGraphics8BitStorageUniformInt32To8Group(tcu::TestCaseGroup *testGroup)
2672 {
2673     de::Random rnd(deStringHash(testGroup->getName()));
2674     map<string, string> fragments;
2675     const uint32_t numDataPoints = 256u;
2676     RGBA defaultColors[4];
2677     GraphicsResources resources;
2678     vector<string> extensions;
2679     const StringTemplate capabilities("OpCapability ${cap}\n");
2680     vector<int8_t> outputs(numDataPoints);
2681 
2682     extensions.push_back("VK_KHR_8bit_storage");
2683     fragments["extension"] = "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
2684                              "OpExtension \"SPV_KHR_8bit_storage\"";
2685 
2686     getDefaultColors(defaultColors);
2687 
2688     struct IntegerFacts
2689     {
2690         const char *name;
2691         const char *type32;
2692         const char *type8;
2693         const char *opcode;
2694         const char *isSigned;
2695     };
2696 
2697     const IntegerFacts intFacts[] = {
2698         {"sint", "%i32", "%i8", "OpSConvert", "1"},
2699         {"uint", "%u32", "%u8", "OpUConvert", "0"},
2700     };
2701 
2702     const StringTemplate scalarPreMain("${itype8} = OpTypeInt 8 ${signed}\n"
2703                                        "%c_i32_256 = OpConstant %i32 256\n"
2704                                        "   %up_i32 = OpTypePointer Uniform ${itype32}\n"
2705                                        "   %up_i8 = OpTypePointer StorageBuffer ${itype8}\n"
2706                                        "   %ra_i32 = OpTypeArray ${itype32} %c_i32_256\n"
2707                                        "   %ra_i8 = OpTypeArray ${itype8} %c_i32_256\n"
2708                                        "   %SSBO32 = OpTypeStruct %ra_i32\n"
2709                                        "   %SSBO8 = OpTypeStruct %ra_i8\n"
2710                                        "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2711                                        "%up_SSBO8 = OpTypePointer StorageBuffer %SSBO8\n"
2712                                        "   %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2713                                        "   %ssbo8 = OpVariable %up_SSBO8 StorageBuffer\n");
2714 
2715     const StringTemplate scalarDecoration("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");
2725 
2726     const StringTemplate scalarTestFunc("%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
2727                                         "    %param = OpFunctionParameter %v4f32\n"
2728 
2729                                         "%entry = OpLabel\n"
2730                                         "    %i = OpVariable %fp_i32 Function\n"
2731                                         "         OpStore %i %c_i32_0\n"
2732                                         "         OpBranch %loop\n"
2733 
2734                                         " %loop = OpLabel\n"
2735                                         "   %15 = OpLoad %i32 %i\n"
2736                                         "   %lt = OpSLessThan %bool %15 %c_i32_256\n"
2737                                         "         OpLoopMerge %merge %inc None\n"
2738                                         "         OpBranchConditional %lt %write %merge\n"
2739 
2740                                         "%write = OpLabel\n"
2741                                         "   %30 = OpLoad %i32 %i\n"
2742                                         "  %src = OpAccessChain %up_i32 %ssbo32 %c_i32_0 %30\n"
2743                                         "%val32 = OpLoad ${itype32} %src\n"
2744                                         "%val8 = ${convert} ${itype8} %val32\n"
2745                                         "  %dst = OpAccessChain %up_i8 %ssbo8 %c_i32_0 %30\n"
2746                                         "         OpStore %dst %val8\n"
2747                                         "         OpBranch %inc\n"
2748 
2749                                         "  %inc = OpLabel\n"
2750                                         "   %37 = OpLoad %i32 %i\n"
2751                                         "   %39 = OpIAdd %i32 %37 %c_i32_1\n"
2752                                         "         OpStore %i %39\n"
2753                                         "         OpBranch %loop\n"
2754 
2755                                         "%merge = OpLabel\n"
2756                                         "         OpReturnValue %param\n"
2757 
2758                                         "OpFunctionEnd\n");
2759 
2760     const StringTemplate vecPreMain("${itype8} = OpTypeInt 8 ${signed}\n"
2761                                     " %c_i32_64 = OpConstant %i32 64\n"
2762                                     "%v4itype8 = OpTypeVector ${itype8} 4\n"
2763                                     " %up_v4i32 = OpTypePointer Uniform ${v4itype32}\n"
2764                                     " %up_v4i8 = OpTypePointer StorageBuffer %v4itype8\n"
2765                                     " %ra_v4i32 = OpTypeArray ${v4itype32} %c_i32_64\n"
2766                                     " %ra_v4i8 = OpTypeArray %v4itype8 %c_i32_64\n"
2767                                     "   %SSBO32 = OpTypeStruct %ra_v4i32\n"
2768                                     "   %SSBO8 = OpTypeStruct %ra_v4i8\n"
2769                                     "%up_SSBO32 = OpTypePointer Uniform %SSBO32\n"
2770                                     "%up_SSBO8 = OpTypePointer StorageBuffer %SSBO8\n"
2771                                     "   %ssbo32 = OpVariable %up_SSBO32 Uniform\n"
2772                                     "   %ssbo8 = OpVariable %up_SSBO8 StorageBuffer\n");
2773 
2774     const StringTemplate vecDecoration("OpDecorate %ra_v4i32 ArrayStride 16\n"
2775                                        "OpDecorate %ra_v4i8 ArrayStride 4\n"
2776                                        "OpDecorate %SSBO32 Block\n"
2777                                        "OpDecorate %SSBO8 Block\n"
2778                                        "OpMemberDecorate %SSBO32 0 Offset 0\n"
2779                                        "OpMemberDecorate %SSBO8 0 Offset 0\n"
2780                                        "OpDecorate %ssbo32 DescriptorSet 0\n"
2781                                        "OpDecorate %ssbo8 DescriptorSet 0\n"
2782                                        "OpDecorate %ssbo32 Binding 0\n"
2783                                        "OpDecorate %ssbo8 Binding 1\n");
2784 
2785     const StringTemplate vecTestFunc("%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
2786                                      "    %param = OpFunctionParameter %v4f32\n"
2787 
2788                                      "%entry = OpLabel\n"
2789                                      "    %i = OpVariable %fp_i32 Function\n"
2790                                      "         OpStore %i %c_i32_0\n"
2791                                      "         OpBranch %loop\n"
2792 
2793                                      " %loop = OpLabel\n"
2794                                      "   %15 = OpLoad %i32 %i\n"
2795                                      "   %lt = OpSLessThan %bool %15 %c_i32_64\n"
2796                                      "         OpLoopMerge %merge %inc None\n"
2797                                      "         OpBranchConditional %lt %write %merge\n"
2798 
2799                                      "%write = OpLabel\n"
2800                                      "   %30 = OpLoad %i32 %i\n"
2801                                      "  %src = OpAccessChain %up_v4i32 %ssbo32 %c_i32_0 %30\n"
2802                                      "%val32 = OpLoad ${v4itype32} %src\n"
2803                                      "%val8 = ${convert} %v4itype8 %val32\n"
2804                                      "  %dst = OpAccessChain %up_v4i8 %ssbo8 %c_i32_0 %30\n"
2805                                      "         OpStore %dst %val8\n"
2806                                      "         OpBranch %inc\n"
2807 
2808                                      "  %inc = OpLabel\n"
2809                                      "   %37 = OpLoad %i32 %i\n"
2810                                      "   %39 = OpIAdd %i32 %37 %c_i32_1\n"
2811                                      "         OpStore %i %39\n"
2812                                      "         OpBranch %loop\n"
2813 
2814                                      "%merge = OpLabel\n"
2815                                      "         OpReturnValue %param\n"
2816 
2817                                      "OpFunctionEnd\n");
2818 
2819     struct Category
2820     {
2821         const char *name;
2822         const StringTemplate &preMain;
2823         const StringTemplate &decoration;
2824         const StringTemplate &testFunction;
2825         const uint32_t numElements;
2826     };
2827 
2828     const Category categories[] = {
2829         {"scalar", scalarPreMain, scalarDecoration, scalarTestFunc, 1},
2830         {"vector", vecPreMain, vecDecoration, vecTestFunc, 4},
2831     };
2832 
2833     for (uint32_t catIdx = 0; catIdx < DE_LENGTH_OF_ARRAY(categories); ++catIdx)
2834     {
2835         resources.inputs.clear();
2836         resources.outputs.clear();
2837         vector<int32_t> inputs =
2838             getInt32s(rnd, ((arrayStrideInBytesUniform / static_cast<uint32_t>(sizeof(int32_t))) * numDataPoints) /
2839                                categories[catIdx].numElements);
2840 
2841         if (0 != (arrayStrideInBytesUniform - static_cast<uint32_t>(sizeof(int32_t)) * categories[catIdx].numElements))
2842             resources.verifyIO = checkUniformsArray<int32_t, int8_t, 1>;
2843         else
2844         {
2845             resources.verifyIO = DE_NULL;
2846             for (uint32_t numNdx = 0; numNdx < numDataPoints; ++numNdx)
2847                 outputs[numNdx] = static_cast<int8_t>(0xffff & inputs[numNdx]);
2848         }
2849 
2850         resources.inputs.push_back(
2851             Resource(BufferSp(new Int32Buffer(inputs)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
2852         resources.outputs.push_back(Resource(BufferSp(new Int8Buffer(outputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
2853 
2854         for (uint32_t factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
2855         {
2856             map<string, string> specs;
2857             VulkanFeatures features;
2858             string name = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name) + "_" + categories[catIdx].name +
2859                           "_" + intFacts[factIdx].name;
2860 
2861             specs["cap"]       = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
2862             specs["itype32"]   = intFacts[factIdx].type32;
2863             specs["v4itype32"] = "%v4" + string(intFacts[factIdx].type32).substr(1);
2864             specs["itype8"]    = intFacts[factIdx].type8;
2865             specs["signed"]    = intFacts[factIdx].isSigned;
2866             specs["convert"]   = intFacts[factIdx].opcode;
2867 
2868             fragments["pre_main"]   = categories[catIdx].preMain.specialize(specs);
2869             fragments["testfun"]    = categories[catIdx].testFunction.specialize(specs);
2870             fragments["capability"] = capabilities.specialize(specs);
2871             fragments["decoration"] = categories[catIdx].decoration.specialize(specs);
2872 
2873             features = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
2874             features.coreFeatures.vertexPipelineStoresAndAtomics = true;
2875             features.coreFeatures.fragmentStoresAndAtomics       = true;
2876 
2877             createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup,
2878                                     features);
2879         }
2880     }
2881 }
2882 
addGraphics8BitStorageUniformInt8To32Group(tcu::TestCaseGroup * testGroup)2883 void addGraphics8BitStorageUniformInt8To32Group(tcu::TestCaseGroup *testGroup)
2884 {
2885     de::Random rnd(deStringHash(testGroup->getName()));
2886     map<string, string> fragments;
2887     const uint32_t numDataPoints = 256;
2888     RGBA defaultColors[4];
2889     vector<int32_t> outputs(numDataPoints);
2890     GraphicsResources resources;
2891     vector<string> extensions;
2892     const StringTemplate capabilities("OpCapability ${cap}\n");
2893 
2894     extensions.push_back("VK_KHR_8bit_storage");
2895     fragments["extension"] = "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
2896                              "OpExtension \"SPV_KHR_8bit_storage\"";
2897 
2898     getDefaultColors(defaultColors);
2899 
2900     struct IntegerFacts
2901     {
2902         const char *name;
2903         const char *type32;
2904         const char *type8;
2905         const char *opcode;
2906         bool isSigned;
2907     };
2908 
2909     const IntegerFacts intFacts[] = {
2910         {"sint", "%i32", "%i8", "OpSConvert", true},
2911         {"uint", "%u32", "%u8", "OpUConvert", false},
2912     };
2913 
2914     struct ConstantIndex
2915     {
2916         bool useConstantIndex;
2917         uint32_t constantIndex;
2918     };
2919 
2920     ConstantIndex constantIndices[] = {{false, 0}, {true, 4}, {true, 5}, {true, 6}};
2921 
2922     const StringTemplate scalarPreMain("${itype8} = OpTypeInt 8 ${signed}\n"
2923                                        " %c_i32_256 = OpConstant %i32 256\n"
2924                                        "%c_i32_ci  = OpConstant %i32 ${constarrayidx}\n"
2925                                        "   %up_i32 = OpTypePointer StorageBuffer ${itype32}\n"
2926                                        "   %up_i8 = OpTypePointer Uniform ${itype8}\n"
2927                                        "   %ra_i32 = OpTypeArray ${itype32} %c_i32_256\n"
2928                                        "   %ra_i8 = OpTypeArray ${itype8} %c_i32_256\n"
2929                                        "   %SSBO32 = OpTypeStruct %ra_i32\n"
2930                                        "   %SSBO8 = OpTypeStruct %ra_i8\n"
2931                                        "%up_SSBO32 = OpTypePointer StorageBuffer %SSBO32\n"
2932                                        "%up_SSBO8 = OpTypePointer Uniform %SSBO8\n"
2933                                        "   %ssbo32 = OpVariable %up_SSBO32 StorageBuffer\n"
2934                                        "   %ssbo8 = OpVariable %up_SSBO8 Uniform\n");
2935 
2936     const StringTemplate scalarDecoration("OpDecorate %ra_i32 ArrayStride 4\n"
2937                                           "OpDecorate %ra_i8 ArrayStride 16\n"
2938                                           "OpDecorate %SSBO32 Block\n"
2939                                           "OpDecorate %SSBO8 Block\n"
2940                                           "OpMemberDecorate %SSBO32 0 Offset 0\n"
2941                                           "OpMemberDecorate %SSBO8 0 Offset 0\n"
2942                                           "OpDecorate %ssbo32 DescriptorSet 0\n"
2943                                           "OpDecorate %ssbo8 DescriptorSet 0\n"
2944                                           "OpDecorate %ssbo32 Binding 1\n"
2945                                           "OpDecorate %ssbo8 Binding 0\n");
2946 
2947     const StringTemplate scalarTestFunc("%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
2948                                         "    %param = OpFunctionParameter %v4f32\n"
2949 
2950                                         "%entry = OpLabel\n"
2951                                         "    %i = OpVariable %fp_i32 Function\n"
2952                                         "         OpStore %i %c_i32_0\n"
2953                                         "         OpBranch %loop\n"
2954 
2955                                         " %loop = OpLabel\n"
2956                                         "   %15 = OpLoad %i32 %i\n"
2957                                         "   %lt = OpSLessThan %bool %15 %c_i32_256\n"
2958                                         "         OpLoopMerge %merge %inc None\n"
2959                                         "         OpBranchConditional %lt %write %merge\n"
2960 
2961                                         "%write = OpLabel\n"
2962                                         "   %30 = OpLoad %i32 %i\n"
2963                                         "  %src = OpAccessChain %up_i8 %ssbo8 %c_i32_0 %${arrayindex}\n"
2964                                         "%val8 = OpLoad ${itype8} %src\n"
2965                                         "%val32 = ${convert} ${itype32} %val8\n"
2966                                         "  %dst = OpAccessChain %up_i32 %ssbo32 %c_i32_0 %30\n"
2967                                         "         OpStore %dst %val32\n"
2968                                         "         OpBranch %inc\n"
2969 
2970                                         "  %inc = OpLabel\n"
2971                                         "   %37 = OpLoad %i32 %i\n"
2972                                         "   %39 = OpIAdd %i32 %37 %c_i32_1\n"
2973                                         "         OpStore %i %39\n"
2974                                         "         OpBranch %loop\n"
2975                                         "%merge = OpLabel\n"
2976                                         "         OpReturnValue %param\n"
2977 
2978                                         "OpFunctionEnd\n");
2979 
2980     const StringTemplate vecPreMain("${itype8} = OpTypeInt 8 ${signed}\n"
2981                                     "%c_i32_128 = OpConstant %i32 128\n"
2982                                     "%c_i32_ci  = OpConstant %i32 ${constarrayidx}\n"
2983                                     "%v2itype8 = OpTypeVector ${itype8} 2\n"
2984                                     " %up_v2i32 = OpTypePointer StorageBuffer ${v2itype32}\n"
2985                                     " %up_v2i8 = OpTypePointer Uniform %v2itype8\n"
2986                                     " %ra_v2i32 = OpTypeArray ${v2itype32} %c_i32_128\n"
2987                                     " %ra_v2i8 = OpTypeArray %v2itype8 %c_i32_128\n"
2988                                     "   %SSBO32 = OpTypeStruct %ra_v2i32\n"
2989                                     "   %SSBO8 = OpTypeStruct %ra_v2i8\n"
2990                                     "%up_SSBO32 = OpTypePointer StorageBuffer %SSBO32\n"
2991                                     "%up_SSBO8 = OpTypePointer Uniform %SSBO8\n"
2992                                     "   %ssbo32 = OpVariable %up_SSBO32 StorageBuffer\n"
2993                                     "   %ssbo8 = OpVariable %up_SSBO8 Uniform\n");
2994 
2995     const StringTemplate vecDecoration("OpDecorate %ra_v2i32 ArrayStride 8\n"
2996                                        "OpDecorate %ra_v2i8 ArrayStride 16\n"
2997                                        "OpDecorate %SSBO32 Block\n"
2998                                        "OpDecorate %SSBO8 Block\n"
2999                                        "OpMemberDecorate %SSBO32 0 Offset 0\n"
3000                                        "OpMemberDecorate %SSBO8 0 Offset 0\n"
3001                                        "OpDecorate %ssbo32 DescriptorSet 0\n"
3002                                        "OpDecorate %ssbo8 DescriptorSet 0\n"
3003                                        "OpDecorate %ssbo32 Binding 1\n"
3004                                        "OpDecorate %ssbo8 Binding 0\n");
3005 
3006     const StringTemplate vecTestFunc("%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3007                                      "    %param = OpFunctionParameter %v4f32\n"
3008 
3009                                      "%entry = OpLabel\n"
3010                                      "    %i = OpVariable %fp_i32 Function\n"
3011                                      "         OpStore %i %c_i32_0\n"
3012                                      "         OpBranch %loop\n"
3013 
3014                                      " %loop = OpLabel\n"
3015                                      "   %15 = OpLoad %i32 %i\n"
3016                                      "   %lt = OpSLessThan %bool %15 %c_i32_128\n"
3017                                      "         OpLoopMerge %merge %inc None\n"
3018                                      "         OpBranchConditional %lt %write %merge\n"
3019 
3020                                      "%write = OpLabel\n"
3021                                      "   %30 = OpLoad %i32 %i\n"
3022                                      "  %src = OpAccessChain %up_v2i8 %ssbo8 %c_i32_0 %${arrayindex}\n"
3023                                      "%val8 = OpLoad %v2itype8 %src\n"
3024                                      "%val32 = ${convert} ${v2itype32} %val8\n"
3025                                      "  %dst = OpAccessChain %up_v2i32 %ssbo32 %c_i32_0 %30\n"
3026                                      "         OpStore %dst %val32\n"
3027                                      "         OpBranch %inc\n"
3028 
3029                                      "  %inc = OpLabel\n"
3030                                      "   %37 = OpLoad %i32 %i\n"
3031                                      "   %39 = OpIAdd %i32 %37 %c_i32_1\n"
3032                                      "         OpStore %i %39\n"
3033                                      "         OpBranch %loop\n"
3034                                      "%merge = OpLabel\n"
3035                                      "         OpReturnValue %param\n"
3036 
3037                                      "OpFunctionEnd\n");
3038 
3039     struct Category
3040     {
3041         const char *name;
3042         const StringTemplate &preMain;
3043         const StringTemplate &decoration;
3044         const StringTemplate &testFunction;
3045         const uint32_t numElements;
3046     };
3047 
3048     const Category categories[] = {
3049         {"scalar", scalarPreMain, scalarDecoration, scalarTestFunc, 1},
3050         {"vector", vecPreMain, vecDecoration, vecTestFunc, 2},
3051     };
3052 
3053     for (uint32_t catIdx = 0; catIdx < DE_LENGTH_OF_ARRAY(categories); ++catIdx)
3054     {
3055         resources.inputs.clear();
3056         vector<int8_t> inputs = getInt8s(rnd, (arrayStrideInBytesUniform / static_cast<uint32_t>(sizeof(int8_t))) *
3057                                                   (numDataPoints / categories[catIdx].numElements));
3058         resources.inputs.push_back(
3059             Resource(BufferSp(new Int8Buffer(inputs)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
3060         for (uint32_t factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
3061             for (uint32_t constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
3062             {
3063                 bool useConstIdx  = constantIndices[constIndexIdx].useConstantIndex;
3064                 uint32_t constIdx = constantIndices[constIndexIdx].constantIndex;
3065                 map<string, string> specs;
3066                 VulkanFeatures features;
3067                 string name = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name) + "_" +
3068                               categories[catIdx].name + "_" + intFacts[factIdx].name;
3069 
3070                 specs["cap"]       = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
3071                 specs["itype32"]   = intFacts[factIdx].type32;
3072                 specs["v2itype32"] = "%v2" + string(intFacts[factIdx].type32).substr(1);
3073                 specs["itype8"]    = intFacts[factIdx].type8;
3074                 if (intFacts[factIdx].isSigned)
3075                     specs["signed"] = "1";
3076                 else
3077                     specs["signed"] = "0";
3078                 specs["convert"]       = intFacts[factIdx].opcode;
3079                 specs["constarrayidx"] = de::toString(constIdx);
3080                 if (useConstIdx)
3081                     specs["arrayindex"] = "c_i32_ci";
3082                 else
3083                     specs["arrayindex"] = "30";
3084 
3085                 fragments["pre_main"]   = categories[catIdx].preMain.specialize(specs);
3086                 fragments["testfun"]    = categories[catIdx].testFunction.specialize(specs);
3087                 fragments["capability"] = capabilities.specialize(specs);
3088                 fragments["decoration"] = categories[catIdx].decoration.specialize(specs);
3089 
3090                 if (useConstIdx)
3091                     name += string("_const_idx_") + de::toString(constIdx);
3092 
3093                 resources.outputs.clear();
3094                 resources.outputs.push_back(
3095                     Resource(BufferSp(new Int32Buffer(outputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3096                 if (useConstIdx)
3097                 {
3098                     switch (constantIndices[constIndexIdx].constantIndex)
3099                     {
3100                     case 0:
3101                         if (categories[catIdx].numElements == 2)
3102                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int32_t, 2, 0>;
3103                         else
3104                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int32_t, 1, 0>;
3105                         break;
3106                     case 4:
3107                         if (categories[catIdx].numElements == 2)
3108                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int32_t, 2, 4>;
3109                         else
3110                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int32_t, 1, 4>;
3111                         break;
3112                     case 5:
3113                         if (categories[catIdx].numElements == 2)
3114                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int32_t, 2, 5>;
3115                         else
3116                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int32_t, 1, 5>;
3117                         break;
3118                     case 6:
3119                         if (categories[catIdx].numElements == 2)
3120                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int32_t, 2, 6>;
3121                         else
3122                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int32_t, 1, 6>;
3123                         break;
3124                     default:
3125                         DE_FATAL("Impossible");
3126                         break;
3127                     }
3128                 }
3129                 else
3130                 {
3131                     if (categories[catIdx].numElements == 2)
3132                         resources.verifyIO = checkUniformsArray<int8_t, int32_t, 2>;
3133                     else
3134                         resources.verifyIO = checkUniformsArray<int8_t, int32_t, 1>;
3135                 }
3136 
3137                 features = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
3138                 features.coreFeatures.vertexPipelineStoresAndAtomics = true;
3139                 features.coreFeatures.fragmentStoresAndAtomics       = true;
3140 
3141                 createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup,
3142                                         features);
3143             }
3144     }
3145 }
3146 
addGraphics8BitStoragePushConstantInt8To32Group(tcu::TestCaseGroup * testGroup)3147 void addGraphics8BitStoragePushConstantInt8To32Group(tcu::TestCaseGroup *testGroup)
3148 {
3149     de::Random rnd(deStringHash(testGroup->getName()));
3150     map<string, string> fragments;
3151     RGBA defaultColors[4];
3152     const uint32_t numDataPoints = 64;
3153     vector<int8_t> inputs        = getInt8s(rnd, numDataPoints);
3154     vector<int32_t> sOutputs;
3155     vector<int32_t> uOutputs;
3156     PushConstants pcs;
3157     GraphicsResources resources;
3158     vector<string> extensions;
3159     const uint8_t signBitMask     = 0x80;
3160     const uint32_t signExtendMask = 0xffff0000;
3161     VulkanFeatures requiredFeatures;
3162 
3163     struct ConstantIndex
3164     {
3165         bool useConstantIndex;
3166         uint32_t constantIndex;
3167     };
3168 
3169     ConstantIndex constantIndices[] = {{false, 0}, {true, 4}, {true, 5}, {true, 6}};
3170 
3171     sOutputs.reserve(inputs.size());
3172     uOutputs.reserve(inputs.size());
3173 
3174     for (uint32_t numNdx = 0; numNdx < inputs.size(); ++numNdx)
3175     {
3176         uOutputs.push_back(static_cast<uint8_t>(inputs[numNdx]));
3177         if (inputs[numNdx] & signBitMask)
3178             sOutputs.push_back(static_cast<int32_t>(inputs[numNdx] | signExtendMask));
3179         else
3180             sOutputs.push_back(static_cast<int32_t>(inputs[numNdx]));
3181     }
3182 
3183     extensions.push_back("VK_KHR_8bit_storage");
3184 
3185     requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics = true;
3186     requiredFeatures.coreFeatures.fragmentStoresAndAtomics       = true;
3187     requiredFeatures.ext8BitStorage.storagePushConstant8         = true;
3188 
3189     fragments["capability"] = "OpCapability StoragePushConstant8\n";
3190     fragments["extension"]  = "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
3191                               "OpExtension \"SPV_KHR_8bit_storage\"";
3192 
3193     pcs.setPushConstant(BufferSp(new Int8Buffer(inputs)));
3194 
3195     getDefaultColors(defaultColors);
3196 
3197     const StringTemplate testFun("%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3198                                  "    %param = OpFunctionParameter %v4f32\n"
3199 
3200                                  "%entry = OpLabel\n"
3201                                  "    %i = OpVariable %fp_i32 Function\n"
3202                                  "         OpStore %i %c_i32_0\n"
3203                                  "         OpBranch %loop\n"
3204 
3205                                  " %loop = OpLabel\n"
3206                                  "   %15 = OpLoad %i32 %i\n"
3207                                  "   %lt = OpSLessThan %bool %15 %c_i32_${count}\n"
3208                                  "         OpLoopMerge %merge %inc None\n"
3209                                  "         OpBranchConditional %lt %write %merge\n"
3210 
3211                                  "%write = OpLabel\n"
3212                                  "   %30 = OpLoad %i32 %i\n"
3213                                  "  %src = OpAccessChain %pp_${type8} %pc8 %c_i32_0 %${arrayindex}\n"
3214                                  "%val8 = OpLoad %${type8} %src\n"
3215                                  "%val32 = ${convert} %${type32} %val8\n"
3216                                  "  %dst = OpAccessChain %up_${type32} %ssbo32 %c_i32_0 %30\n"
3217                                  "         OpStore %dst %val32\n"
3218                                  "         OpBranch %inc\n"
3219 
3220                                  "  %inc = OpLabel\n"
3221                                  "   %37 = OpLoad %i32 %i\n"
3222                                  "   %39 = OpIAdd %i32 %37 %c_i32_1\n"
3223                                  "         OpStore %i %39\n"
3224                                  "         OpBranch %loop\n"
3225 
3226                                  "%merge = OpLabel\n"
3227                                  "         OpReturnValue %param\n"
3228 
3229                                  "OpFunctionEnd\n");
3230 
3231     { // Scalar cases
3232         const StringTemplate preMain(
3233             "         %${type8} = OpTypeInt 8 ${signed}\n"
3234             "    %c_i32_${count} = OpConstant %i32 ${count}\n" // Should be the same as numDataPoints
3235             "         %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
3236             "%a${count}${type8} = OpTypeArray %${type8} %c_i32_${count}\n"
3237             "%a${count}${type32} = OpTypeArray %${type32} %c_i32_${count}\n"
3238             "      %pp_${type8} = OpTypePointer PushConstant %${type8}\n"
3239             "      %up_${type32} = OpTypePointer StorageBuffer      %${type32}\n"
3240             "            %SSBO32 = OpTypeStruct %a${count}${type32}\n"
3241             "         %up_SSBO32 = OpTypePointer StorageBuffer %SSBO32\n"
3242             "            %ssbo32 = OpVariable %up_SSBO32 StorageBuffer\n"
3243             "              %PC8 = OpTypeStruct %a${count}${type8}\n"
3244             "           %pp_PC8 = OpTypePointer PushConstant %PC8\n"
3245             "              %pc8 = OpVariable %pp_PC8 PushConstant\n");
3246 
3247         const StringTemplate decoration("OpDecorate %a${count}${type8} ArrayStride 1\n"
3248                                         "OpDecorate %a${count}${type32} ArrayStride 4\n"
3249                                         "OpDecorate %SSBO32 Block\n"
3250                                         "OpMemberDecorate %SSBO32 0 Offset 0\n"
3251                                         "OpDecorate %PC8 Block\n"
3252                                         "OpMemberDecorate %PC8 0 Offset 0\n"
3253                                         "OpDecorate %ssbo32 DescriptorSet 0\n"
3254                                         "OpDecorate %ssbo32 Binding 0\n");
3255 
3256         { // signed int
3257             map<string, string> specs;
3258 
3259             specs["type8"]   = "i8";
3260             specs["type32"]  = "i32";
3261             specs["signed"]  = "1";
3262             specs["count"]   = "64";
3263             specs["convert"] = "OpSConvert";
3264 
3265             for (uint32_t constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
3266             {
3267                 bool useConstIdx  = constantIndices[constIndexIdx].useConstantIndex;
3268                 uint32_t constIdx = constantIndices[constIndexIdx].constantIndex;
3269                 string testName   = "sint_scalar";
3270                 vector<int32_t> constIdxData;
3271 
3272                 if (useConstIdx)
3273                 {
3274                     constIdxData.reserve(numDataPoints);
3275 
3276                     for (uint32_t numIdx = 0; numIdx < numDataPoints; ++numIdx)
3277                         constIdxData.push_back(sOutputs[constIdx]);
3278                 }
3279 
3280                 specs["constarrayidx"] = de::toString(constIdx);
3281                 if (useConstIdx)
3282                     specs["arrayindex"] = "c_i32_ci";
3283                 else
3284                     specs["arrayindex"] = "30";
3285 
3286                 if (useConstIdx)
3287                     testName += string("_const_idx_") + de::toString(constIdx);
3288 
3289                 resources.outputs.clear();
3290                 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(useConstIdx ? constIdxData : sOutputs)),
3291                                                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3292 
3293                 fragments["testfun"]    = testFun.specialize(specs);
3294                 fragments["pre_main"]   = preMain.specialize(specs);
3295                 fragments["decoration"] = decoration.specialize(specs);
3296 
3297                 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources,
3298                                         extensions, testGroup, requiredFeatures);
3299             }
3300         }
3301         { // signed int
3302             map<string, string> specs;
3303 
3304             specs["type8"]   = "u8";
3305             specs["type32"]  = "u32";
3306             specs["signed"]  = "0";
3307             specs["count"]   = "64";
3308             specs["convert"] = "OpUConvert";
3309 
3310             for (uint32_t constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
3311             {
3312                 bool useConstIdx  = constantIndices[constIndexIdx].useConstantIndex;
3313                 uint32_t constIdx = constantIndices[constIndexIdx].constantIndex;
3314                 string testName   = "uint_scalar";
3315                 vector<int32_t> constIdxData;
3316 
3317                 if (useConstIdx)
3318                 {
3319                     constIdxData.reserve(numDataPoints);
3320 
3321                     for (uint32_t numIdx = 0; numIdx < numDataPoints; ++numIdx)
3322                         constIdxData.push_back(uOutputs[constIdx]);
3323                 }
3324 
3325                 specs["constarrayidx"] = de::toString(constIdx);
3326                 if (useConstIdx)
3327                     specs["arrayindex"] = "c_i32_ci";
3328                 else
3329                     specs["arrayindex"] = "30";
3330 
3331                 if (useConstIdx)
3332                     testName += string("_const_idx_") + de::toString(constIdx);
3333 
3334                 resources.outputs.clear();
3335                 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(useConstIdx ? constIdxData : uOutputs)),
3336                                                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3337 
3338                 fragments["testfun"]    = testFun.specialize(specs);
3339                 fragments["pre_main"]   = preMain.specialize(specs);
3340                 fragments["decoration"] = decoration.specialize(specs);
3341 
3342                 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources,
3343                                         extensions, testGroup, requiredFeatures);
3344             }
3345         }
3346     }
3347 
3348     { // Vector cases
3349         const StringTemplate preMain("    %${base_type8} = OpTypeInt 8 ${signed}\n"
3350                                      "         %${type8} = OpTypeVector %${base_type8} 2\n"
3351                                      "    %c_i32_${count} = OpConstant %i32 ${count}\n"
3352                                      "          %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
3353                                      "%a${count}${type8} = OpTypeArray %${type8} %c_i32_${count}\n"
3354                                      "%a${count}${type32} = OpTypeArray %${type32} %c_i32_${count}\n"
3355                                      "      %pp_${type8} = OpTypePointer PushConstant %${type8}\n"
3356                                      "      %up_${type32} = OpTypePointer StorageBuffer      %${type32}\n"
3357                                      "            %SSBO32 = OpTypeStruct %a${count}${type32}\n"
3358                                      "         %up_SSBO32 = OpTypePointer StorageBuffer %SSBO32\n"
3359                                      "            %ssbo32 = OpVariable %up_SSBO32 StorageBuffer\n"
3360                                      "              %PC8 = OpTypeStruct %a${count}${type8}\n"
3361                                      "           %pp_PC8 = OpTypePointer PushConstant %PC8\n"
3362                                      "              %pc8 = OpVariable %pp_PC8 PushConstant\n");
3363 
3364         const StringTemplate decoration("OpDecorate %a${count}${type8} ArrayStride 2\n"
3365                                         "OpDecorate %a${count}${type32} ArrayStride 8\n"
3366                                         "OpDecorate %SSBO32 Block\n"
3367                                         "OpMemberDecorate %SSBO32 0 Offset 0\n"
3368                                         "OpDecorate %PC8 Block\n"
3369                                         "OpMemberDecorate %PC8 0 Offset 0\n"
3370                                         "OpDecorate %ssbo32 DescriptorSet 0\n"
3371                                         "OpDecorate %ssbo32 Binding 0\n");
3372 
3373         { // signed int
3374             map<string, string> specs;
3375 
3376             specs["base_type8"] = "i8";
3377             specs["type8"]      = "v2i8";
3378             specs["type32"]     = "v2i32";
3379             specs["signed"]     = "1";
3380             specs["count"]      = "32"; // 64 / 2
3381             specs["convert"]    = "OpSConvert";
3382 
3383             for (uint32_t constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
3384             {
3385                 bool useConstIdx  = constantIndices[constIndexIdx].useConstantIndex;
3386                 uint32_t constIdx = constantIndices[constIndexIdx].constantIndex;
3387                 string testName   = "sint_vector";
3388                 vector<int32_t> constIdxData;
3389 
3390                 if (useConstIdx)
3391                 {
3392                     constIdxData.reserve(numDataPoints);
3393 
3394                     for (uint32_t numIdx = 0; numIdx < numDataPoints; ++numIdx)
3395                         constIdxData.push_back(sOutputs[constIdx * 2 + numIdx % 2]);
3396                 }
3397 
3398                 specs["constarrayidx"] = de::toString(constIdx);
3399                 if (useConstIdx)
3400                     specs["arrayindex"] = "c_i32_ci";
3401                 else
3402                     specs["arrayindex"] = "30";
3403 
3404                 if (useConstIdx)
3405                     testName += string("_const_idx_") + de::toString(constIdx);
3406 
3407                 resources.outputs.clear();
3408                 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(useConstIdx ? constIdxData : sOutputs)),
3409                                                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3410 
3411                 fragments["testfun"]    = testFun.specialize(specs);
3412                 fragments["pre_main"]   = preMain.specialize(specs);
3413                 fragments["decoration"] = decoration.specialize(specs);
3414 
3415                 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources,
3416                                         extensions, testGroup, requiredFeatures);
3417             }
3418         }
3419         { // signed int
3420             map<string, string> specs;
3421 
3422             specs["base_type8"] = "u8";
3423             specs["type8"]      = "v2u8";
3424             specs["type32"]     = "v2u32";
3425             specs["signed"]     = "0";
3426             specs["count"]      = "32";
3427             specs["convert"]    = "OpUConvert";
3428 
3429             for (uint32_t constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
3430             {
3431                 bool useConstIdx  = constantIndices[constIndexIdx].useConstantIndex;
3432                 uint32_t constIdx = constantIndices[constIndexIdx].constantIndex;
3433                 string testName   = "uint_vector";
3434                 vector<int32_t> constIdxData;
3435 
3436                 if (useConstIdx)
3437                 {
3438                     constIdxData.reserve(numDataPoints);
3439 
3440                     for (uint32_t numIdx = 0; numIdx < numDataPoints; ++numIdx)
3441                         constIdxData.push_back(uOutputs[constIdx * 2 + numIdx % 2]);
3442                 }
3443 
3444                 specs["constarrayidx"] = de::toString(constIdx);
3445                 if (useConstIdx)
3446                     specs["arrayindex"] = "c_i32_ci";
3447                 else
3448                     specs["arrayindex"] = "30";
3449 
3450                 if (useConstIdx)
3451                     testName += string("_const_idx_") + de::toString(constIdx);
3452 
3453                 resources.outputs.clear();
3454                 resources.outputs.push_back(Resource(BufferSp(new Int32Buffer(useConstIdx ? constIdxData : uOutputs)),
3455                                                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3456 
3457                 fragments["testfun"]    = testFun.specialize(specs);
3458                 fragments["pre_main"]   = preMain.specialize(specs);
3459                 fragments["decoration"] = decoration.specialize(specs);
3460 
3461                 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources,
3462                                         extensions, testGroup, requiredFeatures);
3463             }
3464         }
3465     }
3466 }
3467 
addGraphics8BitStorageUniformInt16To8Group(tcu::TestCaseGroup * testGroup)3468 void addGraphics8BitStorageUniformInt16To8Group(tcu::TestCaseGroup *testGroup)
3469 {
3470     de::Random rnd(deStringHash(testGroup->getName()));
3471     map<string, string> fragments;
3472     const uint32_t numDataPoints = 256;
3473     RGBA defaultColors[4];
3474     GraphicsResources resources;
3475     vector<string> extensions;
3476     const StringTemplate capabilities("OpCapability ${cap}\n");
3477 
3478     extensions.push_back("VK_KHR_8bit_storage");
3479     extensions.push_back("VK_KHR_16bit_storage");
3480     fragments["extension"] = "OpCapability StorageUniform16\n"
3481                              "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
3482                              "OpExtension \"SPV_KHR_8bit_storage\"\n"
3483                              "OpExtension \"SPV_KHR_16bit_storage\"\n";
3484 
3485     getDefaultColors(defaultColors);
3486 
3487     struct IntegerFacts
3488     {
3489         const char *name;
3490         const char *type16;
3491         const char *type8;
3492         const char *opcode;
3493         const char *isSigned;
3494     };
3495 
3496     const IntegerFacts intFacts[] = {
3497         {"sint", "%i16", "%i8", "OpSConvert", "1"},
3498         {"uint", "%u16", "%u8", "OpUConvert", "0"},
3499     };
3500 
3501     const StringTemplate scalarPreMain("${itype8}  = OpTypeInt 8 ${signed}\n"
3502                                        "${itype16} = OpTypeInt 16 ${signed}\n"
3503                                        "%c_i32_256 = OpConstant %i32 256\n"
3504                                        "   %up_i16 = OpTypePointer Uniform ${itype16}\n"
3505                                        "   %up_i8  = OpTypePointer StorageBuffer ${itype8}\n"
3506                                        "   %ra_i16 = OpTypeArray ${itype16} %c_i32_256\n"
3507                                        "   %ra_i8  = OpTypeArray ${itype8} %c_i32_256\n"
3508                                        "   %SSBO16 = OpTypeStruct %ra_i16\n"
3509                                        "   %SSBO8  = OpTypeStruct %ra_i8\n"
3510                                        "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
3511                                        "%up_SSBO8  = OpTypePointer StorageBuffer %SSBO8\n"
3512                                        "   %ssbo16 = OpVariable %up_SSBO16 Uniform\n"
3513                                        "   %ssbo8  = OpVariable %up_SSBO8 StorageBuffer\n");
3514 
3515     const StringTemplate scalarDecoration("OpDecorate %ra_i16 ArrayStride 16\n"
3516                                           "OpDecorate %ra_i8 ArrayStride 1\n"
3517                                           "OpDecorate %SSBO16 Block\n"
3518                                           "OpDecorate %SSBO8 Block\n"
3519                                           "OpMemberDecorate %SSBO16 0 Offset 0\n"
3520                                           "OpMemberDecorate %SSBO8 0 Offset 0\n"
3521                                           "OpDecorate %ssbo16 DescriptorSet 0\n"
3522                                           "OpDecorate %ssbo8 DescriptorSet 0\n"
3523                                           "OpDecorate %ssbo16 Binding 0\n"
3524                                           "OpDecorate %ssbo8 Binding 1\n");
3525 
3526     const StringTemplate scalarTestFunc("%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3527                                         "    %param = OpFunctionParameter %v4f32\n"
3528 
3529                                         "%entry = OpLabel\n"
3530                                         "    %i = OpVariable %fp_i32 Function\n"
3531                                         "         OpStore %i %c_i32_0\n"
3532                                         "         OpBranch %loop\n"
3533 
3534                                         " %loop = OpLabel\n"
3535                                         "   %15 = OpLoad %i32 %i\n"
3536                                         "   %lt = OpSLessThan %bool %15 %c_i32_256\n"
3537                                         "         OpLoopMerge %merge %inc None\n"
3538                                         "         OpBranchConditional %lt %write %merge\n"
3539 
3540                                         "%write = OpLabel\n"
3541                                         "   %30 = OpLoad %i32 %i\n"
3542                                         "  %src = OpAccessChain %up_i16 %ssbo16 %c_i32_0 %30\n"
3543                                         "%val16 = OpLoad ${itype16} %src\n"
3544                                         "%val8 = ${convert} ${itype8} %val16\n"
3545                                         "  %dst = OpAccessChain %up_i8 %ssbo8 %c_i32_0 %30\n"
3546                                         "         OpStore %dst %val8\n"
3547                                         "         OpBranch %inc\n"
3548 
3549                                         "  %inc = OpLabel\n"
3550                                         "   %37 = OpLoad %i32 %i\n"
3551                                         "   %39 = OpIAdd %i32 %37 %c_i32_1\n"
3552                                         "         OpStore %i %39\n"
3553                                         "         OpBranch %loop\n"
3554 
3555                                         "%merge = OpLabel\n"
3556                                         "         OpReturnValue %param\n"
3557 
3558                                         "OpFunctionEnd\n");
3559 
3560     const StringTemplate vecPreMain("${itype8} = OpTypeInt 8 ${signed}\n"
3561                                     "${itype16} = OpTypeInt 16 ${signed}\n"
3562                                     "${v4itype16} = OpTypeVector ${itype16} 4\n"
3563                                     "%c_i32_64 = OpConstant %i32 64\n"
3564                                     "%v4itype8 = OpTypeVector ${itype8} 4\n"
3565                                     " %up_v4i16 = OpTypePointer Uniform ${v4itype16}\n"
3566                                     " %up_v4i8 = OpTypePointer StorageBuffer %v4itype8\n"
3567                                     " %ra_v4i16 = OpTypeArray ${v4itype16} %c_i32_64\n"
3568                                     " %ra_v4i8 = OpTypeArray %v4itype8 %c_i32_64\n"
3569                                     "   %SSBO16 = OpTypeStruct %ra_v4i16\n"
3570                                     "   %SSBO8 = OpTypeStruct %ra_v4i8\n"
3571                                     "%up_SSBO16 = OpTypePointer Uniform %SSBO16\n"
3572                                     "%up_SSBO8 = OpTypePointer StorageBuffer %SSBO8\n"
3573                                     "   %ssbo16 = OpVariable %up_SSBO16 Uniform\n"
3574                                     "   %ssbo8 = OpVariable %up_SSBO8 StorageBuffer\n");
3575 
3576     const StringTemplate vecDecoration("OpDecorate %ra_v4i16 ArrayStride 16\n"
3577                                        "OpDecorate %ra_v4i8 ArrayStride 4\n"
3578                                        "OpDecorate %SSBO16 Block\n"
3579                                        "OpDecorate %SSBO8 Block\n"
3580                                        "OpMemberDecorate %SSBO16 0 Offset 0\n"
3581                                        "OpMemberDecorate %SSBO8 0 Offset 0\n"
3582                                        "OpDecorate %ssbo16 DescriptorSet 0\n"
3583                                        "OpDecorate %ssbo8 DescriptorSet 0\n"
3584                                        "OpDecorate %ssbo16 Binding 0\n"
3585                                        "OpDecorate %ssbo8 Binding 1\n");
3586 
3587     const StringTemplate vecTestFunc("%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3588                                      "    %param = OpFunctionParameter %v4f32\n"
3589 
3590                                      "%entry = OpLabel\n"
3591                                      "    %i = OpVariable %fp_i32 Function\n"
3592                                      "         OpStore %i %c_i32_0\n"
3593                                      "         OpBranch %loop\n"
3594 
3595                                      " %loop = OpLabel\n"
3596                                      "   %15 = OpLoad %i32 %i\n"
3597                                      "   %lt = OpSLessThan %bool %15 %c_i32_64\n"
3598                                      "         OpLoopMerge %merge %inc None\n"
3599                                      "         OpBranchConditional %lt %write %merge\n"
3600 
3601                                      "%write = OpLabel\n"
3602                                      "   %30 = OpLoad %i32 %i\n"
3603                                      "  %src = OpAccessChain %up_v4i16 %ssbo16 %c_i32_0 %30\n"
3604                                      "%val16 = OpLoad ${v4itype16} %src\n"
3605                                      "%val8 = ${convert} %v4itype8 %val16\n"
3606                                      "  %dst = OpAccessChain %up_v4i8 %ssbo8 %c_i32_0 %30\n"
3607                                      "         OpStore %dst %val8\n"
3608                                      "         OpBranch %inc\n"
3609 
3610                                      "  %inc = OpLabel\n"
3611                                      "   %37 = OpLoad %i32 %i\n"
3612                                      "   %39 = OpIAdd %i32 %37 %c_i32_1\n"
3613                                      "         OpStore %i %39\n"
3614                                      "         OpBranch %loop\n"
3615 
3616                                      "%merge = OpLabel\n"
3617                                      "         OpReturnValue %param\n"
3618 
3619                                      "OpFunctionEnd\n");
3620 
3621     struct Category
3622     {
3623         const char *name;
3624         const StringTemplate &preMain;
3625         const StringTemplate &decoration;
3626         const StringTemplate &testFunction;
3627         const uint32_t numElements;
3628     };
3629 
3630     const Category categories[] = {
3631         {"scalar", scalarPreMain, scalarDecoration, scalarTestFunc, 1},
3632         {"vector", vecPreMain, vecDecoration, vecTestFunc, 4},
3633     };
3634 
3635     for (uint32_t catIdx = 0; catIdx < DE_LENGTH_OF_ARRAY(categories); ++catIdx)
3636     {
3637         resources.inputs.clear();
3638         resources.outputs.clear();
3639         vector<int16_t> inputs =
3640             getInt16s(rnd, ((arrayStrideInBytesUniform / static_cast<uint32_t>(sizeof(int16_t))) * numDataPoints) /
3641                                categories[catIdx].numElements);
3642         vector<int8_t> outputs(numDataPoints);
3643 
3644         switch (categories[catIdx].numElements)
3645         {
3646         case 1:
3647             resources.verifyIO = checkUniformsArray<int16_t, int8_t, 1>;
3648             break;
3649         case 4:
3650             resources.verifyIO = checkUniformsArray<int16_t, int8_t, 4>;
3651             break;
3652         default:
3653             DE_FATAL("Impossible");
3654             break;
3655         }
3656 
3657         resources.inputs.push_back(
3658             Resource(BufferSp(new Int16Buffer(inputs)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
3659         resources.outputs.push_back(Resource(BufferSp(new Int8Buffer(outputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3660 
3661         for (uint32_t factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
3662         {
3663             map<string, string> specs;
3664             VulkanFeatures features;
3665             string name = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name) + "_" + categories[catIdx].name +
3666                           "_" + intFacts[factIdx].name;
3667 
3668             specs["cap"]       = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
3669             specs["itype16"]   = intFacts[factIdx].type16;
3670             specs["v4itype16"] = "%v4" + string(intFacts[factIdx].type16).substr(1);
3671             specs["itype8"]    = intFacts[factIdx].type8;
3672             specs["signed"]    = intFacts[factIdx].isSigned;
3673             specs["convert"]   = intFacts[factIdx].opcode;
3674 
3675             fragments["pre_main"]   = categories[catIdx].preMain.specialize(specs);
3676             fragments["testfun"]    = categories[catIdx].testFunction.specialize(specs);
3677             fragments["capability"] = capabilities.specialize(specs);
3678             fragments["decoration"] = categories[catIdx].decoration.specialize(specs);
3679 
3680             features = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
3681             features.ext16BitStorage.uniformAndStorageBuffer16BitAccess = true;
3682             features.coreFeatures.vertexPipelineStoresAndAtomics        = true;
3683             features.coreFeatures.fragmentStoresAndAtomics              = true;
3684 
3685             createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup,
3686                                     features);
3687         }
3688     }
3689 }
3690 
addGraphics8BitStorageUniformInt8To16Group(tcu::TestCaseGroup * testGroup)3691 void addGraphics8BitStorageUniformInt8To16Group(tcu::TestCaseGroup *testGroup)
3692 {
3693     de::Random rnd(deStringHash(testGroup->getName()));
3694     map<string, string> fragments;
3695     const uint32_t numDataPoints = 256;
3696     vector<int16_t> outputs(numDataPoints);
3697     RGBA defaultColors[4];
3698     GraphicsResources resources;
3699     vector<string> extensions;
3700     const StringTemplate capabilities("OpCapability ${cap}\n");
3701 
3702     extensions.push_back("VK_KHR_8bit_storage");
3703     extensions.push_back("VK_KHR_16bit_storage");
3704     fragments["extension"] = "OpCapability StorageUniform16\n"
3705                              "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
3706                              "OpExtension \"SPV_KHR_8bit_storage\"\n"
3707                              "OpExtension \"SPV_KHR_16bit_storage\"\n";
3708 
3709     getDefaultColors(defaultColors);
3710 
3711     struct IntegerFacts
3712     {
3713         const char *name;
3714         const char *type16;
3715         const char *type8;
3716         const char *opcode;
3717         bool isSigned;
3718     };
3719 
3720     const IntegerFacts intFacts[] = {
3721         {"sint", "%i16", "%i8", "OpSConvert", true},
3722         {"uint", "%u16", "%u8", "OpUConvert", false},
3723     };
3724 
3725     struct ConstantIndex
3726     {
3727         bool useConstantIndex;
3728         uint32_t constantIndex;
3729     };
3730 
3731     ConstantIndex constantIndices[] = {{false, 0}, {true, 4}, {true, 5}, {true, 6}};
3732 
3733     const StringTemplate scalarPreMain("${itype8}   = OpTypeInt 8 ${signed}\n"
3734                                        "${itype16}   = OpTypeInt 16 ${signed}\n"
3735                                        " %c_i32_256 = OpConstant %i32 256\n"
3736                                        "%c_i32_ci   = OpConstant %i32 ${constarrayidx}\n"
3737                                        "   %up_i16  = OpTypePointer StorageBuffer ${itype16}\n"
3738                                        "   %up_i8   = OpTypePointer Uniform ${itype8}\n"
3739                                        "   %ra_i16  = OpTypeArray ${itype16} %c_i32_256\n"
3740                                        "   %ra_i8   = OpTypeArray ${itype8} %c_i32_256\n"
3741                                        "   %SSBO16  = OpTypeStruct %ra_i16\n"
3742                                        "   %SSBO8   = OpTypeStruct %ra_i8\n"
3743                                        "%up_SSBO16  = OpTypePointer StorageBuffer %SSBO16\n"
3744                                        "%up_SSBO8   = OpTypePointer Uniform %SSBO8\n"
3745                                        "   %ssbo16  = OpVariable %up_SSBO16 StorageBuffer\n"
3746                                        "   %ssbo8   = OpVariable %up_SSBO8 Uniform\n");
3747 
3748     const StringTemplate scalarDecoration("OpDecorate %ra_i16 ArrayStride 2\n"
3749                                           "OpDecorate %ra_i8 ArrayStride 16\n"
3750                                           "OpDecorate %SSBO16 Block\n"
3751                                           "OpDecorate %SSBO8 Block\n"
3752                                           "OpMemberDecorate %SSBO16 0 Offset 0\n"
3753                                           "OpMemberDecorate %SSBO8 0 Offset 0\n"
3754                                           "OpDecorate %ssbo16 DescriptorSet 0\n"
3755                                           "OpDecorate %ssbo8 DescriptorSet 0\n"
3756                                           "OpDecorate %ssbo16 Binding 1\n"
3757                                           "OpDecorate %ssbo8 Binding 0\n");
3758 
3759     const StringTemplate scalarTestFunc("%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3760                                         "    %param = OpFunctionParameter %v4f32\n"
3761 
3762                                         "%entry = OpLabel\n"
3763                                         "    %i = OpVariable %fp_i32 Function\n"
3764                                         "         OpStore %i %c_i32_0\n"
3765                                         "         OpBranch %loop\n"
3766 
3767                                         " %loop = OpLabel\n"
3768                                         "   %15 = OpLoad %i32 %i\n"
3769                                         "   %lt = OpSLessThan %bool %15 %c_i32_256\n"
3770                                         "         OpLoopMerge %merge %inc None\n"
3771                                         "         OpBranchConditional %lt %write %merge\n"
3772 
3773                                         "%write = OpLabel\n"
3774                                         "   %30 = OpLoad %i32 %i\n"
3775                                         "  %src = OpAccessChain %up_i8 %ssbo8 %c_i32_0 %${arrayindex}\n"
3776                                         "%val8 = OpLoad ${itype8} %src\n"
3777                                         "%val16 = ${convert} ${itype16} %val8\n"
3778                                         "  %dst = OpAccessChain %up_i16 %ssbo16 %c_i32_0 %30\n"
3779                                         "         OpStore %dst %val16\n"
3780                                         "         OpBranch %inc\n"
3781 
3782                                         "  %inc = OpLabel\n"
3783                                         "   %37 = OpLoad %i32 %i\n"
3784                                         "   %39 = OpIAdd %i32 %37 %c_i32_1\n"
3785                                         "         OpStore %i %39\n"
3786                                         "         OpBranch %loop\n"
3787                                         "%merge = OpLabel\n"
3788                                         "         OpReturnValue %param\n"
3789 
3790                                         "OpFunctionEnd\n");
3791 
3792     const StringTemplate vecPreMain("${itype8}  = OpTypeInt 8 ${signed}\n"
3793                                     "${itype16} = OpTypeInt 16 ${signed}\n"
3794                                     "${v2itype16} = OpTypeVector ${itype16} 2\n"
3795                                     "%c_i32_128 = OpConstant %i32 128\n"
3796                                     "%c_i32_ci  = OpConstant %i32 ${constarrayidx}\n"
3797                                     "%v2itype8  = OpTypeVector ${itype8} 2\n"
3798                                     " %up_v2i16 = OpTypePointer StorageBuffer ${v2itype16}\n"
3799                                     " %up_v2i8  = OpTypePointer Uniform %v2itype8\n"
3800                                     " %ra_v2i16 = OpTypeArray ${v2itype16} %c_i32_128\n"
3801                                     " %ra_v2i8  = OpTypeArray %v2itype8 %c_i32_128\n"
3802                                     "   %SSBO16 = OpTypeStruct %ra_v2i16\n"
3803                                     "   %SSBO8  = OpTypeStruct %ra_v2i8\n"
3804                                     "%up_SSBO16 = OpTypePointer StorageBuffer %SSBO16\n"
3805                                     "%up_SSBO8  = OpTypePointer Uniform %SSBO8\n"
3806                                     "   %ssbo16 = OpVariable %up_SSBO16 StorageBuffer\n"
3807                                     "   %ssbo8  = OpVariable %up_SSBO8 Uniform\n");
3808 
3809     const StringTemplate vecDecoration("OpDecorate %ra_v2i16 ArrayStride 4\n"
3810                                        "OpDecorate %ra_v2i8 ArrayStride 16\n"
3811                                        "OpDecorate %SSBO16 Block\n"
3812                                        "OpDecorate %SSBO8 Block\n"
3813                                        "OpMemberDecorate %SSBO16 0 Offset 0\n"
3814                                        "OpMemberDecorate %SSBO8 0 Offset 0\n"
3815                                        "OpDecorate %ssbo16 DescriptorSet 0\n"
3816                                        "OpDecorate %ssbo8 DescriptorSet 0\n"
3817                                        "OpDecorate %ssbo16 Binding 1\n"
3818                                        "OpDecorate %ssbo8 Binding 0\n");
3819 
3820     const StringTemplate vecTestFunc("%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
3821                                      "    %param = OpFunctionParameter %v4f32\n"
3822 
3823                                      "%entry = OpLabel\n"
3824                                      "    %i = OpVariable %fp_i32 Function\n"
3825                                      "         OpStore %i %c_i32_0\n"
3826                                      "         OpBranch %loop\n"
3827 
3828                                      " %loop = OpLabel\n"
3829                                      "   %15 = OpLoad %i32 %i\n"
3830                                      "   %lt = OpSLessThan %bool %15 %c_i32_128\n"
3831                                      "         OpLoopMerge %merge %inc None\n"
3832                                      "         OpBranchConditional %lt %write %merge\n"
3833 
3834                                      "%write = OpLabel\n"
3835                                      "   %30 = OpLoad %i32 %i\n"
3836                                      "  %src = OpAccessChain %up_v2i8 %ssbo8 %c_i32_0 %${arrayindex}\n"
3837                                      "%val8 = OpLoad %v2itype8 %src\n"
3838                                      "%val16 = ${convert} ${v2itype16} %val8\n"
3839                                      "  %dst = OpAccessChain %up_v2i16 %ssbo16 %c_i32_0 %30\n"
3840                                      "         OpStore %dst %val16\n"
3841                                      "         OpBranch %inc\n"
3842 
3843                                      "  %inc = OpLabel\n"
3844                                      "   %37 = OpLoad %i32 %i\n"
3845                                      "   %39 = OpIAdd %i32 %37 %c_i32_1\n"
3846                                      "         OpStore %i %39\n"
3847                                      "         OpBranch %loop\n"
3848                                      "%merge = OpLabel\n"
3849                                      "         OpReturnValue %param\n"
3850 
3851                                      "OpFunctionEnd\n");
3852 
3853     struct Category
3854     {
3855         const char *name;
3856         const StringTemplate &preMain;
3857         const StringTemplate &decoration;
3858         const StringTemplate &testFunction;
3859         const uint32_t numElements;
3860     };
3861 
3862     const Category categories[] = {
3863         {"scalar", scalarPreMain, scalarDecoration, scalarTestFunc, 1},
3864         {"vector", vecPreMain, vecDecoration, vecTestFunc, 2},
3865     };
3866 
3867     for (uint32_t catIdx = 0; catIdx < DE_LENGTH_OF_ARRAY(categories); ++catIdx)
3868     {
3869         resources.inputs.clear();
3870         vector<int8_t> inputs = getInt8s(rnd, (arrayStrideInBytesUniform / static_cast<uint32_t>(sizeof(int8_t))) *
3871                                                   (numDataPoints / categories[catIdx].numElements));
3872         resources.inputs.push_back(
3873             Resource(BufferSp(new Int8Buffer(inputs)), CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].dtype));
3874         for (uint32_t factIdx = 0; factIdx < DE_LENGTH_OF_ARRAY(intFacts); ++factIdx)
3875             for (uint32_t constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
3876             {
3877                 bool useConstIdx  = constantIndices[constIndexIdx].useConstantIndex;
3878                 uint32_t constIdx = constantIndices[constIndexIdx].constantIndex;
3879                 map<string, string> specs;
3880                 VulkanFeatures features;
3881                 string name = string(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name) + "_" +
3882                               categories[catIdx].name + "_" + intFacts[factIdx].name;
3883 
3884                 specs["cap"]       = CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].cap;
3885                 specs["itype16"]   = intFacts[factIdx].type16;
3886                 specs["v2itype16"] = "%v2" + string(intFacts[factIdx].type16).substr(1);
3887                 specs["itype8"]    = intFacts[factIdx].type8;
3888                 if (intFacts[factIdx].isSigned)
3889                     specs["signed"] = "1";
3890                 else
3891                     specs["signed"] = "0";
3892                 specs["convert"]       = intFacts[factIdx].opcode;
3893                 specs["constarrayidx"] = de::toString(constIdx);
3894                 if (useConstIdx)
3895                     specs["arrayindex"] = "c_i32_ci";
3896                 else
3897                     specs["arrayindex"] = "30";
3898 
3899                 fragments["pre_main"]   = categories[catIdx].preMain.specialize(specs);
3900                 fragments["testfun"]    = categories[catIdx].testFunction.specialize(specs);
3901                 fragments["capability"] = capabilities.specialize(specs);
3902                 fragments["decoration"] = categories[catIdx].decoration.specialize(specs);
3903 
3904                 if (useConstIdx)
3905                     name += string("_const_idx_") + de::toString(constIdx);
3906 
3907                 resources.outputs.clear();
3908                 resources.outputs.push_back(
3909                     Resource(BufferSp(new Int16Buffer(outputs)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
3910                 if (useConstIdx)
3911                 {
3912                     switch (constantIndices[constIndexIdx].constantIndex)
3913                     {
3914                     case 0:
3915                         if (categories[catIdx].numElements == 2)
3916                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int16_t, 2, 0>;
3917                         else
3918                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int16_t, 1, 0>;
3919                         break;
3920                     case 4:
3921                         if (categories[catIdx].numElements == 2)
3922                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int16_t, 2, 4>;
3923                         else
3924                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int16_t, 1, 4>;
3925                         break;
3926                     case 5:
3927                         if (categories[catIdx].numElements == 2)
3928                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int16_t, 2, 5>;
3929                         else
3930                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int16_t, 1, 5>;
3931                         break;
3932                     case 6:
3933                         if (categories[catIdx].numElements == 2)
3934                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int16_t, 2, 6>;
3935                         else
3936                             resources.verifyIO = checkUniformsArrayConstNdx<int8_t, int16_t, 1, 6>;
3937                         break;
3938                     default:
3939                         DE_FATAL("Impossible");
3940                         break;
3941                     }
3942                 }
3943                 else
3944                 {
3945                     if (categories[catIdx].numElements == 2)
3946                         resources.verifyIO = checkUniformsArray<int8_t, int16_t, 2>;
3947                     else
3948                         resources.verifyIO = checkUniformsArray<int8_t, int16_t, 1>;
3949                 }
3950 
3951                 features = get8BitStorageFeatures(CAPABILITIES[UNIFORM_AND_STORAGEBUFFER_TEST].name);
3952                 features.ext16BitStorage.uniformAndStorageBuffer16BitAccess = true;
3953                 features.coreFeatures.vertexPipelineStoresAndAtomics        = true;
3954                 features.coreFeatures.fragmentStoresAndAtomics              = true;
3955 
3956                 createTestsForAllStages(name, defaultColors, defaultColors, fragments, resources, extensions, testGroup,
3957                                         features);
3958             }
3959     }
3960 }
3961 
addGraphics8BitStoragePushConstantInt8To16Group(tcu::TestCaseGroup * testGroup)3962 void addGraphics8BitStoragePushConstantInt8To16Group(tcu::TestCaseGroup *testGroup)
3963 {
3964     de::Random rnd(deStringHash(testGroup->getName()));
3965     map<string, string> fragments;
3966     RGBA defaultColors[4];
3967     const uint32_t numDataPoints = 64;
3968     vector<int8_t> inputs        = getInt8s(rnd, numDataPoints);
3969     vector<int16_t> sOutputs;
3970     vector<int16_t> uOutputs;
3971     PushConstants pcs;
3972     GraphicsResources resources;
3973     vector<string> extensions;
3974     const uint8_t signBitMask     = 0x80;
3975     const uint16_t signExtendMask = 0xff00;
3976     VulkanFeatures requiredFeatures;
3977 
3978     struct ConstantIndex
3979     {
3980         bool useConstantIndex;
3981         uint32_t constantIndex;
3982     };
3983 
3984     ConstantIndex constantIndices[] = {{false, 0}, {true, 4}, {true, 5}, {true, 6}};
3985 
3986     sOutputs.reserve(inputs.size());
3987     uOutputs.reserve(inputs.size());
3988 
3989     for (uint32_t numNdx = 0; numNdx < inputs.size(); ++numNdx)
3990     {
3991         uOutputs.push_back(static_cast<uint8_t>(inputs[numNdx]));
3992         if (inputs[numNdx] & signBitMask)
3993             sOutputs.push_back(static_cast<int16_t>(inputs[numNdx] | signExtendMask));
3994         else
3995             sOutputs.push_back(static_cast<int16_t>(inputs[numNdx]));
3996     }
3997 
3998     extensions.push_back("VK_KHR_8bit_storage");
3999     extensions.push_back("VK_KHR_16bit_storage");
4000 
4001     requiredFeatures.coreFeatures.vertexPipelineStoresAndAtomics        = true;
4002     requiredFeatures.coreFeatures.fragmentStoresAndAtomics              = true;
4003     requiredFeatures.ext8BitStorage.storagePushConstant8                = true;
4004     requiredFeatures.ext16BitStorage.uniformAndStorageBuffer16BitAccess = true;
4005 
4006     fragments["capability"] = "OpCapability StoragePushConstant8\n"
4007                               "OpCapability StorageUniform16\n";
4008     fragments["extension"]  = "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n"
4009                               "OpExtension \"SPV_KHR_8bit_storage\"\n"
4010                               "OpExtension \"SPV_KHR_16bit_storage\"\n";
4011 
4012     pcs.setPushConstant(BufferSp(new Int8Buffer(inputs)));
4013 
4014     getDefaultColors(defaultColors);
4015 
4016     const StringTemplate testFun("%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
4017                                  "    %param = OpFunctionParameter %v4f32\n"
4018 
4019                                  "%entry = OpLabel\n"
4020                                  "    %i = OpVariable %fp_i32 Function\n"
4021                                  "         OpStore %i %c_i32_0\n"
4022                                  "         OpBranch %loop\n"
4023 
4024                                  " %loop = OpLabel\n"
4025                                  "   %15 = OpLoad %i32 %i\n"
4026                                  "   %lt = OpSLessThan %bool %15 %c_i32_${count}\n"
4027                                  "         OpLoopMerge %merge %inc None\n"
4028                                  "         OpBranchConditional %lt %write %merge\n"
4029 
4030                                  "%write = OpLabel\n"
4031                                  "   %30 = OpLoad %i32 %i\n"
4032                                  "  %src = OpAccessChain %pp_${type8} %pc8 %c_i32_0 %${arrayindex}\n"
4033                                  "%val8 = OpLoad %${type8} %src\n"
4034                                  "%val16 = ${convert} %${type16} %val8\n"
4035                                  "  %dst = OpAccessChain %up_${type16} %ssbo16 %c_i32_0 %30\n"
4036                                  "         OpStore %dst %val16\n"
4037                                  "         OpBranch %inc\n"
4038 
4039                                  "  %inc = OpLabel\n"
4040                                  "   %37 = OpLoad %i32 %i\n"
4041                                  "   %39 = OpIAdd %i32 %37 %c_i32_1\n"
4042                                  "         OpStore %i %39\n"
4043                                  "         OpBranch %loop\n"
4044 
4045                                  "%merge = OpLabel\n"
4046                                  "         OpReturnValue %param\n"
4047 
4048                                  "OpFunctionEnd\n");
4049 
4050     { // Scalar cases
4051         const StringTemplate preMain(
4052             "         %${type8} = OpTypeInt 8 ${signed}\n"
4053             "         %${type16} = OpTypeInt 16 ${signed}\n"
4054             "    %c_i32_${count} = OpConstant %i32 ${count}\n" // Should be the same as numDataPoints
4055             "         %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
4056             "%a${count}${type8} = OpTypeArray %${type8} %c_i32_${count}\n"
4057             "%a${count}${type16} = OpTypeArray %${type16} %c_i32_${count}\n"
4058             "      %pp_${type8} = OpTypePointer PushConstant %${type8}\n"
4059             "      %up_${type16} = OpTypePointer StorageBuffer      %${type16}\n"
4060             "            %SSBO16 = OpTypeStruct %a${count}${type16}\n"
4061             "         %up_SSBO16 = OpTypePointer StorageBuffer %SSBO16\n"
4062             "            %ssbo16 = OpVariable %up_SSBO16 StorageBuffer\n"
4063             "              %PC8 = OpTypeStruct %a${count}${type8}\n"
4064             "           %pp_PC8 = OpTypePointer PushConstant %PC8\n"
4065             "              %pc8 = OpVariable %pp_PC8 PushConstant\n");
4066 
4067         const StringTemplate decoration("OpDecorate %a${count}${type8} ArrayStride 1\n"
4068                                         "OpDecorate %a${count}${type16} ArrayStride 2\n"
4069                                         "OpDecorate %SSBO16 Block\n"
4070                                         "OpMemberDecorate %SSBO16 0 Offset 0\n"
4071                                         "OpDecorate %PC8 Block\n"
4072                                         "OpMemberDecorate %PC8 0 Offset 0\n"
4073                                         "OpDecorate %ssbo16 DescriptorSet 0\n"
4074                                         "OpDecorate %ssbo16 Binding 0\n");
4075 
4076         { // signed int
4077             map<string, string> specs;
4078 
4079             specs["type8"]   = "i8";
4080             specs["type16"]  = "i16";
4081             specs["signed"]  = "1";
4082             specs["count"]   = "64";
4083             specs["convert"] = "OpSConvert";
4084 
4085             for (uint32_t constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4086             {
4087                 bool useConstIdx  = constantIndices[constIndexIdx].useConstantIndex;
4088                 uint32_t constIdx = constantIndices[constIndexIdx].constantIndex;
4089                 string testName   = "sint_scalar";
4090                 vector<int16_t> constIdxData;
4091 
4092                 if (useConstIdx)
4093                 {
4094                     constIdxData.reserve(numDataPoints);
4095 
4096                     for (uint32_t numIdx = 0; numIdx < numDataPoints; ++numIdx)
4097                         constIdxData.push_back(sOutputs[constIdx]);
4098                 }
4099 
4100                 specs["constarrayidx"] = de::toString(constIdx);
4101                 if (useConstIdx)
4102                     specs["arrayindex"] = "c_i32_ci";
4103                 else
4104                     specs["arrayindex"] = "30";
4105 
4106                 if (useConstIdx)
4107                     testName += string("_const_idx_") + de::toString(constIdx);
4108 
4109                 resources.outputs.clear();
4110                 resources.outputs.push_back(Resource(BufferSp(new Int16Buffer(useConstIdx ? constIdxData : sOutputs)),
4111                                                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4112 
4113                 fragments["testfun"]    = testFun.specialize(specs);
4114                 fragments["pre_main"]   = preMain.specialize(specs);
4115                 fragments["decoration"] = decoration.specialize(specs);
4116 
4117                 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources,
4118                                         extensions, testGroup, requiredFeatures);
4119             }
4120         }
4121         { // signed int
4122             map<string, string> specs;
4123 
4124             specs["type8"]   = "u8";
4125             specs["type16"]  = "u16";
4126             specs["signed"]  = "0";
4127             specs["count"]   = "64";
4128             specs["convert"] = "OpUConvert";
4129 
4130             for (uint32_t constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4131             {
4132                 bool useConstIdx  = constantIndices[constIndexIdx].useConstantIndex;
4133                 uint32_t constIdx = constantIndices[constIndexIdx].constantIndex;
4134                 string testName   = "uint_scalar";
4135                 vector<int16_t> constIdxData;
4136 
4137                 if (useConstIdx)
4138                 {
4139                     constIdxData.reserve(numDataPoints);
4140 
4141                     for (uint32_t numIdx = 0; numIdx < numDataPoints; ++numIdx)
4142                         constIdxData.push_back(uOutputs[constIdx]);
4143                 }
4144 
4145                 specs["constarrayidx"] = de::toString(constIdx);
4146                 if (useConstIdx)
4147                     specs["arrayindex"] = "c_i32_ci";
4148                 else
4149                     specs["arrayindex"] = "30";
4150 
4151                 if (useConstIdx)
4152                     testName += string("_const_idx_") + de::toString(constIdx);
4153 
4154                 resources.outputs.clear();
4155                 resources.outputs.push_back(Resource(BufferSp(new Int16Buffer(useConstIdx ? constIdxData : uOutputs)),
4156                                                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4157 
4158                 fragments["testfun"]    = testFun.specialize(specs);
4159                 fragments["pre_main"]   = preMain.specialize(specs);
4160                 fragments["decoration"] = decoration.specialize(specs);
4161 
4162                 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources,
4163                                         extensions, testGroup, requiredFeatures);
4164             }
4165         }
4166     }
4167 
4168     { // Vector cases
4169         const StringTemplate preMain("    %${base_type8} = OpTypeInt 8 ${signed}\n"
4170                                      "         %${type8} = OpTypeVector %${base_type8} 2\n"
4171                                      "    %${base_type16} = OpTypeInt 16 ${signed}\n"
4172                                      "         %${type16} = OpTypeVector %${base_type16} 2\n"
4173                                      "    %c_i32_${count} = OpConstant %i32 ${count}\n"
4174                                      "          %c_i32_ci = OpConstant %i32 ${constarrayidx}\n"
4175                                      "%a${count}${type8} = OpTypeArray %${type8} %c_i32_${count}\n"
4176                                      "%a${count}${type16} = OpTypeArray %${type16} %c_i32_${count}\n"
4177                                      "      %pp_${type8} = OpTypePointer PushConstant %${type8}\n"
4178                                      "      %up_${type16} = OpTypePointer StorageBuffer      %${type16}\n"
4179                                      "            %SSBO16 = OpTypeStruct %a${count}${type16}\n"
4180                                      "         %up_SSBO16 = OpTypePointer StorageBuffer %SSBO16\n"
4181                                      "            %ssbo16 = OpVariable %up_SSBO16 StorageBuffer\n"
4182                                      "              %PC8 = OpTypeStruct %a${count}${type8}\n"
4183                                      "           %pp_PC8 = OpTypePointer PushConstant %PC8\n"
4184                                      "              %pc8 = OpVariable %pp_PC8 PushConstant\n");
4185 
4186         const StringTemplate decoration("OpDecorate %a${count}${type8} ArrayStride 2\n"
4187                                         "OpDecorate %a${count}${type16} ArrayStride 4\n"
4188                                         "OpDecorate %SSBO16 Block\n"
4189                                         "OpMemberDecorate %SSBO16 0 Offset 0\n"
4190                                         "OpDecorate %PC8 Block\n"
4191                                         "OpMemberDecorate %PC8 0 Offset 0\n"
4192                                         "OpDecorate %ssbo16 DescriptorSet 0\n"
4193                                         "OpDecorate %ssbo16 Binding 0\n");
4194 
4195         { // signed int
4196             map<string, string> specs;
4197 
4198             specs["base_type8"]  = "i8";
4199             specs["base_type16"] = "i16";
4200             specs["type8"]       = "v2i8";
4201             specs["type16"]      = "v2i16";
4202             specs["signed"]      = "1";
4203             specs["count"]       = "32"; // 64 / 2
4204             specs["convert"]     = "OpSConvert";
4205 
4206             for (uint32_t constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4207             {
4208                 bool useConstIdx  = constantIndices[constIndexIdx].useConstantIndex;
4209                 uint32_t constIdx = constantIndices[constIndexIdx].constantIndex;
4210                 string testName   = "sint_vector";
4211                 vector<int16_t> constIdxData;
4212 
4213                 if (useConstIdx)
4214                 {
4215                     constIdxData.reserve(numDataPoints);
4216 
4217                     for (uint32_t numIdx = 0; numIdx < numDataPoints; ++numIdx)
4218                         constIdxData.push_back(sOutputs[constIdx * 2 + numIdx % 2]);
4219                 }
4220 
4221                 specs["constarrayidx"] = de::toString(constIdx);
4222                 if (useConstIdx)
4223                     specs["arrayindex"] = "c_i32_ci";
4224                 else
4225                     specs["arrayindex"] = "30";
4226 
4227                 if (useConstIdx)
4228                     testName += string("_const_idx_") + de::toString(constIdx);
4229 
4230                 resources.outputs.clear();
4231                 resources.outputs.push_back(Resource(BufferSp(new Int16Buffer(useConstIdx ? constIdxData : sOutputs)),
4232                                                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4233 
4234                 fragments["testfun"]    = testFun.specialize(specs);
4235                 fragments["pre_main"]   = preMain.specialize(specs);
4236                 fragments["decoration"] = decoration.specialize(specs);
4237 
4238                 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources,
4239                                         extensions, testGroup, requiredFeatures);
4240             }
4241         }
4242         { // signed int
4243             map<string, string> specs;
4244 
4245             specs["base_type8"]  = "u8";
4246             specs["base_type16"] = "u16";
4247             specs["type8"]       = "v2u8";
4248             specs["type16"]      = "v2u16";
4249             specs["signed"]      = "0";
4250             specs["count"]       = "32";
4251             specs["convert"]     = "OpUConvert";
4252 
4253             for (uint32_t constIndexIdx = 0; constIndexIdx < DE_LENGTH_OF_ARRAY(constantIndices); ++constIndexIdx)
4254             {
4255                 bool useConstIdx  = constantIndices[constIndexIdx].useConstantIndex;
4256                 uint32_t constIdx = constantIndices[constIndexIdx].constantIndex;
4257                 string testName   = "uint_vector";
4258                 vector<int16_t> constIdxData;
4259 
4260                 if (useConstIdx)
4261                 {
4262                     constIdxData.reserve(numDataPoints);
4263 
4264                     for (uint32_t numIdx = 0; numIdx < numDataPoints; ++numIdx)
4265                         constIdxData.push_back(uOutputs[constIdx * 2 + numIdx % 2]);
4266                 }
4267 
4268                 specs["constarrayidx"] = de::toString(constIdx);
4269                 if (useConstIdx)
4270                     specs["arrayindex"] = "c_i32_ci";
4271                 else
4272                     specs["arrayindex"] = "30";
4273 
4274                 if (useConstIdx)
4275                     testName += string("_const_idx_") + de::toString(constIdx);
4276 
4277                 resources.outputs.clear();
4278                 resources.outputs.push_back(Resource(BufferSp(new Int16Buffer(useConstIdx ? constIdxData : uOutputs)),
4279                                                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4280 
4281                 fragments["testfun"]    = testFun.specialize(specs);
4282                 fragments["pre_main"]   = preMain.specialize(specs);
4283                 fragments["decoration"] = decoration.specialize(specs);
4284 
4285                 createTestsForAllStages(testName.c_str(), defaultColors, defaultColors, fragments, pcs, resources,
4286                                         extensions, testGroup, requiredFeatures);
4287             }
4288         }
4289     }
4290 }
4291 
addGraphics8BitStorageUniformStruct8To32Group(tcu::TestCaseGroup * testGroup)4292 void addGraphics8BitStorageUniformStruct8To32Group(tcu::TestCaseGroup *testGroup)
4293 {
4294     de::Random rnd(deStringHash(testGroup->getName()));
4295     map<string, string> fragments;
4296     vector<string> extensions;
4297     RGBA defaultColors[4];
4298     const StringTemplate capabilities("OpCapability ${cap}\n");
4299     vector<int32_t> i32Data = data32bit(SHADERTEMPLATE_STRIDE32BIT_STD430, rnd, false);
4300 
4301     extensions.push_back("VK_KHR_8bit_storage");
4302     fragments["extension"] = "OpExtension \"SPV_KHR_8bit_storage\"\n"
4303                              "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
4304 
4305     getDefaultColors(defaultColors);
4306 
4307     const StringTemplate preMain(
4308         "\n"
4309         "%i8      = OpTypeInt 8 ${signed}\n"
4310         "%v2i8    = OpTypeVector %i8 2\n"
4311         "%v3i8    = OpTypeVector %i8 3\n"
4312         "%v4i8    = OpTypeVector %i8 4\n"
4313         "%i8ptr   = OpTypePointer ${8Storage} %i8\n"
4314         "%v2i8ptr = OpTypePointer ${8Storage} %v2i8\n"
4315         "%v3i8ptr = OpTypePointer ${8Storage} %v3i8\n"
4316         "%v4i8ptr = OpTypePointer ${8Storage} %v4i8\n"
4317         "\n"
4318         "%i32ptr   = OpTypePointer ${32Storage} %${32type}\n"
4319         "%v2i32ptr = OpTypePointer ${32Storage} %v2${32type}\n"
4320         "%v3i32ptr = OpTypePointer ${32Storage} %v3${32type}\n"
4321         "%v4i32ptr = OpTypePointer ${32Storage} %v4${32type}\n"
4322         "\n"
4323         "%zero = OpConstant %i32 0\n"
4324         "%c_i32_5  = OpConstant %i32 5\n"
4325         "%c_i32_6  = OpConstant %i32 6\n"
4326         "%c_i32_7  = OpConstant %i32 7\n"
4327         "%c_i32_8  = OpConstant %i32 8\n"
4328         "%c_i32_9  = OpConstant %i32 9\n"
4329         "%c_i32_11 = OpConstant %i32 11\n"
4330         "\n"
4331         "%c_u32_7 = OpConstant %u32 7\n"
4332         "%c_u32_11 = OpConstant %u32 11\n"
4333         "\n"
4334         "%i8arr3       = OpTypeArray %i8 %c_u32_3\n"
4335         "%v2i8arr3     = OpTypeArray %v2i8 %c_u32_3\n"
4336         "%v2i8arr11    = OpTypeArray %v2i8 %c_u32_11\n"
4337         "%v3i8arr11    = OpTypeArray %v3i8 %c_u32_11\n"
4338         "%v4i8arr3     = OpTypeArray %v4i8 %c_u32_3\n"
4339         "%struct8      = OpTypeStruct %i8 %v2i8arr3\n"
4340         "%struct8arr11 = OpTypeArray %struct8 %c_u32_11\n"
4341         "%i8Struct = OpTypeStruct %i8 %v2i8 %v3i8 %v4i8 %i8arr3 %struct8arr11 %v2i8arr11 %i8 %v3i8arr11 %v4i8arr3\n"
4342         "\n"
4343         "%i32arr3       = OpTypeArray %${32type} %c_u32_3\n"
4344         "%v2i32arr3     = OpTypeArray %v2${32type} %c_u32_3\n"
4345         "%v2i32arr11    = OpTypeArray %v2${32type} %c_u32_11\n"
4346         "%v3i32arr11    = OpTypeArray %v3${32type} %c_u32_11\n"
4347         "%v4i32arr3     = OpTypeArray %v4${32type} %c_u32_3\n"
4348         "%struct32      = OpTypeStruct %${32type} %v2i32arr3\n"
4349         "%struct32arr11 = OpTypeArray %struct32 %c_u32_11\n"
4350         "%i32Struct = OpTypeStruct %${32type} %v2${32type} %v3${32type} %v4${32type} %i32arr3 %struct32arr11 "
4351         "%v2i32arr11 %${32type} %v3i32arr11 %v4i32arr3\n"
4352         "\n"
4353         "%i8StructArr7  = OpTypeArray %i8Struct %c_u32_7\n"
4354         "%i32StructArr7 = OpTypeArray %i32Struct %c_u32_7\n"
4355         "%SSBO_IN       = OpTypeStruct %i8StructArr7\n"
4356         "%SSBO_OUT      = OpTypeStruct %i32StructArr7\n"
4357         "%up_SSBOIN     = OpTypePointer ${8Storage} %SSBO_IN\n"
4358         "%up_SSBOOUT    = OpTypePointer ${32Storage} %SSBO_OUT\n"
4359         "%ssboIN        = OpVariable %up_SSBOIN ${8Storage}\n"
4360         "%ssboOUT       = OpVariable %up_SSBOOUT ${32Storage}\n"
4361         "\n");
4362 
4363     const StringTemplate decoration("${stridei8}"
4364                                     "\n"
4365                                     "${stridei32}"
4366                                     "\n"
4367                                     "OpDecorate %SSBO_IN Block\n"
4368                                     "OpDecorate %SSBO_OUT Block\n"
4369                                     "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
4370                                     "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
4371                                     "OpDecorate %ssboIN DescriptorSet 0\n"
4372                                     "OpDecorate %ssboOUT DescriptorSet 0\n"
4373                                     "OpDecorate %ssboIN Binding 0\n"
4374                                     "OpDecorate %ssboOUT Binding 1\n"
4375                                     "\n");
4376 
4377     const StringTemplate testFun(
4378         "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
4379         "    %param = OpFunctionParameter %v4f32\n"
4380         "%label     = OpLabel\n"
4381         "%loopNdx   = OpVariable %fp_i32 Function\n"
4382         "%insideLoopNdx = OpVariable %fp_i32 Function\n"
4383 
4384         "OpStore %loopNdx %zero\n"
4385         "OpBranch %loop\n"
4386         "%loop = OpLabel\n"
4387         "OpLoopMerge %merge %13 None\n"
4388         "OpBranch %14\n"
4389         "%14 = OpLabel\n"
4390         "%valLoopNdx = OpLoad %i32 %loopNdx\n"
4391         "%18 = OpSLessThan %bool %valLoopNdx %c_i32_7\n"
4392         "OpBranchConditional %18 %11 %merge\n"
4393         "%11 = OpLabel\n"
4394         "\n"
4395         "%i8src  = OpAccessChain %i8ptr %ssboIN %zero %valLoopNdx %zero\n"
4396         "%val_i8 = OpLoad %i8 %i8src\n"
4397         "%val_i32 = ${convert} %${32type} %val_i8\n"
4398         "%i32dst  = OpAccessChain %i32ptr %ssboOUT %zero %valLoopNdx %zero\n"
4399         "OpStore %i32dst %val_i32\n"
4400         "\n"
4401         "%v2i8src  = OpAccessChain %v2i8ptr %ssboIN %zero %valLoopNdx %c_i32_1\n"
4402         "%val_v2i8 = OpLoad %v2i8 %v2i8src\n"
4403         "%val_v2i32 = ${convert} %v2${32type} %val_v2i8\n"
4404         "%v2i32dst  = OpAccessChain %v2i32ptr %ssboOUT %zero %valLoopNdx %c_i32_1\n"
4405         "OpStore %v2i32dst %val_v2i32\n"
4406         "\n"
4407         "%v3i8src  = OpAccessChain %v3i8ptr %ssboIN %zero %valLoopNdx %c_i32_2\n"
4408         "%val_v3i8 = OpLoad %v3i8 %v3i8src\n"
4409         "%val_v3i32 = ${convert} %v3${32type} %val_v3i8\n"
4410         "%v3i32dst  = OpAccessChain %v3i32ptr %ssboOUT %zero %valLoopNdx %c_i32_2\n"
4411         "OpStore %v3i32dst %val_v3i32\n"
4412         "\n"
4413         "%v4i8src  = OpAccessChain %v4i8ptr %ssboIN %zero %valLoopNdx %c_i32_3\n"
4414         "%val_v4i8 = OpLoad %v4i8 %v4i8src\n"
4415         "%val_v4i32 = ${convert} %v4${32type} %val_v4i8\n"
4416         "%v4i32dst  = OpAccessChain %v4i32ptr %ssboOUT %zero %valLoopNdx %c_i32_3\n"
4417         "OpStore %v4i32dst %val_v4i32\n"
4418         "\n"
4419         "%i8src2  = OpAccessChain %i8ptr %ssboIN %zero %valLoopNdx %c_i32_7\n"
4420         "%val2_i8 = OpLoad %i8 %i8src2\n"
4421         "%val2_i32 = ${convert} %${32type} %val2_i8\n"
4422         "%i32dst2  = OpAccessChain %i32ptr %ssboOUT %zero %valLoopNdx %c_i32_7\n"
4423         "OpStore %i32dst2 %val2_i32\n"
4424         "\n"
4425         "OpStore %insideLoopNdx %zero\n"
4426         "OpBranch %loopInside\n"
4427         "%loopInside = OpLabel\n"
4428         "OpLoopMerge %92 %93 None\n"
4429         "OpBranch %94\n"
4430         "%94 = OpLabel\n"
4431         "%valInsideLoopNdx = OpLoad %i32 %insideLoopNdx\n"
4432         "%96 = OpSLessThan %bool %valInsideLoopNdx %c_i32_11\n"
4433         "OpBranchConditional %96 %91 %92\n"
4434         "\n"
4435         "%91 = OpLabel\n"
4436         "\n"
4437         "%v2i8src2  = OpAccessChain %v2i8ptr %ssboIN %zero %valLoopNdx %c_i32_6 %valInsideLoopNdx\n"
4438         "%val2_v2i8 = OpLoad %v2i8 %v2i8src2\n"
4439         "%val2_v2i32 = ${convert} %v2${32type} %val2_v2i8\n"
4440         "%v2i32dst2  = OpAccessChain %v2i32ptr %ssboOUT %zero %valLoopNdx %c_i32_6 %valInsideLoopNdx\n"
4441         "OpStore %v2i32dst2 %val2_v2i32\n"
4442         "\n"
4443         "%v3i8src2  = OpAccessChain %v3i8ptr %ssboIN %zero %valLoopNdx %c_i32_8 %valInsideLoopNdx\n"
4444         "%val2_v3i8 = OpLoad %v3i8 %v3i8src2\n"
4445         "%val2_v3i32 = ${convert} %v3${32type} %val2_v3i8\n"
4446         "%v3i32dst2  = OpAccessChain %v3i32ptr %ssboOUT %zero %valLoopNdx %c_i32_8 %valInsideLoopNdx\n"
4447         "OpStore %v3i32dst2 %val2_v3i32\n"
4448         "\n"
4449         //struct {i8, v2i8[3]}
4450         "%Si8src  = OpAccessChain %i8ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %zero\n"
4451         "%Sval_i8 = OpLoad %i8 %Si8src\n"
4452         "%Sval_i32 = ${convert} %${32type} %Sval_i8\n"
4453         "%Si32dst2  = OpAccessChain %i32ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %zero\n"
4454         "OpStore %Si32dst2 %Sval_i32\n"
4455         "\n"
4456         "%Sv2i8src0   = OpAccessChain %v2i8ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %zero\n"
4457         "%Sv2i8_0     = OpLoad %v2i8 %Sv2i8src0\n"
4458         "%Sv2i32_0     = ${convert} %v2${32type} %Sv2i8_0\n"
4459         "%Sv2i32dst_0  = OpAccessChain %v2i32ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %zero\n"
4460         "OpStore %Sv2i32dst_0 %Sv2i32_0\n"
4461         "\n"
4462         "%Sv2i8src1  = OpAccessChain %v2i8ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_1\n"
4463         "%Sv2i8_1 = OpLoad %v2i8 %Sv2i8src1\n"
4464         "%Sv2i32_1 = ${convert} %v2${32type} %Sv2i8_1\n"
4465         "%Sv2i32dst_1  = OpAccessChain %v2i32ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 "
4466         "%c_i32_1\n"
4467         "OpStore %Sv2i32dst_1 %Sv2i32_1\n"
4468         "\n"
4469         "%Sv2i8src2  = OpAccessChain %v2i8ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_2\n"
4470         "%Sv2i8_2 = OpLoad %v2i8 %Sv2i8src2\n"
4471         "%Sv2i32_2 = ${convert} %v2${32type} %Sv2i8_2\n"
4472         "%Sv2i32dst_2  = OpAccessChain %v2i32ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 "
4473         "%c_i32_2\n"
4474         "OpStore %Sv2i32dst_2 %Sv2i32_2\n"
4475         "\n"
4476         //Array with 3 elements
4477         "%LessThan3 = OpSLessThan %bool %valInsideLoopNdx %c_i32_3\n"
4478         "OpSelectionMerge %BlockIf None\n"
4479         "OpBranchConditional %LessThan3 %LabelIf %BlockIf\n"
4480         "%LabelIf = OpLabel\n"
4481         "  %i8src3  = OpAccessChain %i8ptr %ssboIN %zero %valLoopNdx %c_i32_4 %valInsideLoopNdx\n"
4482         "  %val3_i8 = OpLoad %i8 %i8src3\n"
4483         "  %val3_i32 = ${convert} %${32type} %val3_i8\n"
4484         "  %i32dst3  = OpAccessChain %i32ptr %ssboOUT %zero %valLoopNdx %c_i32_4 %valInsideLoopNdx\n"
4485         "  OpStore %i32dst3 %val3_i32\n"
4486         "\n"
4487         "  %v4i8src2  = OpAccessChain %v4i8ptr %ssboIN %zero %valLoopNdx %c_i32_9 %valInsideLoopNdx\n"
4488         "  %val2_v4i8 = OpLoad %v4i8 %v4i8src2\n"
4489         "  %val2_v4i32 = ${convert} %v4${32type} %val2_v4i8\n"
4490         "  %v4i32dst2  = OpAccessChain %v4i32ptr %ssboOUT %zero %valLoopNdx %c_i32_9 %valInsideLoopNdx\n"
4491         "  OpStore %v4i32dst2 %val2_v4i32\n"
4492         "OpBranch %BlockIf\n"
4493         "%BlockIf = OpLabel\n"
4494         "\n"
4495         "OpBranch %93\n"
4496         "%93 = OpLabel\n"
4497         "%132 = OpLoad %i32 %insideLoopNdx\n"
4498         "%133 = OpIAdd %i32 %132 %c_i32_1\n"
4499         "OpStore %insideLoopNdx %133\n"
4500         "OpBranch %loopInside\n"
4501         "\n"
4502         "%92 = OpLabel\n"
4503         "OpBranch %13\n"
4504         "%13 = OpLabel\n"
4505         "%134 = OpLoad %i32 %loopNdx\n"
4506         "%135 = OpIAdd %i32 %134 %c_i32_1\n"
4507         "OpStore %loopNdx %135\n"
4508         "OpBranch %loop\n"
4509 
4510         "%merge = OpLabel\n"
4511         "         OpReturnValue %param\n"
4512         "         OpFunctionEnd\n");
4513 
4514     struct IntegerFacts
4515     {
4516         const char *name;
4517         const char *opcode;
4518         const char *signedInt;
4519         const char *type32;
4520     };
4521 
4522     const IntegerFacts intFacts[] = {
4523         {"sint", "OpSConvert", "1", "i32"},
4524         {"uint", "OpUConvert", "0", "u32"},
4525     };
4526 
4527     for (uint32_t capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
4528         for (uint32_t intFactsNdx = 0; intFactsNdx < DE_LENGTH_OF_ARRAY(intFacts); ++intFactsNdx)
4529         {
4530             const bool isUniform  = (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == CAPABILITIES[capIdx].dtype);
4531             vector<int8_t> i8Data = isUniform ? data8bit(SHADERTEMPLATE_STRIDE8BIT_STD140, rnd) :
4532                                                 data8bit(SHADERTEMPLATE_STRIDE8BIT_STD430, rnd);
4533             GraphicsResources resources;
4534             map<string, string> specs;
4535             VulkanFeatures features;
4536             const string testName = string(CAPABILITIES[capIdx].name) + "_" + intFacts[intFactsNdx].name;
4537 
4538             specs["cap"]       = CAPABILITIES[capIdx].cap;
4539             specs["stridei8"]  = getStructShaderComponet(isUniform ? SHADERTEMPLATE_STRIDE8BIT_STD140 :
4540                                                                      SHADERTEMPLATE_STRIDE8BIT_STD430);
4541             specs["stridei32"] = getStructShaderComponet(SHADERTEMPLATE_STRIDE32BIT_STD430);
4542             specs["32Storage"] = "StorageBuffer";
4543             specs["8Storage"]  = isUniform ? "Uniform" : "StorageBuffer";
4544             specs["signed"]    = intFacts[intFactsNdx].signedInt;
4545             specs["convert"]   = intFacts[intFactsNdx].opcode;
4546             specs["32type"]    = intFacts[intFactsNdx].type32;
4547 
4548             fragments["capability"] = capabilities.specialize(specs);
4549             fragments["decoration"] = decoration.specialize(specs);
4550             fragments["pre_main"]   = preMain.specialize(specs);
4551             fragments["testfun"]    = testFun.specialize(specs);
4552 
4553             resources.inputs.push_back(Resource(BufferSp(new Int8Buffer(i8Data)), CAPABILITIES[capIdx].dtype));
4554             resources.outputs.push_back(
4555                 Resource(BufferSp(new Int32Buffer(i32Data)), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
4556             if (isUniform)
4557                 resources.verifyIO =
4558                     checkStruct<int8_t, int32_t, SHADERTEMPLATE_STRIDE8BIT_STD140, SHADERTEMPLATE_STRIDE32BIT_STD430>;
4559             else
4560                 resources.verifyIO =
4561                     checkStruct<int8_t, int32_t, SHADERTEMPLATE_STRIDE8BIT_STD430, SHADERTEMPLATE_STRIDE32BIT_STD430>;
4562 
4563             features                                             = get8BitStorageFeatures(CAPABILITIES[capIdx].name);
4564             features.coreFeatures.vertexPipelineStoresAndAtomics = true;
4565             features.coreFeatures.fragmentStoresAndAtomics       = true;
4566 
4567             createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup,
4568                                     features);
4569         }
4570 }
4571 
addGraphics8BitStorageUniformStruct32To8Group(tcu::TestCaseGroup * testGroup)4572 void addGraphics8BitStorageUniformStruct32To8Group(tcu::TestCaseGroup *testGroup)
4573 {
4574     de::Random rnd(deStringHash(testGroup->getName()));
4575     map<string, string> fragments;
4576     vector<string> extensions;
4577     RGBA defaultColors[4];
4578     const StringTemplate capabilities("OpCapability ${cap}\n");
4579     vector<int8_t> i8Data = data8bit(SHADERTEMPLATE_STRIDE8BIT_STD430, rnd, false);
4580 
4581     extensions.push_back("VK_KHR_8bit_storage");
4582     fragments["extension"] = "OpExtension \"SPV_KHR_8bit_storage\"\n"
4583                              "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
4584 
4585     getDefaultColors(defaultColors);
4586 
4587     const StringTemplate preMain(
4588         "\n"
4589         "%i8      = OpTypeInt 8 ${signed}\n"
4590         "%v2i8    = OpTypeVector %i8 2\n"
4591         "%v3i8    = OpTypeVector %i8 3\n"
4592         "%v4i8    = OpTypeVector %i8 4\n"
4593         "%i8ptr   = OpTypePointer ${8Storage} %i8\n"
4594         "%v2i8ptr = OpTypePointer ${8Storage} %v2i8\n"
4595         "%v3i8ptr = OpTypePointer ${8Storage} %v3i8\n"
4596         "%v4i8ptr = OpTypePointer ${8Storage} %v4i8\n"
4597         "\n"
4598         "%i32ptr   = OpTypePointer ${32Storage} %${32type}\n"
4599         "%v2i32ptr = OpTypePointer ${32Storage} %v2${32type}\n"
4600         "%v3i32ptr = OpTypePointer ${32Storage} %v3${32type}\n"
4601         "%v4i32ptr = OpTypePointer ${32Storage} %v4${32type}\n"
4602         "\n"
4603         "%zero = OpConstant %i32 0\n"
4604         "%c_i32_5  = OpConstant %i32 5\n"
4605         "%c_i32_6  = OpConstant %i32 6\n"
4606         "%c_i32_7  = OpConstant %i32 7\n"
4607         "%c_i32_8  = OpConstant %i32 8\n"
4608         "%c_i32_9  = OpConstant %i32 9\n"
4609         "%c_i32_11 = OpConstant %i32 11\n"
4610         "\n"
4611         "%c_u32_7 = OpConstant %u32 7\n"
4612         "%c_u32_11 = OpConstant %u32 11\n"
4613         "\n"
4614         "%i8arr3       = OpTypeArray %i8 %c_u32_3\n"
4615         "%v2i8arr3    = OpTypeArray %v2i8 %c_u32_3\n"
4616         "%v2i8arr11    = OpTypeArray %v2i8 %c_u32_11\n"
4617         "%v3i8arr11    = OpTypeArray %v3i8 %c_u32_11\n"
4618         "%v4i8arr3     = OpTypeArray %v4i8 %c_u32_3\n"
4619         "%struct8      = OpTypeStruct %i8 %v2i8arr3\n"
4620         "%struct8arr11 = OpTypeArray %struct8 %c_u32_11\n"
4621         "%i8Struct = OpTypeStruct %i8 %v2i8 %v3i8 %v4i8 %i8arr3 %struct8arr11 %v2i8arr11 %i8 %v3i8arr11 %v4i8arr3\n"
4622         "\n"
4623         "%i32arr3       = OpTypeArray %${32type} %c_u32_3\n"
4624         "%v2i32arr3     = OpTypeArray %v2${32type} %c_u32_3\n"
4625         "%v2i32arr11    = OpTypeArray %v2${32type} %c_u32_11\n"
4626         "%v3i32arr11    = OpTypeArray %v3${32type} %c_u32_11\n"
4627         "%v4i32arr3     = OpTypeArray %v4${32type} %c_u32_3\n"
4628         "%struct32      = OpTypeStruct %${32type} %v2i32arr3\n"
4629         "%struct32arr11 = OpTypeArray %struct32 %c_u32_11\n"
4630         "%i32Struct = OpTypeStruct %${32type} %v2${32type} %v3${32type} %v4${32type} %i32arr3 %struct32arr11 "
4631         "%v2i32arr11 %${32type} %v3i32arr11 %v4i32arr3\n"
4632         "\n"
4633         "%i8StructArr7  = OpTypeArray %i8Struct %c_u32_7\n"
4634         "%i32StructArr7 = OpTypeArray %i32Struct %c_u32_7\n"
4635         "%SSBO_IN       = OpTypeStruct %i32StructArr7\n"
4636         "%SSBO_OUT      = OpTypeStruct %i8StructArr7\n"
4637         "%up_SSBOIN     = OpTypePointer ${32Storage} %SSBO_IN\n"
4638         "%up_SSBOOUT    = OpTypePointer ${8Storage} %SSBO_OUT\n"
4639         "%ssboIN        = OpVariable %up_SSBOIN ${32Storage}\n"
4640         "%ssboOUT       = OpVariable %up_SSBOOUT ${8Storage}\n"
4641         "\n");
4642 
4643     const StringTemplate decoration("${stridei8}"
4644                                     "\n"
4645                                     "${stridei32}"
4646                                     "\n"
4647                                     "OpDecorate %SSBO_IN Block\n"
4648                                     "OpDecorate %SSBO_OUT Block\n"
4649                                     "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
4650                                     "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
4651                                     "OpDecorate %ssboIN DescriptorSet 0\n"
4652                                     "OpDecorate %ssboOUT DescriptorSet 0\n"
4653                                     "OpDecorate %ssboIN Binding 0\n"
4654                                     "OpDecorate %ssboOUT Binding 1\n"
4655                                     "\n");
4656 
4657     const StringTemplate testFun(
4658         "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
4659         "%param = OpFunctionParameter %v4f32\n"
4660         "%label     = OpLabel\n"
4661         "%loopNdx    = OpVariable %fp_i32 Function\n"
4662         "%insideLoopNdx = OpVariable %fp_i32 Function\n"
4663 
4664         "OpStore %loopNdx %zero\n"
4665         "OpBranch %loop\n"
4666         "%loop = OpLabel\n"
4667         "OpLoopMerge %merge %13 None\n"
4668         "OpBranch %14\n"
4669         "%14 = OpLabel\n"
4670         "%valLoopNdx = OpLoad %i32 %loopNdx\n"
4671         "%18 = OpSLessThan %bool %valLoopNdx %c_i32_7\n"
4672         "OpBranchConditional %18 %11 %merge\n"
4673         "%11 = OpLabel\n"
4674         "\n"
4675         "%i32src  = OpAccessChain %i32ptr %ssboIN %zero %valLoopNdx %zero\n"
4676         "%val_i32 = OpLoad %${32type} %i32src\n"
4677         "%val_i8 = ${convert} %i8 %val_i32\n"
4678         "%i8dst  = OpAccessChain %i8ptr %ssboOUT %zero %valLoopNdx %zero\n"
4679         "OpStore %i8dst %val_i8\n"
4680         "\n"
4681         "%v2i32src  = OpAccessChain %v2i32ptr %ssboIN %zero %valLoopNdx %c_i32_1\n"
4682         "%val_v2i32 = OpLoad %v2${32type} %v2i32src\n"
4683         "%val_v2i8 = ${convert} %v2i8 %val_v2i32\n"
4684         "%v2i8dst  = OpAccessChain %v2i8ptr %ssboOUT %zero %valLoopNdx %c_i32_1\n"
4685         "OpStore %v2i8dst %val_v2i8\n"
4686         "\n"
4687         "%v3i32src  = OpAccessChain %v3i32ptr %ssboIN %zero %valLoopNdx %c_i32_2\n"
4688         "%val_v3i32 = OpLoad %v3${32type} %v3i32src\n"
4689         "%val_v3i8 = ${convert} %v3i8 %val_v3i32\n"
4690         "%v3i8dst  = OpAccessChain %v3i8ptr %ssboOUT %zero %valLoopNdx %c_i32_2\n"
4691         "OpStore %v3i8dst %val_v3i8\n"
4692         "\n"
4693         "%v4i32src  = OpAccessChain %v4i32ptr %ssboIN %zero %valLoopNdx %c_i32_3\n"
4694         "%val_v4i32 = OpLoad %v4${32type} %v4i32src\n"
4695         "%val_v4i8 = ${convert} %v4i8 %val_v4i32\n"
4696         "%v4i8dst  = OpAccessChain %v4i8ptr %ssboOUT %zero %valLoopNdx %c_i32_3\n"
4697         "OpStore %v4i8dst %val_v4i8\n"
4698         "\n"
4699         "%i32src2  = OpAccessChain %i32ptr %ssboIN %zero %valLoopNdx %c_i32_7\n"
4700         "%val2_i32 = OpLoad %${32type} %i32src2\n"
4701         "%val2_i8 = ${convert} %i8 %val2_i32\n"
4702         "%i8dst2  = OpAccessChain %i8ptr %ssboOUT %zero %valLoopNdx %c_i32_7\n"
4703         "OpStore %i8dst2 %val2_i8\n"
4704         "\n"
4705         "OpStore %insideLoopNdx %zero\n"
4706         "OpBranch %loopInside\n"
4707         "%loopInside = OpLabel\n"
4708         "OpLoopMerge %92 %93 None\n"
4709         "OpBranch %94\n"
4710         "%94 = OpLabel\n"
4711         "%valInsideLoopNdx = OpLoad %i32 %insideLoopNdx\n"
4712         "%96 = OpSLessThan %bool %valInsideLoopNdx %c_i32_11\n"
4713         "OpBranchConditional %96 %91 %92\n"
4714         "\n"
4715         "%91 = OpLabel\n"
4716         "\n"
4717         //struct {i8, v2i8[3]}
4718         "%Si32src  = OpAccessChain %i32ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %zero\n"
4719         "%Sval_i32 = OpLoad %${32type} %Si32src\n"
4720         "%Sval_i8  = ${convert} %i8 %Sval_i32\n"
4721         "%Si8dst2  = OpAccessChain %i8ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %zero\n"
4722         "OpStore %Si8dst2 %Sval_i8\n"
4723         "\n"
4724         "%Sv2i32src0 = OpAccessChain %v2i32ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %zero\n"
4725         "%Sv2i32_0   = OpLoad %v2${32type} %Sv2i32src0\n"
4726         "%Sv2i8_0    = ${convert} %v2i8 %Sv2i32_0\n"
4727         "%Sv2i8dst_0 = OpAccessChain %v2i8ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %zero\n"
4728         "OpStore %Sv2i8dst_0 %Sv2i8_0\n"
4729         "\n"
4730         "%Sv2i32src1 = OpAccessChain %v2i32ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_1\n"
4731         "%Sv2i32_1   = OpLoad %v2${32type} %Sv2i32src1\n"
4732         "%Sv2i8_1    = ${convert} %v2i8 %Sv2i32_1\n"
4733         "%Sv2i8dst_1 = OpAccessChain %v2i8ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_1\n"
4734         "OpStore %Sv2i8dst_1 %Sv2i8_1\n"
4735         "\n"
4736         "%Sv2i32src2 = OpAccessChain %v2i32ptr %ssboIN %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_2\n"
4737         "%Sv2i32_2   = OpLoad %v2${32type} %Sv2i32src2\n"
4738         "%Sv2i8_2    = ${convert} %v2i8 %Sv2i32_2\n"
4739         "%Sv2i8dst_2 = OpAccessChain %v2i8ptr %ssboOUT %zero %valLoopNdx %c_i32_5 %valInsideLoopNdx %c_i32_1 %c_i32_2\n"
4740         "OpStore %Sv2i8dst_2 %Sv2i8_2\n"
4741         "\n"
4742 
4743         "%v2i32src2  = OpAccessChain %v2i32ptr %ssboIN %zero %valLoopNdx %c_i32_6 %valInsideLoopNdx\n"
4744         "%val2_v2i32 = OpLoad %v2${32type} %v2i32src2\n"
4745         "%val2_v2i8  = ${convert} %v2i8 %val2_v2i32\n"
4746         "%v2i8dst2   = OpAccessChain %v2i8ptr %ssboOUT %zero %valLoopNdx %c_i32_6 %valInsideLoopNdx\n"
4747         "OpStore %v2i8dst2 %val2_v2i8\n"
4748         "\n"
4749         "%v3i32src2  = OpAccessChain %v3i32ptr %ssboIN %zero %valLoopNdx %c_i32_8 %valInsideLoopNdx\n"
4750         "%val2_v3i32 = OpLoad %v3${32type} %v3i32src2\n"
4751         "%val2_v3i8  = ${convert} %v3i8 %val2_v3i32\n"
4752         "%v3i8dst2   = OpAccessChain %v3i8ptr %ssboOUT %zero %valLoopNdx %c_i32_8 %valInsideLoopNdx\n"
4753         "OpStore %v3i8dst2 %val2_v3i8\n"
4754         "\n"
4755 
4756         //Array with 3 elements
4757         "%LessThan3 = OpSLessThan %bool %valInsideLoopNdx %c_i32_3\n"
4758         "OpSelectionMerge %BlockIf None\n"
4759         "OpBranchConditional %LessThan3 %LabelIf %BlockIf\n"
4760         "  %LabelIf = OpLabel\n"
4761         "  %i32src3  = OpAccessChain %i32ptr %ssboIN %zero %valLoopNdx %c_i32_4 %valInsideLoopNdx\n"
4762         "  %val3_i32 = OpLoad %${32type} %i32src3\n"
4763         "  %val3_i8  = ${convert} %i8 %val3_i32\n"
4764         "  %i8dst3   = OpAccessChain %i8ptr %ssboOUT %zero %valLoopNdx %c_i32_4 %valInsideLoopNdx\n"
4765         "  OpStore %i8dst3 %val3_i8\n"
4766         "\n"
4767         "  %v4i32src2  = OpAccessChain %v4i32ptr %ssboIN %zero %valLoopNdx %c_i32_9 %valInsideLoopNdx\n"
4768         "  %val2_v4i32 = OpLoad %v4${32type} %v4i32src2\n"
4769         "  %val2_v4i8  = ${convert} %v4i8 %val2_v4i32\n"
4770         "  %v4i8dst2   = OpAccessChain %v4i8ptr %ssboOUT %zero %valLoopNdx %c_i32_9 %valInsideLoopNdx\n"
4771         "  OpStore %v4i8dst2 %val2_v4i8\n"
4772         "OpBranch %BlockIf\n"
4773         "%BlockIf = OpLabel\n"
4774 
4775         "OpBranch %93\n"
4776         "%93 = OpLabel\n"
4777         "%132 = OpLoad %i32 %insideLoopNdx\n"
4778         "%133 = OpIAdd %i32 %132 %c_i32_1\n"
4779         "OpStore %insideLoopNdx %133\n"
4780         "OpBranch %loopInside\n"
4781         "\n"
4782         "%92 = OpLabel\n"
4783         "OpBranch %13\n"
4784         "%13 = OpLabel\n"
4785         "%134 = OpLoad %i32 %loopNdx\n"
4786         "%135 = OpIAdd %i32 %134 %c_i32_1\n"
4787         "OpStore %loopNdx %135\n"
4788         "OpBranch %loop\n"
4789 
4790         "%merge = OpLabel\n"
4791         "         OpReturnValue %param\n"
4792         "         OpFunctionEnd\n");
4793 
4794     struct IntegerFacts
4795     {
4796         const char *name;
4797         const char *opcode;
4798         const char *signedInt;
4799         const char *type32;
4800     };
4801 
4802     const IntegerFacts intFacts[] = {
4803         {"sint", "OpSConvert", "1", "i32"},
4804         {"uint", "OpUConvert", "0", "u32"},
4805     };
4806 
4807     for (uint32_t capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
4808         for (uint32_t intFactsNdx = 0; intFactsNdx < DE_LENGTH_OF_ARRAY(intFacts); ++intFactsNdx)
4809         {
4810             const bool isUniform = (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == CAPABILITIES[capIdx].dtype);
4811             map<string, string> specs;
4812             string testName         = string(CAPABILITIES[capIdx].name) + "_" + intFacts[intFactsNdx].name;
4813             vector<int32_t> i32Data = isUniform ? data32bit(SHADERTEMPLATE_STRIDE32BIT_STD140, rnd) :
4814                                                   data32bit(SHADERTEMPLATE_STRIDE32BIT_STD430, rnd);
4815             GraphicsResources resources;
4816             VulkanFeatures features;
4817 
4818             specs["cap"]       = CAPABILITIES[STORAGE_BUFFER_TEST].cap;
4819             specs["stridei8"]  = getStructShaderComponet(SHADERTEMPLATE_STRIDE8BIT_STD430);
4820             specs["stridei32"] = getStructShaderComponet(isUniform ? SHADERTEMPLATE_STRIDE32BIT_STD140 :
4821                                                                      SHADERTEMPLATE_STRIDE32BIT_STD430);
4822             specs["8Storage"]  = "StorageBuffer";
4823             specs["32Storage"] = isUniform ? "Uniform" : "StorageBuffer";
4824             specs["signed"]    = intFacts[intFactsNdx].signedInt;
4825             specs["convert"]   = intFacts[intFactsNdx].opcode;
4826             specs["32type"]    = intFacts[intFactsNdx].type32;
4827 
4828             fragments["capability"] = capabilities.specialize(specs);
4829             fragments["decoration"] = decoration.specialize(specs);
4830             fragments["pre_main"]   = preMain.specialize(specs);
4831             fragments["testfun"]    = testFun.specialize(specs);
4832 
4833             resources.inputs.push_back(Resource(BufferSp(new Int32Buffer(i32Data)), CAPABILITIES[capIdx].dtype));
4834             resources.outputs.push_back(
4835                 Resource(BufferSp(new Int8Buffer(i8Data)), CAPABILITIES[STORAGE_BUFFER_TEST].dtype));
4836             if (isUniform)
4837                 resources.verifyIO =
4838                     checkStruct<int32_t, int8_t, SHADERTEMPLATE_STRIDE32BIT_STD140, SHADERTEMPLATE_STRIDE8BIT_STD430>;
4839             else
4840                 resources.verifyIO =
4841                     checkStruct<int32_t, int8_t, SHADERTEMPLATE_STRIDE32BIT_STD430, SHADERTEMPLATE_STRIDE8BIT_STD430>;
4842 
4843             features = get8BitStorageFeatures(CAPABILITIES[STORAGE_BUFFER_TEST].name);
4844             features.coreFeatures.vertexPipelineStoresAndAtomics = true;
4845             features.coreFeatures.fragmentStoresAndAtomics       = true;
4846 
4847             createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, testGroup,
4848                                     features);
4849         }
4850 }
4851 
addGraphics8bitStorage8bitStructMixedTypesGroup(tcu::TestCaseGroup * group)4852 void addGraphics8bitStorage8bitStructMixedTypesGroup(tcu::TestCaseGroup *group)
4853 {
4854     de::Random rnd(deStringHash(group->getName()));
4855     map<string, string> fragments;
4856     vector<string> extensions;
4857     RGBA defaultColors[4];
4858     const StringTemplate capabilities("OpCapability StorageBuffer8BitAccess\n"
4859                                       "${cap}\n");
4860     vector<int8_t> outData = data8bit(SHADERTEMPLATE_STRIDEMIX_STD430, rnd, false);
4861 
4862     extensions.push_back("VK_KHR_8bit_storage");
4863     fragments["extension"] = "OpExtension \"SPV_KHR_8bit_storage\"\n"
4864                              "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
4865 
4866     getDefaultColors(defaultColors);
4867 
4868     const StringTemplate preMain("\n" //Types
4869                                  "%i8    = OpTypeInt 8 1\n"
4870                                  "%v2i8  = OpTypeVector %i8 2\n"
4871                                  "%v3i8  = OpTypeVector %i8 3\n"
4872                                  "%v4i8  = OpTypeVector %i8 4\n"
4873                                  "\n" //Consta value
4874                                  "%zero     = OpConstant %i32 0\n"
4875                                  "%c_i32_5  = OpConstant %i32 5\n"
4876                                  "%c_i32_6  = OpConstant %i32 6\n"
4877                                  "%c_i32_7  = OpConstant %i32 7\n"
4878                                  "%c_i32_8  = OpConstant %i32 8\n"
4879                                  "%c_i32_9  = OpConstant %i32 9\n"
4880                                  "%c_i32_10 = OpConstant %i32 10\n"
4881                                  "%c_i32_11 = OpConstant %i32 11\n"
4882                                  "%c_u32_7  = OpConstant %u32 7\n"
4883                                  "%c_u32_11 = OpConstant %u32 11\n"
4884                                  "\n" //Arrays & Structs
4885                                  "%v2b8NestedArr11In  = OpTypeArray %v2i8 %c_u32_11\n"
4886                                  "%b32NestedArr11In   = OpTypeArray %i32 %c_u32_11\n"
4887                                  "%sb8Arr11In         = OpTypeArray %i8 %c_u32_11\n"
4888                                  "%sb32Arr11In        = OpTypeArray %i32 %c_u32_11\n"
4889                                  "%sNestedIn          = OpTypeStruct %i8 %i32 %v2b8NestedArr11In %b32NestedArr11In\n"
4890                                  "%sNestedArr11In     = OpTypeArray %sNestedIn %c_u32_11\n"
4891                                  "%structIn           = OpTypeStruct %i8 %i32 %v2i8 %v2i32 %v3i8 %v3i32 %v4i8 %v4i32 "
4892                                  "%sNestedArr11In %sb8Arr11In %sb32Arr11In\n"
4893                                  "%structArr7In       = OpTypeArray %structIn %c_u32_7\n"
4894                                  "%v2b8NestedArr11Out = OpTypeArray %v2i8 %c_u32_11\n"
4895                                  "%b32NestedArr11Out  = OpTypeArray %i32 %c_u32_11\n"
4896                                  "%sb8Arr11Out        = OpTypeArray %i8 %c_u32_11\n"
4897                                  "%sb32Arr11Out       = OpTypeArray %i32 %c_u32_11\n"
4898                                  "%sNestedOut         = OpTypeStruct %i8 %i32 %v2b8NestedArr11Out %b32NestedArr11Out\n"
4899                                  "%sNestedArr11Out    = OpTypeArray %sNestedOut %c_u32_11\n"
4900                                  "%structOut          = OpTypeStruct %i8 %i32 %v2i8 %v2i32 %v3i8 %v3i32 %v4i8 %v4i32 "
4901                                  "%sNestedArr11Out %sb8Arr11Out %sb32Arr11Out\n"
4902                                  "%structArr7Out      = OpTypeArray %structOut %c_u32_7\n"
4903                                  "\n" //Pointers
4904                                  "${uniformPtr}"
4905                                  "%i8outPtr    = OpTypePointer StorageBuffer %i8\n"
4906                                  "%v2i8outPtr  = OpTypePointer StorageBuffer %v2i8\n"
4907                                  "%v3i8outPtr  = OpTypePointer StorageBuffer %v3i8\n"
4908                                  "%v4i8outPtr  = OpTypePointer StorageBuffer %v4i8\n"
4909                                  "%i32outPtr   = OpTypePointer StorageBuffer %i32\n"
4910                                  "%v2i32outPtr = OpTypePointer StorageBuffer %v2i32\n"
4911                                  "%v3i32outPtr = OpTypePointer StorageBuffer %v3i32\n"
4912                                  "%v4i32outPtr = OpTypePointer StorageBuffer %v4i32\n"
4913                                  "%uvec3ptr = OpTypePointer Input %v3u32\n"
4914                                  "\n" //SSBO IN
4915                                  "%SSBO_IN    = OpTypeStruct %structArr7In\n"
4916                                  "%up_SSBOIN  = OpTypePointer ${inStorage} %SSBO_IN\n"
4917                                  "%ssboIN     = OpVariable %up_SSBOIN ${inStorage}\n"
4918                                  "\n" //SSBO OUT
4919                                  "%SSBO_OUT   = OpTypeStruct %structArr7Out\n"
4920                                  "%up_SSBOOUT = OpTypePointer StorageBuffer %SSBO_OUT\n"
4921                                  "%ssboOUT    = OpVariable %up_SSBOOUT StorageBuffer\n");
4922 
4923     const StringTemplate decoration("${OutOffsets}"
4924                                     "${InOffsets}"
4925                                     "\n" //SSBO IN
4926                                     "OpDecorate %SSBO_IN Block\n"
4927                                     "OpMemberDecorate %SSBO_IN 0 Offset 0\n"
4928                                     "OpDecorate %ssboIN DescriptorSet 0\n"
4929                                     "OpDecorate %ssboIN Binding 0\n"
4930                                     "\n" //SSBO OUT
4931                                     "OpDecorate %SSBO_OUT Block\n"
4932                                     "OpMemberDecorate %SSBO_OUT 0 Offset 0\n"
4933                                     "OpDecorate %ssboOUT DescriptorSet 0\n"
4934                                     "OpDecorate %ssboOUT Binding 1\n");
4935 
4936     const StringTemplate testFun(
4937         "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
4938         "%param     = OpFunctionParameter %v4f32\n"
4939         "%label     = OpLabel\n"
4940         "%ndxArrx   = OpVariable %fp_i32  Function\n"
4941         "%ndxArry   = OpVariable %fp_i32  Function\n"
4942         "%ndxArrz   = OpVariable %fp_i32  Function\n"
4943         "${xBeginLoop}"
4944         "\n" //strutOut.b8 = strutIn.b8
4945         "%inP1  = OpAccessChain %i8${inPtr} %ssboIN %zero %Valx %zero\n"
4946         "%inV1  = OpLoad %i8 %inP1\n"
4947         "%outP1 = OpAccessChain %i8outPtr %ssboOUT %zero %Valx %zero\n"
4948         "OpStore %outP1 %inV1\n"
4949         "\n" //strutOut.b32 = strutIn.b32
4950         "%inP2  = OpAccessChain %i32${inPtr} %ssboIN %zero %Valx %c_i32_1\n"
4951         "%inV2  = OpLoad %i32 %inP2\n"
4952         "%outP2 = OpAccessChain %i32outPtr %ssboOUT %zero %Valx %c_i32_1\n"
4953         "OpStore %outP2 %inV2\n"
4954         "\n" //strutOut.v2b8 = strutIn.v2b8
4955         "%inP3  = OpAccessChain %v2i8${inPtr} %ssboIN %zero %Valx %c_i32_2\n"
4956         "%inV3  = OpLoad %v2i8 %inP3\n"
4957         "%outP3 = OpAccessChain %v2i8outPtr %ssboOUT %zero %Valx %c_i32_2\n"
4958         "OpStore %outP3 %inV3\n"
4959         "\n" //strutOut.v2b32 = strutIn.v2b32
4960         "%inP4  = OpAccessChain %v2i32${inPtr} %ssboIN %zero %Valx %c_i32_3\n"
4961         "%inV4  = OpLoad %v2i32 %inP4\n"
4962         "%outP4 = OpAccessChain %v2i32outPtr %ssboOUT %zero %Valx %c_i32_3\n"
4963         "OpStore %outP4 %inV4\n"
4964         "\n" //strutOut.v3b8 = strutIn.v3b8
4965         "%inP5  = OpAccessChain %v3i8${inPtr} %ssboIN %zero %Valx %c_i32_4\n"
4966         "%inV5  = OpLoad %v3i8 %inP5\n"
4967         "%outP5 = OpAccessChain %v3i8outPtr %ssboOUT %zero %Valx %c_i32_4\n"
4968         "OpStore %outP5 %inV5\n"
4969         "\n" //strutOut.v3b32 = strutIn.v3b32
4970         "%inP6  = OpAccessChain %v3i32${inPtr} %ssboIN %zero %Valx %c_i32_5\n"
4971         "%inV6  = OpLoad %v3i32 %inP6\n"
4972         "%outP6 = OpAccessChain %v3i32outPtr %ssboOUT %zero %Valx %c_i32_5\n"
4973         "OpStore %outP6 %inV6\n"
4974         "\n" //strutOut.v4b8 = strutIn.v4b8
4975         "%inP7  = OpAccessChain %v4i8${inPtr} %ssboIN %zero %Valx %c_i32_6\n"
4976         "%inV7  = OpLoad %v4i8 %inP7\n"
4977         "%outP7 = OpAccessChain %v4i8outPtr %ssboOUT %zero %Valx %c_i32_6\n"
4978         "OpStore %outP7 %inV7\n"
4979         "\n" //strutOut.v4b32 = strutIn.v4b32
4980         "%inP8  = OpAccessChain %v4i32${inPtr} %ssboIN %zero %Valx %c_i32_7\n"
4981         "%inV8  = OpLoad %v4i32 %inP8\n"
4982         "%outP8 = OpAccessChain %v4i32outPtr %ssboOUT %zero %Valx %c_i32_7\n"
4983         "OpStore %outP8 %inV8\n"
4984         "${yBeginLoop}"
4985         "\n" //strutOut.b8[y] = strutIn.b8[y]
4986         "%inP9  = OpAccessChain %i8${inPtr} %ssboIN %zero %Valx %c_i32_9 %Valy\n"
4987         "%inV9  = OpLoad %i8 %inP9\n"
4988         "%outP9 = OpAccessChain %i8outPtr %ssboOUT %zero %Valx %c_i32_9 %Valy\n"
4989         "OpStore %outP9 %inV9\n"
4990         "\n" //strutOut.b32[y] = strutIn.b32[y]
4991         "%inP10  = OpAccessChain %i32${inPtr} %ssboIN %zero %Valx %c_i32_10 %Valy\n"
4992         "%inV10  = OpLoad %i32 %inP10\n"
4993         "%outP10 = OpAccessChain %i32outPtr %ssboOUT %zero %Valx %c_i32_10 %Valy\n"
4994         "OpStore %outP10 %inV10\n"
4995         "\n" //strutOut.strutNestedOut[y].b8 = strutIn.strutNestedIn[y].b8
4996         "%inP11 = OpAccessChain %i8${inPtr} %ssboIN %zero %Valx %c_i32_8 %Valy %zero\n"
4997         "%inV11 = OpLoad %i8 %inP11\n"
4998         "%outP11 = OpAccessChain %i8outPtr %ssboOUT %zero %Valx %c_i32_8 %Valy %zero\n"
4999         "OpStore %outP11 %inV11\n"
5000         "\n" //strutOut.strutNestedOut[y].b32 = strutIn.strutNestedIn[y].b32
5001         "%inP12 = OpAccessChain %i32${inPtr} %ssboIN %zero %Valx %c_i32_8 %Valy %c_i32_1\n"
5002         "%inV12 = OpLoad %i32 %inP12\n"
5003         "%outP12 = OpAccessChain %i32outPtr %ssboOUT %zero %Valx %c_i32_8 %Valy %c_i32_1\n"
5004         "OpStore %outP12 %inV12\n"
5005         "${zBeginLoop}"
5006         "\n" //strutOut.strutNestedOut[y].v2b8[valNdx] = strutIn.strutNestedIn[y].v2b8[valNdx]
5007         "%inP13  = OpAccessChain %v2i8${inPtr} %ssboIN %zero %Valx %c_i32_8 %Valy %c_i32_2 %Valz\n"
5008         "%inV13  = OpLoad %v2i8 %inP13\n"
5009         "%outP13 = OpAccessChain %v2i8outPtr %ssboOUT %zero %Valx %c_i32_8 %Valy %c_i32_2 %Valz\n"
5010         "OpStore %outP13 %inV13\n"
5011         "\n" //strutOut.strutNestedOut[y].b32[valNdx] = strutIn.strutNestedIn[y].b32[valNdx]
5012         "%inP14  = OpAccessChain %i32${inPtr} %ssboIN %zero %Valx %c_i32_8 %Valy %c_i32_3 %Valz\n"
5013         "%inV14  = OpLoad %i32 %inP14\n"
5014         "%outP14 = OpAccessChain %i32outPtr %ssboOUT %zero %Valx %c_i32_8 %Valy %c_i32_3 %Valz\n"
5015         "OpStore %outP14 %inV14\n"
5016         "${zEndLoop}"
5017         "${yEndLoop}"
5018         "${xEndLoop}"
5019         "\n"
5020         "OpBranch %ExitLabel\n"
5021         "%ExitLabel = OpLabel\n"
5022         "OpReturnValue %param\n"
5023         "OpFunctionEnd\n");
5024 
5025     for (uint32_t capIdx = 0; capIdx < DE_LENGTH_OF_ARRAY(CAPABILITIES); ++capIdx)
5026     { // int
5027         const bool isUniform = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER == CAPABILITIES[capIdx].dtype;
5028         vector<int8_t> inData =
5029             isUniform ? data8bit(SHADERTEMPLATE_STRIDEMIX_STD140, rnd) : data8bit(SHADERTEMPLATE_STRIDEMIX_STD430, rnd);
5030         GraphicsResources resources;
5031         map<string, string> specsLoop;
5032         map<string, string> specsOffset;
5033         map<string, string> specs;
5034         VulkanFeatures features;
5035         string testName = string(CAPABILITIES[capIdx].name);
5036 
5037         specsLoop["exeCount"] = "c_i32_7";
5038         specsLoop["loopName"] = "x";
5039         specs["xBeginLoop"]   = beginLoop(specsLoop);
5040         specs["xEndLoop"]     = endLoop(specsLoop);
5041 
5042         specsLoop["exeCount"] = "c_i32_11";
5043         specsLoop["loopName"] = "y";
5044         specs["yBeginLoop"]   = beginLoop(specsLoop);
5045         specs["yEndLoop"]     = endLoop(specsLoop);
5046 
5047         specsLoop["exeCount"] = "c_i32_11";
5048         specsLoop["loopName"] = "z";
5049         specs["zBeginLoop"]   = beginLoop(specsLoop);
5050         specs["zEndLoop"]     = endLoop(specsLoop);
5051 
5052         specs["inStorage"]   = isUniform ? "Uniform" : "StorageBuffer";
5053         specs["cap"]         = isUniform ? "OpCapability " + string(CAPABILITIES[capIdx].cap) : "";
5054         specs["uniformPtr"]  = isUniform ? "%i8inPtr     = OpTypePointer Uniform %i8\n"
5055                                            "%v2i8inPtr   = OpTypePointer Uniform %v2i8\n"
5056                                            "%v3i8inPtr   = OpTypePointer Uniform %v3i8\n"
5057                                            "%v4i8inPtr   = OpTypePointer Uniform %v4i8\n"
5058                                            "%i32inPtr    = OpTypePointer Uniform %i32\n"
5059                                            "%v2i32inPtr  = OpTypePointer Uniform %v2i32\n"
5060                                            "%v3i32inPtr  = OpTypePointer Uniform %v3i32\n"
5061                                            "%v4i32inPtr  = OpTypePointer Uniform %v4i32\n" :
5062                                            "";
5063         specs["inPtr"]       = isUniform ? "inPtr" : "outPtr";
5064         specsOffset["InOut"] = "In";
5065         specs["InOffsets"]   = StringTemplate(isUniform ? getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD140) :
5066                                                           getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD430))
5067                                  .specialize(specsOffset);
5068         specsOffset["InOut"] = "Out";
5069         specs["OutOffsets"] =
5070             StringTemplate(getStructShaderComponet(SHADERTEMPLATE_STRIDEMIX_STD430)).specialize(specsOffset);
5071 
5072         fragments["capability"] = capabilities.specialize(specs);
5073         fragments["decoration"] = decoration.specialize(specs);
5074         fragments["pre_main"]   = preMain.specialize(specs);
5075         fragments["testfun"]    = testFun.specialize(specs);
5076 
5077         resources.verifyIO =
5078             isUniform ? checkStruct<int8_t, int8_t, SHADERTEMPLATE_STRIDEMIX_STD140, SHADERTEMPLATE_STRIDEMIX_STD430> :
5079                         checkStruct<int8_t, int8_t, SHADERTEMPLATE_STRIDEMIX_STD430, SHADERTEMPLATE_STRIDEMIX_STD430>;
5080         resources.inputs.push_back(Resource(BufferSp(new Int8Buffer(inData)), CAPABILITIES[capIdx].dtype));
5081         resources.outputs.push_back(
5082             Resource(BufferSp(new Int8Buffer(outData)), CAPABILITIES[STORAGE_BUFFER_TEST].dtype));
5083 
5084         features                                             = get8BitStorageFeatures(CAPABILITIES[capIdx].name);
5085         features.coreFeatures.vertexPipelineStoresAndAtomics = true;
5086         features.coreFeatures.fragmentStoresAndAtomics       = true;
5087 
5088         createTestsForAllStages(testName, defaultColors, defaultColors, fragments, resources, extensions, group,
5089                                 features);
5090     }
5091 }
5092 
5093 } // namespace
5094 
create8BitStorageComputeGroup(tcu::TestContext & testCtx)5095 tcu::TestCaseGroup *create8BitStorageComputeGroup(tcu::TestContext &testCtx)
5096 {
5097     // Compute tests for VK_KHR_8bit_storage extension
5098     de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "8bit_storage"));
5099 
5100     // 32bit ints to 8bit tests under capability StorageBuffer8BitAccess
5101     addTestGroup(group.get(), "storagebuffer_32_to_8", addCompute8bitStorage32To8Group);
5102     // 8bit ints to 32bit tests under capability UniformAndStorageBuffer8BitAccess
5103     addTestGroup(group.get(), "uniform_8_to_32", addCompute8bitUniform8To32Group);
5104     // 8bit ints to 32bit tests under capability StoragePushConstant8
5105     addTestGroup(group.get(), "push_constant_8_to_32", addCompute8bitStoragePushConstant8To32Group);
5106 
5107     // 16bit ints to 8bit tests under capability StorageBuffer8BitAccess
5108     addTestGroup(group.get(), "storagebuffer_16_to_8", addCompute8bitStorage16To8Group);
5109     // 8bit ints to 16bit tests under capability UniformAndStorageBuffer8BitAccess
5110     addTestGroup(group.get(), "uniform_8_to_16", addCompute8bitUniform8To16Group);
5111     // 8bit ints to 16bit tests under capability StoragePushConstant8
5112     addTestGroup(group.get(), "push_constant_8_to_16", addCompute8bitStoragePushConstant8To16Group);
5113 
5114     // 8bit ints to 8bit tests under capability UniformAndStorageBuffer8BitAccess
5115     addTestGroup(group.get(), "uniform_8_to_8", addCompute8bitStorageBuffer8To8Group);
5116 
5117     // 8bit floats struct to 32bit tests under capability UniformAndStorageBuffer8BitAccess
5118     addTestGroup(group.get(), "uniform_8struct_to_32struct", addCompute8bitStorageUniform8StructTo32StructGroup);
5119     // 32bit floats struct to 8bit tests under capability StorageBuffer8BitAccess
5120     addTestGroup(group.get(), "storagebuffer_32struct_to_8struct", addCompute8bitStorageUniform32StructTo8StructGroup);
5121     // mixed type of 8bit and 32bit struct
5122     addTestGroup(group.get(), "struct_mixed_types", addCompute8bitStorage8bitStructMixedTypesGroup);
5123 
5124     return group.release();
5125 }
5126 
create8BitStorageGraphicsGroup(tcu::TestContext & testCtx)5127 tcu::TestCaseGroup *create8BitStorageGraphicsGroup(tcu::TestContext &testCtx)
5128 {
5129     // Graphics tests for VK_KHR_8bit_storage extension
5130     de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "8bit_storage"));
5131 
5132     // 32-bit int into 8-bit tests under capability StorageBuffer8BitAccess
5133     addTestGroup(group.get(), "storagebuffer_int_32_to_8", addGraphics8BitStorageUniformInt32To8Group);
5134     // 8-bit int into 32-bit tests under capability UniformAndStorageBuffer8BitAccess
5135     addTestGroup(group.get(), "uniform_int_8_to_32", addGraphics8BitStorageUniformInt8To32Group);
5136     // 8-bit int into 32-bit tests under capability StoragePushConstant8
5137     addTestGroup(group.get(), "push_constant_int_8_to_32", addGraphics8BitStoragePushConstantInt8To32Group);
5138 
5139     // 16-bit int into 8-bit tests under capability StorageBuffer8BitAccess
5140     addTestGroup(group.get(), "storagebuffer_int_16_to_8", addGraphics8BitStorageUniformInt16To8Group);
5141     // 8-bit int into 16-bit tests under capability UniformAndStorageBuffer8BitAccess
5142     addTestGroup(group.get(), "uniform_int_8_to_16", addGraphics8BitStorageUniformInt8To16Group);
5143     // 8-bit int into 16-bit tests under capability StoragePushConstant8
5144     addTestGroup(group.get(), "push_constant_int_8_to_16", addGraphics8BitStoragePushConstantInt8To16Group);
5145 
5146     // 8bit floats struct to 32bit tests
5147     addTestGroup(group.get(), "8struct_to_32struct", addGraphics8BitStorageUniformStruct8To32Group);
5148     // 32bit floats struct to 8bit tests
5149     addTestGroup(group.get(), "32struct_to_8struct", addGraphics8BitStorageUniformStruct32To8Group);
5150     // mixed type of 8bit and 32bit struc
5151     addTestGroup(group.get(), "struct_mixed_types", addGraphics8bitStorage8bitStructMixedTypesGroup);
5152 
5153     return group.release();
5154 }
5155 
5156 } // namespace SpirVAssembly
5157 } // namespace vkt
5158