1/*-------------------------------------------------------------------------
2 * Vulkan CTS Framework
3 * --------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
7 * Copyright (c) 2015 Google Inc.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Utilities for images.
24 *//*--------------------------------------------------------------------*/
25
26#include "vkImageUtil.hpp"
27#include "tcuTextureUtil.hpp"
28
29namespace vk
30{
31
32bool isFloatFormat (VkFormat format)
33{
34	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
35}
36
37bool isUnormFormat (VkFormat format)
38{
39	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT;
40}
41
42bool isSnormFormat (VkFormat format)
43{
44	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
45}
46
47bool isIntFormat (VkFormat format)
48{
49	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER;
50}
51
52bool isUintFormat (VkFormat format)
53{
54	return tcu::getTextureChannelClass(mapVkFormat(format).type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
55}
56
57bool isDepthStencilFormat (VkFormat format)
58{
59	if (isCompressedFormat(format))
60		return false;
61
62	const tcu::TextureFormat tcuFormat = mapVkFormat(format);
63	return tcuFormat.order == tcu::TextureFormat::D || tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS;
64}
65
66bool isCompressedFormat (VkFormat format)
67{
68	// update this mapping if VkFormat changes
69	DE_STATIC_ASSERT(VK_FORMAT_LAST == 185);
70
71	switch (format)
72	{
73		case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
74		case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
75		case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
76		case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
77		case VK_FORMAT_BC2_UNORM_BLOCK:
78		case VK_FORMAT_BC2_SRGB_BLOCK:
79		case VK_FORMAT_BC3_UNORM_BLOCK:
80		case VK_FORMAT_BC3_SRGB_BLOCK:
81		case VK_FORMAT_BC4_UNORM_BLOCK:
82		case VK_FORMAT_BC4_SNORM_BLOCK:
83		case VK_FORMAT_BC5_UNORM_BLOCK:
84		case VK_FORMAT_BC5_SNORM_BLOCK:
85		case VK_FORMAT_BC6H_UFLOAT_BLOCK:
86		case VK_FORMAT_BC6H_SFLOAT_BLOCK:
87		case VK_FORMAT_BC7_UNORM_BLOCK:
88		case VK_FORMAT_BC7_SRGB_BLOCK:
89		case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
90		case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
91		case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
92		case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
93		case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
94		case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
95		case VK_FORMAT_EAC_R11_UNORM_BLOCK:
96		case VK_FORMAT_EAC_R11_SNORM_BLOCK:
97		case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
98		case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
99		case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
100		case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
101		case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
102		case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
103		case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
104		case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
105		case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
106		case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
107		case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
108		case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
109		case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
110		case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
111		case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
112		case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
113		case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
114		case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
115		case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
116		case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
117		case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
118		case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
119		case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
120		case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
121		case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
122		case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
123		case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
124		case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
125		case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
126		case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
127			return true;
128
129		default:
130			return false;
131	}
132}
133
134VkFormat mapTextureFormat (const tcu::TextureFormat& format)
135{
136	DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELORDER_LAST < (1<<16));
137	DE_STATIC_ASSERT(tcu::TextureFormat::CHANNELTYPE_LAST < (1<<16));
138
139#define PACK_FMT(ORDER, TYPE) ((int(ORDER) << 16) | int(TYPE))
140#define FMT_CASE(ORDER, TYPE) PACK_FMT(tcu::TextureFormat::ORDER, tcu::TextureFormat::TYPE)
141
142	// update this mapping if VkFormat changes
143	DE_STATIC_ASSERT(VK_FORMAT_LAST == 185);
144
145	switch (PACK_FMT(format.order, format.type))
146	{
147		case FMT_CASE(RG, UNORM_BYTE_44):					return VK_FORMAT_R4G4_UNORM_PACK8;
148		case FMT_CASE(RGB, UNORM_SHORT_565):				return VK_FORMAT_R5G6B5_UNORM_PACK16;
149		case FMT_CASE(RGBA, UNORM_SHORT_4444):				return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
150		case FMT_CASE(RGBA, UNORM_SHORT_5551):				return VK_FORMAT_R5G5B5A1_UNORM_PACK16;
151
152		case FMT_CASE(BGR, UNORM_SHORT_565):				return VK_FORMAT_B5G6R5_UNORM_PACK16;
153		case FMT_CASE(BGRA, UNORM_SHORT_4444):				return VK_FORMAT_B4G4R4A4_UNORM_PACK16;
154		case FMT_CASE(BGRA, UNORM_SHORT_5551):				return VK_FORMAT_B5G5R5A1_UNORM_PACK16;
155
156		case FMT_CASE(ARGB, UNORM_SHORT_1555):				return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
157
158		case FMT_CASE(R, UNORM_INT8):						return VK_FORMAT_R8_UNORM;
159		case FMT_CASE(R, SNORM_INT8):						return VK_FORMAT_R8_SNORM;
160		case FMT_CASE(R, UNSIGNED_INT8):					return VK_FORMAT_R8_UINT;
161		case FMT_CASE(R, SIGNED_INT8):						return VK_FORMAT_R8_SINT;
162		case FMT_CASE(sR, UNORM_INT8):						return VK_FORMAT_R8_SRGB;
163
164		case FMT_CASE(RG, UNORM_INT8):						return VK_FORMAT_R8G8_UNORM;
165		case FMT_CASE(RG, SNORM_INT8):						return VK_FORMAT_R8G8_SNORM;
166		case FMT_CASE(RG, UNSIGNED_INT8):					return VK_FORMAT_R8G8_UINT;
167		case FMT_CASE(RG, SIGNED_INT8):						return VK_FORMAT_R8G8_SINT;
168		case FMT_CASE(sRG, UNORM_INT8):						return VK_FORMAT_R8G8_SRGB;
169
170		case FMT_CASE(RGB, UNORM_INT8):						return VK_FORMAT_R8G8B8_UNORM;
171		case FMT_CASE(RGB, SNORM_INT8):						return VK_FORMAT_R8G8B8_SNORM;
172		case FMT_CASE(RGB, UNSIGNED_INT8):					return VK_FORMAT_R8G8B8_UINT;
173		case FMT_CASE(RGB, SIGNED_INT8):					return VK_FORMAT_R8G8B8_SINT;
174		case FMT_CASE(sRGB, UNORM_INT8):					return VK_FORMAT_R8G8B8_SRGB;
175
176		case FMT_CASE(RGBA, UNORM_INT8):					return VK_FORMAT_R8G8B8A8_UNORM;
177		case FMT_CASE(RGBA, SNORM_INT8):					return VK_FORMAT_R8G8B8A8_SNORM;
178		case FMT_CASE(RGBA, UNSIGNED_INT8):					return VK_FORMAT_R8G8B8A8_UINT;
179		case FMT_CASE(RGBA, SIGNED_INT8):					return VK_FORMAT_R8G8B8A8_SINT;
180		case FMT_CASE(sRGBA, UNORM_INT8):					return VK_FORMAT_R8G8B8A8_SRGB;
181
182		case FMT_CASE(RGBA, UNORM_INT_1010102_REV):			return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
183		case FMT_CASE(RGBA, SNORM_INT_1010102_REV):			return VK_FORMAT_A2B10G10R10_SNORM_PACK32;
184		case FMT_CASE(RGBA, UNSIGNED_INT_1010102_REV):		return VK_FORMAT_A2B10G10R10_UINT_PACK32;
185		case FMT_CASE(RGBA, SIGNED_INT_1010102_REV):		return VK_FORMAT_A2B10G10R10_SINT_PACK32;
186
187		case FMT_CASE(R, UNORM_INT16):						return VK_FORMAT_R16_UNORM;
188		case FMT_CASE(R, SNORM_INT16):						return VK_FORMAT_R16_SNORM;
189		case FMT_CASE(R, UNSIGNED_INT16):					return VK_FORMAT_R16_UINT;
190		case FMT_CASE(R, SIGNED_INT16):						return VK_FORMAT_R16_SINT;
191		case FMT_CASE(R, HALF_FLOAT):						return VK_FORMAT_R16_SFLOAT;
192
193		case FMT_CASE(RG, UNORM_INT16):						return VK_FORMAT_R16G16_UNORM;
194		case FMT_CASE(RG, SNORM_INT16):						return VK_FORMAT_R16G16_SNORM;
195		case FMT_CASE(RG, UNSIGNED_INT16):					return VK_FORMAT_R16G16_UINT;
196		case FMT_CASE(RG, SIGNED_INT16):					return VK_FORMAT_R16G16_SINT;
197		case FMT_CASE(RG, HALF_FLOAT):						return VK_FORMAT_R16G16_SFLOAT;
198
199		case FMT_CASE(RGB, UNORM_INT16):					return VK_FORMAT_R16G16B16_UNORM;
200		case FMT_CASE(RGB, SNORM_INT16):					return VK_FORMAT_R16G16B16_SNORM;
201		case FMT_CASE(RGB, UNSIGNED_INT16):					return VK_FORMAT_R16G16B16_UINT;
202		case FMT_CASE(RGB, SIGNED_INT16):					return VK_FORMAT_R16G16B16_SINT;
203		case FMT_CASE(RGB, HALF_FLOAT):						return VK_FORMAT_R16G16B16_SFLOAT;
204
205		case FMT_CASE(RGBA, UNORM_INT16):					return VK_FORMAT_R16G16B16A16_UNORM;
206		case FMT_CASE(RGBA, SNORM_INT16):					return VK_FORMAT_R16G16B16A16_SNORM;
207		case FMT_CASE(RGBA, UNSIGNED_INT16):				return VK_FORMAT_R16G16B16A16_UINT;
208		case FMT_CASE(RGBA, SIGNED_INT16):					return VK_FORMAT_R16G16B16A16_SINT;
209		case FMT_CASE(RGBA, HALF_FLOAT):					return VK_FORMAT_R16G16B16A16_SFLOAT;
210
211		case FMT_CASE(R, UNSIGNED_INT32):					return VK_FORMAT_R32_UINT;
212		case FMT_CASE(R, SIGNED_INT32):						return VK_FORMAT_R32_SINT;
213		case FMT_CASE(R, FLOAT):							return VK_FORMAT_R32_SFLOAT;
214
215		case FMT_CASE(RG, UNSIGNED_INT32):					return VK_FORMAT_R32G32_UINT;
216		case FMT_CASE(RG, SIGNED_INT32):					return VK_FORMAT_R32G32_SINT;
217		case FMT_CASE(RG, FLOAT):							return VK_FORMAT_R32G32_SFLOAT;
218
219		case FMT_CASE(RGB, UNSIGNED_INT32):					return VK_FORMAT_R32G32B32_UINT;
220		case FMT_CASE(RGB, SIGNED_INT32):					return VK_FORMAT_R32G32B32_SINT;
221		case FMT_CASE(RGB, FLOAT):							return VK_FORMAT_R32G32B32_SFLOAT;
222
223		case FMT_CASE(RGBA, UNSIGNED_INT32):				return VK_FORMAT_R32G32B32A32_UINT;
224		case FMT_CASE(RGBA, SIGNED_INT32):					return VK_FORMAT_R32G32B32A32_SINT;
225		case FMT_CASE(RGBA, FLOAT):							return VK_FORMAT_R32G32B32A32_SFLOAT;
226
227		case FMT_CASE(R, FLOAT64):							return VK_FORMAT_R64_SFLOAT;
228		case FMT_CASE(RG, FLOAT64):							return VK_FORMAT_R64G64_SFLOAT;
229		case FMT_CASE(RGB, FLOAT64):						return VK_FORMAT_R64G64B64_SFLOAT;
230		case FMT_CASE(RGBA, FLOAT64):						return VK_FORMAT_R64G64B64A64_SFLOAT;
231
232		case FMT_CASE(RGB, UNSIGNED_INT_11F_11F_10F_REV):	return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
233		case FMT_CASE(RGB, UNSIGNED_INT_999_E5_REV):		return VK_FORMAT_E5B9G9R9_UFLOAT_PACK32;
234
235		case FMT_CASE(BGR, UNORM_INT8):						return VK_FORMAT_B8G8R8_UNORM;
236		case FMT_CASE(BGR, SNORM_INT8):						return VK_FORMAT_B8G8R8_SNORM;
237		case FMT_CASE(BGR, UNSIGNED_INT8):					return VK_FORMAT_B8G8R8_UINT;
238		case FMT_CASE(BGR, SIGNED_INT8):					return VK_FORMAT_B8G8R8_SINT;
239		case FMT_CASE(sBGR, UNORM_INT8):					return VK_FORMAT_B8G8R8_SRGB;
240
241		case FMT_CASE(BGRA, UNORM_INT8):					return VK_FORMAT_B8G8R8A8_UNORM;
242		case FMT_CASE(BGRA, SNORM_INT8):					return VK_FORMAT_B8G8R8A8_SNORM;
243		case FMT_CASE(BGRA, UNSIGNED_INT8):					return VK_FORMAT_B8G8R8A8_UINT;
244		case FMT_CASE(BGRA, SIGNED_INT8):					return VK_FORMAT_B8G8R8A8_SINT;
245		case FMT_CASE(sBGRA, UNORM_INT8):					return VK_FORMAT_B8G8R8A8_SRGB;
246
247		case FMT_CASE(BGRA, UNORM_INT_1010102_REV):			return VK_FORMAT_A2R10G10B10_UNORM_PACK32;
248		case FMT_CASE(BGRA, SNORM_INT_1010102_REV):			return VK_FORMAT_A2R10G10B10_SNORM_PACK32;
249		case FMT_CASE(BGRA, UNSIGNED_INT_1010102_REV):		return VK_FORMAT_A2R10G10B10_UINT_PACK32;
250		case FMT_CASE(BGRA, SIGNED_INT_1010102_REV):		return VK_FORMAT_A2R10G10B10_SINT_PACK32;
251
252		case FMT_CASE(D, UNORM_INT16):						return VK_FORMAT_D16_UNORM;
253		case FMT_CASE(D, UNSIGNED_INT_24_8_REV):			return VK_FORMAT_X8_D24_UNORM_PACK32;
254		case FMT_CASE(D, FLOAT):							return VK_FORMAT_D32_SFLOAT;
255
256		case FMT_CASE(S, UNSIGNED_INT8):					return VK_FORMAT_S8_UINT;
257
258		case FMT_CASE(DS, UNSIGNED_INT_16_8_8):				return VK_FORMAT_D16_UNORM_S8_UINT;
259		case FMT_CASE(DS, UNSIGNED_INT_24_8_REV):			return VK_FORMAT_D24_UNORM_S8_UINT;
260		case FMT_CASE(DS, FLOAT_UNSIGNED_INT_24_8_REV):		return VK_FORMAT_D32_SFLOAT_S8_UINT;
261
262		default:
263			TCU_THROW(InternalError, "Unknown texture format");
264	}
265
266#undef PACK_FMT
267#undef FMT_CASE
268}
269
270tcu::TextureFormat mapVkFormat (VkFormat format)
271{
272	using tcu::TextureFormat;
273
274	// update this mapping if VkFormat changes
275	DE_STATIC_ASSERT(VK_FORMAT_LAST == 185);
276
277	switch (format)
278	{
279		case VK_FORMAT_R4G4_UNORM_PACK8:		return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_BYTE_44);
280		case VK_FORMAT_R5G6B5_UNORM_PACK16:		return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_SHORT_565);
281		case VK_FORMAT_R4G4B4A4_UNORM_PACK16:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_SHORT_4444);
282		case VK_FORMAT_R5G5B5A1_UNORM_PACK16:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_SHORT_5551);
283
284		case VK_FORMAT_B5G6R5_UNORM_PACK16:		return TextureFormat(TextureFormat::BGR,	TextureFormat::UNORM_SHORT_565);
285		case VK_FORMAT_B4G4R4A4_UNORM_PACK16:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNORM_SHORT_4444);
286		case VK_FORMAT_B5G5R5A1_UNORM_PACK16:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNORM_SHORT_5551);
287
288		case VK_FORMAT_A1R5G5B5_UNORM_PACK16:	return TextureFormat(TextureFormat::ARGB,	TextureFormat::UNORM_SHORT_1555);
289
290		case VK_FORMAT_R8_UNORM:				return TextureFormat(TextureFormat::R,		TextureFormat::UNORM_INT8);
291		case VK_FORMAT_R8_SNORM:				return TextureFormat(TextureFormat::R,		TextureFormat::SNORM_INT8);
292		case VK_FORMAT_R8_USCALED:				return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT8);
293		case VK_FORMAT_R8_SSCALED:				return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT8);
294		case VK_FORMAT_R8_UINT:					return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT8);
295		case VK_FORMAT_R8_SINT:					return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT8);
296		case VK_FORMAT_R8_SRGB:					return TextureFormat(TextureFormat::sR,		TextureFormat::UNORM_INT8);
297
298		case VK_FORMAT_R8G8_UNORM:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_INT8);
299		case VK_FORMAT_R8G8_SNORM:				return TextureFormat(TextureFormat::RG,		TextureFormat::SNORM_INT8);
300		case VK_FORMAT_R8G8_USCALED:			return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT8);
301		case VK_FORMAT_R8G8_SSCALED:			return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT8);
302		case VK_FORMAT_R8G8_UINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT8);
303		case VK_FORMAT_R8G8_SINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT8);
304		case VK_FORMAT_R8G8_SRGB:				return TextureFormat(TextureFormat::sRG,	TextureFormat::UNORM_INT8);
305
306		case VK_FORMAT_R8G8B8_UNORM:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT8);
307		case VK_FORMAT_R8G8B8_SNORM:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SNORM_INT8);
308		case VK_FORMAT_R8G8B8_USCALED:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT8);
309		case VK_FORMAT_R8G8B8_SSCALED:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT8);
310		case VK_FORMAT_R8G8B8_UINT:				return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT8);
311		case VK_FORMAT_R8G8B8_SINT:				return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT8);
312		case VK_FORMAT_R8G8B8_SRGB:				return TextureFormat(TextureFormat::sRGB,	TextureFormat::UNORM_INT8);
313
314		case VK_FORMAT_R8G8B8A8_UNORM:			return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
315		case VK_FORMAT_R8G8B8A8_SNORM:			return TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT8);
316		case VK_FORMAT_R8G8B8A8_USCALED:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT8);
317		case VK_FORMAT_R8G8B8A8_SSCALED:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT8);
318		case VK_FORMAT_R8G8B8A8_UINT:			return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT8);
319		case VK_FORMAT_R8G8B8A8_SINT:			return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT8);
320		case VK_FORMAT_R8G8B8A8_SRGB:			return TextureFormat(TextureFormat::sRGBA,	TextureFormat::UNORM_INT8);
321
322		case VK_FORMAT_R16_UNORM:				return TextureFormat(TextureFormat::R,		TextureFormat::UNORM_INT16);
323		case VK_FORMAT_R16_SNORM:				return TextureFormat(TextureFormat::R,		TextureFormat::SNORM_INT16);
324		case VK_FORMAT_R16_USCALED:				return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT16);
325		case VK_FORMAT_R16_SSCALED:				return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT16);
326		case VK_FORMAT_R16_UINT:				return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT16);
327		case VK_FORMAT_R16_SINT:				return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT16);
328		case VK_FORMAT_R16_SFLOAT:				return TextureFormat(TextureFormat::R,		TextureFormat::HALF_FLOAT);
329
330		case VK_FORMAT_R16G16_UNORM:			return TextureFormat(TextureFormat::RG,		TextureFormat::UNORM_INT16);
331		case VK_FORMAT_R16G16_SNORM:			return TextureFormat(TextureFormat::RG,		TextureFormat::SNORM_INT16);
332		case VK_FORMAT_R16G16_USCALED:			return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT16);
333		case VK_FORMAT_R16G16_SSCALED:			return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT16);
334		case VK_FORMAT_R16G16_UINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT16);
335		case VK_FORMAT_R16G16_SINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT16);
336		case VK_FORMAT_R16G16_SFLOAT:			return TextureFormat(TextureFormat::RG,		TextureFormat::HALF_FLOAT);
337
338		case VK_FORMAT_R16G16B16_UNORM:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT16);
339		case VK_FORMAT_R16G16B16_SNORM:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SNORM_INT16);
340		case VK_FORMAT_R16G16B16_USCALED:		return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT16);
341		case VK_FORMAT_R16G16B16_SSCALED:		return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT16);
342		case VK_FORMAT_R16G16B16_UINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT16);
343		case VK_FORMAT_R16G16B16_SINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT16);
344		case VK_FORMAT_R16G16B16_SFLOAT:		return TextureFormat(TextureFormat::RGB,	TextureFormat::HALF_FLOAT);
345
346		case VK_FORMAT_R16G16B16A16_UNORM:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT16);
347		case VK_FORMAT_R16G16B16A16_SNORM:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT16);
348		case VK_FORMAT_R16G16B16A16_USCALED:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT16);
349		case VK_FORMAT_R16G16B16A16_SSCALED:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT16);
350		case VK_FORMAT_R16G16B16A16_UINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT16);
351		case VK_FORMAT_R16G16B16A16_SINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT16);
352		case VK_FORMAT_R16G16B16A16_SFLOAT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::HALF_FLOAT);
353
354		case VK_FORMAT_R32_UINT:				return TextureFormat(TextureFormat::R,		TextureFormat::UNSIGNED_INT32);
355		case VK_FORMAT_R32_SINT:				return TextureFormat(TextureFormat::R,		TextureFormat::SIGNED_INT32);
356		case VK_FORMAT_R32_SFLOAT:				return TextureFormat(TextureFormat::R,		TextureFormat::FLOAT);
357
358		case VK_FORMAT_R32G32_UINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::UNSIGNED_INT32);
359		case VK_FORMAT_R32G32_SINT:				return TextureFormat(TextureFormat::RG,		TextureFormat::SIGNED_INT32);
360		case VK_FORMAT_R32G32_SFLOAT:			return TextureFormat(TextureFormat::RG,		TextureFormat::FLOAT);
361
362		case VK_FORMAT_R32G32B32_UINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT32);
363		case VK_FORMAT_R32G32B32_SINT:			return TextureFormat(TextureFormat::RGB,	TextureFormat::SIGNED_INT32);
364		case VK_FORMAT_R32G32B32_SFLOAT:		return TextureFormat(TextureFormat::RGB,	TextureFormat::FLOAT);
365
366		case VK_FORMAT_R32G32B32A32_UINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT32);
367		case VK_FORMAT_R32G32B32A32_SINT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT32);
368		case VK_FORMAT_R32G32B32A32_SFLOAT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::FLOAT);
369
370		case VK_FORMAT_R64_SFLOAT:				return TextureFormat(TextureFormat::R,		TextureFormat::FLOAT64);
371		case VK_FORMAT_R64G64_SFLOAT:			return TextureFormat(TextureFormat::RG,		TextureFormat::FLOAT64);
372		case VK_FORMAT_R64G64B64_SFLOAT:		return TextureFormat(TextureFormat::RGB,	TextureFormat::FLOAT64);
373		case VK_FORMAT_R64G64B64A64_SFLOAT:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::FLOAT64);
374
375		case VK_FORMAT_B10G11R11_UFLOAT_PACK32:	return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT_11F_11F_10F_REV);
376		case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:	return TextureFormat(TextureFormat::RGB,	TextureFormat::UNSIGNED_INT_999_E5_REV);
377
378		case VK_FORMAT_B8G8R8_UNORM:			return TextureFormat(TextureFormat::BGR,	TextureFormat::UNORM_INT8);
379		case VK_FORMAT_B8G8R8_SNORM:			return TextureFormat(TextureFormat::BGR,	TextureFormat::SNORM_INT8);
380		case VK_FORMAT_B8G8R8_USCALED:			return TextureFormat(TextureFormat::BGR,	TextureFormat::UNSIGNED_INT8);
381		case VK_FORMAT_B8G8R8_SSCALED:			return TextureFormat(TextureFormat::BGR,	TextureFormat::SIGNED_INT8);
382		case VK_FORMAT_B8G8R8_UINT:				return TextureFormat(TextureFormat::BGR,	TextureFormat::UNSIGNED_INT8);
383		case VK_FORMAT_B8G8R8_SINT:				return TextureFormat(TextureFormat::BGR,	TextureFormat::SIGNED_INT8);
384		case VK_FORMAT_B8G8R8_SRGB:				return TextureFormat(TextureFormat::sBGR,	TextureFormat::UNORM_INT8);
385
386		case VK_FORMAT_B8G8R8A8_UNORM:			return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNORM_INT8);
387		case VK_FORMAT_B8G8R8A8_SNORM:			return TextureFormat(TextureFormat::BGRA,	TextureFormat::SNORM_INT8);
388		case VK_FORMAT_B8G8R8A8_USCALED:		return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNSIGNED_INT8);
389		case VK_FORMAT_B8G8R8A8_SSCALED:		return TextureFormat(TextureFormat::BGRA,	TextureFormat::SIGNED_INT8);
390		case VK_FORMAT_B8G8R8A8_UINT:			return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNSIGNED_INT8);
391		case VK_FORMAT_B8G8R8A8_SINT:			return TextureFormat(TextureFormat::BGRA,	TextureFormat::SIGNED_INT8);
392		case VK_FORMAT_B8G8R8A8_SRGB:			return TextureFormat(TextureFormat::sBGRA,	TextureFormat::UNORM_INT8);
393
394		case VK_FORMAT_D16_UNORM:				return TextureFormat(TextureFormat::D,		TextureFormat::UNORM_INT16);
395		case VK_FORMAT_X8_D24_UNORM_PACK32:		return TextureFormat(TextureFormat::D,		TextureFormat::UNSIGNED_INT_24_8_REV);
396		case VK_FORMAT_D32_SFLOAT:				return TextureFormat(TextureFormat::D,		TextureFormat::FLOAT);
397
398		case VK_FORMAT_S8_UINT:					return TextureFormat(TextureFormat::S,		TextureFormat::UNSIGNED_INT8);
399
400		// \note There is no standard interleaved memory layout for DS formats; buffer-image copies
401		//		 will always operate on either D or S aspect only. See Khronos bug 12998
402		case VK_FORMAT_D16_UNORM_S8_UINT:		return TextureFormat(TextureFormat::DS,		TextureFormat::UNSIGNED_INT_16_8_8);
403		case VK_FORMAT_D24_UNORM_S8_UINT:		return TextureFormat(TextureFormat::DS,		TextureFormat::UNSIGNED_INT_24_8_REV);
404		case VK_FORMAT_D32_SFLOAT_S8_UINT:		return TextureFormat(TextureFormat::DS,		TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV);
405
406#if (DE_ENDIANNESS == DE_LITTLE_ENDIAN)
407		case VK_FORMAT_A8B8G8R8_UNORM_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
408		case VK_FORMAT_A8B8G8R8_SNORM_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT8);
409		case VK_FORMAT_A8B8G8R8_USCALED_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT8);
410		case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT8);
411		case VK_FORMAT_A8B8G8R8_UINT_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT8);
412		case VK_FORMAT_A8B8G8R8_SINT_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT8);
413		case VK_FORMAT_A8B8G8R8_SRGB_PACK32:	return TextureFormat(TextureFormat::sRGBA,	TextureFormat::UNORM_INT8);
414#else
415#	error "Big-endian not supported"
416#endif
417
418		case VK_FORMAT_A2R10G10B10_UNORM_PACK32:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNORM_INT_1010102_REV);
419		case VK_FORMAT_A2R10G10B10_SNORM_PACK32:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::SNORM_INT_1010102_REV);
420		case VK_FORMAT_A2R10G10B10_USCALED_PACK32:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNSIGNED_INT_1010102_REV);
421		case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:	return TextureFormat(TextureFormat::BGRA,	TextureFormat::SIGNED_INT_1010102_REV);
422		case VK_FORMAT_A2R10G10B10_UINT_PACK32:		return TextureFormat(TextureFormat::BGRA,	TextureFormat::UNSIGNED_INT_1010102_REV);
423		case VK_FORMAT_A2R10G10B10_SINT_PACK32:		return TextureFormat(TextureFormat::BGRA,	TextureFormat::SIGNED_INT_1010102_REV);
424
425		case VK_FORMAT_A2B10G10R10_UNORM_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT_1010102_REV);
426		case VK_FORMAT_A2B10G10R10_SNORM_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SNORM_INT_1010102_REV);
427		case VK_FORMAT_A2B10G10R10_USCALED_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT_1010102_REV);
428		case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:	return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT_1010102_REV);
429		case VK_FORMAT_A2B10G10R10_UINT_PACK32:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNSIGNED_INT_1010102_REV);
430		case VK_FORMAT_A2B10G10R10_SINT_PACK32:		return TextureFormat(TextureFormat::RGBA,	TextureFormat::SIGNED_INT_1010102_REV);
431
432
433		default:
434			TCU_THROW(InternalError, "Unknown image format");
435	}
436}
437
438tcu::CompressedTexFormat mapVkCompressedFormat (VkFormat format)
439{
440	// update this mapping if VkFormat changes
441	DE_STATIC_ASSERT(VK_FORMAT_LAST == 185);
442
443	switch (format)
444	{
445		case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8;
446		case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8;
447		case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:	return tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1;
448		case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:	return tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1;
449		case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:	return tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8;
450		case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:	return tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8;
451		case VK_FORMAT_EAC_R11_UNORM_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_EAC_R11;
452		case VK_FORMAT_EAC_R11_SNORM_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11;
453		case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_EAC_RG11;
454		case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11;
455		case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA;
456		case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8;
457		case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA;
458		case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8;
459		case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA;
460		case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8;
461		case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA;
462		case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8;
463		case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA;
464		case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8;
465		case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA;
466		case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8;
467		case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA;
468		case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8;
469		case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA;
470		case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:			return tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8;
471		case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA;
472		case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8;
473		case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA;
474		case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8;
475		case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA;
476		case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8;
477		case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA;
478		case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8;
479		case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA;
480		case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8;
481		case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA;
482		case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:		return tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8;
483		default:
484			break;
485	}
486
487	return tcu::COMPRESSEDTEXFORMAT_LAST;
488}
489
490VkComponentMapping getFormatComponentMapping (VkFormat format)
491{
492	using tcu::TextureFormat;
493
494	static const VkComponentMapping	R		= {	VK_COMPONENT_SWIZZLE_R,		VK_COMPONENT_SWIZZLE_ZERO,	VK_COMPONENT_SWIZZLE_ZERO,	VK_COMPONENT_SWIZZLE_ONE	};
495	static const VkComponentMapping	RG		= {	VK_COMPONENT_SWIZZLE_R,		VK_COMPONENT_SWIZZLE_G,		VK_COMPONENT_SWIZZLE_ZERO,	VK_COMPONENT_SWIZZLE_ONE	};
496	static const VkComponentMapping	RGB		= {	VK_COMPONENT_SWIZZLE_R,		VK_COMPONENT_SWIZZLE_G,		VK_COMPONENT_SWIZZLE_B,		VK_COMPONENT_SWIZZLE_ONE	};
497	static const VkComponentMapping	RGBA	= {	VK_COMPONENT_SWIZZLE_R,		VK_COMPONENT_SWIZZLE_G,		VK_COMPONENT_SWIZZLE_B,		VK_COMPONENT_SWIZZLE_A		};
498	static const VkComponentMapping	S		= { VK_COMPONENT_SWIZZLE_ZERO,	VK_COMPONENT_SWIZZLE_ZERO,	VK_COMPONENT_SWIZZLE_ZERO,	VK_COMPONENT_SWIZZLE_A		};
499	static const VkComponentMapping	DS		= {	VK_COMPONENT_SWIZZLE_R,		VK_COMPONENT_SWIZZLE_ZERO,	VK_COMPONENT_SWIZZLE_ZERO,	VK_COMPONENT_SWIZZLE_A		};
500	static const VkComponentMapping	BGRA	= {	VK_COMPONENT_SWIZZLE_B,		VK_COMPONENT_SWIZZLE_G,		VK_COMPONENT_SWIZZLE_R,		VK_COMPONENT_SWIZZLE_A		};
501	static const VkComponentMapping	BGR		= {	VK_COMPONENT_SWIZZLE_B,		VK_COMPONENT_SWIZZLE_G,		VK_COMPONENT_SWIZZLE_R,		VK_COMPONENT_SWIZZLE_ONE	};
502
503	if (format == VK_FORMAT_UNDEFINED)
504		return RGBA;
505
506	const tcu::TextureFormat tcuFormat = (isCompressedFormat(format)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(format))
507																	  : mapVkFormat(format);
508
509	switch (tcuFormat.order)
510	{
511		case TextureFormat::R:		return R;
512		case TextureFormat::RG:		return RG;
513		case TextureFormat::RGB:	return RGB;
514		case TextureFormat::RGBA:	return RGBA;
515		case TextureFormat::BGRA:	return BGRA;
516		case TextureFormat::BGR:	return BGR;
517		case TextureFormat::sR:		return R;
518		case TextureFormat::sRG:	return RG;
519		case TextureFormat::sRGB:	return RGB;
520		case TextureFormat::sRGBA:	return RGBA;
521		case TextureFormat::sBGR:	return BGR;
522		case TextureFormat::sBGRA:	return BGRA;
523		case TextureFormat::D:		return R;
524		case TextureFormat::S:		return S;
525		case TextureFormat::DS:		return DS;
526		default:
527			break;
528	}
529
530	DE_ASSERT(false);
531	return RGBA;
532}
533
534static bool isScaledFormat (VkFormat format)
535{
536	// update this mapping if VkFormat changes
537	DE_STATIC_ASSERT(VK_FORMAT_LAST == 185);
538
539	switch (format)
540	{
541		case VK_FORMAT_R8_USCALED:
542		case VK_FORMAT_R8_SSCALED:
543		case VK_FORMAT_R8G8_USCALED:
544		case VK_FORMAT_R8G8_SSCALED:
545		case VK_FORMAT_R8G8B8_USCALED:
546		case VK_FORMAT_R8G8B8_SSCALED:
547		case VK_FORMAT_R8G8B8A8_USCALED:
548		case VK_FORMAT_R8G8B8A8_SSCALED:
549		case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
550		case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
551		case VK_FORMAT_R16_USCALED:
552		case VK_FORMAT_R16_SSCALED:
553		case VK_FORMAT_R16G16_USCALED:
554		case VK_FORMAT_R16G16_SSCALED:
555		case VK_FORMAT_R16G16B16_USCALED:
556		case VK_FORMAT_R16G16B16_SSCALED:
557		case VK_FORMAT_R16G16B16A16_USCALED:
558		case VK_FORMAT_R16G16B16A16_SSCALED:
559		case VK_FORMAT_B8G8R8_USCALED:
560		case VK_FORMAT_B8G8R8_SSCALED:
561		case VK_FORMAT_B8G8R8A8_USCALED:
562		case VK_FORMAT_B8G8R8A8_SSCALED:
563		case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
564		case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
565			return true;
566
567		default:
568			return false;
569	}
570}
571
572static bool fullTextureFormatRoundTripSupported (VkFormat format)
573{
574	if (isScaledFormat(format))
575	{
576		// *SCALED formats get mapped to correspoding (u)int formats since
577		// accessing them through (float) getPixel/setPixel has same behavior
578		// as in shader access in Vulkan.
579		// Unfortunately full round-trip between tcu::TextureFormat and VkFormat
580		// for most SCALED formats is not supported though.
581
582		const tcu::TextureFormat	tcuFormat	= mapVkFormat(format);
583
584		switch (tcuFormat.type)
585		{
586			case tcu::TextureFormat::UNSIGNED_INT8:
587			case tcu::TextureFormat::UNSIGNED_INT16:
588			case tcu::TextureFormat::UNSIGNED_INT32:
589			case tcu::TextureFormat::SIGNED_INT8:
590			case tcu::TextureFormat::SIGNED_INT16:
591			case tcu::TextureFormat::SIGNED_INT32:
592			case tcu::TextureFormat::UNSIGNED_INT_1010102_REV:
593			case tcu::TextureFormat::SIGNED_INT_1010102_REV:
594				return false;
595
596			default:
597				return true;
598		}
599	}
600	else
601	{
602		switch (format)
603		{
604			case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
605			case VK_FORMAT_A8B8G8R8_SNORM_PACK32:
606			case VK_FORMAT_A8B8G8R8_USCALED_PACK32:
607			case VK_FORMAT_A8B8G8R8_SSCALED_PACK32:
608			case VK_FORMAT_A8B8G8R8_UINT_PACK32:
609			case VK_FORMAT_A8B8G8R8_SINT_PACK32:
610			case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
611				return false; // These map to regular byte array formats
612
613			default:
614				break;
615		}
616
617		return (format != VK_FORMAT_UNDEFINED);
618	}
619}
620
621void imageUtilSelfTest (void)
622{
623	for (int formatNdx = 0; formatNdx < VK_FORMAT_LAST; formatNdx++)
624	{
625		const VkFormat	format	= (VkFormat)formatNdx;
626
627		if (format == VK_FORMAT_R64_UINT			||
628			format == VK_FORMAT_R64_SINT			||
629			format == VK_FORMAT_R64G64_UINT			||
630			format == VK_FORMAT_R64G64_SINT			||
631			format == VK_FORMAT_R64G64B64_UINT		||
632			format == VK_FORMAT_R64G64B64_SINT		||
633			format == VK_FORMAT_R64G64B64A64_UINT	||
634			format == VK_FORMAT_R64G64B64A64_SINT)
635			continue; // \todo [2015-12-05 pyry] Add framework support for (u)int64 channel type
636
637		if (format != VK_FORMAT_UNDEFINED && !isCompressedFormat(format))
638		{
639			const tcu::TextureFormat	tcuFormat		= mapVkFormat(format);
640			const VkFormat				remappedFormat	= mapTextureFormat(tcuFormat);
641
642			DE_TEST_ASSERT(isValid(tcuFormat));
643
644			if (fullTextureFormatRoundTripSupported(format))
645				DE_TEST_ASSERT(format == remappedFormat);
646		}
647	}
648}
649
650VkFilter mapFilterMode (tcu::Sampler::FilterMode filterMode)
651{
652	DE_STATIC_ASSERT(tcu::Sampler::FILTERMODE_LAST == 6);
653
654	switch (filterMode)
655	{
656		case tcu::Sampler::NEAREST:					return VK_FILTER_NEAREST;
657		case tcu::Sampler::LINEAR:					return VK_FILTER_LINEAR;
658		case tcu::Sampler::NEAREST_MIPMAP_NEAREST:	return VK_FILTER_NEAREST;
659		case tcu::Sampler::NEAREST_MIPMAP_LINEAR:	return VK_FILTER_NEAREST;
660		case tcu::Sampler::LINEAR_MIPMAP_NEAREST:	return VK_FILTER_LINEAR;
661		case tcu::Sampler::LINEAR_MIPMAP_LINEAR:	return VK_FILTER_LINEAR;
662		default:
663			DE_FATAL("Illegal filter mode");
664			return (VkFilter)0;
665
666	}
667}
668
669VkSamplerMipmapMode mapMipmapMode (tcu::Sampler::FilterMode filterMode)
670{
671	DE_STATIC_ASSERT(tcu::Sampler::FILTERMODE_LAST == 6);
672
673	// \note VkSamplerCreateInfo doesn't have a flag for disabling mipmapping. Instead
674	//		 minLod = 0 and maxLod = 0.25 should be used to match OpenGL NEAREST and LINEAR
675	//		 filtering mode behavior.
676
677	switch (filterMode)
678	{
679		case tcu::Sampler::NEAREST:					return VK_SAMPLER_MIPMAP_MODE_NEAREST;
680		case tcu::Sampler::LINEAR:					return VK_SAMPLER_MIPMAP_MODE_NEAREST;
681		case tcu::Sampler::NEAREST_MIPMAP_NEAREST:	return VK_SAMPLER_MIPMAP_MODE_NEAREST;
682		case tcu::Sampler::NEAREST_MIPMAP_LINEAR:	return VK_SAMPLER_MIPMAP_MODE_LINEAR;
683		case tcu::Sampler::LINEAR_MIPMAP_NEAREST:	return VK_SAMPLER_MIPMAP_MODE_NEAREST;
684		case tcu::Sampler::LINEAR_MIPMAP_LINEAR:	return VK_SAMPLER_MIPMAP_MODE_LINEAR;
685		default:
686			DE_FATAL("Illegal filter mode");
687			return (VkSamplerMipmapMode)0;
688	}
689}
690
691VkSamplerAddressMode mapWrapMode (tcu::Sampler::WrapMode wrapMode)
692{
693	switch (wrapMode)
694	{
695		case tcu::Sampler::CLAMP_TO_EDGE:		return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
696		case tcu::Sampler::CLAMP_TO_BORDER:		return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
697		case tcu::Sampler::REPEAT_GL:			return VK_SAMPLER_ADDRESS_MODE_REPEAT;
698		case tcu::Sampler::MIRRORED_REPEAT_GL:	return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
699		case tcu::Sampler::MIRRORED_ONCE:		return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
700		default:
701			DE_FATAL("Wrap mode can't be mapped to Vulkan");
702			return (vk::VkSamplerAddressMode)0;
703	}
704}
705
706vk::VkCompareOp mapCompareMode (tcu::Sampler::CompareMode mode)
707{
708	switch (mode)
709	{
710		case tcu::Sampler::COMPAREMODE_NONE:				return vk::VK_COMPARE_OP_NEVER;
711		case tcu::Sampler::COMPAREMODE_LESS:				return vk::VK_COMPARE_OP_LESS;
712		case tcu::Sampler::COMPAREMODE_LESS_OR_EQUAL:		return vk::VK_COMPARE_OP_LESS_OR_EQUAL;
713		case tcu::Sampler::COMPAREMODE_GREATER:				return vk::VK_COMPARE_OP_GREATER;
714		case tcu::Sampler::COMPAREMODE_GREATER_OR_EQUAL:	return vk::VK_COMPARE_OP_GREATER_OR_EQUAL;
715		case tcu::Sampler::COMPAREMODE_EQUAL:				return vk::VK_COMPARE_OP_EQUAL;
716		case tcu::Sampler::COMPAREMODE_NOT_EQUAL:			return vk::VK_COMPARE_OP_NOT_EQUAL;
717		case tcu::Sampler::COMPAREMODE_ALWAYS:				return vk::VK_COMPARE_OP_ALWAYS;
718		case tcu::Sampler::COMPAREMODE_NEVER:				return vk::VK_COMPARE_OP_NEVER;
719		default:
720			DE_FATAL("Illegal compare mode");
721			return (vk::VkCompareOp)0;
722	}
723}
724
725static VkBorderColor mapBorderColor (tcu::TextureChannelClass channelClass, const rr::GenericVec4& color)
726{
727	if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
728	{
729		const tcu::UVec4	uColor	= color.get<deUint32>();
730
731		if (uColor		== tcu::UVec4(0, 0, 0, 0)) return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
732		else if (uColor	== tcu::UVec4(0, 0, 0, 1)) return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
733		else if (uColor == tcu::UVec4(1, 1, 1, 1)) return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
734	}
735	else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
736	{
737		const tcu::IVec4	sColor	= color.get<deInt32>();
738
739		if (sColor		== tcu::IVec4(0, 0, 0, 0)) return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
740		else if (sColor	== tcu::IVec4(0, 0, 0, 1)) return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
741		else if (sColor == tcu::IVec4(1, 1, 1, 1)) return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
742	}
743	else
744	{
745		const tcu::Vec4		fColor	= color.get<float>();
746
747		if (fColor		== tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)) return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
748		else if (fColor == tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)) return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
749		else if (fColor == tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)) return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
750	}
751
752	DE_FATAL("Unsupported border color");
753	return VK_BORDER_COLOR_LAST;
754}
755
756VkSamplerCreateInfo mapSampler (const tcu::Sampler& sampler, const tcu::TextureFormat& format)
757{
758	const bool					compareEnabled	= (sampler.compare != tcu::Sampler::COMPAREMODE_NONE);
759	const VkCompareOp			compareOp		= (compareEnabled) ? (mapCompareMode(sampler.compare)) : (VK_COMPARE_OP_ALWAYS);
760	const VkBorderColor			borderColor		= mapBorderColor(getTextureChannelClass(format.type), sampler.borderColor);
761	const bool					isMipmapEnabled	= (sampler.minFilter != tcu::Sampler::NEAREST && sampler.minFilter != tcu::Sampler::LINEAR);
762
763	const VkSamplerCreateInfo	createInfo		=
764	{
765		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
766		DE_NULL,
767		(VkSamplerCreateFlags)0,
768		mapFilterMode(sampler.magFilter),							// magFilter
769		mapFilterMode(sampler.minFilter),							// minFilter
770		mapMipmapMode(sampler.minFilter),							// mipMode
771		mapWrapMode(sampler.wrapS),									// addressU
772		mapWrapMode(sampler.wrapT),									// addressV
773		mapWrapMode(sampler.wrapR),									// addressW
774		0.0f,														// mipLodBias
775		VK_FALSE,													// anisotropyEnable
776		1.0f,														// maxAnisotropy
777		(VkBool32)(compareEnabled ? VK_TRUE : VK_FALSE),			// compareEnable
778		compareOp,													// compareOp
779		0.0f,														// minLod
780		(isMipmapEnabled ? 1000.0f : 0.25f),						// maxLod
781		borderColor,												// borderColor
782		(VkBool32)(sampler.normalizedCoords ? VK_FALSE : VK_TRUE),	// unnormalizedCoords
783	};
784
785	return createInfo;
786}
787
788tcu::Sampler mapVkSampler (const VkSamplerCreateInfo& samplerCreateInfo)
789{
790	// \note minLod & maxLod are not supported by tcu::Sampler. LOD must be clamped
791	//       before passing it to tcu::Texture*::sample*()
792
793	tcu::Sampler sampler(mapVkSamplerAddressMode(samplerCreateInfo.addressModeU),
794						 mapVkSamplerAddressMode(samplerCreateInfo.addressModeV),
795						 mapVkSamplerAddressMode(samplerCreateInfo.addressModeW),
796						 mapVkMinTexFilter(samplerCreateInfo.minFilter, samplerCreateInfo.mipmapMode),
797						 mapVkMagTexFilter(samplerCreateInfo.magFilter),
798						 0.0f,
799						 !samplerCreateInfo.unnormalizedCoordinates,
800						 samplerCreateInfo.compareEnable ? mapVkSamplerCompareOp(samplerCreateInfo.compareOp)
801														 : tcu::Sampler::COMPAREMODE_NONE,
802						 0,
803						 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
804						 true);
805
806	if (samplerCreateInfo.anisotropyEnable)
807		TCU_THROW(InternalError, "Anisotropic filtering is not supported by tcu::Sampler");
808
809	switch (samplerCreateInfo.borderColor)
810	{
811		case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
812			sampler.borderColor = tcu::UVec4(0,0,0,1);
813			break;
814		case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
815			sampler.borderColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
816			break;
817		case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
818			sampler.borderColor = tcu::UVec4(1, 1, 1, 1);
819			break;
820		case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
821			sampler.borderColor = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
822			break;
823		case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
824			sampler.borderColor = tcu::UVec4(0,0,0,0);
825			break;
826		case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
827			sampler.borderColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
828			break;
829
830		default:
831			DE_ASSERT(false);
832			break;
833	}
834
835	return sampler;
836}
837
838tcu::Sampler::CompareMode mapVkSamplerCompareOp (VkCompareOp compareOp)
839{
840	switch (compareOp)
841	{
842		case VK_COMPARE_OP_NEVER:				return tcu::Sampler::COMPAREMODE_NEVER;
843		case VK_COMPARE_OP_LESS:				return tcu::Sampler::COMPAREMODE_LESS;
844		case VK_COMPARE_OP_EQUAL:				return tcu::Sampler::COMPAREMODE_EQUAL;
845		case VK_COMPARE_OP_LESS_OR_EQUAL:		return tcu::Sampler::COMPAREMODE_LESS_OR_EQUAL;
846		case VK_COMPARE_OP_GREATER:				return tcu::Sampler::COMPAREMODE_GREATER;
847		case VK_COMPARE_OP_NOT_EQUAL:			return tcu::Sampler::COMPAREMODE_NOT_EQUAL;
848		case VK_COMPARE_OP_GREATER_OR_EQUAL:	return tcu::Sampler::COMPAREMODE_GREATER_OR_EQUAL;
849		case VK_COMPARE_OP_ALWAYS:				return tcu::Sampler::COMPAREMODE_ALWAYS;
850		default:
851			break;
852	}
853
854	DE_ASSERT(false);
855	return tcu::Sampler::COMPAREMODE_LAST;
856}
857
858tcu::Sampler::WrapMode mapVkSamplerAddressMode (VkSamplerAddressMode addressMode)
859{
860	switch (addressMode)
861	{
862		case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:			return tcu::Sampler::CLAMP_TO_EDGE;
863		case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:		return tcu::Sampler::CLAMP_TO_BORDER;
864		case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:		return tcu::Sampler::MIRRORED_REPEAT_GL;
865		case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:	return tcu::Sampler::MIRRORED_ONCE;
866		case VK_SAMPLER_ADDRESS_MODE_REPEAT:				return tcu::Sampler::REPEAT_GL;
867		default:
868			break;
869	}
870
871	DE_ASSERT(false);
872	return tcu::Sampler::WRAPMODE_LAST;
873}
874
875tcu::Sampler::FilterMode mapVkMinTexFilter (VkFilter filter, VkSamplerMipmapMode mipMode)
876{
877	switch (filter)
878	{
879		case VK_FILTER_LINEAR:
880			switch (mipMode)
881			{
882				case VK_SAMPLER_MIPMAP_MODE_LINEAR:		return tcu::Sampler::LINEAR_MIPMAP_LINEAR;
883				case VK_SAMPLER_MIPMAP_MODE_NEAREST:	return tcu::Sampler::LINEAR_MIPMAP_NEAREST;
884				default:
885					break;
886			}
887			break;
888
889		case VK_FILTER_NEAREST:
890			switch (mipMode)
891			{
892				case VK_SAMPLER_MIPMAP_MODE_LINEAR:		return tcu::Sampler::NEAREST_MIPMAP_LINEAR;
893				case VK_SAMPLER_MIPMAP_MODE_NEAREST:	return tcu::Sampler::NEAREST_MIPMAP_NEAREST;
894				default:
895					break;
896			}
897			break;
898
899		default:
900			break;
901	}
902
903	DE_ASSERT(false);
904	return tcu::Sampler::FILTERMODE_LAST;
905}
906
907tcu::Sampler::FilterMode mapVkMagTexFilter (VkFilter filter)
908{
909	switch (filter)
910	{
911		case VK_FILTER_LINEAR:		return tcu::Sampler::LINEAR;
912		case VK_FILTER_NEAREST:		return tcu::Sampler::NEAREST;
913		default:
914			break;
915	}
916
917	DE_ASSERT(false);
918	return tcu::Sampler::FILTERMODE_LAST;
919}
920
921
922int mapVkComponentSwizzle (const vk::VkComponentSwizzle& channelSwizzle)
923{
924	switch (channelSwizzle)
925	{
926		case vk::VK_COMPONENT_SWIZZLE_ZERO:	return 0;
927		case vk::VK_COMPONENT_SWIZZLE_ONE:	return 1;
928		case vk::VK_COMPONENT_SWIZZLE_R:	return 2;
929		case vk::VK_COMPONENT_SWIZZLE_G:	return 3;
930		case vk::VK_COMPONENT_SWIZZLE_B:	return 4;
931		case vk::VK_COMPONENT_SWIZZLE_A:	return 5;
932		default:
933			break;
934	}
935
936	DE_ASSERT(false);
937	return 0;
938}
939
940tcu::UVec4 mapVkComponentMapping (const vk::VkComponentMapping& mapping)
941{
942	tcu::UVec4 swizzle;
943
944	swizzle.x() = mapVkComponentSwizzle(mapping.r);
945	swizzle.y() = mapVkComponentSwizzle(mapping.g);
946	swizzle.z() = mapVkComponentSwizzle(mapping.b);
947	swizzle.w() = mapVkComponentSwizzle(mapping.a);
948
949	return swizzle;
950}
951
952//! Get a format the matches the layout in buffer memory used for a
953//! buffer<->image copy on a depth/stencil format.
954tcu::TextureFormat getDepthCopyFormat (VkFormat combinedFormat)
955{
956	switch (combinedFormat)
957	{
958		case VK_FORMAT_D16_UNORM:
959		case VK_FORMAT_X8_D24_UNORM_PACK32:
960		case VK_FORMAT_D32_SFLOAT:
961			return mapVkFormat(combinedFormat);
962
963		case VK_FORMAT_D16_UNORM_S8_UINT:
964			return mapVkFormat(VK_FORMAT_D16_UNORM);
965		case VK_FORMAT_D24_UNORM_S8_UINT:
966			return mapVkFormat(VK_FORMAT_X8_D24_UNORM_PACK32);
967		case VK_FORMAT_D32_SFLOAT_S8_UINT:
968			return mapVkFormat(VK_FORMAT_D32_SFLOAT);
969
970		case VK_FORMAT_S8_UINT:
971		default:
972			DE_FATAL("Unexpected depth/stencil format");
973			return tcu::TextureFormat();
974	}
975}
976
977//! Get a format the matches the layout in buffer memory used for a
978//! buffer<->image copy on a depth/stencil format.
979tcu::TextureFormat getStencilCopyFormat (VkFormat combinedFormat)
980{
981	switch (combinedFormat)
982	{
983		case VK_FORMAT_D16_UNORM_S8_UINT:
984		case VK_FORMAT_D24_UNORM_S8_UINT:
985		case VK_FORMAT_D32_SFLOAT_S8_UINT:
986		case VK_FORMAT_S8_UINT:
987			return mapVkFormat(VK_FORMAT_S8_UINT);
988
989		case VK_FORMAT_D16_UNORM:
990		case VK_FORMAT_X8_D24_UNORM_PACK32:
991		case VK_FORMAT_D32_SFLOAT:
992		default:
993			DE_FATAL("Unexpected depth/stencil format");
994			return tcu::TextureFormat();
995	}
996}
997
998} // vk
999