• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "tcuTestLog.hpp"
36 #include "tcuTexLookupVerifier.hpp"
37 
38 #include "vkImageUtil.hpp"
39 #include "vkMemUtil.hpp"
40 #include "vkPrograms.hpp"
41 #include "vkQueryUtil.hpp"
42 #include "vkRefUtil.hpp"
43 #include "vktTestCase.hpp"
44 #include "vktTestCaseUtil.hpp"
45 #include "vktTestGroupUtil.hpp"
46 #include "vkTypeUtil.hpp"
47 #include "vkCmdUtil.hpp"
48 #include "vkObjUtil.hpp"
49 
50 #include <set>
51 
52 namespace vkt
53 {
54 
55 namespace api
56 {
57 
58 namespace
59 {
60 enum MirrorMode
61 {
62 	MIRROR_MODE_NONE = 0,
63 	MIRROR_MODE_X = (1<<0),
64 	MIRROR_MODE_Y = (1<<1),
65 	MIRROR_MODE_XY = MIRROR_MODE_X | MIRROR_MODE_Y,
66 
67 	MIRROR_MODE_LAST
68 };
69 
70 enum AllocationKind
71 {
72 	ALLOCATION_KIND_SUBALLOCATED,
73 	ALLOCATION_KIND_DEDICATED,
74 };
75 
76 template <typename Type>
77 class BinaryCompare
78 {
79 public:
operator ()(const Type & a,const Type & b) const80 	bool operator() (const Type& a, const Type& b) const
81 	{
82 		return deMemCmp(&a, &b, sizeof(Type)) < 0;
83 	}
84 };
85 
86 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> >	FormatSet;
87 
88 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
89 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
90 
91 using namespace vk;
92 
getAspectFlags(tcu::TextureFormat format)93 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
94 {
95 	VkImageAspectFlags	aspectFlag	= 0;
96 	aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
97 	aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
98 
99 	if (!aspectFlag)
100 		aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
101 
102 	return aspectFlag;
103 }
104 
getAspectFlags(VkFormat format)105 VkImageAspectFlags getAspectFlags (VkFormat format)
106 {
107 	if (isCompressedFormat(format))
108 		return VK_IMAGE_ASPECT_COLOR_BIT;
109 	else
110 		return getAspectFlags(mapVkFormat(format));
111 }
112 
getSizeCompatibleTcuTextureFormat(VkFormat format)113 tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
114 {
115 	if (isCompressedFormat(format))
116 		return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
117 	else
118 		return mapVkFormat(format);
119 }
120 
121 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
122 // except that it supports some formats that are not mappable to VkFormat.
123 // When we are checking combined depth and stencil formats, each aspect is
124 // checked separately, and in some cases we construct PBA with a format that
125 // is not mappable to VkFormat.
isFloatFormat(tcu::TextureFormat format)126 bool isFloatFormat (tcu::TextureFormat format)
127 {
128 	return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
129 }
130 
131 union CopyRegion
132 {
133 	VkBufferCopy		bufferCopy;
134 	VkImageCopy			imageCopy;
135 	VkBufferImageCopy	bufferImageCopy;
136 	VkImageBlit			imageBlit;
137 	VkImageResolve		imageResolve;
138 };
139 
140 struct ImageParms
141 {
142 	VkImageType		imageType;
143 	VkFormat		format;
144 	VkExtent3D		extent;
145 	VkImageTiling	tiling;
146 	VkImageLayout	operationLayout;
147 };
148 
149 struct TestParams
150 {
151 	union Data
152 	{
153 		struct Buffer
154 		{
155 			VkDeviceSize	size;
156 		} buffer;
157 
158 		ImageParms	image;
159 	} src, dst;
160 
161 	std::vector<CopyRegion>	regions;
162 
163 	union
164 	{
165 		VkFilter				filter;
166 		VkSampleCountFlagBits	samples;
167 	};
168 
169 	AllocationKind	allocationKind;
170 	deUint32		mipLevels;
171 	deBool			singleCommand;
172 	deUint32		barrierCount;
173 
TestParamsvkt::api::__anonf5b779060111::TestParams174 	TestParams (void)
175 	{
176 		mipLevels		= 1u;
177 		singleCommand	= DE_TRUE;
178 		barrierCount	= 1u;
179 	}
180 };
181 
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)182 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&	vki,
183 										const DeviceInterface&		vkd,
184 										const VkPhysicalDevice&		physDevice,
185 										const VkDevice				device,
186 										const VkBuffer&				buffer,
187 										const MemoryRequirement		requirement,
188 										Allocator&					allocator,
189 										AllocationKind				allocationKind)
190 {
191 	switch (allocationKind)
192 	{
193 		case ALLOCATION_KIND_SUBALLOCATED:
194 		{
195 			const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
196 
197 			return allocator.allocate(memoryRequirements, requirement);
198 		}
199 
200 		case ALLOCATION_KIND_DEDICATED:
201 		{
202 			return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
203 		}
204 
205 		default:
206 		{
207 			TCU_THROW(InternalError, "Invalid allocation kind");
208 		}
209 	}
210 }
211 
allocateImage(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkImage & image,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)212 de::MovePtr<Allocation> allocateImage (const InstanceInterface&		vki,
213 									   const DeviceInterface&		vkd,
214 									   const VkPhysicalDevice&		physDevice,
215 									   const VkDevice				device,
216 									   const VkImage&				image,
217 									   const MemoryRequirement		requirement,
218 									   Allocator&					allocator,
219 									   AllocationKind				allocationKind)
220 {
221 	switch (allocationKind)
222 	{
223 		case ALLOCATION_KIND_SUBALLOCATED:
224 		{
225 			const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
226 
227 			return allocator.allocate(memoryRequirements, requirement);
228 		}
229 
230 		case ALLOCATION_KIND_DEDICATED:
231 		{
232 			return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
233 		}
234 
235 		default:
236 		{
237 			TCU_THROW(InternalError, "Invalid allocation kind");
238 		}
239 	}
240 }
241 
242 
getArraySize(const ImageParms & parms)243 inline deUint32 getArraySize(const ImageParms& parms)
244 {
245 	return (parms.imageType == VK_IMAGE_TYPE_2D) ? parms.extent.depth : 1u;
246 }
247 
getCreateFlags(const ImageParms & parms)248 inline VkImageCreateFlags getCreateFlags(const ImageParms& parms)
249 {
250 	return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ?
251 		VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
252 }
253 
getExtent3D(const ImageParms & parms,deUint32 mipLevel=0u)254 inline VkExtent3D getExtent3D(const ImageParms& parms, deUint32 mipLevel = 0u)
255 {
256 	const bool			isCompressed	= isCompressedFormat(parms.format);
257 	const deUint32		blockWidth		= (isCompressed) ? getBlockWidth(parms.format) : 1u;
258 	const deUint32		blockHeight		= (isCompressed) ? getBlockHeight(parms.format) : 1u;
259 
260 	if (isCompressed && mipLevel != 0u)
261 		DE_FATAL("Not implemented");
262 
263 	const VkExtent3D	extent			=
264 	{
265 		(parms.extent.width >> mipLevel) * blockWidth,
266 		(parms.extent.height >> mipLevel) * blockHeight,
267 		(parms.imageType == VK_IMAGE_TYPE_2D) ? 1u : parms.extent.depth
268 	};
269 	return extent;
270 }
271 
mapCombinedToDepthTransferFormat(const tcu::TextureFormat & combinedFormat)272 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
273 {
274 	tcu::TextureFormat format;
275 	switch (combinedFormat.type)
276 	{
277 		case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
278 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
279 			break;
280 		case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
281 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
282 			break;
283 		case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
284 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
285 			break;
286 		default:
287 			DE_ASSERT(false);
288 			break;
289 	}
290 	return format;
291 }
292 
293 class CopiesAndBlittingTestInstance : public vkt::TestInstance
294 {
295 public:
296 										CopiesAndBlittingTestInstance		(Context&	context,
297 																			 TestParams	testParams);
298 	virtual tcu::TestStatus				iterate								(void) = 0;
299 
300 	enum FillMode
301 	{
302 		FILL_MODE_GRADIENT = 0,
303 		FILL_MODE_WHITE,
304 		FILL_MODE_RED,
305 		FILL_MODE_MULTISAMPLE,
306 
307 		FILL_MODE_LAST
308 	};
309 
310 protected:
311 	const TestParams					m_params;
312 
313 	Move<VkCommandPool>					m_cmdPool;
314 	Move<VkCommandBuffer>				m_cmdBuffer;
315 	Move<VkFence>						m_fence;
316 	de::MovePtr<tcu::TextureLevel>		m_sourceTextureLevel;
317 	de::MovePtr<tcu::TextureLevel>		m_destinationTextureLevel;
318 	de::MovePtr<tcu::TextureLevel>		m_expectedTextureLevel[16];
319 
320 	VkCommandBufferBeginInfo			m_cmdBufferBeginInfo;
321 
322 	void								generateBuffer						(tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
323 	virtual void						generateExpectedResult				(void);
324 	void								uploadBuffer						(tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
325 	void								uploadImage							(const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u);
326 	virtual tcu::TestStatus				checkTestResult						(tcu::ConstPixelBufferAccess result);
327 	virtual void						copyRegionToTextureLevel			(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u) = 0;
calculateSize(tcu::ConstPixelBufferAccess src) const328 	deUint32							calculateSize						(tcu::ConstPixelBufferAccess src) const
329 										{
330 											return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
331 										}
332 
333 	de::MovePtr<tcu::TextureLevel>		readImage							(vk::VkImage				image,
334 																			 const ImageParms&			imageParms,
335 																			 const deUint32				mipLevel = 0u);
336 
337 private:
338 	void								uploadImageAspect					(const tcu::ConstPixelBufferAccess&	src,
339 																			 const VkImage&						dst,
340 																			 const ImageParms&					parms,
341 																			 const deUint32						mipLevels = 1u);
342 	void								readImageAspect						(vk::VkImage						src,
343 																			 const tcu::PixelBufferAccess&		dst,
344 																			 const ImageParms&					parms,
345 																			 const deUint32						mipLevel = 0u);
346 };
347 
CopiesAndBlittingTestInstance(Context & context,TestParams testParams)348 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
349 	: vkt::TestInstance	(context)
350 	, m_params			(testParams)
351 {
352 	const DeviceInterface&		vk					= context.getDeviceInterface();
353 	const VkDevice				vkDevice			= context.getDevice();
354 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
355 
356 	// Create command pool
357 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
358 
359 	// Create command buffer
360 	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
361 
362 	// Create fence
363 	m_fence = createFence(vk, vkDevice);
364 }
365 
generateBuffer(tcu::PixelBufferAccess buffer,int width,int height,int depth,FillMode mode)366 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
367 {
368 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(buffer.getFormat().type);
369 	tcu::Vec4						maxValue		(1.0f);
370 
371 	if (buffer.getFormat().order == tcu::TextureFormat::S)
372 	{
373 		// Stencil-only is stored in the first component. Stencil is always 8 bits.
374 		maxValue.x() = 1 << 8;
375 	}
376 	else if (buffer.getFormat().order == tcu::TextureFormat::DS)
377 	{
378 		// In a combined format, fillWithComponentGradients expects stencil in the fourth component.
379 		maxValue.w() = 1 << 8;
380 	}
381 	else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
382 	{
383 		// The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
384 		const tcu::IVec4	bits	= tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
385 		const int			signBit	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
386 
387 		for (int i = 0; i < 4; ++i)
388 		{
389 			if (bits[i] != 0)
390 				maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1);
391 		}
392 	}
393 
394 	if (mode == FILL_MODE_GRADIENT)
395 	{
396 		tcu::fillWithComponentGradients(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
397 		return;
398 	}
399 
400 	const tcu::Vec4		redColor	(maxValue.x(),	0.0,			0.0,			maxValue.w());
401 	const tcu::Vec4		greenColor	(0.0,			maxValue.y(),	0.0,			maxValue.w());
402 	const tcu::Vec4		blueColor	(0.0,			0.0,			maxValue.z(),	maxValue.w());
403 	const tcu::Vec4		whiteColor	(maxValue.x(),	maxValue.y(),	maxValue.z(),	maxValue.w());
404 
405 	for (int z = 0; z < depth;  ++z)
406 	for (int y = 0; y < height; ++y)
407 	for (int x = 0; x < width;  ++x)
408 	{
409 		switch (mode)
410 		{
411 			case FILL_MODE_WHITE:
412 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
413 				{
414 					buffer.setPixDepth(1.0f, x, y, z);
415 					if (tcu::hasStencilComponent(buffer.getFormat().order))
416 						buffer.setPixStencil(255, x, y, z);
417 				}
418 				else
419 					buffer.setPixel(whiteColor, x, y, z);
420 				break;
421 
422 			case FILL_MODE_RED:
423 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
424 				{
425 					buffer.setPixDepth(redColor[0], x, y, z);
426 					if (tcu::hasStencilComponent(buffer.getFormat().order))
427 						buffer.setPixStencil((int)redColor[3], x, y, z);
428 				}
429 				else
430 					buffer.setPixel(redColor, x, y, z);
431 				break;
432 
433 			case FILL_MODE_MULTISAMPLE:
434 			{
435 				float xScaled = static_cast<float>(x) / static_cast<float>(width);
436 				float yScaled = static_cast<float>(y) / static_cast<float>(height);
437 				buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
438 				break;
439 			}
440 
441 			default:
442 				break;
443 		}
444 	}
445 }
446 
uploadBuffer(tcu::ConstPixelBufferAccess bufferAccess,const Allocation & bufferAlloc)447 void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
448 {
449 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
450 	const VkDevice				vkDevice	= m_context.getDevice();
451 	const deUint32				bufferSize	= calculateSize(bufferAccess);
452 
453 	// Write buffer data
454 	deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
455 	flushAlloc(vk, vkDevice, bufferAlloc);
456 }
457 
uploadImageAspect(const tcu::ConstPixelBufferAccess & imageAccess,const VkImage & image,const ImageParms & parms,const deUint32 mipLevels)458 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels)
459 {
460 	const InstanceInterface&		vki					= m_context.getInstanceInterface();
461 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
462 	const VkPhysicalDevice			vkPhysDevice		= m_context.getPhysicalDevice();
463 	const VkDevice					vkDevice			= m_context.getDevice();
464 	const VkQueue					queue				= m_context.getUniversalQueue();
465 	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
466 	Allocator&						memAlloc			= m_context.getDefaultAllocator();
467 	Move<VkBuffer>					buffer;
468 	const deUint32					bufferSize			= calculateSize(imageAccess);
469 	de::MovePtr<Allocation>			bufferAlloc;
470 	const deUint32					arraySize			= getArraySize(parms);
471 	const VkExtent3D				imageExtent			= getExtent3D(parms);
472 	std::vector <VkBufferImageCopy>	copyRegions;
473 
474 	// Create source buffer
475 	{
476 		const VkBufferCreateInfo	bufferParams		=
477 		{
478 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
479 			DE_NULL,									// const void*			pNext;
480 			0u,											// VkBufferCreateFlags	flags;
481 			bufferSize,									// VkDeviceSize			size;
482 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
483 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
484 			1u,											// deUint32				queueFamilyIndexCount;
485 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
486 		};
487 
488 		buffer		= createBuffer(vk, vkDevice, &bufferParams);
489 		bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
490 		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
491 	}
492 
493 	// Barriers for copying buffer to image
494 	const VkBufferMemoryBarrier		preBufferBarrier	=
495 	{
496 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
497 		DE_NULL,										// const void*		pNext;
498 		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
499 		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
500 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
501 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
502 		*buffer,										// VkBuffer			buffer;
503 		0u,												// VkDeviceSize		offset;
504 		bufferSize										// VkDeviceSize		size;
505 	};
506 
507 	const VkImageAspectFlags		formatAspect		= getAspectFlags(parms.format);
508 	const bool						skipPreImageBarrier	= formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
509 														  getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT;
510 	const VkImageMemoryBarrier		preImageBarrier		=
511 	{
512 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
513 		DE_NULL,										// const void*				pNext;
514 		0u,												// VkAccessFlags			srcAccessMask;
515 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
516 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
517 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
518 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
519 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
520 		image,											// VkImage					image;
521 		{												// VkImageSubresourceRange	subresourceRange;
522 			formatAspect,	// VkImageAspectFlags	aspect;
523 			0u,				// deUint32				baseMipLevel;
524 			mipLevels,		// deUint32				mipLevels;
525 			0u,				// deUint32				baseArraySlice;
526 			arraySize,		// deUint32				arraySize;
527 		}
528 	};
529 
530 	const VkImageMemoryBarrier		postImageBarrier	=
531 	{
532 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
533 		DE_NULL,										// const void*				pNext;
534 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
535 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
536 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
537 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
538 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
539 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
540 		image,											// VkImage					image;
541 		{												// VkImageSubresourceRange	subresourceRange;
542 			formatAspect,				// VkImageAspectFlags	aspect;
543 			0u,							// deUint32				baseMipLevel;
544 			mipLevels,					// deUint32				mipLevels;
545 			0u,							// deUint32				baseArraySlice;
546 			arraySize,					// deUint32				arraySize;
547 		}
548 	};
549 
550 	for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
551 	{
552 		const VkExtent3D		copyExtent	=
553 		{
554 			imageExtent.width	>> mipLevelNdx,
555 			imageExtent.height	>> mipLevelNdx,
556 			imageExtent.depth
557 		};
558 
559 		const VkBufferImageCopy	copyRegion	=
560 		{
561 			0u,												// VkDeviceSize				bufferOffset;
562 			copyExtent.width,								// deUint32					bufferRowLength;
563 			copyExtent.height,								// deUint32					bufferImageHeight;
564 			{
565 				getAspectFlags(imageAccess.getFormat()),		// VkImageAspectFlags	aspect;
566 				mipLevelNdx,									// deUint32				mipLevel;
567 				0u,												// deUint32				baseArrayLayer;
568 				arraySize,										// deUint32				layerCount;
569 			},												// VkImageSubresourceLayers	imageSubresource;
570 			{ 0, 0, 0 },									// VkOffset3D				imageOffset;
571 			copyExtent										// VkExtent3D				imageExtent;
572 		};
573 
574 		copyRegions.push_back(copyRegion);
575 	}
576 
577 	// Write buffer data
578 	deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
579 	flushAlloc(vk, vkDevice, *bufferAlloc);
580 
581 	// Copy buffer to image
582 	beginCommandBuffer(vk, *m_cmdBuffer);
583 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
584 						  1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
585 	vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), &copyRegions[0]);
586 	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, &postImageBarrier);
587 	endCommandBuffer(vk, *m_cmdBuffer);
588 
589 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
590 }
591 
uploadImage(const tcu::ConstPixelBufferAccess & src,VkImage dst,const ImageParms & parms,const deUint32 mipLevels)592 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels)
593 {
594 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
595 	{
596 		if (tcu::hasDepthComponent(src.getFormat().order))
597 		{
598 			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
599 			tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
600 			uploadImageAspect(depthTexture.getAccess(), dst, parms);
601 		}
602 
603 		if (tcu::hasStencilComponent(src.getFormat().order))
604 		{
605 			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
606 			tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
607 			uploadImageAspect(stencilTexture.getAccess(), dst, parms);
608 		}
609 	}
610 	else
611 		uploadImageAspect(src, dst, parms, mipLevels);
612 }
613 
checkTestResult(tcu::ConstPixelBufferAccess result)614 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
615 {
616 	const tcu::ConstPixelBufferAccess	expected	= m_expectedTextureLevel[0]->getAccess();
617 
618 	if (isFloatFormat(result.getFormat()))
619 	{
620 		const tcu::Vec4	threshold (0.0f);
621 		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
622 			return tcu::TestStatus::fail("CopiesAndBlitting test");
623 	}
624 	else
625 	{
626 		const tcu::UVec4 threshold (0u);
627 		if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
628 			return tcu::TestStatus::fail("CopiesAndBlitting test");
629 	}
630 
631 	return tcu::TestStatus::pass("CopiesAndBlitting test");
632 }
633 
generateExpectedResult(void)634 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
635 {
636 	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
637 	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
638 
639 	m_expectedTextureLevel[0]	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
640 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
641 
642 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
643 		copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
644 }
645 
646 class CopiesAndBlittingTestCase : public vkt::TestCase
647 {
648 public:
CopiesAndBlittingTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description)649 							CopiesAndBlittingTestCase	(tcu::TestContext&			testCtx,
650 														 const std::string&			name,
651 														 const std::string&			description)
652 								: vkt::TestCase	(testCtx, name, description)
653 							{}
654 
655 	virtual TestInstance*	createInstance				(Context&					context) const = 0;
656 };
657 
readImageAspect(vk::VkImage image,const tcu::PixelBufferAccess & dst,const ImageParms & imageParms,const deUint32 mipLevel)658 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage					image,
659 													 const tcu::PixelBufferAccess&	dst,
660 													 const ImageParms&				imageParms,
661 													 const deUint32					mipLevel)
662 {
663 	const InstanceInterface&	vki					= m_context.getInstanceInterface();
664 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
665 	const VkPhysicalDevice		physDevice			= m_context.getPhysicalDevice();
666 	const VkDevice				device				= m_context.getDevice();
667 	const VkQueue				queue				= m_context.getUniversalQueue();
668 	Allocator&					allocator			= m_context.getDefaultAllocator();
669 
670 	Move<VkBuffer>				buffer;
671 	de::MovePtr<Allocation>		bufferAlloc;
672 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
673 	const VkDeviceSize			pixelDataSize		= calculateSize(dst);
674 	const VkExtent3D			imageExtent			= getExtent3D(imageParms, mipLevel);
675 
676 	// Create destination buffer
677 	{
678 		const VkBufferCreateInfo			bufferParams			=
679 		{
680 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
681 			DE_NULL,									// const void*			pNext;
682 			0u,											// VkBufferCreateFlags	flags;
683 			pixelDataSize,								// VkDeviceSize			size;
684 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
685 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
686 			1u,											// deUint32				queueFamilyIndexCount;
687 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
688 		};
689 
690 		buffer		= createBuffer(vk, device, &bufferParams);
691 		bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
692 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
693 
694 		deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
695 		flushAlloc(vk, device, *bufferAlloc);
696 	}
697 
698 	// Barriers for copying image to buffer
699 	const VkImageAspectFlags				formatAspect			= getAspectFlags(imageParms.format);
700 	const VkImageMemoryBarrier				imageBarrier			=
701 	{
702 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
703 		DE_NULL,									// const void*				pNext;
704 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
705 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
706 		imageParms.operationLayout,					// VkImageLayout			oldLayout;
707 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
708 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
709 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
710 		image,										// VkImage					image;
711 		{											// VkImageSubresourceRange	subresourceRange;
712 			formatAspect,			// VkImageAspectFlags	aspectMask;
713 			mipLevel,				// deUint32				baseMipLevel;
714 			1u,						// deUint32				mipLevels;
715 			0u,						// deUint32				baseArraySlice;
716 			getArraySize(imageParms)// deUint32				arraySize;
717 		}
718 	};
719 
720 	const VkBufferMemoryBarrier				bufferBarrier			=
721 	{
722 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
723 		DE_NULL,									// const void*		pNext;
724 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
725 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
726 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
727 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
728 		*buffer,									// VkBuffer			buffer;
729 		0u,											// VkDeviceSize		offset;
730 		pixelDataSize								// VkDeviceSize		size;
731 	};
732 
733 	const VkImageMemoryBarrier				postImageBarrier		=
734 	{
735 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
736 		DE_NULL,									// const void*				pNext;
737 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
738 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
739 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			oldLayout;
740 		imageParms.operationLayout,					// VkImageLayout			newLayout;
741 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
742 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
743 		image,										// VkImage					image;
744 		{
745 			formatAspect,								// VkImageAspectFlags	aspectMask;
746 			mipLevel,									// deUint32				baseMipLevel;
747 			1u,											// deUint32				mipLevels;
748 			0u,											// deUint32				baseArraySlice;
749 			getArraySize(imageParms)					// deUint32				arraySize;
750 		}											// VkImageSubresourceRange	subresourceRange;
751 	};
752 
753 	// Copy image to buffer
754 	const VkImageAspectFlags	aspect			= getAspectFlags(dst.getFormat());
755 	const VkBufferImageCopy		copyRegion		=
756 	{
757 		0u,								// VkDeviceSize				bufferOffset;
758 		imageExtent.width,				// deUint32					bufferRowLength;
759 		imageExtent.height,				// deUint32					bufferImageHeight;
760 		{
761 			aspect,							// VkImageAspectFlags		aspect;
762 			mipLevel,						// deUint32					mipLevel;
763 			0u,								// deUint32					baseArrayLayer;
764 			getArraySize(imageParms),		// deUint32					layerCount;
765 		},								// VkImageSubresourceLayers	imageSubresource;
766 		{ 0, 0, 0 },					// VkOffset3D				imageOffset;
767 		imageExtent						// VkExtent3D				imageExtent;
768 	};
769 
770 	beginCommandBuffer(vk, *m_cmdBuffer);
771 	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);
772 	vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
773 	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);
774 	endCommandBuffer(vk, *m_cmdBuffer);
775 
776 	submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
777 
778 	// Read buffer data
779 	invalidateAlloc(vk, device, *bufferAlloc);
780 	tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
781 }
782 
readImage(vk::VkImage image,const ImageParms & parms,const deUint32 mipLevel)783 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage	(vk::VkImage		image,
784 																		 const ImageParms&	parms,
785 																		 const deUint32		mipLevel)
786 {
787 	const tcu::TextureFormat		imageFormat	= getSizeCompatibleTcuTextureFormat(parms.format);
788 	de::MovePtr<tcu::TextureLevel>	resultLevel	(new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
789 
790 	if (tcu::isCombinedDepthStencilType(imageFormat.type))
791 	{
792 		if (tcu::hasDepthComponent(imageFormat.order))
793 		{
794 			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width, parms.extent.height, parms.extent.depth);
795 			readImageAspect(image, depthTexture.getAccess(), parms);
796 			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
797 		}
798 
799 		if (tcu::hasStencilComponent(imageFormat.order))
800 		{
801 			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width, parms.extent.height, parms.extent.depth);
802 			readImageAspect(image, stencilTexture.getAccess(), parms);
803 			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
804 		}
805 	}
806 	else
807 		readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
808 
809 	return resultLevel;
810 }
811 
812 // Copy from image to image.
813 
814 class CopyImageToImage : public CopiesAndBlittingTestInstance
815 {
816 public:
817 										CopyImageToImage			(Context&	context,
818 																	 TestParams params);
819 	virtual tcu::TestStatus				iterate						(void);
820 
821 protected:
822 	virtual tcu::TestStatus				checkTestResult				(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
823 
824 private:
825 	Move<VkImage>						m_source;
826 	de::MovePtr<Allocation>				m_sourceImageAlloc;
827 	Move<VkImage>						m_destination;
828 	de::MovePtr<Allocation>				m_destinationImageAlloc;
829 
830 	virtual void						copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
831 };
832 
CopyImageToImage(Context & context,TestParams params)833 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
834 	: CopiesAndBlittingTestInstance(context, params)
835 {
836 	const InstanceInterface&	vki					= context.getInstanceInterface();
837 	const DeviceInterface&		vk					= context.getDeviceInterface();
838 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
839 	const VkDevice				vkDevice			= context.getDevice();
840 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
841 	Allocator&					memAlloc			= context.getDefaultAllocator();
842 
843 	// Create source image
844 	{
845 		const VkImageCreateInfo	sourceImageParams		=
846 		{
847 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
848 			DE_NULL,								// const void*			pNext;
849 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
850 			m_params.src.image.imageType,			// VkImageType			imageType;
851 			m_params.src.image.format,				// VkFormat				format;
852 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
853 			1u,										// deUint32				mipLevels;
854 			getArraySize(m_params.src.image),		// deUint32				arraySize;
855 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
856 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
857 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
858 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
859 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
860 			1u,										// deUint32				queueFamilyCount;
861 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
862 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
863 		};
864 
865 		m_source				= createImage(vk, vkDevice, &sourceImageParams);
866 		m_sourceImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
867 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
868 	}
869 
870 	// Create destination image
871 	{
872 		const VkImageCreateInfo	destinationImageParams	=
873 		{
874 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
875 			DE_NULL,								// const void*			pNext;
876 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
877 			m_params.dst.image.imageType,			// VkImageType			imageType;
878 			m_params.dst.image.format,				// VkFormat				format;
879 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
880 			1u,										// deUint32				mipLevels;
881 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
882 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
883 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
884 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
885 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
886 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
887 			1u,										// deUint32				queueFamilyCount;
888 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
889 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
890 		};
891 
892 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
893 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
894 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
895 	}
896 }
897 
iterate(void)898 tcu::TestStatus CopyImageToImage::iterate (void)
899 {
900 	const bool					srcCompressed		= isCompressedFormat(m_params.src.image.format);
901 	const bool					dstCompressed		= isCompressedFormat(m_params.dst.image.format);
902 
903 	const tcu::TextureFormat	srcTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
904 	const tcu::TextureFormat	dstTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
905 
906 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
907 																				(int)m_params.src.image.extent.width,
908 																				(int)m_params.src.image.extent.height,
909 																				(int)m_params.src.image.extent.depth));
910 	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);
911 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
912 																				(int)m_params.dst.image.extent.width,
913 																				(int)m_params.dst.image.extent.height,
914 																				(int)m_params.dst.image.extent.depth));
915 	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);
916 	generateExpectedResult();
917 
918 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
919 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
920 
921 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
922 	const VkDevice				vkDevice			= m_context.getDevice();
923 	const VkQueue				queue				= m_context.getUniversalQueue();
924 
925 	std::vector<VkImageCopy>	imageCopies;
926 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
927 	{
928 		VkImageCopy imageCopy = m_params.regions[i].imageCopy;
929 
930 		// When copying between compressed and uncompressed formats the extent
931 		// members represent the texel dimensions of the source image.
932 		if (srcCompressed)
933 		{
934 			const deUint32	blockWidth	= getBlockWidth(m_params.src.image.format);
935 			const deUint32	blockHeight	= getBlockHeight(m_params.src.image.format);
936 
937 			imageCopy.srcOffset.x *= blockWidth;
938 			imageCopy.srcOffset.y *= blockHeight;
939 			imageCopy.extent.width *= blockWidth;
940 			imageCopy.extent.height *= blockHeight;
941 		}
942 
943 		if (dstCompressed)
944 		{
945 			const deUint32	blockWidth	= getBlockWidth(m_params.dst.image.format);
946 			const deUint32	blockHeight	= getBlockHeight(m_params.dst.image.format);
947 
948 			imageCopy.dstOffset.x *= blockWidth;
949 			imageCopy.dstOffset.y *= blockHeight;
950 		}
951 
952 		imageCopies.push_back(imageCopy);
953 	}
954 
955 	const VkImageMemoryBarrier	imageBarriers[]		=
956 	{
957 		// source image
958 		{
959 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
960 			DE_NULL,									// const void*				pNext;
961 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
962 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
963 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
964 			m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
965 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
966 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
967 			m_source.get(),								// VkImage					image;
968 			{											// VkImageSubresourceRange	subresourceRange;
969 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
970 				0u,								// deUint32				baseMipLevel;
971 				1u,								// deUint32				mipLevels;
972 				0u,								// deUint32				baseArraySlice;
973 				getArraySize(m_params.src.image)// deUint32				arraySize;
974 			}
975 		},
976 		// destination image
977 		{
978 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
979 			DE_NULL,									// const void*				pNext;
980 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
981 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
982 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
983 			m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
984 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
985 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
986 			m_destination.get(),						// VkImage					image;
987 			{											// VkImageSubresourceRange	subresourceRange;
988 				getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
989 				0u,								// deUint32				baseMipLevel;
990 				1u,								// deUint32				mipLevels;
991 				0u,								// deUint32				baseArraySlice;
992 				getArraySize(m_params.dst.image)// deUint32				arraySize;
993 			}
994 		},
995 	};
996 
997 	beginCommandBuffer(vk, *m_cmdBuffer);
998 	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);
999 	vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
1000 	endCommandBuffer(vk, *m_cmdBuffer);
1001 
1002 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1003 
1004 	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);
1005 
1006 	return checkTestResult(resultTextureLevel->getAccess());
1007 }
1008 
checkTestResult(tcu::ConstPixelBufferAccess result)1009 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
1010 {
1011 	const tcu::Vec4	fThreshold (0.0f);
1012 	const tcu::UVec4 uThreshold (0u);
1013 
1014 	if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1015 	{
1016 		if (tcu::hasDepthComponent(result.getFormat().order))
1017 		{
1018 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
1019 			const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
1020 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1021 
1022 			if (isFloatFormat(result.getFormat()))
1023 			{
1024 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1025 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1026 			}
1027 			else
1028 			{
1029 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1030 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1031 			}
1032 		}
1033 
1034 		if (tcu::hasStencilComponent(result.getFormat().order))
1035 		{
1036 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
1037 			const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
1038 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1039 
1040 			if (isFloatFormat(result.getFormat()))
1041 			{
1042 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1043 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1044 			}
1045 			else
1046 			{
1047 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1048 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1049 			}
1050 		}
1051 	}
1052 	else
1053 	{
1054 		if (isFloatFormat(result.getFormat()))
1055 		{
1056 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1057 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1058 		}
1059 		else if (isSnormFormat(mapTextureFormat(result.getFormat())))
1060 		{
1061 			// There may be an ambiguity between two possible binary representations of 1.0.
1062 			// Get rid of that by expanding the data to floats and re-normalizing again.
1063 
1064 			tcu::TextureLevel resultSnorm	(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
1065 			{
1066 				tcu::TextureLevel resultFloat	(tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
1067 
1068 				tcu::copy(resultFloat.getAccess(), result);
1069 				tcu::copy(resultSnorm, resultFloat.getAccess());
1070 			}
1071 
1072 			tcu::TextureLevel expectedSnorm	(m_expectedTextureLevel[0]->getFormat(), m_expectedTextureLevel[0]->getWidth(), m_expectedTextureLevel[0]->getHeight(), m_expectedTextureLevel[0]->getDepth());
1073 
1074 			{
1075 				tcu::TextureLevel expectedFloat	(tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
1076 
1077 				tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess());
1078 				tcu::copy(expectedSnorm, expectedFloat.getAccess());
1079 			}
1080 
1081 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT))
1082 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1083 		}
1084 		else
1085 		{
1086 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1087 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1088 		}
1089 	}
1090 
1091 	return tcu::TestStatus::pass("CopiesAndBlitting test");
1092 }
1093 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1094 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1095 {
1096 	DE_UNREF(mipLevel);
1097 
1098 	VkOffset3D	srcOffset	= region.imageCopy.srcOffset;
1099 	VkOffset3D	dstOffset	= region.imageCopy.dstOffset;
1100 	VkExtent3D	extent		= region.imageCopy.extent;
1101 
1102 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1103 	{
1104 		dstOffset.z = srcOffset.z;
1105 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1106 	}
1107 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1108 	{
1109 		srcOffset.z = dstOffset.z;
1110 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1111 	}
1112 
1113 
1114 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1115 	{
1116 		DE_ASSERT(src.getFormat() == dst.getFormat());
1117 
1118 		// Copy depth.
1119 		if (tcu::hasDepthComponent(src.getFormat().order))
1120 		{
1121 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1122 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1123 			tcu::copy(dstSubRegion, srcSubRegion);
1124 		}
1125 
1126 		// Copy stencil.
1127 		if (tcu::hasStencilComponent(src.getFormat().order))
1128 		{
1129 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1130 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1131 			tcu::copy(dstSubRegion, srcSubRegion);
1132 		}
1133 	}
1134 	else
1135 	{
1136 		const tcu::ConstPixelBufferAccess	srcSubRegion		= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1137 		// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1138 		const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1139 		const tcu::PixelBufferAccess		dstSubRegion		= tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1140 
1141 		tcu::copy(dstSubRegion, srcSubRegion);
1142 	}
1143 }
1144 
1145 class CopyImageToImageTestCase : public vkt::TestCase
1146 {
1147 public:
CopyImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1148 							CopyImageToImageTestCase	(tcu::TestContext&				testCtx,
1149 														 const std::string&				name,
1150 														 const std::string&				description,
1151 														 const TestParams				params)
1152 								: vkt::TestCase	(testCtx, name, description)
1153 								, m_params		(params)
1154 	{}
1155 
createInstance(Context & context) const1156 	virtual TestInstance*	createInstance				(Context&						context) const
1157 	{
1158 		return new CopyImageToImage(context, m_params);
1159 	}
1160 
checkSupport(Context & context) const1161 	virtual void			checkSupport				(Context&						context) const
1162 	{
1163 		if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1164 		{
1165 			if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_dedicated_allocation"))
1166 				TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1167 		}
1168 
1169 		if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1170 			(m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1171 		{
1172 			if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance1"))
1173 				TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1174 		}
1175 
1176 		VkImageFormatProperties properties;
1177 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1178 																					m_params.src.image.format,
1179 																					m_params.src.image.imageType,
1180 																					VK_IMAGE_TILING_OPTIMAL,
1181 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1182 																					0,
1183 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1184 			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1185 																					m_params.dst.image.format,
1186 																					m_params.dst.image.imageType,
1187 																					VK_IMAGE_TILING_OPTIMAL,
1188 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1189 																					0,
1190 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1191 		{
1192 			TCU_THROW(NotSupportedError, "Format not supported");
1193 		}
1194 	}
1195 
1196 private:
1197 	TestParams				m_params;
1198 };
1199 
1200 // Copy from buffer to buffer.
1201 
1202 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
1203 {
1204 public:
1205 								CopyBufferToBuffer			(Context& context, TestParams params);
1206 	virtual tcu::TestStatus		iterate						(void);
1207 private:
1208 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion, deUint32 mipLevel = 0u);
1209 	Move<VkBuffer>				m_source;
1210 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
1211 	Move<VkBuffer>				m_destination;
1212 	de::MovePtr<Allocation>		m_destinationBufferAlloc;
1213 };
1214 
CopyBufferToBuffer(Context & context,TestParams params)1215 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
1216 	: CopiesAndBlittingTestInstance	(context, params)
1217 {
1218 	const InstanceInterface&	vki					= context.getInstanceInterface();
1219 	const DeviceInterface&		vk					= context.getDeviceInterface();
1220 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
1221 	const VkDevice				vkDevice			= context.getDevice();
1222 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
1223 	Allocator&					memAlloc			= context.getDefaultAllocator();
1224 
1225 	// Create source buffer
1226 	{
1227 		const VkBufferCreateInfo	sourceBufferParams		=
1228 		{
1229 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1230 			DE_NULL,									// const void*			pNext;
1231 			0u,											// VkBufferCreateFlags	flags;
1232 			m_params.src.buffer.size,					// VkDeviceSize			size;
1233 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
1234 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1235 			1u,											// deUint32				queueFamilyIndexCount;
1236 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1237 		};
1238 
1239 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
1240 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1241 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1242 	}
1243 
1244 	// Create destination buffer
1245 	{
1246 		const VkBufferCreateInfo	destinationBufferParams	=
1247 		{
1248 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1249 			DE_NULL,									// const void*			pNext;
1250 			0u,											// VkBufferCreateFlags	flags;
1251 			m_params.dst.buffer.size,					// VkDeviceSize			size;
1252 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
1253 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1254 			1u,											// deUint32				queueFamilyIndexCount;
1255 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1256 		};
1257 
1258 		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
1259 		m_destinationBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1260 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1261 	}
1262 }
1263 
iterate(void)1264 tcu::TestStatus CopyBufferToBuffer::iterate (void)
1265 {
1266 	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
1267 	m_sourceTextureLevel		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
1268 	generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
1269 
1270 	const int dstLevelWidth		= (int)(m_params.dst.buffer.size/4);
1271 	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
1272 	generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_WHITE);
1273 
1274 	generateExpectedResult();
1275 
1276 	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
1277 	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
1278 
1279 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
1280 	const VkDevice				vkDevice	= m_context.getDevice();
1281 	const VkQueue				queue		= m_context.getUniversalQueue();
1282 
1283 	const VkBufferMemoryBarrier		srcBufferBarrier	=
1284 	{
1285 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
1286 		DE_NULL,									// const void*		pNext;
1287 		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
1288 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
1289 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
1290 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
1291 		*m_source,									// VkBuffer			buffer;
1292 		0u,											// VkDeviceSize		offset;
1293 		m_params.src.buffer.size					// VkDeviceSize		size;
1294 	};
1295 
1296 	const VkBufferMemoryBarrier		dstBufferBarrier	=
1297 	{
1298 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
1299 		DE_NULL,									// const void*		pNext;
1300 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
1301 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
1302 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
1303 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
1304 		*m_destination,								// VkBuffer			buffer;
1305 		0u,											// VkDeviceSize		offset;
1306 		m_params.dst.buffer.size					// VkDeviceSize		size;
1307 	};
1308 
1309 	std::vector<VkBufferCopy>		bufferCopies;
1310 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1311 		bufferCopies.push_back(m_params.regions[i].bufferCopy);
1312 
1313 	beginCommandBuffer(vk, *m_cmdBuffer);
1314 	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);
1315 	vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
1316 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1317 	endCommandBuffer(vk, *m_cmdBuffer);
1318 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
1319 
1320 	// Read buffer data
1321 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
1322 	invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
1323 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1324 
1325 	return checkTestResult(resultLevel->getAccess());
1326 }
1327 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1328 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1329 {
1330 	DE_UNREF(mipLevel);
1331 
1332 	deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
1333 			 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
1334 			 (size_t)region.bufferCopy.size);
1335 }
1336 
1337 class BufferToBufferTestCase : public vkt::TestCase
1338 {
1339 public:
BufferToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1340 							BufferToBufferTestCase	(tcu::TestContext&	testCtx,
1341 													 const std::string&	name,
1342 													 const std::string&	description,
1343 													 const TestParams	params)
1344 								: vkt::TestCase	(testCtx, name, description)
1345 								, m_params		(params)
1346 							{}
1347 
createInstance(Context & context) const1348 	virtual TestInstance*	createInstance			(Context& context) const
1349 							{
1350 								return new CopyBufferToBuffer(context, m_params);
1351 							}
1352 private:
1353 	TestParams				m_params;
1354 };
1355 
1356 // Copy from image to buffer.
1357 
1358 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
1359 {
1360 public:
1361 								CopyImageToBuffer			(Context&	context,
1362 															 TestParams	testParams);
1363 	virtual tcu::TestStatus		iterate						(void);
1364 private:
1365 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1366 
1367 	tcu::TextureFormat			m_textureFormat;
1368 	VkDeviceSize				m_bufferSize;
1369 
1370 	Move<VkImage>				m_source;
1371 	de::MovePtr<Allocation>		m_sourceImageAlloc;
1372 	Move<VkBuffer>				m_destination;
1373 	de::MovePtr<Allocation>		m_destinationBufferAlloc;
1374 };
1375 
CopyImageToBuffer(Context & context,TestParams testParams)1376 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
1377 	: CopiesAndBlittingTestInstance(context, testParams)
1378 	, m_textureFormat(mapVkFormat(testParams.src.image.format))
1379 	, m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
1380 {
1381 	const InstanceInterface&	vki					= context.getInstanceInterface();
1382 	const DeviceInterface&		vk					= context.getDeviceInterface();
1383 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
1384 	const VkDevice				vkDevice			= context.getDevice();
1385 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
1386 	Allocator&					memAlloc			= context.getDefaultAllocator();
1387 
1388 	// Create source image
1389 	{
1390 		const VkImageCreateInfo		sourceImageParams		=
1391 		{
1392 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1393 			DE_NULL,								// const void*			pNext;
1394 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
1395 			m_params.src.image.imageType,			// VkImageType			imageType;
1396 			m_params.src.image.format,				// VkFormat				format;
1397 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
1398 			1u,										// deUint32				mipLevels;
1399 			getArraySize(m_params.src.image),		// deUint32				arraySize;
1400 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1401 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1402 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1403 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1404 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1405 			1u,										// deUint32				queueFamilyCount;
1406 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1407 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1408 		};
1409 
1410 		m_source			= createImage(vk, vkDevice, &sourceImageParams);
1411 		m_sourceImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1412 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1413 	}
1414 
1415 	// Create destination buffer
1416 	{
1417 		const VkBufferCreateInfo	destinationBufferParams	=
1418 		{
1419 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1420 			DE_NULL,									// const void*			pNext;
1421 			0u,											// VkBufferCreateFlags	flags;
1422 			m_bufferSize,								// VkDeviceSize			size;
1423 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
1424 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1425 			1u,											// deUint32				queueFamilyIndexCount;
1426 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1427 		};
1428 
1429 		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
1430 		m_destinationBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1431 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1432 	}
1433 }
1434 
iterate(void)1435 tcu::TestStatus CopyImageToBuffer::iterate (void)
1436 {
1437 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1438 																				m_params.src.image.extent.width,
1439 																				m_params.src.image.extent.height,
1440 																				m_params.src.image.extent.depth));
1441 	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
1442 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1443 	generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
1444 
1445 	generateExpectedResult();
1446 
1447 	uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
1448 	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
1449 
1450 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
1451 	const VkDevice				vkDevice	= m_context.getDevice();
1452 	const VkQueue				queue		= m_context.getUniversalQueue();
1453 
1454 	// Barriers for copying image to buffer
1455 	const VkImageMemoryBarrier		imageBarrier		=
1456 	{
1457 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1458 		DE_NULL,									// const void*				pNext;
1459 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1460 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
1461 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1462 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
1463 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1464 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1465 		*m_source,									// VkImage					image;
1466 		{											// VkImageSubresourceRange	subresourceRange;
1467 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
1468 			0u,								// deUint32				baseMipLevel;
1469 			1u,								// deUint32				mipLevels;
1470 			0u,								// deUint32				baseArraySlice;
1471 			1u								// deUint32				arraySize;
1472 		}
1473 	};
1474 
1475 	const VkBufferMemoryBarrier		bufferBarrier		=
1476 	{
1477 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
1478 		DE_NULL,									// const void*		pNext;
1479 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
1480 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
1481 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
1482 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
1483 		*m_destination,								// VkBuffer			buffer;
1484 		0u,											// VkDeviceSize		offset;
1485 		m_bufferSize								// VkDeviceSize		size;
1486 	};
1487 
1488 	// Copy from image to buffer
1489 	std::vector<VkBufferImageCopy>	bufferImageCopies;
1490 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1491 		bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
1492 
1493 	beginCommandBuffer(vk, *m_cmdBuffer);
1494 	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);
1495 	vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
1496 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1497 	endCommandBuffer(vk, *m_cmdBuffer);
1498 
1499 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1500 
1501 	// Read buffer data
1502 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1503 	invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
1504 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1505 
1506 	return checkTestResult(resultLevel->getAccess());
1507 }
1508 
1509 class CopyImageToBufferTestCase : public vkt::TestCase
1510 {
1511 public:
CopyImageToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1512 							CopyImageToBufferTestCase	(tcu::TestContext&		testCtx,
1513 														 const std::string&		name,
1514 														 const std::string&		description,
1515 														 const TestParams		params)
1516 								: vkt::TestCase	(testCtx, name, description)
1517 								, m_params		(params)
1518 							{}
1519 
createInstance(Context & context) const1520 	virtual TestInstance*	createInstance				(Context&				context) const
1521 							{
1522 								return new CopyImageToBuffer(context, m_params);
1523 							}
1524 private:
1525 	TestParams				m_params;
1526 };
1527 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1528 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1529 {
1530 	DE_UNREF(mipLevel);
1531 
1532 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
1533 	if (!rowLength)
1534 		rowLength = region.bufferImageCopy.imageExtent.width;
1535 
1536 	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
1537 	if (!imageHeight)
1538 		imageHeight = region.bufferImageCopy.imageExtent.height;
1539 
1540 	const int			texelSize	= src.getFormat().getPixelSize();
1541 	const VkExtent3D	extent		= region.bufferImageCopy.imageExtent;
1542 	const VkOffset3D	srcOffset	= region.bufferImageCopy.imageOffset;
1543 	const int			texelOffset	= (int) region.bufferImageCopy.bufferOffset / texelSize;
1544 
1545 	for (deUint32 z = 0; z < extent.depth; z++)
1546 	{
1547 		for (deUint32 y = 0; y < extent.height; y++)
1548 		{
1549 			int									texelIndex		= texelOffset + (z * imageHeight + y) *	rowLength;
1550 			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z,
1551 																					region.bufferImageCopy.imageExtent.width, 1, 1);
1552 			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1553 			tcu::copy(dstSubRegion, srcSubRegion);
1554 		}
1555 	}
1556 }
1557 
1558 // Copy from buffer to image.
1559 
1560 class CopyBufferToImage : public CopiesAndBlittingTestInstance
1561 {
1562 public:
1563 								CopyBufferToImage			(Context&	context,
1564 															 TestParams	testParams);
1565 	virtual tcu::TestStatus		iterate						(void);
1566 private:
1567 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1568 
1569 	tcu::TextureFormat			m_textureFormat;
1570 	VkDeviceSize				m_bufferSize;
1571 
1572 	Move<VkBuffer>				m_source;
1573 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
1574 	Move<VkImage>				m_destination;
1575 	de::MovePtr<Allocation>		m_destinationImageAlloc;
1576 };
1577 
CopyBufferToImage(Context & context,TestParams testParams)1578 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
1579 	: CopiesAndBlittingTestInstance(context, testParams)
1580 	, m_textureFormat(mapVkFormat(testParams.dst.image.format))
1581 	, m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
1582 {
1583 	const InstanceInterface&	vki					= context.getInstanceInterface();
1584 	const DeviceInterface&		vk					= context.getDeviceInterface();
1585 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
1586 	const VkDevice				vkDevice			= context.getDevice();
1587 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
1588 	Allocator&					memAlloc			= context.getDefaultAllocator();
1589 
1590 	// Create source buffer
1591 	{
1592 		const VkBufferCreateInfo	sourceBufferParams		=
1593 		{
1594 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1595 			DE_NULL,									// const void*			pNext;
1596 			0u,											// VkBufferCreateFlags	flags;
1597 			m_bufferSize,								// VkDeviceSize			size;
1598 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
1599 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1600 			1u,											// deUint32				queueFamilyIndexCount;
1601 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1602 		};
1603 
1604 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
1605 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1606 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1607 	}
1608 
1609 	// Create destination image
1610 	{
1611 		const VkImageCreateInfo		destinationImageParams	=
1612 		{
1613 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1614 			DE_NULL,								// const void*			pNext;
1615 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
1616 			m_params.dst.image.imageType,			// VkImageType			imageType;
1617 			m_params.dst.image.format,				// VkFormat				format;
1618 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
1619 			1u,										// deUint32				mipLevels;
1620 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
1621 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1622 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1623 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1624 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1625 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1626 			1u,										// deUint32				queueFamilyCount;
1627 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1628 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1629 		};
1630 
1631 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
1632 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1633 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1634 	}
1635 }
1636 
iterate(void)1637 tcu::TestStatus CopyBufferToImage::iterate (void)
1638 {
1639 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
1640 	generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
1641 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1642 																					m_params.dst.image.extent.width,
1643 																					m_params.dst.image.extent.height,
1644 																					m_params.dst.image.extent.depth));
1645 
1646 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
1647 
1648 	generateExpectedResult();
1649 
1650 	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
1651 	uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
1652 
1653 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
1654 	const VkDevice				vkDevice	= m_context.getDevice();
1655 	const VkQueue				queue		= m_context.getUniversalQueue();
1656 
1657 	const VkImageMemoryBarrier	imageBarrier	=
1658 	{
1659 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1660 		DE_NULL,									// const void*				pNext;
1661 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1662 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
1663 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1664 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
1665 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1666 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1667 		*m_destination,								// VkImage					image;
1668 		{											// VkImageSubresourceRange	subresourceRange;
1669 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
1670 			0u,								// deUint32				baseMipLevel;
1671 			1u,								// deUint32				mipLevels;
1672 			0u,								// deUint32				baseArraySlice;
1673 			1u								// deUint32				arraySize;
1674 		}
1675 	};
1676 
1677 	// Copy from buffer to image
1678 	std::vector<VkBufferImageCopy>		bufferImageCopies;
1679 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1680 		bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
1681 
1682 	beginCommandBuffer(vk, *m_cmdBuffer);
1683 	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);
1684 	vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
1685 	endCommandBuffer(vk, *m_cmdBuffer);
1686 
1687 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1688 
1689 	de::MovePtr<tcu::TextureLevel>	resultLevel	= readImage(*m_destination, m_params.dst.image);
1690 
1691 	return checkTestResult(resultLevel->getAccess());
1692 }
1693 
1694 class CopyBufferToImageTestCase : public vkt::TestCase
1695 {
1696 public:
CopyBufferToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1697 							CopyBufferToImageTestCase	(tcu::TestContext&		testCtx,
1698 														 const std::string&		name,
1699 														 const std::string&		description,
1700 														 const TestParams		params)
1701 								: vkt::TestCase	(testCtx, name, description)
1702 								, m_params		(params)
1703 							{}
1704 
~CopyBufferToImageTestCase(void)1705 	virtual					~CopyBufferToImageTestCase	(void) {}
1706 
createInstance(Context & context) const1707 	virtual TestInstance*	createInstance				(Context&				context) const
1708 							{
1709 								return new CopyBufferToImage(context, m_params);
1710 							}
1711 private:
1712 	TestParams				m_params;
1713 };
1714 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1715 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1716 {
1717 	DE_UNREF(mipLevel);
1718 
1719 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
1720 	if (!rowLength)
1721 		rowLength = region.bufferImageCopy.imageExtent.width;
1722 
1723 	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
1724 	if (!imageHeight)
1725 		imageHeight = region.bufferImageCopy.imageExtent.height;
1726 
1727 	const int			texelSize	= dst.getFormat().getPixelSize();
1728 	const VkExtent3D	extent		= region.bufferImageCopy.imageExtent;
1729 	const VkOffset3D	dstOffset	= region.bufferImageCopy.imageOffset;
1730 	const int			texelOffset	= (int) region.bufferImageCopy.bufferOffset / texelSize;
1731 
1732 	for (deUint32 z = 0; z < extent.depth; z++)
1733 	{
1734 		for (deUint32 y = 0; y < extent.height; y++)
1735 		{
1736 			int									texelIndex		= texelOffset + (z * imageHeight + y) *	rowLength;
1737 			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1738 			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
1739 																					region.bufferImageCopy.imageExtent.width, 1, 1);
1740 			tcu::copy(dstSubRegion, srcSubRegion);
1741 		}
1742 	}
1743 }
1744 
1745 // Copy from image to image with scaling.
1746 
1747 class BlittingImages : public CopiesAndBlittingTestInstance
1748 {
1749 public:
1750 										BlittingImages					(Context&	context,
1751 																		 TestParams params);
1752 	virtual tcu::TestStatus				iterate							(void);
1753 protected:
1754 	virtual tcu::TestStatus				checkTestResult					(tcu::ConstPixelBufferAccess result);
1755 	virtual void						copyRegionToTextureLevel		(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1756 	virtual void						generateExpectedResult			(void);
1757 private:
1758 	bool								checkLinearFilteredResult		(const tcu::ConstPixelBufferAccess&	result,
1759 																		 const tcu::ConstPixelBufferAccess&	clampedReference,
1760 																		 const tcu::ConstPixelBufferAccess&	unclampedReference,
1761 																		 const tcu::TextureFormat&			sourceFormat);
1762 	bool								checkNearestFilteredResult		(const tcu::ConstPixelBufferAccess&	result,
1763 																		 const tcu::ConstPixelBufferAccess& source);
1764 
1765 	Move<VkImage>						m_source;
1766 	de::MovePtr<Allocation>				m_sourceImageAlloc;
1767 	Move<VkImage>						m_destination;
1768 	de::MovePtr<Allocation>				m_destinationImageAlloc;
1769 
1770 	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel;
1771 };
1772 
BlittingImages(Context & context,TestParams params)1773 BlittingImages::BlittingImages (Context& context, TestParams params)
1774 	: CopiesAndBlittingTestInstance(context, params)
1775 {
1776 	const InstanceInterface&	vki					= context.getInstanceInterface();
1777 	const DeviceInterface&		vk					= context.getDeviceInterface();
1778 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
1779 	const VkDevice				vkDevice			= context.getDevice();
1780 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
1781 	Allocator&					memAlloc			= context.getDefaultAllocator();
1782 
1783 	// Create source image
1784 	{
1785 		const VkImageCreateInfo		sourceImageParams		=
1786 		{
1787 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1788 			DE_NULL,								// const void*			pNext;
1789 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
1790 			m_params.src.image.imageType,			// VkImageType			imageType;
1791 			m_params.src.image.format,				// VkFormat				format;
1792 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
1793 			1u,										// deUint32				mipLevels;
1794 			getArraySize(m_params.src.image),		// deUint32				arraySize;
1795 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1796 			m_params.src.image.tiling,				// VkImageTiling		tiling;
1797 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1798 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1799 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1800 			1u,										// deUint32				queueFamilyCount;
1801 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1802 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1803 		};
1804 
1805 		m_source = createImage(vk, vkDevice, &sourceImageParams);
1806 		m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1807 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1808 	}
1809 
1810 	// Create destination image
1811 	{
1812 		const VkImageCreateInfo		destinationImageParams	=
1813 		{
1814 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1815 			DE_NULL,								// const void*			pNext;
1816 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
1817 			m_params.dst.image.imageType,			// VkImageType			imageType;
1818 			m_params.dst.image.format,				// VkFormat				format;
1819 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
1820 			1u,										// deUint32				mipLevels;
1821 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
1822 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1823 			m_params.dst.image.tiling,				// VkImageTiling		tiling;
1824 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1825 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1826 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1827 			1u,										// deUint32				queueFamilyCount;
1828 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1829 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1830 		};
1831 
1832 		m_destination = createImage(vk, vkDevice, &destinationImageParams);
1833 		m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1834 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1835 	}
1836 }
1837 
iterate(void)1838 tcu::TestStatus BlittingImages::iterate (void)
1839 {
1840 	const tcu::TextureFormat	srcTcuFormat		= mapVkFormat(m_params.src.image.format);
1841 	const tcu::TextureFormat	dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
1842 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1843 																				m_params.src.image.extent.width,
1844 																				m_params.src.image.extent.height,
1845 																				m_params.src.image.extent.depth));
1846 	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);
1847 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1848 																					 (int)m_params.dst.image.extent.width,
1849 																					 (int)m_params.dst.image.extent.height,
1850 																					 (int)m_params.dst.image.extent.depth));
1851 	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);
1852 	generateExpectedResult();
1853 
1854 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1855 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1856 
1857 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
1858 	const VkDevice				vkDevice			= m_context.getDevice();
1859 	const VkQueue				queue				= m_context.getUniversalQueue();
1860 
1861 	std::vector<VkImageBlit>	regions;
1862 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1863 		regions.push_back(m_params.regions[i].imageBlit);
1864 
1865 	// Barriers for copying image to buffer
1866 	const VkImageMemoryBarrier		srcImageBarrier		=
1867 	{
1868 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1869 		DE_NULL,									// const void*				pNext;
1870 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1871 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
1872 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1873 		m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
1874 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1875 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1876 		m_source.get(),								// VkImage					image;
1877 		{											// VkImageSubresourceRange	subresourceRange;
1878 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
1879 			0u,								// deUint32				baseMipLevel;
1880 			1u,								// deUint32				mipLevels;
1881 			0u,								// deUint32				baseArraySlice;
1882 			1u								// deUint32				arraySize;
1883 		}
1884 	};
1885 
1886 	const VkImageMemoryBarrier		dstImageBarrier		=
1887 	{
1888 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1889 		DE_NULL,									// const void*				pNext;
1890 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1891 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
1892 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1893 		m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
1894 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1895 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1896 		m_destination.get(),						// VkImage					image;
1897 		{											// VkImageSubresourceRange	subresourceRange;
1898 			getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
1899 			0u,								// deUint32				baseMipLevel;
1900 			1u,								// deUint32				mipLevels;
1901 			0u,								// deUint32				baseArraySlice;
1902 			1u								// deUint32				arraySize;
1903 		}
1904 	};
1905 
1906 	beginCommandBuffer(vk, *m_cmdBuffer);
1907 	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);
1908 	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, &dstImageBarrier);
1909 	vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)m_params.regions.size(), &regions[0], m_params.filter);
1910 	endCommandBuffer(vk, *m_cmdBuffer);
1911 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
1912 
1913 	de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
1914 
1915 	return checkTestResult(resultTextureLevel->getAccess());
1916 }
1917 
calculateFloatConversionError(int srcBits)1918 static float calculateFloatConversionError (int srcBits)
1919 {
1920 	if (srcBits > 0)
1921 	{
1922 		const int	clampedBits	= de::clamp<int>(srcBits, 0, 32);
1923 		const float	srcMaxValue	= de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
1924 		const float	error		= 1.0f / srcMaxValue;
1925 
1926 		return de::clamp<float>(error, 0.0f, 1.0f);
1927 	}
1928 	else
1929 		return 1.0f;
1930 }
1931 
getFormatThreshold(const tcu::TextureFormat & format)1932 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
1933 {
1934 	tcu::Vec4 threshold(0.01f);
1935 
1936 	switch (format.type)
1937 	{
1938 	case tcu::TextureFormat::HALF_FLOAT:
1939 		threshold = tcu::Vec4(0.005f);
1940 		break;
1941 
1942 	case tcu::TextureFormat::FLOAT:
1943 	case tcu::TextureFormat::FLOAT64:
1944 		threshold = tcu::Vec4(0.001f);
1945 		break;
1946 
1947 	case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
1948 		threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
1949 		break;
1950 
1951 	case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
1952 		threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
1953 		break;
1954 
1955 	default:
1956 		const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
1957 		threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
1958 				      calculateFloatConversionError(bits.y()),
1959 				      calculateFloatConversionError(bits.z()),
1960 				      calculateFloatConversionError(bits.w()));
1961 	}
1962 
1963 	// Return value matching the channel order specified by the format
1964 	if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
1965 		return threshold.swizzle(2, 1, 0, 3);
1966 	else
1967 		return threshold;
1968 }
1969 
checkLinearFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedExpected,const tcu::ConstPixelBufferAccess & unclampedExpected,const tcu::TextureFormat & srcFormat)1970 bool BlittingImages::checkLinearFilteredResult (const tcu::ConstPixelBufferAccess&	result,
1971 												const tcu::ConstPixelBufferAccess&	clampedExpected,
1972 												const tcu::ConstPixelBufferAccess&	unclampedExpected,
1973 												const tcu::TextureFormat&			srcFormat)
1974 {
1975 	tcu::TestLog&					log				(m_context.getTestContext().getLog());
1976 	const tcu::TextureFormat		dstFormat		= result.getFormat();
1977 	const tcu::TextureChannelClass	dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
1978 	const tcu::TextureChannelClass	srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
1979 	bool							isOk			= false;
1980 
1981 	log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
1982 
1983 	// if either of srcImage or dstImage was created with a signed/unsigned integer VkFormat,
1984 	// the other must also have been created with a signed/unsigned integer VkFormat
1985 	bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
1986 							  dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
1987 	bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
1988 							  srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
1989 	if (dstImageIsIntClass != srcImageIsIntClass)
1990 	{
1991 		log << tcu::TestLog::EndSection;
1992 		return false;
1993 	}
1994 
1995 	if (isFloatFormat(dstFormat))
1996 	{
1997 		const bool		srcIsSRGB	= tcu::isSRGB(srcFormat);
1998 		const tcu::Vec4	srcMaxDiff	= getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
1999 		const tcu::Vec4	dstMaxDiff	= getFormatThreshold(dstFormat);
2000 		const tcu::Vec4	threshold	= tcu::max(srcMaxDiff, dstMaxDiff);
2001 
2002 		isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
2003 		log << tcu::TestLog::EndSection;
2004 
2005 		if (!isOk)
2006 		{
2007 			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
2008 			isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
2009 			log << tcu::TestLog::EndSection;
2010 		}
2011 	}
2012 	else
2013 	{
2014 		tcu::UVec4	threshold;
2015 		// Calculate threshold depending on channel width of destination format.
2016 		const tcu::IVec4	bitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
2017 		for (deUint32 i = 0; i < 4; ++i)
2018 			threshold[i] = de::max( (0x1 << bitDepth[i]) / 256, 1);
2019 
2020 		isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
2021 		log << tcu::TestLog::EndSection;
2022 
2023 		if (!isOk)
2024 		{
2025 			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
2026 			isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
2027 			log << tcu::TestLog::EndSection;
2028 		}
2029 	}
2030 
2031 	return isOk;
2032 }
2033 
2034 //! Utility to encapsulate coordinate computation and loops.
2035 struct CompareEachPixelInEachRegion
2036 {
~CompareEachPixelInEachRegionvkt::api::__anonf5b779060111::CompareEachPixelInEachRegion2037 	virtual		 ~CompareEachPixelInEachRegion  (void) {}
2038 	virtual bool compare								(const void* pUserData, const int x, const int y, const int z, const tcu::Vec2& srcNormCoord) const = 0;
2039 
forEachvkt::api::__anonf5b779060111::CompareEachPixelInEachRegion2040 	bool forEach (const void*							pUserData,
2041 				  const std::vector<CopyRegion>&		regions,
2042 				  const int								sourceWidth,
2043 				  const int								sourceHeight,
2044 				  const int								sourceDepth,
2045 				  const tcu::PixelBufferAccess&			errorMask) const
2046 	{
2047 		bool compareOk = true;
2048 
2049 		for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
2050 		{
2051 			const VkImageBlit& blit = regionIter->imageBlit;
2052 
2053 			const int	xStart	= deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
2054 			const int	yStart	= deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
2055 			const int	xEnd	= deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
2056 			const int	yEnd	= deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
2057 			const float	xScale	= static_cast<float>(blit.srcOffsets[1].x - blit.srcOffsets[0].x) / static_cast<float>(blit.dstOffsets[1].x - blit.dstOffsets[0].x);
2058 			const float	yScale	= static_cast<float>(blit.srcOffsets[1].y - blit.srcOffsets[0].y) / static_cast<float>(blit.dstOffsets[1].y - blit.dstOffsets[0].y);
2059 			const float srcInvW	= 1.0f / static_cast<float>(sourceWidth);
2060 			const float srcInvH	= 1.0f / static_cast<float>(sourceHeight);
2061 
2062 			for (int z = 0; z < sourceDepth; z++)
2063 			for (int y = yStart; y < yEnd; y++)
2064 			for (int x = xStart; x < xEnd; x++)
2065 			{
2066 				const tcu::Vec2 srcNormCoord
2067 				(
2068 					(xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
2069 					(yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH
2070 				);
2071 
2072 				if (!compare(pUserData, x, y, z, srcNormCoord))
2073 				{
2074 					errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
2075 					compareOk = false;
2076 				}
2077 			}
2078 		}
2079 		return compareOk;
2080 	}
2081 };
2082 
getFloatOrFixedPointFormatThreshold(const tcu::TextureFormat & format)2083 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
2084 {
2085 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
2086 	const tcu::IVec4				bitDepth		= tcu::getTextureFormatBitDepth(format);
2087 
2088 	if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
2089 	{
2090 		return getFormatThreshold(format);
2091 	}
2092 	else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
2093 			 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
2094 	{
2095 		const bool	isSigned	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
2096 		const float	range		= isSigned ? 1.0f - (-1.0f)
2097 										   : 1.0f -   0.0f;
2098 
2099 		tcu::Vec4 v;
2100 		for (int i = 0; i < 4; ++i)
2101 		{
2102 			if (bitDepth[i] == 0)
2103 				v[i] = 1.0f;
2104 			else
2105 				v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
2106 		}
2107 		return v;
2108 	}
2109 	else
2110 	{
2111 		DE_ASSERT(0);
2112 		return tcu::Vec4();
2113 	}
2114 }
2115 
floatNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask,const std::vector<CopyRegion> & regions)2116 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess&	source,
2117 							  const tcu::ConstPixelBufferAccess&	result,
2118 							  const tcu::PixelBufferAccess&			errorMask,
2119 							  const std::vector<CopyRegion>&		regions)
2120 {
2121 	const tcu::Sampler		sampler		(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
2122 	tcu::LookupPrecision	precision;
2123 
2124 	{
2125 		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(result.getFormat());
2126 		const tcu::Vec4		srcMaxDiff	= getFloatOrFixedPointFormatThreshold(source.getFormat());
2127 		const tcu::Vec4		dstMaxDiff	= getFloatOrFixedPointFormatThreshold(result.getFormat());
2128 
2129 		precision.colorMask		 = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
2130 		precision.colorThreshold = tcu::max(srcMaxDiff, dstMaxDiff);
2131 	}
2132 
2133 	const struct Capture
2134 	{
2135 		const tcu::ConstPixelBufferAccess&	source;
2136 		const tcu::ConstPixelBufferAccess&	result;
2137 		const tcu::Sampler&					sampler;
2138 		const tcu::LookupPrecision&			precision;
2139 		const bool							isSRGB;
2140 	} capture =
2141 	{
2142 		source, result, sampler, precision, tcu::isSRGB(result.getFormat())
2143 	};
2144 
2145 	const struct Loop : CompareEachPixelInEachRegion
2146 	{
2147 		Loop (void) {}
2148 
2149 		bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec2& srcNormCoord) const
2150 		{
2151 			const Capture&					c					= *static_cast<const Capture*>(pUserData);
2152 			const tcu::TexLookupScaleMode	lookupScaleDontCare	= tcu::TEX_LOOKUP_SCALE_MINIFY;
2153 			tcu::Vec4						dstColor			= c.result.getPixel(x, y, z);
2154 
2155 			// TexLookupVerifier performs a conversion to linear space, so we have to as well
2156 			if (c.isSRGB)
2157 				dstColor = tcu::sRGBToLinear(dstColor);
2158 
2159 			return tcu::isLevel2DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, z, dstColor);
2160 		}
2161 	} loop;
2162 
2163 	return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
2164 }
2165 
intNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask,const std::vector<CopyRegion> & regions)2166 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess&	source,
2167 							const tcu::ConstPixelBufferAccess&	result,
2168 							const tcu::PixelBufferAccess&		errorMask,
2169 							const std::vector<CopyRegion>&		regions)
2170 {
2171 	const tcu::Sampler		sampler		(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
2172 	tcu::IntLookupPrecision	precision;
2173 
2174 	{
2175 		const tcu::IVec4	srcBitDepth	= tcu::getTextureFormatBitDepth(source.getFormat());
2176 		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(result.getFormat());
2177 
2178 		for (deUint32 i = 0; i < 4; ++i) {
2179 			precision.colorThreshold[i]	= de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
2180 			precision.colorMask[i]		= dstBitDepth[i] != 0;
2181 		}
2182 	}
2183 
2184 	// Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
2185 	// does the conversion on the fly without wasting memory, but this approach is more straightforward.
2186 	tcu::TextureLevel				convertedSourceTexture	(result.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
2187 	const tcu::PixelBufferAccess	convertedSource			= convertedSourceTexture.getAccess();
2188 
2189 	for (int z = 0; z < source.getDepth();	++z)
2190 	for (int y = 0; y < source.getHeight(); ++y)
2191 	for (int x = 0; x < source.getWidth();  ++x)
2192 		convertedSource.setPixel(source.getPixelInt(x, y, z), x, y, z);	// will be clamped to max. representable value
2193 
2194 	const struct Capture
2195 	{
2196 		const tcu::ConstPixelBufferAccess&	source;
2197 		const tcu::ConstPixelBufferAccess&	result;
2198 		const tcu::Sampler&					sampler;
2199 		const tcu::IntLookupPrecision&		precision;
2200 	} capture =
2201 	{
2202 		convertedSource, result, sampler, precision
2203 	};
2204 
2205 	const struct Loop : CompareEachPixelInEachRegion
2206 	{
2207 		Loop (void) {}
2208 
2209 		bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec2& srcNormCoord) const
2210 		{
2211 			const Capture&					c					= *static_cast<const Capture*>(pUserData);
2212 			const tcu::TexLookupScaleMode	lookupScaleDontCare	= tcu::TEX_LOOKUP_SCALE_MINIFY;
2213 			const tcu::IVec4				dstColor			= c.result.getPixelInt(x, y, z);
2214 
2215 			return tcu::isLevel2DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, z, dstColor);
2216 		}
2217 	} loop;
2218 
2219 	return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
2220 }
2221 
checkNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source)2222 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
2223 												 const tcu::ConstPixelBufferAccess& source)
2224 {
2225 	tcu::TestLog&					log				(m_context.getTestContext().getLog());
2226 	const tcu::TextureFormat		dstFormat		= result.getFormat();
2227 	const tcu::TextureFormat		srcFormat		= source.getFormat();
2228 	const tcu::TextureChannelClass	dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
2229 	const tcu::TextureChannelClass	srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
2230 
2231 	tcu::TextureLevel		errorMaskStorage	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight());
2232 	tcu::PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
2233 	tcu::Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
2234 	tcu::Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
2235 	bool					ok					= false;
2236 
2237 	tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
2238 
2239 	// if either of srcImage or dstImage was created with a signed/unsigned integer VkFormat,
2240 	// the other must also have been created with a signed/unsigned integer VkFormat
2241 	bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
2242 							  dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
2243 	bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
2244 							  srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
2245 	if (dstImageIsIntClass != srcImageIsIntClass)
2246 		return false;
2247 
2248 	if (dstImageIsIntClass)
2249 	{
2250 		ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
2251 	}
2252 	else
2253 		ok = floatNearestBlitCompare(source, result, errorMask, m_params.regions);
2254 
2255 	if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
2256 		tcu::computePixelScaleBias(result, pixelScale, pixelBias);
2257 
2258 	if (!ok)
2259 	{
2260 		log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
2261 			<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
2262 			<< tcu::TestLog::Image("ErrorMask",	"Error mask", errorMask)
2263 			<< tcu::TestLog::EndImageSet;
2264 	}
2265 	else
2266 	{
2267 		log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
2268 			<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
2269 			<< tcu::TestLog::EndImageSet;
2270 	}
2271 
2272 	return ok;
2273 }
2274 
checkTestResult(tcu::ConstPixelBufferAccess result)2275 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
2276 {
2277 	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR);
2278 	const std::string failMessage("Result image is incorrect");
2279 
2280 	if (m_params.filter == VK_FILTER_LINEAR)
2281 	{
2282 		if (tcu::isCombinedDepthStencilType(result.getFormat().type))
2283 		{
2284 			if (tcu::hasDepthComponent(result.getFormat().order))
2285 			{
2286 				const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
2287 				const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
2288 				const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
2289 				const tcu::ConstPixelBufferAccess		unclampedExpected	= tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
2290 				const tcu::TextureFormat				sourceFormat		= tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
2291 
2292 				if (!checkLinearFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
2293 					return tcu::TestStatus::fail(failMessage);
2294 			}
2295 
2296 			if (tcu::hasStencilComponent(result.getFormat().order))
2297 			{
2298 				const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
2299 				const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
2300 				const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
2301 				const tcu::ConstPixelBufferAccess		unclampedExpected	= tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
2302 				const tcu::TextureFormat				sourceFormat		= tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
2303 
2304 				if (!checkLinearFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
2305 					return tcu::TestStatus::fail(failMessage);
2306 			}
2307 		}
2308 		else
2309 		{
2310 			const tcu::TextureFormat	sourceFormat	= mapVkFormat(m_params.src.image.format);
2311 
2312 			if (!checkLinearFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
2313 				return tcu::TestStatus::fail(failMessage);
2314 		}
2315 	}
2316 	else // NEAREST filtering
2317 	{
2318 		if (tcu::isCombinedDepthStencilType(result.getFormat().type))
2319 		{
2320 			if (tcu::hasDepthComponent(result.getFormat().order))
2321 			{
2322 				const tcu::Sampler::DepthStencilMode	mode			= tcu::Sampler::MODE_DEPTH;
2323 				const tcu::ConstPixelBufferAccess		depthResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
2324 				const tcu::ConstPixelBufferAccess		depthSource		= tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
2325 
2326 				if (!checkNearestFilteredResult(depthResult, depthSource))
2327 					return tcu::TestStatus::fail(failMessage);
2328 			}
2329 
2330 			if (tcu::hasStencilComponent(result.getFormat().order))
2331 			{
2332 				const tcu::Sampler::DepthStencilMode	mode			= tcu::Sampler::MODE_STENCIL;
2333 				const tcu::ConstPixelBufferAccess		stencilResult	= tcu::getEffectiveDepthStencilAccess(result, mode);
2334 				const tcu::ConstPixelBufferAccess		stencilSource	= tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
2335 
2336 				if (!checkNearestFilteredResult(stencilResult, stencilSource))
2337 					return tcu::TestStatus::fail(failMessage);
2338 			}
2339 		}
2340 		else
2341 		{
2342 			if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
2343 				return tcu::TestStatus::fail(failMessage);
2344 		}
2345 	}
2346 
2347 	return tcu::TestStatus::pass("Pass");
2348 }
2349 
linearToSRGBIfNeeded(const tcu::TextureFormat & format,const tcu::Vec4 & color)2350 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
2351 {
2352 	return isSRGB(format) ? linearToSRGB(color) : color;
2353 }
2354 
scaleFromWholeSrcBuffer(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const VkOffset3D regionOffset,const VkOffset3D regionExtent,tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode=MIRROR_MODE_NONE)2355 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = MIRROR_MODE_NONE)
2356 {
2357 	DE_ASSERT(filter == tcu::Sampler::LINEAR);
2358 	DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1);
2359 
2360 	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
2361 					filter, filter, 0.0f, false);
2362 
2363 	float sX = (float)regionExtent.x / (float)dst.getWidth();
2364 	float sY = (float)regionExtent.y / (float)dst.getHeight();
2365 
2366 	for (int y = 0; y < dst.getHeight(); y++)
2367 	for (int x = 0; x < dst.getWidth(); x++)
2368 	{
2369 		float srcX = (mirrorMode == MIRROR_MODE_X || mirrorMode == MIRROR_MODE_XY) ? (float)regionExtent.x + (float)regionOffset.x - ((float)x+0.5f)*sX : (float)regionOffset.x + ((float)x+0.5f)*sX;
2370 		float srcY = (mirrorMode == MIRROR_MODE_Y || mirrorMode == MIRROR_MODE_XY) ? (float)regionExtent.y + (float)regionOffset.y - ((float)y+0.5f)*sY : (float)regionOffset.y + ((float)y+0.5f)*sY;
2371 		dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x, y);
2372 	}
2373 }
2374 
blit(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode)2375 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
2376 {
2377 	DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR);
2378 
2379 	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
2380 						 filter, filter, 0.0f, false);
2381 
2382 	const float sX = (float)src.getWidth() / (float)dst.getWidth();
2383 	const float sY = (float)src.getHeight() / (float)dst.getHeight();
2384 	const float sZ = (float)src.getDepth() / (float)dst.getDepth();
2385 
2386 	tcu::Mat2 rotMatrix;
2387 	rotMatrix(0,0) = (mirrorMode & MIRROR_MODE_X) ? -1.0f : 1.0f;
2388 	rotMatrix(0,1) = 0.0f;
2389 	rotMatrix(1,0) = 0.0f;
2390 	rotMatrix(1,1) = (mirrorMode & MIRROR_MODE_Y) ? -1.0f : 1.0f;
2391 
2392 	const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
2393 	const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
2394 
2395 	if (dst.getDepth() == 1 && src.getDepth() == 1)
2396 	{
2397 		for (int y = 0; y < dst.getHeight(); ++y)
2398 		for (int x = 0; x < dst.getWidth(); ++x)
2399 		{
2400 			const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y);
2401 			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);
2402 		}
2403 	}
2404 	else
2405 	{
2406 		for (int z = 0; z < dst.getDepth(); ++z)
2407 		for (int y = 0; y < dst.getHeight(); ++y)
2408 		for (int x = 0; x < dst.getWidth(); ++x)
2409 		{
2410 			const tcu::Vec2 xy = rotMatrix * tcu::Vec2((float)x,(float)y);
2411 			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);
2412 		}
2413 	}
2414 }
2415 
flipCoordinates(CopyRegion & region,const MirrorMode mirrorMode)2416 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
2417 {
2418 	const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
2419 	const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
2420 	const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
2421 	const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
2422 
2423 	if (mirrorMode > MIRROR_MODE_NONE && mirrorMode < MIRROR_MODE_LAST)
2424 	{
2425 		//sourceRegion
2426 		region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
2427 		region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
2428 
2429 		region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
2430 		region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
2431 
2432 		//destinationRegion
2433 		region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
2434 		region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
2435 
2436 		region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
2437 		region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
2438 	}
2439 }
2440 
getMirrorMode(const VkOffset3D x1,const VkOffset3D x2)2441 MirrorMode getMirrorMode(const VkOffset3D x1, const VkOffset3D x2)
2442 {
2443 	if (x1.x >= x2.x && x1.y >= x2.y)
2444 	{
2445 		return MIRROR_MODE_XY;
2446 	}
2447 	else if (x1.x <= x2.x && x1.y <= x2.y)
2448 	{
2449 		return MIRROR_MODE_NONE;
2450 	}
2451 	else if (x1.x <= x2.x && x1.y >= x2.y)
2452 	{
2453 		return MIRROR_MODE_Y;
2454 	}
2455 	else if (x1.x >= x2.x && x1.y <= x2.y)
2456 	{
2457 		return MIRROR_MODE_X;
2458 	}
2459 	return MIRROR_MODE_LAST;
2460 }
2461 
getMirrorMode(const VkOffset3D s1,const VkOffset3D s2,const VkOffset3D d1,const VkOffset3D d2)2462 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
2463 {
2464 	const MirrorMode source		 = getMirrorMode(s1, s2);
2465 	const MirrorMode destination = getMirrorMode(d1, d2);
2466 
2467 	if (source == destination)
2468 	{
2469 		return MIRROR_MODE_NONE;
2470 	}
2471 	else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_X)	  || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_X) ||
2472 			 (source == MIRROR_MODE_Y && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_Y && source == MIRROR_MODE_NONE))
2473 	{
2474 		return MIRROR_MODE_Y;
2475 	}
2476 	else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_Y)	  || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_Y) ||
2477 			 (source == MIRROR_MODE_X && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_X && source == MIRROR_MODE_NONE))
2478 	{
2479 		return MIRROR_MODE_X;
2480 	}
2481 	else if ((source == MIRROR_MODE_XY && destination == MIRROR_MODE_NONE) || (destination == MIRROR_MODE_XY && source == MIRROR_MODE_NONE))
2482 	{
2483 		return MIRROR_MODE_XY;
2484 	}
2485 	return MIRROR_MODE_LAST;
2486 }
2487 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2488 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2489 {
2490 	DE_UNREF(mipLevel);
2491 
2492 	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
2493 												region.imageBlit.srcOffsets[1],
2494 												region.imageBlit.dstOffsets[0],
2495 												region.imageBlit.dstOffsets[1]);
2496 
2497 	flipCoordinates(region, mirrorMode);
2498 
2499 	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
2500 	const VkOffset3D					srcExtent		=
2501 	{
2502 		region.imageBlit.srcOffsets[1].x - srcOffset.x,
2503 		region.imageBlit.srcOffsets[1].y - srcOffset.y,
2504 		region.imageBlit.srcOffsets[1].z - srcOffset.z
2505 	};
2506 	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
2507 	const VkOffset3D					dstExtent		=
2508 	{
2509 		region.imageBlit.dstOffsets[1].x - dstOffset.x,
2510 		region.imageBlit.dstOffsets[1].y - dstOffset.y,
2511 		region.imageBlit.dstOffsets[1].z - dstOffset.z
2512 	};
2513 	const tcu::Sampler::FilterMode		filter			= (m_params.filter == VK_FILTER_LINEAR) ? tcu::Sampler::LINEAR : tcu::Sampler::NEAREST;
2514 
2515 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
2516 	{
2517 		DE_ASSERT(src.getFormat() == dst.getFormat());
2518 		// Scale depth.
2519 		if (tcu::hasDepthComponent(src.getFormat().order))
2520 		{
2521 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
2522 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
2523 			tcu::scale(dstSubRegion, srcSubRegion, filter);
2524 
2525 			if (filter == tcu::Sampler::LINEAR)
2526 			{
2527 				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
2528 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
2529 				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
2530 			}
2531 		}
2532 
2533 		// Scale stencil.
2534 		if (tcu::hasStencilComponent(src.getFormat().order))
2535 		{
2536 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
2537 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
2538 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
2539 
2540 			if (filter == tcu::Sampler::LINEAR)
2541 			{
2542 				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
2543 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
2544 				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
2545 			}
2546 		}
2547 	}
2548 	else
2549 	{
2550 		const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y);
2551 		const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
2552 		blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
2553 
2554 		if (filter == tcu::Sampler::LINEAR)
2555 		{
2556 			const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y);
2557 			scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
2558 		}
2559 	}
2560 }
2561 
generateExpectedResult(void)2562 void BlittingImages::generateExpectedResult (void)
2563 {
2564 	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
2565 	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
2566 
2567 	m_expectedTextureLevel[0]		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
2568 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
2569 
2570 	if (m_params.filter == VK_FILTER_LINEAR)
2571 	{
2572 		m_unclampedExpectedTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
2573 		tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
2574 	}
2575 
2576 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2577 	{
2578 		CopyRegion region = m_params.regions[i];
2579 		copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
2580 	}
2581 }
2582 
2583 class BlitImageTestCase : public vkt::TestCase
2584 {
2585 public:
BlitImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2586 							BlitImageTestCase		(tcu::TestContext&				testCtx,
2587 													 const std::string&				name,
2588 													 const std::string&				description,
2589 													 const TestParams				params)
2590 								: vkt::TestCase	(testCtx, name, description)
2591 								, m_params		(params)
2592 	{}
2593 
createInstance(Context & context) const2594 	virtual TestInstance*	createInstance			(Context&						context) const
2595 	{
2596 		return new BlittingImages(context, m_params);
2597 	}
2598 
checkSupport(Context & context) const2599 	virtual void			checkSupport			(Context&						context) const
2600 	{
2601 		VkImageFormatProperties properties;
2602 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
2603 																					m_params.src.image.format,
2604 																					VK_IMAGE_TYPE_2D,
2605 																					m_params.src.image.tiling,
2606 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
2607 																					0,
2608 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
2609 			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
2610 																					m_params.dst.image.format,
2611 																					VK_IMAGE_TYPE_2D,
2612 																					m_params.dst.image.tiling,
2613 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2614 																					0,
2615 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
2616 		{
2617 			TCU_THROW(NotSupportedError, "Format not supported");
2618 		}
2619 
2620 		VkFormatProperties srcFormatProperties;
2621 		context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
2622 		VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ? srcFormatProperties.linearTilingFeatures : srcFormatProperties.optimalTilingFeatures;
2623 		if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
2624 		{
2625 			TCU_THROW(NotSupportedError, "Format feature blit source not supported");
2626 		}
2627 
2628 		VkFormatProperties dstFormatProperties;
2629 		context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
2630 		VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ? dstFormatProperties.linearTilingFeatures : dstFormatProperties.optimalTilingFeatures;
2631 		if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
2632 		{
2633 			TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
2634 		}
2635 
2636 		if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
2637 			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
2638 	}
2639 
2640 private:
2641 	TestParams				m_params;
2642 };
2643 
2644 class BlittingMipmaps : public CopiesAndBlittingTestInstance
2645 {
2646 public:
2647 										BlittingMipmaps					(Context&   context,
2648 																		 TestParams params);
2649 	virtual tcu::TestStatus				iterate							(void);
2650 protected:
2651 	virtual tcu::TestStatus				checkTestResult					(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
2652 	virtual void						copyRegionToTextureLevel		(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2653 	virtual void						generateExpectedResult			(void);
2654 private:
2655 	bool								checkLinearFilteredResult		(void);
2656 	bool								checkNearestFilteredResult		(void);
2657 
2658 	Move<VkImage>						m_source;
2659 	de::MovePtr<Allocation>				m_sourceImageAlloc;
2660 	Move<VkImage>						m_destination;
2661 	de::MovePtr<Allocation>				m_destinationImageAlloc;
2662 
2663 	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel[16];
2664 };
2665 
BlittingMipmaps(Context & context,TestParams params)2666 BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params)
2667 	: CopiesAndBlittingTestInstance (context, params)
2668 {
2669 	const InstanceInterface&	vki					= context.getInstanceInterface();
2670 	const DeviceInterface&		vk					= context.getDeviceInterface();
2671 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
2672 	const VkDevice				vkDevice			= context.getDevice();
2673 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
2674 	Allocator&					memAlloc			= context.getDefaultAllocator();
2675 
2676 	// Create source image
2677 	{
2678 		const VkImageCreateInfo		sourceImageParams		=
2679 		{
2680 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
2681 			DE_NULL,								// const void*			pNext;
2682 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
2683 			m_params.src.image.imageType,			// VkImageType			imageType;
2684 			m_params.src.image.format,				// VkFormat				format;
2685 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
2686 			1u,										// deUint32				mipLevels;
2687 			getArraySize(m_params.src.image),		// deUint32				arraySize;
2688 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
2689 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
2690 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2691 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
2692 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2693 			1u,										// deUint32				queueFamilyCount;
2694 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
2695 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
2696 		};
2697 
2698 		m_source = createImage(vk, vkDevice, &sourceImageParams);
2699 		m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2700 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
2701 	}
2702 
2703 	// Create destination image
2704 	{
2705 		const VkImageCreateInfo		destinationImageParams  =
2706 		{
2707 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
2708 			DE_NULL,								// const void*			pNext;
2709 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
2710 			m_params.dst.image.imageType,			// VkImageType			imageType;
2711 			m_params.dst.image.format,				// VkFormat				format;
2712 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
2713 			m_params.mipLevels,						// deUint32				mipLevels;
2714 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
2715 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
2716 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
2717 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2718 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
2719 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2720 			1u,										// deUint32				queueFamilyCount;
2721 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
2722 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
2723 		};
2724 
2725 		m_destination = createImage(vk, vkDevice, &destinationImageParams);
2726 		m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2727 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2728 	}
2729 }
2730 
iterate(void)2731 tcu::TestStatus BlittingMipmaps::iterate (void)
2732 {
2733 	const tcu::TextureFormat	srcTcuFormat		= mapVkFormat(m_params.src.image.format);
2734 	const tcu::TextureFormat	dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
2735 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
2736 																				m_params.src.image.extent.width,
2737 																				m_params.src.image.extent.height,
2738 																				m_params.src.image.extent.depth));
2739 	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);
2740 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
2741 																						(int)m_params.dst.image.extent.width,
2742 																						(int)m_params.dst.image.extent.height,
2743 																						(int)m_params.dst.image.extent.depth));
2744 	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);
2745 	generateExpectedResult();
2746 
2747 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
2748 
2749 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
2750 
2751 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
2752 	const VkDevice				vkDevice			= m_context.getDevice();
2753 	const VkQueue				queue				= m_context.getUniversalQueue();
2754 
2755 	std::vector<VkImageBlit>	regions;
2756 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2757 		regions.push_back(m_params.regions[i].imageBlit);
2758 
2759 	// Copy source image to mip level 0 when generating mipmaps with multiple blit commands
2760 	if (!m_params.singleCommand)
2761 		uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
2762 
2763 	beginCommandBuffer(vk, *m_cmdBuffer);
2764 
2765 	// Blit all mip levels with a single blit command
2766 	if (m_params.singleCommand)
2767 	{
2768 		{
2769 			// Source image layout
2770 			const VkImageMemoryBarrier		srcImageBarrier		=
2771 			{
2772 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2773 				DE_NULL,									// const void*				pNext;
2774 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2775 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
2776 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
2777 				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
2778 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2779 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2780 				m_source.get(),								// VkImage					image;
2781 				{											// VkImageSubresourceRange	subresourceRange;
2782 					getAspectFlags(srcTcuFormat),		// VkImageAspectFlags   aspectMask;
2783 					0u,									// deUint32				baseMipLevel;
2784 					1u,									// deUint32				mipLevels;
2785 					0u,									// deUint32				baseArraySlice;
2786 					getArraySize(m_params.src.image)	// deUint32				arraySize;
2787 				}
2788 			};
2789 
2790 			// Destination image layout
2791 			const VkImageMemoryBarrier		dstImageBarrier		=
2792 			{
2793 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2794 				DE_NULL,									// const void*				pNext;
2795 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2796 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
2797 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
2798 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
2799 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2800 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2801 				m_destination.get(),						// VkImage					image;
2802 				{											// VkImageSubresourceRange	subresourceRange;
2803 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags   aspectMask;
2804 					0u,									// deUint32				baseMipLevel;
2805 					m_params.mipLevels,					// deUint32				mipLevels;
2806 					0u,									// deUint32				baseArraySlice;
2807 					getArraySize(m_params.dst.image)	// deUint32				arraySize;
2808 				}
2809 			};
2810 
2811 			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);
2812 			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, &dstImageBarrier);
2813 			vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)regions.size(), &regions[0], m_params.filter);
2814 		}
2815 	}
2816 	// Blit mip levels with multiple blit commands
2817 	else
2818 	{
2819 		// Prepare all mip levels for reading
2820 		{
2821 			for (deUint32 barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
2822 			{
2823 				VkImageMemoryBarrier preImageBarrier =
2824 				{
2825 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType	sType;
2826 					DE_NULL,																// const void*		pNext;
2827 					VK_ACCESS_TRANSFER_WRITE_BIT,											// VkAccessFlags	srcAccessMask;
2828 					VK_ACCESS_TRANSFER_READ_BIT,											// VkAccessFlags	dstAccessMask;
2829 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,									// VkImageLayout	oldLayout;
2830 					m_params.src.image.operationLayout,										// VkImageLayout	newLayout;
2831 					VK_QUEUE_FAMILY_IGNORED,												// deUint32			srcQueueFamilyIndex;
2832 					VK_QUEUE_FAMILY_IGNORED,												// deUint32			dstQueueFamilyIndex;
2833 					m_destination.get(),													// VkImage			image;
2834 					{																		// VkImageSubresourceRange	subresourceRange;
2835 						getAspectFlags(dstTcuFormat),										// VkImageAspectFlags	aspectMask;
2836 							0u,																// deUint32				baseMipLevel;
2837 							VK_REMAINING_MIP_LEVELS,										// deUint32				mipLevels;
2838 							0u,																// deUint32				baseArraySlice;
2839 							getArraySize(m_params.src.image)								// deUint32				arraySize;
2840 					}
2841 				};
2842 
2843 				if (getArraySize(m_params.src.image) == 1)
2844 				{
2845 					DE_ASSERT(barrierno < m_params.mipLevels);
2846 					preImageBarrier.subresourceRange.baseMipLevel	= barrierno;
2847 					preImageBarrier.subresourceRange.levelCount		= (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
2848 				}
2849 				else
2850 				{
2851 					preImageBarrier.subresourceRange.baseArrayLayer	= barrierno;
2852 					preImageBarrier.subresourceRange.layerCount		= (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
2853 				}
2854 				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, &preImageBarrier);
2855 			}
2856 		}
2857 
2858 		for (deUint32 regionNdx = 0u; regionNdx < (deUint32)regions.size(); regionNdx++)
2859 		{
2860 			const deUint32					mipLevel			= regions[regionNdx].dstSubresource.mipLevel;
2861 
2862 			// Prepare single mip level for writing
2863 			const VkImageMemoryBarrier		preImageBarrier		=
2864 			{
2865 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2866 				DE_NULL,									// const void*					pNext;
2867 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
2868 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
2869 				m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
2870 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
2871 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2872 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2873 				m_destination.get(),						// VkImage					image;
2874 				{											// VkImageSubresourceRange	subresourceRange;
2875 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
2876 					mipLevel,							// deUint32				baseMipLevel;
2877 					1u,									// deUint32				mipLevels;
2878 					0u,									// deUint32				baseArraySlice;
2879 					getArraySize(m_params.dst.image)	// deUint32				arraySize;
2880 				}
2881 			};
2882 
2883 			// Prepare single mip level for reading
2884 			const VkImageMemoryBarrier		postImageBarrier	=
2885 			{
2886 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2887 				DE_NULL,									// const void*				pNext;
2888 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2889 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
2890 				m_params.dst.image.operationLayout,			// VkImageLayout			oldLayout;
2891 				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
2892 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2893 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2894 				m_destination.get(),						// VkImage					image;
2895 				{											// VkImageSubresourceRange	subresourceRange;
2896 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
2897 					mipLevel,							// deUint32				baseMipLevel;
2898 					1u,									// deUint32				mipLevels;
2899 					0u,									// deUint32				baseArraySlice;
2900 					getArraySize(m_params.src.image)	// deUint32				arraySize;
2901 				}
2902 			};
2903 
2904 			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, &preImageBarrier);
2905 			vk.cmdBlitImage(*m_cmdBuffer, m_destination.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, 1u, &regions[regionNdx], m_params.filter);
2906 			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, &postImageBarrier);
2907 		}
2908 
2909 		// Prepare all mip levels for writing
2910 		{
2911 			const VkImageMemoryBarrier		postImageBarrier		=
2912 			{
2913 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2914 				DE_NULL,									// const void*				pNext;
2915 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
2916 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
2917 				m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
2918 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
2919 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2920 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2921 				m_destination.get(),						// VkImage					image;
2922 				{											// VkImageSubresourceRange	subresourceRange;
2923 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
2924 					0u,									// deUint32				baseMipLevel;
2925 					VK_REMAINING_MIP_LEVELS,			// deUint32				mipLevels;
2926 					0u,									// deUint32				baseArraySlice;
2927 					getArraySize(m_params.dst.image)	// deUint32				arraySize;
2928 				}
2929 			};
2930 
2931 			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, &postImageBarrier);
2932 		}
2933 	}
2934 
2935 	endCommandBuffer(vk, *m_cmdBuffer);
2936 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2937 
2938 	return checkTestResult();
2939 }
2940 
checkLinearFilteredResult(void)2941 bool BlittingMipmaps::checkLinearFilteredResult (void)
2942 {
2943 	tcu::TestLog&				log				(m_context.getTestContext().getLog());
2944 	bool						allLevelsOk		= true;
2945 
2946 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
2947 	{
2948 		// Update reference results with previous results that have been verified.
2949 		// This needs to be done such that accumulated errors don't exceed the fixed threshold.
2950 		for (deUint32 i = 0; i < m_params.regions.size(); i++)
2951 		{
2952 			const CopyRegion region = m_params.regions[i];
2953 			const deUint32 srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
2954 			const deUint32 dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
2955 			de::MovePtr<tcu::TextureLevel>	prevResultLevel;
2956 			tcu::ConstPixelBufferAccess src;
2957 			if (srcMipLevel < mipLevelNdx)
2958 			{
2959 				// Generate expected result from rendered result that was previously verified
2960 				prevResultLevel	= readImage(*m_destination, m_params.dst.image, srcMipLevel);
2961 				src = prevResultLevel->getAccess();
2962 			}
2963 			else
2964 			{
2965 				// Previous reference mipmaps might have changed, so recompute expected result
2966 				src = m_expectedTextureLevel[srcMipLevel]->getAccess();
2967 			}
2968 			copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
2969 		}
2970 
2971 		de::MovePtr<tcu::TextureLevel>			resultLevel			= readImage(*m_destination, m_params.dst.image, mipLevelNdx);
2972 		const tcu::ConstPixelBufferAccess&		resultAccess		= resultLevel->getAccess();
2973 
2974 		const tcu::Sampler::DepthStencilMode	mode				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::Sampler::MODE_DEPTH :
2975 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
2976 																																	tcu::Sampler::MODE_LAST;
2977 		const tcu::ConstPixelBufferAccess		result				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(resultAccess, mode) :
2978 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
2979 																																	resultAccess;
2980 		const tcu::ConstPixelBufferAccess		clampedLevel		= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
2981 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
2982 																																	m_expectedTextureLevel[mipLevelNdx]->getAccess();
2983 		const tcu::ConstPixelBufferAccess		unclampedLevel		= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
2984 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
2985 																																	m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
2986 		const tcu::TextureFormat				srcFormat			= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
2987 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
2988 																																	mapVkFormat(m_params.src.image.format);
2989 
2990 		const tcu::TextureFormat				dstFormat			= result.getFormat();
2991 		bool									singleLevelOk		= false;
2992 		std::vector <CopyRegion>				mipLevelRegions;
2993 
2994 		for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
2995 			if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
2996 				mipLevelRegions.push_back(m_params.regions.at(regionNdx));
2997 
2998 		log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
2999 
3000 		if (isFloatFormat(dstFormat))
3001 		{
3002 			const bool		srcIsSRGB   = tcu::isSRGB(srcFormat);
3003 			const tcu::Vec4 srcMaxDiff  = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
3004 			const tcu::Vec4 dstMaxDiff  = getFormatThreshold(dstFormat);
3005 			const tcu::Vec4 threshold   = tcu::max(srcMaxDiff, dstMaxDiff);
3006 
3007 			singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
3008 			log << tcu::TestLog::EndSection;
3009 
3010 			if (!singleLevelOk)
3011 			{
3012 				log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3013 				singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
3014 				log << tcu::TestLog::EndSection;
3015 			}
3016 		}
3017 		else
3018 		{
3019 			tcu::UVec4  threshold;
3020 			// Calculate threshold depending on channel width of destination format.
3021 			const tcu::IVec4	bitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
3022 			for (deUint32 i = 0; i < 4; ++i)
3023 				threshold[i] = de::max((0x1 << bitDepth[i]) / 256, 2);
3024 
3025 			singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
3026 			log << tcu::TestLog::EndSection;
3027 
3028 			if (!singleLevelOk)
3029 			{
3030 				log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3031 				singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
3032 				log << tcu::TestLog::EndSection;
3033 			}
3034 		}
3035 		allLevelsOk &= singleLevelOk;
3036 	}
3037 
3038 	return allLevelsOk;
3039 }
3040 
checkNearestFilteredResult(void)3041 bool BlittingMipmaps::checkNearestFilteredResult (void)
3042 {
3043 	bool						allLevelsOk		= true;
3044 	tcu::TestLog&				log				(m_context.getTestContext().getLog());
3045 
3046 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
3047 	{
3048 		de::MovePtr<tcu::TextureLevel>			resultLevel			= readImage(*m_destination, m_params.dst.image, mipLevelNdx);
3049 		const tcu::ConstPixelBufferAccess&		resultAccess		= resultLevel->getAccess();
3050 
3051 		const tcu::Sampler::DepthStencilMode	mode				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::Sampler::MODE_DEPTH :
3052 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
3053 																																	tcu::Sampler::MODE_LAST;
3054 		const tcu::ConstPixelBufferAccess		result				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(resultAccess, mode) :
3055 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
3056 																																	resultAccess;
3057 		const tcu::ConstPixelBufferAccess		source				= (m_params.singleCommand || mipLevelNdx == 0) ?			//  Read from source image
3058 																	  tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
3059 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
3060 																																	m_sourceTextureLevel->getAccess()
3061 																																//  Read from destination image
3062 																	: tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
3063 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
3064 																																	m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
3065 		const tcu::TextureFormat				dstFormat			= result.getFormat();
3066 		const tcu::TextureChannelClass			dstChannelClass		= tcu::getTextureChannelClass(dstFormat.type);
3067 		bool									singleLevelOk		= false;
3068 		std::vector <CopyRegion>				mipLevelRegions;
3069 
3070 		for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
3071 			if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
3072 				mipLevelRegions.push_back(m_params.regions.at(regionNdx));
3073 
3074 		tcu::TextureLevel				errorMaskStorage	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
3075 		tcu::PixelBufferAccess			errorMask			= errorMaskStorage.getAccess();
3076 		tcu::Vec4						pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
3077 		tcu::Vec4						pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
3078 
3079 		tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3080 
3081 		if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3082 			dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
3083 		{
3084 			singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions);
3085 		}
3086 		else
3087 			singleLevelOk = floatNearestBlitCompare(source, result, errorMask, mipLevelRegions);
3088 
3089 		if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
3090 			tcu::computePixelScaleBias(result, pixelScale, pixelBias);
3091 
3092 		if (!singleLevelOk)
3093 		{
3094 			log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
3095 				<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3096 				<< tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
3097 				<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
3098 				<< tcu::TestLog::EndImageSet;
3099 		}
3100 		else
3101 		{
3102 			log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
3103 				<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3104 				<< tcu::TestLog::EndImageSet;
3105 		}
3106 
3107 		allLevelsOk &= singleLevelOk;
3108 	}
3109 
3110 	return allLevelsOk;
3111 }
3112 
checkTestResult(tcu::ConstPixelBufferAccess result)3113 tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result)
3114 {
3115 	DE_UNREF(result);
3116 	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR);
3117 	const std::string failMessage("Result image is incorrect");
3118 
3119 	if (m_params.filter == VK_FILTER_LINEAR)
3120 	{
3121 		if (!checkLinearFilteredResult())
3122 			return tcu::TestStatus::fail(failMessage);
3123 	}
3124 	else // NEAREST filtering
3125 	{
3126 		if (!checkNearestFilteredResult())
3127 			return tcu::TestStatus::fail(failMessage);
3128 	}
3129 
3130 	return tcu::TestStatus::pass("Pass");
3131 }
3132 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)3133 void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
3134 {
3135 	DE_ASSERT(src.getDepth() == dst.getDepth());
3136 
3137 	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
3138 												region.imageBlit.srcOffsets[1],
3139 												region.imageBlit.dstOffsets[0],
3140 												region.imageBlit.dstOffsets[1]);
3141 
3142 	flipCoordinates(region, mirrorMode);
3143 
3144 	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
3145 	const VkOffset3D					srcExtent		=
3146 	{
3147 		region.imageBlit.srcOffsets[1].x - srcOffset.x,
3148 		region.imageBlit.srcOffsets[1].y - srcOffset.y,
3149 		region.imageBlit.srcOffsets[1].z - srcOffset.z
3150 	};
3151 	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
3152 	const VkOffset3D					dstExtent		=
3153 	{
3154 		region.imageBlit.dstOffsets[1].x - dstOffset.x,
3155 		region.imageBlit.dstOffsets[1].y - dstOffset.y,
3156 		region.imageBlit.dstOffsets[1].z - dstOffset.z
3157 	};
3158 	const tcu::Sampler::FilterMode		filter			= (m_params.filter == VK_FILTER_LINEAR) ? tcu::Sampler::LINEAR : tcu::Sampler::NEAREST;
3159 
3160 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
3161 	{
3162 		DE_ASSERT(src.getFormat() == dst.getFormat());
3163 		// Scale depth.
3164 		if (tcu::hasDepthComponent(src.getFormat().order))
3165 		{
3166 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
3167 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
3168 			tcu::scale(dstSubRegion, srcSubRegion, filter);
3169 
3170 			if (filter == tcu::Sampler::LINEAR)
3171 			{
3172 				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
3173 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
3174 				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
3175 			}
3176 		}
3177 
3178 		// Scale stencil.
3179 		if (tcu::hasStencilComponent(src.getFormat().order))
3180 		{
3181 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
3182 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
3183 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
3184 
3185 			if (filter == tcu::Sampler::LINEAR)
3186 			{
3187 				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
3188 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
3189 				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
3190 			}
3191 		}
3192 	}
3193 	else
3194 	{
3195 		for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
3196 		{
3197 			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
3198 			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
3199 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
3200 
3201 			if (filter == tcu::Sampler::LINEAR)
3202 			{
3203 				const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
3204 				scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
3205 			}
3206 		}
3207 	}
3208 }
3209 
generateExpectedResult(void)3210 void BlittingMipmaps::generateExpectedResult (void)
3211 {
3212 	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
3213 	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
3214 
3215 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
3216 		m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
3217 
3218 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
3219 
3220 	if (m_params.filter == VK_FILTER_LINEAR)
3221 	{
3222 		for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
3223 			m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
3224 
3225 		tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
3226 	}
3227 
3228 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
3229 	{
3230 		CopyRegion region = m_params.regions[i];
3231 		copyRegionToTextureLevel(m_expectedTextureLevel[m_params.regions[i].imageBlit.srcSubresource.mipLevel]->getAccess(), m_expectedTextureLevel[m_params.regions[i].imageBlit.dstSubresource.mipLevel]->getAccess(), region, m_params.regions[i].imageBlit.dstSubresource.mipLevel);
3232 	}
3233 }
3234 
3235 class BlitMipmapTestCase : public vkt::TestCase
3236 {
3237 public:
BlitMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)3238 							BlitMipmapTestCase		(tcu::TestContext&				testCtx,
3239 													 const std::string&				name,
3240 													 const std::string&				description,
3241 													 const TestParams				params)
3242 								: vkt::TestCase	(testCtx, name, description)
3243 								, m_params		(params)
3244 	{}
3245 
createInstance(Context & context) const3246 	virtual TestInstance*	createInstance			(Context&						context) const
3247 	{
3248 		return new BlittingMipmaps(context, m_params);
3249 	}
3250 
checkSupport(Context & context) const3251 	virtual void			checkSupport			(Context&						context) const
3252 	{
3253 		const InstanceInterface&	vki					= context.getInstanceInterface();
3254 		const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
3255 		{
3256 			VkImageFormatProperties	properties;
3257 			if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
3258 																						m_params.src.image.format,
3259 																						VK_IMAGE_TYPE_2D,
3260 																						VK_IMAGE_TILING_OPTIMAL,
3261 																						VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
3262 																						0,
3263 																						&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
3264 			{
3265 				TCU_THROW(NotSupportedError, "Format not supported");
3266 			}
3267 			else if ((m_params.src.image.extent.width	> properties.maxExtent.width)	||
3268 						(m_params.src.image.extent.height	> properties.maxExtent.height)	||
3269 						(m_params.src.image.extent.depth	> properties.maxArrayLayers))
3270 			{
3271 				TCU_THROW(NotSupportedError, "Image size not supported");
3272 			}
3273 		}
3274 
3275 		{
3276 			VkImageFormatProperties	properties;
3277 			if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
3278 																						m_params.dst.image.format,
3279 																						VK_IMAGE_TYPE_2D,
3280 																						VK_IMAGE_TILING_OPTIMAL,
3281 																						VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3282 																						0,
3283 																						&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
3284 			{
3285 				TCU_THROW(NotSupportedError, "Format not supported");
3286 			}
3287 			else if ((m_params.dst.image.extent.width	> properties.maxExtent.width)	||
3288 						(m_params.dst.image.extent.height	> properties.maxExtent.height)	||
3289 						(m_params.dst.image.extent.depth	> properties.maxArrayLayers))
3290 			{
3291 				TCU_THROW(NotSupportedError, "Image size not supported");
3292 			}
3293 			else if (m_params.mipLevels > properties.maxMipLevels)
3294 			{
3295 				TCU_THROW(NotSupportedError, "Number of mip levels not supported");
3296 			}
3297 		}
3298 
3299 		const VkFormatProperties	srcFormatProperties	= getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format);
3300 		if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
3301 		{
3302 			TCU_THROW(NotSupportedError, "Format feature blit source not supported");
3303 		}
3304 
3305 		const VkFormatProperties	dstFormatProperties	= getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format);
3306 		if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
3307 		{
3308 			TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
3309 		}
3310 
3311 		if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
3312 			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
3313 	}
3314 
3315 private:
3316 	TestParams				m_params;
3317 };
3318 
3319 // Resolve image to image.
3320 
3321 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION, COPY_MS_IMAGE_TO_MS_IMAGE, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE};
3322 class ResolveImageToImage : public CopiesAndBlittingTestInstance
3323 {
3324 public:
3325 												ResolveImageToImage			(Context&							context,
3326 																			 TestParams							params,
3327 																			 const ResolveImageToImageOptions	options);
3328 	virtual tcu::TestStatus						iterate						(void);
3329 protected:
3330 	virtual tcu::TestStatus						checkTestResult				(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
3331 	void										copyMSImageToMSImage		(deUint32 copyArraySize);
3332 private:
3333 	Move<VkImage>								m_multisampledImage;
3334 	de::MovePtr<Allocation>						m_multisampledImageAlloc;
3335 
3336 	Move<VkImage>								m_destination;
3337 	de::MovePtr<Allocation>						m_destinationImageAlloc;
3338 
3339 	Move<VkImage>								m_multisampledCopyImage;
3340 	de::MovePtr<Allocation>						m_multisampledCopyImageAlloc;
3341 
3342 	const ResolveImageToImageOptions			m_options;
3343 
3344 	virtual void								copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess	src,
3345 																			 tcu::PixelBufferAccess			dst,
3346 																			 CopyRegion						region,
3347 																			 deUint32						mipLevel = 0u);
3348 };
3349 
ResolveImageToImage(Context & context,TestParams params,const ResolveImageToImageOptions options)3350 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
3351 	: CopiesAndBlittingTestInstance	(context, params)
3352 	, m_options						(options)
3353 {
3354 	const InstanceInterface&	vki						= context.getInstanceInterface();
3355 	const DeviceInterface&		vk						= context.getDeviceInterface();
3356 	const VkPhysicalDevice		vkPhysDevice			= context.getPhysicalDevice();
3357 	const VkDevice				vkDevice				= context.getDevice();
3358 	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
3359 	Allocator&					memAlloc				= m_context.getDefaultAllocator();
3360 
3361 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
3362 	Move<VkRenderPass>			renderPass;
3363 
3364 	Move<VkShaderModule>		vertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
3365 	Move<VkShaderModule>		fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
3366 	std::vector<tcu::Vec4>		vertices;
3367 
3368 	Move<VkBuffer>				vertexBuffer;
3369 	de::MovePtr<Allocation>		vertexBufferAlloc;
3370 
3371 	Move<VkPipelineLayout>		pipelineLayout;
3372 	Move<VkPipeline>			graphicsPipeline;
3373 
3374 	const VkSampleCountFlagBits	rasterizationSamples	= m_params.samples;
3375 
3376 	// Create color image.
3377 	{
3378 		VkImageCreateInfo	colorImageParams	=
3379 		{
3380 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
3381 			DE_NULL,																// const void*				pNext;
3382 			getCreateFlags(m_params.src.image),										// VkImageCreateFlags		flags;
3383 			m_params.src.image.imageType,											// VkImageType				imageType;
3384 			m_params.src.image.format,												// VkFormat					format;
3385 			getExtent3D(m_params.src.image),										// VkExtent3D				extent;
3386 			1u,																		// deUint32					mipLevels;
3387 			getArraySize(m_params.src.image),										// deUint32					arrayLayers;
3388 			rasterizationSamples,													// VkSampleCountFlagBits	samples;
3389 			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
3390 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// VkImageUsageFlags		usage;
3391 			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
3392 			1u,																		// deUint32					queueFamilyIndexCount;
3393 			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
3394 			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout			initialLayout;
3395 		};
3396 
3397 		m_multisampledImage						= createImage(vk, vkDevice, &colorImageParams);
3398 
3399 		// Allocate and bind color image memory.
3400 		m_multisampledImageAlloc				= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3401 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset()));
3402 
3403 		switch (m_options)
3404 		{
3405 			case COPY_MS_IMAGE_TO_MS_IMAGE:
3406 			{
3407 				colorImageParams.usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3408 				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
3409 				// Allocate and bind color image memory.
3410 				m_multisampledCopyImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3411 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
3412 				break;
3413 			}
3414 
3415 			case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
3416 			{
3417 				colorImageParams.usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3418 				colorImageParams.arrayLayers	= getArraySize(m_params.dst.image);
3419 				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
3420 				// Allocate and bind color image memory.
3421 				m_multisampledCopyImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3422 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
3423 				break;
3424 			}
3425 
3426 			default :
3427 				break;
3428 		}
3429 	}
3430 
3431 	// Create destination image.
3432 	{
3433 		const VkImageCreateInfo	destinationImageParams	=
3434 		{
3435 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
3436 			DE_NULL,								// const void*			pNext;
3437 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
3438 			m_params.dst.image.imageType,			// VkImageType			imageType;
3439 			m_params.dst.image.format,				// VkFormat				format;
3440 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
3441 			1u,										// deUint32				mipLevels;
3442 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
3443 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
3444 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
3445 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3446 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
3447 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
3448 			1u,										// deUint32				queueFamilyCount;
3449 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
3450 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
3451 		};
3452 
3453 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
3454 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3455 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
3456 	}
3457 
3458 	// Barriers for copying image to buffer
3459 	VkImageMemoryBarrier		srcImageBarrier		=
3460 	{
3461 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3462 		DE_NULL,									// const void*				pNext;
3463 		0u,											// VkAccessFlags			srcAccessMask;
3464 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
3465 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
3466 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
3467 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3468 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3469 		m_multisampledImage.get(),					// VkImage					image;
3470 		{											// VkImageSubresourceRange	subresourceRange;
3471 			VK_IMAGE_ASPECT_COLOR_BIT,			// VkImageAspectFlags	aspectMask;
3472 			0u,									// deUint32				baseMipLevel;
3473 			1u,									// deUint32				mipLevels;
3474 			0u,									// deUint32				baseArraySlice;
3475 			getArraySize(m_params.src.image)	// deUint32				arraySize;
3476 		}
3477 	};
3478 
3479 		// Create render pass.
3480 	{
3481 		const VkAttachmentDescription	attachmentDescriptions[1]	=
3482 		{
3483 			{
3484 				0u,											// VkAttachmentDescriptionFlags		flags;
3485 				m_params.src.image.format,					// VkFormat							format;
3486 				rasterizationSamples,						// VkSampleCountFlagBits			samples;
3487 				VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp				loadOp;
3488 				VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp;
3489 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp;
3490 				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp;
3491 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout;
3492 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout;
3493 			},
3494 		};
3495 
3496 		const VkAttachmentReference		colorAttachmentReference	=
3497 		{
3498 			0u,													// deUint32			attachment;
3499 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
3500 		};
3501 
3502 		const VkSubpassDescription		subpassDescription			=
3503 		{
3504 			0u,									// VkSubpassDescriptionFlags	flags;
3505 			VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint			pipelineBindPoint;
3506 			0u,									// deUint32						inputAttachmentCount;
3507 			DE_NULL,							// const VkAttachmentReference*	pInputAttachments;
3508 			1u,									// deUint32						colorAttachmentCount;
3509 			&colorAttachmentReference,			// const VkAttachmentReference*	pColorAttachments;
3510 			DE_NULL,							// const VkAttachmentReference*	pResolveAttachments;
3511 			DE_NULL,							// const VkAttachmentReference*	pDepthStencilAttachment;
3512 			0u,									// deUint32						preserveAttachmentCount;
3513 			DE_NULL								// const VkAttachmentReference*	pPreserveAttachments;
3514 		};
3515 
3516 		const VkRenderPassCreateInfo	renderPassParams			=
3517 		{
3518 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType					sType;
3519 			DE_NULL,									// const void*						pNext;
3520 			0u,											// VkRenderPassCreateFlags			flags;
3521 			1u,											// deUint32							attachmentCount;
3522 			attachmentDescriptions,						// const VkAttachmentDescription*	pAttachments;
3523 			1u,											// deUint32							subpassCount;
3524 			&subpassDescription,						// const VkSubpassDescription*		pSubpasses;
3525 			0u,											// deUint32							dependencyCount;
3526 			DE_NULL										// const VkSubpassDependency*		pDependencies;
3527 		};
3528 
3529 		renderPass	= createRenderPass(vk, vkDevice, &renderPassParams);
3530 	}
3531 
3532 	// Create pipeline layout
3533 	{
3534 		const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
3535 		{
3536 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
3537 			DE_NULL,											// const void*						pNext;
3538 			0u,													// VkPipelineLayoutCreateFlags		flags;
3539 			0u,													// deUint32							setLayoutCount;
3540 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
3541 			0u,													// deUint32							pushConstantRangeCount;
3542 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
3543 		};
3544 
3545 		pipelineLayout	= createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
3546 	}
3547 
3548 	// Create upper half triangle.
3549 	{
3550 		const tcu::Vec4	a	(-1.0, -1.0, 0.0, 1.0);
3551 		const tcu::Vec4	b	(1.0, -1.0, 0.0, 1.0);
3552 		const tcu::Vec4	c	(1.0, 1.0, 0.0, 1.0);
3553 		// Add triangle.
3554 		vertices.push_back(a);
3555 		vertices.push_back(c);
3556 		vertices.push_back(b);
3557 	}
3558 
3559 	// Create vertex buffer.
3560 	{
3561 		const VkDeviceSize			vertexDataSize		= vertices.size() * sizeof(tcu::Vec4);
3562 		const VkBufferCreateInfo	vertexBufferParams	=
3563 		{
3564 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
3565 			DE_NULL,									// const void*			pNext;
3566 			0u,											// VkBufferCreateFlags	flags;
3567 			vertexDataSize,								// VkDeviceSize			size;
3568 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
3569 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
3570 			1u,											// deUint32				queueFamilyIndexCount;
3571 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
3572 		};
3573 
3574 		vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
3575 		vertexBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
3576 		VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
3577 
3578 		// Load vertices into vertex buffer.
3579 		deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
3580 		flushAlloc(vk, vkDevice, *vertexBufferAlloc);
3581 	}
3582 
3583 	{
3584 		Move<VkFramebuffer>		framebuffer;
3585 		Move<VkImageView>		sourceAttachmentView;
3586 
3587 		// Create color attachment view.
3588 		{
3589 			const VkImageViewCreateInfo	colorAttachmentViewParams	=
3590 			{
3591 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,				// VkStructureType			sType;
3592 				DE_NULL,												// const void*				pNext;
3593 				0u,														// VkImageViewCreateFlags	flags;
3594 				*m_multisampledImage,									// VkImage					image;
3595 				VK_IMAGE_VIEW_TYPE_2D,									// VkImageViewType			viewType;
3596 				m_params.src.image.format,								// VkFormat					format;
3597 				componentMappingRGBA,									// VkComponentMapping		components;
3598 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }	// VkImageSubresourceRange	subresourceRange;
3599 			};
3600 			sourceAttachmentView	= createImageView(vk, vkDevice, &colorAttachmentViewParams);
3601 		}
3602 
3603 		// Create framebuffer
3604 		{
3605 			const VkImageView				attachments[1]		=
3606 			{
3607 					*sourceAttachmentView,
3608 			};
3609 
3610 			const VkFramebufferCreateInfo	framebufferParams	=
3611 			{
3612 					VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
3613 					DE_NULL,											// const void*					pNext;
3614 					0u,													// VkFramebufferCreateFlags		flags;
3615 					*renderPass,										// VkRenderPass					renderPass;
3616 					1u,													// deUint32						attachmentCount;
3617 					attachments,										// const VkImageView*			pAttachments;
3618 					m_params.src.image.extent.width,					// deUint32						width;
3619 					m_params.src.image.extent.height,					// deUint32						height;
3620 					1u													// deUint32						layers;
3621 			};
3622 
3623 			framebuffer	= createFramebuffer(vk, vkDevice, &framebufferParams);
3624 		}
3625 
3626 		// Create pipeline
3627 		{
3628 			const std::vector<VkViewport>	viewports	(1, makeViewport(m_params.src.image.extent));
3629 			const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_params.src.image.extent));
3630 
3631 			const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
3632 			{
3633 				VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
3634 				DE_NULL,													// const void*								pNext;
3635 				0u,															// VkPipelineMultisampleStateCreateFlags	flags;
3636 				rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
3637 				VK_FALSE,													// VkBool32									sampleShadingEnable;
3638 				0.0f,														// float									minSampleShading;
3639 				DE_NULL,													// const VkSampleMask*						pSampleMask;
3640 				VK_FALSE,													// VkBool32									alphaToCoverageEnable;
3641 				VK_FALSE													// VkBool32									alphaToOneEnable;
3642 			};
3643 
3644 			graphicsPipeline = makeGraphicsPipeline(vk,										// const DeviceInterface&                        vk
3645 													vkDevice,								// const VkDevice                                device
3646 													*pipelineLayout,						// const VkPipelineLayout                        pipelineLayout
3647 													*vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
3648 													DE_NULL,								// const VkShaderModule                          tessellationControlModule
3649 													DE_NULL,								// const VkShaderModule                          tessellationEvalModule
3650 													DE_NULL,								// const VkShaderModule                          geometryShaderModule
3651 													*fragmentShaderModule,					// const VkShaderModule                          fragmentShaderModule
3652 													*renderPass,							// const VkRenderPass                            renderPass
3653 													viewports,								// const std::vector<VkViewport>&                viewports
3654 													scissors,								// const std::vector<VkRect2D>&                  scissors
3655 													VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
3656 													0u,										// const deUint32                                subpass
3657 													0u,										// const deUint32                                patchControlPoints
3658 													DE_NULL,								// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
3659 													DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
3660 													&multisampleStateParams);				// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
3661 		}
3662 
3663 		// Create command buffer
3664 		{
3665 			beginCommandBuffer(vk, *m_cmdBuffer, 0u);
3666 			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);
3667 			beginRenderPass(vk, *m_cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_params.src.image.extent.width, m_params.src.image.extent.height), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
3668 
3669 			const VkDeviceSize	vertexBufferOffset	= 0u;
3670 
3671 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
3672 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
3673 			vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
3674 
3675 			endRenderPass(vk, *m_cmdBuffer);
3676 			endCommandBuffer(vk, *m_cmdBuffer);
3677 		}
3678 
3679 		// Queue submit.
3680 		{
3681 			const VkQueue	queue	= m_context.getUniversalQueue();
3682 			submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
3683 		}
3684 	}
3685 }
3686 
iterate(void)3687 tcu::TestStatus ResolveImageToImage::iterate (void)
3688 {
3689 	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
3690 	const tcu::TextureFormat		dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
3691 
3692 	// upload the destination image
3693 	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
3694 																			(int)m_params.dst.image.extent.width,
3695 																			(int)m_params.dst.image.extent.height,
3696 																			(int)m_params.dst.image.extent.depth));
3697 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
3698 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
3699 
3700 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
3701 																	(int)m_params.src.image.extent.width,
3702 																	(int)m_params.src.image.extent.height,
3703 																	(int)m_params.dst.image.extent.depth));
3704 
3705 	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);
3706 	generateExpectedResult();
3707 
3708 	VkImage		sourceImage		= m_multisampledImage.get();
3709 	deUint32	sourceArraySize	= getArraySize(m_params.src.image);
3710 
3711 	switch (m_options)
3712 	{
3713 		case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
3714 			// Duplicate the multisampled image to a multisampled image array
3715 			sourceArraySize	= getArraySize(m_params.dst.image); // fall through
3716 		case COPY_MS_IMAGE_TO_MS_IMAGE:
3717 			copyMSImageToMSImage(sourceArraySize);
3718 			sourceImage	= m_multisampledCopyImage.get();
3719 			break;
3720 		default:
3721 			break;
3722 	}
3723 
3724 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
3725 	const VkDevice					vkDevice			= m_context.getDevice();
3726 	const VkQueue					queue				= m_context.getUniversalQueue();
3727 
3728 	std::vector<VkImageResolve>		imageResolves;
3729 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
3730 		imageResolves.push_back(m_params.regions[i].imageResolve);
3731 
3732 	const VkImageMemoryBarrier	imageBarriers[]		=
3733 	{
3734 		// source image
3735 		{
3736 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3737 			DE_NULL,									// const void*				pNext;
3738 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
3739 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
3740 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout;
3741 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
3742 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3743 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3744 			sourceImage,								// VkImage					image;
3745 			{											// VkImageSubresourceRange	subresourceRange;
3746 				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
3747 				0u,									// deUint32				baseMipLevel;
3748 				1u,									// deUint32				mipLevels;
3749 				0u,									// deUint32				baseArraySlice;
3750 				sourceArraySize						// deUint32				arraySize;
3751 			}
3752 		},
3753 		// destination image
3754 		{
3755 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3756 			DE_NULL,									// const void*				pNext;
3757 			0u,											// VkAccessFlags			srcAccessMask;
3758 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
3759 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
3760 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
3761 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3762 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3763 			m_destination.get(),						// VkImage					image;
3764 			{											// VkImageSubresourceRange	subresourceRange;
3765 				getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
3766 				0u,									// deUint32				baseMipLevel;
3767 				1u,									// deUint32				mipLevels;
3768 				0u,									// deUint32				baseArraySlice;
3769 				getArraySize(m_params.dst.image)	// deUint32				arraySize;
3770 			}
3771 		},
3772 	};
3773 
3774 	const VkImageMemoryBarrier postImageBarrier =
3775 	{
3776 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
3777 		DE_NULL,								// const void*				pNext;
3778 		VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			srcAccessMask;
3779 		VK_ACCESS_HOST_READ_BIT,				// VkAccessFlags			dstAccessMask;
3780 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			oldLayout;
3781 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
3782 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
3783 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
3784 		m_destination.get(),					// VkImage					image;
3785 		{										// VkImageSubresourceRange	subresourceRange;
3786 			getAspectFlags(dstTcuFormat),		// VkImageAspectFlags		aspectMask;
3787 			0u,									// deUint32					baseMipLevel;
3788 			1u,									// deUint32					mipLevels;
3789 			0u,									// deUint32					baseArraySlice;
3790 			getArraySize(m_params.dst.image)	// deUint32					arraySize;
3791 		}
3792 	};
3793 
3794 	beginCommandBuffer(vk, *m_cmdBuffer);
3795 	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);
3796 	vk.cmdResolveImage(*m_cmdBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), imageResolves.data());
3797 	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);
3798 	endCommandBuffer(vk, *m_cmdBuffer);
3799 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
3800 
3801 	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);
3802 
3803 	return checkTestResult(resultTextureLevel->getAccess());
3804 }
3805 
checkTestResult(tcu::ConstPixelBufferAccess result)3806 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
3807 {
3808 	const tcu::ConstPixelBufferAccess	expected		= m_expectedTextureLevel[0]->getAccess();
3809 	const float							fuzzyThreshold	= 0.01f;
3810 
3811 	for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
3812 	{
3813 		const tcu::ConstPixelBufferAccess	expectedSub	= getSubregion (expected, 0, 0, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
3814 		const tcu::ConstPixelBufferAccess	resultSub	= getSubregion (result, 0, 0, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
3815 		if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
3816 			return tcu::TestStatus::fail("CopiesAndBlitting test");
3817 	}
3818 
3819 	return tcu::TestStatus::pass("CopiesAndBlitting test");
3820 }
3821 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)3822 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
3823 {
3824 	DE_UNREF(mipLevel);
3825 
3826 	VkOffset3D srcOffset	= region.imageResolve.srcOffset;
3827 			srcOffset.z		= region.imageResolve.srcSubresource.baseArrayLayer;
3828 	VkOffset3D dstOffset	= region.imageResolve.dstOffset;
3829 			dstOffset.z		= region.imageResolve.dstSubresource.baseArrayLayer;
3830 	VkExtent3D extent		= region.imageResolve.extent;
3831 			extent.depth		= region.imageResolve.srcSubresource.layerCount;
3832 
3833 	const tcu::ConstPixelBufferAccess	srcSubRegion		= getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
3834 	// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
3835 	const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
3836 	const tcu::PixelBufferAccess		dstSubRegion		= getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
3837 
3838 	tcu::copy(dstSubRegion, srcSubRegion);
3839 }
3840 
copyMSImageToMSImage(deUint32 copyArraySize)3841 void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
3842 {
3843 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
3844 	const VkDevice					vkDevice			= m_context.getDevice();
3845 	const VkQueue					queue				= m_context.getUniversalQueue();
3846 	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
3847 	std::vector<VkImageCopy>		imageCopies;
3848 
3849 	for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
3850 	{
3851 		const VkImageSubresourceLayers	sourceSubresourceLayers	=
3852 		{
3853 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
3854 			0u,								// deUint32				mipLevel;
3855 			0u,								// deUint32				baseArrayLayer;
3856 			1u								// deUint32				layerCount;
3857 		};
3858 
3859 		const VkImageSubresourceLayers	destinationSubresourceLayers	=
3860 		{
3861 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;//getAspectFlags(dstTcuFormat)
3862 			0u,								// deUint32				mipLevel;
3863 			layerNdx,						// deUint32				baseArrayLayer;
3864 			1u								// deUint32				layerCount;
3865 		};
3866 
3867 		const VkImageCopy				imageCopy	=
3868 		{
3869 			sourceSubresourceLayers,			// VkImageSubresourceLayers	srcSubresource;
3870 			{0, 0, 0},							// VkOffset3D				srcOffset;
3871 			destinationSubresourceLayers,		// VkImageSubresourceLayers	dstSubresource;
3872 			{0, 0, 0},							// VkOffset3D				dstOffset;
3873 			 getExtent3D(m_params.src.image),	// VkExtent3D				extent;
3874 		};
3875 		imageCopies.push_back(imageCopy);
3876 	}
3877 
3878 	const VkImageMemoryBarrier		imageBarriers[]		=
3879 	{
3880 		// source image
3881 		{
3882 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3883 			DE_NULL,									// const void*				pNext;
3884 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
3885 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
3886 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout;
3887 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
3888 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3889 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3890 			m_multisampledImage.get(),					// VkImage					image;
3891 			{											// VkImageSubresourceRange	subresourceRange;
3892 				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
3893 				0u,									// deUint32				baseMipLevel;
3894 				1u,									// deUint32				mipLevels;
3895 				0u,									// deUint32				baseArraySlice;
3896 				getArraySize(m_params.src.image)	// deUint32				arraySize;
3897 			}
3898 		},
3899 		// destination image
3900 		{
3901 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3902 			DE_NULL,									// const void*				pNext;
3903 			0,											// VkAccessFlags			srcAccessMask;
3904 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
3905 			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
3906 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
3907 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3908 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3909 			m_multisampledCopyImage.get(),				// VkImage					image;
3910 			{											// VkImageSubresourceRange	subresourceRange;
3911 				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
3912 				0u,									// deUint32				baseMipLevel;
3913 				1u,									// deUint32				mipLevels;
3914 				0u,									// deUint32				baseArraySlice;
3915 				copyArraySize						// deUint32				arraySize;
3916 			}
3917 		},
3918 	};
3919 
3920 	const VkImageMemoryBarrier	postImageBarriers		=
3921 	// destination image
3922 	{
3923 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3924 		DE_NULL,									// const void*				pNext;
3925 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
3926 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
3927 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
3928 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
3929 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3930 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3931 		m_multisampledCopyImage.get(),				// VkImage					image;
3932 		{											// VkImageSubresourceRange	subresourceRange;
3933 			getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
3934 			0u,									// deUint32				baseMipLevel;
3935 			1u,									// deUint32				mipLevels;
3936 			0u,									// deUint32				baseArraySlice;
3937 			copyArraySize						// deUint32				arraySize;
3938 		}
3939 	};
3940 
3941 	beginCommandBuffer(vk, *m_cmdBuffer);
3942 	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);
3943 	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());
3944 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarriers);
3945 	endCommandBuffer(vk, *m_cmdBuffer);
3946 
3947 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
3948 }
3949 
3950 class ResolveImageToImageTestCase : public vkt::TestCase
3951 {
3952 public:
ResolveImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params,const ResolveImageToImageOptions options=NO_OPTIONAL_OPERATION)3953 							ResolveImageToImageTestCase	(tcu::TestContext&					testCtx,
3954 														 const std::string&					name,
3955 														 const std::string&					description,
3956 														 const TestParams					params,
3957 														 const ResolveImageToImageOptions	options = NO_OPTIONAL_OPERATION)
3958 								: vkt::TestCase	(testCtx, name, description)
3959 								, m_params		(params)
3960 								, m_options		(options)
3961 	{}
3962 
3963 							virtual	void			initPrograms				(SourceCollections&		programCollection) const;
3964 
createInstance(Context & context) const3965 	virtual TestInstance*	createInstance				(Context&				context) const
3966 	{
3967 		return new ResolveImageToImage(context, m_params, m_options);
3968 	}
3969 
checkSupport(Context & context) const3970 	virtual void			checkSupport				(Context&				context) const
3971 	{
3972 		const VkSampleCountFlagBits	rasterizationSamples = m_params.samples;
3973 
3974 		if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
3975 			throw tcu::NotSupportedError("Unsupported number of rasterization samples");
3976 
3977 		VkImageFormatProperties properties;
3978 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
3979 																					m_params.src.image.format,
3980 																					m_params.src.image.imageType,
3981 																					VK_IMAGE_TILING_OPTIMAL,
3982 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
3983 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
3984 			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
3985 																					m_params.dst.image.format,
3986 																					m_params.dst.image.imageType,
3987 																					VK_IMAGE_TILING_OPTIMAL,
3988 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
3989 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
3990 		{
3991 			TCU_THROW(NotSupportedError, "Format not supported");
3992 		}
3993 	}
3994 
3995 private:
3996 	TestParams							m_params;
3997 	const ResolveImageToImageOptions	m_options;
3998 };
3999 
initPrograms(SourceCollections & programCollection) const4000 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
4001 {
4002 	programCollection.glslSources.add("vert") << glu::VertexSource(
4003 		"#version 310 es\n"
4004 		"layout (location = 0) in highp vec4 a_position;\n"
4005 		"void main()\n"
4006 		"{\n"
4007 		"	gl_Position = a_position;\n"
4008 		"}\n");
4009 
4010 
4011 	programCollection.glslSources.add("frag") << glu::FragmentSource(
4012 		"#version 310 es\n"
4013 		"layout (location = 0) out highp vec4 o_color;\n"
4014 		"void main()\n"
4015 		"{\n"
4016 		"	o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
4017 		"}\n");
4018 }
4019 
getSampleCountCaseName(VkSampleCountFlagBits sampleFlag)4020 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
4021 {
4022 	return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
4023 }
4024 
getFormatCaseName(VkFormat format)4025 std::string getFormatCaseName (VkFormat format)
4026 {
4027 	return de::toLower(de::toString(getFormatStr(format)).substr(10));
4028 }
4029 
getImageLayoutCaseName(VkImageLayout layout)4030 std::string getImageLayoutCaseName (VkImageLayout layout)
4031 {
4032 	switch (layout)
4033 	{
4034 		case VK_IMAGE_LAYOUT_GENERAL:
4035 			return "general";
4036 		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
4037 		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
4038 			return "optimal";
4039 		default:
4040 			DE_ASSERT(false);
4041 			return "";
4042 	}
4043 }
4044 
4045 const deInt32					defaultSize				= 64;
4046 const deInt32					defaultHalfSize			= defaultSize / 2;
4047 const deInt32					defaultFourthSize		= defaultSize / 4;
4048 const VkExtent3D				defaultExtent			= {defaultSize, defaultSize, 1};
4049 const VkExtent3D				defaultHalfExtent		= {defaultHalfSize, defaultHalfSize, 1};
4050 
4051 const VkImageSubresourceLayers	defaultSourceLayer		=
4052 {
4053 	VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
4054 	0u,							// deUint32				mipLevel;
4055 	0u,							// deUint32				baseArrayLayer;
4056 	1u,							// deUint32				layerCount;
4057 };
4058 
addImageToImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)4059 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4060 {
4061 	tcu::TestContext& testCtx	= group->getTestContext();
4062 
4063 	{
4064 		TestParams	params;
4065 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
4066 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
4067 		params.src.image.extent				= defaultExtent;
4068 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
4069 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4070 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
4071 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
4072 		params.dst.image.extent				= defaultExtent;
4073 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
4074 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4075 		params.allocationKind				= allocationKind;
4076 
4077 		{
4078 			const VkImageCopy				testCopy	=
4079 			{
4080 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4081 				{0, 0, 0},			// VkOffset3D				srcOffset;
4082 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4083 				{0, 0, 0},			// VkOffset3D				dstOffset;
4084 				defaultExtent,		// VkExtent3D				extent;
4085 			};
4086 
4087 			CopyRegion	imageCopy;
4088 			imageCopy.imageCopy	= testCopy;
4089 
4090 			params.regions.push_back(imageCopy);
4091 		}
4092 
4093 		group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
4094 	}
4095 
4096 	{
4097 		TestParams	params;
4098 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
4099 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
4100 		params.src.image.extent				= defaultExtent;
4101 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
4102 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4103 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
4104 		params.dst.image.format				= VK_FORMAT_R32_UINT;
4105 		params.dst.image.extent				= defaultExtent;
4106 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
4107 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4108 		params.allocationKind				= allocationKind;
4109 
4110 		{
4111 			const VkImageCopy				testCopy	=
4112 			{
4113 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4114 				{0, 0, 0},			// VkOffset3D				srcOffset;
4115 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4116 				{0, 0, 0},			// VkOffset3D				dstOffset;
4117 				defaultExtent,		// VkExtent3D				extent;
4118 			};
4119 
4120 			CopyRegion	imageCopy;
4121 			imageCopy.imageCopy	= testCopy;
4122 
4123 			params.regions.push_back(imageCopy);
4124 		}
4125 
4126 		group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
4127 	}
4128 
4129 	{
4130 		TestParams	params;
4131 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
4132 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
4133 		params.src.image.extent				= defaultExtent;
4134 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
4135 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4136 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
4137 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
4138 		params.dst.image.extent				= defaultExtent;
4139 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
4140 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4141 		params.allocationKind				= allocationKind;
4142 
4143 		{
4144 			const VkImageCopy				testCopy	=
4145 			{
4146 				defaultSourceLayer,									// VkImageSubresourceLayers	srcSubresource;
4147 				{0, 0, 0},											// VkOffset3D				srcOffset;
4148 				defaultSourceLayer,									// VkImageSubresourceLayers	dstSubresource;
4149 				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
4150 				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
4151 			};
4152 
4153 			CopyRegion	imageCopy;
4154 			imageCopy.imageCopy	= testCopy;
4155 
4156 			params.regions.push_back(imageCopy);
4157 		}
4158 
4159 		group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
4160 	}
4161 
4162 	{
4163 		TestParams	params;
4164 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
4165 		params.src.image.format				= VK_FORMAT_D32_SFLOAT;
4166 		params.src.image.extent				= defaultExtent;
4167 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
4168 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4169 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
4170 		params.dst.image.format				= VK_FORMAT_D32_SFLOAT;
4171 		params.dst.image.extent				= defaultExtent;
4172 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
4173 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4174 		params.allocationKind				= allocationKind;
4175 
4176 		{
4177 			const VkImageSubresourceLayers  sourceLayer =
4178 			{
4179 				VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
4180 				0u,							// deUint32				mipLevel;
4181 				0u,							// deUint32				baseArrayLayer;
4182 				1u							// deUint32				layerCount;
4183 			};
4184 			const VkImageCopy				testCopy	=
4185 			{
4186 				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
4187 				{0, 0, 0},											// VkOffset3D				srcOffset;
4188 				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
4189 				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
4190 				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
4191 			};
4192 
4193 			CopyRegion	imageCopy;
4194 			imageCopy.imageCopy	= testCopy;
4195 
4196 			params.regions.push_back(imageCopy);
4197 		}
4198 
4199 		group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
4200 	}
4201 
4202 	{
4203 		TestParams	params;
4204 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
4205 		params.src.image.format				= VK_FORMAT_S8_UINT;
4206 		params.src.image.extent				= defaultExtent;
4207 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
4208 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4209 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
4210 		params.dst.image.format				= VK_FORMAT_S8_UINT;
4211 		params.dst.image.extent				= defaultExtent;
4212 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
4213 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4214 		params.allocationKind				= allocationKind;
4215 
4216 		{
4217 			const VkImageSubresourceLayers  sourceLayer =
4218 			{
4219 				VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
4220 				0u,								// deUint32				mipLevel;
4221 				0u,								// deUint32				baseArrayLayer;
4222 				1u								// deUint32				layerCount;
4223 			};
4224 			const VkImageCopy				testCopy	=
4225 			{
4226 				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
4227 				{0, 0, 0},											// VkOffset3D				srcOffset;
4228 				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
4229 				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
4230 				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
4231 			};
4232 
4233 			CopyRegion	imageCopy;
4234 			imageCopy.imageCopy	= testCopy;
4235 
4236 			params.regions.push_back(imageCopy);
4237 		}
4238 
4239 		group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
4240 	}
4241 }
4242 
4243 struct CopyColorTestParams
4244 {
4245 	TestParams		params;
4246 	const VkFormat*	compatibleFormats;
4247 };
4248 
addImageToImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,TestParams params)4249 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
4250 {
4251 	const VkImageLayout copySrcLayouts[]		=
4252 	{
4253 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4254 		VK_IMAGE_LAYOUT_GENERAL
4255 	};
4256 	const VkImageLayout copyDstLayouts[]		=
4257 	{
4258 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4259 		VK_IMAGE_LAYOUT_GENERAL
4260 	};
4261 
4262 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
4263 	{
4264 		params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
4265 
4266 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
4267 		{
4268 			params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
4269 
4270 			const std::string testName	= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
4271 										  getImageLayoutCaseName(params.dst.image.operationLayout);
4272 			const std::string description	= "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
4273 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
4274 			group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
4275 		}
4276 	}
4277 }
4278 
isAllowedImageToImageAllFormatsColorSrcFormatTests(CopyColorTestParams & testParams)4279 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(CopyColorTestParams& testParams)
4280 {
4281 	bool result = true;
4282 
4283 	if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
4284 	{
4285 		DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
4286 
4287 		result =
4288 			de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
4289 			de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
4290 	}
4291 
4292 	return result;
4293 }
4294 
addImageToImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,CopyColorTestParams testParams)4295 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
4296 {
4297 	for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
4298 	{
4299 		testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
4300 
4301 		const VkFormat		srcFormat	= testParams.params.src.image.format;
4302 		const VkFormat		dstFormat	= testParams.params.dst.image.format;
4303 
4304 		if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
4305 			continue;
4306 
4307 		if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
4308 			continue;
4309 
4310 		if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
4311 			if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) || (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
4312 				continue;
4313 
4314 		const std::string	description	= "Copy to destination format " + getFormatCaseName(dstFormat);
4315 		addTestGroup(group, getFormatCaseName(dstFormat), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
4316 	}
4317 }
4318 
4319 const VkFormat	compatibleFormats8Bit[]		=
4320 {
4321 	VK_FORMAT_R4G4_UNORM_PACK8,
4322 	VK_FORMAT_R8_UNORM,
4323 	VK_FORMAT_R8_SNORM,
4324 	VK_FORMAT_R8_USCALED,
4325 	VK_FORMAT_R8_SSCALED,
4326 	VK_FORMAT_R8_UINT,
4327 	VK_FORMAT_R8_SINT,
4328 	VK_FORMAT_R8_SRGB,
4329 
4330 	VK_FORMAT_UNDEFINED
4331 };
4332 const VkFormat	compatibleFormats16Bit[]	=
4333 {
4334 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
4335 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
4336 	VK_FORMAT_R5G6B5_UNORM_PACK16,
4337 	VK_FORMAT_B5G6R5_UNORM_PACK16,
4338 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
4339 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
4340 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
4341 	VK_FORMAT_R8G8_UNORM,
4342 	VK_FORMAT_R8G8_SNORM,
4343 	VK_FORMAT_R8G8_USCALED,
4344 	VK_FORMAT_R8G8_SSCALED,
4345 	VK_FORMAT_R8G8_UINT,
4346 	VK_FORMAT_R8G8_SINT,
4347 	VK_FORMAT_R8G8_SRGB,
4348 	VK_FORMAT_R16_UNORM,
4349 	VK_FORMAT_R16_SNORM,
4350 	VK_FORMAT_R16_USCALED,
4351 	VK_FORMAT_R16_SSCALED,
4352 	VK_FORMAT_R16_UINT,
4353 	VK_FORMAT_R16_SINT,
4354 	VK_FORMAT_R16_SFLOAT,
4355 
4356 	VK_FORMAT_UNDEFINED
4357 };
4358 const VkFormat	compatibleFormats24Bit[]	=
4359 {
4360 	VK_FORMAT_R8G8B8_UNORM,
4361 	VK_FORMAT_R8G8B8_SNORM,
4362 	VK_FORMAT_R8G8B8_USCALED,
4363 	VK_FORMAT_R8G8B8_SSCALED,
4364 	VK_FORMAT_R8G8B8_UINT,
4365 	VK_FORMAT_R8G8B8_SINT,
4366 	VK_FORMAT_R8G8B8_SRGB,
4367 	VK_FORMAT_B8G8R8_UNORM,
4368 	VK_FORMAT_B8G8R8_SNORM,
4369 	VK_FORMAT_B8G8R8_USCALED,
4370 	VK_FORMAT_B8G8R8_SSCALED,
4371 	VK_FORMAT_B8G8R8_UINT,
4372 	VK_FORMAT_B8G8R8_SINT,
4373 	VK_FORMAT_B8G8R8_SRGB,
4374 
4375 	VK_FORMAT_UNDEFINED
4376 };
4377 const VkFormat	compatibleFormats32Bit[]	=
4378 {
4379 	VK_FORMAT_R8G8B8A8_UNORM,
4380 	VK_FORMAT_R8G8B8A8_SNORM,
4381 	VK_FORMAT_R8G8B8A8_USCALED,
4382 	VK_FORMAT_R8G8B8A8_SSCALED,
4383 	VK_FORMAT_R8G8B8A8_UINT,
4384 	VK_FORMAT_R8G8B8A8_SINT,
4385 	VK_FORMAT_R8G8B8A8_SRGB,
4386 	VK_FORMAT_B8G8R8A8_UNORM,
4387 	VK_FORMAT_B8G8R8A8_SNORM,
4388 	VK_FORMAT_B8G8R8A8_USCALED,
4389 	VK_FORMAT_B8G8R8A8_SSCALED,
4390 	VK_FORMAT_B8G8R8A8_UINT,
4391 	VK_FORMAT_B8G8R8A8_SINT,
4392 	VK_FORMAT_B8G8R8A8_SRGB,
4393 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
4394 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
4395 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
4396 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
4397 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
4398 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
4399 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
4400 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
4401 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
4402 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
4403 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
4404 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
4405 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
4406 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
4407 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
4408 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
4409 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
4410 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
4411 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
4412 	VK_FORMAT_R16G16_UNORM,
4413 	VK_FORMAT_R16G16_SNORM,
4414 	VK_FORMAT_R16G16_USCALED,
4415 	VK_FORMAT_R16G16_SSCALED,
4416 	VK_FORMAT_R16G16_UINT,
4417 	VK_FORMAT_R16G16_SINT,
4418 	VK_FORMAT_R16G16_SFLOAT,
4419 	VK_FORMAT_R32_UINT,
4420 	VK_FORMAT_R32_SINT,
4421 	VK_FORMAT_R32_SFLOAT,
4422 
4423 	VK_FORMAT_UNDEFINED
4424 };
4425 const VkFormat	compatibleFormats48Bit[]	=
4426 {
4427 	VK_FORMAT_R16G16B16_UNORM,
4428 	VK_FORMAT_R16G16B16_SNORM,
4429 	VK_FORMAT_R16G16B16_USCALED,
4430 	VK_FORMAT_R16G16B16_SSCALED,
4431 	VK_FORMAT_R16G16B16_UINT,
4432 	VK_FORMAT_R16G16B16_SINT,
4433 	VK_FORMAT_R16G16B16_SFLOAT,
4434 
4435 	VK_FORMAT_UNDEFINED
4436 };
4437 const VkFormat	compatibleFormats64Bit[]	=
4438 {
4439 	VK_FORMAT_R16G16B16A16_UNORM,
4440 	VK_FORMAT_R16G16B16A16_SNORM,
4441 	VK_FORMAT_R16G16B16A16_USCALED,
4442 	VK_FORMAT_R16G16B16A16_SSCALED,
4443 	VK_FORMAT_R16G16B16A16_UINT,
4444 	VK_FORMAT_R16G16B16A16_SINT,
4445 	VK_FORMAT_R16G16B16A16_SFLOAT,
4446 	VK_FORMAT_R32G32_UINT,
4447 	VK_FORMAT_R32G32_SINT,
4448 	VK_FORMAT_R32G32_SFLOAT,
4449 	VK_FORMAT_R64_UINT,
4450 	VK_FORMAT_R64_SINT,
4451 	VK_FORMAT_R64_SFLOAT,
4452 
4453 	VK_FORMAT_BC1_RGB_UNORM_BLOCK,
4454 	VK_FORMAT_BC1_RGB_SRGB_BLOCK,
4455 	VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
4456 	VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
4457 	VK_FORMAT_BC4_UNORM_BLOCK,
4458 	VK_FORMAT_BC4_SNORM_BLOCK,
4459 
4460 	VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
4461 	VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
4462 	VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
4463 	VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
4464 
4465 	VK_FORMAT_EAC_R11_UNORM_BLOCK,
4466 	VK_FORMAT_EAC_R11_SNORM_BLOCK,
4467 
4468 	VK_FORMAT_UNDEFINED
4469 };
4470 const VkFormat	compatibleFormats96Bit[]	=
4471 {
4472 	VK_FORMAT_R32G32B32_UINT,
4473 	VK_FORMAT_R32G32B32_SINT,
4474 	VK_FORMAT_R32G32B32_SFLOAT,
4475 
4476 	VK_FORMAT_UNDEFINED
4477 };
4478 const VkFormat	compatibleFormats128Bit[]	=
4479 {
4480 	VK_FORMAT_R32G32B32A32_UINT,
4481 	VK_FORMAT_R32G32B32A32_SINT,
4482 	VK_FORMAT_R32G32B32A32_SFLOAT,
4483 	VK_FORMAT_R64G64_UINT,
4484 	VK_FORMAT_R64G64_SINT,
4485 	VK_FORMAT_R64G64_SFLOAT,
4486 
4487 	VK_FORMAT_BC2_UNORM_BLOCK,
4488 	VK_FORMAT_BC2_SRGB_BLOCK,
4489 	VK_FORMAT_BC3_UNORM_BLOCK,
4490 	VK_FORMAT_BC3_SRGB_BLOCK,
4491 	VK_FORMAT_BC5_UNORM_BLOCK,
4492 	VK_FORMAT_BC5_SNORM_BLOCK,
4493 	VK_FORMAT_BC6H_UFLOAT_BLOCK,
4494 	VK_FORMAT_BC6H_SFLOAT_BLOCK,
4495 	VK_FORMAT_BC7_UNORM_BLOCK,
4496 	VK_FORMAT_BC7_SRGB_BLOCK,
4497 
4498 	VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
4499 	VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
4500 
4501 	VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
4502 	VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
4503 
4504 	VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
4505 	VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
4506 	VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
4507 	VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
4508 	VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
4509 	VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
4510 	VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
4511 	VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
4512 	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
4513 	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
4514 	VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
4515 	VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
4516 	VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
4517 	VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
4518 	VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
4519 	VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
4520 	VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
4521 	VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
4522 	VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
4523 	VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
4524 	VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
4525 	VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
4526 	VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
4527 	VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
4528 	VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
4529 	VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
4530 	VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
4531 	VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
4532 
4533 	VK_FORMAT_UNDEFINED
4534 };
4535 const VkFormat	compatibleFormats192Bit[]	=
4536 {
4537 	VK_FORMAT_R64G64B64_UINT,
4538 	VK_FORMAT_R64G64B64_SINT,
4539 	VK_FORMAT_R64G64B64_SFLOAT,
4540 
4541 	VK_FORMAT_UNDEFINED
4542 };
4543 const VkFormat	compatibleFormats256Bit[]	=
4544 {
4545 	VK_FORMAT_R64G64B64A64_UINT,
4546 	VK_FORMAT_R64G64B64A64_SINT,
4547 	VK_FORMAT_R64G64B64A64_SFLOAT,
4548 
4549 	VK_FORMAT_UNDEFINED
4550 };
4551 
4552 const VkFormat*	colorImageFormatsToTest[]	=
4553 {
4554 	compatibleFormats8Bit,
4555 	compatibleFormats16Bit,
4556 	compatibleFormats24Bit,
4557 	compatibleFormats32Bit,
4558 	compatibleFormats48Bit,
4559 	compatibleFormats64Bit,
4560 	compatibleFormats96Bit,
4561 	compatibleFormats128Bit,
4562 	compatibleFormats192Bit,
4563 	compatibleFormats256Bit
4564 };
4565 
4566 const VkFormat	dedicatedAllocationImageToImageFormatsToTest[]	=
4567 {
4568 	// From compatibleFormats8Bit
4569 	VK_FORMAT_R4G4_UNORM_PACK8,
4570 	VK_FORMAT_R8_SRGB,
4571 
4572 	// From compatibleFormats16Bit
4573 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
4574 	VK_FORMAT_R16_SFLOAT,
4575 
4576 	// From compatibleFormats24Bit
4577 	VK_FORMAT_R8G8B8_UNORM,
4578 	VK_FORMAT_B8G8R8_SRGB,
4579 
4580 	// From compatibleFormats32Bit
4581 	VK_FORMAT_R8G8B8A8_UNORM,
4582 	VK_FORMAT_R32_SFLOAT,
4583 
4584 	// From compatibleFormats48Bit
4585 	VK_FORMAT_R16G16B16_UNORM,
4586 	VK_FORMAT_R16G16B16_SFLOAT,
4587 
4588 	// From compatibleFormats64Bit
4589 	VK_FORMAT_R16G16B16A16_UNORM,
4590 	VK_FORMAT_R64_SFLOAT,
4591 
4592 	// From compatibleFormats96Bit
4593 	VK_FORMAT_R32G32B32_UINT,
4594 	VK_FORMAT_R32G32B32_SFLOAT,
4595 
4596 	// From compatibleFormats128Bit
4597 	VK_FORMAT_R32G32B32A32_UINT,
4598 	VK_FORMAT_R64G64_SFLOAT,
4599 
4600 	// From compatibleFormats192Bit
4601 	VK_FORMAT_R64G64B64_UINT,
4602 	VK_FORMAT_R64G64B64_SFLOAT,
4603 
4604 	// From compatibleFormats256Bit
4605 	VK_FORMAT_R64G64B64A64_UINT,
4606 	VK_FORMAT_R64G64B64A64_SFLOAT,
4607 };
4608 
addImageToImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)4609 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4610 {
4611 	TestParams	params;
4612 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
4613 	params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
4614 	params.src.image.extent		= defaultExtent;
4615 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
4616 	params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
4617 	params.dst.image.extent		= defaultExtent;
4618 	params.allocationKind		= allocationKind;
4619 
4620 	for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
4621 	{
4622 		const VkImageCopy				testCopy =
4623 		{
4624 			defaultSourceLayer,								// VkImageSubresourceLayers	srcSubresource;
4625 			{0, 0, 0},										// VkOffset3D				srcOffset;
4626 			defaultSourceLayer,								// VkImageSubresourceLayers	dstSubresource;
4627 			{i, defaultSize - i - defaultFourthSize, 0},	// VkOffset3D				dstOffset;
4628 			{defaultFourthSize, defaultFourthSize, 1},		// VkExtent3D				extent;
4629 		};
4630 
4631 		CopyRegion	imageCopy;
4632 		imageCopy.imageCopy = testCopy;
4633 
4634 		params.regions.push_back(imageCopy);
4635 	}
4636 
4637 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
4638 	{
4639 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
4640 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
4641 			dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
4642 	}
4643 
4644 	const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
4645 	for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
4646 	{
4647 		const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
4648 		for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
4649 		{
4650 			params.src.image.format = compatibleFormats[srcFormatIndex];
4651 			if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
4652 				continue;
4653 
4654 			CopyColorTestParams	testParams;
4655 			testParams.params				= params;
4656 			testParams.compatibleFormats	= compatibleFormats;
4657 
4658 			const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
4659 			addTestGroup(group, getFormatCaseName(params.src.image.format), description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
4660 		}
4661 	}
4662 }
4663 
addImageToImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)4664 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
4665 {
4666 	const VkImageLayout copySrcLayouts[]		=
4667 	{
4668 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4669 		VK_IMAGE_LAYOUT_GENERAL
4670 	};
4671 	const VkImageLayout copyDstLayouts[]		=
4672 	{
4673 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
4674 		VK_IMAGE_LAYOUT_GENERAL
4675 	};
4676 
4677 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
4678 	{
4679 		params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
4680 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
4681 		{
4682 			params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
4683 
4684 			const std::string testName		= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
4685 											  getImageLayoutCaseName(params.dst.image.operationLayout);
4686 			const std::string description	= "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
4687 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
4688 			group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
4689 		}
4690 	}
4691 }
4692 
addImageToImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)4693 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4694 {
4695 	const VkFormat	depthAndStencilFormats[]	=
4696 	{
4697 		VK_FORMAT_D16_UNORM,
4698 		VK_FORMAT_X8_D24_UNORM_PACK32,
4699 		VK_FORMAT_D32_SFLOAT,
4700 		VK_FORMAT_S8_UINT,
4701 		VK_FORMAT_D16_UNORM_S8_UINT,
4702 		VK_FORMAT_D24_UNORM_S8_UINT,
4703 		VK_FORMAT_D32_SFLOAT_S8_UINT,
4704 	};
4705 
4706 	for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
4707 	{
4708 		TestParams	params;
4709 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
4710 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
4711 		params.src.image.extent				= defaultExtent;
4712 		params.dst.image.extent				= defaultExtent;
4713 		params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
4714 		params.dst.image.format				= params.src.image.format;
4715 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
4716 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
4717 		params.allocationKind				= allocationKind;
4718 
4719 		const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
4720 		const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
4721 
4722 		for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
4723 		{
4724 			CopyRegion			copyRegion;
4725 			const VkOffset3D	srcOffset	= {0, 0, 0};
4726 			const VkOffset3D	dstOffset	= {i, defaultSize - i - defaultFourthSize, 0};
4727 			const VkExtent3D	extent		= {defaultFourthSize, defaultFourthSize, 1};
4728 
4729 			if (tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order))
4730 			{
4731 				const VkImageCopy				testCopy	=
4732 				{
4733 					defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4734 					srcOffset,					// VkOffset3D				srcOffset;
4735 					defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4736 					dstOffset,					// VkOffset3D				dstOffset;
4737 					extent,						// VkExtent3D				extent;
4738 				};
4739 
4740 				copyRegion.imageCopy	= testCopy;
4741 				params.regions.push_back(copyRegion);
4742 			}
4743 			if (tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order))
4744 			{
4745 				const VkImageCopy				testCopy	=
4746 				{
4747 					defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
4748 					srcOffset,					// VkOffset3D				srcOffset;
4749 					defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
4750 					dstOffset,					// VkOffset3D				dstOffset;
4751 					extent,						// VkExtent3D				extent;
4752 				};
4753 
4754 				copyRegion.imageCopy	= testCopy;
4755 				params.regions.push_back(copyRegion);
4756 			}
4757 		}
4758 
4759 		const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
4760 		const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
4761 		addTestGroup(group, testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
4762 	}
4763 }
4764 
addImageToImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)4765 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4766 {
4767 	addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind);
4768 	addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind);
4769 }
4770 
addImageToImage3dImagesTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)4771 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
4772 {
4773 	tcu::TestContext& testCtx	= group->getTestContext();
4774 
4775 	{
4776 		TestParams	params3DTo2D;
4777 		const deUint32	slicesLayers			= 16u;
4778 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
4779 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
4780 		params3DTo2D.src.image.extent			= defaultHalfExtent;
4781 		params3DTo2D.src.image.extent.depth		= slicesLayers;
4782 		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
4783 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4784 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
4785 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
4786 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
4787 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
4788 		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
4789 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4790 		params3DTo2D.allocationKind				= allocationKind;
4791 
4792 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
4793 		{
4794 			const VkImageSubresourceLayers	sourceLayer	=
4795 			{
4796 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
4797 				0u,							// deUint32				mipLevel;
4798 				0u,							// deUint32				baseArrayLayer;
4799 				1u							// deUint32				layerCount;
4800 			};
4801 
4802 			const VkImageSubresourceLayers	destinationLayer	=
4803 			{
4804 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
4805 				0u,							// deUint32				mipLevel;
4806 				slicesLayersNdx,			// deUint32				baseArrayLayer;
4807 				1u							// deUint32				layerCount;
4808 			};
4809 
4810 			const VkImageCopy				testCopy	=
4811 			{
4812 				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
4813 				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D					srcOffset;
4814 				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
4815 				{0, 0, 0},							// VkOffset3D					dstOffset;
4816 				defaultHalfExtent,					// VkExtent3D					extent;
4817 			};
4818 
4819 			CopyRegion	imageCopy;
4820 			imageCopy.imageCopy	= testCopy;
4821 
4822 			params3DTo2D.regions.push_back(imageCopy);
4823 		}
4824 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
4825 	}
4826 
4827 	{
4828 		TestParams	params2DTo3D;
4829 		const deUint32	slicesLayers			= 16u;
4830 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
4831 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
4832 		params2DTo3D.src.image.extent			= defaultHalfExtent;
4833 		params2DTo3D.src.image.extent.depth		= slicesLayers;
4834 		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
4835 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4836 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
4837 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
4838 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
4839 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
4840 		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
4841 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4842 		params2DTo3D.allocationKind				= allocationKind;
4843 
4844 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
4845 		{
4846 			const VkImageSubresourceLayers	sourceLayer	=
4847 			{
4848 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
4849 				0u,							// deUint32				mipLevel;
4850 				slicesLayersNdx,			// deUint32				baseArrayLayer;
4851 				1u							// deUint32				layerCount;
4852 			};
4853 
4854 			const VkImageSubresourceLayers	destinationLayer	=
4855 			{
4856 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
4857 				0u,							// deUint32				mipLevel;
4858 				0u,							// deUint32				baseArrayLayer;
4859 				1u							// deUint32				layerCount;
4860 			};
4861 
4862 			const VkImageCopy				testCopy	=
4863 			{
4864 				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
4865 				{0, 0, 0},							// VkOffset3D				srcOffset;
4866 				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
4867 				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D				dstOffset;
4868 				defaultHalfExtent,					// VkExtent3D				extent;
4869 			};
4870 
4871 			CopyRegion	imageCopy;
4872 			imageCopy.imageCopy	= testCopy;
4873 
4874 			params2DTo3D.regions.push_back(imageCopy);
4875 		}
4876 
4877 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
4878 	}
4879 
4880 	{
4881 		TestParams	params3DTo2D;
4882 		const deUint32	slicesLayers			= 16u;
4883 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
4884 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
4885 		params3DTo2D.src.image.extent			= defaultHalfExtent;
4886 		params3DTo2D.src.image.extent.depth		= slicesLayers;
4887 		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
4888 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4889 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
4890 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
4891 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
4892 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
4893 		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
4894 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4895 		params3DTo2D.allocationKind				= allocationKind;
4896 
4897 		{
4898 			const VkImageSubresourceLayers	sourceLayer	=
4899 			{
4900 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
4901 				0u,							// deUint32				mipLevel;
4902 				0u,							// deUint32				baseArrayLayer;
4903 				1u							// deUint32				layerCount;
4904 			};
4905 
4906 			const VkImageSubresourceLayers	destinationLayer	=
4907 			{
4908 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
4909 				0u,							// deUint32				mipLevel;
4910 				0,							// deUint32				baseArrayLayer;
4911 				slicesLayers				// deUint32				layerCount;
4912 			};
4913 
4914 			const VkImageCopy				testCopy	=
4915 			{
4916 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
4917 				{0, 0, 0},						// VkOffset3D				srcOffset;
4918 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
4919 				{0, 0, 0},						// VkOffset3D				dstOffset;
4920 				params3DTo2D.src.image.extent	// VkExtent3D				extent;
4921 			};
4922 
4923 			CopyRegion	imageCopy;
4924 			imageCopy.imageCopy	= testCopy;
4925 
4926 			params3DTo2D.regions.push_back(imageCopy);
4927 		}
4928 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
4929 	}
4930 
4931 	{
4932 		TestParams	params2DTo3D;
4933 		const deUint32	slicesLayers			= 16u;
4934 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
4935 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
4936 		params2DTo3D.src.image.extent			= defaultHalfExtent;
4937 		params2DTo3D.src.image.extent.depth		= slicesLayers;
4938 		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
4939 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4940 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
4941 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
4942 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
4943 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
4944 		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
4945 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4946 		params2DTo3D.allocationKind				= allocationKind;
4947 
4948 		{
4949 			const VkImageSubresourceLayers	sourceLayer	=
4950 			{
4951 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
4952 				0u,							// deUint32				mipLevel;
4953 				0u,							// deUint32				baseArrayLayer;
4954 				slicesLayers				// deUint32				layerCount;
4955 			};
4956 
4957 			const VkImageSubresourceLayers	destinationLayer	=
4958 			{
4959 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
4960 				0u,							// deUint32				mipLevel;
4961 				0u,							// deUint32				baseArrayLayer;
4962 				1u							// deUint32				layerCount;
4963 			};
4964 
4965 			const VkImageCopy				testCopy	=
4966 			{
4967 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
4968 				{0, 0, 0},						// VkOffset3D				srcOffset;
4969 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
4970 				{0, 0, 0},						// VkOffset3D				dstOffset;
4971 				params2DTo3D.src.image.extent,	// VkExtent3D				extent;
4972 			};
4973 
4974 			CopyRegion	imageCopy;
4975 			imageCopy.imageCopy	= testCopy;
4976 
4977 			params2DTo3D.regions.push_back(imageCopy);
4978 		}
4979 
4980 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
4981 	}
4982 
4983 	{
4984 		TestParams	params3DTo2D;
4985 		const deUint32	slicesLayers			= 16u;
4986 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
4987 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
4988 		params3DTo2D.src.image.extent			= defaultHalfExtent;
4989 		params3DTo2D.src.image.extent.depth		= slicesLayers;
4990 		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
4991 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
4992 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
4993 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
4994 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
4995 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
4996 		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
4997 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
4998 		params3DTo2D.allocationKind				= allocationKind;
4999 
5000 		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
5001 		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;
5002 
5003 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
5004 		{
5005 			const VkImageSubresourceLayers	sourceLayer	=
5006 			{
5007 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5008 				0u,							// deUint32				mipLevel;
5009 				0u,							// deUint32				baseArrayLayer;
5010 				1u							// deUint32				layerCount;
5011 			};
5012 
5013 			const VkImageSubresourceLayers	destinationLayer	=
5014 			{
5015 					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
5016 					0u,								// deUint32				mipLevel;
5017 					slicesLayersNdx,				// deUint32				baseArrayLayer;
5018 					1u								// deUint32				layerCount;
5019 			};
5020 
5021 
5022 			const VkImageCopy				testCopy	=
5023 			{
5024 				sourceLayer,															// VkImageSubresourceLayers	srcSubresource;
5025 				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx},	// VkOffset3D				srcOffset;
5026 					destinationLayer,													// VkImageSubresourceLayers	dstSubresource;
5027 					{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},						// VkOffset3D				dstOffset;
5028 					{
5029 						(defaultHalfExtent.width - regionWidth*slicesLayersNdx),
5030 						(defaultHalfExtent.height - regionHeight*slicesLayersNdx),
5031 						1
5032 					}																	// VkExtent3D				extent;
5033 			};
5034 
5035 			CopyRegion	imageCopy;
5036 			imageCopy.imageCopy = testCopy;
5037 			params3DTo2D.regions.push_back(imageCopy);
5038 		}
5039 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
5040 	}
5041 
5042 	{
5043 		TestParams	params2DTo3D;
5044 		const deUint32	slicesLayers			= 16u;
5045 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
5046 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5047 		params2DTo3D.src.image.extent			= defaultHalfExtent;
5048 		params2DTo3D.src.image.extent.depth		= slicesLayers;
5049 		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
5050 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5051 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
5052 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
5053 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
5054 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
5055 		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
5056 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5057 		params2DTo3D.allocationKind				= allocationKind;
5058 
5059 		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
5060 		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;
5061 
5062 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
5063 		{
5064 			const VkImageSubresourceLayers	sourceLayer	=
5065 			{
5066 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5067 				0u,							// deUint32				mipLevel;
5068 				slicesLayersNdx,			// deUint32				baseArrayLayer;
5069 				1u							// deUint32				layerCount;
5070 			};
5071 
5072 			const VkImageSubresourceLayers	destinationLayer	=
5073 			{
5074 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
5075 				0u,							// deUint32				mipLevel;
5076 				0u,							// deUint32				baseArrayLayer;
5077 				1u							// deUint32				layerCount;
5078 			};
5079 
5080 			const VkImageCopy				testCopy	=
5081 			{
5082 				sourceLayer,																// VkImageSubresourceLayers	srcSubresource;
5083 				{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},								// VkOffset3D				srcOffset;
5084 				destinationLayer,															// VkImageSubresourceLayers	dstSubresource;
5085 				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)},	// VkOffset3D				dstOffset;
5086 				{
5087 					defaultHalfExtent.width - regionWidth*slicesLayersNdx,
5088 					defaultHalfExtent.height - regionHeight*slicesLayersNdx,
5089 					1
5090 				}																			// VkExtent3D				extent;
5091 			};
5092 
5093 			CopyRegion	imageCopy;
5094 			imageCopy.imageCopy	= testCopy;
5095 
5096 			params2DTo3D.regions.push_back(imageCopy);
5097 		}
5098 
5099 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
5100 	}
5101 }
5102 
addImageToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5103 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5104 {
5105 	addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind);
5106 	addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind);
5107 	addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind);
5108 }
5109 
addImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5110 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5111 {
5112 	tcu::TestContext& testCtx	= group->getTestContext();
5113 
5114 	{
5115 		TestParams	params;
5116 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
5117 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5118 		params.src.image.extent				= defaultExtent;
5119 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5120 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5121 		params.dst.buffer.size				= defaultSize * defaultSize;
5122 		params.allocationKind				= allocationKind;
5123 
5124 		const VkBufferImageCopy	bufferImageCopy	=
5125 		{
5126 			0u,											// VkDeviceSize				bufferOffset;
5127 			0u,											// deUint32					bufferRowLength;
5128 			0u,											// deUint32					bufferImageHeight;
5129 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
5130 			{0, 0, 0},									// VkOffset3D				imageOffset;
5131 			defaultExtent								// VkExtent3D				imageExtent;
5132 		};
5133 		CopyRegion	copyRegion;
5134 		copyRegion.bufferImageCopy	= bufferImageCopy;
5135 
5136 		params.regions.push_back(copyRegion);
5137 
5138 		group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
5139 	}
5140 
5141 	{
5142 		TestParams	params;
5143 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
5144 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5145 		params.src.image.extent				= defaultExtent;
5146 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5147 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5148 		params.dst.buffer.size				= defaultSize * defaultSize;
5149 		params.allocationKind				= allocationKind;
5150 
5151 		const VkBufferImageCopy	bufferImageCopy	=
5152 		{
5153 			defaultSize * defaultHalfSize,				// VkDeviceSize				bufferOffset;
5154 			0u,											// deUint32					bufferRowLength;
5155 			0u,											// deUint32					bufferImageHeight;
5156 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
5157 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
5158 			defaultHalfExtent							// VkExtent3D				imageExtent;
5159 		};
5160 		CopyRegion	copyRegion;
5161 		copyRegion.bufferImageCopy	= bufferImageCopy;
5162 
5163 		params.regions.push_back(copyRegion);
5164 
5165 		group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
5166 	}
5167 
5168 	{
5169 		TestParams	params;
5170 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
5171 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5172 		params.src.image.extent				= defaultExtent;
5173 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5174 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5175 		params.dst.buffer.size				= defaultSize * defaultSize;
5176 		params.allocationKind				= allocationKind;
5177 
5178 		const int			pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
5179 		const VkDeviceSize	bufferSize	= pixelSize * params.dst.buffer.size;
5180 		const VkDeviceSize	offsetSize	= pixelSize * defaultFourthSize * defaultFourthSize;
5181 		deUint32			divisor		= 1;
5182 		for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
5183 		{
5184 			const deUint32			bufferRowLength		= defaultFourthSize;
5185 			const deUint32			bufferImageHeight	= defaultFourthSize;
5186 			const VkExtent3D		imageExtent			= {defaultFourthSize / divisor, defaultFourthSize, 1};
5187 			DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
5188 			DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
5189 			DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
5190 
5191 			CopyRegion				region;
5192 			const VkBufferImageCopy	bufferImageCopy		=
5193 			{
5194 				offset,						// VkDeviceSize				bufferOffset;
5195 				bufferRowLength,			// deUint32					bufferRowLength;
5196 				bufferImageHeight,			// deUint32					bufferImageHeight;
5197 				defaultSourceLayer,			// VkImageSubresourceLayers	imageSubresource;
5198 				{0, 0, 0},					// VkOffset3D				imageOffset;
5199 				imageExtent					// VkExtent3D				imageExtent;
5200 			};
5201 			region.bufferImageCopy	= bufferImageCopy;
5202 			params.regions.push_back(region);
5203 		}
5204 
5205 		group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
5206 	}
5207 
5208 	{
5209 		TestParams				params;
5210 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
5211 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5212 		params.src.image.extent				= defaultExtent;
5213 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5214 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5215 		params.dst.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
5216 		params.allocationKind				= allocationKind;
5217 
5218 		const VkBufferImageCopy	bufferImageCopy	=
5219 		{
5220 			0u,											// VkDeviceSize				bufferOffset;
5221 			defaultSize,								// deUint32					bufferRowLength;
5222 			defaultSize,								// deUint32					bufferImageHeight;
5223 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
5224 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
5225 			defaultHalfExtent							// VkExtent3D				imageExtent;
5226 		};
5227 		CopyRegion				copyRegion;
5228 		copyRegion.bufferImageCopy	= bufferImageCopy;
5229 
5230 		params.regions.push_back(copyRegion);
5231 
5232 		group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
5233 	}
5234 
5235 	{
5236 		TestParams				params;
5237 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
5238 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5239 		params.src.image.extent				= defaultExtent;
5240 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5241 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5242 		params.dst.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
5243 		params.allocationKind				= allocationKind;
5244 
5245 		const VkBufferImageCopy	bufferImageCopy	=
5246 		{
5247 			defaultFourthSize,							// VkDeviceSize				bufferOffset;
5248 			defaultSize,								// deUint32					bufferRowLength;
5249 			defaultSize,								// deUint32					bufferImageHeight;
5250 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
5251 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
5252 			defaultHalfExtent							// VkExtent3D				imageExtent;
5253 		};
5254 		CopyRegion				copyRegion;
5255 		copyRegion.bufferImageCopy	= bufferImageCopy;
5256 
5257 		params.regions.push_back(copyRegion);
5258 
5259 		group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from image to a buffer that is just large enough to contain the data", params));
5260 	}
5261 }
5262 
addBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5263 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5264 {
5265 	tcu::TestContext& testCtx	= group->getTestContext();
5266 
5267 	{
5268 		TestParams	params;
5269 		params.src.buffer.size				= defaultSize * defaultSize;
5270 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
5271 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
5272 		params.dst.image.extent				= defaultExtent;
5273 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5274 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5275 		params.allocationKind				= allocationKind;
5276 
5277 		const VkBufferImageCopy	bufferImageCopy	=
5278 		{
5279 			0u,											// VkDeviceSize				bufferOffset;
5280 			0u,											// deUint32					bufferRowLength;
5281 			0u,											// deUint32					bufferImageHeight;
5282 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
5283 			{0, 0, 0},									// VkOffset3D				imageOffset;
5284 			defaultExtent								// VkExtent3D				imageExtent;
5285 		};
5286 		CopyRegion	copyRegion;
5287 		copyRegion.bufferImageCopy	= bufferImageCopy;
5288 
5289 		params.regions.push_back(copyRegion);
5290 
5291 		group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
5292 	}
5293 
5294 	{
5295 		TestParams	params;
5296 		params.src.buffer.size				= defaultSize * defaultSize;
5297 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
5298 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5299 		params.dst.image.extent				= defaultExtent;
5300 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5301 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5302 		params.allocationKind				= allocationKind;
5303 
5304 		CopyRegion	region;
5305 		deUint32	divisor	= 1;
5306 		for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
5307 		{
5308 			const VkBufferImageCopy	bufferImageCopy	=
5309 			{
5310 				0u,																// VkDeviceSize				bufferOffset;
5311 				0u,																// deUint32					bufferRowLength;
5312 				0u,																// deUint32					bufferImageHeight;
5313 				defaultSourceLayer,												// VkImageSubresourceLayers	imageSubresource;
5314 				{offset, defaultHalfSize, 0},									// VkOffset3D				imageOffset;
5315 				{defaultFourthSize / divisor, defaultFourthSize / divisor, 1}	// VkExtent3D				imageExtent;
5316 			};
5317 			region.bufferImageCopy	= bufferImageCopy;
5318 			params.regions.push_back(region);
5319 		}
5320 
5321 		group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
5322 	}
5323 
5324 	{
5325 		TestParams	params;
5326 		params.src.buffer.size				= defaultSize * defaultSize;
5327 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
5328 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5329 		params.dst.image.extent				= defaultExtent;
5330 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5331 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5332 		params.allocationKind				= allocationKind;
5333 
5334 		const VkBufferImageCopy	bufferImageCopy	=
5335 		{
5336 			defaultFourthSize,							// VkDeviceSize				bufferOffset;
5337 			defaultHalfSize + defaultFourthSize,		// deUint32					bufferRowLength;
5338 			defaultHalfSize + defaultFourthSize,		// deUint32					bufferImageHeight;
5339 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
5340 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
5341 			defaultHalfExtent							// VkExtent3D				imageExtent;
5342 		};
5343 		CopyRegion	copyRegion;
5344 		copyRegion.bufferImageCopy	= bufferImageCopy;
5345 
5346 		params.regions.push_back(copyRegion);
5347 
5348 		group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
5349 	}
5350 
5351 	{
5352 		TestParams				params;
5353 		params.src.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
5354 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
5355 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5356 		params.dst.image.extent				= defaultExtent;
5357 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5358 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5359 		params.allocationKind				= allocationKind;
5360 
5361 		const VkBufferImageCopy	bufferImageCopy	=
5362 		{
5363 			0u,											// VkDeviceSize				bufferOffset;
5364 			defaultSize,								// deUint32					bufferRowLength;
5365 			defaultSize,								// deUint32					bufferImageHeight;
5366 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
5367 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
5368 			defaultHalfExtent							// VkExtent3D				imageExtent;
5369 		};
5370 		CopyRegion				copyRegion;
5371 		copyRegion.bufferImageCopy	= bufferImageCopy;
5372 
5373 		params.regions.push_back(copyRegion);
5374 
5375 		group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from buffer that is just large enough to contain the accessed elements", params));
5376 	}
5377 
5378 	{
5379 		TestParams				params;
5380 		params.src.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
5381 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
5382 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5383 		params.dst.image.extent				= defaultExtent;
5384 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5385 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5386 		params.allocationKind				= allocationKind;
5387 
5388 		const VkBufferImageCopy	bufferImageCopy	=
5389 		{
5390 			defaultFourthSize,							// VkDeviceSize				bufferOffset;
5391 			defaultSize,								// deUint32					bufferRowLength;
5392 			defaultSize,								// deUint32					bufferImageHeight;
5393 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
5394 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
5395 			defaultHalfExtent							// VkExtent3D				imageExtent;
5396 		};
5397 		CopyRegion				copyRegion;
5398 		copyRegion.bufferImageCopy	= bufferImageCopy;
5399 
5400 		params.regions.push_back(copyRegion);
5401 
5402 		group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from buffer that is just large enough to contain the accessed elements", params));
5403 	}
5404 }
5405 
addBufferToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5406 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5407 {
5408 	tcu::TestContext&				testCtx					= group->getTestContext();
5409 
5410 	{
5411 		TestParams			params;
5412 		params.src.buffer.size	= defaultSize;
5413 		params.dst.buffer.size	= defaultSize;
5414 		params.allocationKind	= allocationKind;
5415 
5416 		const VkBufferCopy	bufferCopy	=
5417 		{
5418 			0u,				// VkDeviceSize	srcOffset;
5419 			0u,				// VkDeviceSize	dstOffset;
5420 			defaultSize,	// VkDeviceSize	size;
5421 		};
5422 
5423 		CopyRegion	copyRegion;
5424 		copyRegion.bufferCopy	= bufferCopy;
5425 		params.regions.push_back(copyRegion);
5426 
5427 		group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
5428 	}
5429 
5430 	// Filter is VK_FILTER_NEAREST.
5431 	{
5432 		TestParams			params;
5433 		params.src.buffer.size	= defaultFourthSize;
5434 		params.dst.buffer.size	= defaultFourthSize;
5435 		params.allocationKind	= allocationKind;
5436 
5437 		const VkBufferCopy	bufferCopy	=
5438 		{
5439 			12u,	// VkDeviceSize	srcOffset;
5440 			4u,		// VkDeviceSize	dstOffset;
5441 			1u,		// VkDeviceSize	size;
5442 		};
5443 
5444 		CopyRegion	copyRegion;
5445 		copyRegion.bufferCopy = bufferCopy;
5446 		params.regions.push_back(copyRegion);
5447 
5448 		group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
5449 	}
5450 
5451 	{
5452 		const deUint32		size		= 16;
5453 		TestParams			params;
5454 		params.src.buffer.size	= size;
5455 		params.dst.buffer.size	= size * (size + 1);
5456 		params.allocationKind	= allocationKind;
5457 
5458 		// Copy region with size 1..size
5459 		for (unsigned int i = 1; i <= size; i++)
5460 		{
5461 			const VkBufferCopy	bufferCopy	=
5462 			{
5463 				0,			// VkDeviceSize	srcOffset;
5464 				i * size,	// VkDeviceSize	dstOffset;
5465 				i,			// VkDeviceSize	size;
5466 			};
5467 
5468 			CopyRegion	copyRegion;
5469 			copyRegion.bufferCopy = bufferCopy;
5470 			params.regions.push_back(copyRegion);
5471 		}
5472 
5473 		group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
5474 	}
5475 }
5476 
addBlittingImageSimpleWholeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5477 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5478 {
5479 	tcu::TestContext&	testCtx			= group->getTestContext();
5480 	TestParams			params;
5481 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
5482 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5483 	params.src.image.extent				= defaultExtent;
5484 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5485 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5486 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
5487 	params.dst.image.extent				= defaultExtent;
5488 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5489 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5490 	params.allocationKind				= allocationKind;
5491 
5492 	{
5493 		const VkImageBlit				imageBlit =
5494 		{
5495 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
5496 			{
5497 				{ 0, 0, 0 },
5498 				{ defaultSize, defaultSize, 1 }
5499 			},					// VkOffset3D				srcOffsets[2];
5500 
5501 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
5502 			{
5503 				{ 0, 0, 0 },
5504 				{ defaultSize, defaultSize, 1 }
5505 			}					// VkOffset3D				dstOffset[2];
5506 		};
5507 
5508 		CopyRegion	region;
5509 		region.imageBlit = imageBlit;
5510 		params.regions.push_back(region);
5511 	}
5512 
5513 	// Filter is VK_FILTER_NEAREST.
5514 	{
5515 		params.filter					= VK_FILTER_NEAREST;
5516 		const std::string description	= "Nearest filter";
5517 
5518 		params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
5519 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
5520 
5521 		params.dst.image.format = VK_FORMAT_R32_SFLOAT;
5522 		const std::string	descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
5523 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
5524 
5525 		params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
5526 		const std::string	descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5527 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
5528 	}
5529 
5530 	// Filter is VK_FILTER_LINEAR.
5531 	{
5532 		params.filter					= VK_FILTER_LINEAR;
5533 		const std::string description	= "Linear filter";
5534 
5535 		params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
5536 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
5537 
5538 		params.dst.image.format = VK_FORMAT_R32_SFLOAT;
5539 		const std::string	descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
5540 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
5541 
5542 		params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
5543 		const std::string	descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5544 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
5545 	}
5546 }
5547 
addBlittingImageSimpleMirrorXYTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5548 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5549 {
5550 	tcu::TestContext&	testCtx			= group->getTestContext();
5551 	TestParams			params;
5552 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
5553 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5554 	params.src.image.extent				= defaultExtent;
5555 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5556 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5557 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
5558 	params.dst.image.extent				= defaultExtent;
5559 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5560 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5561 	params.allocationKind				= allocationKind;
5562 
5563 	{
5564 		const VkImageBlit				imageBlit	=
5565 		{
5566 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
5567 			{
5568 				{0, 0, 0},
5569 				{defaultSize, defaultSize, 1}
5570 			},					// VkOffset3D				srcOffsets[2];
5571 
5572 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
5573 			{
5574 				{defaultSize, defaultSize, 0},
5575 				{0, 0, 1}
5576 			}					// VkOffset3D				dstOffset[2];
5577 		};
5578 
5579 		CopyRegion	region;
5580 		region.imageBlit = imageBlit;
5581 		params.regions.push_back(region);
5582 	}
5583 
5584 	// Filter is VK_FILTER_NEAREST.
5585 	{
5586 		params.filter					= VK_FILTER_NEAREST;
5587 		const std::string description	= "Nearest filter";
5588 
5589 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
5590 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
5591 
5592 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
5593 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
5594 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
5595 
5596 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
5597 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5598 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
5599 	}
5600 
5601 	// Filter is VK_FILTER_LINEAR.
5602 	{
5603 		params.filter					= VK_FILTER_LINEAR;
5604 		const std::string description	= "Linear filter";
5605 
5606 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
5607 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
5608 
5609 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
5610 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
5611 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
5612 
5613 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
5614 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5615 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
5616 	}
5617 }
5618 
addBlittingImageSimpleMirrorXTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5619 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5620 {
5621 	tcu::TestContext&	testCtx			= group->getTestContext();
5622 	TestParams			params;
5623 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
5624 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5625 	params.src.image.extent				= defaultExtent;
5626 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5627 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5628 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
5629 	params.dst.image.extent				= defaultExtent;
5630 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5631 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5632 	params.allocationKind				= allocationKind;
5633 
5634 	{
5635 		const VkImageBlit				imageBlit	=
5636 		{
5637 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
5638 			{
5639 				{0, 0, 0},
5640 				{defaultSize, defaultSize, 1}
5641 			},					// VkOffset3D				srcOffsets[2];
5642 
5643 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
5644 			{
5645 				{defaultSize, 0, 0},
5646 				{0, defaultSize, 1}
5647 			}					// VkOffset3D				dstOffset[2];
5648 		};
5649 
5650 		CopyRegion	region;
5651 		region.imageBlit = imageBlit;
5652 		params.regions.push_back(region);
5653 	}
5654 
5655 	// Filter is VK_FILTER_NEAREST.
5656 	{
5657 		params.filter					= VK_FILTER_NEAREST;
5658 		const std::string description	= "Nearest filter";
5659 
5660 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
5661 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
5662 
5663 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
5664 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
5665 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
5666 
5667 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
5668 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5669 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
5670 	}
5671 
5672 	// Filter is VK_FILTER_LINEAR.
5673 	{
5674 		params.filter					= VK_FILTER_LINEAR;
5675 		const std::string description	= "Linear filter";
5676 
5677 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
5678 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
5679 
5680 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
5681 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
5682 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
5683 
5684 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
5685 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5686 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
5687 	}
5688 }
5689 
addBlittingImageSimpleMirrorYTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5690 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5691 {
5692 	tcu::TestContext&	testCtx			= group->getTestContext();
5693 	TestParams			params;
5694 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
5695 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5696 	params.src.image.extent				= defaultExtent;
5697 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5698 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5699 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
5700 	params.dst.image.extent				= defaultExtent;
5701 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5702 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5703 	params.allocationKind				= allocationKind;
5704 
5705 	{
5706 		const VkImageBlit				imageBlit	=
5707 		{
5708 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
5709 			{
5710 				{0, 0, 0},
5711 				{defaultSize, defaultSize, 1}
5712 			},					// VkOffset3D				srcOffsets[2];
5713 
5714 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
5715 			{
5716 				{0, defaultSize, 0},
5717 				{defaultSize, 0, 1}
5718 			}					// VkOffset3D				dstOffset[2];
5719 		};
5720 
5721 		CopyRegion	region;
5722 		region.imageBlit = imageBlit;
5723 		params.regions.push_back(region);
5724 	}
5725 
5726 	// Filter is VK_FILTER_NEAREST.
5727 	{
5728 		params.filter					= VK_FILTER_NEAREST;
5729 		const std::string description	= "Nearest filter";
5730 
5731 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
5732 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
5733 
5734 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
5735 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
5736 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
5737 
5738 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
5739 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5740 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
5741 	}
5742 
5743 	// Filter is VK_FILTER_LINEAR.
5744 	{
5745 		params.filter					= VK_FILTER_LINEAR;
5746 		const std::string description	= "Linear filter";
5747 
5748 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
5749 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
5750 
5751 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
5752 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
5753 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
5754 
5755 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
5756 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5757 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
5758 	}
5759 }
5760 
addBlittingImageSimpleMirrorSubregionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5761 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5762 {
5763 	tcu::TestContext&	testCtx			= group->getTestContext();
5764 	TestParams			params;
5765 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
5766 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5767 	params.src.image.extent				= defaultExtent;
5768 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5769 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5770 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
5771 	params.dst.image.extent				= defaultExtent;
5772 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5773 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5774 	params.allocationKind				= allocationKind;
5775 
5776 	// No mirroring.
5777 	{
5778 		const VkImageBlit				imageBlit	=
5779 		{
5780 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
5781 			{
5782 				{0, 0, 0},
5783 				{defaultHalfSize, defaultHalfSize, 1}
5784 			},					// VkOffset3D				srcOffsets[2];
5785 
5786 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
5787 			{
5788 				{0, 0, 0},
5789 				{defaultHalfSize, defaultHalfSize, 1}
5790 			}					// VkOffset3D				dstOffset[2];
5791 		};
5792 
5793 		CopyRegion	region;
5794 		region.imageBlit = imageBlit;
5795 		params.regions.push_back(region);
5796 	}
5797 
5798 	// Flipping y coordinates.
5799 	{
5800 		const VkImageBlit				imageBlit	=
5801 		{
5802 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
5803 			{
5804 				{defaultHalfSize, 0, 0},
5805 				{defaultSize, defaultHalfSize, 1}
5806 			},					// VkOffset3D				srcOffsets[2];
5807 
5808 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
5809 			{
5810 				{defaultHalfSize, defaultHalfSize, 0},
5811 				{defaultSize, 0, 1}
5812 			}					// VkOffset3D				dstOffset[2];
5813 		};
5814 		CopyRegion	region;
5815 		region.imageBlit = imageBlit;
5816 		params.regions.push_back(region);
5817 	}
5818 
5819 	// Flipping x coordinates.
5820 	{
5821 		const VkImageBlit				imageBlit	=
5822 		{
5823 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
5824 			{
5825 				{0, defaultHalfSize, 0},
5826 				{defaultHalfSize, defaultSize, 1}
5827 			},					// VkOffset3D				srcOffsets[2];
5828 
5829 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
5830 			{
5831 				{defaultHalfSize, defaultHalfSize, 0},
5832 				{0, defaultSize, 1}
5833 			}					// VkOffset3D				dstOffset[2];
5834 		};
5835 
5836 		CopyRegion	region;
5837 		region.imageBlit = imageBlit;
5838 		params.regions.push_back(region);
5839 	}
5840 
5841 	// Flipping x and y coordinates.
5842 	{
5843 		const VkImageBlit				imageBlit	=
5844 		{
5845 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
5846 			{
5847 				{defaultHalfSize, defaultHalfSize, 0},
5848 				{defaultSize, defaultSize, 1}
5849 			},					// VkOffset3D				srcOffsets[2];
5850 
5851 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
5852 			{
5853 				{defaultSize, defaultSize, 0},
5854 				{defaultHalfSize, defaultHalfSize, 1}
5855 			}					// VkOffset3D				dstOffset[2];
5856 		};
5857 
5858 		CopyRegion	region;
5859 		region.imageBlit = imageBlit;
5860 		params.regions.push_back(region);
5861 	}
5862 
5863 	// Filter is VK_FILTER_NEAREST.
5864 	{
5865 		params.filter					= VK_FILTER_NEAREST;
5866 		const std::string description	= "Nearest filter";
5867 
5868 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
5869 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
5870 
5871 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
5872 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
5873 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
5874 
5875 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
5876 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5877 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
5878 	}
5879 
5880 	// Filter is VK_FILTER_LINEAR.
5881 	{
5882 		params.filter					= VK_FILTER_LINEAR;
5883 		const std::string description	= "Linear filter";
5884 
5885 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
5886 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
5887 
5888 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
5889 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
5890 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
5891 
5892 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
5893 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5894 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
5895 	}
5896 }
5897 
addBlittingImageSimpleScalingWhole1Tests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5898 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5899 {
5900 	tcu::TestContext&	testCtx			= group->getTestContext();
5901 	TestParams			params;
5902 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
5903 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5904 	params.src.image.extent				= defaultExtent;
5905 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5906 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5907 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
5908 	params.dst.image.extent				= defaultHalfExtent;
5909 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5910 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5911 	params.allocationKind				= allocationKind;
5912 
5913 	{
5914 		const VkImageBlit				imageBlit	=
5915 		{
5916 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
5917 			{
5918 				{0, 0, 0},
5919 				{defaultSize, defaultSize, 1}
5920 			},					// VkOffset3D					srcOffsets[2];
5921 
5922 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
5923 			{
5924 				{0, 0, 0},
5925 				{defaultHalfSize, defaultHalfSize, 1}
5926 			}					// VkOffset3D					dstOffset[2];
5927 		};
5928 
5929 		CopyRegion	region;
5930 		region.imageBlit	= imageBlit;
5931 		params.regions.push_back(region);
5932 	}
5933 
5934 	// Filter is VK_FILTER_NEAREST.
5935 	{
5936 		params.filter					= VK_FILTER_NEAREST;
5937 		const std::string description	= "Nearest filter";
5938 
5939 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
5940 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
5941 
5942 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
5943 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
5944 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
5945 
5946 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
5947 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5948 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
5949 	}
5950 
5951 	// Filter is VK_FILTER_LINEAR.
5952 	{
5953 		params.filter					= VK_FILTER_LINEAR;
5954 		const std::string description	= "Linear filter";
5955 
5956 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
5957 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
5958 
5959 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
5960 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)" );
5961 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
5962 
5963 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
5964 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
5965 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
5966 	}
5967 }
5968 
addBlittingImageSimpleScalingWhole2Tests(tcu::TestCaseGroup * group,AllocationKind allocationKind)5969 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
5970 {
5971 	tcu::TestContext&	testCtx			= group->getTestContext();
5972 	TestParams			params;
5973 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
5974 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
5975 	params.src.image.extent				= defaultHalfExtent;
5976 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5977 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
5978 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
5979 	params.dst.image.extent				= defaultExtent;
5980 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
5981 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
5982 	params.allocationKind				= allocationKind;
5983 
5984 	{
5985 		const VkImageBlit				imageBlit	=
5986 		{
5987 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
5988 			{
5989 				{0, 0, 0},
5990 				{defaultHalfSize, defaultHalfSize, 1}
5991 			},					// VkOffset3D					srcOffsets[2];
5992 
5993 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
5994 			{
5995 				{0, 0, 0},
5996 				{defaultSize, defaultSize, 1}
5997 			}					// VkOffset3D					dstOffset[2];
5998 		};
5999 
6000 		CopyRegion	region;
6001 		region.imageBlit	= imageBlit;
6002 		params.regions.push_back(region);
6003 	}
6004 
6005 	// Filter is VK_FILTER_NEAREST.
6006 	{
6007 		params.filter					= VK_FILTER_NEAREST;
6008 		const std::string description	= "Nearest filter";
6009 
6010 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
6011 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
6012 
6013 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
6014 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
6015 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
6016 
6017 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
6018 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
6019 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
6020 	}
6021 
6022 	// Filter is VK_FILTER_LINEAR.
6023 	{
6024 		params.filter					= VK_FILTER_LINEAR;
6025 		const std::string description	= "Linear filter";
6026 
6027 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
6028 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
6029 
6030 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
6031 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
6032 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
6033 
6034 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
6035 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
6036 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
6037 	}
6038 }
6039 
addBlittingImageSimpleScalingAndOffsetTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)6040 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6041 {
6042 	tcu::TestContext&	testCtx			= group->getTestContext();
6043 	TestParams			params;
6044 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
6045 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
6046 	params.src.image.extent				= defaultExtent;
6047 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
6048 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6049 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
6050 	params.dst.image.extent				= defaultExtent;
6051 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
6052 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6053 	params.allocationKind				= allocationKind;
6054 
6055 	{
6056 		const VkImageBlit				imageBlit	=
6057 		{
6058 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
6059 			{
6060 				{defaultFourthSize, defaultFourthSize, 0},
6061 				{defaultFourthSize*3, defaultFourthSize*3, 1}
6062 			},					// VkOffset3D					srcOffsets[2];
6063 
6064 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
6065 			{
6066 				{0, 0, 0},
6067 				{defaultSize, defaultSize, 1}
6068 			}					// VkOffset3D					dstOffset[2];
6069 		};
6070 
6071 		CopyRegion	region;
6072 		region.imageBlit	= imageBlit;
6073 		params.regions.push_back(region);
6074 	}
6075 
6076 	// Filter is VK_FILTER_NEAREST.
6077 	{
6078 		params.filter					= VK_FILTER_NEAREST;
6079 		const std::string description	= "Nearest filter";
6080 
6081 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
6082 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
6083 
6084 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
6085 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
6086 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
6087 
6088 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
6089 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
6090 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
6091 	}
6092 
6093 	// Filter is VK_FILTER_LINEAR.
6094 	{
6095 		params.filter					= VK_FILTER_LINEAR;
6096 		const std::string description	= "Linear filter";
6097 
6098 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
6099 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
6100 
6101 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
6102 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
6103 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
6104 
6105 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
6106 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
6107 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
6108 	}
6109 }
6110 
addBlittingImageSimpleWithoutScalingPartialTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)6111 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6112 {
6113 	tcu::TestContext&	testCtx			= group->getTestContext();
6114 	TestParams			params;
6115 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
6116 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
6117 	params.src.image.extent				= defaultExtent;
6118 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
6119 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
6120 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
6121 	params.dst.image.extent				= defaultExtent;
6122 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
6123 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
6124 	params.allocationKind				= allocationKind;
6125 
6126 	{
6127 		CopyRegion	region;
6128 		for (int i = 0; i < defaultSize; i += defaultFourthSize)
6129 		{
6130 			const VkImageBlit			imageBlit	=
6131 			{
6132 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
6133 				{
6134 					{defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, 0},
6135 					{defaultSize - i, defaultSize - i, 1}
6136 				},					// VkOffset3D					srcOffsets[2];
6137 
6138 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
6139 				{
6140 					{i, i, 0},
6141 					{i + defaultFourthSize, i + defaultFourthSize, 1}
6142 				}					// VkOffset3D					dstOffset[2];
6143 			};
6144 			region.imageBlit	= imageBlit;
6145 			params.regions.push_back(region);
6146 		}
6147 	}
6148 
6149 	// Filter is VK_FILTER_NEAREST.
6150 	{
6151 		params.filter					= VK_FILTER_NEAREST;
6152 		const std::string description	= "Nearest filter";
6153 
6154 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
6155 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
6156 
6157 
6158 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
6159 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
6160 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
6161 
6162 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
6163 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
6164 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
6165 	}
6166 
6167 	// Filter is VK_FILTER_LINEAR.
6168 	{
6169 		params.filter					= VK_FILTER_LINEAR;
6170 		const std::string description	= "Linear filter";
6171 
6172 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
6173 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
6174 
6175 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
6176 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
6177 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
6178 
6179 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
6180 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
6181 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
6182 	}
6183 }
6184 
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)6185 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6186 {
6187 	addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, allocationKind);
6188 	addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, allocationKind);
6189 	addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, allocationKind);
6190 	addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, allocationKind);
6191 	addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, allocationKind);
6192 	addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, allocationKind);
6193 	addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, allocationKind);
6194 	addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, allocationKind);
6195 	addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, allocationKind);
6196 }
6197 
6198 struct BlitColorTestParams
6199 {
6200 	TestParams		params;
6201 	const VkFormat*	compatibleFormats;
6202 	bool			onlyNearest;
6203 };
6204 
isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams & testParams)6205 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
6206 {
6207 	bool result = true;
6208 
6209 	if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
6210 	{
6211 		DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
6212 
6213 		result =
6214 			de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
6215 			de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
6216 	}
6217 
6218 	return result;
6219 }
6220 
6221 const VkFormat	linearOtherImageFormatsToTest[]	=
6222 {
6223 	// From compatibleFormats8Bit
6224 	VK_FORMAT_R4G4_UNORM_PACK8,
6225 	VK_FORMAT_R8_SRGB,
6226 
6227 	// From compatibleFormats16Bit
6228 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
6229 	VK_FORMAT_R16_SFLOAT,
6230 
6231 	// From compatibleFormats24Bit
6232 	VK_FORMAT_R8G8B8_UNORM,
6233 	VK_FORMAT_B8G8R8_SRGB,
6234 
6235 	// From compatibleFormats32Bit
6236 	VK_FORMAT_R8G8B8A8_UNORM,
6237 	VK_FORMAT_R32_SFLOAT,
6238 
6239 	// From compatibleFormats48Bit
6240 	VK_FORMAT_R16G16B16_UNORM,
6241 	VK_FORMAT_R16G16B16_SFLOAT,
6242 
6243 	// From compatibleFormats64Bit
6244 	VK_FORMAT_R16G16B16A16_UNORM,
6245 	VK_FORMAT_R64_SFLOAT,
6246 
6247 	// From compatibleFormats96Bit
6248 	VK_FORMAT_R32G32B32_UINT,
6249 	VK_FORMAT_R32G32B32_SFLOAT,
6250 
6251 	// From compatibleFormats128Bit
6252 	VK_FORMAT_R32G32B32A32_UINT,
6253 	VK_FORMAT_R64G64_SFLOAT,
6254 
6255 	// From compatibleFormats192Bit
6256 	VK_FORMAT_R64G64B64_UINT,
6257 	VK_FORMAT_R64G64B64_SFLOAT,
6258 
6259 	// From compatibleFormats256Bit
6260 	VK_FORMAT_R64G64B64A64_UINT,
6261 	VK_FORMAT_R64G64B64A64_SFLOAT,
6262 };
6263 
getBlitImageTilingLayoutCaseName(VkImageTiling tiling,VkImageLayout layout)6264 std::string getBlitImageTilingLayoutCaseName (VkImageTiling tiling, VkImageLayout layout)
6265 {
6266 	switch (tiling)
6267 	{
6268 		case VK_IMAGE_TILING_OPTIMAL:
6269 			return getImageLayoutCaseName(layout);
6270 		case VK_IMAGE_TILING_LINEAR:
6271 			return "linear";
6272 		default:
6273 			DE_ASSERT(false);
6274 			return "";
6275 	}
6276 }
6277 
addBlittingImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)6278 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
6279 {
6280 	tcu::TestContext& testCtx				= group->getTestContext();
6281 
6282 	FormatSet linearOtherImageFormatsToTestSet;
6283 	const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
6284 	for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter; ++otherImageFormatsIndex)
6285 		linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);
6286 
6287 	const VkImageTiling blitSrcTilings[]	=
6288 	{
6289 		VK_IMAGE_TILING_OPTIMAL,
6290 		VK_IMAGE_TILING_LINEAR,
6291 	};
6292 	const VkImageLayout blitSrcLayouts[]	=
6293 	{
6294 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
6295 		VK_IMAGE_LAYOUT_GENERAL
6296 	};
6297 	const VkImageTiling blitDstTilings[]	=
6298 	{
6299 		VK_IMAGE_TILING_OPTIMAL,
6300 		VK_IMAGE_TILING_LINEAR,
6301 	};
6302 	const VkImageLayout blitDstLayouts[]	=
6303 	{
6304 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
6305 		VK_IMAGE_LAYOUT_GENERAL
6306 	};
6307 
6308 	for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
6309 	{
6310 		testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];
6311 
6312 		for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
6313 		{
6314 			testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
6315 
6316 			// Don't bother testing VK_IMAGE_TILING_LINEAR + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL as it's likely to be the same as VK_IMAGE_LAYOUT_GENERAL
6317 			if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
6318 				continue;
6319 
6320 			for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
6321 			{
6322 				testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];
6323 
6324 				for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
6325 				{
6326 					testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
6327 
6328 					// Don't bother testing VK_IMAGE_TILING_LINEAR + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL as it's likely to be the same as VK_IMAGE_LAYOUT_GENERAL
6329 					if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
6330 						continue;
6331 
6332 					if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
6333 					    (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
6334 						continue;
6335 
6336 					testParams.params.filter			= VK_FILTER_NEAREST;
6337 					const std::string testName			= getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) + "_" +
6338 														  getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
6339 					const std::string description		= "Blit from layout " + getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) +
6340 														  " to " + getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
6341 					group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params));
6342 
6343 					if (!testParams.onlyNearest)
6344 					{
6345 						testParams.params.filter		= VK_FILTER_LINEAR;
6346 						group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params));
6347 					}
6348 				}
6349 			}
6350 		}
6351 	}
6352 }
6353 
addBlittingImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)6354 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
6355 {
6356 	for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
6357 	{
6358 		testParams.params.dst.image.format	= testParams.compatibleFormats[dstFormatIndex];
6359 		if (!isSupportedByFramework(testParams.params.dst.image.format))
6360 			continue;
6361 
6362 		if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
6363 			continue;
6364 
6365 		const std::string description	= "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
6366 		addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
6367 	}
6368 }
6369 
6370 const VkFormat	compatibleFormatsUInts[]	=
6371 {
6372 	VK_FORMAT_R8_UINT,
6373 	VK_FORMAT_R8G8_UINT,
6374 	VK_FORMAT_R8G8B8_UINT,
6375 	VK_FORMAT_B8G8R8_UINT,
6376 	VK_FORMAT_R8G8B8A8_UINT,
6377 	VK_FORMAT_B8G8R8A8_UINT,
6378 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
6379 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
6380 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
6381 	VK_FORMAT_R16_UINT,
6382 	VK_FORMAT_R16G16_UINT,
6383 	VK_FORMAT_R16G16B16_UINT,
6384 	VK_FORMAT_R16G16B16A16_UINT,
6385 	VK_FORMAT_R32_UINT,
6386 	VK_FORMAT_R32G32_UINT,
6387 	VK_FORMAT_R32G32B32_UINT,
6388 	VK_FORMAT_R32G32B32A32_UINT,
6389 	VK_FORMAT_R64_UINT,
6390 	VK_FORMAT_R64G64_UINT,
6391 	VK_FORMAT_R64G64B64_UINT,
6392 	VK_FORMAT_R64G64B64A64_UINT,
6393 
6394 	VK_FORMAT_UNDEFINED
6395 };
6396 const VkFormat	compatibleFormatsSInts[]	=
6397 {
6398 	VK_FORMAT_R8_SINT,
6399 	VK_FORMAT_R8G8_SINT,
6400 	VK_FORMAT_R8G8B8_SINT,
6401 	VK_FORMAT_B8G8R8_SINT,
6402 	VK_FORMAT_R8G8B8A8_SINT,
6403 	VK_FORMAT_B8G8R8A8_SINT,
6404 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
6405 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
6406 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
6407 	VK_FORMAT_R16_SINT,
6408 	VK_FORMAT_R16G16_SINT,
6409 	VK_FORMAT_R16G16B16_SINT,
6410 	VK_FORMAT_R16G16B16A16_SINT,
6411 	VK_FORMAT_R32_SINT,
6412 	VK_FORMAT_R32G32_SINT,
6413 	VK_FORMAT_R32G32B32_SINT,
6414 	VK_FORMAT_R32G32B32A32_SINT,
6415 	VK_FORMAT_R64_SINT,
6416 	VK_FORMAT_R64G64_SINT,
6417 	VK_FORMAT_R64G64B64_SINT,
6418 	VK_FORMAT_R64G64B64A64_SINT,
6419 
6420 	VK_FORMAT_UNDEFINED
6421 };
6422 const VkFormat	compatibleFormatsFloats[]	=
6423 {
6424 	VK_FORMAT_R4G4_UNORM_PACK8,
6425 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
6426 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
6427 	VK_FORMAT_R5G6B5_UNORM_PACK16,
6428 	VK_FORMAT_B5G6R5_UNORM_PACK16,
6429 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
6430 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
6431 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
6432 	VK_FORMAT_R8_UNORM,
6433 	VK_FORMAT_R8_SNORM,
6434 	VK_FORMAT_R8_USCALED,
6435 	VK_FORMAT_R8_SSCALED,
6436 	VK_FORMAT_R8G8_UNORM,
6437 	VK_FORMAT_R8G8_SNORM,
6438 	VK_FORMAT_R8G8_USCALED,
6439 	VK_FORMAT_R8G8_SSCALED,
6440 	VK_FORMAT_R8G8B8_UNORM,
6441 	VK_FORMAT_R8G8B8_SNORM,
6442 	VK_FORMAT_R8G8B8_USCALED,
6443 	VK_FORMAT_R8G8B8_SSCALED,
6444 	VK_FORMAT_B8G8R8_UNORM,
6445 	VK_FORMAT_B8G8R8_SNORM,
6446 	VK_FORMAT_B8G8R8_USCALED,
6447 	VK_FORMAT_B8G8R8_SSCALED,
6448 	VK_FORMAT_R8G8B8A8_UNORM,
6449 	VK_FORMAT_R8G8B8A8_SNORM,
6450 	VK_FORMAT_R8G8B8A8_USCALED,
6451 	VK_FORMAT_R8G8B8A8_SSCALED,
6452 	VK_FORMAT_B8G8R8A8_UNORM,
6453 	VK_FORMAT_B8G8R8A8_SNORM,
6454 	VK_FORMAT_B8G8R8A8_USCALED,
6455 	VK_FORMAT_B8G8R8A8_SSCALED,
6456 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
6457 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
6458 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
6459 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
6460 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
6461 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
6462 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
6463 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
6464 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
6465 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
6466 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
6467 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
6468 	VK_FORMAT_R16_UNORM,
6469 	VK_FORMAT_R16_SNORM,
6470 	VK_FORMAT_R16_USCALED,
6471 	VK_FORMAT_R16_SSCALED,
6472 	VK_FORMAT_R16_SFLOAT,
6473 	VK_FORMAT_R16G16_UNORM,
6474 	VK_FORMAT_R16G16_SNORM,
6475 	VK_FORMAT_R16G16_USCALED,
6476 	VK_FORMAT_R16G16_SSCALED,
6477 	VK_FORMAT_R16G16_SFLOAT,
6478 	VK_FORMAT_R16G16B16_UNORM,
6479 	VK_FORMAT_R16G16B16_SNORM,
6480 	VK_FORMAT_R16G16B16_USCALED,
6481 	VK_FORMAT_R16G16B16_SSCALED,
6482 	VK_FORMAT_R16G16B16_SFLOAT,
6483 	VK_FORMAT_R16G16B16A16_UNORM,
6484 	VK_FORMAT_R16G16B16A16_SNORM,
6485 	VK_FORMAT_R16G16B16A16_USCALED,
6486 	VK_FORMAT_R16G16B16A16_SSCALED,
6487 	VK_FORMAT_R16G16B16A16_SFLOAT,
6488 	VK_FORMAT_R32_SFLOAT,
6489 	VK_FORMAT_R32G32_SFLOAT,
6490 	VK_FORMAT_R32G32B32_SFLOAT,
6491 	VK_FORMAT_R32G32B32A32_SFLOAT,
6492 	VK_FORMAT_R64_SFLOAT,
6493 	VK_FORMAT_R64G64_SFLOAT,
6494 	VK_FORMAT_R64G64B64_SFLOAT,
6495 	VK_FORMAT_R64G64B64A64_SFLOAT,
6496 	VK_FORMAT_B10G11R11_UFLOAT_PACK32,
6497 	VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
6498 //	VK_FORMAT_BC1_RGB_UNORM_BLOCK,
6499 //	VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
6500 //	VK_FORMAT_BC2_UNORM_BLOCK,
6501 //	VK_FORMAT_BC3_UNORM_BLOCK,
6502 //	VK_FORMAT_BC4_UNORM_BLOCK,
6503 //	VK_FORMAT_BC4_SNORM_BLOCK,
6504 //	VK_FORMAT_BC5_UNORM_BLOCK,
6505 //	VK_FORMAT_BC5_SNORM_BLOCK,
6506 //	VK_FORMAT_BC6H_UFLOAT_BLOCK,
6507 //	VK_FORMAT_BC6H_SFLOAT_BLOCK,
6508 //	VK_FORMAT_BC7_UNORM_BLOCK,
6509 //	VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
6510 //	VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
6511 //	VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
6512 //	VK_FORMAT_EAC_R11_UNORM_BLOCK,
6513 //	VK_FORMAT_EAC_R11_SNORM_BLOCK,
6514 //	VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
6515 //	VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
6516 //	VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
6517 //	VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
6518 //	VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
6519 //	VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
6520 //	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
6521 //	VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
6522 //	VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
6523 //	VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
6524 //	VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
6525 //	VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
6526 //	VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
6527 //	VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
6528 //	VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
6529 //	VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
6530 
6531 	VK_FORMAT_UNDEFINED
6532 };
6533 const VkFormat	compatibleFormatsSrgb[]		=
6534 {
6535 	VK_FORMAT_R8_SRGB,
6536 	VK_FORMAT_R8G8_SRGB,
6537 	VK_FORMAT_R8G8B8_SRGB,
6538 	VK_FORMAT_B8G8R8_SRGB,
6539 	VK_FORMAT_R8G8B8A8_SRGB,
6540 	VK_FORMAT_B8G8R8A8_SRGB,
6541 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
6542 //	VK_FORMAT_BC1_RGB_SRGB_BLOCK,
6543 //	VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
6544 //	VK_FORMAT_BC2_SRGB_BLOCK,
6545 //	VK_FORMAT_BC3_SRGB_BLOCK,
6546 //	VK_FORMAT_BC7_SRGB_BLOCK,
6547 //	VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
6548 //	VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
6549 //	VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
6550 //	VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
6551 //	VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
6552 //	VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
6553 //	VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
6554 //	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
6555 //	VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
6556 //	VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
6557 //	VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
6558 //	VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
6559 //	VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
6560 //	VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
6561 //	VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
6562 //	VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
6563 //	VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
6564 
6565 	VK_FORMAT_UNDEFINED
6566 };
6567 
6568 const VkFormat	dedicatedAllocationBlittingFormatsToTest[]	=
6569 {
6570 	// compatibleFormatsUInts
6571 	VK_FORMAT_R8_UINT,
6572 	VK_FORMAT_R64G64B64A64_UINT,
6573 
6574 	// compatibleFormatsSInts
6575 	VK_FORMAT_R8_SINT,
6576 	VK_FORMAT_R64G64B64A64_SINT,
6577 
6578 	// compatibleFormatsFloats
6579 	VK_FORMAT_R4G4_UNORM_PACK8,
6580 	VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
6581 
6582 	// compatibleFormatsSrgb
6583 	VK_FORMAT_R8_SRGB,
6584 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
6585 };
6586 
addBlittingImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)6587 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6588 {
6589 	const struct {
6590 		const VkFormat*	compatibleFormats;
6591 		const bool		onlyNearest;
6592 	}	colorImageFormatsToTestBlit[]			=
6593 	{
6594 		{ compatibleFormatsUInts,	true	},
6595 		{ compatibleFormatsSInts,	true	},
6596 		{ compatibleFormatsFloats,	false	},
6597 		{ compatibleFormatsSrgb,	false	},
6598 	};
6599 
6600 	const int	numOfColorImageFormatsToTest		= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
6601 
6602 	TestParams	params;
6603 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
6604 	params.src.image.extent		= defaultExtent;
6605 	params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
6606 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
6607 	params.dst.image.extent		= defaultExtent;
6608 	params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
6609 	params.allocationKind		= allocationKind;
6610 
6611 	CopyRegion	region;
6612 	for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
6613 	{
6614 		const VkImageBlit			imageBlit	=
6615 		{
6616 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
6617 			{
6618 				{0, 0, 0},
6619 				{defaultSize, defaultSize, 1}
6620 			},					// VkOffset3D					srcOffsets[2];
6621 
6622 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
6623 			{
6624 				{i, 0, 0},
6625 				{i + defaultFourthSize / j, defaultFourthSize / j, 1}
6626 			}					// VkOffset3D					dstOffset[2];
6627 		};
6628 		region.imageBlit	= imageBlit;
6629 		params.regions.push_back(region);
6630 	}
6631 	for (int i = 0; i < defaultSize; i += defaultFourthSize)
6632 	{
6633 		const VkImageBlit			imageBlit	=
6634 		{
6635 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
6636 			{
6637 				{i, i, 0},
6638 				{i + defaultFourthSize, i + defaultFourthSize, 1}
6639 			},					// VkOffset3D					srcOffsets[2];
6640 
6641 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
6642 			{
6643 				{i, defaultSize / 2, 0},
6644 				{i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1}
6645 			}					// VkOffset3D					dstOffset[2];
6646 		};
6647 		region.imageBlit	= imageBlit;
6648 		params.regions.push_back(region);
6649 	}
6650 
6651 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
6652 	{
6653 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
6654 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
6655 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
6656 	}
6657 
6658 	for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
6659 	{
6660 		const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
6661 		const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
6662 		for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
6663 		{
6664 			params.src.image.format	= compatibleFormats[srcFormatIndex];
6665 			if (!isSupportedByFramework(params.src.image.format))
6666 				continue;
6667 
6668 			BlitColorTestParams		testParams;
6669 			testParams.params				= params;
6670 			testParams.compatibleFormats	= compatibleFormats;
6671 			testParams.onlyNearest			= onlyNearest;
6672 
6673 			const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
6674 			addTestGroup(group, getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
6675 		}
6676 	}
6677 }
6678 
addBlittingImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)6679 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
6680 {
6681 	const VkImageLayout blitSrcLayouts[]	=
6682 	{
6683 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
6684 		VK_IMAGE_LAYOUT_GENERAL
6685 	};
6686 	const VkImageLayout blitDstLayouts[]	=
6687 	{
6688 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
6689 		VK_IMAGE_LAYOUT_GENERAL
6690 	};
6691 
6692 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
6693 	{
6694 		params.src.image.operationLayout	= blitSrcLayouts[srcLayoutNdx];
6695 
6696 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
6697 		{
6698 			params.dst.image.operationLayout	= blitDstLayouts[dstLayoutNdx];
6699 			params.filter						= VK_FILTER_NEAREST;
6700 
6701 			const std::string testName		= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
6702 											  getImageLayoutCaseName(params.dst.image.operationLayout);
6703 			const std::string description	= "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
6704 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
6705 
6706 			group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params));
6707 		}
6708 	}
6709 }
6710 
addBlittingImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)6711 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6712 {
6713 	const VkFormat	depthAndStencilFormats[]	=
6714 	{
6715 		VK_FORMAT_D16_UNORM,
6716 		VK_FORMAT_X8_D24_UNORM_PACK32,
6717 		VK_FORMAT_D32_SFLOAT,
6718 		VK_FORMAT_S8_UINT,
6719 		VK_FORMAT_D16_UNORM_S8_UINT,
6720 		VK_FORMAT_D24_UNORM_S8_UINT,
6721 		VK_FORMAT_D32_SFLOAT_S8_UINT,
6722 	};
6723 
6724 	const VkImageSubresourceLayers	defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
6725 	const VkImageSubresourceLayers	defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
6726 	const VkImageSubresourceLayers	defaultDSSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
6727 
6728 	for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
6729 	{
6730 		TestParams	params;
6731 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
6732 		params.src.image.extent				= defaultExtent;
6733 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
6734 		params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
6735 		params.dst.image.extent				= defaultExtent;
6736 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
6737 		params.dst.image.format				= params.src.image.format;
6738 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
6739 		params.allocationKind				= allocationKind;
6740 
6741 		bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
6742 		bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
6743 
6744 		CopyRegion	region;
6745 		for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
6746 		{
6747 			const VkOffset3D	srcOffset0	= {0, 0, 0};
6748 			const VkOffset3D	srcOffset1	= {defaultSize, defaultSize, 1};
6749 			const VkOffset3D	dstOffset0	= {i, 0, 0};
6750 			const VkOffset3D	dstOffset1	= {i + defaultFourthSize / j, defaultFourthSize / j, 1};
6751 
6752 			if (hasDepth)
6753 			{
6754 				const VkImageBlit			imageBlit	=
6755 				{
6756 					defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
6757 					{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
6758 					defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
6759 					{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
6760 				};
6761 				region.imageBlit	= imageBlit;
6762 				params.regions.push_back(region);
6763 			}
6764 			if (hasStencil)
6765 			{
6766 				const VkImageBlit			imageBlit	=
6767 				{
6768 					defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
6769 					{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
6770 					defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
6771 					{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
6772 				};
6773 				region.imageBlit	= imageBlit;
6774 				params.regions.push_back(region);
6775 			}
6776 		}
6777 		for (int i = 0; i < defaultSize; i += defaultFourthSize)
6778 		{
6779 			const VkOffset3D	srcOffset0	= {i, i, 0};
6780 			const VkOffset3D	srcOffset1	= {i + defaultFourthSize, i + defaultFourthSize, 1};
6781 			const VkOffset3D	dstOffset0	= {i, defaultSize / 2, 0};
6782 			const VkOffset3D	dstOffset1	= {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};
6783 
6784 			if (hasDepth)
6785 			{
6786 				const VkImageBlit			imageBlit	=
6787 				{
6788 					defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
6789 					{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
6790 					defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
6791 					{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
6792 				};
6793 				region.imageBlit	= imageBlit;
6794 				params.regions.push_back(region);
6795 			}
6796 			if (hasStencil)
6797 			{
6798 				const VkImageBlit			imageBlit	=
6799 				{
6800 					defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
6801 					{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
6802 					defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
6803 					{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
6804 				};
6805 				region.imageBlit	= imageBlit;
6806 				params.regions.push_back(region);
6807 			}
6808 			if (hasDepth && hasStencil)
6809 			{
6810 				const VkOffset3D			dstDSOffset0	= {i, 3 * defaultFourthSize, 0};
6811 				const VkOffset3D			dstDSOffset1	= {i + defaultFourthSize, defaultSize, 1};
6812 				const VkImageBlit			imageBlit	=
6813 				{
6814 					defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
6815 					{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
6816 					defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
6817 					{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
6818 				};
6819 				region.imageBlit	= imageBlit;
6820 				params.regions.push_back(region);
6821 			}
6822 		}
6823 
6824 		const std::string testName		= getFormatCaseName(params.src.image.format) + "_" +
6825 										  getFormatCaseName(params.dst.image.format);
6826 		const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
6827 										  " to " + getFormatCaseName(params.dst.image.format);
6828 		addTestGroup(group, testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
6829 	}
6830 }
6831 
addBlittingImageAllFormatsMipmapFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)6832 void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
6833 {
6834 	tcu::TestContext& testCtx				= group->getTestContext();
6835 
6836 	const VkImageLayout blitSrcLayouts[]	=
6837 	{
6838 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
6839 		VK_IMAGE_LAYOUT_GENERAL
6840 	};
6841 	const VkImageLayout blitDstLayouts[]	=
6842 	{
6843 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
6844 		VK_IMAGE_LAYOUT_GENERAL
6845 	};
6846 
6847 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
6848 	{
6849 		testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
6850 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
6851 		{
6852 			testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
6853 
6854 			testParams.params.filter			= VK_FILTER_NEAREST;
6855 			const std::string testName			= getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
6856 												  getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
6857 			const std::string description		= "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
6858 												  " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
6859 			group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params));
6860 
6861 			if (!testParams.onlyNearest)
6862 			{
6863 				testParams.params.filter		= VK_FILTER_LINEAR;
6864 				group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params));
6865 			}
6866 		}
6867 	}
6868 }
6869 
addBlittingImageAllFormatsBaseLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)6870 void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6871 {
6872 	const struct
6873 	{
6874 		const VkFormat* const	compatibleFormats;
6875 		const bool				onlyNearest;
6876 	}	colorImageFormatsToTestBlit[]			=
6877 	{
6878 		{ compatibleFormatsUInts,	true	},
6879 		{ compatibleFormatsSInts,	true	},
6880 		{ compatibleFormatsFloats,	false	},
6881 		{ compatibleFormatsSrgb,	false	},
6882 	};
6883 
6884 	const int	numOfColorImageFormatsToTest	= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
6885 
6886 	const int	layerCountsToTest[]				=
6887 	{
6888 		1,
6889 		6
6890 	};
6891 
6892 	TestParams	params;
6893 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
6894 	params.src.image.extent		= defaultExtent;
6895 	params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
6896 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
6897 	params.dst.image.extent		= defaultExtent;
6898 	params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
6899 	params.allocationKind		= allocationKind;
6900 	params.mipLevels			= deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
6901 	params.singleCommand		= DE_TRUE;
6902 
6903 	CopyRegion	region;
6904 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
6905 	{
6906 		VkImageSubresourceLayers	destLayer	= defaultSourceLayer;
6907 		destLayer.mipLevel = mipLevelNdx;
6908 
6909 		const VkImageBlit			imageBlit	=
6910 		{
6911 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
6912 			{
6913 				{0, 0, 0},
6914 				{defaultSize, defaultSize, 1}
6915 			},					// VkOffset3D					srcOffsets[2];
6916 
6917 			destLayer,			// VkImageSubresourceLayers	dstSubresource;
6918 			{
6919 				{0, 0, 0},
6920 				{defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
6921 			}					// VkOffset3D					dstOffset[2];
6922 		};
6923 		region.imageBlit	= imageBlit;
6924 		params.regions.push_back(region);
6925 	}
6926 
6927 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
6928 	{
6929 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
6930 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
6931 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
6932 	}
6933 
6934 	for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
6935 	{
6936 		const int						layerCount		= layerCountsToTest[layerCountIndex];
6937 		const std::string				layerGroupName	= "layercount_" + de::toString(layerCount);
6938 		const std::string				layerGroupDesc	= "Blit mipmaps with layerCount = " + de::toString(layerCount);
6939 
6940 		de::MovePtr<tcu::TestCaseGroup>	layerCountGroup	(new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
6941 
6942 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
6943 		{
6944 			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
6945 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
6946 
6947 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
6948 			{
6949 				params.src.image.format	= compatibleFormats[srcFormatIndex];
6950 				params.dst.image.format	= compatibleFormats[srcFormatIndex];
6951 
6952 				if (!isSupportedByFramework(params.src.image.format))
6953 					continue;
6954 
6955 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
6956 
6957 				BlitColorTestParams testParams;
6958 				testParams.params				= params;
6959 				testParams.compatibleFormats	= compatibleFormats;
6960 				testParams.onlyNearest			= onlyNearest;
6961 
6962 				testParams.params.src.image.extent.depth = layerCount;
6963 				testParams.params.dst.image.extent.depth = layerCount;
6964 
6965 				for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
6966 				{
6967 					testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
6968 					testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
6969 				}
6970 
6971 				addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
6972 			}
6973 		}
6974 		group->addChild(layerCountGroup.release());
6975 	}
6976 }
6977 
addBlittingImageAllFormatsPreviousLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)6978 void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
6979 {
6980 	const struct
6981 	{
6982 		const VkFormat* const	compatibleFormats;
6983 		const bool				onlyNearest;
6984 	}	colorImageFormatsToTestBlit[]			=
6985 	{
6986 		{ compatibleFormatsUInts,	true	},
6987 		{ compatibleFormatsSInts,	true	},
6988 		{ compatibleFormatsFloats,	false	},
6989 		{ compatibleFormatsSrgb,	false	},
6990 	};
6991 
6992 	const int	numOfColorImageFormatsToTest	= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
6993 
6994 	const int	layerCountsToTest[]				=
6995 	{
6996 		1,
6997 		6
6998 	};
6999 
7000 	TestParams	params;
7001 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
7002 	params.src.image.extent		= defaultExtent;
7003 	params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
7004 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
7005 	params.dst.image.extent		= defaultExtent;
7006 	params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
7007 	params.allocationKind		= allocationKind;
7008 	params.mipLevels			= deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
7009 	params.singleCommand		= DE_FALSE;
7010 
7011 	CopyRegion	region;
7012 	for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
7013 	{
7014 		VkImageSubresourceLayers	srcLayer	= defaultSourceLayer;
7015 		VkImageSubresourceLayers	destLayer	= defaultSourceLayer;
7016 
7017 		srcLayer.mipLevel	= mipLevelNdx - 1u;
7018 		destLayer.mipLevel	= mipLevelNdx;
7019 
7020 		const VkImageBlit			imageBlit	=
7021 		{
7022 			srcLayer,			// VkImageSubresourceLayers	srcSubresource;
7023 			{
7024 				{0, 0, 0},
7025 				{defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}
7026 			},					// VkOffset3D					srcOffsets[2];
7027 
7028 			destLayer,			// VkImageSubresourceLayers	dstSubresource;
7029 			{
7030 				{0, 0, 0},
7031 				{defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
7032 			}					// VkOffset3D					dstOffset[2];
7033 		};
7034 		region.imageBlit	= imageBlit;
7035 		params.regions.push_back(region);
7036 	}
7037 
7038 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
7039 	{
7040 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
7041 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
7042 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
7043 	}
7044 
7045 	for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
7046 	{
7047 		const int						layerCount		= layerCountsToTest[layerCountIndex];
7048 		const std::string				layerGroupName	= "layercount_" + de::toString(layerCount);
7049 		const std::string				layerGroupDesc	= "Blit mipmaps with layerCount = " + de::toString(layerCount);
7050 
7051 		de::MovePtr<tcu::TestCaseGroup>	layerCountGroup	(new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
7052 
7053 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7054 		{
7055 			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
7056 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
7057 
7058 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7059 			{
7060 				params.src.image.format						= compatibleFormats[srcFormatIndex];
7061 				params.dst.image.format						= compatibleFormats[srcFormatIndex];
7062 
7063 				if (!isSupportedByFramework(params.src.image.format))
7064 					continue;
7065 
7066 				const std::string	description				= "Blit source format " + getFormatCaseName(params.src.image.format);
7067 
7068 				BlitColorTestParams	testParams;
7069 				testParams.params							= params;
7070 				testParams.compatibleFormats				= compatibleFormats;
7071 				testParams.onlyNearest						= onlyNearest;
7072 
7073 				testParams.params.src.image.extent.depth	= layerCount;
7074 				testParams.params.dst.image.extent.depth	= layerCount;
7075 
7076 				for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
7077 				{
7078 					testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
7079 					testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
7080 				}
7081 
7082 				addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
7083 			}
7084 		}
7085 		group->addChild(layerCountGroup.release());
7086 	}
7087 
7088 	for (int multiLayer = 0; multiLayer < 2; multiLayer++)
7089 	{
7090 		const int layerCount = multiLayer ? 6 : 1;
7091 
7092 		for (int barrierCount = 1; barrierCount < 4; barrierCount++)
7093 		{
7094 			if (layerCount != 1 || barrierCount != 1)
7095 			{
7096 				const std::string				barrierGroupName = (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
7097 				const std::string				barrierGroupDesc = "Use " + de::toString(barrierCount) + " image barriers";
7098 
7099 				de::MovePtr<tcu::TestCaseGroup>	barrierCountGroup(new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str(), barrierGroupDesc.c_str()));
7100 
7101 				params.barrierCount = barrierCount;
7102 
7103 				// Only go through a few common formats
7104 				for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
7105 				{
7106 					params.src.image.format						= compatibleFormatsUInts[srcFormatIndex];
7107 					params.dst.image.format						= compatibleFormatsUInts[srcFormatIndex];
7108 
7109 					if (!isSupportedByFramework(params.src.image.format))
7110 						continue;
7111 
7112 					const std::string description				= "Blit source format " + getFormatCaseName(params.src.image.format);
7113 
7114 					BlitColorTestParams testParams;
7115 					testParams.params							= params;
7116 					testParams.compatibleFormats				= compatibleFormatsUInts;
7117 					testParams.onlyNearest						= true;
7118 
7119 					testParams.params.src.image.extent.depth	= layerCount;
7120 					testParams.params.dst.image.extent.depth	= layerCount;
7121 
7122 					for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
7123 					{
7124 						testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
7125 						testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
7126 					}
7127 
7128 					addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
7129 				}
7130 				group->addChild(barrierCountGroup.release());
7131 			}
7132 		}
7133 	}
7134 }
7135 
addBlittingImageAllFormatsMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)7136 void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
7137 {
7138 	addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind);
7139 	addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind);
7140 }
7141 
addBlittingImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)7142 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
7143 {
7144 	addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind);
7145 	addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind);
7146 	addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind);
7147 }
7148 
addBlittingImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)7149 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
7150 {
7151 	addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind);
7152 	addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind);
7153 }
7154 
7155 const VkSampleCountFlagBits	samples[]		=
7156 {
7157 	VK_SAMPLE_COUNT_2_BIT,
7158 	VK_SAMPLE_COUNT_4_BIT,
7159 	VK_SAMPLE_COUNT_8_BIT,
7160 	VK_SAMPLE_COUNT_16_BIT,
7161 	VK_SAMPLE_COUNT_32_BIT,
7162 	VK_SAMPLE_COUNT_64_BIT
7163 };
7164 const VkExtent3D			resolveExtent	= {256u, 256u, 1};
7165 
addResolveImageWholeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)7166 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
7167 {
7168 	TestParams	params;
7169 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7170 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7171 	params.src.image.extent				= resolveExtent;
7172 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7173 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7174 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7175 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7176 	params.dst.image.extent				= resolveExtent;
7177 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7178 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7179 	params.allocationKind				= allocationKind;
7180 
7181 	{
7182 		const VkImageSubresourceLayers	sourceLayer	=
7183 		{
7184 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
7185 			0u,							// deUint32				mipLevel;
7186 			0u,							// deUint32				baseArrayLayer;
7187 			1u							// deUint32				layerCount;
7188 		};
7189 		const VkImageResolve			testResolve	=
7190 		{
7191 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
7192 			{0, 0, 0},		// VkOffset3D				srcOffset;
7193 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
7194 			{0, 0, 0},		// VkOffset3D				dstOffset;
7195 			resolveExtent,	// VkExtent3D				extent;
7196 		};
7197 
7198 		CopyRegion	imageResolve;
7199 		imageResolve.imageResolve	= testResolve;
7200 		params.regions.push_back(imageResolve);
7201 	}
7202 
7203 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
7204 	{
7205 		params.samples					= samples[samplesIndex];
7206 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
7207 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
7208 	}
7209 }
7210 
addResolveImagePartialTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)7211 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
7212 {
7213 	TestParams	params;
7214 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7215 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7216 	params.src.image.extent				= resolveExtent;
7217 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7218 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7219 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7220 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7221 	params.dst.image.extent				= resolveExtent;
7222 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7223 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7224 	params.allocationKind				= allocationKind;
7225 
7226 	{
7227 		const VkImageSubresourceLayers	sourceLayer	=
7228 		{
7229 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
7230 			0u,							// deUint32				mipLevel;
7231 			0u,							// deUint32				baseArrayLayer;
7232 			1u							// deUint32				layerCount;
7233 		};
7234 		const VkImageResolve			testResolve	=
7235 		{
7236 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
7237 			{0, 0, 0},		// VkOffset3D				srcOffset;
7238 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
7239 			{64u, 64u, 0},		// VkOffset3D				dstOffset;
7240 			{128u, 128u, 1u},	// VkExtent3D				extent;
7241 		};
7242 
7243 		CopyRegion	imageResolve;
7244 		imageResolve.imageResolve = testResolve;
7245 		params.regions.push_back(imageResolve);
7246 	}
7247 
7248 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
7249 	{
7250 		params.samples					= samples[samplesIndex];
7251 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
7252 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
7253 	}
7254 }
7255 
addResolveImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)7256 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
7257 {
7258 	TestParams	params;
7259 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7260 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7261 	params.src.image.extent				= resolveExtent;
7262 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7263 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7264 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7265 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7266 	params.dst.image.extent				= resolveExtent;
7267 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7268 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7269 	params.allocationKind				= allocationKind;
7270 
7271 	{
7272 		const VkImageSubresourceLayers	sourceLayer	=
7273 		{
7274 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
7275 			0u,							// deUint32				mipLevel;
7276 			0u,							// deUint32				baseArrayLayer;
7277 			1u							// deUint32				layerCount;
7278 		};
7279 
7280 		for (int i = 0; i < 256; i += 64)
7281 		{
7282 			const VkImageResolve			testResolve	=
7283 			{
7284 				sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
7285 				{i, i, 0},		// VkOffset3D				srcOffset;
7286 				sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
7287 				{i, 0, 0},		// VkOffset3D				dstOffset;
7288 				{64u, 64u, 1u},	// VkExtent3D				extent;
7289 			};
7290 
7291 			CopyRegion	imageResolve;
7292 			imageResolve.imageResolve = testResolve;
7293 			params.regions.push_back(imageResolve);
7294 		}
7295 	}
7296 
7297 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
7298 	{
7299 		params.samples					= samples[samplesIndex];
7300 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
7301 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
7302 	}
7303 }
7304 
addResolveImageWholeCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)7305 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
7306 {
7307 	TestParams	params;
7308 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7309 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7310 	params.src.image.extent				= defaultExtent;
7311 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7312 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7313 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7314 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7315 	params.dst.image.extent				= defaultExtent;
7316 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7317 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7318 	params.allocationKind				= allocationKind;
7319 
7320 	{
7321 		const VkImageSubresourceLayers	sourceLayer	=
7322 		{
7323 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
7324 			0u,							// deUint32				mipLevel;
7325 			0u,							// deUint32				baseArrayLayer;
7326 			1u							// deUint32				layerCount;
7327 		};
7328 
7329 		const VkImageResolve			testResolve	=
7330 		{
7331 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
7332 			{0, 0, 0},			// VkOffset3D				srcOffset;
7333 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
7334 			{0, 0, 0},			// VkOffset3D				dstOffset;
7335 			defaultExtent,		// VkExtent3D				extent;
7336 		};
7337 
7338 		CopyRegion	imageResolve;
7339 		imageResolve.imageResolve	= testResolve;
7340 		params.regions.push_back(imageResolve);
7341 	}
7342 
7343 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
7344 	{
7345 		params.samples					= samples[samplesIndex];
7346 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
7347 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
7348 	}
7349 }
7350 
addResolveImageWholeArrayImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)7351 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
7352 {
7353 	TestParams	params;
7354 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7355 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7356 	params.src.image.extent				= defaultExtent;
7357 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7358 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7359 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7360 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7361 	params.dst.image.extent				= defaultExtent;
7362 	params.dst.image.extent.depth		= 5u;
7363 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7364 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7365 	params.allocationKind				= allocationKind;
7366 
7367 	for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
7368 	{
7369 		const VkImageSubresourceLayers	sourceLayer	=
7370 		{
7371 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
7372 			0u,								// deUint32				mipLevel;
7373 			layerNdx,						// deUint32				baseArrayLayer;
7374 			1u								// deUint32				layerCount;
7375 		};
7376 
7377 		const VkImageResolve			testResolve	=
7378 		{
7379 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
7380 			{0, 0, 0},			// VkOffset3D				srcOffset;
7381 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
7382 			{0, 0, 0},			// VkOffset3D				dstOffset;
7383 			defaultExtent,		// VkExtent3D				extent;
7384 		};
7385 
7386 		CopyRegion	imageResolve;
7387 		imageResolve.imageResolve	= testResolve;
7388 		params.regions.push_back(imageResolve);
7389 	}
7390 
7391 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
7392 	{
7393 		params.samples					= samples[samplesIndex];
7394 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
7395 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
7396 	}
7397 }
7398 
addResolveImageWholeArrayImageSingleRegionTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)7399 void addResolveImageWholeArrayImageSingleRegionTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
7400 {
7401 	TestParams	params;
7402 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7403 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7404 	params.src.image.extent				= defaultExtent;
7405 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7406 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7407 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7408 	params.dst.image.extent				= defaultExtent;
7409 	params.dst.image.extent.depth		= 5u;
7410 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7411 	params.allocationKind				= allocationKind;
7412 
7413 	const VkImageSubresourceLayers	sourceLayer	=
7414 	{
7415 		VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
7416 		0u,								// uint32_t				mipLevel;
7417 		0,						// uint32_t				baseArrayLayer;
7418 		params.dst.image.extent.depth			// uint32_t				layerCount;
7419 	};
7420 
7421 	const VkImageResolve			testResolve	=
7422 	{
7423 		sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
7424 		{0, 0, 0},			// VkOffset3D				srcOffset;
7425 		sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
7426 		{0, 0, 0},			// VkOffset3D				dstOffset;
7427 		defaultExtent,		// VkExtent3D				extent;
7428 	};
7429 
7430 	CopyRegion	imageResolve;
7431 	imageResolve.imageResolve	= testResolve;
7432 	params.regions.push_back(imageResolve);
7433 
7434 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
7435 	{
7436 		params.samples					= samples[samplesIndex];
7437 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
7438 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
7439 	}
7440 }
7441 
addResolveImageDiffImageSizeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)7442 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
7443 {
7444 	tcu::TestContext&	testCtx			= group->getTestContext();
7445 	TestParams			params;
7446 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7447 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7448 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7449 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7450 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7451 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
7452 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7453 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7454 	params.allocationKind				= allocationKind;
7455 
7456 	{
7457 		const VkImageSubresourceLayers	sourceLayer	=
7458 		{
7459 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
7460 			0u,							// deUint32				mipLevel;
7461 			0u,							// deUint32				baseArrayLayer;
7462 			1u							// deUint32				layerCount;
7463 		};
7464 		const VkImageResolve			testResolve	=
7465 		{
7466 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
7467 			{0, 0, 0},		// VkOffset3D				srcOffset;
7468 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
7469 			{0, 0, 0},		// VkOffset3D				dstOffset;
7470 			resolveExtent,	// VkExtent3D				extent;
7471 		};
7472 		CopyRegion	imageResolve;
7473 		imageResolve.imageResolve	= testResolve;
7474 		params.regions.push_back(imageResolve);
7475 	}
7476 
7477 	const VkExtent3D imageExtents[]		=
7478 	{
7479 		{ resolveExtent.width + 10,	resolveExtent.height,		resolveExtent.depth },
7480 		{ resolveExtent.width,		resolveExtent.height * 2,	resolveExtent.depth },
7481 		{ resolveExtent.width,		resolveExtent.height,		resolveExtent.depth + 10 }
7482 	};
7483 
7484 	for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
7485 	{
7486 		const VkExtent3D&	srcImageSize	= imageExtents[srcImageExtentIndex];
7487 		params.src.image.extent				= srcImageSize;
7488 		params.dst.image.extent				= resolveExtent;
7489 		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
7490 		{
7491 			params.samples	= samples[samplesIndex];
7492 			std::ostringstream testName;
7493 			testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
7494 			std::ostringstream description;
7495 			description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
7496 						<< srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
7497 			group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
7498 		}
7499 	}
7500 	for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
7501 	{
7502 		const VkExtent3D&	dstImageSize	= imageExtents[dstImageExtentIndex];
7503 		params.src.image.extent				= resolveExtent;
7504 		params.dst.image.extent				= dstImageSize;
7505 		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
7506 		{
7507 			params.samples	= samples[samplesIndex];
7508 			std::ostringstream testName;
7509 			testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
7510 			std::ostringstream description;
7511 			description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
7512 						<< dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
7513 			group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
7514 		}
7515 	}
7516 }
7517 
addResolveImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)7518 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
7519 {
7520 	addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind);
7521 	addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind);
7522 	addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind);
7523 	addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind);
7524 	addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind);
7525 	addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind);
7526 	addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind);
7527 }
7528 
addCopiesAndBlittingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind)7529 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
7530 {
7531 	addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind);
7532 	addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind);
7533 	addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind);
7534 	addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind);
7535 	addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind);
7536 	addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind);
7537 }
7538 
addCoreCopiesAndBlittingTests(tcu::TestCaseGroup * group)7539 void addCoreCopiesAndBlittingTests (tcu::TestCaseGroup* group)
7540 {
7541 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED);
7542 }
7543 
addDedicatedAllocationCopiesAndBlittingTests(tcu::TestCaseGroup * group)7544 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
7545 {
7546 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED);
7547 }
7548 
7549 } // anonymous
7550 
createCopiesAndBlittingTests(tcu::TestContext & testCtx)7551 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
7552 {
7553 	de::MovePtr<tcu::TestCaseGroup>	copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
7554 
7555 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core",					"Core Copies And Blitting Tests",								addCoreCopiesAndBlittingTests));
7556 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation",	"Copies And Blitting Tests For Dedicated Memory Allocation",	addDedicatedAllocationCopiesAndBlittingTests));
7557 
7558 	return copiesAndBlittingTests.release();
7559 }
7560 
7561 } // api
7562 } // vkt
7563