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
getStructSize(const ShaderTemplate shaderTemplate)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
get8BitStorageFeatures(const char * cap)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
computeCheckBuffers(const std::vector<Resource> & originalInts,const vector<AllocationSp> & outputAllocs,const std::vector<Resource> &,tcu::TestLog &)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
addInfo(vector<bool> & info,int & ndx,const int count,const bool isData)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
data8bit(const ShaderTemplate std,de::Random & rnd,const bool isData=true)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
data32bit(const ShaderTemplate std,de::Random & rnd,const bool isData=true)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
info8bitStd140(void)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
info8bitStd430(void)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
info32bitStd140(void)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
info32bitStd430(void)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
infoMixStd140(void)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
infoMixStd430(void)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>
compareStruct(const resultType * returned,const originType * original)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>
checkStruct(const std::vector<Resource> & originalFloats,const vector<AllocationSp> & outputAllocs,const std::vector<Resource> &,tcu::TestLog &)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>
checkUniformsArray(const std::vector<Resource> & originalFloats,const vector<AllocationSp> & outputAllocs,const std::vector<Resource> &,tcu::TestLog &)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>
checkUniformsArrayConstNdx(const std::vector<Resource> & originalFloats,const vector<AllocationSp> & outputAllocs,const std::vector<Resource> &,tcu::TestLog &)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
getStructShaderComponet(const ShaderTemplate component)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*/
beginLoop(const std::map<std::string,std::string> & spec)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*/
endLoop(const std::map<std::string,std::string> & spec)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
addCompute8bitStorage32To8Group(tcu::TestCaseGroup * group)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
addCompute8bitUniform8To32Group(tcu::TestCaseGroup * group)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
addCompute8bitStoragePushConstant8To32Group(tcu::TestCaseGroup * group)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
addCompute8bitStorage16To8Group(tcu::TestCaseGroup * group)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
addCompute8bitUniform8To16Group(tcu::TestCaseGroup * group)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
addCompute8bitStoragePushConstant8To16Group(tcu::TestCaseGroup * group)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
addCompute8bitStorageBuffer8To8Group(tcu::TestCaseGroup * group)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> int8DummyData (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(int8DummyData)));
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
addCompute8bitStorageUniform8StructTo32StructGroup(tcu::TestCaseGroup * group)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
addCompute8bitStorageUniform32StructTo8StructGroup(tcu::TestCaseGroup * group)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
addCompute8bitStorage8bitStructMixedTypesGroup(tcu::TestCaseGroup * group)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
addGraphics8BitStorageUniformInt32To8Group(tcu::TestCaseGroup * testGroup)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
addGraphics8BitStorageUniformInt8To32Group(tcu::TestCaseGroup * testGroup)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
addGraphics8BitStoragePushConstantInt8To32Group(tcu::TestCaseGroup * testGroup)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
addGraphics8BitStorageUniformInt16To8Group(tcu::TestCaseGroup * testGroup)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
addGraphics8BitStorageUniformInt8To16Group(tcu::TestCaseGroup * testGroup)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
addGraphics8BitStoragePushConstantInt8To16Group(tcu::TestCaseGroup * testGroup)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
addGraphics8BitStorageUniformStruct8To32Group(tcu::TestCaseGroup * testGroup)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
addGraphics8BitStorageUniformStruct32To8Group(tcu::TestCaseGroup * testGroup)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
addGraphics8bitStorage8bitStructMixedTypesGroup(tcu::TestCaseGroup * group)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
create8BitStorageComputeGroup(tcu::TestContext & testCtx)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
create8BitStorageGraphicsGroup(tcu::TestContext & testCtx)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
5147