1/*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Utilities for vertex buffers.
23 *//*--------------------------------------------------------------------*/
24
25#include "vktPipelineVertexUtil.hpp"
26#include "vkStrUtil.hpp"
27#include "tcuVectorUtil.hpp"
28#include "deStringUtil.hpp"
29
30namespace vkt
31{
32namespace pipeline
33{
34
35using namespace vk;
36
37deUint32 getVertexFormatSize (VkFormat format)
38{
39	switch (format)
40	{
41		case VK_FORMAT_R8_UNORM:
42		case VK_FORMAT_R8_SNORM:
43		case VK_FORMAT_R8_USCALED:
44		case VK_FORMAT_R8_SSCALED:
45		case VK_FORMAT_R8_UINT:
46		case VK_FORMAT_R8_SINT:
47		case VK_FORMAT_R8_SRGB:
48		case VK_FORMAT_R4G4_UNORM_PACK8:
49			return 1;
50
51		case VK_FORMAT_R8G8_UNORM:
52		case VK_FORMAT_R8G8_SNORM:
53		case VK_FORMAT_R8G8_USCALED:
54		case VK_FORMAT_R8G8_SSCALED:
55		case VK_FORMAT_R8G8_UINT:
56		case VK_FORMAT_R8G8_SINT:
57		case VK_FORMAT_R8G8_SRGB:
58		case VK_FORMAT_R16_UNORM:
59		case VK_FORMAT_R16_SNORM:
60		case VK_FORMAT_R16_USCALED:
61		case VK_FORMAT_R16_SSCALED:
62		case VK_FORMAT_R16_UINT:
63		case VK_FORMAT_R16_SINT:
64		case VK_FORMAT_R16_SFLOAT:
65		case VK_FORMAT_R5G6B5_UNORM_PACK16:
66		case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
67			return 2;
68
69		case VK_FORMAT_R8G8B8_UNORM:
70		case VK_FORMAT_R8G8B8_SNORM:
71		case VK_FORMAT_R8G8B8_USCALED:
72		case VK_FORMAT_R8G8B8_SSCALED:
73		case VK_FORMAT_R8G8B8_UINT:
74		case VK_FORMAT_R8G8B8_SINT:
75		case VK_FORMAT_R8G8B8_SRGB:
76		case VK_FORMAT_B8G8R8_UNORM:
77		case VK_FORMAT_B8G8R8_SNORM:
78		case VK_FORMAT_B8G8R8_USCALED:
79		case VK_FORMAT_B8G8R8_SSCALED:
80		case VK_FORMAT_B8G8R8_UINT:
81		case VK_FORMAT_B8G8R8_SINT:
82		case VK_FORMAT_B8G8R8_SRGB:
83			return 3;
84
85		case VK_FORMAT_R8G8B8A8_UNORM:
86		case VK_FORMAT_R8G8B8A8_SNORM:
87		case VK_FORMAT_R8G8B8A8_USCALED:
88		case VK_FORMAT_R8G8B8A8_SSCALED:
89		case VK_FORMAT_R8G8B8A8_UINT:
90		case VK_FORMAT_R8G8B8A8_SINT:
91		case VK_FORMAT_R8G8B8A8_SRGB:
92		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
93		case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
94		case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
95		case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
96		case VK_FORMAT_A2R10G10B10_UINT_PACK32:
97		case VK_FORMAT_A2R10G10B10_SINT_PACK32:
98		case VK_FORMAT_R16G16_UNORM:
99		case VK_FORMAT_R16G16_SNORM:
100		case VK_FORMAT_R16G16_USCALED:
101		case VK_FORMAT_R16G16_SSCALED:
102		case VK_FORMAT_R16G16_UINT:
103		case VK_FORMAT_R16G16_SINT:
104		case VK_FORMAT_R16G16_SFLOAT:
105		case VK_FORMAT_R32_UINT:
106		case VK_FORMAT_R32_SINT:
107		case VK_FORMAT_R32_SFLOAT:
108		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
109		case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
110		case VK_FORMAT_B8G8R8A8_UNORM:
111		case VK_FORMAT_B8G8R8A8_SNORM:
112		case VK_FORMAT_B8G8R8A8_USCALED:
113		case VK_FORMAT_B8G8R8A8_SSCALED:
114		case VK_FORMAT_B8G8R8A8_UINT:
115		case VK_FORMAT_B8G8R8A8_SINT:
116		case VK_FORMAT_B8G8R8A8_SRGB:
117		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
118		case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
119		case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
120		case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
121		case VK_FORMAT_A2B10G10R10_UINT_PACK32:
122		case VK_FORMAT_A2B10G10R10_SINT_PACK32:
123			return 4;
124
125		case VK_FORMAT_R16G16B16_UNORM:
126		case VK_FORMAT_R16G16B16_SNORM:
127		case VK_FORMAT_R16G16B16_USCALED:
128		case VK_FORMAT_R16G16B16_SSCALED:
129		case VK_FORMAT_R16G16B16_UINT:
130		case VK_FORMAT_R16G16B16_SINT:
131		case VK_FORMAT_R16G16B16_SFLOAT:
132			return 6;
133
134		case VK_FORMAT_R16G16B16A16_UNORM:
135		case VK_FORMAT_R16G16B16A16_SNORM:
136		case VK_FORMAT_R16G16B16A16_USCALED:
137		case VK_FORMAT_R16G16B16A16_SSCALED:
138		case VK_FORMAT_R16G16B16A16_UINT:
139		case VK_FORMAT_R16G16B16A16_SINT:
140		case VK_FORMAT_R16G16B16A16_SFLOAT:
141		case VK_FORMAT_R32G32_UINT:
142		case VK_FORMAT_R32G32_SINT:
143		case VK_FORMAT_R32G32_SFLOAT:
144		case VK_FORMAT_R64_SFLOAT:
145			return 8;
146
147		case VK_FORMAT_R32G32B32_UINT:
148		case VK_FORMAT_R32G32B32_SINT:
149		case VK_FORMAT_R32G32B32_SFLOAT:
150			return 12;
151
152		case VK_FORMAT_R32G32B32A32_UINT:
153		case VK_FORMAT_R32G32B32A32_SINT:
154		case VK_FORMAT_R32G32B32A32_SFLOAT:
155		case VK_FORMAT_R64G64_SFLOAT:
156			return 16;
157
158		case VK_FORMAT_R64G64B64_SFLOAT:
159			return 24;
160
161		case VK_FORMAT_R64G64B64A64_SFLOAT:
162			return 32;
163
164		default:
165			break;
166	}
167
168	DE_ASSERT(false);
169	return 0;
170}
171
172deUint32 getVertexFormatComponentCount (VkFormat format)
173{
174	switch (format)
175	{
176		case VK_FORMAT_R8_USCALED:
177		case VK_FORMAT_R8_UNORM:
178		case VK_FORMAT_R8_UINT:
179		case VK_FORMAT_R8_SSCALED:
180		case VK_FORMAT_R8_SRGB:
181		case VK_FORMAT_R8_SNORM:
182		case VK_FORMAT_R8_SINT:
183		case VK_FORMAT_R16_USCALED:
184		case VK_FORMAT_R16_UNORM:
185		case VK_FORMAT_R16_UINT:
186		case VK_FORMAT_R16_SSCALED:
187		case VK_FORMAT_R16_SNORM:
188		case VK_FORMAT_R16_SINT:
189		case VK_FORMAT_R16_SFLOAT:
190		case VK_FORMAT_R32_UINT:
191		case VK_FORMAT_R32_SINT:
192		case VK_FORMAT_R32_SFLOAT:
193		case VK_FORMAT_R64_SFLOAT:
194			return 1;
195
196		case VK_FORMAT_R4G4_UNORM_PACK8:
197		case VK_FORMAT_R8G8_UNORM:
198		case VK_FORMAT_R8G8_SNORM:
199		case VK_FORMAT_R8G8_USCALED:
200		case VK_FORMAT_R8G8_SSCALED:
201		case VK_FORMAT_R8G8_UINT:
202		case VK_FORMAT_R8G8_SINT:
203		case VK_FORMAT_R8G8_SRGB:
204		case VK_FORMAT_R16G16_UNORM:
205		case VK_FORMAT_R16G16_SNORM:
206		case VK_FORMAT_R16G16_USCALED:
207		case VK_FORMAT_R16G16_SSCALED:
208		case VK_FORMAT_R16G16_UINT:
209		case VK_FORMAT_R16G16_SINT:
210		case VK_FORMAT_R16G16_SFLOAT:
211		case VK_FORMAT_R32G32_UINT:
212		case VK_FORMAT_R32G32_SINT:
213		case VK_FORMAT_R32G32_SFLOAT:
214		case VK_FORMAT_R64G64_SFLOAT:
215			return 2;
216
217		case VK_FORMAT_R8G8B8_UNORM:
218		case VK_FORMAT_R8G8B8_SNORM:
219		case VK_FORMAT_R8G8B8_USCALED:
220		case VK_FORMAT_R8G8B8_SSCALED:
221		case VK_FORMAT_R8G8B8_UINT:
222		case VK_FORMAT_R8G8B8_SINT:
223		case VK_FORMAT_R8G8B8_SRGB:
224		case VK_FORMAT_B8G8R8_UNORM:
225		case VK_FORMAT_B8G8R8_SNORM:
226		case VK_FORMAT_B8G8R8_USCALED:
227		case VK_FORMAT_B8G8R8_SSCALED:
228		case VK_FORMAT_B8G8R8_UINT:
229		case VK_FORMAT_B8G8R8_SINT:
230		case VK_FORMAT_B8G8R8_SRGB:
231		case VK_FORMAT_R16G16B16_UNORM:
232		case VK_FORMAT_R16G16B16_SNORM:
233		case VK_FORMAT_R16G16B16_USCALED:
234		case VK_FORMAT_R16G16B16_SSCALED:
235		case VK_FORMAT_R16G16B16_UINT:
236		case VK_FORMAT_R16G16B16_SINT:
237		case VK_FORMAT_R16G16B16_SFLOAT:
238		case VK_FORMAT_R32G32B32_UINT:
239		case VK_FORMAT_R32G32B32_SINT:
240		case VK_FORMAT_R32G32B32_SFLOAT:
241		case VK_FORMAT_R64G64B64_SFLOAT:
242		case VK_FORMAT_R5G6B5_UNORM_PACK16:
243		case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
244		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
245			return 3;
246
247		case VK_FORMAT_R8G8B8A8_UNORM:
248		case VK_FORMAT_R8G8B8A8_SNORM:
249		case VK_FORMAT_R8G8B8A8_USCALED:
250		case VK_FORMAT_R8G8B8A8_SSCALED:
251		case VK_FORMAT_R8G8B8A8_UINT:
252		case VK_FORMAT_R8G8B8A8_SINT:
253		case VK_FORMAT_R8G8B8A8_SRGB:
254		case VK_FORMAT_B8G8R8A8_UNORM:
255		case VK_FORMAT_B8G8R8A8_SNORM:
256		case VK_FORMAT_B8G8R8A8_USCALED:
257		case VK_FORMAT_B8G8R8A8_SSCALED:
258		case VK_FORMAT_B8G8R8A8_UINT:
259		case VK_FORMAT_B8G8R8A8_SINT:
260		case VK_FORMAT_B8G8R8A8_SRGB:
261		case VK_FORMAT_R16G16B16A16_UNORM:
262		case VK_FORMAT_R16G16B16A16_SNORM:
263		case VK_FORMAT_R16G16B16A16_USCALED:
264		case VK_FORMAT_R16G16B16A16_SSCALED:
265		case VK_FORMAT_R16G16B16A16_UINT:
266		case VK_FORMAT_R16G16B16A16_SINT:
267		case VK_FORMAT_R16G16B16A16_SFLOAT:
268		case VK_FORMAT_R32G32B32A32_UINT:
269		case VK_FORMAT_R32G32B32A32_SINT:
270		case VK_FORMAT_R32G32B32A32_SFLOAT:
271		case VK_FORMAT_R64G64B64A64_SFLOAT:
272		case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
273		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
274		case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
275		case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
276		case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
277		case VK_FORMAT_A2R10G10B10_UINT_PACK32:
278		case VK_FORMAT_A2R10G10B10_SINT_PACK32:
279		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
280		case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
281		case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
282		case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
283		case VK_FORMAT_A2B10G10R10_UINT_PACK32:
284		case VK_FORMAT_A2B10G10R10_SINT_PACK32:
285			return 4;
286
287		default:
288			break;
289	}
290
291	DE_ASSERT(false);
292	return 0;
293}
294
295deUint32 getVertexFormatComponentSize (VkFormat format)
296{
297	switch (format)
298	{
299		case VK_FORMAT_R8_UNORM:
300		case VK_FORMAT_R8_SNORM:
301		case VK_FORMAT_R8_USCALED:
302		case VK_FORMAT_R8_SSCALED:
303		case VK_FORMAT_R8_UINT:
304		case VK_FORMAT_R8_SINT:
305		case VK_FORMAT_R8_SRGB:
306		case VK_FORMAT_R8G8_UNORM:
307		case VK_FORMAT_R8G8_SNORM:
308		case VK_FORMAT_R8G8_USCALED:
309		case VK_FORMAT_R8G8_SSCALED:
310		case VK_FORMAT_R8G8_UINT:
311		case VK_FORMAT_R8G8_SINT:
312		case VK_FORMAT_R8G8_SRGB:
313		case VK_FORMAT_R8G8B8_UNORM:
314		case VK_FORMAT_R8G8B8_SNORM:
315		case VK_FORMAT_R8G8B8_USCALED:
316		case VK_FORMAT_R8G8B8_SSCALED:
317		case VK_FORMAT_R8G8B8_UINT:
318		case VK_FORMAT_R8G8B8_SINT:
319		case VK_FORMAT_R8G8B8_SRGB:
320		case VK_FORMAT_B8G8R8_UNORM:
321		case VK_FORMAT_B8G8R8_SNORM:
322		case VK_FORMAT_B8G8R8_USCALED:
323		case VK_FORMAT_B8G8R8_SSCALED:
324		case VK_FORMAT_B8G8R8_UINT:
325		case VK_FORMAT_B8G8R8_SINT:
326		case VK_FORMAT_B8G8R8_SRGB:
327		case VK_FORMAT_R8G8B8A8_UNORM:
328		case VK_FORMAT_R8G8B8A8_SNORM:
329		case VK_FORMAT_R8G8B8A8_USCALED:
330		case VK_FORMAT_R8G8B8A8_SSCALED:
331		case VK_FORMAT_R8G8B8A8_UINT:
332		case VK_FORMAT_R8G8B8A8_SINT:
333		case VK_FORMAT_R8G8B8A8_SRGB:
334		case VK_FORMAT_B8G8R8A8_UNORM:
335		case VK_FORMAT_B8G8R8A8_SNORM:
336		case VK_FORMAT_B8G8R8A8_USCALED:
337		case VK_FORMAT_B8G8R8A8_SSCALED:
338		case VK_FORMAT_B8G8R8A8_UINT:
339		case VK_FORMAT_B8G8R8A8_SINT:
340		case VK_FORMAT_B8G8R8A8_SRGB:
341			return 1;
342
343		case VK_FORMAT_R16_UNORM:
344		case VK_FORMAT_R16_SNORM:
345		case VK_FORMAT_R16_USCALED:
346		case VK_FORMAT_R16_SSCALED:
347		case VK_FORMAT_R16_UINT:
348		case VK_FORMAT_R16_SINT:
349		case VK_FORMAT_R16_SFLOAT:
350		case VK_FORMAT_R16G16_UNORM:
351		case VK_FORMAT_R16G16_SNORM:
352		case VK_FORMAT_R16G16_USCALED:
353		case VK_FORMAT_R16G16_SSCALED:
354		case VK_FORMAT_R16G16_UINT:
355		case VK_FORMAT_R16G16_SINT:
356		case VK_FORMAT_R16G16_SFLOAT:
357		case VK_FORMAT_R16G16B16_UNORM:
358		case VK_FORMAT_R16G16B16_SNORM:
359		case VK_FORMAT_R16G16B16_USCALED:
360		case VK_FORMAT_R16G16B16_SSCALED:
361		case VK_FORMAT_R16G16B16_UINT:
362		case VK_FORMAT_R16G16B16_SINT:
363		case VK_FORMAT_R16G16B16_SFLOAT:
364		case VK_FORMAT_R16G16B16A16_UNORM:
365		case VK_FORMAT_R16G16B16A16_SNORM:
366		case VK_FORMAT_R16G16B16A16_USCALED:
367		case VK_FORMAT_R16G16B16A16_SSCALED:
368		case VK_FORMAT_R16G16B16A16_UINT:
369		case VK_FORMAT_R16G16B16A16_SINT:
370		case VK_FORMAT_R16G16B16A16_SFLOAT:
371			return 2;
372
373		case VK_FORMAT_R32_UINT:
374		case VK_FORMAT_R32_SINT:
375		case VK_FORMAT_R32_SFLOAT:
376		case VK_FORMAT_R32G32_UINT:
377		case VK_FORMAT_R32G32_SINT:
378		case VK_FORMAT_R32G32_SFLOAT:
379		case VK_FORMAT_R32G32B32_UINT:
380		case VK_FORMAT_R32G32B32_SINT:
381		case VK_FORMAT_R32G32B32_SFLOAT:
382		case VK_FORMAT_R32G32B32A32_UINT:
383		case VK_FORMAT_R32G32B32A32_SINT:
384		case VK_FORMAT_R32G32B32A32_SFLOAT:
385			return 4;
386
387		case VK_FORMAT_R64_SFLOAT:
388		case VK_FORMAT_R64G64_SFLOAT:
389		case VK_FORMAT_R64G64B64_SFLOAT:
390		case VK_FORMAT_R64G64B64A64_SFLOAT:
391			return 8;
392
393		default:
394			break;
395	}
396
397	DE_ASSERT(false);
398	return 0;
399}
400
401bool isVertexFormatComponentOrderBGR (VkFormat format)
402{
403	switch (format)
404	{
405		case VK_FORMAT_B8G8R8_UNORM:
406		case VK_FORMAT_B8G8R8_SNORM:
407		case VK_FORMAT_B8G8R8_USCALED:
408		case VK_FORMAT_B8G8R8_SSCALED:
409		case VK_FORMAT_B8G8R8_UINT:
410		case VK_FORMAT_B8G8R8_SINT:
411		case VK_FORMAT_B8G8R8_SRGB:
412		case VK_FORMAT_B8G8R8A8_UNORM:
413		case VK_FORMAT_B8G8R8A8_SNORM:
414		case VK_FORMAT_B8G8R8A8_USCALED:
415		case VK_FORMAT_B8G8R8A8_SSCALED:
416		case VK_FORMAT_B8G8R8A8_UINT:
417		case VK_FORMAT_B8G8R8A8_SINT:
418		case VK_FORMAT_B8G8R8A8_SRGB:
419		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
420		case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
421		case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
422		case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
423		case VK_FORMAT_A2B10G10R10_UINT_PACK32:
424		case VK_FORMAT_A2B10G10R10_SINT_PACK32:
425			return true;
426
427		default:
428			break;
429	}
430	return false;
431}
432
433bool isVertexFormatSint (VkFormat format)
434{
435	switch (format)
436	{
437		case VK_FORMAT_R8_SINT:
438		case VK_FORMAT_R8G8_SINT:
439		case VK_FORMAT_R16_SINT:
440		case VK_FORMAT_R8G8B8_SINT:
441		case VK_FORMAT_B8G8R8_SINT:
442		case VK_FORMAT_R8G8B8A8_SINT:
443		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
444		case VK_FORMAT_R16G16_SINT:
445		case VK_FORMAT_R32_SINT:
446		case VK_FORMAT_B8G8R8A8_SINT:
447		case VK_FORMAT_A2B10G10R10_SINT_PACK32:
448		case VK_FORMAT_R16G16B16_SINT:
449		case VK_FORMAT_R16G16B16A16_SINT:
450		case VK_FORMAT_R32G32_SINT:
451		case VK_FORMAT_R32G32B32_SINT:
452		case VK_FORMAT_R32G32B32A32_SINT:
453			return true;
454
455		default:
456			break;
457	}
458
459	return false;
460}
461
462bool isVertexFormatUint (VkFormat format)
463{
464	switch (format)
465	{
466		case VK_FORMAT_R8_UINT:
467		case VK_FORMAT_R8G8_UINT:
468		case VK_FORMAT_R16_UINT:
469		case VK_FORMAT_R8G8B8_UINT:
470		case VK_FORMAT_B8G8R8_UINT:
471		case VK_FORMAT_R8G8B8A8_UINT:
472		case VK_FORMAT_A2R10G10B10_UINT_PACK32:
473		case VK_FORMAT_R16G16_UINT:
474		case VK_FORMAT_R32_UINT:
475		case VK_FORMAT_B8G8R8A8_UINT:
476		case VK_FORMAT_A2B10G10R10_UINT_PACK32:
477		case VK_FORMAT_R16G16B16_UINT:
478		case VK_FORMAT_R16G16B16A16_UINT:
479		case VK_FORMAT_R32G32_UINT:
480		case VK_FORMAT_R32G32B32_UINT:
481		case VK_FORMAT_R32G32B32A32_UINT:
482			return true;
483
484		default:
485			break;
486	}
487
488	return false;
489
490}
491
492bool isVertexFormatSfloat (VkFormat format)
493{
494	switch (format)
495	{
496		case VK_FORMAT_R16_SFLOAT:
497		case VK_FORMAT_R16G16_SFLOAT:
498		case VK_FORMAT_R32_SFLOAT:
499		case VK_FORMAT_R16G16B16_SFLOAT:
500		case VK_FORMAT_R16G16B16A16_SFLOAT:
501		case VK_FORMAT_R32G32_SFLOAT:
502		case VK_FORMAT_R64_SFLOAT:
503		case VK_FORMAT_R32G32B32_SFLOAT:
504		case VK_FORMAT_R32G32B32A32_SFLOAT:
505		case VK_FORMAT_R64G64_SFLOAT:
506		case VK_FORMAT_R64G64B64_SFLOAT:
507		case VK_FORMAT_R64G64B64A64_SFLOAT:
508			return true;
509
510		default:
511			break;
512	}
513
514	return false;
515
516}
517
518bool isVertexFormatUfloat (VkFormat format)
519{
520	switch (format)
521	{
522		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
523		case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
524			return true;
525
526		default:
527			break;
528	}
529
530	return false;
531
532}
533
534bool isVertexFormatUnorm (VkFormat format)
535{
536	switch (format)
537	{
538		case VK_FORMAT_R8_UNORM:
539		case VK_FORMAT_R4G4_UNORM_PACK8:
540		case VK_FORMAT_R8G8_UNORM:
541		case VK_FORMAT_R16_UNORM:
542		case VK_FORMAT_R5G6B5_UNORM_PACK16:
543		case VK_FORMAT_R5G5B5A1_UNORM_PACK16:
544		case VK_FORMAT_R8G8B8_UNORM:
545		case VK_FORMAT_B8G8R8_UNORM:
546		case VK_FORMAT_R8G8B8A8_UNORM:
547		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
548		case VK_FORMAT_R16G16_UNORM:
549		case VK_FORMAT_B8G8R8A8_UNORM:
550		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
551		case VK_FORMAT_R16G16B16_UNORM:
552		case VK_FORMAT_R16G16B16A16_UNORM:
553			return true;
554
555		default:
556			break;
557	}
558
559	return false;
560
561}
562
563bool isVertexFormatSnorm (VkFormat format)
564{
565	switch (format)
566	{
567		case VK_FORMAT_R8_SNORM:
568		case VK_FORMAT_R8G8_SNORM:
569		case VK_FORMAT_R16_SNORM:
570		case VK_FORMAT_R8G8B8_SNORM:
571		case VK_FORMAT_B8G8R8_SNORM:
572		case VK_FORMAT_R8G8B8A8_SNORM:
573		case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
574		case VK_FORMAT_R16G16_SNORM:
575		case VK_FORMAT_B8G8R8A8_SNORM:
576		case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
577		case VK_FORMAT_R16G16B16_SNORM:
578		case VK_FORMAT_R16G16B16A16_SNORM:
579			return true;
580
581		default:
582			break;
583	}
584
585	return false;
586
587}
588
589bool isVertexFormatSRGB (VkFormat format)
590{
591	switch (format)
592	{
593		case VK_FORMAT_R8_SRGB:
594		case VK_FORMAT_R8G8_SRGB:
595		case VK_FORMAT_R8G8B8_SRGB:
596		case VK_FORMAT_B8G8R8_SRGB:
597		case VK_FORMAT_R8G8B8A8_SRGB:
598		case VK_FORMAT_B8G8R8A8_SRGB:
599			return true;
600
601		default:
602			break;
603	}
604
605	return false;
606
607}
608
609bool isVertexFormatSscaled (VkFormat format)
610{
611	switch (format)
612	{
613		case VK_FORMAT_R8_SSCALED:
614		case VK_FORMAT_R8G8_SSCALED:
615		case VK_FORMAT_R16_SSCALED:
616		case VK_FORMAT_R8G8B8_SSCALED:
617		case VK_FORMAT_B8G8R8_SSCALED:
618		case VK_FORMAT_R8G8B8A8_SSCALED:
619		case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
620		case VK_FORMAT_R16G16_SSCALED:
621		case VK_FORMAT_B8G8R8A8_SSCALED:
622		case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
623		case VK_FORMAT_R16G16B16_SSCALED:
624		case VK_FORMAT_R16G16B16A16_SSCALED:
625			return true;
626
627		default:
628			break;
629	}
630
631	return false;
632
633}
634
635bool isVertexFormatUscaled (VkFormat format)
636{
637	switch (format)
638	{
639		case VK_FORMAT_R8_USCALED:
640		case VK_FORMAT_R8G8_USCALED:
641		case VK_FORMAT_R16_USCALED:
642		case VK_FORMAT_A1R5G5B5_UNORM_PACK16:
643		case VK_FORMAT_R8G8B8_USCALED:
644		case VK_FORMAT_B8G8R8_USCALED:
645		case VK_FORMAT_R8G8B8A8_USCALED:
646		case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
647		case VK_FORMAT_R16G16_USCALED:
648		case VK_FORMAT_B8G8R8A8_USCALED:
649		case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
650		case VK_FORMAT_R16G16B16_USCALED:
651		case VK_FORMAT_R16G16B16A16_USCALED:
652			return true;
653
654		default:
655			break;
656	}
657
658	return false;
659
660}
661
662bool isVertexFormatDouble (VkFormat format)
663{
664	switch (format)
665	{
666		case VK_FORMAT_R64_UINT:
667		case VK_FORMAT_R64_SINT:
668		case VK_FORMAT_R64_SFLOAT:
669		case VK_FORMAT_R64G64_UINT:
670		case VK_FORMAT_R64G64_SINT:
671		case VK_FORMAT_R64G64_SFLOAT:
672		case VK_FORMAT_R64G64B64_UINT:
673		case VK_FORMAT_R64G64B64_SINT:
674		case VK_FORMAT_R64G64B64_SFLOAT:
675		case VK_FORMAT_R64G64B64A64_UINT:
676		case VK_FORMAT_R64G64B64A64_SINT:
677		case VK_FORMAT_R64G64B64A64_SFLOAT:
678			return true;
679
680		default:
681			break;
682	}
683	return false;
684}
685
686std::vector<Vertex4RGBA> createOverlappingQuads (void)
687{
688	using tcu::Vec2;
689	using tcu::Vec4;
690
691	std::vector<Vertex4RGBA> vertices;
692
693	const Vec2 translations[4] =
694	{
695		Vec2(-0.25f, -0.25f),
696		Vec2(-1.0f, -0.25f),
697		Vec2(-1.0f, -1.0f),
698		Vec2(-0.25f, -1.0f)
699	};
700
701	const Vec4 quadColors[4] =
702	{
703		Vec4(1.0f, 0.0f, 0.0f, 1.0),
704		Vec4(0.0f, 1.0f, 0.0f, 1.0),
705		Vec4(0.0f, 0.0f, 1.0f, 1.0),
706		Vec4(1.0f, 0.0f, 1.0f, 1.0)
707	};
708
709	const float quadSize = 1.25f;
710
711	for (int quadNdx = 0; quadNdx < 4; quadNdx++)
712	{
713		const Vec2&	translation	= translations[quadNdx];
714		const Vec4&	color		= quadColors[quadNdx];
715
716		const Vertex4RGBA lowerLeftVertex =
717		{
718			Vec4(translation.x(), translation.y(), 0.0f, 1.0f),
719			color
720		};
721		const Vertex4RGBA upperLeftVertex =
722		{
723			Vec4(translation.x(), translation.y() + quadSize, 0.0f, 1.0f),
724			color
725		};
726		const Vertex4RGBA lowerRightVertex =
727		{
728			Vec4(translation.x() + quadSize, translation.y(), 0.0f, 1.0f),
729			color
730		};
731		const Vertex4RGBA upperRightVertex =
732		{
733			Vec4(translation.x() + quadSize, translation.y() + quadSize, 0.0f, 1.0f),
734			color
735		};
736
737		// Triangle 1, CCW
738		vertices.push_back(lowerLeftVertex);
739		vertices.push_back(lowerRightVertex);
740		vertices.push_back(upperLeftVertex);
741
742		// Triangle 2, CW
743		vertices.push_back(lowerRightVertex);
744		vertices.push_back(upperLeftVertex);
745		vertices.push_back(upperRightVertex);
746	}
747
748	return vertices;
749}
750
751std::vector<Vertex4Tex4> createFullscreenQuad (void)
752{
753	using tcu::Vec4;
754
755	const Vertex4Tex4 lowerLeftVertex =
756	{
757		Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
758		Vec4(0.0f, 0.0f, 0.0f, 0.0f)
759	};
760	const Vertex4Tex4 upperLeftVertex =
761	{
762		Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
763		Vec4(0.0f, 1.0f, 0.0f, 0.0f)
764	};
765	const Vertex4Tex4 lowerRightVertex =
766	{
767		Vec4(1.0f, -1.0f, 0.0f, 1.0f),
768		Vec4(1.0f, 0.0f, 0.0f, 0.0f)
769	};
770	const Vertex4Tex4 upperRightVertex =
771	{
772		Vec4(1.0f, 1.0f, 0.0f, 1.0f),
773		Vec4(1.0f, 1.0f, 0.0f, 0.0f)
774	};
775
776	const Vertex4Tex4 vertices[6] =
777	{
778		lowerLeftVertex,
779		lowerRightVertex,
780		upperLeftVertex,
781
782		upperLeftVertex,
783		lowerRightVertex,
784		upperRightVertex
785	};
786
787	return std::vector<Vertex4Tex4>(vertices, vertices + DE_LENGTH_OF_ARRAY(vertices));
788}
789
790std::vector<Vertex4Tex4> createQuadMosaic (int rows, int columns)
791{
792	using tcu::Vec4;
793
794	DE_ASSERT(rows >= 1);
795	DE_ASSERT(columns >= 1);
796
797	std::vector<Vertex4Tex4>	vertices;
798	const float					rowSize		= 2.0f / (float)rows;
799	const float					columnSize	= 2.0f / (float)columns;
800	int							arrayIndex	= 0;
801
802	for (int rowNdx = 0; rowNdx < rows; rowNdx++)
803	{
804		for (int columnNdx = 0; columnNdx < columns; columnNdx++)
805		{
806			const Vertex4Tex4 lowerLeftVertex =
807			{
808				Vec4(-1.0f + (float)columnNdx * columnSize, -1.0f + (float)rowNdx * rowSize, 0.0f, 1.0f),
809				Vec4(0.0f, 0.0f, (float)arrayIndex, 0.0f)
810			};
811			const Vertex4Tex4 upperLeftVertex =
812			{
813				Vec4(lowerLeftVertex.position.x(), lowerLeftVertex.position.y() + rowSize, 0.0f, 1.0f),
814				Vec4(0.0f, 1.0f, (float)arrayIndex, 0.0f)
815			};
816			const Vertex4Tex4 lowerRightVertex =
817			{
818				Vec4(lowerLeftVertex.position.x() + columnSize, lowerLeftVertex.position.y(), 0.0f, 1.0f),
819				Vec4(1.0f, 0.0f, (float)arrayIndex, 0.0f)
820			};
821			const Vertex4Tex4 upperRightVertex =
822			{
823				Vec4(lowerLeftVertex.position.x() + columnSize, lowerLeftVertex.position.y() + rowSize, 0.0f, 1.0f),
824				Vec4(1.0f, 1.0f, (float)arrayIndex, 0.0f)
825			};
826
827			vertices.push_back(lowerLeftVertex);
828			vertices.push_back(lowerRightVertex);
829			vertices.push_back(upperLeftVertex);
830			vertices.push_back(upperLeftVertex);
831			vertices.push_back(lowerRightVertex);
832			vertices.push_back(upperRightVertex);
833
834			arrayIndex++;
835		}
836	}
837
838	return vertices;
839}
840
841std::vector<Vertex4Tex4> createQuadMosaicCube (void)
842{
843	using tcu::Vec3;
844
845	static const Vec3 texCoordsCube[8] =
846	{
847		Vec3(-1.0f, -1.0f, -1.0f),	// 0: -X, -Y, -Z
848		Vec3(1.0f, -1.0f, -1.0f),	// 1:  X, -Y, -Z
849		Vec3(1.0f, -1.0f, 1.0f),	// 2:  X, -Y,  Z
850		Vec3(-1.0f, -1.0f, 1.0f),	// 3: -X, -Y,  Z
851
852		Vec3(-1.0f, 1.0f, -1.0f),	// 4: -X,  Y, -Z
853		Vec3(1.0f, 1.0f, -1.0f),	// 5:  X,  Y, -Z
854		Vec3(1.0f, 1.0f, 1.0f),		// 6:  X,  Y,  Z
855		Vec3(-1.0f, 1.0f, 1.0f),	// 7: -X,  Y,  Z
856	};
857
858	static const int texCoordCubeIndices[6][6] =
859	{
860		{ 6, 5, 2, 2, 5, 1 },		// +X face
861		{ 3, 0, 7, 7, 0, 4 },		// -X face
862		{ 4, 5, 7, 7, 5, 6 },		// +Y face
863		{ 3, 2, 0, 0, 2, 1 },		// -Y face
864		{ 2, 3, 6, 6, 3, 7 },		// +Z face
865		{ 0, 1, 4, 4, 1, 5 }		// -Z face
866	};
867
868	// Create 6 quads and set appropriate texture coordinates for cube mapping
869
870	std::vector<Vertex4Tex4>			vertices	= createQuadMosaic(2, 3);
871	std::vector<Vertex4Tex4>::iterator	vertexItr	= vertices.begin();
872
873	for (int quadNdx = 0; quadNdx < 6; quadNdx++)
874	{
875		for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
876		{
877			vertexItr->texCoord.xyz() = texCoordsCube[texCoordCubeIndices[quadNdx][vertexNdx]];
878			vertexItr++;
879		}
880	}
881
882	return vertices;
883}
884
885std::vector<Vertex4Tex4> createQuadMosaicCubeArray (int faceArrayIndices[6])
886{
887	std::vector<Vertex4Tex4>			vertices	= createQuadMosaicCube();
888	std::vector<Vertex4Tex4>::iterator	vertexItr	= vertices.begin();
889
890	for (int quadNdx = 0; quadNdx < 6; quadNdx++)
891	{
892		for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
893		{
894			vertexItr->texCoord.w() = (float)faceArrayIndices[quadNdx];
895			vertexItr++;
896		}
897	}
898
899	return vertices;
900}
901
902std::vector<Vertex4Tex4> createTestQuadMosaic (vk::VkImageViewType viewType)
903{
904	std::vector<Vertex4Tex4> vertices;
905
906	switch (viewType)
907	{
908		case vk::VK_IMAGE_VIEW_TYPE_1D:
909		case vk::VK_IMAGE_VIEW_TYPE_2D:
910			vertices = createFullscreenQuad();
911			break;
912
913		case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
914			vertices = createQuadMosaic(2, 3);
915
916			// Set up array indices
917			for (size_t quadNdx = 0; quadNdx < 6; quadNdx++)
918				for (size_t vertexNdx = 0; vertexNdx < 6; vertexNdx++)
919					vertices[quadNdx * 6 + vertexNdx].texCoord.y() = (float)quadNdx;
920
921			break;
922
923		case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
924			vertices = createQuadMosaic(2, 3);
925			break;
926
927		case vk::VK_IMAGE_VIEW_TYPE_3D:
928			vertices = createQuadMosaic(2, 3);
929
930			// Use z between 0.0 and 1.0.
931			for (size_t vertexNdx = 0; vertexNdx < vertices.size(); vertexNdx++)
932			{
933				vertices[vertexNdx].texCoord.z() /= 5.0f;
934				vertices[vertexNdx].texCoord.z() -= 0.001f; // Substract small value to correct floating-point errors at the boundaries between slices
935			}
936
937			break;
938
939		case vk::VK_IMAGE_VIEW_TYPE_CUBE:
940			vertices = createQuadMosaicCube();
941			break;
942
943		case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
944			{
945				int faceArrayIndices[6] = { 0, 1, 2, 3, 4, 5 };
946				vertices = createQuadMosaicCubeArray(faceArrayIndices);
947			}
948			break;
949
950		default:
951			DE_ASSERT(false);
952			break;
953	}
954
955	return vertices;
956}
957
958} // pipeline
959} // vkt
960