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