1/*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015-2016 The Khronos Group Inc.
6 * Copyright (c) 2015-2016 Samsung Electronics Co., 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 Vulkan Copies And Blitting Tests
23 *//*--------------------------------------------------------------------*/
24
25#include "vktApiCopiesAndBlittingTests.hpp"
26
27#include "deStringUtil.hpp"
28#include "deUniquePtr.hpp"
29
30#include "tcuImageCompare.hpp"
31#include "tcuTexture.hpp"
32#include "tcuTextureUtil.hpp"
33#include "tcuVectorType.hpp"
34#include "tcuVectorUtil.hpp"
35
36#include "vkImageUtil.hpp"
37#include "vkMemUtil.hpp"
38#include "vkPrograms.hpp"
39#include "vkQueryUtil.hpp"
40#include "vkRefUtil.hpp"
41#include "vktTestCase.hpp"
42#include "vktTestCaseUtil.hpp"
43#include "vkTypeUtil.hpp"
44
45namespace vkt
46{
47
48namespace api
49{
50
51namespace
52{
53enum MirrorMode
54{
55	MIRROR_MODE_NONE = 0,
56	MIRROR_MODE_X = (1<<0),
57	MIRROR_MODE_Y = (1<<1),
58	MIRROR_MODE_XY = MIRROR_MODE_X | MIRROR_MODE_Y,
59
60	MIRROR_MODE_LAST
61};
62
63}
64
65using namespace vk;
66
67namespace
68{
69
70VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
71{
72	VkImageAspectFlags	aspectFlag	= 0;
73	aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
74	aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
75
76	if (!aspectFlag)
77		aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
78
79	return aspectFlag;
80}
81
82// This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
83// except that it supports some formats that are not mappable to VkFormat.
84// When we are checking combined depth and stencil formats, each aspect is
85// checked separately, and in some cases we construct PBA with a format that
86// is not mappable to VkFormat.
87bool isFloatFormat (tcu::TextureFormat format)
88{
89	return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
90}
91
92union CopyRegion
93{
94	VkBufferCopy		bufferCopy;
95	VkImageCopy			imageCopy;
96	VkBufferImageCopy	bufferImageCopy;
97	VkImageBlit			imageBlit;
98	VkImageResolve		imageResolve;
99};
100
101struct ImageParms
102{
103	VkImageType		imageType;
104	VkFormat		format;
105	VkExtent3D		extent;
106};
107
108struct TestParams
109{
110	union Data
111	{
112		struct Buffer
113		{
114			VkDeviceSize	size;
115		} buffer;
116
117		ImageParms	image;
118	} src, dst;
119
120	std::vector<CopyRegion>	regions;
121
122	union
123	{
124		VkFilter				filter;
125		VkSampleCountFlagBits	samples;
126	};
127};
128
129inline deUint32 getArraySize(const ImageParms& parms)
130{
131	return (parms.imageType == VK_IMAGE_TYPE_2D) ? parms.extent.depth : 1u;
132}
133
134inline VkExtent3D getExtent3D(const ImageParms& parms)
135{
136	const VkExtent3D		extent					=
137	{
138		parms.extent.width,
139		parms.extent.height,
140		(parms.imageType == VK_IMAGE_TYPE_2D) ? 1u : parms.extent.depth
141	};
142	return extent;
143}
144
145const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
146{
147	tcu::TextureFormat format;
148	switch (combinedFormat.type)
149	{
150		case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
151			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
152			break;
153		case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
154			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
155			break;
156		case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
157			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
158			break;
159		default:
160			DE_ASSERT(false);
161			break;
162	}
163	return format;
164}
165
166class CopiesAndBlittingTestInstance : public vkt::TestInstance
167{
168public:
169										CopiesAndBlittingTestInstance		(Context&	context,
170																			 TestParams	testParams);
171	virtual tcu::TestStatus				iterate								(void) = 0;
172
173	enum FillMode
174	{
175		FILL_MODE_GRADIENT = 0,
176		FILL_MODE_WHITE,
177		FILL_MODE_RED,
178		FILL_MODE_MULTISAMPLE,
179
180		FILL_MODE_LAST
181	};
182
183protected:
184	const TestParams					m_params;
185
186	Move<VkCommandPool>					m_cmdPool;
187	Move<VkCommandBuffer>				m_cmdBuffer;
188	Move<VkFence>						m_fence;
189	de::MovePtr<tcu::TextureLevel>		m_sourceTextureLevel;
190	de::MovePtr<tcu::TextureLevel>		m_destinationTextureLevel;
191	de::MovePtr<tcu::TextureLevel>		m_expectedTextureLevel;
192
193	VkCommandBufferBeginInfo			m_cmdBufferBeginInfo;
194
195	void								generateBuffer						(tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
196	virtual void						generateExpectedResult				(void);
197	void								uploadBuffer						(tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
198	void								uploadImage							(const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms);
199	virtual tcu::TestStatus				checkTestResult						(tcu::ConstPixelBufferAccess result);
200	virtual void						copyRegionToTextureLevel			(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) = 0;
201	deUint32							calculateSize						(tcu::ConstPixelBufferAccess src) const
202										{
203											return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
204										}
205
206	de::MovePtr<tcu::TextureLevel>		readImage							(vk::VkImage				image,
207																			 const ImageParms&			imageParms);
208	void								submitCommandsAndWait				(const DeviceInterface&		vk,
209																			const VkDevice				device,
210																			const VkQueue				queue,
211																			const VkCommandBuffer&		cmdBuffer);
212
213private:
214	void								uploadImageAspect					(const tcu::ConstPixelBufferAccess&	src,
215																			 const VkImage&						dst,
216																			 const ImageParms&					parms);
217	void								readImageAspect						(vk::VkImage						src,
218																			 const tcu::PixelBufferAccess&		dst,
219																			 const ImageParms&					parms);
220};
221
222CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
223	: vkt::TestInstance	(context)
224	, m_params			(testParams)
225{
226	const DeviceInterface&		vk					= context.getDeviceInterface();
227	const VkDevice				vkDevice			= context.getDevice();
228	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
229
230	// Create command pool
231	{
232		const VkCommandPoolCreateInfo		cmdPoolParams			=
233		{
234			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// VkStructureType		sType;
235			DE_NULL,										// const void*			pNext;
236			VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,// VkCmdPoolCreateFlags	flags;
237			queueFamilyIndex,								// deUint32				queueFamilyIndex;
238		};
239
240		m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
241	}
242
243	// Create command buffer
244	{
245		const VkCommandBufferAllocateInfo	cmdBufferAllocateInfo	=
246		{
247			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
248			DE_NULL,										// const void*				pNext;
249			*m_cmdPool,										// VkCommandPool			commandPool;
250			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
251			1u												// deUint32					bufferCount;
252		};
253
254		m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
255	}
256
257	// Create fence
258	{
259		const VkFenceCreateInfo				fenceParams				=
260		{
261			VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
262			DE_NULL,								// const void*			pNext;
263			0u										// VkFenceCreateFlags	flags;
264		};
265
266		m_fence = createFence(vk, vkDevice, &fenceParams);
267	}
268}
269
270void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
271{
272	if (mode == FILL_MODE_GRADIENT)
273	{
274		tcu::fillWithComponentGradients(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
275		return;
276	}
277
278	const tcu::Vec4		redColor	(1.0, 0.0, 0.0, 1.0);
279	const tcu::Vec4		greenColor	(0.0, 1.0, 0.0, 1.0);
280	const tcu::Vec4		blueColor	(0.0, 0.0, 1.0, 1.0);
281	const tcu::Vec4		whiteColor	(1.0, 1.0, 1.0, 1.0);
282
283	for (int z = 0; z < depth; z++)
284	{
285		for (int y = 0; y < height; y++)
286		{
287			for (int x = 0; x < width; x++)
288			{
289				switch (mode)
290				{
291					case FILL_MODE_WHITE:
292						if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
293						{
294							buffer.setPixDepth(1.0f, x, y, z);
295							if (tcu::hasStencilComponent(buffer.getFormat().order))
296								buffer.setPixStencil(255, x, y, z);
297						}
298						else
299							buffer.setPixel(whiteColor, x, y, z);
300						break;
301					case FILL_MODE_RED:
302						if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
303						{
304							buffer.setPixDepth(redColor[x % 4], x, y, z);
305							if (tcu::hasStencilComponent(buffer.getFormat().order))
306								buffer.setPixStencil(255 * (int)redColor[y % 4], x, y, z);
307						}
308						else
309							buffer.setPixel(redColor, x, y, z);
310						break;
311					case FILL_MODE_MULTISAMPLE:
312						buffer.setPixel((x == y) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((x > y) ? greenColor : blueColor), x, y, z);
313						break;
314					default:
315						break;
316				}
317			}
318		}
319	}
320}
321
322void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
323{
324	const DeviceInterface&		vk			= m_context.getDeviceInterface();
325	const VkDevice				vkDevice	= m_context.getDevice();
326	const deUint32				bufferSize	= calculateSize(bufferAccess);
327
328	// Write buffer data
329	deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
330	flushMappedMemoryRange(vk, vkDevice, bufferAlloc.getMemory(), bufferAlloc.getOffset(), bufferSize);
331}
332
333void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms)
334{
335	const DeviceInterface&		vk					= m_context.getDeviceInterface();
336	const VkDevice				vkDevice			= m_context.getDevice();
337	const VkQueue				queue				= m_context.getUniversalQueue();
338	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
339	Allocator&					memAlloc			= m_context.getDefaultAllocator();
340	Move<VkBuffer>				buffer;
341	const deUint32				bufferSize			= calculateSize(imageAccess);
342	de::MovePtr<Allocation>		bufferAlloc;
343	const deUint32				arraySize			= getArraySize(parms);
344	const VkExtent3D			imageExtent			= getExtent3D(parms);
345
346	// Create source buffer
347	{
348		const VkBufferCreateInfo			bufferParams			=
349		{
350			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
351			DE_NULL,									// const void*			pNext;
352			0u,											// VkBufferCreateFlags	flags;
353			bufferSize,									// VkDeviceSize			size;
354			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
355			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
356			1u,											// deUint32				queueFamilyIndexCount;
357			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
358		};
359
360		buffer		= createBuffer(vk, vkDevice, &bufferParams);
361		bufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
362		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
363	}
364
365	// Barriers for copying buffer to image
366	const VkBufferMemoryBarrier				preBufferBarrier		=
367	{
368		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
369		DE_NULL,										// const void*		pNext;
370		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
371		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
372		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
373		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
374		*buffer,										// VkBuffer			buffer;
375		0u,												// VkDeviceSize		offset;
376		bufferSize										// VkDeviceSize		size;
377	};
378
379	const VkImageAspectFlags				formatAspect			= getAspectFlags(mapVkFormat(parms.format));
380	const bool								skipPreImageBarrier		= formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
381																	  getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT;
382	const VkImageMemoryBarrier				preImageBarrier			=
383	{
384		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
385		DE_NULL,										// const void*				pNext;
386		0u,												// VkAccessFlags			srcAccessMask;
387		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
388		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
389		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
390		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
391		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
392		image,											// VkImage					image;
393		{												// VkImageSubresourceRange	subresourceRange;
394			formatAspect,	// VkImageAspectFlags	aspect;
395			0u,				// deUint32				baseMipLevel;
396			1u,				// deUint32				mipLevels;
397			0u,				// deUint32				baseArraySlice;
398			arraySize,		// deUint32				arraySize;
399		}
400	};
401
402	const VkImageMemoryBarrier				postImageBarrier		=
403	{
404		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
405		DE_NULL,										// const void*				pNext;
406		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
407		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
408		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
409		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
410		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
411		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
412		image,											// VkImage					image;
413		{												// VkImageSubresourceRange	subresourceRange;
414			formatAspect,				// VkImageAspectFlags	aspect;
415			0u,							// deUint32				baseMipLevel;
416			1u,							// deUint32				mipLevels;
417			0u,							// deUint32				baseArraySlice;
418			arraySize,					// deUint32				arraySize;
419		}
420	};
421
422	const VkBufferImageCopy		copyRegion		=
423	{
424		0u,												// VkDeviceSize				bufferOffset;
425		(deUint32)imageAccess.getWidth(),				// deUint32					bufferRowLength;
426		(deUint32)imageAccess.getHeight(),				// deUint32					bufferImageHeight;
427		{
428			getAspectFlags(imageAccess.getFormat()),		// VkImageAspectFlags	aspect;
429			0u,												// deUint32				mipLevel;
430			0u,												// deUint32				baseArrayLayer;
431			arraySize,										// deUint32				layerCount;
432		},												// VkImageSubresourceLayers	imageSubresource;
433		{ 0, 0, 0 },									// VkOffset3D				imageOffset;
434		imageExtent										// VkExtent3D				imageExtent;
435	};
436
437	// Write buffer data
438	deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
439	flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
440
441	// Copy buffer to image
442	const VkCommandBufferBeginInfo			cmdBufferBeginInfo		=
443	{
444		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
445		DE_NULL,												// const void*						pNext;
446		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
447		(const VkCommandBufferInheritanceInfo*)DE_NULL,
448	};
449
450	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
451	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
452						  1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
453	vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
454	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
455	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
456
457	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
458}
459
460void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms)
461{
462	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
463	{
464		if (tcu::hasDepthComponent(src.getFormat().order))
465		{
466			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
467			tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
468			uploadImageAspect(depthTexture.getAccess(), dst, parms);
469		}
470
471		if (tcu::hasStencilComponent(src.getFormat().order))
472		{
473			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
474			tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
475			uploadImageAspect(stencilTexture.getAccess(), dst, parms);
476		}
477	}
478	else
479		uploadImageAspect(src, dst, parms);
480}
481
482tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
483{
484	const tcu::ConstPixelBufferAccess	expected	= m_expectedTextureLevel->getAccess();
485
486	if (isFloatFormat(result.getFormat()))
487	{
488		const tcu::Vec4	threshold (0.0f);
489		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
490			return tcu::TestStatus::fail("CopiesAndBlitting test");
491	}
492	else
493	{
494		const tcu::UVec4 threshold (0u);
495		if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
496			return tcu::TestStatus::fail("CopiesAndBlitting test");
497	}
498
499	return tcu::TestStatus::pass("CopiesAndBlitting test");
500}
501
502void CopiesAndBlittingTestInstance::generateExpectedResult (void)
503{
504	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
505	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
506
507	m_expectedTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
508	tcu::copy(m_expectedTextureLevel->getAccess(), dst);
509
510	for (deUint32 i = 0; i < m_params.regions.size(); i++)
511		copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), m_params.regions[i]);
512}
513
514class CopiesAndBlittingTestCase : public vkt::TestCase
515{
516public:
517							CopiesAndBlittingTestCase	(tcu::TestContext&			testCtx,
518														 const std::string&			name,
519														 const std::string&			description)
520								: vkt::TestCase	(testCtx, name, description)
521							{}
522
523	virtual TestInstance*	createInstance				(Context&					context) const = 0;
524};
525
526void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage					image,
527													 const tcu::PixelBufferAccess&	dst,
528													 const ImageParms&				imageParms)
529{
530	const DeviceInterface&		vk					= m_context.getDeviceInterface();
531	const VkDevice				device				= m_context.getDevice();
532	const VkQueue				queue				= m_context.getUniversalQueue();
533	Allocator&					allocator			= m_context.getDefaultAllocator();
534
535	Move<VkBuffer>				buffer;
536	de::MovePtr<Allocation>		bufferAlloc;
537	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
538	const VkDeviceSize			pixelDataSize		= calculateSize(dst);
539	const VkExtent3D			imageExtent			= getExtent3D(imageParms);
540
541	// Create destination buffer
542	{
543		const VkBufferCreateInfo			bufferParams			=
544		{
545			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
546			DE_NULL,									// const void*			pNext;
547			0u,											// VkBufferCreateFlags	flags;
548			pixelDataSize,								// VkDeviceSize			size;
549			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
550			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
551			1u,											// deUint32				queueFamilyIndexCount;
552			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
553		};
554
555		buffer		= createBuffer(vk, device, &bufferParams);
556		bufferAlloc	= allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
557		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
558
559		deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
560		flushMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
561	}
562
563	// Barriers for copying image to buffer
564	const VkImageAspectFlags				formatAspect			= getAspectFlags(mapVkFormat(imageParms.format));
565	const VkImageMemoryBarrier				imageBarrier			=
566	{
567		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
568		DE_NULL,									// const void*				pNext;
569		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
570		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
571		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
572		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
573		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
574		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
575		image,										// VkImage					image;
576		{											// VkImageSubresourceRange	subresourceRange;
577			formatAspect,			// VkImageAspectFlags	aspectMask;
578			0u,						// deUint32				baseMipLevel;
579			1u,						// deUint32				mipLevels;
580			0u,						// deUint32				baseArraySlice;
581			getArraySize(imageParms)// deUint32				arraySize;
582		}
583	};
584
585	const VkBufferMemoryBarrier				bufferBarrier			=
586	{
587		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
588		DE_NULL,									// const void*		pNext;
589		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
590		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
591		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
592		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
593		*buffer,									// VkBuffer			buffer;
594		0u,											// VkDeviceSize		offset;
595		pixelDataSize								// VkDeviceSize		size;
596	};
597
598	const VkImageMemoryBarrier				postImageBarrier		=
599	{
600		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
601		DE_NULL,									// const void*				pNext;
602		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
603		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
604		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			oldLayout;
605		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
606		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
607		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
608		image,										// VkImage					image;
609		{
610			formatAspect,								// VkImageAspectFlags	aspectMask;
611			0u,											// deUint32				baseMipLevel;
612			1u,											// deUint32				mipLevels;
613			0u,											// deUint32				baseArraySlice;
614			getArraySize(imageParms)					// deUint32				arraySize;
615		}											// VkImageSubresourceRange	subresourceRange;
616	};
617
618	// Copy image to buffer
619	const VkImageAspectFlags	aspect			= getAspectFlags(dst.getFormat());
620	const VkBufferImageCopy		copyRegion		=
621	{
622		0u,									// VkDeviceSize				bufferOffset;
623		(deUint32)dst.getWidth(),			// deUint32					bufferRowLength;
624		(deUint32)dst.getHeight(),			// deUint32					bufferImageHeight;
625		{
626			aspect,								// VkImageAspectFlags		aspect;
627			0u,									// deUint32					mipLevel;
628			0u,									// deUint32					baseArrayLayer;
629			getArraySize(imageParms),			// deUint32					layerCount;
630		},									// VkImageSubresourceLayers	imageSubresource;
631		{ 0, 0, 0 },						// VkOffset3D				imageOffset;
632		imageExtent							// VkExtent3D				imageExtent;
633	};
634
635	const VkCommandBufferBeginInfo			cmdBufferBeginInfo		=
636	{
637		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
638		DE_NULL,												// const void*						pNext;
639		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
640		(const VkCommandBufferInheritanceInfo*)DE_NULL,
641	};
642
643	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
644	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
645	vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
646	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT|VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &postImageBarrier);
647	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
648
649	submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
650
651	// Read buffer data
652	invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
653	tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
654}
655
656void CopiesAndBlittingTestInstance::submitCommandsAndWait (const DeviceInterface& vk, const VkDevice device, const VkQueue queue, const VkCommandBuffer& cmdBuffer)
657{
658	const VkSubmitInfo						submitInfo				=
659	{
660		VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
661		DE_NULL,						// const void*				pNext;
662		0u,								// deUint32					waitSemaphoreCount;
663		DE_NULL,						// const VkSemaphore*		pWaitSemaphores;
664		(const VkPipelineStageFlags*)DE_NULL,
665		1u,								// deUint32					commandBufferCount;
666		&cmdBuffer,						// const VkCommandBuffer*	pCommandBuffers;
667		0u,								// deUint32					signalSemaphoreCount;
668		DE_NULL							// const VkSemaphore*		pSignalSemaphores;
669	};
670
671	VK_CHECK(vk.resetFences(device, 1, &m_fence.get()));
672	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
673	VK_CHECK(vk.waitForFences(device, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
674}
675
676de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage	(vk::VkImage		image,
677																		 const ImageParms&	parms)
678{
679	const tcu::TextureFormat		imageFormat	= mapVkFormat(parms.format);
680	de::MovePtr<tcu::TextureLevel>	resultLevel	(new tcu::TextureLevel(imageFormat, parms.extent.width, parms.extent.height, parms.extent.depth));
681
682	if (tcu::isCombinedDepthStencilType(imageFormat.type))
683	{
684		if (tcu::hasDepthComponent(imageFormat.order))
685		{
686			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width, parms.extent.height, parms.extent.depth);
687			readImageAspect(image, depthTexture.getAccess(), parms);
688			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
689		}
690
691		if (tcu::hasStencilComponent(imageFormat.order))
692		{
693			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width, parms.extent.height, parms.extent.depth);
694			readImageAspect(image, stencilTexture.getAccess(), parms);
695			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
696		}
697	}
698	else
699		readImageAspect(image, resultLevel->getAccess(), parms);
700
701	return resultLevel;
702}
703
704// Copy from image to image.
705
706class CopyImageToImage : public CopiesAndBlittingTestInstance
707{
708public:
709										CopyImageToImage			(Context&	context,
710																	 TestParams params);
711	virtual tcu::TestStatus				iterate						(void);
712
713protected:
714	virtual tcu::TestStatus				checkTestResult				(tcu::ConstPixelBufferAccess result);
715
716private:
717	Move<VkImage>						m_source;
718	de::MovePtr<Allocation>				m_sourceImageAlloc;
719	Move<VkImage>						m_destination;
720	de::MovePtr<Allocation>				m_destinationImageAlloc;
721
722	virtual void						copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
723};
724
725CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
726	: CopiesAndBlittingTestInstance(context, params)
727{
728	const DeviceInterface&		vk					= context.getDeviceInterface();
729	const VkDevice				vkDevice			= context.getDevice();
730	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
731	Allocator&					memAlloc			= context.getDefaultAllocator();
732
733	if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
734		(m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
735	{
736		if (std::find(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_maintenance1") == context.getDeviceExtensions().end())
737			TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
738	}
739
740	VkImageFormatProperties properties;
741	if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
742																				m_params.src.image.format,
743																				m_params.src.image.imageType,
744																				VK_IMAGE_TILING_OPTIMAL,
745																				VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
746																				0,
747																				&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
748		(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
749																				m_params.dst.image.format,
750																				m_params.dst.image.imageType,
751																				VK_IMAGE_TILING_OPTIMAL,
752																				VK_IMAGE_USAGE_TRANSFER_DST_BIT,
753																				0,
754																				&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
755	{
756		TCU_THROW(NotSupportedError, "Format not supported");
757	}
758
759	// Create source image
760	{
761		const VkImageCreateInfo	sourceImageParams		=
762		{
763			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
764			DE_NULL,								// const void*			pNext;
765			0u,										// VkImageCreateFlags	flags;
766			m_params.src.image.imageType,			// VkImageType			imageType;
767			m_params.src.image.format,				// VkFormat				format;
768			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
769			1u,										// deUint32				mipLevels;
770			getArraySize(m_params.src.image),		// deUint32				arraySize;
771			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
772			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
773			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
774				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
775			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
776			1u,										// deUint32				queueFamilyCount;
777			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
778			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
779		};
780
781		m_source				= createImage(vk, vkDevice, &sourceImageParams);
782		m_sourceImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
783		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
784	}
785
786	// Create destination image
787	{
788		const VkImageCreateInfo	destinationImageParams	=
789		{
790			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
791			DE_NULL,								// const void*			pNext;
792			0u,										// VkImageCreateFlags	flags;
793			m_params.dst.image.imageType,			// VkImageType			imageType;
794			m_params.dst.image.format,				// VkFormat				format;
795			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
796			1u,										// deUint32				mipLevels;
797			getArraySize(m_params.dst.image),		// deUint32				arraySize;
798			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
799			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
800			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
801				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
802			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
803			1u,										// deUint32				queueFamilyCount;
804			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
805			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
806		};
807
808		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
809		m_destinationImageAlloc	= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
810		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
811	}
812}
813
814tcu::TestStatus CopyImageToImage::iterate (void)
815{
816	const tcu::TextureFormat	srcTcuFormat		= mapVkFormat(m_params.src.image.format);
817	const tcu::TextureFormat	dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
818	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
819																				(int)m_params.src.image.extent.width,
820																				(int)m_params.src.image.extent.height,
821																				(int)m_params.src.image.extent.depth));
822	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_RED);
823	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
824																				(int)m_params.dst.image.extent.width,
825																				(int)m_params.dst.image.extent.height,
826																				(int)m_params.dst.image.extent.depth));
827	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_GRADIENT);
828	generateExpectedResult();
829
830	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
831	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
832
833	const DeviceInterface&		vk					= m_context.getDeviceInterface();
834	const VkDevice				vkDevice			= m_context.getDevice();
835	const VkQueue				queue				= m_context.getUniversalQueue();
836
837	std::vector<VkImageCopy>	imageCopies;
838	for (deUint32 i = 0; i < m_params.regions.size(); i++)
839		imageCopies.push_back(m_params.regions[i].imageCopy);
840
841	const VkImageMemoryBarrier	imageBarriers[]		=
842	{
843		// source image
844		{
845			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
846			DE_NULL,									// const void*				pNext;
847			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
848			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
849			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
850			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
851			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
852			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
853			m_source.get(),								// VkImage					image;
854			{											// VkImageSubresourceRange	subresourceRange;
855				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
856				0u,								// deUint32				baseMipLevel;
857				1u,								// deUint32				mipLevels;
858				0u,								// deUint32				baseArraySlice;
859				getArraySize(m_params.src.image)// deUint32				arraySize;
860			}
861		},
862		// destination image
863		{
864			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
865			DE_NULL,									// const void*				pNext;
866			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
867			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
868			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
869			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
870			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
871			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
872			m_destination.get(),						// VkImage					image;
873			{											// VkImageSubresourceRange	subresourceRange;
874				getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
875				0u,								// deUint32				baseMipLevel;
876				1u,								// deUint32				mipLevels;
877				0u,								// deUint32				baseArraySlice;
878				getArraySize(m_params.dst.image)// deUint32				arraySize;
879			}
880		},
881	};
882
883	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
884	{
885		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
886		DE_NULL,												// const void*						pNext;
887		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
888		(const VkCommandBufferInheritanceInfo*)DE_NULL,
889	};
890
891	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
892	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
893	vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), imageCopies.data());
894	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
895
896	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
897
898	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);
899
900	return checkTestResult(resultTextureLevel->getAccess());
901}
902
903tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
904{
905	const tcu::Vec4	fThreshold (0.0f);
906	const tcu::UVec4 uThreshold (0u);
907
908	if (tcu::isCombinedDepthStencilType(result.getFormat().type))
909	{
910		if (tcu::hasDepthComponent(result.getFormat().order))
911		{
912			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
913			const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
914			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
915
916			if (isFloatFormat(result.getFormat()))
917			{
918				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
919					return tcu::TestStatus::fail("CopiesAndBlitting test");
920			}
921			else
922			{
923				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
924					return tcu::TestStatus::fail("CopiesAndBlitting test");
925			}
926		}
927
928		if (tcu::hasStencilComponent(result.getFormat().order))
929		{
930			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
931			const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
932			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
933
934			if (isFloatFormat(result.getFormat()))
935			{
936				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
937					return tcu::TestStatus::fail("CopiesAndBlitting test");
938			}
939			else
940			{
941				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
942					return tcu::TestStatus::fail("CopiesAndBlitting test");
943			}
944		}
945	}
946	else
947	{
948		if (isFloatFormat(result.getFormat()))
949		{
950			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", m_expectedTextureLevel->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
951				return tcu::TestStatus::fail("CopiesAndBlitting test");
952		}
953		else
954		{
955			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", m_expectedTextureLevel->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
956				return tcu::TestStatus::fail("CopiesAndBlitting test");
957		}
958	}
959
960	return tcu::TestStatus::pass("CopiesAndBlitting test");
961}
962
963void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
964{
965	VkOffset3D	srcOffset	= region.imageCopy.srcOffset;
966	VkOffset3D	dstOffset	= region.imageCopy.dstOffset;
967	VkExtent3D	extent		= region.imageCopy.extent;
968
969	if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
970		dstOffset.z = srcOffset.z;
971	if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
972	{
973		srcOffset.z = dstOffset.z;
974		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
975	}
976
977
978	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
979	{
980		DE_ASSERT(src.getFormat() == dst.getFormat());
981
982		// Copy depth.
983		if (tcu::hasDepthComponent(src.getFormat().order))
984		{
985			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
986			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
987			tcu::copy(dstSubRegion, srcSubRegion);
988		}
989
990		// Copy stencil.
991		if (tcu::hasStencilComponent(src.getFormat().order))
992		{
993			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
994			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
995			tcu::copy(dstSubRegion, srcSubRegion);
996		}
997	}
998	else
999	{
1000		const tcu::ConstPixelBufferAccess	srcSubRegion		= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1001		// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1002		const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1003		const tcu::PixelBufferAccess		dstSubRegion		= tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1004
1005		tcu::copy(dstSubRegion, srcSubRegion);
1006	}
1007}
1008
1009class CopyImageToImageTestCase : public vkt::TestCase
1010{
1011public:
1012							CopyImageToImageTestCase	(tcu::TestContext&				testCtx,
1013														 const std::string&				name,
1014														 const std::string&				description,
1015														 const TestParams				params)
1016								: vkt::TestCase	(testCtx, name, description)
1017								, m_params		(params)
1018							{}
1019
1020	virtual TestInstance*	createInstance				(Context&						context) const
1021							{
1022								return new CopyImageToImage(context, m_params);
1023							}
1024private:
1025	TestParams				m_params;
1026};
1027
1028// Copy from buffer to buffer.
1029
1030class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
1031{
1032public:
1033								CopyBufferToBuffer			(Context& context, TestParams params);
1034	virtual tcu::TestStatus		iterate						(void);
1035private:
1036	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion);
1037	Move<VkBuffer>				m_source;
1038	de::MovePtr<Allocation>		m_sourceBufferAlloc;
1039	Move<VkBuffer>				m_destination;
1040	de::MovePtr<Allocation>		m_destinationBufferAlloc;
1041};
1042
1043CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
1044	: CopiesAndBlittingTestInstance	(context, params)
1045{
1046	const DeviceInterface&		vk					= context.getDeviceInterface();
1047	const VkDevice				vkDevice			= context.getDevice();
1048	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
1049	Allocator&					memAlloc			= context.getDefaultAllocator();
1050
1051	// Create source buffer
1052	{
1053		const VkBufferCreateInfo	sourceBufferParams		=
1054		{
1055			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1056			DE_NULL,									// const void*			pNext;
1057			0u,											// VkBufferCreateFlags	flags;
1058			m_params.src.buffer.size,					// VkDeviceSize			size;
1059			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
1060			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1061			1u,											// deUint32				queueFamilyIndexCount;
1062			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1063		};
1064
1065		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
1066		m_sourceBufferAlloc		= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible);
1067		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1068	}
1069
1070	// Create destination buffer
1071	{
1072		const VkBufferCreateInfo	destinationBufferParams	=
1073		{
1074			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1075			DE_NULL,									// const void*			pNext;
1076			0u,											// VkBufferCreateFlags	flags;
1077			m_params.dst.buffer.size,					// VkDeviceSize			size;
1078			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
1079			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1080			1u,											// deUint32				queueFamilyIndexCount;
1081			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1082		};
1083
1084		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
1085		m_destinationBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible);
1086		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1087	}
1088}
1089
1090tcu::TestStatus CopyBufferToBuffer::iterate (void)
1091{
1092	const int srcLevelWidth		= (int)(m_params.src.buffer.size/4); // Here the format is VK_FORMAT_R32_UINT, we need to divide the buffer size by 4
1093	m_sourceTextureLevel		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
1094	generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
1095
1096	const int dstLevelWidth		= (int)(m_params.dst.buffer.size/4);
1097	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
1098	generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_WHITE);
1099
1100	generateExpectedResult();
1101
1102	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
1103	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
1104
1105	const DeviceInterface&		vk			= m_context.getDeviceInterface();
1106	const VkDevice				vkDevice	= m_context.getDevice();
1107	const VkQueue				queue		= m_context.getUniversalQueue();
1108
1109	const VkBufferMemoryBarrier		srcBufferBarrier	=
1110	{
1111		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
1112		DE_NULL,									// const void*		pNext;
1113		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
1114		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
1115		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
1116		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
1117		*m_source,									// VkBuffer			buffer;
1118		0u,											// VkDeviceSize		offset;
1119		m_params.src.buffer.size					// VkDeviceSize		size;
1120	};
1121
1122	const VkBufferMemoryBarrier		dstBufferBarrier	=
1123	{
1124		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
1125		DE_NULL,									// const void*		pNext;
1126		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
1127		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
1128		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
1129		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
1130		*m_destination,								// VkBuffer			buffer;
1131		0u,											// VkDeviceSize		offset;
1132		m_params.dst.buffer.size					// VkDeviceSize		size;
1133	};
1134
1135	std::vector<VkBufferCopy>		bufferCopies;
1136	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1137		bufferCopies.push_back(m_params.regions[i].bufferCopy);
1138
1139	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
1140	{
1141		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
1142		DE_NULL,												// const void*						pNext;
1143		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
1144		(const VkCommandBufferInheritanceInfo*)DE_NULL,
1145	};
1146
1147	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1148	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1149	vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
1150	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1151	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1152	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
1153
1154
1155
1156	// Read buffer data
1157	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
1158	invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_params.dst.buffer.size);
1159	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1160
1161	return checkTestResult(resultLevel->getAccess());
1162}
1163
1164void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1165{
1166	deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
1167			 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
1168			 (size_t)region.bufferCopy.size);
1169}
1170
1171class BufferToBufferTestCase : public vkt::TestCase
1172{
1173public:
1174							BufferToBufferTestCase	(tcu::TestContext&	testCtx,
1175													 const std::string&	name,
1176													 const std::string&	description,
1177													 const TestParams	params)
1178								: vkt::TestCase	(testCtx, name, description)
1179								, m_params		(params)
1180							{}
1181
1182	virtual TestInstance*	createInstance			(Context& context) const
1183							{
1184								return new CopyBufferToBuffer(context, m_params);
1185							}
1186private:
1187	TestParams				m_params;
1188};
1189
1190// Copy from image to buffer.
1191
1192class CopyImageToBuffer : public CopiesAndBlittingTestInstance
1193{
1194public:
1195								CopyImageToBuffer			(Context&	context,
1196															 TestParams	testParams);
1197	virtual tcu::TestStatus		iterate						(void);
1198private:
1199	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1200
1201	tcu::TextureFormat			m_textureFormat;
1202	VkDeviceSize				m_bufferSize;
1203
1204	Move<VkImage>				m_source;
1205	de::MovePtr<Allocation>		m_sourceImageAlloc;
1206	Move<VkBuffer>				m_destination;
1207	de::MovePtr<Allocation>		m_destinationBufferAlloc;
1208};
1209
1210CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
1211	: CopiesAndBlittingTestInstance(context, testParams)
1212	, m_textureFormat(mapVkFormat(testParams.src.image.format))
1213	, m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
1214{
1215	const DeviceInterface&		vk					= context.getDeviceInterface();
1216	const VkDevice				vkDevice			= context.getDevice();
1217	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
1218	Allocator&					memAlloc			= context.getDefaultAllocator();
1219
1220	// Create source image
1221	{
1222		const VkImageCreateInfo		sourceImageParams		=
1223		{
1224			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1225			DE_NULL,								// const void*			pNext;
1226			0u,										// VkImageCreateFlags	flags;
1227			m_params.src.image.imageType,			// VkImageType			imageType;
1228			m_params.src.image.format,				// VkFormat				format;
1229			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
1230			1u,										// deUint32				mipLevels;
1231			getArraySize(m_params.src.image),		// deUint32				arraySize;
1232			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1233			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1234			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1235				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1236			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1237			1u,										// deUint32				queueFamilyCount;
1238			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1239			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1240		};
1241
1242		m_source			= createImage(vk, vkDevice, &sourceImageParams);
1243		m_sourceImageAlloc	= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
1244		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1245	}
1246
1247	// Create destination buffer
1248	{
1249		const VkBufferCreateInfo	destinationBufferParams	=
1250		{
1251			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1252			DE_NULL,									// const void*			pNext;
1253			0u,											// VkBufferCreateFlags	flags;
1254			m_bufferSize,								// VkDeviceSize			size;
1255			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
1256			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1257			1u,											// deUint32				queueFamilyIndexCount;
1258			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1259		};
1260
1261		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
1262		m_destinationBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible);
1263		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1264	}
1265}
1266
1267tcu::TestStatus CopyImageToBuffer::iterate (void)
1268{
1269	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1270																				m_params.src.image.extent.width,
1271																				m_params.src.image.extent.height,
1272																				m_params.src.image.extent.depth));
1273	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
1274	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1275	generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
1276
1277	generateExpectedResult();
1278
1279	uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
1280	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
1281
1282	const DeviceInterface&		vk			= m_context.getDeviceInterface();
1283	const VkDevice				vkDevice	= m_context.getDevice();
1284	const VkQueue				queue		= m_context.getUniversalQueue();
1285
1286	// Barriers for copying image to buffer
1287	const VkImageMemoryBarrier		imageBarrier		=
1288	{
1289		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1290		DE_NULL,									// const void*				pNext;
1291		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1292		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
1293		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1294		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
1295		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1296		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1297		*m_source,									// VkImage					image;
1298		{											// VkImageSubresourceRange	subresourceRange;
1299			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
1300			0u,								// deUint32				baseMipLevel;
1301			1u,								// deUint32				mipLevels;
1302			0u,								// deUint32				baseArraySlice;
1303			1u								// deUint32				arraySize;
1304		}
1305	};
1306
1307	const VkBufferMemoryBarrier		bufferBarrier		=
1308	{
1309		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
1310		DE_NULL,									// const void*		pNext;
1311		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
1312		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
1313		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
1314		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
1315		*m_destination,								// VkBuffer			buffer;
1316		0u,											// VkDeviceSize		offset;
1317		m_bufferSize								// VkDeviceSize		size;
1318	};
1319
1320	// Copy from image to buffer
1321	std::vector<VkBufferImageCopy>	bufferImageCopies;
1322	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1323		bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
1324
1325	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
1326	{
1327		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
1328		DE_NULL,												// const void*						pNext;
1329		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
1330		(const VkCommandBufferInheritanceInfo*)DE_NULL,
1331	};
1332
1333	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1334	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
1335	vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
1336	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1337	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1338
1339	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1340
1341	// Read buffer data
1342	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1343	invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_bufferSize);
1344	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1345
1346	return checkTestResult(resultLevel->getAccess());
1347}
1348
1349class CopyImageToBufferTestCase : public vkt::TestCase
1350{
1351public:
1352							CopyImageToBufferTestCase	(tcu::TestContext&		testCtx,
1353														 const std::string&		name,
1354														 const std::string&		description,
1355														 const TestParams		params)
1356								: vkt::TestCase	(testCtx, name, description)
1357								, m_params		(params)
1358							{}
1359
1360	virtual TestInstance*	createInstance				(Context&				context) const
1361							{
1362								return new CopyImageToBuffer(context, m_params);
1363							}
1364private:
1365	TestParams				m_params;
1366};
1367
1368void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1369{
1370	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
1371	if (!rowLength)
1372		rowLength = region.bufferImageCopy.imageExtent.width;
1373
1374	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
1375	if (!imageHeight)
1376		imageHeight = region.bufferImageCopy.imageExtent.height;
1377
1378	const int			texelSize	= src.getFormat().getPixelSize();
1379	const VkExtent3D	extent		= region.bufferImageCopy.imageExtent;
1380	const VkOffset3D	srcOffset	= region.bufferImageCopy.imageOffset;
1381	const int			texelOffset	= (int) region.bufferImageCopy.bufferOffset / texelSize;
1382
1383	for (deUint32 z = 0; z < extent.depth; z++)
1384	{
1385		for (deUint32 y = 0; y < extent.height; y++)
1386		{
1387			int									texelIndex		= texelOffset + (z * imageHeight + y) *	rowLength;
1388			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z,
1389																					region.bufferImageCopy.imageExtent.width, 1, 1);
1390			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1391			tcu::copy(dstSubRegion, srcSubRegion);
1392		}
1393	}
1394}
1395
1396// Copy from buffer to image.
1397
1398class CopyBufferToImage : public CopiesAndBlittingTestInstance
1399{
1400public:
1401								CopyBufferToImage			(Context&	context,
1402															 TestParams	testParams);
1403	virtual tcu::TestStatus		iterate						(void);
1404private:
1405	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1406
1407	tcu::TextureFormat			m_textureFormat;
1408	VkDeviceSize				m_bufferSize;
1409
1410	Move<VkBuffer>				m_source;
1411	de::MovePtr<Allocation>		m_sourceBufferAlloc;
1412	Move<VkImage>				m_destination;
1413	de::MovePtr<Allocation>		m_destinationImageAlloc;
1414};
1415
1416CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
1417	: CopiesAndBlittingTestInstance(context, testParams)
1418	, m_textureFormat(mapVkFormat(testParams.dst.image.format))
1419	, m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
1420{
1421	const DeviceInterface&		vk					= context.getDeviceInterface();
1422	const VkDevice				vkDevice			= context.getDevice();
1423	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
1424	Allocator&					memAlloc			= context.getDefaultAllocator();
1425
1426	// Create source buffer
1427	{
1428		const VkBufferCreateInfo	sourceBufferParams		=
1429		{
1430			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1431			DE_NULL,									// const void*			pNext;
1432			0u,											// VkBufferCreateFlags	flags;
1433			m_bufferSize,								// VkDeviceSize			size;
1434			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
1435			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1436			1u,											// deUint32				queueFamilyIndexCount;
1437			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1438		};
1439
1440		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
1441		m_sourceBufferAlloc		= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible);
1442		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1443	}
1444
1445	// Create destination image
1446	{
1447		const VkImageCreateInfo		destinationImageParams	=
1448		{
1449			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1450			DE_NULL,								// const void*			pNext;
1451			0u,										// VkImageCreateFlags	flags;
1452			m_params.dst.image.imageType,			// VkImageType			imageType;
1453			m_params.dst.image.format,				// VkFormat				format;
1454			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
1455			1u,										// deUint32				mipLevels;
1456			getArraySize(m_params.dst.image),		// deUint32				arraySize;
1457			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1458			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1459			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1460				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1461			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1462			1u,										// deUint32				queueFamilyCount;
1463			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1464			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1465		};
1466
1467		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
1468		m_destinationImageAlloc	= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
1469		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1470	}
1471}
1472
1473tcu::TestStatus CopyBufferToImage::iterate (void)
1474{
1475	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
1476	generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
1477	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1478																					m_params.dst.image.extent.width,
1479																					m_params.dst.image.extent.height,
1480																					m_params.dst.image.extent.depth));
1481
1482	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
1483
1484	generateExpectedResult();
1485
1486	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
1487	uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
1488
1489	const DeviceInterface&		vk			= m_context.getDeviceInterface();
1490	const VkDevice				vkDevice	= m_context.getDevice();
1491	const VkQueue				queue		= m_context.getUniversalQueue();
1492
1493	const VkImageMemoryBarrier	imageBarrier	=
1494	{
1495		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1496		DE_NULL,									// const void*				pNext;
1497		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1498		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
1499		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1500		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
1501		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1502		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1503		*m_destination,								// VkImage					image;
1504		{											// VkImageSubresourceRange	subresourceRange;
1505			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
1506			0u,								// deUint32				baseMipLevel;
1507			1u,								// deUint32				mipLevels;
1508			0u,								// deUint32				baseArraySlice;
1509			1u								// deUint32				arraySize;
1510		}
1511	};
1512
1513	// Copy from buffer to image
1514	std::vector<VkBufferImageCopy>		bufferImageCopies;
1515	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1516		bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
1517
1518	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
1519	{
1520		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
1521		DE_NULL,												// const void*						pNext;
1522		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
1523		(const VkCommandBufferInheritanceInfo*)DE_NULL,
1524	};
1525
1526	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1527	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
1528	vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
1529	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1530
1531	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1532
1533	de::MovePtr<tcu::TextureLevel>	resultLevel	= readImage(*m_destination, m_params.dst.image);
1534
1535	return checkTestResult(resultLevel->getAccess());
1536}
1537
1538class CopyBufferToImageTestCase : public vkt::TestCase
1539{
1540public:
1541							CopyBufferToImageTestCase	(tcu::TestContext&		testCtx,
1542														 const std::string&		name,
1543														 const std::string&		description,
1544														 const TestParams		params)
1545								: vkt::TestCase	(testCtx, name, description)
1546								, m_params		(params)
1547							{}
1548
1549	virtual					~CopyBufferToImageTestCase	(void) {}
1550
1551	virtual TestInstance*	createInstance				(Context&				context) const
1552							{
1553								return new CopyBufferToImage(context, m_params);
1554							}
1555private:
1556	TestParams				m_params;
1557};
1558
1559void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1560{
1561	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
1562	if (!rowLength)
1563		rowLength = region.bufferImageCopy.imageExtent.width;
1564
1565	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
1566	if (!imageHeight)
1567		imageHeight = region.bufferImageCopy.imageExtent.height;
1568
1569	const int			texelSize	= dst.getFormat().getPixelSize();
1570	const VkExtent3D	extent		= region.bufferImageCopy.imageExtent;
1571	const VkOffset3D	dstOffset	= region.bufferImageCopy.imageOffset;
1572	const int			texelOffset	= (int) region.bufferImageCopy.bufferOffset / texelSize;
1573
1574	for (deUint32 z = 0; z < extent.depth; z++)
1575	{
1576		for (deUint32 y = 0; y < extent.height; y++)
1577		{
1578			int									texelIndex		= texelOffset + (z * imageHeight + y) *	rowLength;
1579			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1580			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
1581																					region.bufferImageCopy.imageExtent.width, 1, 1);
1582			tcu::copy(dstSubRegion, srcSubRegion);
1583		}
1584	}
1585}
1586
1587// Copy from image to image with scaling.
1588
1589class BlittingImages : public CopiesAndBlittingTestInstance
1590{
1591public:
1592										BlittingImages					(Context&	context,
1593																		 TestParams params);
1594	virtual tcu::TestStatus				iterate							(void);
1595protected:
1596	virtual tcu::TestStatus				checkTestResult					(tcu::ConstPixelBufferAccess result);
1597	virtual void						copyRegionToTextureLevel		(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1598	virtual void						generateExpectedResult			(void);
1599private:
1600	bool								checkClampedAndUnclampedResult	(const tcu::ConstPixelBufferAccess&	result,
1601																		 const tcu::ConstPixelBufferAccess&	clampedReference,
1602																		 const tcu::ConstPixelBufferAccess&	unclampedReference,
1603																		 VkImageAspectFlagBits				aspect);
1604	Move<VkImage>						m_source;
1605	de::MovePtr<Allocation>				m_sourceImageAlloc;
1606	Move<VkImage>						m_destination;
1607	de::MovePtr<Allocation>				m_destinationImageAlloc;
1608
1609	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel;
1610};
1611
1612BlittingImages::BlittingImages (Context& context, TestParams params)
1613	: CopiesAndBlittingTestInstance(context, params)
1614{
1615	const DeviceInterface&		vk					= context.getDeviceInterface();
1616	const VkDevice				vkDevice			= context.getDevice();
1617	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
1618	Allocator&					memAlloc			= context.getDefaultAllocator();
1619
1620	VkImageFormatProperties properties;
1621	if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1622																				m_params.src.image.format,
1623																				VK_IMAGE_TYPE_2D,
1624																				VK_IMAGE_TILING_OPTIMAL,
1625																				VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1626																				0,
1627																				&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1628		(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1629																				m_params.dst.image.format,
1630																				VK_IMAGE_TYPE_2D,
1631																				VK_IMAGE_TILING_OPTIMAL,
1632																				VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1633																				0,
1634																				&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1635	{
1636		TCU_THROW(NotSupportedError, "Format not supported");
1637	}
1638
1639	VkFormatProperties srcFormatProperties;
1640	context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
1641	if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
1642	{
1643		TCU_THROW(NotSupportedError, "Format feature blit source not supported");
1644	}
1645
1646	VkFormatProperties dstFormatProperties;
1647	context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
1648	if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
1649	{
1650		TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
1651	}
1652
1653	if (m_params.filter == VK_FILTER_LINEAR)
1654	{
1655		if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
1656			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
1657		if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
1658			TCU_THROW(NotSupportedError, "Destination format feature sampled image filter linear not supported");
1659	}
1660
1661	// Create source image
1662	{
1663		const VkImageCreateInfo		sourceImageParams		=
1664		{
1665			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1666			DE_NULL,								// const void*			pNext;
1667			0u,										// VkImageCreateFlags	flags;
1668			m_params.src.image.imageType,			// VkImageType			imageType;
1669			m_params.src.image.format,				// VkFormat				format;
1670			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
1671			1u,										// deUint32				mipLevels;
1672			getArraySize(m_params.src.image),		// deUint32				arraySize;
1673			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1674			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1675			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1676				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1677			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1678			1u,										// deUint32				queueFamilyCount;
1679			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1680			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1681		};
1682
1683		m_source = createImage(vk, vkDevice, &sourceImageParams);
1684		m_sourceImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
1685		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1686	}
1687
1688	// Create destination image
1689	{
1690		const VkImageCreateInfo		destinationImageParams	=
1691		{
1692			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1693			DE_NULL,								// const void*			pNext;
1694			0u,										// VkImageCreateFlags	flags;
1695			m_params.dst.image.imageType,			// VkImageType			imageType;
1696			m_params.dst.image.format,				// VkFormat				format;
1697			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
1698			1u,										// deUint32				mipLevels;
1699			getArraySize(m_params.dst.image),		// deUint32				arraySize;
1700			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1701			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1702			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1703				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1704			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1705			1u,										// deUint32				queueFamilyCount;
1706			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1707			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1708		};
1709
1710		m_destination = createImage(vk, vkDevice, &destinationImageParams);
1711		m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
1712		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1713	}
1714}
1715
1716tcu::TestStatus BlittingImages::iterate (void)
1717{
1718	const tcu::TextureFormat	srcTcuFormat		= mapVkFormat(m_params.src.image.format);
1719	const tcu::TextureFormat	dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
1720	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1721																				m_params.src.image.extent.width,
1722																				m_params.src.image.extent.height,
1723																				m_params.src.image.extent.depth));
1724	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_GRADIENT);
1725	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1726																					 (int)m_params.dst.image.extent.width,
1727																					 (int)m_params.dst.image.extent.height,
1728																					 (int)m_params.dst.image.extent.depth));
1729	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_WHITE);
1730	generateExpectedResult();
1731
1732	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1733	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1734
1735	const DeviceInterface&		vk					= m_context.getDeviceInterface();
1736	const VkDevice				vkDevice			= m_context.getDevice();
1737	const VkQueue				queue				= m_context.getUniversalQueue();
1738
1739	std::vector<VkImageBlit>	regions;
1740	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1741		regions.push_back(m_params.regions[i].imageBlit);
1742
1743	// Barriers for copying image to buffer
1744	const VkImageMemoryBarrier		srcImageBarrier		=
1745	{
1746		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1747		DE_NULL,									// const void*				pNext;
1748		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1749		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
1750		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1751		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
1752		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1753		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1754		m_source.get(),								// VkImage					image;
1755		{											// VkImageSubresourceRange	subresourceRange;
1756			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
1757			0u,								// deUint32				baseMipLevel;
1758			1u,								// deUint32				mipLevels;
1759			0u,								// deUint32				baseArraySlice;
1760			1u								// deUint32				arraySize;
1761		}
1762	};
1763
1764	const VkImageMemoryBarrier		dstImageBarrier		=
1765	{
1766		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1767		DE_NULL,									// const void*				pNext;
1768		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1769		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
1770		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1771		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
1772		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1773		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1774		m_destination.get(),						// VkImage					image;
1775		{											// VkImageSubresourceRange	subresourceRange;
1776			getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
1777			0u,								// deUint32				baseMipLevel;
1778			1u,								// deUint32				mipLevels;
1779			0u,								// deUint32				baseArraySlice;
1780			1u								// deUint32				arraySize;
1781		}
1782	};
1783
1784	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
1785	{
1786		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
1787		DE_NULL,												// const void*						pNext;
1788		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
1789		(const VkCommandBufferInheritanceInfo*)DE_NULL,
1790	};
1791
1792	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1793	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
1794	vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), &regions[0], m_params.filter);
1795	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
1796	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1797	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
1798
1799	de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
1800
1801	return checkTestResult(resultTextureLevel->getAccess());
1802}
1803
1804static float calculateFloatConversionError (int srcBits)
1805{
1806	if (srcBits > 0)
1807	{
1808		const int	clampedBits	= de::clamp<int>(srcBits, 0, 32);
1809		const float	srcMaxValue	= de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
1810		const float	error		= 1.0f / srcMaxValue;
1811
1812		return de::clamp<float>(error, 0.0f, 1.0f);
1813	}
1814	else
1815		return 1.0f;
1816}
1817
1818tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
1819{
1820	tcu::Vec4 threshold(0.01f);
1821
1822	switch (format.type)
1823	{
1824	case tcu::TextureFormat::HALF_FLOAT:
1825		threshold = tcu::Vec4(0.005f);
1826		break;
1827
1828	case tcu::TextureFormat::FLOAT:
1829	case tcu::TextureFormat::FLOAT64:
1830		threshold = tcu::Vec4(0.001f);
1831		break;
1832
1833	case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
1834		threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
1835		break;
1836
1837	case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
1838		threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
1839		break;
1840
1841	default:
1842		const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
1843		threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
1844				      calculateFloatConversionError(bits.y()),
1845				      calculateFloatConversionError(bits.z()),
1846				      calculateFloatConversionError(bits.w()));
1847	}
1848
1849	// Return value matching the channel order specified by the format
1850	if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
1851		return threshold.swizzle(2, 1, 0, 3);
1852	else
1853		return threshold;
1854}
1855
1856tcu::TextureFormat getFormatAspect (VkFormat format, VkImageAspectFlagBits aspect)
1857{
1858	const tcu::TextureFormat	baseFormat	= mapVkFormat(format);
1859
1860	if (isCombinedDepthStencilType(baseFormat.type))
1861	{
1862		if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT)
1863			return getEffectiveDepthStencilTextureFormat(baseFormat, tcu::Sampler::MODE_DEPTH);
1864		else if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT)
1865			return getEffectiveDepthStencilTextureFormat(baseFormat, tcu::Sampler::MODE_STENCIL);
1866		else
1867			DE_FATAL("Invalid aspect");
1868	}
1869
1870	return baseFormat;
1871}
1872
1873bool BlittingImages::checkClampedAndUnclampedResult (const tcu::ConstPixelBufferAccess&	result,
1874													 const tcu::ConstPixelBufferAccess& clampedExpected,
1875													 const tcu::ConstPixelBufferAccess& unclampedExpected,
1876													 VkImageAspectFlagBits				aspect)
1877{
1878	tcu::TestLog&				log			(m_context.getTestContext().getLog());
1879	const bool					isLinear	= m_params.filter == VK_FILTER_LINEAR;
1880	const tcu::TextureFormat	srcFormat	= getFormatAspect(m_params.src.image.format, aspect);
1881	const tcu::TextureFormat	dstFormat	= result.getFormat();
1882	bool						isOk		= false;
1883
1884	DE_ASSERT(dstFormat == getFormatAspect(m_params.dst.image.format, aspect));
1885
1886	if (isLinear)
1887		log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
1888
1889	if (isFloatFormat(dstFormat))
1890	{
1891		const bool		srcIsSRGB	= tcu::isSRGB(srcFormat);
1892		const tcu::Vec4	srcMaxDiff	= getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
1893		const tcu::Vec4	dstMaxDiff	= getFormatThreshold(dstFormat);
1894		const tcu::Vec4	threshold	= tcu::max(srcMaxDiff, dstMaxDiff);
1895
1896		isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
1897
1898		if (isLinear)
1899			log << tcu::TestLog::EndSection;
1900
1901		if (!isOk && isLinear)
1902		{
1903			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
1904			isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
1905			log << tcu::TestLog::EndSection;
1906		}
1907	}
1908	else
1909	{
1910		tcu::UVec4	threshold;
1911		// Calculate threshold depending on channel width of destination format.
1912		const tcu::IVec4	bitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
1913		for (deUint32 i = 0; i < 4; ++i)
1914			threshold[i] = de::max( (0x1 << bitDepth[i]) / 256, 1);
1915
1916		isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
1917
1918		if (isLinear)
1919			log << tcu::TestLog::EndSection;
1920
1921		if (!isOk && isLinear)
1922		{
1923			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
1924			isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
1925			log << tcu::TestLog::EndSection;
1926		}
1927	}
1928	return isOk;
1929}
1930
1931tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
1932{
1933	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR);
1934
1935	if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1936	{
1937		if (tcu::hasDepthComponent(result.getFormat().order))
1938		{
1939			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
1940			const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
1941			const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
1942			const tcu::ConstPixelBufferAccess		unclampedExpected	= m_params.filter == VK_FILTER_LINEAR ? tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode) : tcu::ConstPixelBufferAccess();
1943
1944			if (!checkClampedAndUnclampedResult(depthResult, clampedExpected, unclampedExpected, VK_IMAGE_ASPECT_DEPTH_BIT))
1945			{
1946				return tcu::TestStatus::fail("CopiesAndBlitting test");
1947			}
1948		}
1949
1950		if (tcu::hasStencilComponent(result.getFormat().order))
1951		{
1952			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
1953			const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
1954			const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel->getAccess(), mode);
1955			const tcu::ConstPixelBufferAccess		unclampedExpected	= m_params.filter == VK_FILTER_LINEAR ? tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode) : tcu::ConstPixelBufferAccess();
1956
1957			if (!checkClampedAndUnclampedResult(stencilResult, clampedExpected, unclampedExpected, VK_IMAGE_ASPECT_STENCIL_BIT))
1958			{
1959				return tcu::TestStatus::fail("CopiesAndBlitting test");
1960			}
1961		}
1962	}
1963	else
1964	{
1965		if (!checkClampedAndUnclampedResult(result, m_expectedTextureLevel->getAccess(), m_params.filter == VK_FILTER_LINEAR ? m_unclampedExpectedTextureLevel->getAccess() : tcu::ConstPixelBufferAccess(), VK_IMAGE_ASPECT_COLOR_BIT))
1966		{
1967			return tcu::TestStatus::fail("CopiesAndBlitting test");
1968		}
1969	}
1970
1971	return tcu::TestStatus::pass("CopiesAndBlitting test");
1972}
1973
1974tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
1975{
1976	return isSRGB(format) ? linearToSRGB(color) : color;
1977}
1978
1979void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter)
1980{
1981	DE_ASSERT(filter == tcu::Sampler::LINEAR);
1982	DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1);
1983
1984	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
1985					filter, filter, 0.0f, false);
1986
1987	float sX = (float)regionExtent.x / (float)dst.getWidth();
1988	float sY = (float)regionExtent.y / (float)dst.getHeight();
1989
1990	for (int y = 0; y < dst.getHeight(); y++)
1991	for (int x = 0; x < dst.getWidth(); x++)
1992		dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, (float)regionOffset.x + ((float)x+0.5f)*sX, (float)regionOffset.y + ((float)y+0.5f)*sY, 0)), x, y);
1993}
1994
1995void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
1996{
1997	DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR);
1998
1999	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
2000						 filter, filter, 0.0f, false);
2001
2002	const float sX = (float)src.getWidth() / (float)dst.getWidth();
2003	const float sY = (float)src.getHeight() / (float)dst.getHeight();
2004	const float sZ = (float)src.getDepth() / (float)dst.getDepth();
2005
2006	tcu::Mat2 rotMatrix;
2007	rotMatrix(0,0) = (mirrorMode & MIRROR_MODE_X) ? -1.0f : 1.0f;
2008	rotMatrix(0,1) = 0.0f;
2009	rotMatrix(1,0) = 0.0f;
2010	rotMatrix(1,1) = (mirrorMode & MIRROR_MODE_Y) ? -1.0f : 1.0f;
2011
2012	const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
2013	const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
2014
2015	if (dst.getDepth() == 1 && src.getDepth() == 1)
2016	{
2017		for (int y = 0; y < dst.getHeight(); ++y)
2018		for (int x = 0; x < dst.getWidth(); ++x)
2019		{
2020			const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y);
2021			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, 0)), (int)round(xy[0]) + xOffset, (int)round(xy[1]) + yOffset);
2022		}
2023	}
2024	else
2025	{
2026		for (int z = 0; z < dst.getDepth(); ++z)
2027		for (int y = 0; y < dst.getHeight(); ++y)
2028		for (int x = 0; x < dst.getWidth(); ++x)
2029		{
2030			const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y);
2031			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x+0.5f)*sX, ((float)y+0.5f)*sY, ((float)z+0.5f)*sZ)), (int)round(xy[0]) + xOffset, (int)round(xy[1]) + yOffset, z);
2032		}
2033	}
2034}
2035
2036void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
2037{
2038	const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
2039	const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
2040	const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
2041	const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
2042
2043	if (mirrorMode > MIRROR_MODE_NONE && mirrorMode < MIRROR_MODE_LAST)
2044	{
2045		//sourceRegion
2046		region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
2047		region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
2048
2049		region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
2050		region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
2051
2052		//destinationRegion
2053		region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
2054		region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
2055
2056		region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
2057		region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
2058	}
2059}
2060
2061MirrorMode getMirrorMode(const VkOffset3D x1, const VkOffset3D x2)
2062{
2063	if (x1.x >= x2.x && x1.y >= x2.y)
2064	{
2065		return MIRROR_MODE_XY;
2066	}
2067	else if (x1.x <= x2.x && x1.y <= x2.y)
2068	{
2069		return MIRROR_MODE_NONE;
2070	}
2071	else if (x1.x <= x2.x && x1.y >= x2.y)
2072	{
2073		return MIRROR_MODE_Y;
2074	}
2075	else if (x1.x >= x2.x && x1.y <= x2.y)
2076	{
2077		return MIRROR_MODE_X;
2078	}
2079	return MIRROR_MODE_LAST;
2080}
2081
2082MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
2083{
2084	const MirrorMode source		 = getMirrorMode(s1, s2);
2085	const MirrorMode destination = getMirrorMode(d1, d2);
2086
2087	if (source == destination)
2088	{
2089		return MIRROR_MODE_NONE;
2090	}
2091	else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_X)	  || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_X) ||
2092			 (source == MIRROR_MODE_Y && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_Y && source == MIRROR_MODE_NONE))
2093	{
2094		return MIRROR_MODE_Y;
2095	}
2096	else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_Y)	  || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_Y) ||
2097			 (source == MIRROR_MODE_X && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_X && source == MIRROR_MODE_NONE))
2098	{
2099		return MIRROR_MODE_X;
2100	}
2101	else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_NONE))
2102	{
2103		return MIRROR_MODE_XY;
2104	}
2105	return MIRROR_MODE_LAST;
2106}
2107
2108void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
2109{
2110	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
2111												region.imageBlit.srcOffsets[1],
2112												region.imageBlit.dstOffsets[0],
2113												region.imageBlit.dstOffsets[1]);
2114
2115	flipCoordinates(region, mirrorMode);
2116
2117	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
2118	const VkOffset3D					srcExtent		=
2119	{
2120		region.imageBlit.srcOffsets[1].x - srcOffset.x,
2121		region.imageBlit.srcOffsets[1].y - srcOffset.y,
2122		region.imageBlit.srcOffsets[1].z - srcOffset.z
2123	};
2124	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
2125	const VkOffset3D					dstExtent		=
2126	{
2127		region.imageBlit.dstOffsets[1].x - dstOffset.x,
2128		region.imageBlit.dstOffsets[1].y - dstOffset.y,
2129		region.imageBlit.dstOffsets[1].z - dstOffset.z
2130	};
2131	const tcu::Sampler::FilterMode		filter			= (m_params.filter == VK_FILTER_LINEAR) ? tcu::Sampler::LINEAR : tcu::Sampler::NEAREST;
2132
2133	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
2134	{
2135		DE_ASSERT(src.getFormat() == dst.getFormat());
2136		// Scale depth.
2137		if (tcu::hasDepthComponent(src.getFormat().order))
2138		{
2139			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
2140			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
2141			tcu::scale(dstSubRegion, srcSubRegion, filter);
2142
2143			if (filter == tcu::Sampler::LINEAR)
2144			{
2145				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
2146				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
2147				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
2148			}
2149		}
2150
2151		// Scale stencil.
2152		if (tcu::hasStencilComponent(src.getFormat().order))
2153		{
2154			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
2155			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
2156			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
2157
2158			if (filter == tcu::Sampler::LINEAR)
2159			{
2160				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
2161				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
2162				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
2163			}
2164		}
2165	}
2166	else
2167	{
2168		const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y);
2169		const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
2170		blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
2171
2172		if (filter == tcu::Sampler::LINEAR)
2173		{
2174			const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
2175			scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter);
2176		}
2177	}
2178}
2179
2180void BlittingImages::generateExpectedResult (void)
2181{
2182	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
2183	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
2184
2185	m_expectedTextureLevel			= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
2186	tcu::copy(m_expectedTextureLevel->getAccess(), dst);
2187
2188	if (m_params.filter == VK_FILTER_LINEAR)
2189	{
2190		m_unclampedExpectedTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
2191		tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
2192	}
2193
2194	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2195	{
2196		CopyRegion region = m_params.regions[i];
2197		copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), region);
2198	}
2199}
2200
2201class BlittingTestCase : public vkt::TestCase
2202{
2203public:
2204							BlittingTestCase		(tcu::TestContext&				testCtx,
2205													 const std::string&				name,
2206													 const std::string&				description,
2207													 const TestParams				params)
2208								: vkt::TestCase	(testCtx, name, description)
2209								, m_params		(params)
2210							{}
2211
2212	virtual TestInstance*	createInstance			(Context&						context) const
2213							{
2214								return new BlittingImages(context, m_params);
2215							}
2216private:
2217	TestParams				m_params;
2218};
2219
2220// Resolve image to image.
2221
2222enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE};
2223class ResolveImageToImage : public CopiesAndBlittingTestInstance
2224{
2225public:
2226												ResolveImageToImage			(Context&							context,
2227																			 TestParams							params,
2228																			 const ResolveImageToImageOptions	options);
2229	virtual tcu::TestStatus						iterate						(void);
2230protected:
2231	virtual tcu::TestStatus						checkTestResult				(tcu::ConstPixelBufferAccess result);
2232	void										copyMSImageToMSImage		(void);
2233private:
2234	Move<VkImage>								m_multisampledImage;
2235	de::MovePtr<Allocation>						m_multisampledImageAlloc;
2236
2237	Move<VkImage>								m_destination;
2238	de::MovePtr<Allocation>						m_destinationImageAlloc;
2239
2240	Move<VkImage>								m_multisampledCopyImage;
2241	de::MovePtr<Allocation>						m_multisampledCopyImageAlloc;
2242
2243	const ResolveImageToImageOptions			m_options;
2244
2245	virtual void								copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess	src,
2246																			 tcu::PixelBufferAccess			dst,
2247																			 CopyRegion						region);
2248};
2249
2250ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
2251	: CopiesAndBlittingTestInstance	(context, params)
2252	, m_options						(options)
2253{
2254	const VkSampleCountFlagBits	rasterizationSamples	= m_params.samples;
2255
2256	if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
2257		throw tcu::NotSupportedError("Unsupported number of rasterization samples");
2258
2259	const DeviceInterface&		vk						= context.getDeviceInterface();
2260	const VkDevice				vkDevice				= context.getDevice();
2261	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
2262	Allocator&					memAlloc				= m_context.getDefaultAllocator();
2263
2264	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
2265	Move<VkRenderPass>			renderPass;
2266
2267	Move<VkShaderModule>		vertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
2268	Move<VkShaderModule>		fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
2269	std::vector<tcu::Vec4>		vertices;
2270
2271	Move<VkBuffer>				vertexBuffer;
2272	de::MovePtr<Allocation>		vertexBufferAlloc;
2273
2274	Move<VkPipelineLayout>		pipelineLayout;
2275	Move<VkPipeline>			graphicsPipeline;
2276
2277	VkImageFormatProperties properties;
2278	if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
2279																				m_params.src.image.format,
2280																				m_params.src.image.imageType,
2281																				VK_IMAGE_TILING_OPTIMAL,
2282																				VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
2283																				&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
2284		(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
2285																				m_params.dst.image.format,
2286																				m_params.dst.image.imageType,
2287																				VK_IMAGE_TILING_OPTIMAL,
2288																				VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
2289																				&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
2290	{
2291		TCU_THROW(NotSupportedError, "Format not supported");
2292	}
2293
2294	// Create color image.
2295	{
2296		VkImageCreateInfo	colorImageParams	=
2297		{
2298			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
2299			DE_NULL,																// const void*				pNext;
2300			0u,																		// VkImageCreateFlags		flags;
2301			m_params.src.image.imageType,											// VkImageType				imageType;
2302			m_params.src.image.format,												// VkFormat					format;
2303			getExtent3D(m_params.src.image),										// VkExtent3D				extent;
2304			1u,																		// deUint32					mipLevels;
2305			getArraySize(m_params.src.image),										// deUint32					arrayLayers;
2306			rasterizationSamples,													// VkSampleCountFlagBits	samples;
2307			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
2308			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
2309			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
2310			1u,																		// deUint32					queueFamilyIndexCount;
2311			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
2312			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout			initialLayout;
2313		};
2314
2315		m_multisampledImage						= createImage(vk, vkDevice, &colorImageParams);
2316
2317		// Allocate and bind color image memory.
2318		m_multisampledImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_multisampledImage), MemoryRequirement::Any);
2319		VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset()));
2320
2321		switch (m_options)
2322		{
2323			case COPY_MS_IMAGE_TO_MS_IMAGE:
2324			{
2325				colorImageParams.usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2326				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
2327				// Allocate and bind color image memory.
2328				m_multisampledCopyImageAlloc	= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_multisampledCopyImage), MemoryRequirement::Any);
2329				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
2330				break;
2331			}
2332
2333			case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
2334			{
2335				colorImageParams.usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2336				colorImageParams.arrayLayers	= getArraySize(m_params.dst.image);
2337				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
2338				// Allocate and bind color image memory.
2339				m_multisampledCopyImageAlloc	= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_multisampledCopyImage), MemoryRequirement::Any);
2340				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
2341				break;
2342			}
2343
2344			default :
2345				break;
2346		}
2347	}
2348
2349	// Create destination image.
2350	{
2351		const VkImageCreateInfo	destinationImageParams	=
2352		{
2353			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
2354			DE_NULL,								// const void*			pNext;
2355			0u,										// VkImageCreateFlags	flags;
2356			m_params.dst.image.imageType,			// VkImageType			imageType;
2357			m_params.dst.image.format,				// VkFormat				format;
2358			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
2359			1u,										// deUint32				mipLevels;
2360			getArraySize(m_params.dst.image),		// deUint32				arraySize;
2361			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
2362			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
2363			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2364				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
2365			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2366			1u,										// deUint32				queueFamilyCount;
2367			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
2368			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
2369		};
2370
2371		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
2372		m_destinationImageAlloc	= memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
2373		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2374	}
2375
2376	// Barriers for copying image to buffer
2377	VkImageMemoryBarrier		srcImageBarrier		=
2378	{
2379		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2380		DE_NULL,									// const void*				pNext;
2381		0u,											// VkAccessFlags			srcAccessMask;
2382		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
2383		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
2384		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
2385		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2386		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2387		m_multisampledImage.get(),					// VkImage					image;
2388		{											// VkImageSubresourceRange	subresourceRange;
2389			VK_IMAGE_ASPECT_COLOR_BIT,			// VkImageAspectFlags	aspectMask;
2390			0u,									// deUint32				baseMipLevel;
2391			1u,									// deUint32				mipLevels;
2392			0u,									// deUint32				baseArraySlice;
2393			getArraySize(m_params.src.image)	// deUint32				arraySize;
2394		}
2395	};
2396
2397		// Create render pass.
2398	{
2399		const VkAttachmentDescription	attachmentDescriptions[1]	=
2400		{
2401			{
2402				0u,											// VkAttachmentDescriptionFlags		flags;
2403				m_params.src.image.format,					// VkFormat							format;
2404				rasterizationSamples,						// VkSampleCountFlagBits			samples;
2405				VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp				loadOp;
2406				VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp;
2407				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp;
2408				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp;
2409				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout;
2410				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout;
2411			},
2412		};
2413
2414		const VkAttachmentReference		colorAttachmentReference	=
2415		{
2416			0u,													// deUint32			attachment;
2417			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
2418		};
2419
2420		const VkSubpassDescription		subpassDescription			=
2421		{
2422			0u,									// VkSubpassDescriptionFlags	flags;
2423			VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint			pipelineBindPoint;
2424			0u,									// deUint32						inputAttachmentCount;
2425			DE_NULL,							// const VkAttachmentReference*	pInputAttachments;
2426			1u,									// deUint32						colorAttachmentCount;
2427			&colorAttachmentReference,			// const VkAttachmentReference*	pColorAttachments;
2428			DE_NULL,							// const VkAttachmentReference*	pResolveAttachments;
2429			DE_NULL,							// const VkAttachmentReference*	pDepthStencilAttachment;
2430			0u,									// deUint32						preserveAttachmentCount;
2431			DE_NULL								// const VkAttachmentReference*	pPreserveAttachments;
2432		};
2433
2434		const VkRenderPassCreateInfo	renderPassParams			=
2435		{
2436			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType					sType;
2437			DE_NULL,									// const void*						pNext;
2438			0u,											// VkRenderPassCreateFlags			flags;
2439			1u,											// deUint32							attachmentCount;
2440			attachmentDescriptions,						// const VkAttachmentDescription*	pAttachments;
2441			1u,											// deUint32							subpassCount;
2442			&subpassDescription,						// const VkSubpassDescription*		pSubpasses;
2443			0u,											// deUint32							dependencyCount;
2444			DE_NULL										// const VkSubpassDependency*		pDependencies;
2445		};
2446
2447		renderPass	= createRenderPass(vk, vkDevice, &renderPassParams);
2448	}
2449
2450	// Create pipeline layout
2451	{
2452		const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
2453		{
2454			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
2455			DE_NULL,											// const void*						pNext;
2456			0u,													// VkPipelineLayoutCreateFlags		flags;
2457			0u,													// deUint32							setLayoutCount;
2458			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
2459			0u,													// deUint32							pushConstantRangeCount;
2460			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
2461		};
2462
2463		pipelineLayout	= createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
2464	}
2465
2466	// Create upper half triangle.
2467	{
2468		const tcu::Vec4	a	(-1.0, -1.0, 0.0, 1.0);
2469		const tcu::Vec4	b	(1.0, -1.0, 0.0, 1.0);
2470		const tcu::Vec4	c	(1.0, 1.0, 0.0, 1.0);
2471		// Add triangle.
2472		vertices.push_back(a);
2473		vertices.push_back(c);
2474		vertices.push_back(b);
2475	}
2476
2477	// Create vertex buffer.
2478	{
2479		const VkDeviceSize			vertexDataSize		= vertices.size() * sizeof(tcu::Vec4);
2480		const VkBufferCreateInfo	vertexBufferParams	=
2481		{
2482			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2483			DE_NULL,									// const void*			pNext;
2484			0u,											// VkBufferCreateFlags	flags;
2485			vertexDataSize,								// VkDeviceSize			size;
2486			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
2487			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2488			1u,											// deUint32				queueFamilyIndexCount;
2489			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
2490		};
2491
2492		vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
2493		vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
2494
2495		VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
2496
2497		// Load vertices into vertex buffer.
2498		deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
2499		flushMappedMemoryRange(vk, vkDevice, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset(), vertexDataSize);
2500	}
2501
2502	{
2503		Move<VkFramebuffer>		framebuffer;
2504		Move<VkImageView>		sourceAttachmentView;
2505		//const VkExtent3D		extent3D = getExtent3D(m_params.src.image); TODO
2506
2507		// Create color attachment view.
2508		{
2509			const VkImageViewCreateInfo	colorAttachmentViewParams	=
2510			{
2511				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,				// VkStructureType			sType;
2512				DE_NULL,												// const void*				pNext;
2513				0u,														// VkImageViewCreateFlags	flags;
2514				*m_multisampledImage,									// VkImage					image;
2515				VK_IMAGE_VIEW_TYPE_2D,									// VkImageViewType			viewType;
2516				m_params.src.image.format,								// VkFormat					format;
2517				componentMappingRGBA,									// VkComponentMapping		components;
2518				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
2519			};
2520			sourceAttachmentView	= createImageView(vk, vkDevice, &colorAttachmentViewParams);
2521		}
2522
2523		// Create framebuffer
2524		{
2525			const VkImageView				attachments[1]		=
2526			{
2527					*sourceAttachmentView,
2528			};
2529
2530			const VkFramebufferCreateInfo	framebufferParams	=
2531			{
2532					VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
2533					DE_NULL,											// const void*					pNext;
2534					0u,													// VkFramebufferCreateFlags		flags;
2535					*renderPass,										// VkRenderPass					renderPass;
2536					1u,													// deUint32						attachmentCount;
2537					attachments,										// const VkImageView*			pAttachments;
2538					m_params.src.image.extent.width,					// deUint32						width;
2539					m_params.src.image.extent.height,					// deUint32						height;
2540					1u													// deUint32						layers;
2541			};
2542
2543			framebuffer	= createFramebuffer(vk, vkDevice, &framebufferParams);
2544		}
2545
2546		// Create pipeline
2547		{
2548			const VkPipelineShaderStageCreateInfo			shaderStageParams[2]				=
2549			{
2550				{
2551					VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
2552					DE_NULL,													// const void*							pNext;
2553					0u,															// VkPipelineShaderStageCreateFlags		flags;
2554					VK_SHADER_STAGE_VERTEX_BIT,									// VkShaderStageFlagBits				stage;
2555					*vertexShaderModule,										// VkShaderModule						module;
2556					"main",														// const char*							pName;
2557					DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
2558				},
2559				{
2560					VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,		// VkStructureType						sType;
2561					DE_NULL,													// const void*							pNext;
2562					0u,															// VkPipelineShaderStageCreateFlags		flags;
2563					VK_SHADER_STAGE_FRAGMENT_BIT,								// VkShaderStageFlagBits				stage;
2564					*fragmentShaderModule,										// VkShaderModule						module;
2565					"main",														// const char*							pName;
2566					DE_NULL														// const VkSpecializationInfo*			pSpecializationInfo;
2567				}
2568			};
2569
2570			const VkVertexInputBindingDescription			vertexInputBindingDescription		=
2571			{
2572					0u,									// deUint32				binding;
2573					sizeof(tcu::Vec4),					// deUint32				stride;
2574					VK_VERTEX_INPUT_RATE_VERTEX			// VkVertexInputRate	inputRate;
2575			};
2576
2577			const VkVertexInputAttributeDescription			vertexInputAttributeDescriptions[1]	=
2578			{
2579				{
2580					0u,									// deUint32	location;
2581					0u,									// deUint32	binding;
2582					VK_FORMAT_R32G32B32A32_SFLOAT,		// VkFormat	format;
2583					0u									// deUint32	offset;
2584				}
2585			};
2586
2587			const VkPipelineVertexInputStateCreateInfo		vertexInputStateParams				=
2588			{
2589				VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType;
2590				DE_NULL,													// const void*								pNext;
2591				0u,															// VkPipelineVertexInputStateCreateFlags	flags;
2592				1u,															// deUint32									vertexBindingDescriptionCount;
2593				&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
2594				1u,															// deUint32									vertexAttributeDescriptionCount;
2595				vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
2596			};
2597
2598			const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateParams			=
2599			{
2600				VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
2601				DE_NULL,														// const void*								pNext;
2602				0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
2603				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,							// VkPrimitiveTopology						topology;
2604				false															// VkBool32									primitiveRestartEnable;
2605			};
2606
2607			const VkViewport	viewport	=
2608			{
2609				0.0f,									// float	x;
2610				0.0f,									// float	y;
2611				(float)m_params.src.image.extent.width,	// float	width;
2612				(float)m_params.src.image.extent.height,// float	height;
2613				0.0f,									// float	minDepth;
2614				1.0f									// float	maxDepth;
2615			};
2616
2617			const VkRect2D		scissor		=
2618			{
2619				{ 0, 0 },																// VkOffset2D	offset;
2620				{ m_params.src.image.extent.width, m_params.src.image.extent.height }	// VkExtent2D	extent;
2621			};
2622
2623			const VkPipelineViewportStateCreateInfo			viewportStateParams		=
2624			{
2625				VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType						sType;
2626				DE_NULL,												// const void*							pNext;
2627				0u,														// VkPipelineViewportStateCreateFlags	flags;
2628				1u,														// deUint32								viewportCount;
2629				&viewport,												// const VkViewport*					pViewports;
2630				1u,														// deUint32								scissorCount;
2631				&scissor												// const VkRect2D*						pScissors;
2632			};
2633
2634			const VkPipelineRasterizationStateCreateInfo	rasterStateParams		=
2635			{
2636				VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType							sType;
2637				DE_NULL,													// const void*								pNext;
2638				0u,															// VkPipelineRasterizationStateCreateFlags	flags;
2639				false,														// VkBool32									depthClampEnable;
2640				false,														// VkBool32									rasterizerDiscardEnable;
2641				VK_POLYGON_MODE_FILL,										// VkPolygonMode							polygonMode;
2642				VK_CULL_MODE_NONE,											// VkCullModeFlags							cullMode;
2643				VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace								frontFace;
2644				VK_FALSE,													// VkBool32									depthBiasEnable;
2645				0.0f,														// float									depthBiasConstantFactor;
2646				0.0f,														// float									depthBiasClamp;
2647				0.0f,														// float									depthBiasSlopeFactor;
2648				1.0f														// float									lineWidth;
2649			};
2650
2651			const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
2652			{
2653				VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
2654				DE_NULL,													// const void*								pNext;
2655				0u,															// VkPipelineMultisampleStateCreateFlags	flags;
2656				rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
2657				VK_FALSE,													// VkBool32									sampleShadingEnable;
2658				0.0f,														// float									minSampleShading;
2659				DE_NULL,													// const VkSampleMask*						pSampleMask;
2660				VK_FALSE,													// VkBool32									alphaToCoverageEnable;
2661				VK_FALSE													// VkBool32									alphaToOneEnable;
2662			};
2663
2664			const VkPipelineColorBlendAttachmentState	colorBlendAttachmentState	=
2665			{
2666				false,							// VkBool32			blendEnable;
2667				VK_BLEND_FACTOR_ONE,			// VkBlend			srcBlendColor;
2668				VK_BLEND_FACTOR_ZERO,			// VkBlend			destBlendColor;
2669				VK_BLEND_OP_ADD,				// VkBlendOp		blendOpColor;
2670				VK_BLEND_FACTOR_ONE,			// VkBlend			srcBlendAlpha;
2671				VK_BLEND_FACTOR_ZERO,			// VkBlend			destBlendAlpha;
2672				VK_BLEND_OP_ADD,				// VkBlendOp		blendOpAlpha;
2673				(VK_COLOR_COMPONENT_R_BIT |
2674				VK_COLOR_COMPONENT_G_BIT |
2675				VK_COLOR_COMPONENT_B_BIT |
2676				VK_COLOR_COMPONENT_A_BIT)		// VkChannelFlags	channelWriteMask;
2677			};
2678
2679			const VkPipelineColorBlendStateCreateInfo	colorBlendStateParams	=
2680			{
2681				VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
2682				DE_NULL,													// const void*									pNext;
2683				0u,															// VkPipelineColorBlendStateCreateFlags			flags;
2684				false,														// VkBool32										logicOpEnable;
2685				VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
2686				1u,															// deUint32										attachmentCount;
2687				&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
2688				{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4];
2689			};
2690
2691			const VkGraphicsPipelineCreateInfo			graphicsPipelineParams	=
2692			{
2693				VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,	// VkStructureType									sType;
2694				DE_NULL,											// const void*										pNext;
2695				0u,													// VkPipelineCreateFlags							flags;
2696				2u,													// deUint32											stageCount;
2697				shaderStageParams,									// const VkPipelineShaderStageCreateInfo*			pStages;
2698				&vertexInputStateParams,							// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
2699				&inputAssemblyStateParams,							// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
2700				DE_NULL,											// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
2701				&viewportStateParams,								// const VkPipelineViewportStateCreateInfo*			pViewportState;
2702				&rasterStateParams,									// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
2703				&multisampleStateParams,							// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
2704				DE_NULL,											// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
2705				&colorBlendStateParams,								// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
2706				DE_NULL,											// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
2707				*pipelineLayout,									// VkPipelineLayout									layout;
2708				*renderPass,										// VkRenderPass										renderPass;
2709				0u,													// deUint32											subpass;
2710				0u,													// VkPipeline										basePipelineHandle;
2711				0u													// deInt32											basePipelineIndex;
2712			};
2713
2714			graphicsPipeline	= createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
2715		}
2716
2717		// Create command buffer
2718		{
2719			const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2720			{
2721				VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType					sType;
2722				DE_NULL,										// const void*						pNext;
2723				0u,												// VkCommandBufferUsageFlags		flags;
2724				(const VkCommandBufferInheritanceInfo*)DE_NULL,
2725			};
2726
2727			const VkClearValue clearValues[1] =
2728			{
2729				makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f),
2730			};
2731
2732			const VkRenderPassBeginInfo renderPassBeginInfo =
2733			{
2734				VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,				// VkStructureType		sType;
2735				DE_NULL,												// const void*			pNext;
2736				*renderPass,											// VkRenderPass			renderPass;
2737				*framebuffer,											// VkFramebuffer		framebuffer;
2738				{
2739					{ 0, 0 },
2740					{ m_params.src.image.extent.width, m_params.src.image.extent.height }
2741				},														// VkRect2D				renderArea;
2742				1u,														// deUint32				clearValueCount;
2743				clearValues												// const VkClearValue*	pClearValues;
2744			};
2745
2746			VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
2747			vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
2748			vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2749
2750			const VkDeviceSize	vertexBufferOffset	= 0u;
2751
2752			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2753			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
2754			vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
2755
2756			vk.cmdEndRenderPass(*m_cmdBuffer);
2757			VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
2758		}
2759
2760		// Queue submit.
2761		{
2762			const VkQueue	queue	= m_context.getUniversalQueue();
2763			submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2764		}
2765	}
2766}
2767
2768tcu::TestStatus ResolveImageToImage::iterate (void)
2769{
2770	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
2771	const tcu::TextureFormat		dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
2772
2773	// upload the destination image
2774		m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
2775																				(int)m_params.dst.image.extent.width,
2776																				(int)m_params.dst.image.extent.height,
2777																				(int)m_params.dst.image.extent.depth));
2778		generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2779		uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
2780
2781		m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
2782																		(int)m_params.src.image.extent.width,
2783																		(int)m_params.src.image.extent.height,
2784																		(int)m_params.dst.image.extent.depth));
2785
2786		generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_MULTISAMPLE);
2787		generateExpectedResult();
2788
2789	switch (m_options)
2790	{
2791		case COPY_MS_IMAGE_TO_MS_IMAGE:
2792		case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
2793			copyMSImageToMSImage();
2794			break;
2795		default:
2796			break;
2797	}
2798
2799	const DeviceInterface&			vk					= m_context.getDeviceInterface();
2800	const VkDevice					vkDevice			= m_context.getDevice();
2801	const VkQueue					queue				= m_context.getUniversalQueue();
2802
2803	std::vector<VkImageResolve>		imageResolves;
2804	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2805		imageResolves.push_back(m_params.regions[i].imageResolve);
2806
2807	const VkImageMemoryBarrier	imageBarriers[]		=
2808	{
2809		// source image
2810		{
2811			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2812			DE_NULL,									// const void*				pNext;
2813			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
2814			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
2815			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout;
2816			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
2817			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2818			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2819			m_multisampledImage.get(),					// VkImage					image;
2820			{											// VkImageSubresourceRange	subresourceRange;
2821				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
2822				0u,									// deUint32				baseMipLevel;
2823				1u,									// deUint32				mipLevels;
2824				0u,									// deUint32				baseArraySlice;
2825				getArraySize(m_params.dst.image)	// deUint32				arraySize;
2826			}
2827		},
2828		// destination image
2829		{
2830			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2831			DE_NULL,									// const void*				pNext;
2832			0u,											// VkAccessFlags			srcAccessMask;
2833			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
2834			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
2835			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
2836			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2837			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2838			m_destination.get(),						// VkImage					image;
2839			{											// VkImageSubresourceRange	subresourceRange;
2840				getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
2841				0u,									// deUint32				baseMipLevel;
2842				1u,									// deUint32				mipLevels;
2843				0u,									// deUint32				baseArraySlice;
2844				getArraySize(m_params.dst.image)	// deUint32				arraySize;
2845			}
2846		},
2847	};
2848
2849	const VkImageMemoryBarrier postImageBarrier =
2850	{
2851		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
2852		DE_NULL,								// const void*				pNext;
2853		VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			srcAccessMask;
2854		VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
2855		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			oldLayout;
2856		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
2857		VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
2858		VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
2859		m_destination.get(),					// VkImage					image;
2860		{										// VkImageSubresourceRange	subresourceRange;
2861			getAspectFlags(dstTcuFormat),		// VkImageAspectFlags		aspectMask;
2862			0u,									// deUint32					baseMipLevel;
2863			1u,									// deUint32					mipLevels;
2864			0u,									// deUint32					baseArraySlice;
2865			getArraySize(m_params.dst.image)	// deUint32					arraySize;
2866		}
2867	};
2868
2869	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
2870	{
2871		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
2872		DE_NULL,												// const void*						pNext;
2873		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
2874		(const VkCommandBufferInheritanceInfo*)DE_NULL,
2875	};
2876
2877	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
2878	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
2879	vk.cmdResolveImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), imageResolves.data());
2880	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
2881	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
2882	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2883
2884	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);
2885
2886	return checkTestResult(resultTextureLevel->getAccess());
2887}
2888
2889tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
2890{
2891	const tcu::ConstPixelBufferAccess	expected		= m_expectedTextureLevel->getAccess();
2892	const float							fuzzyThreshold	= 0.01f;
2893
2894	for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
2895	{
2896		const tcu::ConstPixelBufferAccess	expectedSub	= getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
2897		const tcu::ConstPixelBufferAccess	resultSub	= getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
2898		if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
2899			return tcu::TestStatus::fail("CopiesAndBlitting test");
2900	}
2901
2902	return tcu::TestStatus::pass("CopiesAndBlitting test");
2903}
2904
2905void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
2906{
2907	VkOffset3D srcOffset	= region.imageResolve.srcOffset;
2908			srcOffset.z		= region.imageResolve.srcSubresource.baseArrayLayer;
2909	VkOffset3D dstOffset	= region.imageResolve.dstOffset;
2910			dstOffset.z		= region.imageResolve.dstSubresource.baseArrayLayer;
2911	VkExtent3D extent		= region.imageResolve.extent;
2912
2913	const tcu::ConstPixelBufferAccess	srcSubRegion		= getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
2914	// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
2915	const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
2916	const tcu::PixelBufferAccess		dstSubRegion		= getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
2917
2918	tcu::copy(dstSubRegion, srcSubRegion);
2919}
2920
2921void ResolveImageToImage::copyMSImageToMSImage (void)
2922{
2923	const DeviceInterface&			vk					= m_context.getDeviceInterface();
2924	const VkDevice					vkDevice			= m_context.getDevice();
2925	const VkQueue					queue				= m_context.getUniversalQueue();
2926	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
2927	std::vector<VkImageCopy>		imageCopies;
2928
2929	for (deUint32 layerNdx = 0; layerNdx < getArraySize(m_params.dst.image); ++layerNdx)
2930	{
2931		const VkImageSubresourceLayers	sourceSubresourceLayers	=
2932		{
2933			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
2934			0u,								// uint32_t				mipLevel;
2935			0u,								// uint32_t				baseArrayLayer;
2936			1u								// uint32_t				layerCount;
2937		};
2938
2939		const VkImageSubresourceLayers	destinationSubresourceLayers	=
2940		{
2941			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;//getAspectFlags(dstTcuFormat)
2942			0u,								// uint32_t				mipLevel;
2943			layerNdx,						// uint32_t				baseArrayLayer;
2944			1u								// uint32_t				layerCount;
2945		};
2946
2947		const VkImageCopy				imageCopy	=
2948		{
2949			sourceSubresourceLayers,			// VkImageSubresourceLayers	srcSubresource;
2950			{0, 0, 0},							// VkOffset3D				srcOffset;
2951			destinationSubresourceLayers,		// VkImageSubresourceLayers	dstSubresource;
2952			{0, 0, 0},							// VkOffset3D				dstOffset;
2953			 getExtent3D(m_params.src.image),	// VkExtent3D				extent;
2954		};
2955		imageCopies.push_back(imageCopy);
2956	}
2957
2958	const VkImageMemoryBarrier		imageBarriers[]		=
2959	{
2960		//// source image
2961		{
2962			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2963			DE_NULL,									// const void*				pNext;
2964			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
2965			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
2966			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout;
2967			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
2968			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2969			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2970			m_multisampledImage.get(),					// VkImage					image;
2971			{											// VkImageSubresourceRange	subresourceRange;
2972				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
2973				0u,									// deUint32				baseMipLevel;
2974				1u,									// deUint32				mipLevels;
2975				0u,									// deUint32				baseArraySlice;
2976				getArraySize(m_params.src.image)	// deUint32				arraySize;
2977			}
2978		},
2979		// destination image
2980		{
2981			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2982			DE_NULL,									// const void*				pNext;
2983			0,											// VkAccessFlags			srcAccessMask;
2984			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
2985			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
2986			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
2987			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2988			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2989			m_multisampledCopyImage.get(),				// VkImage					image;
2990			{											// VkImageSubresourceRange	subresourceRange;
2991				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
2992				0u,									// deUint32				baseMipLevel;
2993				1u,									// deUint32				mipLevels;
2994				0u,									// deUint32				baseArraySlice;
2995				getArraySize(m_params.dst.image)	// deUint32				arraySize;
2996			}
2997		},
2998	};
2999
3000	const VkImageMemoryBarrier	postImageBarriers		=
3001	// source image
3002	{
3003		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3004		DE_NULL,									// const void*				pNext;
3005		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
3006		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
3007		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
3008		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
3009		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3010		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3011		m_multisampledCopyImage.get(),				// VkImage					image;
3012		{											// VkImageSubresourceRange	subresourceRange;
3013			getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
3014			0u,									// deUint32				baseMipLevel;
3015			1u,									// deUint32				mipLevels;
3016			0u,									// deUint32				baseArraySlice;
3017			getArraySize(m_params.dst.image)	// deUint32				arraySize;
3018		}
3019	};
3020
3021	const VkCommandBufferBeginInfo	cmdBufferBeginInfo	=
3022	{
3023		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// VkStructureType					sType;
3024		DE_NULL,												// const void*						pNext;
3025		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,			// VkCommandBufferUsageFlags		flags;
3026		(const VkCommandBufferInheritanceInfo*)DE_NULL,
3027	};
3028
3029	VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
3030	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
3031	vk.cmdCopyImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)imageCopies.size(), imageCopies.data());
3032	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarriers);
3033	VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
3034
3035	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
3036
3037	m_multisampledImage = m_multisampledCopyImage;
3038}
3039
3040class ResolveImageToImageTestCase : public vkt::TestCase
3041{
3042public:
3043							ResolveImageToImageTestCase	(tcu::TestContext&					testCtx,
3044														 const std::string&					name,
3045														 const std::string&					description,
3046														 const TestParams					params,
3047														 const ResolveImageToImageOptions	options = NO_OPTIONAL_OPERATION)
3048								: vkt::TestCase	(testCtx, name, description)
3049								, m_params		(params)
3050								, m_options		(options)
3051							{}
3052	virtual	void			initPrograms				(SourceCollections&		programCollection) const;
3053
3054	virtual TestInstance*	createInstance				(Context&				context) const
3055							{
3056								return new ResolveImageToImage(context, m_params, m_options);
3057							}
3058private:
3059	TestParams							m_params;
3060	const ResolveImageToImageOptions	m_options;
3061};
3062
3063void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
3064{
3065	programCollection.glslSources.add("vert") << glu::VertexSource(
3066		"#version 310 es\n"
3067		"layout (location = 0) in highp vec4 a_position;\n"
3068		"void main()\n"
3069		"{\n"
3070		"	gl_Position = a_position;\n"
3071		"}\n");
3072
3073
3074	programCollection.glslSources.add("frag") << glu::FragmentSource(
3075		"#version 310 es\n"
3076		"layout (location = 0) out highp vec4 o_color;\n"
3077		"void main()\n"
3078		"{\n"
3079		"	o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
3080		"}\n");
3081}
3082
3083std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
3084{
3085	return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
3086}
3087
3088std::string getFormatCaseName (VkFormat format)
3089{
3090	return de::toLower(de::toString(getFormatStr(format)).substr(10));
3091}
3092
3093void addCopyImageTestsAllFormats (tcu::TestCaseGroup*	testCaseGroup,
3094								  tcu::TestContext&		testCtx,
3095								  TestParams&			params)
3096{
3097	const VkFormat	compatibleFormats8Bit[]			=
3098	{
3099		VK_FORMAT_R4G4_UNORM_PACK8,
3100		VK_FORMAT_R8_UNORM,
3101		VK_FORMAT_R8_SNORM,
3102		VK_FORMAT_R8_USCALED,
3103		VK_FORMAT_R8_SSCALED,
3104		VK_FORMAT_R8_UINT,
3105		VK_FORMAT_R8_SINT,
3106		VK_FORMAT_R8_SRGB,
3107
3108		VK_FORMAT_UNDEFINED
3109	};
3110	const VkFormat	compatibleFormats16Bit[]		=
3111	{
3112		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
3113		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
3114		VK_FORMAT_R5G6B5_UNORM_PACK16,
3115		VK_FORMAT_B5G6R5_UNORM_PACK16,
3116		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
3117		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
3118		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
3119		VK_FORMAT_R8G8_UNORM,
3120		VK_FORMAT_R8G8_SNORM,
3121		VK_FORMAT_R8G8_USCALED,
3122		VK_FORMAT_R8G8_SSCALED,
3123		VK_FORMAT_R8G8_UINT,
3124		VK_FORMAT_R8G8_SINT,
3125		VK_FORMAT_R8G8_SRGB,
3126		VK_FORMAT_R16_UNORM,
3127		VK_FORMAT_R16_SNORM,
3128		VK_FORMAT_R16_USCALED,
3129		VK_FORMAT_R16_SSCALED,
3130		VK_FORMAT_R16_UINT,
3131		VK_FORMAT_R16_SINT,
3132		VK_FORMAT_R16_SFLOAT,
3133
3134		VK_FORMAT_UNDEFINED
3135	 };
3136	const VkFormat	compatibleFormats24Bit[]		=
3137	{
3138		VK_FORMAT_R8G8B8_UNORM,
3139		VK_FORMAT_R8G8B8_SNORM,
3140		VK_FORMAT_R8G8B8_USCALED,
3141		VK_FORMAT_R8G8B8_SSCALED,
3142		VK_FORMAT_R8G8B8_UINT,
3143		VK_FORMAT_R8G8B8_SINT,
3144		VK_FORMAT_R8G8B8_SRGB,
3145		VK_FORMAT_B8G8R8_UNORM,
3146		VK_FORMAT_B8G8R8_SNORM,
3147		VK_FORMAT_B8G8R8_USCALED,
3148		VK_FORMAT_B8G8R8_SSCALED,
3149		VK_FORMAT_B8G8R8_UINT,
3150		VK_FORMAT_B8G8R8_SINT,
3151		VK_FORMAT_B8G8R8_SRGB,
3152
3153		VK_FORMAT_UNDEFINED
3154	 };
3155	const VkFormat	compatibleFormats32Bit[]		=
3156	{
3157		VK_FORMAT_R8G8B8A8_UNORM,
3158		VK_FORMAT_R8G8B8A8_SNORM,
3159		VK_FORMAT_R8G8B8A8_USCALED,
3160		VK_FORMAT_R8G8B8A8_SSCALED,
3161		VK_FORMAT_R8G8B8A8_UINT,
3162		VK_FORMAT_R8G8B8A8_SINT,
3163		VK_FORMAT_R8G8B8A8_SRGB,
3164		VK_FORMAT_B8G8R8A8_UNORM,
3165		VK_FORMAT_B8G8R8A8_SNORM,
3166		VK_FORMAT_B8G8R8A8_USCALED,
3167		VK_FORMAT_B8G8R8A8_SSCALED,
3168		VK_FORMAT_B8G8R8A8_UINT,
3169		VK_FORMAT_B8G8R8A8_SINT,
3170		VK_FORMAT_B8G8R8A8_SRGB,
3171		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3172		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3173		VK_FORMAT_A8B8G8R8_USCALED_PACK32,
3174		VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
3175		VK_FORMAT_A8B8G8R8_UINT_PACK32,
3176		VK_FORMAT_A8B8G8R8_SINT_PACK32,
3177		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
3178		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
3179		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
3180		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
3181		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
3182		VK_FORMAT_A2R10G10B10_UINT_PACK32,
3183		VK_FORMAT_A2R10G10B10_SINT_PACK32,
3184		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3185		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
3186		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
3187		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
3188		VK_FORMAT_A2B10G10R10_UINT_PACK32,
3189		VK_FORMAT_A2B10G10R10_SINT_PACK32,
3190		VK_FORMAT_R16G16_UNORM,
3191		VK_FORMAT_R16G16_SNORM,
3192		VK_FORMAT_R16G16_USCALED,
3193		VK_FORMAT_R16G16_SSCALED,
3194		VK_FORMAT_R16G16_UINT,
3195		VK_FORMAT_R16G16_SINT,
3196		VK_FORMAT_R16G16_SFLOAT,
3197		VK_FORMAT_R32_UINT,
3198		VK_FORMAT_R32_SINT,
3199		VK_FORMAT_R32_SFLOAT,
3200
3201		VK_FORMAT_UNDEFINED
3202	 };
3203	const VkFormat	compatibleFormats48Bit[]		=
3204	{
3205		VK_FORMAT_R16G16B16_UNORM,
3206		VK_FORMAT_R16G16B16_SNORM,
3207		VK_FORMAT_R16G16B16_USCALED,
3208		VK_FORMAT_R16G16B16_SSCALED,
3209		VK_FORMAT_R16G16B16_UINT,
3210		VK_FORMAT_R16G16B16_SINT,
3211		VK_FORMAT_R16G16B16_SFLOAT,
3212
3213		VK_FORMAT_UNDEFINED
3214	 };
3215	const VkFormat	compatibleFormats64Bit[]		=
3216	{
3217		VK_FORMAT_R16G16B16A16_UNORM,
3218		VK_FORMAT_R16G16B16A16_SNORM,
3219		VK_FORMAT_R16G16B16A16_USCALED,
3220		VK_FORMAT_R16G16B16A16_SSCALED,
3221		VK_FORMAT_R16G16B16A16_UINT,
3222		VK_FORMAT_R16G16B16A16_SINT,
3223		VK_FORMAT_R16G16B16A16_SFLOAT,
3224		VK_FORMAT_R32G32_UINT,
3225		VK_FORMAT_R32G32_SINT,
3226		VK_FORMAT_R32G32_SFLOAT,
3227		VK_FORMAT_R64_UINT,
3228		VK_FORMAT_R64_SINT,
3229		VK_FORMAT_R64_SFLOAT,
3230
3231		VK_FORMAT_UNDEFINED
3232	 };
3233	const VkFormat	compatibleFormats96Bit[]		=
3234	{
3235		VK_FORMAT_R32G32B32_UINT,
3236		VK_FORMAT_R32G32B32_SINT,
3237		VK_FORMAT_R32G32B32_SFLOAT,
3238
3239		VK_FORMAT_UNDEFINED
3240	 };
3241	const VkFormat	compatibleFormats128Bit[]		=
3242	{
3243		VK_FORMAT_R32G32B32A32_UINT,
3244		VK_FORMAT_R32G32B32A32_SINT,
3245		VK_FORMAT_R32G32B32A32_SFLOAT,
3246		VK_FORMAT_R64G64_UINT,
3247		VK_FORMAT_R64G64_SINT,
3248		VK_FORMAT_R64G64_SFLOAT,
3249
3250		VK_FORMAT_UNDEFINED
3251	 };
3252	const VkFormat	compatibleFormats192Bit[]		=
3253	{
3254		VK_FORMAT_R64G64B64_UINT,
3255		VK_FORMAT_R64G64B64_SINT,
3256		VK_FORMAT_R64G64B64_SFLOAT,
3257
3258		VK_FORMAT_UNDEFINED
3259	 };
3260	const VkFormat	compatibleFormats256Bit[]		=
3261	{
3262		VK_FORMAT_R64G64B64A64_UINT,
3263		VK_FORMAT_R64G64B64A64_SINT,
3264		VK_FORMAT_R64G64B64A64_SFLOAT,
3265
3266		VK_FORMAT_UNDEFINED
3267	};
3268
3269	const VkFormat*	colorImageFormatsToTest[]		=
3270	{
3271		compatibleFormats8Bit,
3272		compatibleFormats16Bit,
3273		compatibleFormats24Bit,
3274		compatibleFormats32Bit,
3275		compatibleFormats48Bit,
3276		compatibleFormats64Bit,
3277		compatibleFormats96Bit,
3278		compatibleFormats128Bit,
3279		compatibleFormats192Bit,
3280		compatibleFormats256Bit,
3281	};
3282	const size_t	numOfColorImageFormatsToTest	= DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
3283
3284	for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
3285	{
3286		const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
3287		for (size_t srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
3288		{
3289			params.src.image.format	= compatibleFormats[srcFormatIndex];
3290			for (size_t dstFormatIndex = 0; compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
3291			{
3292				params.dst.image.format	= compatibleFormats[dstFormatIndex];
3293
3294				if (!isSupportedByFramework(params.src.image.format) || !isSupportedByFramework(params.dst.image.format))
3295					continue;
3296
3297				std::ostringstream	testName;
3298				testName << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format);
3299				std::ostringstream	description;
3300				description << "Copy from src " << params.src.image.format << " to dst " << params.dst.image.format;
3301
3302				testCaseGroup->addChild(new CopyImageToImageTestCase(testCtx, testName.str(), description.str(), params));
3303			}
3304		}
3305	}
3306}
3307
3308void addBlittingTestsAllFormats (tcu::TestCaseGroup*	testCaseGroup,
3309								 tcu::TestContext&		testCtx,
3310								 TestParams&			params)
3311{
3312	// Test Image formats.
3313	const VkFormat	compatibleFormatsUInts[]			=
3314	{
3315		VK_FORMAT_R8_UINT,
3316		VK_FORMAT_R8G8_UINT,
3317		VK_FORMAT_R8G8B8_UINT,
3318		VK_FORMAT_B8G8R8_UINT,
3319		VK_FORMAT_R8G8B8A8_UINT,
3320		VK_FORMAT_B8G8R8A8_UINT,
3321		VK_FORMAT_A8B8G8R8_UINT_PACK32,
3322		VK_FORMAT_A2R10G10B10_UINT_PACK32,
3323		VK_FORMAT_A2B10G10R10_UINT_PACK32,
3324		VK_FORMAT_R16_UINT,
3325		VK_FORMAT_R16G16_UINT,
3326		VK_FORMAT_R16G16B16_UINT,
3327		VK_FORMAT_R16G16B16A16_UINT,
3328		VK_FORMAT_R32_UINT,
3329		VK_FORMAT_R32G32_UINT,
3330		VK_FORMAT_R32G32B32_UINT,
3331		VK_FORMAT_R32G32B32A32_UINT,
3332		VK_FORMAT_R64_UINT,
3333		VK_FORMAT_R64G64_UINT,
3334		VK_FORMAT_R64G64B64_UINT,
3335		VK_FORMAT_R64G64B64A64_UINT,
3336
3337		VK_FORMAT_UNDEFINED
3338	};
3339	const VkFormat	compatibleFormatsSInts[]			=
3340	{
3341		VK_FORMAT_R8_SINT,
3342		VK_FORMAT_R8G8_SINT,
3343		VK_FORMAT_R8G8B8_SINT,
3344		VK_FORMAT_B8G8R8_SINT,
3345		VK_FORMAT_R8G8B8A8_SINT,
3346		VK_FORMAT_B8G8R8A8_SINT,
3347		VK_FORMAT_A8B8G8R8_SINT_PACK32,
3348		VK_FORMAT_A2R10G10B10_SINT_PACK32,
3349		VK_FORMAT_A2B10G10R10_SINT_PACK32,
3350		VK_FORMAT_R16_SINT,
3351		VK_FORMAT_R16G16_SINT,
3352		VK_FORMAT_R16G16B16_SINT,
3353		VK_FORMAT_R16G16B16A16_SINT,
3354		VK_FORMAT_R32_SINT,
3355		VK_FORMAT_R32G32_SINT,
3356		VK_FORMAT_R32G32B32_SINT,
3357		VK_FORMAT_R32G32B32A32_SINT,
3358		VK_FORMAT_R64_SINT,
3359		VK_FORMAT_R64G64_SINT,
3360		VK_FORMAT_R64G64B64_SINT,
3361		VK_FORMAT_R64G64B64A64_SINT,
3362
3363		VK_FORMAT_UNDEFINED
3364	};
3365	const VkFormat	compatibleFormatsFloats[]			=
3366	{
3367		VK_FORMAT_R4G4_UNORM_PACK8,
3368		VK_FORMAT_R4G4B4A4_UNORM_PACK16,
3369		VK_FORMAT_B4G4R4A4_UNORM_PACK16,
3370		VK_FORMAT_R5G6B5_UNORM_PACK16,
3371		VK_FORMAT_B5G6R5_UNORM_PACK16,
3372		VK_FORMAT_R5G5B5A1_UNORM_PACK16,
3373		VK_FORMAT_B5G5R5A1_UNORM_PACK16,
3374		VK_FORMAT_A1R5G5B5_UNORM_PACK16,
3375		VK_FORMAT_R8_UNORM,
3376		VK_FORMAT_R8_SNORM,
3377		VK_FORMAT_R8_USCALED,
3378		VK_FORMAT_R8_SSCALED,
3379		VK_FORMAT_R8G8_UNORM,
3380		VK_FORMAT_R8G8_SNORM,
3381		VK_FORMAT_R8G8_USCALED,
3382		VK_FORMAT_R8G8_SSCALED,
3383		VK_FORMAT_R8G8B8_UNORM,
3384		VK_FORMAT_R8G8B8_SNORM,
3385		VK_FORMAT_R8G8B8_USCALED,
3386		VK_FORMAT_R8G8B8_SSCALED,
3387		VK_FORMAT_B8G8R8_UNORM,
3388		VK_FORMAT_B8G8R8_SNORM,
3389		VK_FORMAT_B8G8R8_USCALED,
3390		VK_FORMAT_B8G8R8_SSCALED,
3391		VK_FORMAT_R8G8B8A8_UNORM,
3392		VK_FORMAT_R8G8B8A8_SNORM,
3393		VK_FORMAT_R8G8B8A8_USCALED,
3394		VK_FORMAT_R8G8B8A8_SSCALED,
3395		VK_FORMAT_B8G8R8A8_UNORM,
3396		VK_FORMAT_B8G8R8A8_SNORM,
3397		VK_FORMAT_B8G8R8A8_USCALED,
3398		VK_FORMAT_B8G8R8A8_SSCALED,
3399		VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3400		VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3401		VK_FORMAT_A8B8G8R8_USCALED_PACK32,
3402		VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
3403		VK_FORMAT_A2R10G10B10_UNORM_PACK32,
3404		VK_FORMAT_A2R10G10B10_SNORM_PACK32,
3405		VK_FORMAT_A2R10G10B10_USCALED_PACK32,
3406		VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
3407		VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3408		VK_FORMAT_A2B10G10R10_SNORM_PACK32,
3409		VK_FORMAT_A2B10G10R10_USCALED_PACK32,
3410		VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
3411		VK_FORMAT_R16_UNORM,
3412		VK_FORMAT_R16_SNORM,
3413		VK_FORMAT_R16_USCALED,
3414		VK_FORMAT_R16_SSCALED,
3415		VK_FORMAT_R16_SFLOAT,
3416		VK_FORMAT_R16G16_UNORM,
3417		VK_FORMAT_R16G16_SNORM,
3418		VK_FORMAT_R16G16_USCALED,
3419		VK_FORMAT_R16G16_SSCALED,
3420		VK_FORMAT_R16G16_SFLOAT,
3421		VK_FORMAT_R16G16B16_UNORM,
3422		VK_FORMAT_R16G16B16_SNORM,
3423		VK_FORMAT_R16G16B16_USCALED,
3424		VK_FORMAT_R16G16B16_SSCALED,
3425		VK_FORMAT_R16G16B16_SFLOAT,
3426		VK_FORMAT_R16G16B16A16_UNORM,
3427		VK_FORMAT_R16G16B16A16_SNORM,
3428		VK_FORMAT_R16G16B16A16_USCALED,
3429		VK_FORMAT_R16G16B16A16_SSCALED,
3430		VK_FORMAT_R16G16B16A16_SFLOAT,
3431		VK_FORMAT_R32_SFLOAT,
3432		VK_FORMAT_R32G32_SFLOAT,
3433		VK_FORMAT_R32G32B32_SFLOAT,
3434		VK_FORMAT_R32G32B32A32_SFLOAT,
3435		VK_FORMAT_R64_SFLOAT,
3436		VK_FORMAT_R64G64_SFLOAT,
3437		VK_FORMAT_R64G64B64_SFLOAT,
3438		VK_FORMAT_R64G64B64A64_SFLOAT,
3439//		VK_FORMAT_B10G11R11_UFLOAT_PACK32,
3440//		VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
3441//		VK_FORMAT_BC1_RGB_UNORM_BLOCK,
3442//		VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
3443//		VK_FORMAT_BC2_UNORM_BLOCK,
3444//		VK_FORMAT_BC3_UNORM_BLOCK,
3445//		VK_FORMAT_BC4_UNORM_BLOCK,
3446//		VK_FORMAT_BC4_SNORM_BLOCK,
3447//		VK_FORMAT_BC5_UNORM_BLOCK,
3448//		VK_FORMAT_BC5_SNORM_BLOCK,
3449//		VK_FORMAT_BC6H_UFLOAT_BLOCK,
3450//		VK_FORMAT_BC6H_SFLOAT_BLOCK,
3451//		VK_FORMAT_BC7_UNORM_BLOCK,
3452//		VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
3453//		VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
3454//		VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
3455//		VK_FORMAT_EAC_R11_UNORM_BLOCK,
3456//		VK_FORMAT_EAC_R11_SNORM_BLOCK,
3457//		VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
3458//		VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
3459//		VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
3460//		VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
3461//		VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
3462//		VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
3463//		VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
3464//		VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
3465//		VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
3466//		VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
3467//		VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
3468//		VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
3469//		VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
3470//		VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
3471//		VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
3472//		VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
3473
3474		VK_FORMAT_UNDEFINED
3475	};
3476	const VkFormat	compatibleFormatsSrgb[]				=
3477	{
3478		VK_FORMAT_R8_SRGB,
3479		VK_FORMAT_R8G8_SRGB,
3480		VK_FORMAT_R8G8B8_SRGB,
3481		VK_FORMAT_B8G8R8_SRGB,
3482		VK_FORMAT_R8G8B8A8_SRGB,
3483		VK_FORMAT_B8G8R8A8_SRGB,
3484		VK_FORMAT_A8B8G8R8_SRGB_PACK32,
3485//		VK_FORMAT_BC1_RGB_SRGB_BLOCK,
3486//		VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
3487//		VK_FORMAT_BC2_SRGB_BLOCK,
3488//		VK_FORMAT_BC3_SRGB_BLOCK,
3489//		VK_FORMAT_BC7_SRGB_BLOCK,
3490//		VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
3491//		VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
3492//		VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
3493//		VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
3494//		VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
3495//		VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
3496//		VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
3497//		VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
3498//		VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
3499//		VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
3500//		VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
3501//		VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
3502//		VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
3503//		VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
3504//		VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
3505//		VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
3506//		VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
3507
3508		VK_FORMAT_UNDEFINED
3509	};
3510
3511	const struct {
3512		const VkFormat*	compatibleFormats;
3513		const bool		onlyNearest;
3514	}	colorImageFormatsToTest[]			=
3515	{
3516		{ compatibleFormatsUInts,	true	},
3517		{ compatibleFormatsSInts,	true	},
3518		{ compatibleFormatsFloats,	false	},
3519		{ compatibleFormatsSrgb,	false	},
3520	};
3521	const size_t	numOfColorImageFormatsToTest		= DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
3522
3523	for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
3524	{
3525		const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex].compatibleFormats;
3526		const bool		onlyNearest			= colorImageFormatsToTest[compatibleFormatsIndex].onlyNearest;
3527		for (size_t srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
3528		{
3529			params.src.image.format	= compatibleFormats[srcFormatIndex];
3530			for (size_t dstFormatIndex = 0; compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
3531			{
3532				params.dst.image.format	= compatibleFormats[dstFormatIndex];
3533
3534				if (!isSupportedByFramework(params.src.image.format) || !isSupportedByFramework(params.dst.image.format))
3535					continue;
3536
3537				std::ostringstream	testName;
3538				testName << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format);
3539				std::ostringstream	description;
3540				description << "Blit image from src " << params.src.image.format << " to dst " << params.dst.image.format;
3541
3542				params.filter			= VK_FILTER_NEAREST;
3543				testCaseGroup->addChild(new BlittingTestCase(testCtx, testName.str() + "_nearest", description.str(), params));
3544
3545				if (!onlyNearest)
3546				{
3547					params.filter		= VK_FILTER_LINEAR;
3548					testCaseGroup->addChild(new BlittingTestCase(testCtx, testName.str() + "_linear", description.str(), params));
3549				}
3550			}
3551		}
3552	}
3553}
3554
3555} // anonymous
3556
3557tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
3558{
3559	de::MovePtr<tcu::TestCaseGroup>	copiesAndBlittingTests	(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
3560
3561	de::MovePtr<tcu::TestCaseGroup>	imageToImageTests		(new tcu::TestCaseGroup(testCtx, "image_to_image", "Copy from image to image"));
3562	de::MovePtr<tcu::TestCaseGroup>	imgToImgSimpleTests		(new tcu::TestCaseGroup(testCtx, "simple_tests", "Copy from image to image simple tests"));
3563	de::MovePtr<tcu::TestCaseGroup>	imgToImgAllFormatsTests	(new tcu::TestCaseGroup(testCtx, "all_formats", "Copy from image to image with all compatible formats"));
3564	de::MovePtr<tcu::TestCaseGroup>	imgToImg3dImagesTests	(new tcu::TestCaseGroup(testCtx, "3d_images", "Coping operations on 3d images"));
3565
3566	de::MovePtr<tcu::TestCaseGroup>	imageToBufferTests		(new tcu::TestCaseGroup(testCtx, "image_to_buffer", "Copy from image to buffer"));
3567	de::MovePtr<tcu::TestCaseGroup>	bufferToImageTests		(new tcu::TestCaseGroup(testCtx, "buffer_to_image", "Copy from buffer to image"));
3568	de::MovePtr<tcu::TestCaseGroup>	bufferToBufferTests		(new tcu::TestCaseGroup(testCtx, "buffer_to_buffer", "Copy from buffer to buffer"));
3569
3570	de::MovePtr<tcu::TestCaseGroup>	blittingImageTests		(new tcu::TestCaseGroup(testCtx, "blit_image", "Blitting image"));
3571	de::MovePtr<tcu::TestCaseGroup>	blitImgSimpleTests		(new tcu::TestCaseGroup(testCtx, "simple_tests", "Blitting image simple tests"));
3572	de::MovePtr<tcu::TestCaseGroup>	blitImgAllFormatsTests	(new tcu::TestCaseGroup(testCtx, "all_formats", "Blitting image with all compatible formats"));
3573
3574	de::MovePtr<tcu::TestCaseGroup>	resolveImageTests		(new tcu::TestCaseGroup(testCtx, "resolve_image", "Resolve image"));
3575
3576	const deInt32					defaultSize				= 64;
3577	const deInt32					defaultHalfSize			= defaultSize / 2;
3578	const deInt32					defaultFourthSize		= defaultSize / 4;
3579	const VkExtent3D				defaultExtent			= {defaultSize, defaultSize, 1};
3580	const VkExtent3D				defaultHalfExtent		= {defaultHalfSize, defaultHalfSize, 1};
3581
3582	const VkImageSubresourceLayers	defaultSourceLayer		=
3583	{
3584		VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
3585		0u,							// uint32_t				mipLevel;
3586		0u,							// uint32_t				baseArrayLayer;
3587		1u,							// uint32_t				layerCount;
3588	};
3589
3590	const VkFormat	depthAndStencilFormats[]	=
3591	{
3592		VK_FORMAT_D16_UNORM,
3593		VK_FORMAT_X8_D24_UNORM_PACK32,
3594		VK_FORMAT_D32_SFLOAT,
3595		VK_FORMAT_S8_UINT,
3596		VK_FORMAT_D16_UNORM_S8_UINT,
3597		VK_FORMAT_D24_UNORM_S8_UINT,
3598		VK_FORMAT_D32_SFLOAT_S8_UINT,
3599	};
3600
3601	// Copy image to image testcases.
3602	{
3603		TestParams			params;
3604		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
3605		params.src.image.format		= VK_FORMAT_R8G8B8A8_UINT;
3606		params.src.image.extent		= defaultExtent;
3607		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
3608		params.dst.image.format		= VK_FORMAT_R8G8B8A8_UINT;
3609		params.dst.image.extent		= defaultExtent;
3610
3611		{
3612			const VkImageCopy				testCopy	=
3613			{
3614				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
3615				{0, 0, 0},			// VkOffset3D				srcOffset;
3616				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
3617				{0, 0, 0},			// VkOffset3D				dstOffset;
3618				defaultExtent,		// VkExtent3D				extent;
3619			};
3620
3621			CopyRegion	imageCopy;
3622			imageCopy.imageCopy	= testCopy;
3623
3624			params.regions.push_back(imageCopy);
3625		}
3626
3627		imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
3628	}
3629
3630	{
3631		TestParams			params;
3632		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
3633		params.src.image.format		= VK_FORMAT_R8G8B8A8_UINT;
3634		params.src.image.extent		= defaultExtent;
3635		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
3636		params.dst.image.format		= VK_FORMAT_R32_UINT;
3637		params.dst.image.extent		= defaultExtent;
3638
3639		{
3640			const VkImageCopy				testCopy	=
3641			{
3642				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
3643				{0, 0, 0},			// VkOffset3D				srcOffset;
3644				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
3645				{0, 0, 0},			// VkOffset3D				dstOffset;
3646				defaultExtent,		// VkExtent3D				extent;
3647			};
3648
3649			CopyRegion	imageCopy;
3650			imageCopy.imageCopy	= testCopy;
3651
3652			params.regions.push_back(imageCopy);
3653		}
3654
3655		imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
3656	}
3657
3658	{
3659		TestParams			params;
3660		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
3661		params.src.image.format		= VK_FORMAT_R8G8B8A8_UINT;
3662		params.src.image.extent		= defaultExtent;
3663		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
3664		params.dst.image.format		= VK_FORMAT_R8G8B8A8_UINT;
3665		params.dst.image.extent		= defaultExtent;
3666
3667		{
3668			const VkImageCopy				testCopy	=
3669			{
3670				defaultSourceLayer,									// VkImageSubresourceLayers	srcSubresource;
3671				{0, 0, 0},											// VkOffset3D				srcOffset;
3672				defaultSourceLayer,									// VkImageSubresourceLayers	dstSubresource;
3673				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
3674				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
3675			};
3676
3677			CopyRegion	imageCopy;
3678			imageCopy.imageCopy	= testCopy;
3679
3680			params.regions.push_back(imageCopy);
3681		}
3682
3683		imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
3684	}
3685
3686	{
3687		TestParams			params;
3688		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
3689		params.src.image.format		= VK_FORMAT_D32_SFLOAT;
3690		params.src.image.extent		= defaultExtent;
3691		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
3692		params.dst.image.format		= VK_FORMAT_D32_SFLOAT;
3693		params.dst.image.extent		= defaultExtent;
3694
3695		{
3696			const VkImageSubresourceLayers  sourceLayer =
3697			{
3698				VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
3699				0u,							// uint32_t				mipLevel;
3700				0u,							// uint32_t				baseArrayLayer;
3701				1u							// uint32_t				layerCount;
3702			};
3703			const VkImageCopy				testCopy	=
3704			{
3705				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
3706				{0, 0, 0},											// VkOffset3D				srcOffset;
3707				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
3708				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
3709				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
3710			};
3711
3712			CopyRegion	imageCopy;
3713			imageCopy.imageCopy	= testCopy;
3714
3715			params.regions.push_back(imageCopy);
3716		}
3717
3718		imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
3719	}
3720
3721	{
3722		TestParams			params;
3723		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
3724		params.src.image.format		= VK_FORMAT_S8_UINT;
3725		params.src.image.extent		= defaultExtent;
3726		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
3727		params.dst.image.format		= VK_FORMAT_S8_UINT;
3728		params.dst.image.extent		= defaultExtent;
3729
3730		{
3731			const VkImageSubresourceLayers  sourceLayer =
3732			{
3733				VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
3734				0u,								// uint32_t				mipLevel;
3735				0u,								// uint32_t				baseArrayLayer;
3736				1u								// uint32_t				layerCount;
3737			};
3738			const VkImageCopy				testCopy	=
3739			{
3740				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
3741				{0, 0, 0},											// VkOffset3D				srcOffset;
3742				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
3743				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
3744				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
3745			};
3746
3747			CopyRegion	imageCopy;
3748			imageCopy.imageCopy	= testCopy;
3749
3750			params.regions.push_back(imageCopy);
3751		}
3752
3753		imgToImgSimpleTests->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
3754	}
3755
3756	{
3757		// Test Color formats.
3758		{
3759			TestParams			params;
3760			params.src.image.imageType	= VK_IMAGE_TYPE_2D;
3761			params.src.image.extent	= defaultExtent;
3762			params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
3763			params.dst.image.extent	= defaultExtent;
3764
3765			for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
3766			{
3767				const VkImageCopy				testCopy	=
3768				{
3769					defaultSourceLayer,								// VkImageSubresourceLayers	srcSubresource;
3770					{0, 0, 0},										// VkOffset3D				srcOffset;
3771					defaultSourceLayer,								// VkImageSubresourceLayers	dstSubresource;
3772					{i, defaultSize - i - defaultFourthSize, 0},	// VkOffset3D				dstOffset;
3773					{defaultFourthSize, defaultFourthSize, 1},		// VkExtent3D				extent;
3774				};
3775
3776				CopyRegion	imageCopy;
3777				imageCopy.imageCopy	= testCopy;
3778
3779				params.regions.push_back(imageCopy);
3780			}
3781
3782			addCopyImageTestsAllFormats(imgToImgAllFormatsTests.get(), testCtx, params);
3783		}
3784
3785		// Test Depth and Stencil formats.
3786		{
3787			const std::string	description	("Copy image to image with depth/stencil formats ");
3788			const std::string	testName	("depth_stencil");
3789
3790			for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
3791			{
3792				TestParams params;
3793
3794				params.src.image.imageType	= VK_IMAGE_TYPE_2D;
3795				params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
3796				params.src.image.extent		= defaultExtent;
3797				params.dst.image.extent		= defaultExtent;
3798				params.src.image.format		= depthAndStencilFormats[compatibleFormatsIndex];
3799				params.dst.image.format		= params.src.image.format;
3800				std::ostringstream	oss;
3801				oss << testName << "_" << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format);
3802
3803				const VkImageSubresourceLayers	defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
3804				const VkImageSubresourceLayers	defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
3805
3806				for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
3807				{
3808					CopyRegion			copyRegion;
3809					const VkOffset3D	srcOffset	= {0, 0, 0};
3810					const VkOffset3D	dstOffset	= {i, defaultSize - i - defaultFourthSize, 0};
3811					const VkExtent3D	extent		= {defaultFourthSize, defaultFourthSize, 1};
3812
3813					if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
3814					{
3815						const VkImageCopy				testCopy	=
3816						{
3817							defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
3818							srcOffset,					// VkOffset3D				srcOffset;
3819							defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
3820							dstOffset,					// VkOffset3D				dstOffset;
3821							extent,						// VkExtent3D				extent;
3822						};
3823
3824						copyRegion.imageCopy	= testCopy;
3825						params.regions.push_back(copyRegion);
3826					}
3827					if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
3828					{
3829						const VkImageCopy				testCopy	=
3830						{
3831							defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
3832							srcOffset,					// VkOffset3D				srcOffset;
3833							defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
3834							dstOffset,					// VkOffset3D				dstOffset;
3835							extent,						// VkExtent3D				extent;
3836						};
3837
3838						copyRegion.imageCopy	= testCopy;
3839						params.regions.push_back(copyRegion);
3840					}
3841				}
3842
3843				imgToImgAllFormatsTests->addChild(new CopyImageToImageTestCase(testCtx, oss.str(), description, params));
3844			}
3845		}
3846	}
3847	imageToImageTests->addChild(imgToImgSimpleTests.release());
3848	imageToImageTests->addChild(imgToImgAllFormatsTests.release());
3849
3850	// Copy image to buffer testcases.
3851	{
3852		TestParams	params;
3853		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
3854		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
3855		params.src.image.extent		= defaultExtent;
3856		params.dst.buffer.size		= defaultSize * defaultSize;
3857
3858		const VkBufferImageCopy	bufferImageCopy	=
3859		{
3860			0u,											// VkDeviceSize				bufferOffset;
3861			0u,											// uint32_t					bufferRowLength;
3862			0u,											// uint32_t					bufferImageHeight;
3863			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
3864			{0, 0, 0},									// VkOffset3D				imageOffset;
3865			defaultExtent								// VkExtent3D				imageExtent;
3866		};
3867		CopyRegion	copyRegion;
3868		copyRegion.bufferImageCopy	= bufferImageCopy;
3869
3870		params.regions.push_back(copyRegion);
3871
3872		imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
3873	}
3874
3875	{
3876		TestParams	params;
3877		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
3878		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
3879		params.src.image.extent		= defaultExtent;
3880		params.dst.buffer.size		= defaultSize * defaultSize;
3881
3882		const VkBufferImageCopy	bufferImageCopy	=
3883		{
3884			defaultSize * defaultHalfSize,				// VkDeviceSize				bufferOffset;
3885			0u,											// uint32_t					bufferRowLength;
3886			0u,											// uint32_t					bufferImageHeight;
3887			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
3888			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
3889			defaultHalfExtent							// VkExtent3D				imageExtent;
3890		};
3891		CopyRegion	copyRegion;
3892		copyRegion.bufferImageCopy	= bufferImageCopy;
3893
3894		params.regions.push_back(copyRegion);
3895
3896		imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
3897	}
3898
3899	{
3900		TestParams	params;
3901		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
3902		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
3903		params.src.image.extent		= defaultExtent;
3904		params.dst.buffer.size		= defaultSize * defaultSize;
3905
3906		const int			pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
3907		const VkDeviceSize	bufferSize	= pixelSize * params.dst.buffer.size;
3908		const VkDeviceSize	offsetSize	= pixelSize * defaultFourthSize * defaultFourthSize;
3909		deUint32			divisor		= 1;
3910		for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
3911		{
3912			const deUint32			bufferRowLength		= defaultFourthSize;
3913			const deUint32			bufferImageHeight	= defaultFourthSize;
3914			const VkExtent3D		imageExtent			= {defaultFourthSize / divisor, defaultFourthSize, 1};
3915			DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
3916			DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
3917			DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
3918
3919			CopyRegion				region;
3920			const VkBufferImageCopy	bufferImageCopy		=
3921			{
3922				offset,						// VkDeviceSize				bufferOffset;
3923				bufferRowLength,			// uint32_t					bufferRowLength;
3924				bufferImageHeight,			// uint32_t					bufferImageHeight;
3925				defaultSourceLayer,			// VkImageSubresourceLayers	imageSubresource;
3926				{0, 0, 0},					// VkOffset3D				imageOffset;
3927				imageExtent					// VkExtent3D				imageExtent;
3928			};
3929			region.bufferImageCopy	= bufferImageCopy;
3930			params.regions.push_back(region);
3931		}
3932
3933		imageToBufferTests->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
3934	}
3935
3936	// Copy buffer to image testcases.
3937	{
3938		TestParams	params;
3939		params.src.buffer.size		= defaultSize * defaultSize;
3940		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
3941		params.dst.image.format		= VK_FORMAT_R8G8B8A8_UINT;
3942		params.dst.image.extent		= defaultExtent;
3943
3944		const VkBufferImageCopy	bufferImageCopy	=
3945		{
3946			0u,											// VkDeviceSize				bufferOffset;
3947			0u,											// uint32_t					bufferRowLength;
3948			0u,											// uint32_t					bufferImageHeight;
3949			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
3950			{0, 0, 0},									// VkOffset3D				imageOffset;
3951			defaultExtent								// VkExtent3D				imageExtent;
3952		};
3953		CopyRegion	copyRegion;
3954		copyRegion.bufferImageCopy	= bufferImageCopy;
3955
3956		params.regions.push_back(copyRegion);
3957
3958		bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
3959	}
3960
3961	{
3962		TestParams	params;
3963		params.src.buffer.size		= defaultSize * defaultSize;
3964		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
3965		params.dst.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
3966		params.dst.image.extent		= defaultExtent;
3967
3968		CopyRegion	region;
3969		deUint32	divisor	= 1;
3970		for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
3971		{
3972			const VkBufferImageCopy	bufferImageCopy	=
3973			{
3974				0u,																// VkDeviceSize				bufferOffset;
3975				0u,																// uint32_t					bufferRowLength;
3976				0u,																// uint32_t					bufferImageHeight;
3977				defaultSourceLayer,												// VkImageSubresourceLayers	imageSubresource;
3978				{offset, defaultHalfSize, 0},									// VkOffset3D				imageOffset;
3979				{defaultFourthSize / divisor, defaultFourthSize / divisor, 1}	// VkExtent3D				imageExtent;
3980			};
3981			region.bufferImageCopy	= bufferImageCopy;
3982			params.regions.push_back(region);
3983		}
3984
3985		bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
3986	}
3987
3988	{
3989		TestParams	params;
3990		params.src.buffer.size		= defaultSize * defaultSize;
3991		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
3992		params.dst.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
3993		params.dst.image.extent		= defaultExtent;
3994
3995		const VkBufferImageCopy	bufferImageCopy	=
3996		{
3997			defaultFourthSize,							// VkDeviceSize				bufferOffset;
3998			defaultHalfSize + defaultFourthSize,		// uint32_t					bufferRowLength;
3999			defaultHalfSize + defaultFourthSize,		// uint32_t					bufferImageHeight;
4000			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
4001			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
4002			defaultHalfExtent							// VkExtent3D				imageExtent;
4003		};
4004		CopyRegion	copyRegion;
4005		copyRegion.bufferImageCopy	= bufferImageCopy;
4006
4007		params.regions.push_back(copyRegion);
4008
4009		bufferToImageTests->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
4010	}
4011
4012	// Copy buffer to buffer testcases.
4013	{
4014		TestParams			params;
4015		params.src.buffer.size	= defaultSize;
4016		params.dst.buffer.size	= defaultSize;
4017
4018		const VkBufferCopy	bufferCopy	=
4019		{
4020			0u,				// VkDeviceSize	srcOffset;
4021			0u,				// VkDeviceSize	dstOffset;
4022			defaultSize,	// VkDeviceSize	size;
4023		};
4024
4025		CopyRegion	copyRegion;
4026		copyRegion.bufferCopy	= bufferCopy;
4027		params.regions.push_back(copyRegion);
4028
4029		bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
4030	}
4031
4032	{
4033		TestParams			params;
4034		params.src.buffer.size	= defaultFourthSize;
4035		params.dst.buffer.size	= defaultFourthSize;
4036
4037		const VkBufferCopy	bufferCopy	=
4038		{
4039			12u,	// VkDeviceSize	srcOffset;
4040			4u,		// VkDeviceSize	dstOffset;
4041			1u,		// VkDeviceSize	size;
4042		};
4043
4044		CopyRegion	copyRegion;
4045		copyRegion.bufferCopy = bufferCopy;
4046		params.regions.push_back(copyRegion);
4047
4048		bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
4049	}
4050
4051	{
4052		const deUint32		size		= 16;
4053		TestParams			params;
4054		params.src.buffer.size	= size;
4055		params.dst.buffer.size	= size * (size + 1);
4056
4057		// Copy region with size 1..size
4058		for (unsigned int i = 1; i <= size; i++)
4059		{
4060			const VkBufferCopy	bufferCopy	=
4061			{
4062				0,			// VkDeviceSize	srcOffset;
4063				i * size,	// VkDeviceSize	dstOffset;
4064				i,			// VkDeviceSize	size;
4065			};
4066
4067			CopyRegion	copyRegion;
4068			copyRegion.bufferCopy = bufferCopy;
4069			params.regions.push_back(copyRegion);
4070		}
4071
4072		bufferToBufferTests->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
4073	}
4074
4075	// Blitting testcases.
4076	{
4077		const std::string	description	("Blit without scaling (whole)");
4078		const std::string	testName	("whole");
4079
4080		TestParams			params;
4081		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4082		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4083		params.src.image.extent		= defaultExtent;
4084		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4085		params.dst.image.extent		= defaultExtent;
4086
4087		{
4088			const VkImageBlit				imageBlit	=
4089			{
4090				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4091				{
4092					{0, 0, 0},
4093					{defaultSize, defaultSize, 1}
4094				},					// VkOffset3D				srcOffsets[2];
4095
4096				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4097				{
4098					{0, 0, 0},
4099					{defaultSize, defaultSize, 1}
4100				}					// VkOffset3D				dstOffset[2];
4101			};
4102
4103			CopyRegion	region;
4104			region.imageBlit = imageBlit;
4105			params.regions.push_back(region);
4106		}
4107
4108		// Filter is VK_FILTER_NEAREST.
4109		{
4110			params.filter			= VK_FILTER_NEAREST;
4111
4112			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4113			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4114
4115			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4116			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
4117			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4118
4119			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4120			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4121			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4122		}
4123
4124		// Filter is VK_FILTER_LINEAR.
4125		{
4126			params.filter			= VK_FILTER_LINEAR;
4127
4128			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4129			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4130
4131			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4132			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4133			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4134
4135			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4136			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4137			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4138		}
4139	}
4140
4141	{
4142		const std::string	description	("Flipping x and y coordinates (whole)");
4143		const std::string	testName	("mirror_xy");
4144
4145		TestParams			params;
4146		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4147		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4148		params.src.image.extent		= defaultExtent;
4149		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4150		params.dst.image.extent		= defaultExtent;
4151
4152		{
4153			const VkImageBlit				imageBlit	=
4154			{
4155				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4156				{
4157					{0, 0, 0},
4158					{defaultSize, defaultSize, 1}
4159				},					// VkOffset3D				srcOffsets[2];
4160
4161				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4162				{
4163					{defaultSize, defaultSize, 0},
4164					{0, 0, 1}
4165				}					// VkOffset3D				dstOffset[2];
4166			};
4167
4168			CopyRegion	region;
4169			region.imageBlit = imageBlit;
4170			params.regions.push_back(region);
4171		}
4172
4173		// Filter is VK_FILTER_NEAREST.
4174		{
4175			params.filter			= VK_FILTER_NEAREST;
4176
4177			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4178			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4179
4180			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4181			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
4182			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4183
4184			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4185			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4186			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" +  getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4187		}
4188
4189		// Filter is VK_FILTER_LINEAR.
4190		{
4191			params.filter			= VK_FILTER_LINEAR;
4192
4193			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4194			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4195
4196			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4197			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4198			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4199
4200			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4201			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4202			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4203		}
4204	}
4205
4206	{
4207		const std::string	description	("Flipping x coordinates (whole)");
4208		const std::string	testName	("mirror_x");
4209
4210		TestParams			params;
4211		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4212		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4213		params.src.image.extent		= defaultExtent;
4214		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4215		params.dst.image.extent		= defaultExtent;
4216
4217		{
4218			const VkImageBlit				imageBlit	=
4219			{
4220				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4221				{
4222					{0, 0, 0},
4223					{defaultSize, defaultSize, 1}
4224				},					// VkOffset3D				srcOffsets[2];
4225
4226				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4227				{
4228					{defaultSize, 0, 0},
4229					{0, defaultSize, 1}
4230				}					// VkOffset3D				dstOffset[2];
4231			};
4232
4233			CopyRegion	region;
4234			region.imageBlit = imageBlit;
4235			params.regions.push_back(region);
4236		}
4237
4238		// Filter is VK_FILTER_NEAREST.
4239		{
4240			params.filter			= VK_FILTER_NEAREST;
4241
4242			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4243			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4244
4245			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4246			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
4247			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4248
4249			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4250			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4251			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4252		}
4253
4254		// Filter is VK_FILTER_LINEAR.
4255		{
4256			params.filter			= VK_FILTER_LINEAR;
4257
4258			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4259			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4260
4261			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4262			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4263			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4264
4265			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4266			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4267			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4268		}
4269	}
4270
4271	{
4272		const std::string	description	("Flipping Y coordinates (whole)");
4273		const std::string	testName	("mirror_y");
4274
4275		TestParams			params;
4276		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4277		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4278		params.src.image.extent		= defaultExtent;
4279		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4280		params.dst.image.extent		= defaultExtent;
4281
4282		{
4283			const VkImageBlit				imageBlit	=
4284			{
4285				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4286				{
4287					{0, 0, 0},
4288					{defaultSize, defaultSize, 1}
4289				},					// VkOffset3D				srcOffsets[2];
4290
4291				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4292				{
4293					{0, defaultSize, 0},
4294					{defaultSize, 0, 1}
4295				}					// VkOffset3D				dstOffset[2];
4296			};
4297
4298			CopyRegion	region;
4299			region.imageBlit = imageBlit;
4300			params.regions.push_back(region);
4301		}
4302
4303		// Filter is VK_FILTER_NEAREST.
4304		{
4305			params.filter			= VK_FILTER_NEAREST;
4306
4307			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4308			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4309
4310			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4311			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
4312			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4313
4314			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4315			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4316			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4317		}
4318
4319		// Filter is VK_FILTER_LINEAR.
4320		{
4321			params.filter			= VK_FILTER_LINEAR;
4322
4323			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4324			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4325
4326			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4327			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4328			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4329
4330			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4331			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4332			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4333		}
4334	}
4335
4336	{
4337		const std::string	description	("Mirroring subregions in image (no flip ,y flip ,x flip, xy flip)");
4338		const std::string	testName	("mirror_subregions");
4339
4340		TestParams			params;
4341		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4342		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4343		params.src.image.extent		= defaultExtent;
4344		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4345		params.dst.image.extent		= defaultExtent;
4346
4347		// No mirroring.
4348		{
4349			const VkImageBlit				imageBlit	=
4350			{
4351				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4352				{
4353					{0, 0, 0},
4354					{defaultHalfSize, defaultHalfSize, 1}
4355				},					// VkOffset3D				srcOffsets[2];
4356
4357				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4358				{
4359					{0, 0, 0},
4360					{defaultHalfSize, defaultHalfSize, 1}
4361				}					// VkOffset3D				dstOffset[2];
4362			};
4363
4364			CopyRegion	region;
4365			region.imageBlit = imageBlit;
4366			params.regions.push_back(region);
4367		}
4368
4369		// Flipping y coordinates.
4370		{
4371			const VkImageBlit				imageBlit	=
4372			{
4373				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4374				{
4375					{defaultHalfSize, 0, 0},
4376					{defaultSize, defaultHalfSize, 1}
4377				},					// VkOffset3D				srcOffsets[2];
4378
4379				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4380				{
4381					{defaultHalfSize, defaultHalfSize, 0},
4382					{defaultSize, 0, 1}
4383				}					// VkOffset3D				dstOffset[2];
4384			};
4385
4386			CopyRegion	region;
4387			region.imageBlit = imageBlit;
4388			params.regions.push_back(region);
4389		}
4390
4391		// Flipping x coordinates.
4392		{
4393			const VkImageBlit				imageBlit	=
4394			{
4395				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4396				{
4397					{0, defaultHalfSize, 0},
4398					{defaultHalfSize, defaultSize, 1}
4399				},					// VkOffset3D				srcOffsets[2];
4400
4401				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4402				{
4403					{defaultHalfSize, defaultHalfSize, 0},
4404					{0, defaultSize, 1}
4405				}					// VkOffset3D				dstOffset[2];
4406			};
4407
4408			CopyRegion	region;
4409			region.imageBlit = imageBlit;
4410			params.regions.push_back(region);
4411		}
4412
4413		// Flipping x and y coordinates.
4414		{
4415			const VkImageBlit				imageBlit	=
4416			{
4417				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4418				{
4419					{defaultHalfSize, defaultHalfSize, 0},
4420					{defaultSize, defaultSize, 1}
4421				},					// VkOffset3D				srcOffsets[2];
4422
4423				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4424				{
4425					{defaultSize, defaultSize, 0},
4426					{defaultHalfSize, defaultHalfSize, 1}
4427				}					// VkOffset3D				dstOffset[2];
4428			};
4429
4430			CopyRegion	region;
4431			region.imageBlit = imageBlit;
4432			params.regions.push_back(region);
4433		}
4434
4435		// Filter is VK_FILTER_NEAREST.
4436		{
4437			params.filter			= VK_FILTER_NEAREST;
4438
4439			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4440			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4441
4442			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4443			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
4444			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4445
4446			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4447			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4448			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4449		}
4450
4451		// Filter is VK_FILTER_LINEAR.
4452		{
4453			params.filter			= VK_FILTER_LINEAR;
4454
4455			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4456			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4457
4458			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4459			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4460			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4461
4462			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4463			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4464			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4465		}
4466	}
4467
4468	{
4469		const std::string	description	("Blit with scaling (whole, src extent bigger)");
4470		const std::string	testName	("scaling_whole1");
4471
4472		TestParams			params;
4473		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4474		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4475		params.src.image.extent		= defaultExtent;
4476		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4477		params.dst.image.extent		= defaultHalfExtent;
4478
4479		{
4480			const VkImageBlit				imageBlit	=
4481			{
4482				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4483				{
4484					{0, 0, 0},
4485					{defaultSize, defaultSize, 1}
4486				},					// VkOffset3D					srcOffsets[2];
4487
4488				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4489				{
4490					{0, 0, 0},
4491					{defaultHalfSize, defaultHalfSize, 1}
4492				}					// VkOffset3D					dstOffset[2];
4493			};
4494
4495			CopyRegion	region;
4496			region.imageBlit	= imageBlit;
4497			params.regions.push_back(region);
4498		}
4499
4500		// Filter is VK_FILTER_NEAREST.
4501		{
4502			params.filter			= VK_FILTER_NEAREST;
4503
4504			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4505			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4506
4507			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4508			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
4509			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4510
4511			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4512			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4513			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4514		}
4515
4516		// Filter is VK_FILTER_LINEAR.
4517		{
4518			params.filter			= VK_FILTER_LINEAR;
4519
4520			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4521			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4522
4523			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4524			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4525			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4526
4527			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4528			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4529			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4530		}
4531	}
4532
4533	{
4534		const std::string	description	("Blit with scaling (whole, dst extent bigger)");
4535		const std::string	testName	("scaling_whole2");
4536
4537		TestParams			params;
4538		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4539		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4540		params.src.image.extent		= defaultHalfExtent;
4541		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4542		params.dst.image.extent		= defaultExtent;
4543
4544		{
4545			const VkImageBlit				imageBlit	=
4546			{
4547				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4548				{
4549					{0, 0, 0},
4550					{defaultHalfSize, defaultHalfSize, 1}
4551				},					// VkOffset3D					srcOffsets[2];
4552
4553				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4554				{
4555					{0, 0, 0},
4556					{defaultSize, defaultSize, 1}
4557				}					// VkOffset3D					dstOffset[2];
4558			};
4559
4560			CopyRegion	region;
4561			region.imageBlit	= imageBlit;
4562			params.regions.push_back(region);
4563		}
4564
4565		// Filter is VK_FILTER_NEAREST.
4566		{
4567			params.filter			= VK_FILTER_NEAREST;
4568
4569			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4570			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4571
4572			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4573			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
4574			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4575
4576			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4577			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4578			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4579		}
4580
4581		// Filter is VK_FILTER_LINEAR.
4582		{
4583			params.filter			= VK_FILTER_LINEAR;
4584
4585			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4586			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4587
4588			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4589			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4590			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4591
4592			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4593			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4594			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4595		}
4596	}
4597
4598	{
4599		const std::string	description	("Blit with scaling and offset (whole, dst extent bigger)");
4600		const std::string	testName	("scaling_and_offset");
4601
4602		TestParams			params;
4603		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4604		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4605		params.src.image.extent		= defaultExtent;
4606		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4607		params.dst.image.extent		= defaultExtent;
4608
4609		{
4610			const VkImageBlit				imageBlit	=
4611			{
4612				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4613				{
4614					{defaultFourthSize, defaultFourthSize, 0},
4615					{defaultFourthSize*3, defaultFourthSize*3, 1}
4616				},					// VkOffset3D					srcOffsets[2];
4617
4618				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4619				{
4620					{0, 0, 0},
4621					{defaultSize, defaultSize, 1}
4622				}					// VkOffset3D					dstOffset[2];
4623			};
4624
4625			CopyRegion	region;
4626			region.imageBlit	= imageBlit;
4627			params.regions.push_back(region);
4628		}
4629
4630		// Filter is VK_FILTER_NEAREST.
4631		{
4632			params.filter			= VK_FILTER_NEAREST;
4633
4634			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4635			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4636
4637			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4638			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
4639			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4640
4641			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4642			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4643			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4644		}
4645
4646		// Filter is VK_FILTER_LINEAR.
4647		{
4648			params.filter			= VK_FILTER_LINEAR;
4649
4650			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4651			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4652
4653			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4654			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4655			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4656
4657			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4658			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4659			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4660		}
4661	}
4662
4663	{
4664		const std::string	description	("Blit without scaling (partial)");
4665		const std::string	testName	("without_scaling_partial");
4666
4667		TestParams			params;
4668		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4669		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4670		params.src.image.extent		= defaultExtent;
4671		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4672		params.dst.image.extent		= defaultExtent;
4673
4674		{
4675			CopyRegion	region;
4676			for (int i = 0; i < defaultSize; i += defaultFourthSize)
4677			{
4678				const VkImageBlit			imageBlit	=
4679				{
4680					defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4681					{
4682						{defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, 0},
4683						{defaultSize - i, defaultSize - i, 1}
4684					},					// VkOffset3D					srcOffsets[2];
4685
4686					defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4687					{
4688						{i, i, 0},
4689						{i + defaultFourthSize, i + defaultFourthSize, 1}
4690					}					// VkOffset3D					dstOffset[2];
4691				};
4692				region.imageBlit	= imageBlit;
4693				params.regions.push_back(region);
4694			}
4695		}
4696
4697		// Filter is VK_FILTER_NEAREST.
4698		{
4699			params.filter			= VK_FILTER_NEAREST;
4700
4701			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4702			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_nearest", description, params));
4703
4704
4705			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4706			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
4707			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
4708
4709			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4710			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
4711			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
4712		}
4713
4714		// Filter is VK_FILTER_LINEAR.
4715		{
4716			params.filter			= VK_FILTER_LINEAR;
4717
4718			params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
4719			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_linear", description + " (VK_FILTER_LINEAR)", params));
4720
4721			params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
4722			const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)" + " (VK_FILTER_LINEAR)");
4723			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
4724
4725			params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
4726			const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)" + " (VK_FILTER_LINEAR)");
4727			blitImgSimpleTests->addChild(new BlittingTestCase(testCtx, testName + "_" + getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
4728		}
4729	}
4730
4731	{
4732		const std::string	description	("Blit with scaling (partial)");
4733		const std::string	testName	("scaling_partial");
4734
4735		// Test Color formats.
4736		{
4737			TestParams	params;
4738			params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4739			params.src.image.extent		= defaultExtent;
4740			params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4741			params.dst.image.extent		= defaultExtent;
4742
4743			CopyRegion	region;
4744			for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
4745			{
4746				const VkImageBlit			imageBlit	=
4747				{
4748					defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4749					{
4750						{0, 0, 0},
4751						{defaultSize, defaultSize, 1}
4752					},					// VkOffset3D					srcOffsets[2];
4753
4754					defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4755					{
4756						{i, 0, 0},
4757						{i + defaultFourthSize / j, defaultFourthSize / j, 1}
4758					}					// VkOffset3D					dstOffset[2];
4759				};
4760				region.imageBlit	= imageBlit;
4761				params.regions.push_back(region);
4762			}
4763			for (int i = 0; i < defaultSize; i += defaultFourthSize)
4764			{
4765				const VkImageBlit			imageBlit	=
4766				{
4767					defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4768					{
4769						{i, i, 0},
4770						{i + defaultFourthSize, i + defaultFourthSize, 1}
4771					},					// VkOffset3D					srcOffsets[2];
4772
4773					defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4774					{
4775						{i, defaultSize / 2, 0},
4776						{i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}
4777					}					// VkOffset3D					dstOffset[2];
4778				};
4779				region.imageBlit	= imageBlit;
4780				params.regions.push_back(region);
4781			}
4782
4783			addBlittingTestsAllFormats(blitImgAllFormatsTests.get(), testCtx, params);
4784		}
4785
4786		// Test Depth and Stencil formats.
4787		{
4788			for (size_t compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
4789			{
4790				TestParams params;
4791
4792				params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4793				params.src.image.extent		= defaultExtent;
4794				params.dst.image.extent		= defaultExtent;
4795				params.src.image.format		= depthAndStencilFormats[compatibleFormatsIndex];
4796				params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4797				params.dst.image.format		= params.src.image.format;
4798				std::ostringstream	oss;
4799				oss << testName << "_" << getFormatCaseName(params.src.image.format) << "_" << getFormatCaseName(params.dst.image.format);
4800
4801				const VkImageSubresourceLayers	defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
4802				const VkImageSubresourceLayers	defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
4803
4804				CopyRegion	region;
4805				for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
4806				{
4807					const VkOffset3D	srcOffset0	= {0, 0, 0};
4808					const VkOffset3D	srcOffset1	= {defaultSize, defaultSize, 1};
4809					const VkOffset3D	dstOffset0	= {i, 0, 0};
4810					const VkOffset3D	dstOffset1	= {i + defaultFourthSize / j, defaultFourthSize / j, 1};
4811
4812					if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
4813					{
4814						const VkImageBlit			imageBlit	=
4815						{
4816							defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
4817							{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
4818							defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
4819							{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
4820						};
4821						region.imageBlit	= imageBlit;
4822						params.regions.push_back(region);
4823					}
4824					if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
4825					{
4826						const VkImageBlit			imageBlit	=
4827						{
4828							defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
4829							{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
4830							defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
4831							{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
4832						};
4833						region.imageBlit	= imageBlit;
4834						params.regions.push_back(region);
4835					}
4836				}
4837				for (int i = 0; i < defaultSize; i += defaultFourthSize)
4838				{
4839					const VkOffset3D	srcOffset0	= {i, i, 0};
4840					const VkOffset3D	srcOffset1	= {i + defaultFourthSize, i + defaultFourthSize, 1};
4841					const VkOffset3D	dstOffset0	= {i, defaultSize / 2, 0};
4842					const VkOffset3D	dstOffset1	= {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};
4843
4844					if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
4845					{
4846						const VkImageBlit			imageBlit	=
4847						{
4848							defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
4849							{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
4850							defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
4851							{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
4852						};
4853						region.imageBlit	= imageBlit;
4854						params.regions.push_back(region);
4855					}
4856					if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
4857					{
4858						const VkImageBlit			imageBlit	=
4859						{
4860							defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
4861							{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
4862							defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
4863							{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
4864						};
4865						region.imageBlit	= imageBlit;
4866						params.regions.push_back(region);
4867					}
4868				}
4869
4870				params.filter			= VK_FILTER_NEAREST;
4871				blitImgAllFormatsTests->addChild(new BlittingTestCase(testCtx, oss.str() + "_nearest", description, params));
4872			}
4873		}
4874	}
4875	blittingImageTests->addChild(blitImgSimpleTests.release());
4876	blittingImageTests->addChild(blitImgAllFormatsTests.release());
4877
4878	// Resolve image to image testcases.
4879	const VkSampleCountFlagBits	samples[]		=
4880	{
4881		VK_SAMPLE_COUNT_2_BIT,
4882		VK_SAMPLE_COUNT_4_BIT,
4883		VK_SAMPLE_COUNT_8_BIT,
4884		VK_SAMPLE_COUNT_16_BIT,
4885		VK_SAMPLE_COUNT_32_BIT,
4886		VK_SAMPLE_COUNT_64_BIT
4887	};
4888	const VkExtent3D			resolveExtent	= {256u, 256u, 1};
4889
4890	{
4891		const std::string	description	("Resolve from image to image");
4892		const std::string	testName	("whole");
4893
4894		TestParams			params;
4895		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4896		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4897		params.src.image.extent		= resolveExtent;
4898		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4899		params.dst.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4900		params.dst.image.extent		= resolveExtent;
4901
4902		{
4903			const VkImageSubresourceLayers	sourceLayer	=
4904			{
4905				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
4906				0u,							// uint32_t				mipLevel;
4907				0u,							// uint32_t				baseArrayLayer;
4908				1u							// uint32_t				layerCount;
4909			};
4910			const VkImageResolve			testResolve	=
4911			{
4912				sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4913				{0, 0, 0},		// VkOffset3D				srcOffset;
4914				sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4915				{0, 0, 0},		// VkOffset3D				dstOffset;
4916				resolveExtent,	// VkExtent3D				extent;
4917			};
4918
4919			CopyRegion	imageResolve;
4920			imageResolve.imageResolve	= testResolve;
4921			params.regions.push_back(imageResolve);
4922		}
4923
4924		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
4925		{
4926			params.samples = samples[samplesIndex];
4927			std::ostringstream caseName;
4928			caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
4929			resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params));
4930		}
4931	}
4932
4933	{
4934		const std::string	description	("Resolve from image to image");
4935		const std::string	testName	("partial");
4936
4937		TestParams			params;
4938		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4939		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4940		params.src.image.extent		= resolveExtent;
4941		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4942		params.dst.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4943		params.dst.image.extent		= resolveExtent;
4944
4945		{
4946			const VkImageSubresourceLayers	sourceLayer	=
4947			{
4948				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
4949				0u,							// uint32_t				mipLevel;
4950				0u,							// uint32_t				baseArrayLayer;
4951				1u							// uint32_t				layerCount;
4952			};
4953			const VkImageResolve			testResolve	=
4954			{
4955				sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4956				{0, 0, 0},		// VkOffset3D				srcOffset;
4957				sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4958				{64u, 64u, 0},		// VkOffset3D				dstOffset;
4959				{128u, 128u, 1u},	// VkExtent3D				extent;
4960			};
4961
4962			CopyRegion	imageResolve;
4963			imageResolve.imageResolve = testResolve;
4964			params.regions.push_back(imageResolve);
4965		}
4966
4967		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
4968		{
4969			params.samples = samples[samplesIndex];
4970			std::ostringstream caseName;
4971			caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
4972			resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params));
4973		}
4974	}
4975
4976	{
4977		const std::string	description	("Resolve from image to image");
4978		const std::string	testName	("with_regions");
4979
4980		TestParams			params;
4981		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4982		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4983		params.src.image.extent		= resolveExtent;
4984		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4985		params.dst.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
4986		params.dst.image.extent		= resolveExtent;
4987
4988		{
4989			const VkImageSubresourceLayers	sourceLayer	=
4990			{
4991				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
4992				0u,							// uint32_t				mipLevel;
4993				0u,							// uint32_t				baseArrayLayer;
4994				1u							// uint32_t				layerCount;
4995			};
4996
4997			for (int i = 0; i < 256; i += 64)
4998			{
4999				const VkImageResolve			testResolve	=
5000				{
5001					sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
5002					{i, i, 0},		// VkOffset3D				srcOffset;
5003					sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
5004					{i, 0, 0},		// VkOffset3D				dstOffset;
5005					{64u, 64u, 1u},	// VkExtent3D				extent;
5006				};
5007
5008				CopyRegion	imageResolve;
5009				imageResolve.imageResolve = testResolve;
5010				params.regions.push_back(imageResolve);
5011			}
5012		}
5013
5014		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
5015		{
5016			params.samples = samples[samplesIndex];
5017			std::ostringstream caseName;
5018			caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
5019			resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params));
5020		}
5021	}
5022
5023	{
5024		const std::string	description	("Resolve from image to image");
5025		const std::string	testName	("whole_copy_before_resolving");
5026
5027		TestParams			params;
5028		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
5029		params.src.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
5030		params.src.image.extent		= defaultExtent;
5031		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
5032		params.dst.image.format		= VK_FORMAT_R8G8B8A8_UNORM;
5033		params.dst.image.extent		= defaultExtent;
5034
5035		{
5036			const VkImageSubresourceLayers	sourceLayer	=
5037			{
5038				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5039				0u,							// uint32_t				mipLevel;
5040				0u,							// uint32_t				baseArrayLayer;
5041				1u							// uint32_t				layerCount;
5042			};
5043
5044			const VkImageResolve			testResolve	=
5045			{
5046				sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
5047				{0, 0, 0},			// VkOffset3D				srcOffset;
5048				sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
5049				{0, 0, 0},			// VkOffset3D				dstOffset;
5050				defaultExtent,		// VkExtent3D				extent;
5051			};
5052
5053			CopyRegion	imageResolve;
5054			imageResolve.imageResolve	= testResolve;
5055			params.regions.push_back(imageResolve);
5056		}
5057
5058		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
5059		{
5060			params.samples = samples[samplesIndex];
5061			std::ostringstream caseName;
5062			caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
5063			resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
5064		}
5065	}
5066
5067	{
5068		const std::string	description	("Resolve from image to image");
5069		const std::string	testName	("whole_array_image");
5070
5071		TestParams			params;
5072		params.src.image.imageType		= VK_IMAGE_TYPE_2D;
5073		params.src.image.format			= VK_FORMAT_R8G8B8A8_UNORM;
5074		params.src.image.extent			= defaultExtent;
5075		params.dst.image.imageType		= VK_IMAGE_TYPE_2D;
5076		params.dst.image.format			= VK_FORMAT_R8G8B8A8_UNORM;
5077		params.dst.image.extent			= defaultExtent;
5078		params.dst.image.extent.depth	= 5u;
5079
5080		for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
5081		{
5082			const VkImageSubresourceLayers	sourceLayer	=
5083			{
5084				VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
5085				0u,								// uint32_t				mipLevel;
5086				layerNdx,						// uint32_t				baseArrayLayer;
5087				1u								// uint32_t				layerCount;
5088			};
5089
5090			const VkImageResolve			testResolve	=
5091			{
5092				sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
5093				{0, 0, 0},			// VkOffset3D				srcOffset;
5094				sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
5095				{0, 0, 0},			// VkOffset3D				dstOffset;
5096				defaultExtent,		// VkExtent3D				extent;
5097			};
5098
5099			CopyRegion	imageResolve;
5100			imageResolve.imageResolve	= testResolve;
5101			params.regions.push_back(imageResolve);
5102		}
5103
5104		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
5105		{
5106			params.samples = samples[samplesIndex];
5107			std::ostringstream caseName;
5108			caseName << testName << "_" << getSampleCountCaseName(samples[samplesIndex]);
5109			resolveImageTests->addChild(new ResolveImageToImageTestCase(testCtx, caseName.str(), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
5110		}
5111	}
5112
5113	{
5114		TestParams	params3DTo2D;
5115		const deUint32	slicesLayers			= 16u;
5116		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
5117		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5118		params3DTo2D.src.image.extent			= defaultHalfExtent;
5119		params3DTo2D.src.image.extent.depth		= slicesLayers;
5120		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
5121		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5122		params3DTo2D.dst.image.extent			= defaultHalfExtent;
5123		params3DTo2D.dst.image.extent.depth		= slicesLayers;
5124
5125		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
5126		{
5127			const VkImageSubresourceLayers	sourceLayer	=
5128			{
5129				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5130				0u,							// uint32_t				mipLevel;
5131				0u,							// uint32_t				baseArrayLayer;
5132				1u							// uint32_t				layerCount;
5133			};
5134
5135			const VkImageSubresourceLayers	destinationLayer	=
5136			{
5137				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5138				0u,							// uint32_t				mipLevel;
5139				slicesLayersNdx,			// uint32_t				baseArrayLayer;
5140				1u							// uint32_t				layerCount;
5141			};
5142
5143			const VkImageCopy				testCopy	=
5144			{
5145				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
5146				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D					srcOffset;
5147				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
5148				{0, 0, 0},							// VkOffset3D					dstOffset;
5149				defaultHalfExtent,					// VkExtent3D					extent;
5150			};
5151
5152			CopyRegion	imageCopy;
5153			imageCopy.imageCopy	= testCopy;
5154
5155			params3DTo2D.regions.push_back(imageCopy);
5156		}
5157		imgToImg3dImagesTests->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
5158	}
5159
5160	{
5161		TestParams	params2DTo3D;
5162		const deUint32	slicesLayers			= 16u;
5163		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
5164		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5165		params2DTo3D.src.image.extent			= defaultHalfExtent;
5166		params2DTo3D.src.image.extent.depth		= slicesLayers;
5167		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
5168		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5169		params2DTo3D.dst.image.extent			= defaultHalfExtent;
5170		params2DTo3D.dst.image.extent.depth		= slicesLayers;
5171
5172		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
5173		{
5174			const VkImageSubresourceLayers	sourceLayer	=
5175			{
5176				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5177				0u,							// uint32_t				mipLevel;
5178				slicesLayersNdx,			// uint32_t				baseArrayLayer;
5179				1u							// uint32_t				layerCount;
5180			};
5181
5182			const VkImageSubresourceLayers	destinationLayer	=
5183			{
5184				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5185				0u,							// uint32_t				mipLevel;
5186				0u,							// uint32_t				baseArrayLayer;
5187				1u							// uint32_t				layerCount;
5188			};
5189
5190			const VkImageCopy				testCopy	=
5191			{
5192				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
5193				{0, 0, 0},							// VkOffset3D				srcOffset;
5194				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
5195				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D				dstOffset;
5196				defaultHalfExtent,					// VkExtent3D				extent;
5197			};
5198
5199			CopyRegion	imageCopy;
5200			imageCopy.imageCopy	= testCopy;
5201
5202			params2DTo3D.regions.push_back(imageCopy);
5203		}
5204
5205		imgToImg3dImagesTests->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
5206	}
5207
5208	{
5209		TestParams	params3DTo2D;
5210		const deUint32	slicesLayers			= 16u;
5211		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
5212		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5213		params3DTo2D.src.image.extent			= defaultHalfExtent;
5214		params3DTo2D.src.image.extent.depth		= slicesLayers;
5215		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
5216		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5217		params3DTo2D.dst.image.extent			= defaultHalfExtent;
5218		params3DTo2D.dst.image.extent.depth		= slicesLayers;
5219
5220		{
5221			const VkImageSubresourceLayers	sourceLayer	=
5222			{
5223				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5224				0u,							// uint32_t				mipLevel;
5225				0u,							// uint32_t				baseArrayLayer;
5226				1u							// uint32_t				layerCount;
5227			};
5228
5229			const VkImageSubresourceLayers	destinationLayer	=
5230			{
5231				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5232				0u,							// uint32_t				mipLevel;
5233				0,							// uint32_t				baseArrayLayer;
5234				slicesLayers				// uint32_t				layerCount;
5235			};
5236
5237			const VkImageCopy				testCopy	=
5238			{
5239				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
5240				{0, 0, 0},						// VkOffset3D				srcOffset;
5241				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
5242				{0, 0, 0},						// VkOffset3D				dstOffset;
5243				params3DTo2D.src.image.extent	// VkExtent3D				extent;
5244			};
5245
5246			CopyRegion	imageCopy;
5247			imageCopy.imageCopy	= testCopy;
5248
5249			params3DTo2D.regions.push_back(imageCopy);
5250		}
5251		imgToImg3dImagesTests->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
5252	}
5253
5254	{
5255		TestParams	params2DTo3D;
5256		const deUint32	slicesLayers			= 16u;
5257		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
5258		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5259		params2DTo3D.src.image.extent			= defaultHalfExtent;
5260		params2DTo3D.src.image.extent.depth		= slicesLayers;
5261		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
5262		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5263		params2DTo3D.dst.image.extent			= defaultHalfExtent;
5264		params2DTo3D.dst.image.extent.depth		= slicesLayers;
5265
5266		{
5267			const VkImageSubresourceLayers	sourceLayer	=
5268			{
5269				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5270				0u,							// uint32_t				mipLevel;
5271				0u,							// uint32_t				baseArrayLayer;
5272				slicesLayers				// uint32_t				layerCount;
5273			};
5274
5275			const VkImageSubresourceLayers	destinationLayer	=
5276			{
5277				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5278				0u,							// uint32_t				mipLevel;
5279				0u,							// uint32_t				baseArrayLayer;
5280				1u							// uint32_t				layerCount;
5281			};
5282
5283			const VkImageCopy				testCopy	=
5284			{
5285				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
5286				{0, 0, 0},						// VkOffset3D				srcOffset;
5287				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
5288				{0, 0, 0},						// VkOffset3D				dstOffset;
5289				params2DTo3D.dst.image.extent,	// VkExtent3D				extent;
5290			};
5291
5292			CopyRegion	imageCopy;
5293			imageCopy.imageCopy	= testCopy;
5294
5295			params2DTo3D.regions.push_back(imageCopy);
5296		}
5297
5298		imgToImg3dImagesTests->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
5299	}
5300
5301	{
5302		TestParams	params3DTo2D;
5303		const deUint32	slicesLayers			= 16u;
5304		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
5305		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5306		params3DTo2D.src.image.extent			= defaultHalfExtent;
5307		params3DTo2D.src.image.extent.depth		= slicesLayers;
5308		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
5309		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5310		params3DTo2D.dst.image.extent			= defaultHalfExtent;
5311		params3DTo2D.dst.image.extent.depth		= slicesLayers;
5312
5313		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
5314		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;
5315
5316		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
5317		{
5318			const VkImageSubresourceLayers	sourceLayer	=
5319			{
5320				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5321				0u,							// uint32_t				mipLevel;
5322				0u,							// uint32_t				baseArrayLayer;
5323				1u							// uint32_t				layerCount;
5324			};
5325
5326			const VkImageSubresourceLayers	destinationLayer	=
5327			{
5328					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
5329					0u,								// uint32_t				mipLevel;
5330					slicesLayersNdx,				// uint32_t				baseArrayLayer;
5331					1u								// uint32_t				layerCount;
5332			};
5333
5334
5335			const VkImageCopy				testCopy	=
5336			{
5337				sourceLayer,															// VkImageSubresourceLayers	srcSubresource;
5338				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx},	// VkOffset3D				srcOffset;
5339					destinationLayer,													// VkImageSubresourceLayers	dstSubresource;
5340					{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},						// VkOffset3D				dstOffset;
5341					{
5342						(defaultHalfExtent.width - regionWidth*slicesLayersNdx),
5343						(defaultHalfExtent.height - regionHeight*slicesLayersNdx),
5344						1
5345					}																	// VkExtent3D				extent;
5346			};
5347
5348			CopyRegion	imageCopy;
5349			imageCopy.imageCopy     = testCopy;
5350			params3DTo2D.regions.push_back(imageCopy);
5351		}
5352		imgToImg3dImagesTests->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
5353	}
5354
5355	{
5356		TestParams	params2DTo3D;
5357		const deUint32	slicesLayers			= 16u;
5358		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
5359		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5360		params2DTo3D.src.image.extent			= defaultHalfExtent;
5361		params2DTo3D.src.image.extent.depth		= slicesLayers;
5362		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
5363		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5364		params2DTo3D.dst.image.extent			= defaultHalfExtent;
5365		params2DTo3D.dst.image.extent.depth		= slicesLayers;
5366
5367		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
5368		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;
5369
5370		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
5371		{
5372			const VkImageSubresourceLayers	sourceLayer	=
5373			{
5374				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5375				0u,							// uint32_t				mipLevel;
5376				slicesLayersNdx,			// uint32_t				baseArrayLayer;
5377				1u							// uint32_t				layerCount;
5378			};
5379
5380			const VkImageSubresourceLayers	destinationLayer	=
5381			{
5382				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5383				0u,							// uint32_t				mipLevel;
5384				0u,							// uint32_t				baseArrayLayer;
5385				1u							// uint32_t				layerCount;
5386			};
5387
5388			const VkImageCopy				testCopy	=
5389			{
5390				sourceLayer,																// VkImageSubresourceLayers	srcSubresource;
5391				{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},								// VkOffset3D				srcOffset;
5392				destinationLayer,															// VkImageSubresourceLayers	dstSubresource;
5393				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)},	// VkOffset3D				dstOffset;
5394				{
5395					defaultHalfExtent.width - regionWidth*slicesLayersNdx,
5396					defaultHalfExtent.height - regionHeight*slicesLayersNdx,
5397					1
5398				}																			// VkExtent3D				extent;
5399			};
5400
5401			CopyRegion	imageCopy;
5402			imageCopy.imageCopy	= testCopy;
5403
5404			params2DTo3D.regions.push_back(imageCopy);
5405		}
5406
5407		imgToImg3dImagesTests->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
5408	}
5409
5410	imageToImageTests->addChild(imgToImg3dImagesTests.release());
5411
5412	copiesAndBlittingTests->addChild(imageToImageTests.release());
5413	copiesAndBlittingTests->addChild(imageToBufferTests.release());
5414	copiesAndBlittingTests->addChild(bufferToImageTests.release());
5415	copiesAndBlittingTests->addChild(bufferToBufferTests.release());
5416	copiesAndBlittingTests->addChild(blittingImageTests.release());
5417	copiesAndBlittingTests->addChild(resolveImageTests.release());
5418
5419	return copiesAndBlittingTests.release();
5420}
5421
5422} // api
5423} // vkt
5424