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