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