• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015-2020 The Khronos Group Inc.
6  * Copyright (c) 2020 Google Inc.
7  * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Vulkan Copies And Blitting Tests
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vktApiCopiesAndBlittingTests.hpp"
27 
28 #include "deStringUtil.hpp"
29 #include "deUniquePtr.hpp"
30 
31 #include "tcuImageCompare.hpp"
32 #include "tcuAstcUtil.hpp"
33 #include "tcuTexture.hpp"
34 #include "tcuTextureUtil.hpp"
35 #include "tcuVectorType.hpp"
36 #include "tcuVectorUtil.hpp"
37 #include "tcuTestLog.hpp"
38 #include "tcuTexLookupVerifier.hpp"
39 
40 #include "vkImageUtil.hpp"
41 #include "vkMemUtil.hpp"
42 #include "vkPrograms.hpp"
43 #include "vkQueryUtil.hpp"
44 #include "vkRefUtil.hpp"
45 #include "vktTestCase.hpp"
46 #include "vktTestCaseUtil.hpp"
47 #include "vktTestGroupUtil.hpp"
48 #include "vkTypeUtil.hpp"
49 #include "vkCmdUtil.hpp"
50 #include "vkObjUtil.hpp"
51 #include "vkBuilderUtil.hpp"
52 #include "vkBufferWithMemory.hpp"
53 #include "vkBarrierUtil.hpp"
54 
55 #include "pipeline/vktPipelineImageUtil.hpp"		// required for compressed image blit
56 
57 #include <set>
58 #include <array>
59 #include <algorithm>
60 #include <iterator>
61 #include <sstream>
62 
63 namespace vkt
64 {
65 
66 namespace api
67 {
68 
69 namespace
70 {
71 
72 enum FillMode
73 {
74 	FILL_MODE_GRADIENT = 0,
75 	FILL_MODE_WHITE,
76 	FILL_MODE_BLACK,
77 	FILL_MODE_RED,
78 	FILL_MODE_MULTISAMPLE,
79 	FILL_MODE_BLUE_RED_X,
80 	FILL_MODE_BLUE_RED_Y,
81 	FILL_MODE_BLUE_RED_Z,
82 
83 	FILL_MODE_LAST
84 };
85 
86 enum MirrorModeBits
87 {
88 	MIRROR_MODE_X		= (1<<0),
89 	MIRROR_MODE_Y		= (1<<1),
90 	MIRROR_MODE_Z		= (1<<2),
91 	MIRROR_MODE_LAST	= (1<<3),
92 };
93 
94 using MirrorMode = deUint32;
95 
96 enum AllocationKind
97 {
98 	ALLOCATION_KIND_SUBALLOCATED,
99 	ALLOCATION_KIND_DEDICATED,
100 };
101 
102 enum ExtensionUse
103 {
104 	EXTENSION_USE_NONE,
105 	EXTENSION_USE_COPY_COMMANDS2,
106 };
107 
108 template <typename Type>
109 class BinaryCompare
110 {
111 public:
operator ()(const Type & a,const Type & b) const112 	bool operator() (const Type& a, const Type& b) const
113 	{
114 		return deMemCmp(&a, &b, sizeof(Type)) < 0;
115 	}
116 };
117 
118 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> >	FormatSet;
119 
120 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
121 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
122 
123 using namespace vk;
124 
convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)125 VkImageCopy2KHR convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)
126 {
127 	const VkImageCopy2KHR	imageCopy2 =
128 	{
129 		VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR,		// VkStructureType				sType;
130 		DE_NULL,								// const void*					pNext;
131 		imageCopy.srcSubresource,				// VkImageSubresourceLayers		srcSubresource;
132 		imageCopy.srcOffset,					// VkOffset3D					srcOffset;
133 		imageCopy.dstSubresource,				// VkImageSubresourceLayers		dstSubresource;
134 		imageCopy.dstOffset,					// VkOffset3D					dstOffset;
135 		imageCopy.extent						// VkExtent3D					extent;
136 	};
137 	return imageCopy2;
138 }
convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)139 VkBufferCopy2KHR convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)
140 {
141 	const VkBufferCopy2KHR	bufferCopy2 =
142 	{
143 		VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR,	// VkStructureType				sType;
144 		DE_NULL,								// const void*					pNext;
145 		bufferCopy.srcOffset,					// VkDeviceSize					srcOffset;
146 		bufferCopy.dstOffset,					// VkDeviceSize					dstOffset;
147 		bufferCopy.size,						// VkDeviceSize					size;
148 	};
149 	return bufferCopy2;
150 }
151 
convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)152 VkBufferImageCopy2KHR convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)
153 {
154 	const VkBufferImageCopy2KHR	bufferImageCopy2 =
155 	{
156 		VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR,	// VkStructureType				sType;
157 		DE_NULL,									// const void*					pNext;
158 		bufferImageCopy.bufferOffset,				// VkDeviceSize					bufferOffset;
159 		bufferImageCopy.bufferRowLength,			// uint32_t						bufferRowLength;
160 		bufferImageCopy.bufferImageHeight,			// uint32_t						bufferImageHeight;
161 		bufferImageCopy.imageSubresource,			// VkImageSubresourceLayers		imageSubresource;
162 		bufferImageCopy.imageOffset,				// VkOffset3D					imageOffset;
163 		bufferImageCopy.imageExtent					// VkExtent3D					imageExtent;
164 	};
165 	return bufferImageCopy2;
166 }
167 
convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)168 VkImageBlit2KHR convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)
169 {
170 	const VkImageBlit2KHR	imageBlit2 =
171 	{
172 		VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR,			// VkStructureType				sType;
173 		DE_NULL,									// const void*					pNext;
174 		imageBlit.srcSubresource,					// VkImageSubresourceLayers		srcSubresource;
175 		{											// VkOffset3D					srcOffsets[2];
176 			{
177 				imageBlit.srcOffsets[0].x,				// VkOffset3D			srcOffsets[0].x;
178 				imageBlit.srcOffsets[0].y,				// VkOffset3D			srcOffsets[0].y;
179 				imageBlit.srcOffsets[0].z				// VkOffset3D			srcOffsets[0].z;
180 			},
181 			{
182 				imageBlit.srcOffsets[1].x,				// VkOffset3D			srcOffsets[1].x;
183 				imageBlit.srcOffsets[1].y,				// VkOffset3D			srcOffsets[1].y;
184 				imageBlit.srcOffsets[1].z				// VkOffset3D			srcOffsets[1].z;
185 			}
186 		},
187 		imageBlit.dstSubresource,					// VkImageSubresourceLayers		dstSubresource;
188 		{											// VkOffset3D					srcOffsets[2];
189 			{
190 				imageBlit.dstOffsets[0].x,				// VkOffset3D			dstOffsets[0].x;
191 				imageBlit.dstOffsets[0].y,				// VkOffset3D			dstOffsets[0].y;
192 				imageBlit.dstOffsets[0].z				// VkOffset3D			dstOffsets[0].z;
193 			},
194 			{
195 				imageBlit.dstOffsets[1].x,				// VkOffset3D			dstOffsets[1].x;
196 				imageBlit.dstOffsets[1].y,				// VkOffset3D			dstOffsets[1].y;
197 				imageBlit.dstOffsets[1].z				// VkOffset3D			dstOffsets[1].z;
198 			}
199 		}
200 	};
201 	return imageBlit2;
202 }
203 
convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)204 VkImageResolve2KHR convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)
205 {
206 	const VkImageResolve2KHR	imageResolve2 =
207 	{
208 		VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,		// VkStructureType				sType;
209 		DE_NULL,									// const void*					pNext;
210 		imageResolve.srcSubresource,				// VkImageSubresourceLayers		srcSubresource;
211 		imageResolve.srcOffset,						// VkOffset3D					srcOffset;
212 		imageResolve.dstSubresource,				// VkImageSubresourceLayers		dstSubresource;
213 		imageResolve.dstOffset,						// VkOffset3D					dstOffset;
214 		imageResolve.extent							// VkExtent3D					extent;
215 	};
216 	return imageResolve2;
217 }
218 
getAspectFlags(tcu::TextureFormat format)219 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
220 {
221 	VkImageAspectFlags	aspectFlag	= 0;
222 	aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
223 	aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
224 
225 	if (!aspectFlag)
226 		aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
227 
228 	return aspectFlag;
229 }
230 
getAspectFlags(VkFormat format)231 VkImageAspectFlags getAspectFlags (VkFormat format)
232 {
233 	if (isCompressedFormat(format))
234 		return VK_IMAGE_ASPECT_COLOR_BIT;
235 	else
236 		return getAspectFlags(mapVkFormat(format));
237 }
238 
getSizeCompatibleTcuTextureFormat(VkFormat format)239 tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
240 {
241 	if (isCompressedFormat(format))
242 		return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
243 	else
244 		return mapVkFormat(format);
245 }
246 
247 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
248 // except that it supports some formats that are not mappable to VkFormat.
249 // When we are checking combined depth and stencil formats, each aspect is
250 // checked separately, and in some cases we construct PBA with a format that
251 // is not mappable to VkFormat.
isFloatFormat(tcu::TextureFormat format)252 bool isFloatFormat (tcu::TextureFormat format)
253 {
254 	return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
255 }
256 
257 union CopyRegion
258 {
259 	VkBufferCopy			bufferCopy;
260 	VkImageCopy				imageCopy;
261 	VkBufferImageCopy		bufferImageCopy;
262 	VkImageBlit				imageBlit;
263 	VkImageResolve			imageResolve;
264 };
265 
266 struct ImageParms
267 {
268 	VkImageType			imageType;
269 	VkFormat			format;
270 	VkExtent3D			extent;
271 	VkImageTiling		tiling;
272 	VkImageLayout		operationLayout;
273 	VkImageCreateFlags	createFlags;
274 	FillMode			fillMode;
275 };
276 
277 struct TestParams
278 {
279 	union Data
280 	{
281 		struct Buffer
282 		{
283 			VkDeviceSize	size;
284 		} buffer;
285 
286 		ImageParms	image;
287 	} src, dst;
288 
289 	std::vector<CopyRegion>	regions;
290 
291 	union
292 	{
293 		VkFilter				filter;
294 		VkSampleCountFlagBits	samples;
295 	};
296 
297 	AllocationKind	allocationKind;
298 	ExtensionUse	extensionUse;
299 	deUint32		mipLevels;
300 	deBool			singleCommand;
301 	deUint32		barrierCount;
302 	deBool			separateDepthStencilLayouts;
303 	deBool			clearDestination;
304 
TestParamsvkt::api::__anone7bc485d0111::TestParams305 	TestParams (void)
306 	{
307 		allocationKind				= ALLOCATION_KIND_DEDICATED;
308 		extensionUse				= EXTENSION_USE_NONE;
309 		mipLevels					= 1u;
310 		singleCommand				= DE_TRUE;
311 		barrierCount				= 1u;
312 		separateDepthStencilLayouts	= DE_FALSE;
313 		src.image.createFlags		= VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
314 		dst.image.createFlags		= VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
315 		src.image.fillMode			= FILL_MODE_GRADIENT;
316 		dst.image.fillMode			= FILL_MODE_WHITE;
317 		clearDestination			= DE_FALSE;
318 		samples						= VK_SAMPLE_COUNT_1_BIT;
319 	}
320 };
321 
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)322 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&	vki,
323 										const DeviceInterface&		vkd,
324 										const VkPhysicalDevice&		physDevice,
325 										const VkDevice				device,
326 										const VkBuffer&				buffer,
327 										const MemoryRequirement		requirement,
328 										Allocator&					allocator,
329 										AllocationKind				allocationKind)
330 {
331 	switch (allocationKind)
332 	{
333 		case ALLOCATION_KIND_SUBALLOCATED:
334 		{
335 			const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
336 
337 			return allocator.allocate(memoryRequirements, requirement);
338 		}
339 
340 		case ALLOCATION_KIND_DEDICATED:
341 		{
342 			return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
343 		}
344 
345 		default:
346 		{
347 			TCU_THROW(InternalError, "Invalid allocation kind");
348 		}
349 	}
350 }
351 
allocateImage(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkImage & image,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)352 de::MovePtr<Allocation> allocateImage (const InstanceInterface&		vki,
353 									   const DeviceInterface&		vkd,
354 									   const VkPhysicalDevice&		physDevice,
355 									   const VkDevice				device,
356 									   const VkImage&				image,
357 									   const MemoryRequirement		requirement,
358 									   Allocator&					allocator,
359 									   AllocationKind				allocationKind)
360 {
361 	switch (allocationKind)
362 	{
363 		case ALLOCATION_KIND_SUBALLOCATED:
364 		{
365 			const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
366 
367 			return allocator.allocate(memoryRequirements, requirement);
368 		}
369 
370 		case ALLOCATION_KIND_DEDICATED:
371 		{
372 			return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
373 		}
374 
375 		default:
376 		{
377 			TCU_THROW(InternalError, "Invalid allocation kind");
378 		}
379 	}
380 }
381 
382 
getArraySize(const ImageParms & parms)383 inline deUint32 getArraySize(const ImageParms& parms)
384 {
385 	return (parms.imageType != VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u;
386 }
387 
getCreateFlags(const ImageParms & parms)388 inline VkImageCreateFlags  getCreateFlags(const ImageParms& parms)
389 {
390 	if (parms.createFlags == VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM)
391 		return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
392 	else
393 		return parms.createFlags;
394 }
395 
getExtent3D(const ImageParms & parms,deUint32 mipLevel=0u)396 inline VkExtent3D getExtent3D(const ImageParms& parms, deUint32 mipLevel = 0u)
397 {
398 	const bool			isCompressed	= isCompressedFormat(parms.format);
399 	const deUint32		blockWidth		= (isCompressed) ? getBlockWidth(parms.format) : 1u;
400 	const deUint32		blockHeight		= (isCompressed) ? getBlockHeight(parms.format) : 1u;
401 
402 	if (isCompressed && mipLevel != 0u)
403 		DE_FATAL("Not implemented");
404 
405 	const VkExtent3D	extent			=
406 	{
407 		(parms.extent.width >> mipLevel) * blockWidth,
408 		(parms.imageType != VK_IMAGE_TYPE_1D) ? ((parms.extent.height >> mipLevel) * blockHeight) : 1u,
409 		(parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
410 	};
411 	return extent;
412 }
413 
mapCombinedToDepthTransferFormat(const tcu::TextureFormat & combinedFormat)414 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
415 {
416 	tcu::TextureFormat format;
417 	switch (combinedFormat.type)
418 	{
419 		case tcu::TextureFormat::UNORM_INT16:
420 		case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
421 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
422 			break;
423 		case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
424 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
425 			break;
426 		case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
427 		case tcu::TextureFormat::FLOAT:
428 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
429 			break;
430 		default:
431 			DE_ASSERT(false);
432 			break;
433 	}
434 	return format;
435 }
436 
437 class CopiesAndBlittingTestInstance : public vkt::TestInstance
438 {
439 public:
440 										CopiesAndBlittingTestInstance		(Context&	context,
441 																			 TestParams	testParams);
442 	virtual tcu::TestStatus				iterate								(void) = 0;
443 
444 protected:
445 	const TestParams					m_params;
446 
447 	Move<VkCommandPool>					m_cmdPool;
448 	Move<VkCommandBuffer>				m_cmdBuffer;
449 	Move<VkFence>						m_fence;
450 	de::MovePtr<tcu::TextureLevel>		m_sourceTextureLevel;
451 	de::MovePtr<tcu::TextureLevel>		m_destinationTextureLevel;
452 	de::MovePtr<tcu::TextureLevel>		m_expectedTextureLevel[16];
453 
454 	VkCommandBufferBeginInfo			m_cmdBufferBeginInfo;
455 
456 	void								generateBuffer						(tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
457 	virtual void						generateExpectedResult				(void);
458 	void								uploadBuffer						(tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
459 	void								uploadImage							(const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u);
460 	virtual tcu::TestStatus				checkTestResult						(tcu::ConstPixelBufferAccess result);
461 	virtual void						copyRegionToTextureLevel			(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u) = 0;
calculateSize(tcu::ConstPixelBufferAccess src) const462 	deUint32							calculateSize						(tcu::ConstPixelBufferAccess src) const
463 										{
464 											return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
465 										}
466 
467 	de::MovePtr<tcu::TextureLevel>		readImage							(vk::VkImage				image,
468 																			 const ImageParms&			imageParms,
469 																			 const deUint32				mipLevel = 0u);
470 
471 private:
472 	void								uploadImageAspect					(const tcu::ConstPixelBufferAccess&	src,
473 																			 const VkImage&						dst,
474 																			 const ImageParms&					parms,
475 																			 const deUint32						mipLevels = 1u);
476 	void								readImageAspect						(vk::VkImage						src,
477 																			 const tcu::PixelBufferAccess&		dst,
478 																			 const ImageParms&					parms,
479 																			 const deUint32						mipLevel = 0u);
480 };
481 
CopiesAndBlittingTestInstance(Context & context,TestParams testParams)482 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
483 	: vkt::TestInstance	(context)
484 	, m_params			(testParams)
485 {
486 	const DeviceInterface&		vk					= context.getDeviceInterface();
487 	const VkDevice				vkDevice			= context.getDevice();
488 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
489 
490 	// Create command pool
491 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
492 
493 	// Create command buffer
494 	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
495 
496 	// Create fence
497 	m_fence = createFence(vk, vkDevice);
498 }
499 
generateBuffer(tcu::PixelBufferAccess buffer,int width,int height,int depth,FillMode mode)500 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
501 {
502 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(buffer.getFormat().type);
503 	tcu::Vec4						maxValue		(1.0f);
504 
505 	if (buffer.getFormat().order == tcu::TextureFormat::S)
506 	{
507 		// Stencil-only is stored in the first component. Stencil is always 8 bits.
508 		maxValue.x() = 1 << 8;
509 	}
510 	else if (buffer.getFormat().order == tcu::TextureFormat::DS)
511 	{
512 		// In a combined format, fillWithComponentGradients expects stencil in the fourth component.
513 		maxValue.w() = 1 << 8;
514 	}
515 	else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
516 	{
517 		// The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
518 		const tcu::IVec4	bits	= tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
519 		const int			signBit	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
520 
521 		for (int i = 0; i < 4; ++i)
522 		{
523 			if (bits[i] != 0)
524 				maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1);
525 		}
526 	}
527 
528 	if (mode == FILL_MODE_GRADIENT)
529 	{
530 		tcu::fillWithComponentGradients2(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
531 		return;
532 	}
533 
534 	const tcu::Vec4		redColor	(maxValue.x(),	0.0,			0.0,			maxValue.w());
535 	const tcu::Vec4		greenColor	(0.0,			maxValue.y(),	0.0,			maxValue.w());
536 	const tcu::Vec4		blueColor	(0.0,			0.0,			maxValue.z(),	maxValue.w());
537 	const tcu::Vec4		whiteColor	(maxValue.x(),	maxValue.y(),	maxValue.z(),	maxValue.w());
538 	const tcu::Vec4		blackColor	(0.0f,			0.0f,			0.0f,			0.0f);
539 
540 	for (int z = 0; z < depth;  ++z)
541 	for (int y = 0; y < height; ++y)
542 	for (int x = 0; x < width;  ++x)
543 	{
544 		switch (mode)
545 		{
546 			case FILL_MODE_WHITE:
547 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
548 				{
549 					buffer.setPixDepth(1.0f, x, y, z);
550 					if (tcu::hasStencilComponent(buffer.getFormat().order))
551 						buffer.setPixStencil(255, x, y, z);
552 				}
553 				else
554 					buffer.setPixel(whiteColor, x, y, z);
555 				break;
556 
557 			case FILL_MODE_BLACK:
558 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
559 				{
560 					buffer.setPixDepth(0.0f, x, y, z);
561 					if (tcu::hasStencilComponent(buffer.getFormat().order))
562 						buffer.setPixStencil(0, x, y, z);
563 				}
564 				else
565 					buffer.setPixel(blackColor, x, y, z);
566 				break;
567 
568 			case FILL_MODE_RED:
569 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
570 				{
571 					buffer.setPixDepth(redColor[0], x, y, z);
572 					if (tcu::hasStencilComponent(buffer.getFormat().order))
573 						buffer.setPixStencil((int)redColor[3], x, y, z);
574 				}
575 				else
576 					buffer.setPixel(redColor, x, y, z);
577 				break;
578 
579 			case FILL_MODE_BLUE_RED_X:
580 			case FILL_MODE_BLUE_RED_Y:
581 			case FILL_MODE_BLUE_RED_Z:
582 				bool useBlue;
583 				switch (mode)
584 				{
585 					case FILL_MODE_BLUE_RED_X: useBlue = (x & 1); break;
586 					case FILL_MODE_BLUE_RED_Y: useBlue = (y & 1); break;
587 					case FILL_MODE_BLUE_RED_Z: useBlue = (z & 1); break;
588 					default: DE_ASSERT(false); break;
589 				}
590 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
591 				{
592 					buffer.setPixDepth((useBlue ? blueColor[0] : redColor[0]), x, y, z);
593 					if (tcu::hasStencilComponent(buffer.getFormat().order))
594 						buffer.setPixStencil((useBlue ? (int) blueColor[3] : (int)redColor[3]), x, y, z);
595 				}
596 				else
597 					buffer.setPixel((useBlue ? blueColor : redColor), x, y, z);
598 				break;
599 
600 			case FILL_MODE_MULTISAMPLE:
601 			{
602 				float xScaled = static_cast<float>(x) / static_cast<float>(width);
603 				float yScaled = static_cast<float>(y) / static_cast<float>(height);
604 				buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
605 				break;
606 			}
607 
608 			default:
609 				break;
610 		}
611 	}
612 }
613 
uploadBuffer(tcu::ConstPixelBufferAccess bufferAccess,const Allocation & bufferAlloc)614 void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
615 {
616 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
617 	const VkDevice				vkDevice	= m_context.getDevice();
618 	const deUint32				bufferSize	= calculateSize(bufferAccess);
619 
620 	// Write buffer data
621 	deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
622 	flushAlloc(vk, vkDevice, bufferAlloc);
623 }
624 
uploadImageAspect(const tcu::ConstPixelBufferAccess & imageAccess,const VkImage & image,const ImageParms & parms,const deUint32 mipLevels)625 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels)
626 {
627 	const InstanceInterface&		vki					= m_context.getInstanceInterface();
628 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
629 	const VkPhysicalDevice			vkPhysDevice		= m_context.getPhysicalDevice();
630 	const VkDevice					vkDevice			= m_context.getDevice();
631 	const VkQueue					queue				= m_context.getUniversalQueue();
632 	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
633 	Allocator&						memAlloc			= m_context.getDefaultAllocator();
634 	Move<VkBuffer>					buffer;
635 	const deUint32					bufferSize			= calculateSize(imageAccess);
636 	de::MovePtr<Allocation>			bufferAlloc;
637 	const deUint32					arraySize			= getArraySize(parms);
638 	const VkExtent3D				imageExtent			= getExtent3D(parms);
639 	std::vector <VkBufferImageCopy>	copyRegions;
640 
641 	// Create source buffer
642 	{
643 		const VkBufferCreateInfo	bufferParams		=
644 		{
645 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
646 			DE_NULL,									// const void*			pNext;
647 			0u,											// VkBufferCreateFlags	flags;
648 			bufferSize,									// VkDeviceSize			size;
649 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
650 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
651 			1u,											// deUint32				queueFamilyIndexCount;
652 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
653 		};
654 
655 		buffer		= createBuffer(vk, vkDevice, &bufferParams);
656 		bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
657 		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
658 	}
659 
660 	// Barriers for copying buffer to image
661 	const VkBufferMemoryBarrier		preBufferBarrier	=
662 	{
663 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
664 		DE_NULL,										// const void*		pNext;
665 		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
666 		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
667 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
668 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
669 		*buffer,										// VkBuffer			buffer;
670 		0u,												// VkDeviceSize		offset;
671 		bufferSize										// VkDeviceSize		size;
672 	};
673 
674 	const VkImageAspectFlags		formatAspect		= (m_params.separateDepthStencilLayouts) ? getAspectFlags(imageAccess.getFormat()) : getAspectFlags(parms.format);
675 	const bool						skipPreImageBarrier	= (m_params.separateDepthStencilLayouts) ? false : ((formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
676 														  getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT));
677 
678 	const VkImageMemoryBarrier		preImageBarrier		=
679 	{
680 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
681 		DE_NULL,										// const void*				pNext;
682 		0u,												// VkAccessFlags			srcAccessMask;
683 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
684 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
685 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
686 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
687 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
688 		image,											// VkImage					image;
689 		{												// VkImageSubresourceRange	subresourceRange;
690 			formatAspect,	// VkImageAspectFlags	aspect;
691 			0u,				// deUint32				baseMipLevel;
692 			mipLevels,		// deUint32				mipLevels;
693 			0u,				// deUint32				baseArraySlice;
694 			arraySize,		// deUint32				arraySize;
695 		}
696 	};
697 
698 	const VkImageMemoryBarrier		postImageBarrier	=
699 	{
700 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
701 		DE_NULL,										// const void*				pNext;
702 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
703 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
704 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
705 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
706 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
707 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
708 		image,											// VkImage					image;
709 		{												// VkImageSubresourceRange	subresourceRange;
710 			formatAspect,				// VkImageAspectFlags	aspect;
711 			0u,							// deUint32				baseMipLevel;
712 			mipLevels,					// deUint32				mipLevels;
713 			0u,							// deUint32				baseArraySlice;
714 			arraySize,					// deUint32				arraySize;
715 		}
716 	};
717 
718 	for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
719 	{
720 		const VkExtent3D		copyExtent	=
721 		{
722 			imageExtent.width	>> mipLevelNdx,
723 			imageExtent.height	>> mipLevelNdx,
724 			imageExtent.depth
725 		};
726 
727 		const bool		isCompressed	= isCompressedFormat(parms.format);
728 		const deUint32	blockWidth		= (isCompressed) ? getBlockWidth(parms.format) : 1u;
729 		const deUint32	blockHeight		= (isCompressed) ? getBlockHeight(parms.format) : 1u;
730 		deUint32 rowLength		= ((copyExtent.width + blockWidth-1) / blockWidth) * blockWidth;
731 		deUint32 imageHeight	= ((copyExtent.height + blockHeight-1) / blockHeight) * blockHeight;
732 
733 		const VkBufferImageCopy	copyRegion	=
734 		{
735 			0u,												// VkDeviceSize				bufferOffset;
736 			rowLength,										// deUint32					bufferRowLength;
737 			imageHeight,									// deUint32					bufferImageHeight;
738 			{
739 				getAspectFlags(imageAccess.getFormat()),		// VkImageAspectFlags	aspect;
740 				mipLevelNdx,									// deUint32				mipLevel;
741 				0u,												// deUint32				baseArrayLayer;
742 				arraySize,										// deUint32				layerCount;
743 			},												// VkImageSubresourceLayers	imageSubresource;
744 			{ 0, 0, 0 },									// VkOffset3D				imageOffset;
745 			copyExtent										// VkExtent3D				imageExtent;
746 		};
747 
748 		copyRegions.push_back(copyRegion);
749 	}
750 
751 	// Write buffer data
752 	deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
753 	flushAlloc(vk, vkDevice, *bufferAlloc);
754 
755 	// Copy buffer to image
756 	beginCommandBuffer(vk, *m_cmdBuffer);
757 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
758 						  1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
759 	vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), &copyRegions[0]);
760 	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);
761 	endCommandBuffer(vk, *m_cmdBuffer);
762 
763 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
764 }
765 
uploadImage(const tcu::ConstPixelBufferAccess & src,VkImage dst,const ImageParms & parms,const deUint32 mipLevels)766 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels)
767 {
768 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
769 	{
770 		if (tcu::hasDepthComponent(src.getFormat().order))
771 		{
772 			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
773 			tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
774 			uploadImageAspect(depthTexture.getAccess(), dst, parms, mipLevels);
775 		}
776 
777 		if (tcu::hasStencilComponent(src.getFormat().order))
778 		{
779 			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
780 			tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
781 			uploadImageAspect(stencilTexture.getAccess(), dst, parms, mipLevels);
782 		}
783 	}
784 	else
785 		uploadImageAspect(src, dst, parms, mipLevels);
786 }
787 
checkTestResult(tcu::ConstPixelBufferAccess result)788 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
789 {
790 	const tcu::ConstPixelBufferAccess	expected	= m_expectedTextureLevel[0]->getAccess();
791 
792 	if (isFloatFormat(result.getFormat()))
793 	{
794 		const tcu::Vec4	threshold (0.0f);
795 		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
796 			return tcu::TestStatus::fail("CopiesAndBlitting test");
797 	}
798 	else
799 	{
800 		const tcu::UVec4 threshold (0u);
801 		if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
802 		{
803 			if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, 0.1f, tcu::COMPARE_LOG_RESULT))
804 				return tcu::TestStatus::fail("CopiesAndBlitting test");
805 		}
806 		else
807 		{
808 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
809 				return tcu::TestStatus::fail("CopiesAndBlitting test");
810 		}
811 	}
812 
813 	return tcu::TestStatus::pass("CopiesAndBlitting test");
814 }
815 
generateExpectedResult(void)816 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
817 {
818 	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
819 	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
820 
821 	m_expectedTextureLevel[0]	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
822 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
823 
824 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
825 		copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
826 }
827 
828 class CopiesAndBlittingTestCase : public vkt::TestCase
829 {
830 public:
CopiesAndBlittingTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description)831 							CopiesAndBlittingTestCase	(tcu::TestContext&			testCtx,
832 														 const std::string&			name,
833 														 const std::string&			description)
834 								: vkt::TestCase	(testCtx, name, description)
835 							{}
836 
837 	virtual TestInstance*	createInstance				(Context&					context) const = 0;
838 };
839 
readImageAspect(vk::VkImage image,const tcu::PixelBufferAccess & dst,const ImageParms & imageParms,const deUint32 mipLevel)840 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage					image,
841 													 const tcu::PixelBufferAccess&	dst,
842 													 const ImageParms&				imageParms,
843 													 const deUint32					mipLevel)
844 {
845 	const InstanceInterface&	vki					= m_context.getInstanceInterface();
846 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
847 	const VkPhysicalDevice		physDevice			= m_context.getPhysicalDevice();
848 	const VkDevice				device				= m_context.getDevice();
849 	const VkQueue				queue				= m_context.getUniversalQueue();
850 	Allocator&					allocator			= m_context.getDefaultAllocator();
851 
852 	Move<VkBuffer>				buffer;
853 	de::MovePtr<Allocation>		bufferAlloc;
854 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
855 	const VkDeviceSize			pixelDataSize		= calculateSize(dst);
856 	const VkExtent3D			imageExtent			= getExtent3D(imageParms, mipLevel);
857 
858 	// Create destination buffer
859 	{
860 		const VkBufferCreateInfo			bufferParams			=
861 		{
862 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
863 			DE_NULL,									// const void*			pNext;
864 			0u,											// VkBufferCreateFlags	flags;
865 			pixelDataSize,								// VkDeviceSize			size;
866 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
867 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
868 			1u,											// deUint32				queueFamilyIndexCount;
869 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
870 		};
871 
872 		buffer		= createBuffer(vk, device, &bufferParams);
873 		bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
874 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
875 
876 		deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
877 		flushAlloc(vk, device, *bufferAlloc);
878 	}
879 
880 	// Barriers for copying image to buffer
881 	const VkImageAspectFlags				formatAspect			= getAspectFlags(imageParms.format);
882 	const VkImageMemoryBarrier				imageBarrier			=
883 	{
884 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
885 		DE_NULL,									// const void*				pNext;
886 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
887 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
888 		imageParms.operationLayout,					// VkImageLayout			oldLayout;
889 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
890 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
891 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
892 		image,										// VkImage					image;
893 		{											// VkImageSubresourceRange	subresourceRange;
894 			formatAspect,			// VkImageAspectFlags	aspectMask;
895 			mipLevel,				// deUint32				baseMipLevel;
896 			1u,						// deUint32				mipLevels;
897 			0u,						// deUint32				baseArraySlice;
898 			getArraySize(imageParms)// deUint32				arraySize;
899 		}
900 	};
901 
902 	const VkBufferMemoryBarrier				bufferBarrier			=
903 	{
904 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
905 		DE_NULL,									// const void*		pNext;
906 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
907 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
908 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
909 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
910 		*buffer,									// VkBuffer			buffer;
911 		0u,											// VkDeviceSize		offset;
912 		pixelDataSize								// VkDeviceSize		size;
913 	};
914 
915 	const VkImageMemoryBarrier				postImageBarrier		=
916 	{
917 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
918 		DE_NULL,									// const void*				pNext;
919 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
920 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
921 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			oldLayout;
922 		imageParms.operationLayout,					// VkImageLayout			newLayout;
923 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
924 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
925 		image,										// VkImage					image;
926 		{
927 			formatAspect,								// VkImageAspectFlags	aspectMask;
928 			mipLevel,									// deUint32				baseMipLevel;
929 			1u,											// deUint32				mipLevels;
930 			0u,											// deUint32				baseArraySlice;
931 			getArraySize(imageParms)					// deUint32				arraySize;
932 		}											// VkImageSubresourceRange	subresourceRange;
933 	};
934 
935 	// Copy image to buffer
936 	const bool		isCompressed	= isCompressedFormat(imageParms.format);
937 	const deUint32	blockWidth		= (isCompressed) ? getBlockWidth(imageParms.format) : 1u;
938 	const deUint32	blockHeight		= (isCompressed) ? getBlockHeight(imageParms.format) : 1u;
939 	deUint32 rowLength		= ((imageExtent.width + blockWidth-1) / blockWidth) * blockWidth;
940 	deUint32 imageHeight	= ((imageExtent.height + blockHeight-1) / blockHeight) * blockHeight;
941 
942 	// Copy image to buffer - note that there are cases where m_params.dst.image.format is not the same as dst.getFormat()
943 	const VkImageAspectFlags	aspect			= isCompressedFormat(m_params.dst.image.format) ?
944 													static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) : getAspectFlags(dst.getFormat());
945 	const VkBufferImageCopy		copyRegion		=
946 	{
947 		0u,								// VkDeviceSize				bufferOffset;
948 		rowLength,						// deUint32					bufferRowLength;
949 		imageHeight,					// deUint32					bufferImageHeight;
950 		{
951 			aspect,							// VkImageAspectFlags		aspect;
952 			mipLevel,						// deUint32					mipLevel;
953 			0u,								// deUint32					baseArrayLayer;
954 			getArraySize(imageParms),		// deUint32					layerCount;
955 		},								// VkImageSubresourceLayers	imageSubresource;
956 		{ 0, 0, 0 },					// VkOffset3D				imageOffset;
957 		imageExtent						// VkExtent3D				imageExtent;
958 	};
959 
960 	beginCommandBuffer(vk, *m_cmdBuffer);
961 	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);
962 	vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
963 	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);
964 	endCommandBuffer(vk, *m_cmdBuffer);
965 
966 	submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
967 
968 	// Read buffer data
969 	invalidateAlloc(vk, device, *bufferAlloc);
970 	tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
971 }
972 
readImage(vk::VkImage image,const ImageParms & parms,const deUint32 mipLevel)973 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage	(vk::VkImage		image,
974 																		 const ImageParms&	parms,
975 																		 const deUint32		mipLevel)
976 {
977 	const tcu::TextureFormat		imageFormat	= getSizeCompatibleTcuTextureFormat(parms.format);
978 	de::MovePtr<tcu::TextureLevel>	resultLevel	(new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
979 
980 	if (tcu::isCombinedDepthStencilType(imageFormat.type))
981 	{
982 		if (tcu::hasDepthComponent(imageFormat.order))
983 		{
984 			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
985 			readImageAspect(image, depthTexture.getAccess(), parms, mipLevel);
986 			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
987 		}
988 
989 		if (tcu::hasStencilComponent(imageFormat.order))
990 		{
991 			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
992 			readImageAspect(image, stencilTexture.getAccess(), parms, mipLevel);
993 			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
994 		}
995 	}
996 	else
997 		readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
998 
999 	return resultLevel;
1000 }
1001 
1002 // Copy from image to image.
1003 
1004 class CopyImageToImage : public CopiesAndBlittingTestInstance
1005 {
1006 public:
1007 										CopyImageToImage			(Context&	context,
1008 																	 TestParams params);
1009 	virtual tcu::TestStatus				iterate						(void);
1010 
1011 protected:
1012 	virtual tcu::TestStatus				checkTestResult				(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
1013 
1014 private:
1015 	Move<VkImage>						m_source;
1016 	de::MovePtr<Allocation>				m_sourceImageAlloc;
1017 	Move<VkImage>						m_destination;
1018 	de::MovePtr<Allocation>				m_destinationImageAlloc;
1019 
1020 	virtual void						copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1021 };
1022 
CopyImageToImage(Context & context,TestParams params)1023 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
1024 	: CopiesAndBlittingTestInstance(context, params)
1025 {
1026 	const InstanceInterface&	vki					= context.getInstanceInterface();
1027 	const DeviceInterface&		vk					= context.getDeviceInterface();
1028 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
1029 	const VkDevice				vkDevice			= context.getDevice();
1030 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
1031 	Allocator&					memAlloc			= context.getDefaultAllocator();
1032 
1033 	// Create source image
1034 	{
1035 		const VkImageCreateInfo	sourceImageParams		=
1036 		{
1037 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1038 			DE_NULL,								// const void*			pNext;
1039 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
1040 			m_params.src.image.imageType,			// VkImageType			imageType;
1041 			m_params.src.image.format,				// VkFormat				format;
1042 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
1043 			1u,										// deUint32				mipLevels;
1044 			getArraySize(m_params.src.image),		// deUint32				arraySize;
1045 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1046 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1047 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1048 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1049 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1050 			1u,										// deUint32				queueFamilyCount;
1051 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1052 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1053 		};
1054 
1055 		m_source				= createImage(vk, vkDevice, &sourceImageParams);
1056 		m_sourceImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1057 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1058 	}
1059 
1060 	// Create destination image
1061 	{
1062 		const VkImageCreateInfo	destinationImageParams	=
1063 		{
1064 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1065 			DE_NULL,								// const void*			pNext;
1066 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
1067 			m_params.dst.image.imageType,			// VkImageType			imageType;
1068 			m_params.dst.image.format,				// VkFormat				format;
1069 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
1070 			1u,										// deUint32				mipLevels;
1071 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
1072 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1073 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1074 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1075 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1076 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1077 			1u,										// deUint32				queueFamilyCount;
1078 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1079 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1080 		};
1081 
1082 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
1083 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1084 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1085 	}
1086 }
1087 
iterate(void)1088 tcu::TestStatus CopyImageToImage::iterate (void)
1089 {
1090 	const bool					srcCompressed		= isCompressedFormat(m_params.src.image.format);
1091 	const bool					dstCompressed		= isCompressedFormat(m_params.dst.image.format);
1092 
1093 	const tcu::TextureFormat	srcTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1094 	const tcu::TextureFormat	dstTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1095 
1096 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1097 																				(int)m_params.src.image.extent.width,
1098 																				(int)m_params.src.image.extent.height,
1099 																				(int)m_params.src.image.extent.depth));
1100 	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);
1101 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1102 																				(int)m_params.dst.image.extent.width,
1103 																				(int)m_params.dst.image.extent.height,
1104 																				(int)m_params.dst.image.extent.depth));
1105 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.clearDestination ? FILL_MODE_WHITE : FILL_MODE_GRADIENT);
1106 	generateExpectedResult();
1107 
1108 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1109 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1110 
1111 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
1112 	const VkDevice				vkDevice			= m_context.getDevice();
1113 	const VkQueue				queue				= m_context.getUniversalQueue();
1114 
1115 	std::vector<VkImageCopy>		imageCopies;
1116 	std::vector<VkImageCopy2KHR>	imageCopies2KHR;
1117 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1118 	{
1119 		VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1120 
1121 		// When copying between compressed and uncompressed formats the extent
1122 		// members represent the texel dimensions of the source image.
1123 		if (srcCompressed)
1124 		{
1125 			const deUint32	blockWidth	= getBlockWidth(m_params.src.image.format);
1126 			const deUint32	blockHeight	= getBlockHeight(m_params.src.image.format);
1127 
1128 			imageCopy.srcOffset.x *= blockWidth;
1129 			imageCopy.srcOffset.y *= blockHeight;
1130 			imageCopy.extent.width *= blockWidth;
1131 			imageCopy.extent.height *= blockHeight;
1132 		}
1133 
1134 		if (dstCompressed)
1135 		{
1136 			const deUint32	blockWidth	= getBlockWidth(m_params.dst.image.format);
1137 			const deUint32	blockHeight	= getBlockHeight(m_params.dst.image.format);
1138 
1139 			imageCopy.dstOffset.x *= blockWidth;
1140 			imageCopy.dstOffset.y *= blockHeight;
1141 		}
1142 
1143 		if (m_params.extensionUse == EXTENSION_USE_NONE)
1144 		{
1145 			imageCopies.push_back(imageCopy);
1146 		}
1147 		else
1148 		{
1149 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1150 			imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1151 		}
1152 	}
1153 
1154 	const VkImageMemoryBarrier	imageBarriers[]		=
1155 	{
1156 		// source image
1157 		{
1158 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1159 			DE_NULL,									// const void*				pNext;
1160 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1161 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
1162 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1163 			m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
1164 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1165 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1166 			m_source.get(),								// VkImage					image;
1167 			{											// VkImageSubresourceRange	subresourceRange;
1168 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
1169 				0u,								// deUint32				baseMipLevel;
1170 				1u,								// deUint32				mipLevels;
1171 				0u,								// deUint32				baseArraySlice;
1172 				getArraySize(m_params.src.image)// deUint32				arraySize;
1173 			}
1174 		},
1175 		// destination image
1176 		{
1177 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1178 			DE_NULL,									// const void*				pNext;
1179 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1180 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
1181 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1182 			m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
1183 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1184 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1185 			m_destination.get(),						// VkImage					image;
1186 			{											// VkImageSubresourceRange	subresourceRange;
1187 				getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
1188 				0u,								// deUint32				baseMipLevel;
1189 				1u,								// deUint32				mipLevels;
1190 				0u,								// deUint32				baseArraySlice;
1191 				getArraySize(m_params.dst.image)// deUint32				arraySize;
1192 			}
1193 		},
1194 	};
1195 
1196 	beginCommandBuffer(vk, *m_cmdBuffer);
1197 	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);
1198 
1199 	if (m_params.clearDestination)
1200 	{
1201 		VkImageSubresourceRange	range		= { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
1202 		VkClearColorValue		clearColor;
1203 
1204 		clearColor.float32[0] = 1.0f;
1205 		clearColor.float32[1] = 1.0f;
1206 		clearColor.float32[2] = 1.0f;
1207 		clearColor.float32[3] = 1.0f;
1208 		vk.cmdClearColorImage(*m_cmdBuffer, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u, &range);
1209 		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);
1210 	}
1211 
1212 	if (m_params.extensionUse == EXTENSION_USE_NONE)
1213 	{
1214 		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());
1215 	}
1216 	else
1217 	{
1218 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1219 		const VkCopyImageInfo2KHR copyImageInfo2KHR =
1220 		{
1221 			VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
1222 			DE_NULL,									// const void*				pNext;
1223 			m_source.get(),								// VkImage					srcImage;
1224 			m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
1225 			m_destination.get(),						// VkImage					dstImage;
1226 			m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
1227 			(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
1228 			imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
1229 		};
1230 
1231 		vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
1232 	}
1233 
1234 	endCommandBuffer(vk, *m_cmdBuffer);
1235 
1236 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1237 
1238 	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);
1239 
1240 	return checkTestResult(resultTextureLevel->getAccess());
1241 }
1242 
checkTestResult(tcu::ConstPixelBufferAccess result)1243 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
1244 {
1245 	const tcu::Vec4	fThreshold (0.0f);
1246 	const tcu::UVec4 uThreshold (0u);
1247 
1248 	if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1249 	{
1250 		if (tcu::hasDepthComponent(result.getFormat().order))
1251 		{
1252 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
1253 			const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
1254 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1255 
1256 			if (isFloatFormat(result.getFormat()))
1257 			{
1258 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1259 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1260 			}
1261 			else
1262 			{
1263 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1264 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1265 			}
1266 		}
1267 
1268 		if (tcu::hasStencilComponent(result.getFormat().order))
1269 		{
1270 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
1271 			const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
1272 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1273 
1274 			if (isFloatFormat(result.getFormat()))
1275 			{
1276 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1277 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1278 			}
1279 			else
1280 			{
1281 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1282 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1283 			}
1284 		}
1285 	}
1286 	else
1287 	{
1288 		if (isFloatFormat(result.getFormat()))
1289 		{
1290 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1291 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1292 		}
1293 		else
1294 		{
1295 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1296 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1297 		}
1298 	}
1299 
1300 	return tcu::TestStatus::pass("CopiesAndBlitting test");
1301 }
1302 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1303 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1304 {
1305 	DE_UNREF(mipLevel);
1306 
1307 	VkOffset3D	srcOffset	= region.imageCopy.srcOffset;
1308 	VkOffset3D	dstOffset	= region.imageCopy.dstOffset;
1309 	VkExtent3D	extent		= region.imageCopy.extent;
1310 
1311 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1312 	{
1313 		dstOffset.z = srcOffset.z;
1314 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1315 	}
1316 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1317 	{
1318 		srcOffset.z = dstOffset.z;
1319 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1320 	}
1321 
1322 
1323 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1324 	{
1325 		DE_ASSERT(src.getFormat() == dst.getFormat());
1326 
1327 		// Copy depth.
1328 		if (tcu::hasDepthComponent(src.getFormat().order))
1329 		{
1330 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1331 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1332 			tcu::copy(dstSubRegion, srcSubRegion);
1333 		}
1334 
1335 		// Copy stencil.
1336 		if (tcu::hasStencilComponent(src.getFormat().order))
1337 		{
1338 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1339 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1340 			tcu::copy(dstSubRegion, srcSubRegion);
1341 		}
1342 	}
1343 	else
1344 	{
1345 		const tcu::ConstPixelBufferAccess	srcSubRegion		= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1346 		// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1347 		const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1348 		const tcu::PixelBufferAccess		dstSubRegion		= tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1349 
1350 		tcu::copy(dstSubRegion, srcSubRegion);
1351 	}
1352 }
1353 
1354 class CopyImageToImageTestCase : public vkt::TestCase
1355 {
1356 public:
CopyImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1357 							CopyImageToImageTestCase	(tcu::TestContext&				testCtx,
1358 														 const std::string&				name,
1359 														 const std::string&				description,
1360 														 const TestParams				params)
1361 								: vkt::TestCase	(testCtx, name, description)
1362 								, m_params		(params)
1363 	{}
1364 
createInstance(Context & context) const1365 	virtual TestInstance*	createInstance				(Context&						context) const
1366 	{
1367 		return new CopyImageToImage(context, m_params);
1368 	}
1369 
checkSupport(Context & context) const1370 	virtual void			checkSupport				(Context&						context) const
1371 	{
1372 		if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1373 		{
1374 			if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1375 				TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1376 		}
1377 
1378 		if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1379 		{
1380 			if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1381 				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1382 		}
1383 
1384 		if (m_params.separateDepthStencilLayouts)
1385 			if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1386 				TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1387 
1388 		if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1389 			(m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1390 		{
1391 			if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1392 				TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1393 		}
1394 
1395 		const VkPhysicalDeviceLimits	limits		= context.getDeviceProperties().limits;
1396 		VkImageFormatProperties			properties;
1397 
1398 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1399 																					m_params.src.image.format,
1400 																					m_params.src.image.imageType,
1401 																					VK_IMAGE_TILING_OPTIMAL,
1402 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1403 																					0,
1404 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1405 			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1406 																					m_params.dst.image.format,
1407 																					m_params.dst.image.imageType,
1408 																					VK_IMAGE_TILING_OPTIMAL,
1409 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1410 																					0,
1411 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1412 		{
1413 			TCU_THROW(NotSupportedError, "Format not supported");
1414 		}
1415 
1416 		// Check maxImageDimension1D
1417 		{
1418 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1419 				TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1420 
1421 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1422 				TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1423 		}
1424 
1425 		// Check maxImageDimension2D
1426 		{
1427 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1428 				|| m_params.src.image.extent.height > limits.maxImageDimension2D))
1429 			{
1430 				TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1431 			}
1432 
1433 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1434 				|| m_params.dst.image.extent.height > limits.maxImageDimension2D))
1435 			{
1436 				TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1437 			}
1438 		}
1439 
1440 		// Check maxImageDimension3D
1441 		{
1442 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1443 				|| m_params.src.image.extent.height > limits.maxImageDimension3D
1444 				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
1445 			{
1446 				TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1447 			}
1448 
1449 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1450 				|| m_params.dst.image.extent.height > limits.maxImageDimension3D
1451 				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
1452 			{
1453 				TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1454 			}
1455 		}
1456 	}
1457 
1458 private:
1459 	TestParams				m_params;
1460 };
1461 
1462 class CopyImageToImageMipmap : public CopiesAndBlittingTestInstance
1463 {
1464 public:
1465 										CopyImageToImageMipmap		(Context&	context,
1466 																	 TestParams params);
1467 	virtual tcu::TestStatus				iterate						(void);
1468 
1469 protected:
1470 	tcu::TestStatus						checkResult					(tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected);
1471 
1472 private:
1473 	Move<VkImage>						m_source;
1474 	de::MovePtr<Allocation>				m_sourceImageAlloc;
1475 	Move<VkImage>						m_destination;
1476 	de::MovePtr<Allocation>				m_destinationImageAlloc;
1477 
1478 	virtual void						copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1479 
1480 };
1481 
CopyImageToImageMipmap(Context & context,TestParams params)1482 CopyImageToImageMipmap::CopyImageToImageMipmap (Context& context, TestParams params)
1483 	: CopiesAndBlittingTestInstance(context, params)
1484 {
1485 	const InstanceInterface&	vki					= context.getInstanceInterface();
1486 	const DeviceInterface&		vk					= context.getDeviceInterface();
1487 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
1488 	const VkDevice				vkDevice			= context.getDevice();
1489 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
1490 	Allocator&					memAlloc			= context.getDefaultAllocator();
1491 
1492 	// Create source image
1493 	{
1494 		const VkImageCreateInfo	sourceImageParams		=
1495 		{
1496 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1497 			DE_NULL,								// const void*			pNext;
1498 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
1499 			m_params.src.image.imageType,			// VkImageType			imageType;
1500 			m_params.src.image.format,				// VkFormat				format;
1501 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
1502 			params.mipLevels,						// deUint32				mipLevels;
1503 			getArraySize(m_params.src.image),		// deUint32				arraySize;
1504 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1505 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1506 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1507 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1508 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1509 			1u,										// deUint32				queueFamilyCount;
1510 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1511 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1512 		};
1513 
1514 		m_source				= createImage(vk, vkDevice, &sourceImageParams);
1515 		m_sourceImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1516 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1517 	}
1518 
1519 	// Create destination image
1520 	{
1521 		const VkImageCreateInfo	destinationImageParams	=
1522 		{
1523 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1524 			DE_NULL,								// const void*			pNext;
1525 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
1526 			m_params.dst.image.imageType,			// VkImageType			imageType;
1527 			m_params.dst.image.format,				// VkFormat				format;
1528 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
1529 			params.mipLevels,						// deUint32				mipLevels;
1530 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
1531 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1532 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1533 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1534 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1535 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1536 			1u,										// deUint32				queueFamilyCount;
1537 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1538 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1539 		};
1540 
1541 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
1542 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1543 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1544 	}
1545 }
1546 
iterate(void)1547 tcu::TestStatus CopyImageToImageMipmap::iterate (void)
1548 {
1549 	const bool					srcCompressed		= isCompressedFormat(m_params.src.image.format);
1550 	const bool					dstCompressed		= isCompressedFormat(m_params.dst.image.format);
1551 
1552 	const tcu::TextureFormat	srcTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1553 	const tcu::TextureFormat	dstTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1554 
1555 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1556 																				(int)m_params.src.image.extent.width,
1557 																				(int)m_params.src.image.extent.height,
1558 																				(int)m_params.src.image.extent.depth));
1559 	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);
1560 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image, m_params.mipLevels);
1561 
1562 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1563 																					 (int)m_params.dst.image.extent.width,
1564 																					 (int)m_params.dst.image.extent.height,
1565 																					 (int)m_params.dst.image.extent.depth));
1566 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_RED);
1567 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
1568 
1569 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
1570 	const VkDevice				vkDevice			= m_context.getDevice();
1571 	const VkQueue				queue				= m_context.getUniversalQueue();
1572 
1573 	std::vector<VkImageCopy>		imageCopies;
1574 	std::vector<VkImageCopy2KHR>	imageCopies2KHR;
1575 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1576 	{
1577 		VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1578 
1579 		// When copying between compressed and uncompressed formats the extent
1580 		// members represent the texel dimensions of the source image.
1581 		if (srcCompressed)
1582 		{
1583 			const deUint32	blockWidth	= getBlockWidth(m_params.src.image.format);
1584 			const deUint32	blockHeight	= getBlockHeight(m_params.src.image.format);
1585 
1586 			imageCopy.srcOffset.x *= blockWidth;
1587 			imageCopy.srcOffset.y *= blockHeight;
1588 			imageCopy.extent.width *= blockWidth;
1589 			imageCopy.extent.height *= blockHeight;
1590 		}
1591 
1592 		if (dstCompressed)
1593 		{
1594 			const deUint32	blockWidth	= getBlockWidth(m_params.dst.image.format);
1595 			const deUint32	blockHeight	= getBlockHeight(m_params.dst.image.format);
1596 
1597 			imageCopy.dstOffset.x *= blockWidth;
1598 			imageCopy.dstOffset.y *= blockHeight;
1599 		}
1600 
1601 		if (m_params.extensionUse == EXTENSION_USE_NONE)
1602 		{
1603 			imageCopies.push_back(imageCopy);
1604 		}
1605 		else
1606 		{
1607 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1608 			imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1609 		}
1610 	}
1611 
1612 	const VkImageMemoryBarrier	imageBarriers[]		=
1613 	{
1614 		// source image
1615 		{
1616 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1617 			DE_NULL,									// const void*				pNext;
1618 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1619 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
1620 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1621 			m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
1622 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1623 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1624 			m_source.get(),								// VkImage					image;
1625 			{											// VkImageSubresourceRange	subresourceRange;
1626 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
1627 				0u,								// deUint32				baseMipLevel;
1628 				m_params.mipLevels,				// deUint32				mipLevels;
1629 				0u,								// deUint32				baseArraySlice;
1630 				getArraySize(m_params.src.image)// deUint32				arraySize;
1631 			}
1632 		},
1633 		// destination image
1634 		{
1635 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1636 			DE_NULL,									// const void*				pNext;
1637 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1638 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
1639 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1640 			m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
1641 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1642 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1643 			m_destination.get(),						// VkImage					image;
1644 			{											// VkImageSubresourceRange	subresourceRange;
1645 				getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
1646 				0u,								// deUint32				baseMipLevel;
1647 				m_params.mipLevels,				// deUint32				mipLevels;
1648 				0u,								// deUint32				baseArraySlice;
1649 				getArraySize(m_params.dst.image)// deUint32				arraySize;
1650 			}
1651 		},
1652 	};
1653 
1654 	beginCommandBuffer(vk, *m_cmdBuffer);
1655 	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);
1656 
1657 	if (m_params.extensionUse == EXTENSION_USE_NONE)
1658 	{
1659 		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());
1660 	}
1661 	else
1662 	{
1663 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1664 		const VkCopyImageInfo2KHR copyImageInfo2KHR =
1665 		{
1666 			VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
1667 			DE_NULL,									// const void*				pNext;
1668 			m_source.get(),								// VkImage					srcImage;
1669 			m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
1670 			m_destination.get(),						// VkImage					dstImage;
1671 			m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
1672 			(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
1673 			imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
1674 		};
1675 
1676 		vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
1677 	}
1678 
1679 	endCommandBuffer(vk, *m_cmdBuffer);
1680 
1681 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1682 
1683 	for (deUint32 miplevel = 0; miplevel < m_params.mipLevels; miplevel++)
1684 	{
1685 		de::MovePtr<tcu::TextureLevel>	resultTextureLevel		= readImage(*m_destination, m_params.dst.image, miplevel);
1686 		de::MovePtr<tcu::TextureLevel>	expectedTextureLevel	= readImage(*m_source, m_params.src.image, miplevel);
1687 
1688 		tcu::TestStatus result = checkResult(resultTextureLevel->getAccess(), expectedTextureLevel->getAccess());
1689 		if (result.getCode() != QP_TEST_RESULT_PASS)
1690 			return result;
1691 	}
1692 	return tcu::TestStatus::pass("Pass");
1693 }
1694 
checkResult(tcu::ConstPixelBufferAccess result,tcu::ConstPixelBufferAccess expected)1695 tcu::TestStatus CopyImageToImageMipmap::checkResult (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected)
1696 {
1697 	const tcu::Vec4	fThreshold (0.0f);
1698 	const tcu::UVec4 uThreshold (0u);
1699 
1700 	if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1701 	{
1702 		if (tcu::hasDepthComponent(result.getFormat().order))
1703 		{
1704 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
1705 			const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
1706 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(expected, mode);
1707 
1708 			if (isFloatFormat(result.getFormat()))
1709 			{
1710 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1711 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1712 			}
1713 			else
1714 			{
1715 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1716 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1717 			}
1718 		}
1719 
1720 		if (tcu::hasStencilComponent(result.getFormat().order))
1721 		{
1722 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
1723 			const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
1724 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(expected, mode);
1725 
1726 			if (isFloatFormat(result.getFormat()))
1727 			{
1728 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1729 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1730 			}
1731 			else
1732 			{
1733 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1734 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1735 			}
1736 		}
1737 	}
1738 	else
1739 	{
1740 		if (isFloatFormat(result.getFormat()))
1741 		{
1742 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, fThreshold, tcu::COMPARE_LOG_RESULT))
1743 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1744 		}
1745 		else if (isSnormFormat(mapTextureFormat(result.getFormat())))
1746 		{
1747 			// There may be an ambiguity between two possible binary representations of 1.0.
1748 			// Get rid of that by expanding the data to floats and re-normalizing again.
1749 
1750 			tcu::TextureLevel resultSnorm	(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
1751 			{
1752 				tcu::TextureLevel resultFloat	(tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
1753 
1754 				tcu::copy(resultFloat.getAccess(), result);
1755 				tcu::copy(resultSnorm, resultFloat.getAccess());
1756 			}
1757 
1758 			tcu::TextureLevel expectedSnorm	(expected.getFormat(), expected.getWidth(), expected.getHeight(), expected.getDepth());
1759 
1760 			{
1761 				tcu::TextureLevel expectedFloat	(tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
1762 
1763 				tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess());
1764 				tcu::copy(expectedSnorm, expectedFloat.getAccess());
1765 			}
1766 
1767 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT))
1768 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1769 		}
1770 		else
1771 		{
1772 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, uThreshold, tcu::COMPARE_LOG_RESULT))
1773 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1774 		}
1775 	}
1776 
1777 	return tcu::TestStatus::pass("CopiesAndBlitting test");
1778 }
1779 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1780 void CopyImageToImageMipmap::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1781 {
1782 	DE_UNREF(mipLevel);
1783 
1784 	VkOffset3D	srcOffset	= region.imageCopy.srcOffset;
1785 	VkOffset3D	dstOffset	= region.imageCopy.dstOffset;
1786 	VkExtent3D	extent		= region.imageCopy.extent;
1787 
1788 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1789 	{
1790 		dstOffset.z = srcOffset.z;
1791 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1792 	}
1793 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1794 	{
1795 		srcOffset.z = dstOffset.z;
1796 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1797 	}
1798 
1799 
1800 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1801 	{
1802 		DE_ASSERT(src.getFormat() == dst.getFormat());
1803 
1804 		// Copy depth.
1805 		if (tcu::hasDepthComponent(src.getFormat().order))
1806 		{
1807 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1808 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1809 			tcu::copy(dstSubRegion, srcSubRegion);
1810 		}
1811 
1812 		// Copy stencil.
1813 		if (tcu::hasStencilComponent(src.getFormat().order))
1814 		{
1815 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1816 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1817 			tcu::copy(dstSubRegion, srcSubRegion);
1818 		}
1819 	}
1820 	else
1821 	{
1822 		const tcu::ConstPixelBufferAccess	srcSubRegion		= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1823 		// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1824 		const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1825 		const tcu::PixelBufferAccess		dstSubRegion		= tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1826 
1827 		tcu::copy(dstSubRegion, srcSubRegion);
1828 	}
1829 }
1830 
1831 class CopyImageToImageMipmapTestCase : public vkt::TestCase
1832 {
1833 public:
CopyImageToImageMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1834 							CopyImageToImageMipmapTestCase	(tcu::TestContext&				testCtx,
1835 															 const std::string&				name,
1836 															 const std::string&				description,
1837 															 const TestParams				params)
1838 								: vkt::TestCase	(testCtx, name, description)
1839 								, m_params		(params)
1840 	{}
1841 
createInstance(Context & context) const1842 	virtual TestInstance*	createInstance				(Context&						context) const
1843 	{
1844 		return new CopyImageToImageMipmap(context, m_params);
1845 	}
1846 
checkSupport(Context & context) const1847 	virtual void			checkSupport				(Context&						context) const
1848 	{
1849 		if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1850 		{
1851 			if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1852 				TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1853 		}
1854 
1855 		if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1856 		{
1857 			if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1858 				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1859 		}
1860 
1861 		if (m_params.separateDepthStencilLayouts)
1862 			if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1863 				TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1864 
1865 		if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1866 			(m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1867 		{
1868 			if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1869 				TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1870 		}
1871 
1872 		const VkPhysicalDeviceLimits	limits		= context.getDeviceProperties().limits;
1873 		VkImageFormatProperties			properties;
1874 
1875 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1876 																					m_params.src.image.format,
1877 																					m_params.src.image.imageType,
1878 																					VK_IMAGE_TILING_OPTIMAL,
1879 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1880 																					0,
1881 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1882 			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1883 																					m_params.dst.image.format,
1884 																					m_params.dst.image.imageType,
1885 																					VK_IMAGE_TILING_OPTIMAL,
1886 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1887 																					0,
1888 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1889 		{
1890 			TCU_THROW(NotSupportedError, "Format not supported");
1891 		}
1892 
1893 		// Check maxImageDimension1D
1894 		{
1895 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1896 				TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1897 
1898 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1899 				TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1900 		}
1901 
1902 		// Check maxImageDimension2D
1903 		{
1904 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1905 				|| m_params.src.image.extent.height > limits.maxImageDimension2D))
1906 			{
1907 				TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1908 			}
1909 
1910 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1911 				|| m_params.dst.image.extent.height > limits.maxImageDimension2D))
1912 			{
1913 				TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1914 			}
1915 		}
1916 
1917 		// Check maxImageDimension3D
1918 		{
1919 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1920 				|| m_params.src.image.extent.height > limits.maxImageDimension3D
1921 				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
1922 			{
1923 				TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1924 			}
1925 
1926 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1927 				|| m_params.dst.image.extent.height > limits.maxImageDimension3D
1928 				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
1929 			{
1930 				TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1931 			}
1932 		}
1933 	}
1934 
1935 private:
1936 	TestParams				m_params;
1937 };
1938 
1939 // Copy from buffer to buffer.
1940 
1941 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
1942 {
1943 public:
1944 								CopyBufferToBuffer			(Context& context, TestParams params);
1945 	virtual tcu::TestStatus		iterate						(void);
1946 private:
1947 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion, deUint32 mipLevel = 0u);
1948 	Move<VkBuffer>				m_source;
1949 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
1950 	Move<VkBuffer>				m_destination;
1951 	de::MovePtr<Allocation>		m_destinationBufferAlloc;
1952 };
1953 
CopyBufferToBuffer(Context & context,TestParams params)1954 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
1955 	: CopiesAndBlittingTestInstance	(context, params)
1956 {
1957 	const InstanceInterface&	vki					= context.getInstanceInterface();
1958 	const DeviceInterface&		vk					= context.getDeviceInterface();
1959 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
1960 	const VkDevice				vkDevice			= context.getDevice();
1961 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
1962 	Allocator&					memAlloc			= context.getDefaultAllocator();
1963 
1964 	// Create source buffer
1965 	{
1966 		const VkBufferCreateInfo	sourceBufferParams		=
1967 		{
1968 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1969 			DE_NULL,									// const void*			pNext;
1970 			0u,											// VkBufferCreateFlags	flags;
1971 			m_params.src.buffer.size,					// VkDeviceSize			size;
1972 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
1973 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1974 			1u,											// deUint32				queueFamilyIndexCount;
1975 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1976 		};
1977 
1978 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
1979 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1980 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1981 	}
1982 
1983 	// Create destination buffer
1984 	{
1985 		const VkBufferCreateInfo	destinationBufferParams	=
1986 		{
1987 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1988 			DE_NULL,									// const void*			pNext;
1989 			0u,											// VkBufferCreateFlags	flags;
1990 			m_params.dst.buffer.size,					// VkDeviceSize			size;
1991 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
1992 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1993 			1u,											// deUint32				queueFamilyIndexCount;
1994 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
1995 		};
1996 
1997 		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
1998 		m_destinationBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1999 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2000 	}
2001 }
2002 
iterate(void)2003 tcu::TestStatus CopyBufferToBuffer::iterate (void)
2004 {
2005 	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
2006 	m_sourceTextureLevel		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
2007 	generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
2008 
2009 	const int dstLevelWidth		= (int)(m_params.dst.buffer.size/4);
2010 	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2011 	generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_BLACK);
2012 
2013 	generateExpectedResult();
2014 
2015 	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2016 	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2017 
2018 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
2019 	const VkDevice				vkDevice	= m_context.getDevice();
2020 	const VkQueue				queue		= m_context.getUniversalQueue();
2021 
2022 	const VkBufferMemoryBarrier		srcBufferBarrier	=
2023 	{
2024 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2025 		DE_NULL,									// const void*		pNext;
2026 		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
2027 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
2028 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
2029 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
2030 		*m_source,									// VkBuffer			buffer;
2031 		0u,											// VkDeviceSize		offset;
2032 		m_params.src.buffer.size					// VkDeviceSize		size;
2033 	};
2034 
2035 	const VkBufferMemoryBarrier		dstBufferBarrier	=
2036 	{
2037 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2038 		DE_NULL,									// const void*		pNext;
2039 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
2040 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
2041 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
2042 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
2043 		*m_destination,								// VkBuffer			buffer;
2044 		0u,											// VkDeviceSize		offset;
2045 		m_params.dst.buffer.size					// VkDeviceSize		size;
2046 	};
2047 
2048 	std::vector<VkBufferCopy>		bufferCopies;
2049 	std::vector<VkBufferCopy2KHR>	bufferCopies2KHR;
2050 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2051 	{
2052 		if (m_params.extensionUse == EXTENSION_USE_NONE)
2053 		{
2054 			bufferCopies.push_back(m_params.regions[i].bufferCopy);
2055 		}
2056 		else
2057 		{
2058 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2059 			bufferCopies2KHR.push_back(convertvkBufferCopyTovkBufferCopy2KHR(m_params.regions[i].bufferCopy));
2060 		}
2061 	}
2062 
2063 	beginCommandBuffer(vk, *m_cmdBuffer);
2064 	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);
2065 
2066 	if (m_params.extensionUse == EXTENSION_USE_NONE)
2067 	{
2068 		vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
2069 	}
2070 	else
2071 	{
2072 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2073 		const VkCopyBufferInfo2KHR copyBufferInfo2KHR =
2074 		{
2075 			VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR,	// VkStructureType			sType;
2076 			DE_NULL,									// const void*				pNext;
2077 			m_source.get(),								// VkBuffer					srcBuffer;
2078 			m_destination.get(),						// VkBuffer					dstBuffer;
2079 			(deUint32)m_params.regions.size(),			// uint32_t					regionCount;
2080 			&bufferCopies2KHR[0]						// const VkBufferCopy2KHR*	pRegions;
2081 		};
2082 
2083 		vk.cmdCopyBuffer2KHR(*m_cmdBuffer, &copyBufferInfo2KHR);
2084 	}
2085 
2086 	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);
2087 	endCommandBuffer(vk, *m_cmdBuffer);
2088 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2089 
2090 	// Read buffer data
2091 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2092 	invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2093 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2094 
2095 	return checkTestResult(resultLevel->getAccess());
2096 }
2097 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2098 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2099 {
2100 	DE_UNREF(mipLevel);
2101 
2102 	deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
2103 			 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
2104 			 (size_t)region.bufferCopy.size);
2105 }
2106 
2107 class BufferToBufferTestCase : public vkt::TestCase
2108 {
2109 public:
BufferToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2110 							BufferToBufferTestCase	(tcu::TestContext&	testCtx,
2111 													 const std::string&	name,
2112 													 const std::string&	description,
2113 													 const TestParams	params)
2114 								: vkt::TestCase	(testCtx, name, description)
2115 								, m_params		(params)
2116 							{}
2117 
createInstance(Context & context) const2118 	virtual TestInstance*	createInstance			(Context& context) const
2119 							{
2120 								return new CopyBufferToBuffer(context, m_params);
2121 							}
2122 
checkSupport(Context & context) const2123 	virtual void			checkSupport(Context&	context) const
2124 	{
2125 							if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
2126 							{
2127 								if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
2128 								{
2129 									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2130 								}
2131 							}
2132 	}
2133 
2134 	private:
2135 	TestParams				m_params;
2136 };
2137 
2138 // Copy from image to buffer.
2139 
2140 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
2141 {
2142 public:
2143 								CopyImageToBuffer			(Context&	context,
2144 															 TestParams	testParams);
2145 	virtual tcu::TestStatus		iterate						(void);
2146 private:
2147 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2148 
2149 	tcu::TextureFormat			m_textureFormat;
2150 	VkDeviceSize				m_bufferSize;
2151 
2152 	Move<VkImage>				m_source;
2153 	de::MovePtr<Allocation>		m_sourceImageAlloc;
2154 	Move<VkBuffer>				m_destination;
2155 	de::MovePtr<Allocation>		m_destinationBufferAlloc;
2156 };
2157 
CopyImageToBuffer(Context & context,TestParams testParams)2158 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
2159 	: CopiesAndBlittingTestInstance(context, testParams)
2160 	, m_textureFormat(mapVkFormat(testParams.src.image.format))
2161 	, m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
2162 {
2163 	const InstanceInterface&	vki					= context.getInstanceInterface();
2164 	const DeviceInterface&		vk					= context.getDeviceInterface();
2165 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
2166 	const VkDevice				vkDevice			= context.getDevice();
2167 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
2168 	Allocator&					memAlloc			= context.getDefaultAllocator();
2169 
2170 	// Create source image
2171 	{
2172 		const VkImageCreateInfo		sourceImageParams		=
2173 		{
2174 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
2175 			DE_NULL,								// const void*			pNext;
2176 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
2177 			m_params.src.image.imageType,			// VkImageType			imageType;
2178 			m_params.src.image.format,				// VkFormat				format;
2179 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
2180 			1u,										// deUint32				mipLevels;
2181 			getArraySize(m_params.src.image),		// deUint32				arraySize;
2182 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
2183 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
2184 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2185 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
2186 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2187 			1u,										// deUint32				queueFamilyCount;
2188 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
2189 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
2190 		};
2191 
2192 		m_source			= createImage(vk, vkDevice, &sourceImageParams);
2193 		m_sourceImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2194 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
2195 	}
2196 
2197 	// Create destination buffer
2198 	{
2199 		const VkBufferCreateInfo	destinationBufferParams	=
2200 		{
2201 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2202 			DE_NULL,									// const void*			pNext;
2203 			0u,											// VkBufferCreateFlags	flags;
2204 			m_bufferSize,								// VkDeviceSize			size;
2205 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
2206 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2207 			1u,											// deUint32				queueFamilyIndexCount;
2208 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
2209 		};
2210 
2211 		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
2212 		m_destinationBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2213 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2214 	}
2215 }
2216 
iterate(void)2217 tcu::TestStatus CopyImageToBuffer::iterate (void)
2218 {
2219 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2220 																				m_params.src.image.extent.width,
2221 																				m_params.src.image.extent.height,
2222 																				m_params.src.image.extent.depth));
2223 	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
2224 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2225 	generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
2226 
2227 	generateExpectedResult();
2228 
2229 	uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
2230 	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2231 
2232 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
2233 	const VkDevice				vkDevice	= m_context.getDevice();
2234 	const VkQueue				queue		= m_context.getUniversalQueue();
2235 
2236 	// Barriers for copying image to buffer
2237 	const VkImageMemoryBarrier		imageBarrier		=
2238 	{
2239 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2240 		DE_NULL,									// const void*				pNext;
2241 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2242 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
2243 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
2244 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
2245 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2246 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2247 		*m_source,									// VkImage					image;
2248 		{											// VkImageSubresourceRange	subresourceRange;
2249 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
2250 			0u,									// deUint32				baseMipLevel;
2251 			1u,									// deUint32				mipLevels;
2252 			0u,									// deUint32				baseArraySlice;
2253 			getArraySize(m_params.src.image)	// deUint32				arraySize;
2254 		}
2255 	};
2256 
2257 	const VkBufferMemoryBarrier		bufferBarrier		=
2258 	{
2259 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2260 		DE_NULL,									// const void*		pNext;
2261 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
2262 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
2263 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
2264 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
2265 		*m_destination,								// VkBuffer			buffer;
2266 		0u,											// VkDeviceSize		offset;
2267 		m_bufferSize								// VkDeviceSize		size;
2268 	};
2269 
2270 	// Copy from image to buffer
2271 	std::vector<VkBufferImageCopy>		bufferImageCopies;
2272 	std::vector<VkBufferImageCopy2KHR>	bufferImageCopies2KHR;
2273 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2274 	{
2275 		if (m_params.extensionUse == EXTENSION_USE_NONE)
2276 		{
2277 			bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2278 		}
2279 		else
2280 		{
2281 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2282 			bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2283 		}
2284 	}
2285 
2286 	beginCommandBuffer(vk, *m_cmdBuffer);
2287 	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);
2288 
2289 	if (m_params.extensionUse == EXTENSION_USE_NONE)
2290 	{
2291 		vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
2292 	}
2293 	else
2294 	{
2295 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2296 		const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR =
2297 		{
2298 			VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR,	// VkStructureType				sType;
2299 			DE_NULL,											// const void*					pNext;
2300 			m_source.get(),										// VkImage						srcImage;
2301 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,				// VkImageLayout				srcImageLayout;
2302 			m_destination.get(),								// VkBuffer						dstBuffer;
2303 			(deUint32)m_params.regions.size(),					// uint32_t						regionCount;
2304 			&bufferImageCopies2KHR[0]							// const VkBufferImageCopy2KHR*	pRegions;
2305 		};
2306 
2307 		vk.cmdCopyImageToBuffer2KHR(*m_cmdBuffer, &copyImageToBufferInfo2KHR);
2308 	}
2309 
2310 	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);
2311 	endCommandBuffer(vk, *m_cmdBuffer);
2312 
2313 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2314 
2315 	// Read buffer data
2316 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2317 	invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2318 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2319 
2320 	return checkTestResult(resultLevel->getAccess());
2321 }
2322 
2323 class CopyImageToBufferTestCase : public vkt::TestCase
2324 {
2325 public:
CopyImageToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2326 							CopyImageToBufferTestCase	(tcu::TestContext&		testCtx,
2327 														 const std::string&		name,
2328 														 const std::string&		description,
2329 														 const TestParams		params)
2330 								: vkt::TestCase	(testCtx, name, description)
2331 								, m_params		(params)
2332 							{}
2333 
createInstance(Context & context) const2334 	virtual TestInstance*	createInstance				(Context&				context) const
2335 							{
2336 								return new CopyImageToBuffer(context, m_params);
2337 							}
2338 
checkSupport(Context & context) const2339 	virtual void			checkSupport				(Context&				context) const
2340 							{
2341 								if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2342 									(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2343 								{
2344 									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2345 								}
2346 							}
2347 
2348 private:
2349 	TestParams				m_params;
2350 };
2351 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2352 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2353 {
2354 	DE_UNREF(mipLevel);
2355 
2356 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
2357 	if (!rowLength)
2358 		rowLength = region.bufferImageCopy.imageExtent.width;
2359 
2360 	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
2361 	if (!imageHeight)
2362 		imageHeight = region.bufferImageCopy.imageExtent.height;
2363 
2364 	const int			texelSize		= src.getFormat().getPixelSize();
2365 	const VkExtent3D	extent			= region.bufferImageCopy.imageExtent;
2366 	const VkOffset3D	srcOffset		= region.bufferImageCopy.imageOffset;
2367 	const int			texelOffset		= (int) region.bufferImageCopy.bufferOffset / texelSize;
2368 	const deUint32		baseArrayLayer	= region.bufferImageCopy.imageSubresource.baseArrayLayer;
2369 
2370 	for (deUint32 z = 0; z < extent.depth; z++)
2371 	{
2372 		for (deUint32 y = 0; y < extent.height; y++)
2373 		{
2374 			int									texelIndex		= texelOffset + (z * imageHeight + y) *	rowLength;
2375 			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z + baseArrayLayer,
2376 																					region.bufferImageCopy.imageExtent.width, 1, 1);
2377 			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2378 			tcu::copy(dstSubRegion, srcSubRegion);
2379 		}
2380 	}
2381 }
2382 
2383 // Copy from buffer to image.
2384 
2385 class CopyBufferToImage : public CopiesAndBlittingTestInstance
2386 {
2387 public:
2388 								CopyBufferToImage			(Context&	context,
2389 															 TestParams	testParams);
2390 	virtual tcu::TestStatus		iterate						(void);
2391 
2392 private:
2393 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2394 
2395 	tcu::TextureFormat			m_textureFormat;
2396 	VkDeviceSize				m_bufferSize;
2397 
2398 	Move<VkBuffer>				m_source;
2399 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
2400 	Move<VkImage>				m_destination;
2401 	de::MovePtr<Allocation>		m_destinationImageAlloc;
2402 };
2403 
CopyBufferToImage(Context & context,TestParams testParams)2404 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
2405 	: CopiesAndBlittingTestInstance(context, testParams)
2406 	, m_textureFormat(mapVkFormat(testParams.dst.image.format))
2407 	, m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
2408 {
2409 	const InstanceInterface&	vki					= context.getInstanceInterface();
2410 	const DeviceInterface&		vk					= context.getDeviceInterface();
2411 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
2412 	const VkDevice				vkDevice			= context.getDevice();
2413 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
2414 	Allocator&					memAlloc			= context.getDefaultAllocator();
2415 
2416 	// Create source buffer
2417 	{
2418 		const VkBufferCreateInfo	sourceBufferParams		=
2419 		{
2420 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2421 			DE_NULL,									// const void*			pNext;
2422 			0u,											// VkBufferCreateFlags	flags;
2423 			m_bufferSize,								// VkDeviceSize			size;
2424 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
2425 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2426 			1u,											// deUint32				queueFamilyIndexCount;
2427 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
2428 		};
2429 
2430 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
2431 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2432 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2433 	}
2434 
2435 	// Create destination image
2436 	{
2437 		const VkImageCreateInfo		destinationImageParams	=
2438 		{
2439 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
2440 			DE_NULL,								// const void*			pNext;
2441 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
2442 			m_params.dst.image.imageType,			// VkImageType			imageType;
2443 			m_params.dst.image.format,				// VkFormat				format;
2444 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
2445 			1u,										// deUint32				mipLevels;
2446 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
2447 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
2448 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
2449 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2450 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
2451 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2452 			1u,										// deUint32				queueFamilyCount;
2453 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
2454 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
2455 		};
2456 
2457 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
2458 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2459 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2460 	}
2461 }
2462 
iterate(void)2463 tcu::TestStatus CopyBufferToImage::iterate (void)
2464 {
2465 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2466 	generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2467 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2468 																					m_params.dst.image.extent.width,
2469 																					m_params.dst.image.extent.height,
2470 																					m_params.dst.image.extent.depth));
2471 
2472 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2473 
2474 	generateExpectedResult();
2475 
2476 	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2477 	uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2478 
2479 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
2480 	const VkDevice				vkDevice	= m_context.getDevice();
2481 	const VkQueue				queue		= m_context.getUniversalQueue();
2482 
2483 	const VkImageMemoryBarrier	imageBarrier	=
2484 	{
2485 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2486 		DE_NULL,									// const void*				pNext;
2487 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2488 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
2489 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
2490 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
2491 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2492 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2493 		*m_destination,								// VkImage					image;
2494 		{											// VkImageSubresourceRange	subresourceRange;
2495 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
2496 			0u,								// deUint32				baseMipLevel;
2497 			1u,								// deUint32				mipLevels;
2498 			0u,								// deUint32				baseArraySlice;
2499 			getArraySize(m_params.dst.image)								// deUint32				arraySize;
2500 		}
2501 	};
2502 
2503 	// Copy from buffer to image
2504 	std::vector<VkBufferImageCopy>		bufferImageCopies;
2505 	std::vector<VkBufferImageCopy2KHR>	bufferImageCopies2KHR;
2506 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2507 	{
2508 		if (m_params.extensionUse == EXTENSION_USE_NONE)
2509 		{
2510 			bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2511 		}
2512 		else
2513 		{
2514 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2515 			bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2516 		}
2517 	}
2518 
2519 	beginCommandBuffer(vk, *m_cmdBuffer);
2520 	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);
2521 
2522 	if (m_params.extensionUse == EXTENSION_USE_NONE)
2523 	{
2524 		vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2525 	}
2526 	else
2527 	{
2528 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2529 		const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2530 		{
2531 			VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
2532 			DE_NULL,											// const void*					pNext;
2533 			m_source.get(),										// VkBuffer						srcBuffer;
2534 			m_destination.get(),								// VkImage						dstImage;
2535 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout				dstImageLayout;
2536 			(deUint32)m_params.regions.size(),					// uint32_t						regionCount;
2537 			bufferImageCopies2KHR.data()						// const VkBufferImageCopy2KHR*	pRegions;
2538 		};
2539 
2540 		vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2541 	}
2542 
2543 
2544 	endCommandBuffer(vk, *m_cmdBuffer);
2545 
2546 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2547 
2548 	de::MovePtr<tcu::TextureLevel>	resultLevel	= readImage(*m_destination, m_params.dst.image);
2549 
2550 	return checkTestResult(resultLevel->getAccess());
2551 }
2552 
2553 class CopyBufferToImageTestCase : public vkt::TestCase
2554 {
2555 public:
CopyBufferToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2556 							CopyBufferToImageTestCase	(tcu::TestContext&		testCtx,
2557 														 const std::string&		name,
2558 														 const std::string&		description,
2559 														 const TestParams		params)
2560 								: vkt::TestCase	(testCtx, name, description)
2561 								, m_params		(params)
2562 							{}
2563 
~CopyBufferToImageTestCase(void)2564 	virtual					~CopyBufferToImageTestCase	(void) {}
2565 
createInstance(Context & context) const2566 	virtual TestInstance*	createInstance				(Context&				context) const
2567 							{
2568 								return new CopyBufferToImage(context, m_params);
2569 							}
2570 
checkSupport(Context & context) const2571 	virtual void			checkSupport				(Context&				context) const
2572 							{
2573 								if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2574 									(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2575 								{
2576 									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2577 								}
2578 							}
2579 
2580 
2581 private:
2582 	TestParams				m_params;
2583 };
2584 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2585 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2586 {
2587 	DE_UNREF(mipLevel);
2588 
2589 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
2590 	if (!rowLength)
2591 		rowLength = region.bufferImageCopy.imageExtent.width;
2592 
2593 	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
2594 	if (!imageHeight)
2595 		imageHeight = region.bufferImageCopy.imageExtent.height;
2596 
2597 	const int			texelSize		= dst.getFormat().getPixelSize();
2598 	const VkExtent3D	extent			= region.bufferImageCopy.imageExtent;
2599 	const VkOffset3D	dstOffset		= region.bufferImageCopy.imageOffset;
2600 	const int			texelOffset		= (int) region.bufferImageCopy.bufferOffset / texelSize;
2601 	const deUint32		baseArrayLayer	= region.bufferImageCopy.imageSubresource.baseArrayLayer;
2602 
2603 	for (deUint32 z = 0; z < extent.depth; z++)
2604 	{
2605 		for (deUint32 y = 0; y < extent.height; y++)
2606 		{
2607 			int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2608 			const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2609 			const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z + baseArrayLayer,
2610 																		  region.bufferImageCopy.imageExtent.width, 1, 1);
2611 			tcu::copy(dstSubRegion, srcSubRegion);
2612 		}
2613 	}
2614 }
2615 
2616 class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
2617 {
2618 public:
2619 								CopyBufferToDepthStencil	(Context& context,
2620 															 TestParams	testParams);
2621 	virtual tcu::TestStatus		iterate						(void);
2622 private:
2623 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2624 
2625 	tcu::TextureFormat			m_textureFormat;
2626 	VkDeviceSize				m_bufferSize;
2627 
2628 	Move<VkBuffer>				m_source;
2629 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
2630 	Move<VkImage>				m_destination;
2631 	de::MovePtr<Allocation>		m_destinationImageAlloc;
2632 };
2633 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2634 void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2635 {
2636 	DE_UNREF(mipLevel);
2637 
2638 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
2639 	if (!rowLength)
2640 		rowLength = region.bufferImageCopy.imageExtent.width;
2641 
2642 	deUint32			imageHeight = region.bufferImageCopy.bufferImageHeight;
2643 	if (!imageHeight)
2644 		imageHeight = region.bufferImageCopy.imageExtent.height;
2645 
2646 	const int			texelSize	= dst.getFormat().getPixelSize();
2647 	const VkExtent3D	extent		= region.bufferImageCopy.imageExtent;
2648 	const VkOffset3D	dstOffset	= region.bufferImageCopy.imageOffset;
2649 	const int			texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
2650 
2651 	for (deUint32 z = 0; z < extent.depth; z++)
2652 	{
2653 		for (deUint32 y = 0; y < extent.height; y++)
2654 		{
2655 			int									texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2656 			const tcu::ConstPixelBufferAccess	srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2657 			const tcu::PixelBufferAccess		dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
2658 				region.bufferImageCopy.imageExtent.width, 1, 1);
2659 
2660 			if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
2661 			{
2662 				tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH), DE_FALSE);
2663 			}
2664 			else
2665 			{
2666 				tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL), DE_FALSE);
2667 			}
2668 		}
2669 	}
2670 }
2671 
isSupportedDepthStencilFormat(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat format)2672 bool isSupportedDepthStencilFormat(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
2673 {
2674 	VkFormatProperties formatProps;
2675 	vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
2676 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
2677 }
2678 
CopyBufferToDepthStencil(Context & context,TestParams testParams)2679 CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context& context, TestParams testParams)
2680 	: CopiesAndBlittingTestInstance(context, testParams)
2681 	, m_textureFormat(mapVkFormat(testParams.dst.image.format))
2682 	, m_bufferSize(0)
2683 {
2684 	const InstanceInterface&	vki					= context.getInstanceInterface();
2685 	const DeviceInterface&		vk					= context.getDeviceInterface();
2686 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
2687 	const VkDevice				vkDevice			= context.getDevice();
2688 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
2689 	Allocator&					memAlloc			= context.getDefaultAllocator();
2690 	const bool					hasDepth			= tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
2691 	const bool					hasStencil			= tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
2692 
2693 	if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
2694 	{
2695 		TCU_THROW(NotSupportedError, "Image format not supported.");
2696 	}
2697 
2698 	if (hasDepth)
2699 	{
2700 		glw::GLuint texelSize = m_textureFormat.getPixelSize();
2701 		if (texelSize > sizeof(float))
2702 		{
2703 			// We must have D32F_S8 format, depth must be packed so we only need
2704 			// to allocate space for the D32F part. Stencil will be separate
2705 			texelSize = sizeof(float);
2706 		}
2707 		m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height) * static_cast<VkDeviceSize>(texelSize);
2708 	}
2709 	if (hasStencil)
2710 	{
2711 		// Stencil is always 8bits and packed.
2712 		m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
2713 	}
2714 
2715 	// Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
2716 	{
2717 		const VkBufferCreateInfo	sourceBufferParams		=
2718 		{
2719 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2720 			DE_NULL,									// const void*			pNext;
2721 			0u,											// VkBufferCreateFlags	flags;
2722 			m_bufferSize,								// VkDeviceSize			size;
2723 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
2724 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2725 			1u,											// deUint32				queueFamilyIndexCount;
2726 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
2727 		};
2728 
2729 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
2730 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2731 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2732 	}
2733 
2734 	// Create destination image
2735 	{
2736 		const VkImageCreateInfo		destinationImageParams	=
2737 		{
2738 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
2739 			DE_NULL,								// const void*			pNext;
2740 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
2741 			m_params.dst.image.imageType,			// VkImageType			imageType;
2742 			m_params.dst.image.format,				// VkFormat				format;
2743 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
2744 			1u,										// deUint32				mipLevels;
2745 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
2746 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
2747 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
2748 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2749 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
2750 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2751 			1u,										// deUint32				queueFamilyCount;
2752 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
2753 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
2754 		};
2755 
2756 		m_destination				= createImage(vk, vkDevice, &destinationImageParams);
2757 		m_destinationImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2758 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2759 	}
2760 }
2761 
iterate(void)2762 tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
2763 {
2764 	// Create source depth/stencil content. Treat as 1D texture to get different pattern
2765 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2766 	// Fill buffer with linear gradiant
2767 	generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2768 
2769 	// Create image layer for depth/stencil
2770 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2771 		m_params.dst.image.extent.width,
2772 		m_params.dst.image.extent.height,
2773 		m_params.dst.image.extent.depth));
2774 
2775 	// Fill image layer with 2D gradiant
2776 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2777 
2778 	// Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
2779 	// Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
2780 	// This emulates what the HW will be doing.
2781 	generateExpectedResult();
2782 
2783 	// Upload our source depth/stencil content to the source buffer
2784 	// This is the buffer that will be used by region commands
2785 	std::vector<VkBufferImageCopy>		bufferImageCopies;
2786 	std::vector<VkBufferImageCopy2KHR>	bufferImageCopies2KHR;
2787 	VkDeviceSize					bufferOffset	= 0;
2788 	const VkDevice					vkDevice		= m_context.getDevice();
2789 	const DeviceInterface&			vk				= m_context.getDeviceInterface();
2790 	const VkQueue					queue			= m_context.getUniversalQueue();
2791 	char*							dstPtr			= reinterpret_cast<char*>(m_sourceBufferAlloc->getHostPtr());
2792 	bool							depthLoaded		= DE_FALSE;
2793 	bool							stencilLoaded	= DE_FALSE;
2794 	VkDeviceSize					depthOffset		= 0;
2795 	VkDeviceSize					stencilOffset	= 0;
2796 
2797 	// To be able to test ordering depth & stencil differently
2798 	// we take the given copy regions and use that as the desired order
2799 	// and copy the appropriate data into place and compute the appropriate
2800 	// data offsets to be used in the copy command.
2801 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2802 	{
2803 		tcu::ConstPixelBufferAccess bufferAccess	= m_sourceTextureLevel->getAccess();
2804 		deUint32					bufferSize		= bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
2805 		VkBufferImageCopy			copyData		= m_params.regions[i].bufferImageCopy;
2806 		char*						srcPtr;
2807 
2808 		if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
2809 		{
2810 			// Create level that is same component as depth buffer (e.g. D16, D24, D32F)
2811 			tcu::TextureLevel	depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2812 			bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
2813 			// Copy depth component only from source data. This gives us packed depth-only data.
2814 			tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
2815 			srcPtr = (char*)depthTexture.getAccess().getDataPtr();
2816 			// Copy packed depth-only data to output buffer
2817 			deMemcpy(dstPtr, srcPtr, bufferSize);
2818 			depthLoaded = DE_TRUE;
2819 			depthOffset = bufferOffset;
2820 			dstPtr += bufferSize;
2821 			bufferOffset += bufferSize;
2822 			copyData.bufferOffset += depthOffset;
2823 		}
2824 		else if (!stencilLoaded)
2825 		{
2826 			// Create level that is same component as stencil buffer (always 8-bits)
2827 			tcu::TextureLevel	stencilTexture(tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2828 			// Copy stencil component only from source data. This gives us packed stencil-only data.
2829 			tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
2830 			srcPtr = (char*)stencilTexture.getAccess().getDataPtr();
2831 			// Copy packed stencil-only data to output buffer
2832 			deMemcpy(dstPtr, srcPtr, bufferSize);
2833 			stencilLoaded = DE_TRUE;
2834 			stencilOffset = bufferOffset;
2835 			dstPtr += bufferSize;
2836 			bufferOffset += bufferSize;
2837 
2838 			// Reference image generation uses pixel offsets based on buffer offset.
2839 			// We need to adjust the offset now that the stencil data is not interleaved.
2840 			copyData.bufferOffset /= tcu::getPixelSize(m_textureFormat);
2841 
2842 			copyData.bufferOffset += stencilOffset;
2843 		}
2844 
2845 		if (m_params.extensionUse == EXTENSION_USE_NONE)
2846 		{
2847 			bufferImageCopies.push_back(copyData);
2848 		}
2849 		else
2850 		{
2851 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2852 			bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyData));
2853 		}
2854 	}
2855 
2856 	flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
2857 
2858 	// Upload the depth/stencil data from m_destinationTextureLevel to initialize
2859 	// depth and stencil to known values.
2860 	// Uses uploadImageAspect so makes its own buffers for depth and stencil
2861 	// aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
2862 	uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2863 
2864 	const VkImageMemoryBarrier	imageBarrier	=
2865 	{
2866 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2867 		DE_NULL,									// const void*				pNext;
2868 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2869 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
2870 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
2871 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
2872 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2873 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2874 		*m_destination,								// VkImage					image;
2875 		{											// VkImageSubresourceRange	subresourceRange;
2876 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
2877 			0u,								// deUint32				baseMipLevel;
2878 			1u,								// deUint32				mipLevels;
2879 			0u,								// deUint32				baseArraySlice;
2880 			1u								// deUint32				arraySize;
2881 		}
2882 	};
2883 
2884 	// Copy from buffer to depth/stencil image
2885 
2886 	beginCommandBuffer(vk, *m_cmdBuffer);
2887 	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);
2888 
2889 	if (m_params.extensionUse == EXTENSION_USE_NONE)
2890 	{
2891 		if (m_params.singleCommand)
2892 		{
2893 			// Issue a single copy command with regions defined by the test.
2894 			vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2895 		}
2896 		else
2897 		{
2898 			// Issue a a copy command per region defined by the test.
2899 			for (deUint32 i = 0; i < bufferImageCopies.size(); i++)
2900 			{
2901 				vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
2902 			}
2903 		}
2904 	}
2905 	else
2906 	{
2907 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2908 
2909 		if (m_params.singleCommand)
2910 		{
2911 			// Issue a single copy command with regions defined by the test.
2912 			const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2913 			{
2914 				VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
2915 				DE_NULL,											// const void*					pNext;
2916 				m_source.get(),										// VkBuffer						srcBuffer;
2917 				m_destination.get(),								// VkImage						dstImage;
2918 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout				dstImageLayout;
2919 				(deUint32)m_params.regions.size(),					// uint32_t						regionCount;
2920 				bufferImageCopies2KHR.data()						// const VkBufferImageCopy2KHR*	pRegions;
2921 			};
2922 			vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2923 		}
2924 		else
2925 		{
2926 			// Issue a a copy command per region defined by the test.
2927 			for (deUint32 i = 0; i < bufferImageCopies2KHR.size(); i++)
2928 			{
2929 				const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2930 				{
2931 					VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
2932 					DE_NULL,											// const void*					pNext;
2933 					m_source.get(),										// VkBuffer						srcBuffer;
2934 					m_destination.get(),								// VkImage						dstImage;
2935 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout				dstImageLayout;
2936 					1,													// uint32_t						regionCount;
2937 					&bufferImageCopies2KHR[i]							// const VkBufferImageCopy2KHR*	pRegions;
2938 				};
2939 				// Issue a single copy command with regions defined by the test.
2940 				vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2941 			}
2942 		}
2943 	}
2944 	endCommandBuffer(vk, *m_cmdBuffer);
2945 
2946 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2947 
2948 	de::MovePtr<tcu::TextureLevel>	resultLevel = readImage(*m_destination, m_params.dst.image);
2949 
2950 	// For combined depth/stencil formats both aspects are checked even when the test only
2951 	// copies one. Clear such aspects here for both the result and the reference.
2952 	if (tcu::hasDepthComponent(m_textureFormat.order) && !depthLoaded)
2953 	{
2954 		tcu::clearDepth(m_expectedTextureLevel[0]->getAccess(), 0.0f);
2955 		tcu::clearDepth(resultLevel->getAccess(), 0.0f);
2956 	}
2957 	if (tcu::hasStencilComponent(m_textureFormat.order) && !stencilLoaded)
2958 	{
2959 		tcu::clearStencil(m_expectedTextureLevel[0]->getAccess(), 0);
2960 		tcu::clearStencil(resultLevel->getAccess(), 0);
2961 	}
2962 
2963 	return checkTestResult(resultLevel->getAccess());
2964 }
2965 
2966 class CopyBufferToDepthStencilTestCase : public vkt::TestCase
2967 {
2968 public:
CopyBufferToDepthStencilTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2969 							CopyBufferToDepthStencilTestCase	(tcu::TestContext&		testCtx,
2970 																 const std::string&		name,
2971 																 const std::string&		description,
2972 																 const TestParams		params)
2973 								: vkt::TestCase(testCtx, name, description)
2974 								, m_params(params)
2975 							{}
2976 
~CopyBufferToDepthStencilTestCase(void)2977 	virtual					~CopyBufferToDepthStencilTestCase	(void) {}
2978 
createInstance(Context & context) const2979 	virtual TestInstance*	createInstance						(Context&				context) const
2980 							{
2981 								return new CopyBufferToDepthStencil(context, m_params);
2982 							}
2983 
checkSupport(Context & context) const2984 	virtual void			checkSupport						(Context&				context) const
2985 							{
2986 								if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2987 									(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2988 								{
2989 									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2990 								}
2991 							}
2992 
2993 private:
2994 	TestParams				m_params;
2995 };
2996 
2997 // CompressedTextureForBlit is a helper class that stores compressed texture data.
2998 // Implementation is based on pipeline::TestTexture2D but it allocates only one level
2999 // and has special cases needed for blits to some formats.
3000 
3001 class CompressedTextureForBlit
3002 {
3003 public:
3004 	CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth, VkFormat dstFormat);
3005 
3006 	tcu::PixelBufferAccess			getDecompressedAccess() const;
3007 	const tcu::CompressedTexture&	getCompressedTexture() const;
3008 
3009 protected:
3010 
3011 	tcu::CompressedTexture		m_compressedTexture;
3012 	de::ArrayBuffer<deUint8>	m_decompressedData;
3013 	tcu::PixelBufferAccess		m_decompressedAccess;
3014 };
3015 
CompressedTextureForBlit(const tcu::CompressedTexFormat & srcFormat,int width,int height,int depth,VkFormat dstFormat)3016 CompressedTextureForBlit::CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth, VkFormat dstFormat)
3017 	: m_compressedTexture(srcFormat, width, height, depth)
3018 {
3019 	de::Random			random					(123);
3020 
3021 	const int			compressedDataSize		(m_compressedTexture.getDataSize());
3022 	deUint8*			compressedData			((deUint8*)m_compressedTexture.getData());
3023 
3024 	tcu::TextureFormat	decompressedSrcFormat	(tcu::getUncompressedFormat(srcFormat));
3025 	const int			decompressedDataSize	(tcu::getPixelSize(decompressedSrcFormat) * width * height * depth);
3026 
3027 	// generate random data for compresed textre
3028 	if (tcu::isAstcFormat(srcFormat))
3029 	{
3030 		// comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
3031 		tcu::astc::generateRandomValidBlocks(compressedData, compressedDataSize / tcu::astc::BLOCK_SIZE_BYTES,
3032 											 srcFormat, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
3033 	}
3034 	else if ((dstFormat == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) &&
3035 			((srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK) ||
3036 			 (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)))
3037 	{
3038 		// special case - when we are blitting compressed image to RGB999E5 image we can't have both big and small values
3039 		// in compressed image; to resolve this we are constructing source texture out of set of predefined compressed
3040 		// blocks that after decompression will have components in proper range
3041 
3042 		struct BC6HBlock
3043 		{
3044 			deUint32 data[4];
3045 		};
3046 		std::vector<BC6HBlock> validBlocks;
3047 
3048 		if (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)
3049 		{
3050 			// define set of few valid blocks that contain values from <0; 1> range
3051 			validBlocks =
3052 			{
3053 				{ 1686671500, 3957317723, 3010132342, 2420137890 },
3054 				{ 3538027716, 298848033, 1925786021, 2022072301 },
3055 				{ 2614043466, 1636155440, 1023731774, 1894349986 },
3056 				{ 3433039318, 1294346072, 1587319645, 1738449906 },
3057 				{ 1386298160, 1639492154, 1273285776, 361562050 },
3058 				{ 1310110688, 526460754, 3630858047, 537617591 },
3059 				{ 3270356556, 2432993217, 2415924417, 1792488857 },
3060 				{ 1204947583, 353249154, 3739153467, 2068076443 },
3061 			};
3062 		}
3063 		else
3064 		{
3065 			// define set of few valid blocks that contain values from <-1; 1> range
3066 			validBlocks =
3067 			{
3068 				{ 2120678840, 3264271120, 4065378848, 3479743703 },
3069 				{ 1479697556, 3480872527, 3369382558, 568252340 },
3070 				{ 1301480032, 1607738094, 3055221704, 3663953681 },
3071 				{ 3531657186, 2285472028, 1429601507, 1969308187 },
3072 				{ 73229044, 650504649, 1120954865, 2626631975 },
3073 				{ 3872486086, 15326178, 2565171269, 2857722432 },
3074 				{ 1301480032, 1607738094, 3055221704, 3663953681 },
3075 				{ 73229044, 650504649, 1120954865, 2626631975 },
3076 			};
3077 		}
3078 
3079 		deUint32*	compressedDataUint32	= reinterpret_cast<deUint32*>(compressedData);
3080 		const int	blocksCount				= compressedDataSize / static_cast<int>(sizeof(BC6HBlock));
3081 
3082 		// fill data using randomly selected valid blocks
3083 		for (int blockNdx = 0; blockNdx < blocksCount; blockNdx++)
3084 		{
3085 			deUint32 selectedBlock = random.getUint32() % static_cast<deUint32>(validBlocks.size());
3086 			deMemcpy(compressedDataUint32, validBlocks[selectedBlock].data, sizeof(BC6HBlock));
3087 			compressedDataUint32 += 4;
3088 		}
3089 	}
3090 	else if (srcFormat != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
3091 	{
3092 		// random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
3093 		for (int byteNdx = 0; byteNdx < compressedDataSize; byteNdx++)
3094 			compressedData[byteNdx] = 0xFF & random.getUint32();
3095 	}
3096 
3097 	// alocate space for decompressed texture
3098 	m_decompressedData.setStorage(decompressedDataSize);
3099 	m_decompressedAccess = tcu::PixelBufferAccess(decompressedSrcFormat, width, height, depth, m_decompressedData.getPtr());
3100 
3101 	// store decompressed data
3102 	m_compressedTexture.decompress(m_decompressedAccess, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
3103 }
3104 
getDecompressedAccess() const3105 tcu::PixelBufferAccess CompressedTextureForBlit::getDecompressedAccess() const
3106 {
3107 	return m_decompressedAccess;
3108 }
3109 
getCompressedTexture() const3110 const tcu::CompressedTexture& CompressedTextureForBlit::getCompressedTexture() const
3111 {
3112 	return m_compressedTexture;
3113 }
3114 
3115 // Copy from image to image with scaling.
3116 
3117 class BlittingImages : public CopiesAndBlittingTestInstance
3118 {
3119 public:
3120 											BlittingImages					(Context&	context,
3121 																			 TestParams params);
3122 	virtual tcu::TestStatus					iterate							(void);
3123 protected:
3124 	virtual tcu::TestStatus					checkTestResult							(tcu::ConstPixelBufferAccess	result);
3125 	virtual void							copyRegionToTextureLevel				(tcu::ConstPixelBufferAccess	src,
3126 																					 tcu::PixelBufferAccess			dst,
3127 																					 CopyRegion						region,
3128 																					 deUint32						mipLevel = 0u);
3129 	virtual void							generateExpectedResult					(void);
3130 	void									uploadCompressedImage					(const VkImage& image, const ImageParms& parms);
3131 private:
3132 	bool									checkNonNearestFilteredResult			(const tcu::ConstPixelBufferAccess&	result,
3133 																					 const tcu::ConstPixelBufferAccess&	clampedReference,
3134 																					 const tcu::ConstPixelBufferAccess&	unclampedReference,
3135 																					 const tcu::TextureFormat&			sourceFormat);
3136 	bool									checkNearestFilteredResult				(const tcu::ConstPixelBufferAccess&	result,
3137 																					 const tcu::ConstPixelBufferAccess&	source);
3138 
3139 	bool									checkCompressedNonNearestFilteredResult	(const tcu::ConstPixelBufferAccess&	result,
3140 																					 const tcu::ConstPixelBufferAccess&	clampedReference,
3141 																					 const tcu::ConstPixelBufferAccess&	unclampedReference,
3142 																					 const tcu::CompressedTexFormat		format);
3143 	bool									checkCompressedNearestFilteredResult	(const tcu::ConstPixelBufferAccess&	result,
3144 																					 const tcu::ConstPixelBufferAccess&	source,
3145 																					 const tcu::CompressedTexFormat		format);
3146 
3147 
3148 	Move<VkImage>						m_source;
3149 	de::MovePtr<Allocation>				m_sourceImageAlloc;
3150 	Move<VkImage>						m_destination;
3151 	de::MovePtr<Allocation>				m_destinationImageAlloc;
3152 
3153 	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel;
3154 
3155 	// helper used only when bliting from compressed formats
3156 	typedef de::SharedPtr<CompressedTextureForBlit> CompressedTextureForBlitSp;
3157 	CompressedTextureForBlitSp			m_sourceCompressedTexture;
3158 	CompressedTextureForBlitSp			m_destinationCompressedTexture;
3159 };
3160 
BlittingImages(Context & context,TestParams params)3161 BlittingImages::BlittingImages (Context& context, TestParams params)
3162 	: CopiesAndBlittingTestInstance(context, params)
3163 {
3164 	const InstanceInterface&	vki					= context.getInstanceInterface();
3165 	const DeviceInterface&		vk					= context.getDeviceInterface();
3166 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
3167 	const VkDevice				vkDevice			= context.getDevice();
3168 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
3169 	Allocator&					memAlloc			= context.getDefaultAllocator();
3170 
3171 	// Create source image
3172 	{
3173 		const VkImageCreateInfo		sourceImageParams		=
3174 		{
3175 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
3176 			DE_NULL,								// const void*			pNext;
3177 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
3178 			m_params.src.image.imageType,			// VkImageType			imageType;
3179 			m_params.src.image.format,				// VkFormat				format;
3180 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
3181 			1u,										// deUint32				mipLevels;
3182 			getArraySize(m_params.src.image),		// deUint32				arraySize;
3183 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
3184 			m_params.src.image.tiling,				// VkImageTiling		tiling;
3185 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3186 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
3187 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
3188 			1u,										// deUint32				queueFamilyCount;
3189 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
3190 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
3191 		};
3192 
3193 		m_source = createImage(vk, vkDevice, &sourceImageParams);
3194 		m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3195 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
3196 	}
3197 
3198 	// Create destination image
3199 	{
3200 		const VkImageCreateInfo		destinationImageParams	=
3201 		{
3202 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
3203 			DE_NULL,								// const void*			pNext;
3204 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
3205 			m_params.dst.image.imageType,			// VkImageType			imageType;
3206 			m_params.dst.image.format,				// VkFormat				format;
3207 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
3208 			1u,										// deUint32				mipLevels;
3209 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
3210 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
3211 			m_params.dst.image.tiling,				// VkImageTiling		tiling;
3212 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3213 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
3214 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
3215 			1u,										// deUint32				queueFamilyCount;
3216 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
3217 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
3218 		};
3219 
3220 		m_destination = createImage(vk, vkDevice, &destinationImageParams);
3221 		m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3222 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
3223 	}
3224 }
3225 
iterate(void)3226 tcu::TestStatus BlittingImages::iterate (void)
3227 {
3228 	const DeviceInterface&		vk				= m_context.getDeviceInterface();
3229 	const VkDevice				vkDevice		= m_context.getDevice();
3230 	const VkQueue				queue			= m_context.getUniversalQueue();
3231 
3232 	const ImageParms&			srcImageParams	= m_params.src.image;
3233 	const int					srcWidth		= static_cast<int>(srcImageParams.extent.width);
3234 	const int					srcHeight		= static_cast<int>(srcImageParams.extent.height);
3235 	const int					srcDepth		= static_cast<int>(srcImageParams.extent.depth);
3236 	const ImageParms&			dstImageParams	= m_params.dst.image;
3237 	const int					dstWidth		= static_cast<int>(dstImageParams.extent.width);
3238 	const int					dstHeight		= static_cast<int>(dstImageParams.extent.height);
3239 	const int					dstDepth		= static_cast<int>(dstImageParams.extent.depth);
3240 
3241 	std::vector<VkImageBlit>		regions;
3242 	std::vector<VkImageBlit2KHR>	regions2KHR;
3243 
3244 	// setup blit regions - they are also needed for reference generation
3245 	if (m_params.extensionUse == EXTENSION_USE_NONE)
3246 	{
3247 		regions.reserve(m_params.regions.size());
3248 		for (const auto& r : m_params.regions)
3249 			regions.push_back(r.imageBlit);
3250 	}
3251 	else
3252 	{
3253 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3254 		regions2KHR.reserve(m_params.regions.size());
3255 		for (const auto& r : m_params.regions)
3256 			regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(r.imageBlit));
3257 	}
3258 
3259 	// generate source image
3260 	if (isCompressedFormat(srcImageParams.format))
3261 	{
3262 		// for compressed images srcImageParams.fillMode is not used - we are using random data
3263 		tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(srcImageParams.format);
3264 		m_sourceCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth, dstImageParams.format));
3265 		uploadCompressedImage(m_source.get(), srcImageParams);
3266 	}
3267 	else
3268 	{
3269 		// non-compressed image is filled with selected fillMode
3270 		const tcu::TextureFormat srcTcuFormat = mapVkFormat(srcImageParams.format);
3271 		m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, srcWidth, srcHeight, srcDepth));
3272 		generateBuffer(m_sourceTextureLevel->getAccess(), srcWidth, srcHeight, srcDepth, srcImageParams.fillMode);
3273 		uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), srcImageParams);
3274 	}
3275 
3276 	// generate destination image
3277 	if (isCompressedFormat(dstImageParams.format))
3278 	{
3279 		// compressed images are filled with random data
3280 		tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(dstImageParams.format);
3281 		m_destinationCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth, VK_FORMAT_UNDEFINED));
3282 		uploadCompressedImage(m_destination.get(), dstImageParams);
3283 	}
3284 	else
3285 	{
3286 		// non-compressed image is filled with white background
3287 		const tcu::TextureFormat dstTcuFormat = mapVkFormat(dstImageParams.format);
3288 		m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, dstWidth, dstHeight, dstDepth));
3289 		generateBuffer(m_destinationTextureLevel->getAccess(), dstWidth, dstHeight, dstDepth, dstImageParams.fillMode);
3290 		uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), dstImageParams);
3291 	}
3292 
3293 	generateExpectedResult();
3294 
3295 	// Barriers for copying images to buffer
3296 	const VkImageMemoryBarrier imageBarriers[]
3297 	{
3298 		{
3299 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3300 			DE_NULL,									// const void*				pNext;
3301 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
3302 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
3303 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
3304 			srcImageParams.operationLayout,				// VkImageLayout			newLayout;
3305 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3306 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3307 			m_source.get(),								// VkImage					image;
3308 			{											// VkImageSubresourceRange	subresourceRange;
3309 				getAspectFlags(srcImageParams.format),	//   VkImageAspectFlags		aspectMask;
3310 				0u,										//   deUint32				baseMipLevel;
3311 				1u,										//   deUint32				mipLevels;
3312 				0u,										//   deUint32				baseArraySlice;
3313 				1u										//   deUint32				arraySize;
3314 			}
3315 		},
3316 		{
3317 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3318 			DE_NULL,									// const void*				pNext;
3319 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
3320 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
3321 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
3322 			dstImageParams.operationLayout,				// VkImageLayout			newLayout;
3323 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3324 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3325 			m_destination.get(),						// VkImage					image;
3326 			{											// VkImageSubresourceRange	subresourceRange;
3327 				getAspectFlags(dstImageParams.format),	//   VkImageAspectFlags		aspectMask;
3328 				0u,										//   deUint32				baseMipLevel;
3329 				1u,										//   deUint32				mipLevels;
3330 				0u,										//   deUint32				baseArraySlice;
3331 				1u										//   deUint32				arraySize;
3332 			}
3333 		}
3334 	};
3335 
3336 	beginCommandBuffer(vk, *m_cmdBuffer);
3337 	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, 2, imageBarriers);
3338 
3339 	if (m_params.extensionUse == EXTENSION_USE_NONE)
3340 	{
3341 		vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), srcImageParams.operationLayout, m_destination.get(), dstImageParams.operationLayout, (deUint32)m_params.regions.size(), &regions[0], m_params.filter);
3342 	}
3343 	else
3344 	{
3345 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3346 		const VkBlitImageInfo2KHR blitImageInfo2KHR
3347 		{
3348 			VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
3349 			DE_NULL,									// const void*					pNext;
3350 			m_source.get(),								// VkImage						srcImage;
3351 			srcImageParams.operationLayout,				// VkImageLayout				srcImageLayout;
3352 			m_destination.get(),						// VkImage						dstImage;
3353 			dstImageParams.operationLayout,				// VkImageLayout				dstImageLayout;
3354 			(deUint32)m_params.regions.size(),			// uint32_t						regionCount;
3355 			&regions2KHR[0],							// const VkImageBlit2KHR*		pRegions;
3356 			m_params.filter,							// VkFilter						filter;
3357 		};
3358 		vk.cmdBlitImage2KHR(*m_cmdBuffer, &blitImageInfo2KHR);
3359 	}
3360 
3361 	endCommandBuffer(vk, *m_cmdBuffer);
3362 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
3363 
3364 	de::MovePtr<tcu::TextureLevel>	resultLevel		= readImage(*m_destination, dstImageParams);
3365 	tcu::PixelBufferAccess			resultAccess	= resultLevel->getAccess();
3366 
3367 	// if blit was done to a compressed format we need to decompress it to be able to verify it
3368 	if (m_destinationCompressedTexture)
3369 	{
3370 		deUint8* const					compressedDataSrc	(static_cast<deUint8*>(resultAccess.getDataPtr()));
3371 		const tcu::CompressedTexFormat	dstCompressedFormat (mapVkCompressedFormat(dstImageParams.format));
3372 		tcu::TextureLevel				decompressedLevel	(getUncompressedFormat(dstCompressedFormat), dstWidth, dstHeight, dstDepth);
3373 		tcu::PixelBufferAccess			decompressedAccess	(decompressedLevel.getAccess());
3374 
3375 		tcu::decompress(decompressedAccess, dstCompressedFormat, compressedDataSrc);
3376 
3377 		return checkTestResult(decompressedAccess);
3378 	}
3379 
3380 	return checkTestResult(resultAccess);
3381 }
3382 
calculateFloatConversionError(int srcBits)3383 static float calculateFloatConversionError (int srcBits)
3384 {
3385 	if (srcBits > 0)
3386 	{
3387 		const int	clampedBits	= de::clamp<int>(srcBits, 0, 32);
3388 		const float	srcMaxValue	= de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
3389 		const float	error		= 1.0f / srcMaxValue;
3390 
3391 		return de::clamp<float>(error, 0.0f, 1.0f);
3392 	}
3393 	else
3394 		return 1.0f;
3395 }
3396 
getFormatThreshold(const tcu::TextureFormat & format)3397 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
3398 {
3399 	tcu::Vec4 threshold(0.01f);
3400 
3401 	switch (format.type)
3402 	{
3403 	case tcu::TextureFormat::HALF_FLOAT:
3404 		threshold = tcu::Vec4(0.005f);
3405 		break;
3406 
3407 	case tcu::TextureFormat::FLOAT:
3408 	case tcu::TextureFormat::FLOAT64:
3409 		threshold = tcu::Vec4(0.001f);
3410 		break;
3411 
3412 	case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
3413 		threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
3414 		break;
3415 
3416 	case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
3417 		threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
3418 		break;
3419 
3420 	case tcu::TextureFormat::UNORM_INT_1010102_REV:
3421 		threshold = tcu::Vec4(0.002f, 0.002f, 0.002f, 0.3f);
3422 		break;
3423 
3424 	case tcu:: TextureFormat::UNORM_INT8:
3425 		threshold = tcu::Vec4(0.008f, 0.008f, 0.008f, 0.008f);
3426 		break;
3427 
3428 	default:
3429 		const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
3430 		threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
3431 				      calculateFloatConversionError(bits.y()),
3432 				      calculateFloatConversionError(bits.z()),
3433 				      calculateFloatConversionError(bits.w()));
3434 	}
3435 
3436 	// Return value matching the channel order specified by the format
3437 	if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
3438 		return threshold.swizzle(2, 1, 0, 3);
3439 	else
3440 		return threshold;
3441 }
3442 
getCompressedFormatThreshold(const tcu::CompressedTexFormat & format)3443 tcu::Vec4 getCompressedFormatThreshold(const tcu::CompressedTexFormat& format)
3444 {
3445 	bool		isSigned(false);
3446 	tcu::IVec4	bitDepth(0);
3447 
3448 	switch (format)
3449 	{
3450 	case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
3451 		bitDepth = { 7, 0, 0, 0 };
3452 		isSigned = true;
3453 		break;
3454 
3455 	case tcu::COMPRESSEDTEXFORMAT_EAC_R11:
3456 		bitDepth = { 8, 0, 0, 0 };
3457 		break;
3458 
3459 	case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
3460 		bitDepth = { 7, 7, 0, 0 };
3461 		isSigned = true;
3462 		break;
3463 
3464 	case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:
3465 		bitDepth = { 8, 8, 0, 0 };
3466 		break;
3467 
3468 	case tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8:
3469 	case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:
3470 	case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:
3471 		bitDepth = { 8, 8, 8, 0 };
3472 		break;
3473 
3474 	case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
3475 	case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
3476 		bitDepth = { 8, 8, 8, 1 };
3477 		break;
3478 
3479 	case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
3480 	case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
3481 	case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
3482 	case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
3483 	case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
3484 	case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
3485 	case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
3486 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
3487 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
3488 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
3489 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
3490 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
3491 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
3492 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
3493 	case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
3494 	case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
3495 	case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
3496 	case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
3497 	case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
3498 	case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
3499 	case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
3500 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
3501 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
3502 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
3503 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
3504 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
3505 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
3506 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
3507 	case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
3508 	case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
3509 		bitDepth = { 8, 8, 8, 8 };
3510 		break;
3511 
3512 	case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
3513 	case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
3514 	case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
3515 	case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
3516 	case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
3517 	case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
3518 		bitDepth = { 5, 6, 5, 0 };
3519 		break;
3520 
3521 	case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
3522 	case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
3523 	case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
3524 	case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
3525 		bitDepth = { 5, 5, 5, 1 };
3526 		break;
3527 
3528 	case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
3529 		bitDepth = { 7, 0, 0, 0 };
3530 		isSigned = true;
3531 		break;
3532 
3533 	case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
3534 		bitDepth = { 8, 0, 0, 0 };
3535 		break;
3536 
3537 	case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
3538 		bitDepth = { 7, 7, 0, 0 };
3539 		isSigned = true;
3540 		break;
3541 
3542 	case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
3543 		bitDepth = { 8, 8, 0, 0 };
3544 		break;
3545 
3546 	case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
3547 		return tcu::Vec4(0.01f);
3548 	case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
3549 		return tcu::Vec4(0.005f);
3550 
3551 	default:
3552 		DE_ASSERT(DE_FALSE);
3553 	}
3554 
3555 	const float	range = isSigned ? 1.0f - (-1.0f)
3556 								 : 1.0f - 0.0f;
3557 	tcu::Vec4 v;
3558 	for (int i = 0; i < 4; ++i)
3559 	{
3560 		if (bitDepth[i] == 0)
3561 			v[i] = 1.0f;
3562 		else
3563 			v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3564 	}
3565 	return v;
3566 }
3567 
checkNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedExpected,const tcu::ConstPixelBufferAccess & unclampedExpected,const tcu::TextureFormat & srcFormat)3568 bool BlittingImages::checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
3569 													const tcu::ConstPixelBufferAccess&	clampedExpected,
3570 													const tcu::ConstPixelBufferAccess&	unclampedExpected,
3571 													const tcu::TextureFormat&			srcFormat)
3572 {
3573 	tcu::TestLog&					log				(m_context.getTestContext().getLog());
3574 	const tcu::TextureFormat		dstFormat		= result.getFormat();
3575 	const tcu::TextureChannelClass	dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3576 	const tcu::TextureChannelClass	srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3577 	bool							isOk			= false;
3578 
3579 	log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3580 
3581 	// if either of srcImage or dstImage stores values as a signed/unsigned integer,
3582 	// the other must also store values a signed/unsigned integer
3583 	// e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3584 	// despite the fact that both formats are sampled as floats
3585 	bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3586 							  dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3587 	bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3588 							  srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3589 	if (dstImageIsIntClass != srcImageIsIntClass)
3590 	{
3591 		log << tcu::TestLog::EndSection;
3592 		return false;
3593 	}
3594 
3595 	if (isFloatFormat(dstFormat))
3596 	{
3597 		const bool		srcIsSRGB	= tcu::isSRGB(srcFormat);
3598 		const tcu::Vec4	srcMaxDiff	= getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
3599 		const tcu::Vec4	dstMaxDiff	= getFormatThreshold(dstFormat);
3600 		const tcu::Vec4	threshold	= ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
3601 
3602 		isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3603 		log << tcu::TestLog::EndSection;
3604 
3605 		if (!isOk)
3606 		{
3607 			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3608 			isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3609 			log << tcu::TestLog::EndSection;
3610 		}
3611 	}
3612 	else
3613 	{
3614 		tcu::UVec4	threshold;
3615 		// Calculate threshold depending on channel width of destination format.
3616 		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
3617 		const tcu::IVec4	srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
3618 		for (deUint32 i = 0; i < 4; ++i)
3619 			threshold[i] = 1 + de::max( ( ( 1 << dstBitDepth[i] ) - 1 ) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
3620 
3621 		isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3622 		log << tcu::TestLog::EndSection;
3623 
3624 		if (!isOk)
3625 		{
3626 			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3627 			isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3628 			log << tcu::TestLog::EndSection;
3629 		}
3630 	}
3631 
3632 	return isOk;
3633 }
3634 
checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedReference,const tcu::ConstPixelBufferAccess & unclampedReference,const tcu::CompressedTexFormat format)3635 bool BlittingImages::checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess&	result,
3636 															 const tcu::ConstPixelBufferAccess&	clampedReference,
3637 															 const tcu::ConstPixelBufferAccess&	unclampedReference,
3638 															 const tcu::CompressedTexFormat		format)
3639 {
3640 	tcu::TestLog&				log				= m_context.getTestContext().getLog();
3641 	const tcu::TextureFormat	dstFormat		= result.getFormat();
3642 
3643 	// there are rare cases wher one or few pixels have slightly bigger error
3644 	// in one of channels this accepted error allows those casses to pass
3645 	const tcu::Vec4				acceptedError	(0.04f);
3646 
3647 	const tcu::Vec4				srcMaxDiff		= getCompressedFormatThreshold(format);
3648 	const tcu::Vec4				dstMaxDiff		= m_destinationCompressedTexture ?
3649 													getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
3650 													getFormatThreshold(dstFormat);
3651 	const tcu::Vec4				threshold		= (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f) + acceptedError;
3652 
3653 	bool						filteredResultVerification(false);
3654 	tcu::Vec4					filteredResultMinValue(-6e6);
3655 	tcu::Vec4					filteredResultMaxValue(6e6);
3656 	tcu::TextureLevel			filteredResult;
3657 	tcu::TextureLevel			filteredClampedReference;
3658 	tcu::TextureLevel			filteredUnclampedReference;
3659 
3660 	if (((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
3661 		(format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)))
3662 	{
3663 		if ((dstFormat.type == tcu::TextureFormat::FLOAT) ||
3664 			(dstFormat.type == tcu::TextureFormat::HALF_FLOAT))
3665 		{
3666 			// for compressed formats we are using random data and for bc6h formats
3667 			// this will give us also large color values; when we are bliting to
3668 			// a format that accepts large values we can end up with large diferences
3669 			// betwean filtered result and reference; to avoid that we need to remove
3670 			// values that are to big from verification
3671 			filteredResultVerification	= true;
3672 			filteredResultMinValue		= tcu::Vec4(-10.0f);
3673 			filteredResultMaxValue		= tcu::Vec4( 10.0f);
3674 		}
3675 		else if (dstFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
3676 		{
3677 			// we need to clamp some formats to <0;1> range as it has
3678 			// small precision for big numbers compared to reference
3679 			filteredResultVerification	= true;
3680 			filteredResultMinValue		= tcu::Vec4(0.0f);
3681 			filteredResultMaxValue		= tcu::Vec4(1.0f);
3682 		}
3683 		// else don't use filtered verification
3684 	}
3685 
3686 	if (filteredResultVerification)
3687 	{
3688 		filteredResult.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3689 		tcu::PixelBufferAccess filteredResultAcccess(filteredResult.getAccess());
3690 
3691 		filteredClampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3692 		tcu::PixelBufferAccess filteredClampedAcccess(filteredClampedReference.getAccess());
3693 
3694 		filteredUnclampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3695 		tcu::PixelBufferAccess filteredUnclampedResultAcccess(filteredUnclampedReference.getAccess());
3696 
3697 		for (deInt32 z = 0; z < result.getDepth(); z++)
3698 		for (deInt32 y = 0; y < result.getHeight(); y++)
3699 		for (deInt32 x = 0; x < result.getWidth(); x++)
3700 		{
3701 			tcu::Vec4 resultTexel				= result.getPixel(x, y, z);
3702 			tcu::Vec4 clampedReferenceTexel		= clampedReference.getPixel(x, y, z);
3703 			tcu::Vec4 unclampedReferenceTexel	= unclampedReference.getPixel(x, y, z);
3704 
3705 			resultTexel				= tcu::clamp(resultTexel, filteredResultMinValue, filteredResultMaxValue);
3706 			clampedReferenceTexel	= tcu::clamp(clampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3707 			unclampedReferenceTexel	= tcu::clamp(unclampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3708 
3709 			filteredResultAcccess.setPixel(resultTexel, x, y, z);
3710 			filteredClampedAcccess.setPixel(clampedReferenceTexel, x, y, z);
3711 			filteredUnclampedResultAcccess.setPixel(unclampedReferenceTexel, x, y, z);
3712 		}
3713 	}
3714 
3715 	const tcu::ConstPixelBufferAccess clampedRef	= filteredResultVerification ? filteredClampedReference.getAccess() : clampedReference;
3716 	const tcu::ConstPixelBufferAccess res			= filteredResultVerification ? filteredResult.getAccess() : result;
3717 
3718 	log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3719 	bool isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3720 	log << tcu::TestLog::EndSection;
3721 
3722 	if (!isOk)
3723 	{
3724 		const tcu::ConstPixelBufferAccess unclampedRef = filteredResultVerification ? filteredUnclampedReference.getAccess() : unclampedReference;
3725 
3726 		log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3727 		isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3728 		log << tcu::TestLog::EndSection;
3729 	}
3730 
3731 	return isOk;
3732 }
3733 
3734 //! Utility to encapsulate coordinate computation and loops.
3735 struct CompareEachPixelInEachRegion
3736 {
~CompareEachPixelInEachRegionvkt::api::__anone7bc485d0111::CompareEachPixelInEachRegion3737 	virtual		 ~CompareEachPixelInEachRegion  (void) {}
3738 	virtual bool compare								(const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const = 0;
3739 
forEachvkt::api::__anone7bc485d0111::CompareEachPixelInEachRegion3740 	bool forEach (const void*							pUserData,
3741 				  const std::vector<CopyRegion>&		regions,
3742 				  const int								sourceWidth,
3743 				  const int								sourceHeight,
3744 				  const int								sourceDepth,
3745 				  const tcu::PixelBufferAccess&			errorMask) const
3746 	{
3747 		bool compareOk = true;
3748 
3749 		for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
3750 		{
3751 			const VkImageBlit& blit = regionIter->imageBlit;
3752 
3753 			const int	xStart	= deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3754 			const int	yStart	= deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3755 			const int	zStart	= deMin32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3756 			const int	xEnd	= deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3757 			const int	yEnd	= deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3758 			const int	zEnd	= deMax32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3759 			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);
3760 			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);
3761 			const float	zScale	= static_cast<float>(blit.srcOffsets[1].z - blit.srcOffsets[0].z) / static_cast<float>(blit.dstOffsets[1].z - blit.dstOffsets[0].z);
3762 			const float srcInvW	= 1.0f / static_cast<float>(sourceWidth);
3763 			const float srcInvH	= 1.0f / static_cast<float>(sourceHeight);
3764 			const float srcInvD	= 1.0f / static_cast<float>(sourceDepth);
3765 
3766 			for (int z = zStart; z < zEnd; z++)
3767 			for (int y = yStart; y < yEnd; y++)
3768 			for (int x = xStart; x < xEnd; x++)
3769 			{
3770 				const tcu::Vec3 srcNormCoord
3771 				(
3772 					(xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
3773 					(yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH,
3774 					(zScale * (static_cast<float>(z - blit.dstOffsets[0].z) + 0.5f) + static_cast<float>(blit.srcOffsets[0].z)) * srcInvD
3775 				);
3776 
3777 				if (!compare(pUserData, x, y, z, srcNormCoord))
3778 				{
3779 					errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
3780 					compareOk = false;
3781 				}
3782 			}
3783 		}
3784 		return compareOk;
3785 	}
3786 };
3787 
getFloatOrFixedPointFormatThreshold(const tcu::TextureFormat & format)3788 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
3789 {
3790 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
3791 	const tcu::IVec4				bitDepth		= tcu::getTextureFormatBitDepth(format);
3792 
3793 	if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
3794 	{
3795 		return getFormatThreshold(format);
3796 	}
3797 	else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
3798 			 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
3799 	{
3800 		const bool	isSigned	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
3801 		const float	range		= isSigned ? 1.0f - (-1.0f)
3802 										   : 1.0f -   0.0f;
3803 
3804 		tcu::Vec4 v;
3805 		for (int i = 0; i < 4; ++i)
3806 		{
3807 			if (bitDepth[i] == 0)
3808 				v[i] = 1.0f;
3809 			else
3810 				v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3811 		}
3812 		return v;
3813 	}
3814 	else
3815 	{
3816 		DE_ASSERT(0);
3817 		return tcu::Vec4();
3818 	}
3819 }
3820 
floatNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::Vec4 & sourceThreshold,const tcu::Vec4 & resultThreshold,const tcu::PixelBufferAccess & errorMask,const std::vector<CopyRegion> & regions)3821 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess&	source,
3822 							  const tcu::ConstPixelBufferAccess&	result,
3823 							  const tcu::Vec4&						sourceThreshold,
3824 							  const tcu::Vec4&						resultThreshold,
3825 							  const tcu::PixelBufferAccess&			errorMask,
3826 							  const std::vector<CopyRegion>&		regions)
3827 {
3828 	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);
3829 	const tcu::IVec4		dstBitDepth (tcu::getTextureFormatBitDepth(result.getFormat()));
3830 	tcu::LookupPrecision	precision;
3831 
3832 	precision.colorMask		 = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
3833 	precision.colorThreshold = tcu::max(sourceThreshold, resultThreshold);
3834 
3835 	const struct Capture
3836 	{
3837 		const tcu::ConstPixelBufferAccess&	source;
3838 		const tcu::ConstPixelBufferAccess&	result;
3839 		const tcu::Sampler&					sampler;
3840 		const tcu::LookupPrecision&			precision;
3841 		const bool							isSRGB;
3842 	} capture =
3843 	{
3844 		source, result, sampler, precision, tcu::isSRGB(result.getFormat())
3845 	};
3846 
3847 	const struct Loop : CompareEachPixelInEachRegion
3848 	{
3849 		Loop (void) {}
3850 
3851 		bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3852 		{
3853 			const Capture&					c					= *static_cast<const Capture*>(pUserData);
3854 			const tcu::TexLookupScaleMode	lookupScaleDontCare	= tcu::TEX_LOOKUP_SCALE_MINIFY;
3855 			tcu::Vec4						dstColor			= c.result.getPixel(x, y, z);
3856 
3857 			// TexLookupVerifier performs a conversion to linear space, so we have to as well
3858 			if (c.isSRGB)
3859 				dstColor = tcu::sRGBToLinear(dstColor);
3860 
3861 			return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3862 		}
3863 	} loop;
3864 
3865 	return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3866 }
3867 
intNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask,const std::vector<CopyRegion> & regions)3868 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess&	source,
3869 							const tcu::ConstPixelBufferAccess&	result,
3870 							const tcu::PixelBufferAccess&		errorMask,
3871 							const std::vector<CopyRegion>&		regions)
3872 {
3873 	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);
3874 	tcu::IntLookupPrecision	precision;
3875 
3876 	{
3877 		const tcu::IVec4	srcBitDepth	= tcu::getTextureFormatBitDepth(source.getFormat());
3878 		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(result.getFormat());
3879 
3880 		for (deUint32 i = 0; i < 4; ++i) {
3881 			precision.colorThreshold[i]	= de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
3882 			precision.colorMask[i]		= dstBitDepth[i] != 0;
3883 		}
3884 	}
3885 
3886 	// Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
3887 	// does the conversion on the fly without wasting memory, but this approach is more straightforward.
3888 	tcu::TextureLevel				convertedSourceTexture	(result.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
3889 	const tcu::PixelBufferAccess	convertedSource			= convertedSourceTexture.getAccess();
3890 
3891 	for (int z = 0; z < source.getDepth();	++z)
3892 	for (int y = 0; y < source.getHeight(); ++y)
3893 	for (int x = 0; x < source.getWidth();  ++x)
3894 		convertedSource.setPixel(source.getPixelInt(x, y, z), x, y, z);	// will be clamped to max. representable value
3895 
3896 	const struct Capture
3897 	{
3898 		const tcu::ConstPixelBufferAccess&	source;
3899 		const tcu::ConstPixelBufferAccess&	result;
3900 		const tcu::Sampler&					sampler;
3901 		const tcu::IntLookupPrecision&		precision;
3902 	} capture =
3903 	{
3904 		convertedSource, result, sampler, precision
3905 	};
3906 
3907 	const struct Loop : CompareEachPixelInEachRegion
3908 	{
3909 		Loop (void) {}
3910 
3911 		bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3912 		{
3913 			const Capture&					c					= *static_cast<const Capture*>(pUserData);
3914 			const tcu::TexLookupScaleMode	lookupScaleDontCare	= tcu::TEX_LOOKUP_SCALE_MINIFY;
3915 			const tcu::IVec4				dstColor			= c.result.getPixelInt(x, y, z);
3916 
3917 			return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3918 		}
3919 	} loop;
3920 
3921 	return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3922 }
3923 
checkNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source)3924 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
3925 												 const tcu::ConstPixelBufferAccess& source)
3926 {
3927 	tcu::TestLog&					log				(m_context.getTestContext().getLog());
3928 	const tcu::TextureFormat		dstFormat		= result.getFormat();
3929 	const tcu::TextureFormat		srcFormat		= source.getFormat();
3930 	const tcu::TextureChannelClass	dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3931 	const tcu::TextureChannelClass	srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3932 
3933 	tcu::TextureLevel		errorMaskStorage	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
3934 	tcu::PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
3935 	tcu::Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
3936 	tcu::Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
3937 	bool					ok					= false;
3938 
3939 	tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3940 
3941 	// if either of srcImage or dstImage stores values as a signed/unsigned integer,
3942 	// the other must also store values a signed/unsigned integer
3943 	// e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3944 	// despite the fact that both formats are sampled as floats
3945 	bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3946 							  dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3947 	bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3948 							  srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3949 	if (dstImageIsIntClass != srcImageIsIntClass)
3950 		return false;
3951 
3952 	if (dstImageIsIntClass)
3953 	{
3954 		ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
3955 	}
3956 	else
3957 	{
3958 		const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
3959 		const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
3960 		ok = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions);
3961 	}
3962 
3963 	if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
3964 		tcu::computePixelScaleBias(result, pixelScale, pixelBias);
3965 
3966 	if (!ok)
3967 	{
3968 		log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
3969 			<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3970 			<< tcu::TestLog::Image("ErrorMask",	"Error mask", errorMask)
3971 			<< tcu::TestLog::EndImageSet;
3972 	}
3973 	else
3974 	{
3975 		log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
3976 			<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3977 			<< tcu::TestLog::EndImageSet;
3978 	}
3979 
3980 	return ok;
3981 }
3982 
checkCompressedNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source,const tcu::CompressedTexFormat format)3983 bool BlittingImages::checkCompressedNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
3984 														   const tcu::ConstPixelBufferAccess&	source,
3985 														   const tcu::CompressedTexFormat		format)
3986 {
3987 	tcu::TestLog&				log					(m_context.getTestContext().getLog());
3988 	tcu::TextureFormat			errorMaskFormat		(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8);
3989 	tcu::TextureLevel			errorMaskStorage	(errorMaskFormat, result.getWidth(), result.getHeight(), result.getDepth());
3990 	tcu::PixelBufferAccess		errorMask			(errorMaskStorage.getAccess());
3991 	tcu::Vec4					pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
3992 	tcu::Vec4					pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
3993 	const tcu::TextureFormat&	resultFormat		(result.getFormat());
3994 	VkFormat					nativeResultFormat	(mapTextureFormat(resultFormat));
3995 
3996 	// there are rare cases wher one or few pixels have slightly bigger error
3997 	// in one of channels this accepted error allows those casses to pass
3998 	const tcu::Vec4				acceptedError		(0.04f);
3999 	const tcu::Vec4				srcMaxDiff			(acceptedError + getCompressedFormatThreshold(format));
4000 	const tcu::Vec4				dstMaxDiff			(acceptedError + (m_destinationCompressedTexture ?
4001 														getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
4002 														getFloatOrFixedPointFormatThreshold(resultFormat)));
4003 
4004 	tcu::TextureLevel			clampedSourceLevel;
4005 	bool						clampSource			(false);
4006 	tcu::Vec4					clampSourceMinValue	(-1.0f);
4007 	tcu::Vec4					clampSourceMaxValue	(1.0f);
4008 	tcu::TextureLevel			clampedResultLevel;
4009 	bool						clampResult			(false);
4010 
4011 	tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
4012 
4013 	if (resultFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4014 		tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4015 
4016 	log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4017 		<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias);
4018 
4019 	// for compressed formats source buffer access is not actual compressed format
4020 	// but equivalent uncompressed format that is some cases needs additional
4021 	// modifications so that sampling it will produce valid reference
4022 	if ((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
4023 		(format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK))
4024 	{
4025 		if (resultFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
4026 		{
4027 			// for compressed formats we are using random data and for some formats it
4028 			// can be outside of <-1;1> range - for cases where result is not a float
4029 			// format we need to clamp source to <-1;1> range as this will be done on
4030 			// the device but not in software sampler in framework
4031 			clampSource = true;
4032 			// for this format we also need to clamp the result as precision of
4033 			// this format is smaller then precision of calculations in framework;
4034 			// the biger color valus are the bigger errors can be
4035 			clampResult = true;
4036 
4037 			if (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)
4038 				clampSourceMinValue = tcu::Vec4(0.0f);
4039 		}
4040 		else if ((resultFormat.type != tcu::TextureFormat::FLOAT) &&
4041 				 (resultFormat.type != tcu::TextureFormat::HALF_FLOAT))
4042 		{
4043 			// clamp source for all non float formats
4044 			clampSource = true;
4045 		}
4046 	}
4047 
4048 	if (isUnormFormat(nativeResultFormat) || isUfloatFormat(nativeResultFormat))
4049 	{
4050 		// when tested compressed format is signed but the result format
4051 		// is unsigned we need to clamp source to <0; x> so that proper
4052 		// reference is calculated
4053 		if ((format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11) ||
4054 			(format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11) ||
4055 			(format == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK) ||
4056 			(format == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK) ||
4057 			(format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
4058 		{
4059 			clampSource			= true;
4060 			clampSourceMinValue	= tcu::Vec4(0.0f);
4061 		}
4062 	}
4063 
4064 	if (clampSource || clampResult)
4065 	{
4066 		if (clampSource)
4067 		{
4068 			clampedSourceLevel.setStorage(source.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
4069 			tcu::PixelBufferAccess clampedSourceAcccess(clampedSourceLevel.getAccess());
4070 
4071 			for (deInt32 z = 0; z < source.getDepth() ; z++)
4072 			for (deInt32 y = 0; y < source.getHeight() ; y++)
4073 			for (deInt32 x = 0; x < source.getWidth() ; x++)
4074 			{
4075 				tcu::Vec4 texel = source.getPixel(x, y, z);
4076 				texel = tcu::clamp(texel, tcu::Vec4(clampSourceMinValue), tcu::Vec4(clampSourceMaxValue));
4077 				clampedSourceAcccess.setPixel(texel, x, y, z);
4078 			}
4079 		}
4080 
4081 		if (clampResult)
4082 		{
4083 			clampedResultLevel.setStorage(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
4084 			tcu::PixelBufferAccess clampedResultAcccess(clampedResultLevel.getAccess());
4085 
4086 			for (deInt32 z = 0; z < result.getDepth() ; z++)
4087 			for (deInt32 y = 0; y < result.getHeight() ; y++)
4088 			for (deInt32 x = 0; x < result.getWidth() ; x++)
4089 			{
4090 				tcu::Vec4 texel = result.getPixel(x, y, z);
4091 				texel = tcu::clamp(texel, tcu::Vec4(-1.0f), tcu::Vec4(1.0f));
4092 				clampedResultAcccess.setPixel(texel, x, y, z);
4093 			}
4094 		}
4095 	}
4096 
4097 	const tcu::ConstPixelBufferAccess src = clampSource ? clampedSourceLevel.getAccess() : source;
4098 	const tcu::ConstPixelBufferAccess res = clampResult ? clampedResultLevel.getAccess() : result;
4099 
4100 	if (floatNearestBlitCompare(src, res, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions))
4101 	{
4102 		log << tcu::TestLog::EndImageSet;
4103 		return true;
4104 	}
4105 
4106 	log << tcu::TestLog::Image("ErrorMask",	"Error mask", errorMask)
4107 		<< tcu::TestLog::EndImageSet;
4108 	return false;
4109 }
4110 
checkTestResult(tcu::ConstPixelBufferAccess result)4111 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
4112 {
4113 	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
4114 	const std::string failMessage("Result image is incorrect");
4115 
4116 	if (m_params.filter != VK_FILTER_NEAREST)
4117 	{
4118 		if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4119 		{
4120 			if (tcu::hasDepthComponent(result.getFormat().order))
4121 			{
4122 				const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
4123 				const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
4124 				const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4125 				const tcu::ConstPixelBufferAccess		unclampedExpected	= tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4126 				const tcu::TextureFormat				sourceFormat		= tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4127 
4128 				if (!checkNonNearestFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
4129 					return tcu::TestStatus::fail(failMessage);
4130 			}
4131 
4132 			if (tcu::hasStencilComponent(result.getFormat().order))
4133 			{
4134 				const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
4135 				const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
4136 				const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4137 				const tcu::ConstPixelBufferAccess		unclampedExpected	= tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4138 				const tcu::TextureFormat				sourceFormat		= tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4139 
4140 				if (!checkNonNearestFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
4141 					return tcu::TestStatus::fail(failMessage);
4142 			}
4143 		}
4144 		else if (m_sourceCompressedTexture)
4145 		{
4146 			const tcu::CompressedTexture& compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4147 			if (!checkCompressedNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), compressedLevel.getFormat()))
4148 				return tcu::TestStatus::fail(failMessage);
4149 		}
4150 		else
4151 		{
4152 			const tcu::TextureFormat sourceFormat = mapVkFormat(m_params.src.image.format);
4153 			if (!checkNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
4154 				return tcu::TestStatus::fail(failMessage);
4155 		}
4156 	}
4157 	else // NEAREST filtering
4158 	{
4159 		if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4160 		{
4161 			if (tcu::hasDepthComponent(result.getFormat().order))
4162 			{
4163 				const tcu::Sampler::DepthStencilMode	mode			= tcu::Sampler::MODE_DEPTH;
4164 				const tcu::ConstPixelBufferAccess		depthResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
4165 				const tcu::ConstPixelBufferAccess		depthSource		= tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4166 
4167 				if (!checkNearestFilteredResult(depthResult, depthSource))
4168 					return tcu::TestStatus::fail(failMessage);
4169 			}
4170 
4171 			if (tcu::hasStencilComponent(result.getFormat().order))
4172 			{
4173 				const tcu::Sampler::DepthStencilMode	mode			= tcu::Sampler::MODE_STENCIL;
4174 				const tcu::ConstPixelBufferAccess		stencilResult	= tcu::getEffectiveDepthStencilAccess(result, mode);
4175 				const tcu::ConstPixelBufferAccess		stencilSource	= tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4176 
4177 				if (!checkNearestFilteredResult(stencilResult, stencilSource))
4178 					return tcu::TestStatus::fail(failMessage);
4179 			}
4180 		}
4181 		else if (m_sourceCompressedTexture)
4182 		{
4183 			const tcu::CompressedTexture& compressedLevel	= m_sourceCompressedTexture->getCompressedTexture();
4184 			const tcu::PixelBufferAccess& decompressedLevel	= m_sourceCompressedTexture->getDecompressedAccess();
4185 
4186 			if (!checkCompressedNearestFilteredResult(result, decompressedLevel, compressedLevel.getFormat()))
4187 				return tcu::TestStatus::fail(failMessage);
4188 		}
4189 		else if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
4190 			return tcu::TestStatus::fail(failMessage);
4191 	}
4192 
4193 	return tcu::TestStatus::pass("Pass");
4194 }
4195 
linearToSRGBIfNeeded(const tcu::TextureFormat & format,const tcu::Vec4 & color)4196 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
4197 {
4198 	return isSRGB(format) ? linearToSRGB(color) : color;
4199 }
4200 
scaleFromWholeSrcBuffer(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const VkOffset3D regionOffset,const VkOffset3D regionExtent,tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode=0u)4201 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = 0u)
4202 {
4203 	DE_ASSERT(filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4204 
4205 	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4206 					filter, filter, 0.0f, false);
4207 
4208 	float sX = (float)regionExtent.x / (float)dst.getWidth();
4209 	float sY = (float)regionExtent.y / (float)dst.getHeight();
4210 	float sZ = (float)regionExtent.z / (float)dst.getDepth();
4211 
4212 	for (int z = 0; z < dst.getDepth(); z++)
4213 	for (int y = 0; y < dst.getHeight(); y++)
4214 	for (int x = 0; x < dst.getWidth(); x++)
4215 	{
4216 		float srcX = ((mirrorMode & MIRROR_MODE_X) != 0) ? (float)regionExtent.x + (float)regionOffset.x - ((float)x+0.5f)*sX : (float)regionOffset.x + ((float)x+0.5f)*sX;
4217 		float srcY = ((mirrorMode & MIRROR_MODE_Y) != 0) ? (float)regionExtent.y + (float)regionOffset.y - ((float)y+0.5f)*sY : (float)regionOffset.y + ((float)y+0.5f)*sY;
4218 		float srcZ = ((mirrorMode & MIRROR_MODE_Z) != 0) ? (float)regionExtent.z + (float)regionOffset.z - ((float)z+0.5f)*sZ : (float)regionOffset.z + ((float)z+0.5f)*sZ;
4219 		if (dst.getDepth() > 1)
4220 			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, srcX, srcY, srcZ)), x, y, z);
4221 		else
4222 			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x, y);
4223 	}
4224 }
4225 
blit(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode)4226 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
4227 {
4228 	DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4229 
4230 	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4231 			filter, filter, 0.0f, false);
4232 
4233 	const float sX = (float)src.getWidth() / (float)dst.getWidth();
4234 	const float sY = (float)src.getHeight() / (float)dst.getHeight();
4235 	const float sZ = (float)src.getDepth() / (float)dst.getDepth();
4236 
4237 	const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
4238 	const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
4239 	const int zOffset = (mirrorMode & MIRROR_MODE_Z) ? dst.getDepth() - 1 : 0;
4240 
4241 	const int xScale = (mirrorMode & MIRROR_MODE_X) ? -1 : 1;
4242 	const int yScale = (mirrorMode & MIRROR_MODE_Y) ? -1 : 1;
4243 	const int zScale = (mirrorMode & MIRROR_MODE_Z) ? -1 : 1;
4244 
4245 	for (int z = 0; z < dst.getDepth(); ++z)
4246 	for (int y = 0; y < dst.getHeight(); ++y)
4247 	for (int x = 0; x < dst.getWidth(); ++x)
4248 	{
4249 		dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x + 0.5f) * sX, ((float)y + 0.5f) * sY, ((float)z + 0.5f) * sZ)), x * xScale + xOffset, y * yScale + yOffset, z * zScale + zOffset);
4250 	}
4251 }
4252 
flipCoordinates(CopyRegion & region,const MirrorMode mirrorMode)4253 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
4254 {
4255 	const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
4256 	const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
4257 	const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
4258 	const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
4259 
4260 	if (mirrorMode != 0u)
4261 	{
4262 		//sourceRegion
4263 		region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
4264 		region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
4265 		region.imageBlit.srcOffsets[0].z = std::min(srcOffset0.z, srcOffset1.z);
4266 
4267 		region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
4268 		region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
4269 		region.imageBlit.srcOffsets[1].z = std::max(srcOffset0.z, srcOffset1.z);
4270 
4271 		//destinationRegion
4272 		region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
4273 		region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
4274 		region.imageBlit.dstOffsets[0].z = std::min(dstOffset0.z, dstOffset1.z);
4275 
4276 		region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
4277 		region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
4278 		region.imageBlit.dstOffsets[1].z = std::max(dstOffset0.z, dstOffset1.z);
4279 	}
4280 }
4281 
4282 // Mirror X, Y and Z as required by the offset values in the 3 axes.
getMirrorMode(const VkOffset3D from,const VkOffset3D to)4283 MirrorMode getMirrorMode(const VkOffset3D from, const VkOffset3D to)
4284 {
4285 	MirrorMode mode = 0u;
4286 
4287 	if (from.x > to.x)
4288 		mode |= MIRROR_MODE_X;
4289 
4290 	if (from.y > to.y)
4291 		mode |= MIRROR_MODE_Y;
4292 
4293 	if (from.z > to.z)
4294 		mode |= MIRROR_MODE_Z;
4295 
4296 	return mode;
4297 }
4298 
4299 // Mirror the axes that are mirrored either in the source or destination, but not both.
getMirrorMode(const VkOffset3D s1,const VkOffset3D s2,const VkOffset3D d1,const VkOffset3D d2)4300 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
4301 {
4302 	static const MirrorModeBits kBits[] = { MIRROR_MODE_X, MIRROR_MODE_Y, MIRROR_MODE_Z };
4303 
4304 	const MirrorMode source		 = getMirrorMode(s1, s2);
4305 	const MirrorMode destination = getMirrorMode(d1, d2);
4306 
4307 	MirrorMode mode = 0u;
4308 
4309 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(kBits); ++i)
4310 	{
4311 		const MirrorModeBits bit = kBits[i];
4312 		if ((source & bit) != (destination & bit))
4313 			mode |= bit;
4314 	}
4315 
4316 	return mode;
4317 }
4318 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)4319 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
4320 {
4321 	DE_UNREF(mipLevel);
4322 
4323 	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
4324 												region.imageBlit.srcOffsets[1],
4325 												region.imageBlit.dstOffsets[0],
4326 												region.imageBlit.dstOffsets[1]);
4327 
4328 	flipCoordinates(region, mirrorMode);
4329 
4330 	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
4331 	const VkOffset3D					srcExtent		=
4332 	{
4333 		region.imageBlit.srcOffsets[1].x - srcOffset.x,
4334 		region.imageBlit.srcOffsets[1].y - srcOffset.y,
4335 		region.imageBlit.srcOffsets[1].z - srcOffset.z,
4336 	};
4337 	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
4338 	const VkOffset3D					dstExtent		=
4339 	{
4340 		region.imageBlit.dstOffsets[1].x - dstOffset.x,
4341 		region.imageBlit.dstOffsets[1].y - dstOffset.y,
4342 		region.imageBlit.dstOffsets[1].z - dstOffset.z,
4343 	};
4344 
4345 	tcu::Sampler::FilterMode		filter;
4346 	switch (m_params.filter)
4347 	{
4348 		case VK_FILTER_LINEAR:		filter = tcu::Sampler::LINEAR; break;
4349 		case VK_FILTER_CUBIC_EXT:	filter = tcu::Sampler::CUBIC;  break;
4350 		case VK_FILTER_NEAREST:
4351 		default:					filter = tcu::Sampler::NEAREST;  break;
4352 	}
4353 
4354 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
4355 	{
4356 		DE_ASSERT(src.getFormat() == dst.getFormat());
4357 
4358 		// Scale depth.
4359 		if (tcu::hasDepthComponent(src.getFormat().order))
4360 		{
4361 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_DEPTH);
4362 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
4363 			tcu::scale(dstSubRegion, srcSubRegion, filter);
4364 
4365 			if (filter != tcu::Sampler::NEAREST)
4366 			{
4367 				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
4368 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
4369 				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
4370 			}
4371 		}
4372 
4373 		// Scale stencil.
4374 		if (tcu::hasStencilComponent(src.getFormat().order))
4375 		{
4376 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_STENCIL);
4377 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
4378 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4379 
4380 			if (filter != tcu::Sampler::NEAREST)
4381 			{
4382 				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
4383 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
4384 				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
4385 			}
4386 		}
4387 	}
4388 	else
4389 	{
4390 		const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z);
4391 		const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4392 		blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4393 
4394 		if (filter != tcu::Sampler::NEAREST)
4395 		{
4396 			const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4397 			scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
4398 		}
4399 	}
4400 }
4401 
generateExpectedResult(void)4402 void BlittingImages::generateExpectedResult (void)
4403 {
4404 	const tcu::ConstPixelBufferAccess src = m_sourceCompressedTexture ? m_sourceCompressedTexture->getDecompressedAccess() : m_sourceTextureLevel->getAccess();
4405 	const tcu::ConstPixelBufferAccess dst = m_destinationCompressedTexture ? m_destinationCompressedTexture->getDecompressedAccess() : m_destinationTextureLevel->getAccess();
4406 
4407 	m_expectedTextureLevel[0]		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4408 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
4409 
4410 	if (m_params.filter != VK_FILTER_NEAREST)
4411 	{
4412 		m_unclampedExpectedTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4413 		tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
4414 	}
4415 
4416 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
4417 	{
4418 		CopyRegion region = m_params.regions[i];
4419 		copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
4420 	}
4421 }
4422 
uploadCompressedImage(const VkImage & image,const ImageParms & parms)4423 void BlittingImages::uploadCompressedImage (const VkImage& image, const ImageParms& parms)
4424 {
4425 	DE_ASSERT(m_sourceCompressedTexture);
4426 
4427 	const InstanceInterface&		vki					= m_context.getInstanceInterface();
4428 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
4429 	const VkPhysicalDevice			vkPhysDevice		= m_context.getPhysicalDevice();
4430 	const VkDevice					vkDevice			= m_context.getDevice();
4431 	const VkQueue					queue				= m_context.getUniversalQueue();
4432 	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
4433 	Allocator&						memAlloc			= m_context.getDefaultAllocator();
4434 	Move<VkBuffer>					buffer;
4435 	const deUint32					bufferSize			= m_sourceCompressedTexture->getCompressedTexture().getDataSize();
4436 	de::MovePtr<Allocation>			bufferAlloc;
4437 	const deUint32					arraySize			= getArraySize(parms);
4438 	const VkExtent3D				imageExtent
4439 	{
4440 		parms.extent.width,
4441 		(parms.imageType != VK_IMAGE_TYPE_1D) ? parms.extent.height : 1u,
4442 		(parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
4443 	};
4444 
4445 	// Create source buffer
4446 	{
4447 		const VkBufferCreateInfo bufferParams
4448 		{
4449 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
4450 			DE_NULL,									// const void*			pNext;
4451 			0u,											// VkBufferCreateFlags	flags;
4452 			bufferSize,									// VkDeviceSize			size;
4453 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
4454 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
4455 			1u,											// deUint32				queueFamilyIndexCount;
4456 			&queueFamilyIndex,							// const deUint32*		pQueueFamilyIndices;
4457 		};
4458 
4459 		buffer		= createBuffer(vk, vkDevice, &bufferParams);
4460 		bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
4461 		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
4462 	}
4463 
4464 	// Barriers for copying buffer to image
4465 	const VkBufferMemoryBarrier preBufferBarrier
4466 	{
4467 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
4468 		DE_NULL,										// const void*		pNext;
4469 		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
4470 		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
4471 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
4472 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
4473 		*buffer,										// VkBuffer			buffer;
4474 		0u,												// VkDeviceSize		offset;
4475 		bufferSize										// VkDeviceSize		size;
4476 	};
4477 
4478 	const VkImageMemoryBarrier preImageBarrier
4479 	{
4480 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
4481 		DE_NULL,										// const void*				pNext;
4482 		0u,												// VkAccessFlags			srcAccessMask;
4483 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
4484 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
4485 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
4486 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
4487 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
4488 		image,											// VkImage					image;
4489 		{												// VkImageSubresourceRange	subresourceRange;
4490 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspect;
4491 			0u,							// deUint32				baseMipLevel;
4492 			1u,							// deUint32				mipLevels;
4493 			0u,							// deUint32				baseArraySlice;
4494 			arraySize,					// deUint32				arraySize;
4495 		}
4496 	};
4497 
4498 	const VkImageMemoryBarrier postImageBarrier
4499 	{
4500 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
4501 		DE_NULL,										// const void*				pNext;
4502 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
4503 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
4504 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
4505 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
4506 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
4507 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
4508 		image,											// VkImage					image;
4509 		{												// VkImageSubresourceRange	subresourceRange;
4510 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspect;
4511 			0u,								// deUint32				baseMipLevel;
4512 			1u,								// deUint32				mipLevels;
4513 			0u,								// deUint32				baseArraySlice;
4514 			arraySize,						// deUint32				arraySize;
4515 		}
4516 	};
4517 
4518 	const VkExtent3D copyExtent
4519 	{
4520 		imageExtent.width,
4521 		imageExtent.height,
4522 		imageExtent.depth
4523 	};
4524 
4525 	VkBufferImageCopy copyRegion
4526 	{
4527 		0u,												// VkDeviceSize				bufferOffset;
4528 		copyExtent.width,								// deUint32					bufferRowLength;
4529 		copyExtent.height,								// deUint32					bufferImageHeight;
4530 		{
4531 			VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspect;
4532 			0u,												// deUint32				mipLevel;
4533 			0u,												// deUint32				baseArrayLayer;
4534 			arraySize,										// deUint32				layerCount;
4535 		},												// VkImageSubresourceLayers	imageSubresource;
4536 		{ 0, 0, 0 },									// VkOffset3D				imageOffset;
4537 		copyExtent										// VkExtent3D				imageExtent;
4538 	};
4539 
4540 	// Write buffer data
4541 	deMemcpy(bufferAlloc->getHostPtr(), m_sourceCompressedTexture->getCompressedTexture().getData(), bufferSize);
4542 	flushAlloc(vk, vkDevice, *bufferAlloc);
4543 
4544 	// Copy buffer to image
4545 	beginCommandBuffer(vk, *m_cmdBuffer);
4546 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
4547 						  1, &preBufferBarrier, 1, &preImageBarrier);
4548 	vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
4549 	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);
4550 	endCommandBuffer(vk, *m_cmdBuffer);
4551 
4552 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4553 }
4554 
4555 
4556 class BlitImageTestCase : public vkt::TestCase
4557 {
4558 public:
BlitImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)4559 							BlitImageTestCase		(tcu::TestContext&				testCtx,
4560 													 const std::string&				name,
4561 													 const std::string&				description,
4562 													 const TestParams				params)
4563 								: vkt::TestCase	(testCtx, name, description)
4564 								, m_params		(params)
4565 	{}
4566 
createInstance(Context & context) const4567 	virtual TestInstance*	createInstance			(Context&						context) const
4568 	{
4569 		return new BlittingImages(context, m_params);
4570 	}
4571 
checkSupport(Context & context) const4572 	virtual void			checkSupport			(Context&						context) const
4573 	{
4574 		VkImageFormatProperties properties;
4575 		if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4576 																					m_params.src.image.format,
4577 																					m_params.src.image.imageType,
4578 																					m_params.src.image.tiling,
4579 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
4580 																					0,
4581 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4582 		{
4583 			TCU_THROW(NotSupportedError, "Source format not supported");
4584 		}
4585 		if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4586 																					m_params.dst.image.format,
4587 																					m_params.dst.image.imageType,
4588 																					m_params.dst.image.tiling,
4589 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4590 																					0,
4591 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4592 		{
4593 			TCU_THROW(NotSupportedError, "Destination format not supported");
4594 		}
4595 
4596 		VkFormatProperties srcFormatProperties;
4597 		context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
4598 		VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ? srcFormatProperties.linearTilingFeatures : srcFormatProperties.optimalTilingFeatures;
4599 		if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
4600 		{
4601 			TCU_THROW(NotSupportedError, "Format feature blit source not supported");
4602 		}
4603 
4604 		VkFormatProperties dstFormatProperties;
4605 		context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
4606 		VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ? dstFormatProperties.linearTilingFeatures : dstFormatProperties.optimalTilingFeatures;
4607 		if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
4608 		{
4609 			TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
4610 		}
4611 
4612 		if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
4613 		{
4614 			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
4615 		}
4616 
4617 		if (m_params.filter == VK_FILTER_CUBIC_EXT)
4618 		{
4619 			context.requireDeviceFunctionality("VK_EXT_filter_cubic");
4620 
4621 			if (!(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
4622 			{
4623 				TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
4624 			}
4625 		}
4626 
4627 		if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
4628 		{
4629 			if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
4630 			{
4631 				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
4632 			}
4633 		}
4634 	}
4635 
4636 private:
4637 	TestParams				m_params;
4638 };
4639 
4640 class BlittingMipmaps : public CopiesAndBlittingTestInstance
4641 {
4642 public:
4643 										BlittingMipmaps					(Context&   context,
4644 																		 TestParams params);
4645 	virtual tcu::TestStatus				iterate							(void);
4646 protected:
4647 	virtual tcu::TestStatus				checkTestResult					(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
4648 	virtual void						copyRegionToTextureLevel		(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
4649 	virtual void						generateExpectedResult			(void);
4650 private:
4651 	bool								checkNonNearestFilteredResult	(void);
4652 	bool								checkNearestFilteredResult		(void);
4653 
4654 	Move<VkImage>						m_source;
4655 	de::MovePtr<Allocation>				m_sourceImageAlloc;
4656 	Move<VkImage>						m_destination;
4657 	de::MovePtr<Allocation>				m_destinationImageAlloc;
4658 
4659 	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel[16];
4660 };
4661 
BlittingMipmaps(Context & context,TestParams params)4662 BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params)
4663 	: CopiesAndBlittingTestInstance (context, params)
4664 {
4665 	const InstanceInterface&	vki					= context.getInstanceInterface();
4666 	const DeviceInterface&		vk					= context.getDeviceInterface();
4667 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
4668 	const VkDevice				vkDevice			= context.getDevice();
4669 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
4670 	Allocator&					memAlloc			= context.getDefaultAllocator();
4671 
4672 	// Create source image
4673 	{
4674 		const VkImageCreateInfo		sourceImageParams		=
4675 		{
4676 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
4677 			DE_NULL,								// const void*			pNext;
4678 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
4679 			m_params.src.image.imageType,			// VkImageType			imageType;
4680 			m_params.src.image.format,				// VkFormat				format;
4681 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
4682 			1u,										// deUint32				mipLevels;
4683 			getArraySize(m_params.src.image),		// deUint32				arraySize;
4684 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
4685 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
4686 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4687 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
4688 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
4689 			1u,										// deUint32				queueFamilyCount;
4690 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
4691 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
4692 		};
4693 
4694 		m_source = createImage(vk, vkDevice, &sourceImageParams);
4695 		m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
4696 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
4697 	}
4698 
4699 	// Create destination image
4700 	{
4701 		const VkImageCreateInfo		destinationImageParams  =
4702 		{
4703 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
4704 			DE_NULL,								// const void*			pNext;
4705 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
4706 			m_params.dst.image.imageType,			// VkImageType			imageType;
4707 			m_params.dst.image.format,				// VkFormat				format;
4708 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
4709 			m_params.mipLevels,						// deUint32				mipLevels;
4710 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
4711 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
4712 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
4713 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4714 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
4715 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
4716 			1u,										// deUint32				queueFamilyCount;
4717 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
4718 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
4719 		};
4720 
4721 		m_destination = createImage(vk, vkDevice, &destinationImageParams);
4722 		m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
4723 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
4724 	}
4725 }
4726 
iterate(void)4727 tcu::TestStatus BlittingMipmaps::iterate (void)
4728 {
4729 	const tcu::TextureFormat	srcTcuFormat		= mapVkFormat(m_params.src.image.format);
4730 	const tcu::TextureFormat	dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
4731 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
4732 																				m_params.src.image.extent.width,
4733 																				m_params.src.image.extent.height,
4734 																				m_params.src.image.extent.depth));
4735 	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, m_params.src.image.fillMode);
4736 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
4737 																						(int)m_params.dst.image.extent.width,
4738 																						(int)m_params.dst.image.extent.height,
4739 																						(int)m_params.dst.image.extent.depth));
4740 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.dst.image.fillMode);
4741 	generateExpectedResult();
4742 
4743 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
4744 
4745 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
4746 
4747 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
4748 	const VkDevice				vkDevice			= m_context.getDevice();
4749 	const VkQueue				queue				= m_context.getUniversalQueue();
4750 
4751 	std::vector<VkImageBlit>		regions;
4752 	std::vector<VkImageBlit2KHR>	regions2KHR;
4753 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
4754 	{
4755 		if (m_params.extensionUse == EXTENSION_USE_NONE)
4756 		{
4757 			regions.push_back(m_params.regions[i].imageBlit);
4758 		}
4759 		else
4760 		{
4761 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4762 			regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
4763 		}
4764 	}
4765 
4766 	// Copy source image to mip level 0 when generating mipmaps with multiple blit commands
4767 	if (!m_params.singleCommand)
4768 		uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
4769 
4770 	beginCommandBuffer(vk, *m_cmdBuffer);
4771 
4772 	// Blit all mip levels with a single blit command
4773 	if (m_params.singleCommand)
4774 	{
4775 		{
4776 			// Source image layout
4777 			const VkImageMemoryBarrier		srcImageBarrier		=
4778 			{
4779 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4780 				DE_NULL,									// const void*				pNext;
4781 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4782 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
4783 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
4784 				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
4785 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4786 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4787 				m_source.get(),								// VkImage					image;
4788 				{											// VkImageSubresourceRange	subresourceRange;
4789 					getAspectFlags(srcTcuFormat),		// VkImageAspectFlags   aspectMask;
4790 					0u,									// deUint32				baseMipLevel;
4791 					1u,									// deUint32				mipLevels;
4792 					0u,									// deUint32				baseArraySlice;
4793 					getArraySize(m_params.src.image)	// deUint32				arraySize;
4794 				}
4795 			};
4796 
4797 			// Destination image layout
4798 			const VkImageMemoryBarrier		dstImageBarrier		=
4799 			{
4800 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4801 				DE_NULL,									// const void*				pNext;
4802 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4803 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
4804 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
4805 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
4806 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4807 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4808 				m_destination.get(),						// VkImage					image;
4809 				{											// VkImageSubresourceRange	subresourceRange;
4810 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags   aspectMask;
4811 					0u,									// deUint32				baseMipLevel;
4812 					m_params.mipLevels,					// deUint32				mipLevels;
4813 					0u,									// deUint32				baseArraySlice;
4814 					getArraySize(m_params.dst.image)	// deUint32				arraySize;
4815 				}
4816 			};
4817 
4818 			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);
4819 			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);
4820 
4821 			if (m_params.extensionUse == EXTENSION_USE_NONE)
4822 			{
4823 				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);
4824 			}
4825 			else
4826 			{
4827 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4828 				const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4829 				{
4830 					VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
4831 					DE_NULL,									// const void*					pNext;
4832 					m_source.get(),								// VkImage						srcImage;
4833 					m_params.src.image.operationLayout,			// VkImageLayout				srcImageLayout;
4834 					m_destination.get(),						// VkImage						dstImage;
4835 					m_params.dst.image.operationLayout,			// VkImageLayout				dstImageLayout;
4836 					(deUint32)m_params.regions.size(),			// uint32_t						regionCount;
4837 					&regions2KHR[0],							// const VkImageBlit2KHR*		pRegions;
4838 					m_params.filter								// VkFilter						filter;
4839 				};
4840 				vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
4841 			}
4842 		}
4843 	}
4844 	// Blit mip levels with multiple blit commands
4845 	else
4846 	{
4847 		// Prepare all mip levels for reading
4848 		{
4849 			for (deUint32 barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
4850 			{
4851 				VkImageMemoryBarrier preImageBarrier =
4852 				{
4853 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType	sType;
4854 					DE_NULL,																// const void*		pNext;
4855 					VK_ACCESS_TRANSFER_WRITE_BIT,											// VkAccessFlags	srcAccessMask;
4856 					VK_ACCESS_TRANSFER_READ_BIT,											// VkAccessFlags	dstAccessMask;
4857 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,									// VkImageLayout	oldLayout;
4858 					m_params.src.image.operationLayout,										// VkImageLayout	newLayout;
4859 					VK_QUEUE_FAMILY_IGNORED,												// deUint32			srcQueueFamilyIndex;
4860 					VK_QUEUE_FAMILY_IGNORED,												// deUint32			dstQueueFamilyIndex;
4861 					m_destination.get(),													// VkImage			image;
4862 					{																		// VkImageSubresourceRange	subresourceRange;
4863 						getAspectFlags(dstTcuFormat),										// VkImageAspectFlags	aspectMask;
4864 							0u,																// deUint32				baseMipLevel;
4865 							VK_REMAINING_MIP_LEVELS,										// deUint32				mipLevels;
4866 							0u,																// deUint32				baseArraySlice;
4867 							getArraySize(m_params.src.image)								// deUint32				arraySize;
4868 					}
4869 				};
4870 
4871 				if (getArraySize(m_params.src.image) == 1)
4872 				{
4873 					DE_ASSERT(barrierno < m_params.mipLevels);
4874 					preImageBarrier.subresourceRange.baseMipLevel	= barrierno;
4875 					preImageBarrier.subresourceRange.levelCount		= (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
4876 				}
4877 				else
4878 				{
4879 					preImageBarrier.subresourceRange.baseArrayLayer	= barrierno;
4880 					preImageBarrier.subresourceRange.layerCount		= (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
4881 				}
4882 				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);
4883 			}
4884 		}
4885 
4886 		for (deUint32 regionNdx = 0u; regionNdx < (deUint32)m_params.regions.size(); regionNdx++)
4887 		{
4888 			const deUint32	mipLevel	= m_params.regions[regionNdx].imageBlit.dstSubresource.mipLevel;
4889 
4890 			// Prepare single mip level for writing
4891 			const VkImageMemoryBarrier		preImageBarrier		=
4892 			{
4893 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4894 				DE_NULL,									// const void*					pNext;
4895 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
4896 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
4897 				m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
4898 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
4899 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4900 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4901 				m_destination.get(),						// VkImage					image;
4902 				{											// VkImageSubresourceRange	subresourceRange;
4903 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
4904 					mipLevel,							// deUint32				baseMipLevel;
4905 					1u,									// deUint32				mipLevels;
4906 					0u,									// deUint32				baseArraySlice;
4907 					getArraySize(m_params.dst.image)	// deUint32				arraySize;
4908 				}
4909 			};
4910 
4911 			// Prepare single mip level for reading
4912 			const VkImageMemoryBarrier		postImageBarrier	=
4913 			{
4914 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4915 				DE_NULL,									// const void*				pNext;
4916 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4917 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
4918 				m_params.dst.image.operationLayout,			// VkImageLayout			oldLayout;
4919 				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
4920 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4921 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4922 				m_destination.get(),						// VkImage					image;
4923 				{											// VkImageSubresourceRange	subresourceRange;
4924 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
4925 					mipLevel,							// deUint32				baseMipLevel;
4926 					1u,									// deUint32				mipLevels;
4927 					0u,									// deUint32				baseArraySlice;
4928 					getArraySize(m_params.src.image)	// deUint32				arraySize;
4929 				}
4930 			};
4931 
4932 			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);
4933 
4934 			if (m_params.extensionUse == EXTENSION_USE_NONE)
4935 			{
4936 				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);
4937 			}
4938 			else
4939 			{
4940 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4941 				const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4942 				{
4943 					VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
4944 					DE_NULL,									// const void*					pNext;
4945 					m_destination.get(),						// VkImage						srcImage;
4946 					m_params.src.image.operationLayout,			// VkImageLayout				srcImageLayout;
4947 					m_destination.get(),						// VkImage						dstImage;
4948 					m_params.dst.image.operationLayout,			// VkImageLayout				dstImageLayout;
4949 					1u,											// uint32_t						regionCount;
4950 					&regions2KHR[regionNdx],					// const VkImageBlit2KHR*		pRegions;
4951 					m_params.filter								// VkFilter						filter;
4952 				};
4953 				vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
4954 			}
4955 
4956 			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);
4957 		}
4958 
4959 		// Prepare all mip levels for writing
4960 		{
4961 			const VkImageMemoryBarrier		postImageBarrier		=
4962 			{
4963 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4964 				DE_NULL,									// const void*				pNext;
4965 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
4966 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
4967 				m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
4968 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
4969 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4970 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4971 				m_destination.get(),						// VkImage					image;
4972 				{											// VkImageSubresourceRange	subresourceRange;
4973 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
4974 					0u,									// deUint32				baseMipLevel;
4975 					VK_REMAINING_MIP_LEVELS,			// deUint32				mipLevels;
4976 					0u,									// deUint32				baseArraySlice;
4977 					getArraySize(m_params.dst.image)	// deUint32				arraySize;
4978 				}
4979 			};
4980 
4981 			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);
4982 		}
4983 	}
4984 
4985 	endCommandBuffer(vk, *m_cmdBuffer);
4986 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4987 
4988 	return checkTestResult();
4989 }
4990 
checkNonNearestFilteredResult(void)4991 bool BlittingMipmaps::checkNonNearestFilteredResult (void)
4992 {
4993 	tcu::TestLog&				log				(m_context.getTestContext().getLog());
4994 	bool						allLevelsOk		= true;
4995 
4996 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
4997 	{
4998 		// Update reference results with previous results that have been verified.
4999 		// This needs to be done such that accumulated errors don't exceed the fixed threshold.
5000 		for (deUint32 i = 0; i < m_params.regions.size(); i++)
5001 		{
5002 			const CopyRegion region = m_params.regions[i];
5003 			const deUint32 srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
5004 			const deUint32 dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
5005 			de::MovePtr<tcu::TextureLevel>	prevResultLevel;
5006 			tcu::ConstPixelBufferAccess src;
5007 			if (srcMipLevel < mipLevelNdx)
5008 			{
5009 				// Generate expected result from rendered result that was previously verified
5010 				prevResultLevel	= readImage(*m_destination, m_params.dst.image, srcMipLevel);
5011 				src = prevResultLevel->getAccess();
5012 			}
5013 			else
5014 			{
5015 				// Previous reference mipmaps might have changed, so recompute expected result
5016 				src = m_expectedTextureLevel[srcMipLevel]->getAccess();
5017 			}
5018 			copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
5019 		}
5020 
5021 		de::MovePtr<tcu::TextureLevel>			resultLevel			= readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5022 		const tcu::ConstPixelBufferAccess&		resultAccess		= resultLevel->getAccess();
5023 
5024 		const tcu::Sampler::DepthStencilMode	mode				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::Sampler::MODE_DEPTH :
5025 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
5026 																																	tcu::Sampler::MODE_LAST;
5027 		const tcu::ConstPixelBufferAccess		result				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5028 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5029 																																	resultAccess;
5030 		const tcu::ConstPixelBufferAccess		clampedLevel		= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5031 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5032 																																	m_expectedTextureLevel[mipLevelNdx]->getAccess();
5033 		const tcu::ConstPixelBufferAccess		unclampedLevel		= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5034 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5035 																																	m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
5036 		const tcu::TextureFormat				srcFormat			= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5037 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5038 																																	mapVkFormat(m_params.src.image.format);
5039 
5040 		const tcu::TextureFormat				dstFormat			= result.getFormat();
5041 		bool									singleLevelOk		= false;
5042 		std::vector <CopyRegion>				mipLevelRegions;
5043 
5044 		for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5045 			if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5046 				mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5047 
5048 		log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
5049 
5050 		if (isFloatFormat(dstFormat))
5051 		{
5052 			const bool		srcIsSRGB   = tcu::isSRGB(srcFormat);
5053 			const tcu::Vec4 srcMaxDiff  = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
5054 			const tcu::Vec4 dstMaxDiff  = getFormatThreshold(dstFormat);
5055 			const tcu::Vec4 threshold   = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT)? 1.5f : 1.0f);
5056 
5057 			singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5058 			log << tcu::TestLog::EndSection;
5059 
5060 			if (!singleLevelOk)
5061 			{
5062 				log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5063 				singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5064 				log << tcu::TestLog::EndSection;
5065 			}
5066 		}
5067 		else
5068 		{
5069 			tcu::UVec4  threshold;
5070 			// Calculate threshold depending on channel width of destination format.
5071 			const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
5072 			const tcu::IVec4	srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
5073 			for (deUint32 i = 0; i < 4; ++i)
5074 				threshold[i] = 1 + de::max(((1 << dstBitDepth[i]) - 1) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
5075 
5076 			singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5077 			log << tcu::TestLog::EndSection;
5078 
5079 			if (!singleLevelOk)
5080 			{
5081 				log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5082 				singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5083 				log << tcu::TestLog::EndSection;
5084 			}
5085 		}
5086 		allLevelsOk &= singleLevelOk;
5087 	}
5088 
5089 	return allLevelsOk;
5090 }
5091 
checkNearestFilteredResult(void)5092 bool BlittingMipmaps::checkNearestFilteredResult (void)
5093 {
5094 	bool						allLevelsOk		= true;
5095 	tcu::TestLog&				log				(m_context.getTestContext().getLog());
5096 
5097 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5098 	{
5099 		de::MovePtr<tcu::TextureLevel>			resultLevel			= readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5100 		const tcu::ConstPixelBufferAccess&		resultAccess		= resultLevel->getAccess();
5101 
5102 		const tcu::Sampler::DepthStencilMode	mode				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::Sampler::MODE_DEPTH :
5103 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
5104 																																	tcu::Sampler::MODE_LAST;
5105 		const tcu::ConstPixelBufferAccess		result				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5106 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5107 																																	resultAccess;
5108 		const tcu::ConstPixelBufferAccess		source				= (m_params.singleCommand || mipLevelNdx == 0) ?			//  Read from source image
5109 																	  tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5110 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5111 																																	m_sourceTextureLevel->getAccess()
5112 																																//  Read from destination image
5113 																	: tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5114 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5115 																																	m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
5116 		const tcu::TextureFormat				dstFormat			= result.getFormat();
5117 		const tcu::TextureChannelClass			dstChannelClass		= tcu::getTextureChannelClass(dstFormat.type);
5118 		bool									singleLevelOk		= false;
5119 		std::vector <CopyRegion>				mipLevelRegions;
5120 
5121 		for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5122 			if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5123 				mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5124 
5125 		tcu::TextureLevel				errorMaskStorage	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
5126 		tcu::PixelBufferAccess			errorMask			= errorMaskStorage.getAccess();
5127 		tcu::Vec4						pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
5128 		tcu::Vec4						pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
5129 
5130 		tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
5131 
5132 		if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
5133 			dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
5134 		{
5135 			singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions);
5136 		}
5137 		else
5138 		{
5139 			const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
5140 			const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
5141 
5142 			singleLevelOk = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, mipLevelRegions);
5143 		}
5144 
5145 		if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
5146 			tcu::computePixelScaleBias(result, pixelScale, pixelBias);
5147 
5148 		if (!singleLevelOk)
5149 		{
5150 			log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5151 				<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5152 				<< tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
5153 				<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
5154 				<< tcu::TestLog::EndImageSet;
5155 		}
5156 		else
5157 		{
5158 			log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5159 				<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5160 				<< tcu::TestLog::EndImageSet;
5161 		}
5162 
5163 		allLevelsOk &= singleLevelOk;
5164 	}
5165 
5166 	return allLevelsOk;
5167 }
5168 
checkTestResult(tcu::ConstPixelBufferAccess result)5169 tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result)
5170 {
5171 	DE_UNREF(result);
5172 	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
5173 	const std::string failMessage("Result image is incorrect");
5174 
5175 	if (m_params.filter != VK_FILTER_NEAREST)
5176 	{
5177 		if (!checkNonNearestFilteredResult())
5178 			return tcu::TestStatus::fail(failMessage);
5179 	}
5180 	else // NEAREST filtering
5181 	{
5182 		if (!checkNearestFilteredResult())
5183 			return tcu::TestStatus::fail(failMessage);
5184 	}
5185 
5186 	return tcu::TestStatus::pass("Pass");
5187 }
5188 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)5189 void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
5190 {
5191 	DE_ASSERT(src.getDepth() == dst.getDepth());
5192 
5193 	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
5194 												region.imageBlit.srcOffsets[1],
5195 												region.imageBlit.dstOffsets[0],
5196 												region.imageBlit.dstOffsets[1]);
5197 
5198 	flipCoordinates(region, mirrorMode);
5199 
5200 	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
5201 	const VkOffset3D					srcExtent		=
5202 	{
5203 		region.imageBlit.srcOffsets[1].x - srcOffset.x,
5204 		region.imageBlit.srcOffsets[1].y - srcOffset.y,
5205 		region.imageBlit.srcOffsets[1].z - srcOffset.z
5206 	};
5207 	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
5208 	const VkOffset3D					dstExtent		=
5209 	{
5210 		region.imageBlit.dstOffsets[1].x - dstOffset.x,
5211 		region.imageBlit.dstOffsets[1].y - dstOffset.y,
5212 		region.imageBlit.dstOffsets[1].z - dstOffset.z
5213 	};
5214 
5215 	tcu::Sampler::FilterMode		filter;
5216 	switch (m_params.filter)
5217 	{
5218 	case VK_FILTER_LINEAR:		filter = tcu::Sampler::LINEAR; break;
5219 	case VK_FILTER_CUBIC_EXT:	filter = tcu::Sampler::CUBIC;  break;
5220 	case VK_FILTER_NEAREST:
5221 	default:					filter = tcu::Sampler::NEAREST;  break;
5222 	}
5223 
5224 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
5225 	{
5226 		DE_ASSERT(src.getFormat() == dst.getFormat());
5227 		// Scale depth.
5228 		if (tcu::hasDepthComponent(src.getFormat().order))
5229 		{
5230 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
5231 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5232 			tcu::scale(dstSubRegion, srcSubRegion, filter);
5233 
5234 			if (filter != tcu::Sampler::NEAREST)
5235 			{
5236 				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
5237 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5238 				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
5239 			}
5240 		}
5241 
5242 		// Scale stencil.
5243 		if (tcu::hasStencilComponent(src.getFormat().order))
5244 		{
5245 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
5246 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5247 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5248 
5249 			if (filter != tcu::Sampler::NEAREST)
5250 			{
5251 				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
5252 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5253 				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
5254 			}
5255 		}
5256 	}
5257 	else
5258 	{
5259 		for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
5260 		{
5261 			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
5262 			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5263 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5264 
5265 			if (filter != tcu::Sampler::NEAREST)
5266 			{
5267 				const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5268 				scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
5269 			}
5270 		}
5271 	}
5272 }
5273 
generateExpectedResult(void)5274 void BlittingMipmaps::generateExpectedResult (void)
5275 {
5276 	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
5277 	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
5278 
5279 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5280 		m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5281 
5282 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
5283 
5284 	if (m_params.filter != VK_FILTER_NEAREST)
5285 	{
5286 		for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5287 			m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5288 
5289 		tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
5290 	}
5291 
5292 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
5293 	{
5294 		CopyRegion region = m_params.regions[i];
5295 		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);
5296 	}
5297 }
5298 
5299 class BlitMipmapTestCase : public vkt::TestCase
5300 {
5301 public:
BlitMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)5302 							BlitMipmapTestCase		(tcu::TestContext&				testCtx,
5303 													 const std::string&				name,
5304 													 const std::string&				description,
5305 													 const TestParams				params)
5306 								: vkt::TestCase	(testCtx, name, description)
5307 								, m_params		(params)
5308 	{}
5309 
createInstance(Context & context) const5310 	virtual TestInstance*	createInstance			(Context&						context) const
5311 	{
5312 		return new BlittingMipmaps(context, m_params);
5313 	}
5314 
checkSupport(Context & context) const5315 	virtual void			checkSupport			(Context&						context) const
5316 	{
5317 		const InstanceInterface&	vki					= context.getInstanceInterface();
5318 		const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
5319 		{
5320 			VkImageFormatProperties	properties;
5321 			if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5322 																						m_params.src.image.format,
5323 																						VK_IMAGE_TYPE_2D,
5324 																						VK_IMAGE_TILING_OPTIMAL,
5325 																						VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
5326 																						0,
5327 																						&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5328 			{
5329 				TCU_THROW(NotSupportedError, "Format not supported");
5330 			}
5331 			else if ((m_params.src.image.extent.width	> properties.maxExtent.width)	||
5332 						(m_params.src.image.extent.height	> properties.maxExtent.height)	||
5333 						(m_params.src.image.extent.depth	> properties.maxArrayLayers))
5334 			{
5335 				TCU_THROW(NotSupportedError, "Image size not supported");
5336 			}
5337 		}
5338 
5339 		{
5340 			VkImageFormatProperties	properties;
5341 			if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5342 																						m_params.dst.image.format,
5343 																						VK_IMAGE_TYPE_2D,
5344 																						VK_IMAGE_TILING_OPTIMAL,
5345 																						VK_IMAGE_USAGE_TRANSFER_DST_BIT,
5346 																						0,
5347 																						&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5348 			{
5349 				TCU_THROW(NotSupportedError, "Format not supported");
5350 			}
5351 			else if ((m_params.dst.image.extent.width	> properties.maxExtent.width)	||
5352 						(m_params.dst.image.extent.height	> properties.maxExtent.height)	||
5353 						(m_params.dst.image.extent.depth	> properties.maxArrayLayers))
5354 			{
5355 				TCU_THROW(NotSupportedError, "Image size not supported");
5356 			}
5357 			else if (m_params.mipLevels > properties.maxMipLevels)
5358 			{
5359 				TCU_THROW(NotSupportedError, "Number of mip levels not supported");
5360 			}
5361 			else if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)	&&
5362 					 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
5363 			{
5364 				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
5365 			}
5366 		}
5367 
5368 		const VkFormatProperties	srcFormatProperties	= getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format);
5369 		if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
5370 		{
5371 			TCU_THROW(NotSupportedError, "Format feature blit source not supported");
5372 		}
5373 
5374 		const VkFormatProperties	dstFormatProperties	= getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format);
5375 		if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
5376 		{
5377 			TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
5378 		}
5379 
5380 		if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
5381 			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
5382 
5383 		if (m_params.filter == VK_FILTER_CUBIC_EXT)
5384 		{
5385 			context.requireDeviceFunctionality("VK_EXT_filter_cubic");
5386 
5387 			if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
5388 			{
5389 				TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
5390 			}
5391 		}
5392 	}
5393 
5394 private:
5395 	TestParams				m_params;
5396 };
5397 
5398 // Resolve image to image.
5399 
5400 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION,
5401 								COPY_MS_IMAGE_TO_MS_IMAGE,
5402 								COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE,
5403 								COPY_MS_IMAGE_LAYER_TO_MS_IMAGE,
5404 								COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION,
5405 								COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB};
5406 class ResolveImageToImage : public CopiesAndBlittingTestInstance
5407 {
5408 public:
5409 												ResolveImageToImage				(Context&							context,
5410 																				 TestParams							params,
5411 																				 const ResolveImageToImageOptions	options);
5412 	virtual tcu::TestStatus						iterate							(void);
shouldVerifyIntermediateResults(ResolveImageToImageOptions option)5413 	static inline bool							shouldVerifyIntermediateResults	(ResolveImageToImageOptions option)
5414 	{
5415 		return option == COPY_MS_IMAGE_TO_MS_IMAGE || option == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE || option == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE;
5416 	}
5417 protected:
5418 	virtual tcu::TestStatus						checkTestResult					(tcu::ConstPixelBufferAccess result);
5419 	void										copyMSImageToMSImage			(deUint32 copyArraySize);
5420 	tcu::TestStatus								checkIntermediateCopy			(void);
5421 private:
5422 	Move<VkImage>								m_multisampledImage;
5423 	de::MovePtr<Allocation>						m_multisampledImageAlloc;
5424 
5425 	Move<VkImage>								m_destination;
5426 	de::MovePtr<Allocation>						m_destinationImageAlloc;
5427 
5428 	Move<VkImage>								m_multisampledCopyImage;
5429 	de::MovePtr<Allocation>						m_multisampledCopyImageAlloc;
5430 	Move<VkImage>								m_multisampledCopyNoCabImage;
5431 	de::MovePtr<Allocation>						m_multisampledCopyImageNoCabAlloc;
5432 
5433 	const ResolveImageToImageOptions			m_options;
5434 
5435 	virtual void								copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess	src,
5436 																			 tcu::PixelBufferAccess			dst,
5437 																			 CopyRegion						region,
5438 																			 deUint32						mipLevel = 0u);
5439 };
5440 
ResolveImageToImage(Context & context,TestParams params,const ResolveImageToImageOptions options)5441 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
5442 	: CopiesAndBlittingTestInstance	(context, params)
5443 	, m_options						(options)
5444 {
5445 	const InstanceInterface&	vki						= m_context.getInstanceInterface();
5446 	const DeviceInterface&		vk						= m_context.getDeviceInterface();
5447 	const VkPhysicalDevice		vkPhysDevice			= m_context.getPhysicalDevice();
5448 	const VkDevice				vkDevice				= m_context.getDevice();
5449 	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
5450 	Allocator&					memAlloc				= m_context.getDefaultAllocator();
5451 
5452 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
5453 	Move<VkRenderPass>			renderPass;
5454 
5455 	Move<VkShaderModule>		vertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
5456 	Move<VkShaderModule>		fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
5457 	std::vector<tcu::Vec4>		vertices;
5458 
5459 	Move<VkBuffer>				vertexBuffer;
5460 	de::MovePtr<Allocation>		vertexBufferAlloc;
5461 
5462 	Move<VkPipelineLayout>		pipelineLayout;
5463 	Move<VkPipeline>			graphicsPipeline;
5464 
5465 	const VkSampleCountFlagBits	rasterizationSamples	= m_params.samples;
5466 
5467 	// Create color image.
5468 	{
5469 		VkImageCreateInfo	colorImageParams	=
5470 		{
5471 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
5472 			DE_NULL,																// const void*				pNext;
5473 			getCreateFlags(m_params.src.image),										// VkImageCreateFlags		flags;
5474 			m_params.src.image.imageType,											// VkImageType				imageType;
5475 			m_params.src.image.format,												// VkFormat					format;
5476 			getExtent3D(m_params.src.image),										// VkExtent3D				extent;
5477 			1u,																		// deUint32					mipLevels;
5478 			getArraySize(m_params.src.image),										// deUint32					arrayLayers;
5479 			rasterizationSamples,													// VkSampleCountFlagBits	samples;
5480 			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
5481 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT										// VkImageUsageFlags		usage;
5482 				| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
5483 				| VK_IMAGE_USAGE_TRANSFER_DST_BIT
5484 				| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
5485 			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
5486 			1u,																		// deUint32					queueFamilyIndexCount;
5487 			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
5488 			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout			initialLayout;
5489 		};
5490 
5491 		m_multisampledImage						= createImage(vk, vkDevice, &colorImageParams);
5492 
5493 		// Allocate and bind color image memory.
5494 		m_multisampledImageAlloc				= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5495 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset()));
5496 
5497 		switch (m_options)
5498 		{
5499 			case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
5500 			case COPY_MS_IMAGE_TO_MS_IMAGE:
5501 			{
5502 				colorImageParams.usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5503 				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
5504 				// Allocate and bind color image memory.
5505 				m_multisampledCopyImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5506 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5507 				break;
5508 			}
5509 			case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
5510 			case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
5511 			{
5512 				colorImageParams.usage			= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5513 				colorImageParams.arrayLayers	= getArraySize(m_params.dst.image);
5514 				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
5515 				// Allocate and bind color image memory.
5516 				m_multisampledCopyImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5517 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5518 				break;
5519 			}
5520 			case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
5521 			{
5522 				colorImageParams.usage				= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5523 				colorImageParams.arrayLayers		= getArraySize(m_params.dst.image);
5524 				m_multisampledCopyImage				= createImage(vk, vkDevice, &colorImageParams);
5525 				m_multisampledCopyNoCabImage		= createImage(vk, vkDevice, &colorImageParams);
5526 				// Allocate and bind color image memory.
5527 				m_multisampledCopyImageAlloc			= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5528 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5529 				m_multisampledCopyImageNoCabAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyNoCabImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5530 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyNoCabImage, m_multisampledCopyImageNoCabAlloc->getMemory(), m_multisampledCopyImageNoCabAlloc->getOffset()));
5531 				break;
5532 			}
5533 
5534 			default :
5535 				break;
5536 		}
5537 	}
5538 
5539 	// Create destination image.
5540 	{
5541 		const VkImageCreateInfo	destinationImageParams	=
5542 		{
5543 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
5544 			DE_NULL,								// const void*			pNext;
5545 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
5546 			m_params.dst.image.imageType,			// VkImageType			imageType;
5547 			m_params.dst.image.format,				// VkFormat				format;
5548 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
5549 			1u,										// deUint32				mipLevels;
5550 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
5551 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
5552 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
5553 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
5554 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
5555 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
5556 			1u,										// deUint32				queueFamilyCount;
5557 			&queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
5558 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
5559 		};
5560 
5561 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
5562 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5563 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
5564 	}
5565 
5566 	// Barriers for image clearing.
5567 	std::vector<VkImageMemoryBarrier> srcImageBarriers;
5568 
5569 	const VkImageMemoryBarrier m_multisampledImageBarrier =
5570 	{
5571 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5572 		DE_NULL,									// const void*				pNext;
5573 		0u,											// VkAccessFlags			srcAccessMask;
5574 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
5575 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
5576 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
5577 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5578 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5579 		m_multisampledImage.get(),					// VkImage					image;
5580 		{											// VkImageSubresourceRange	subresourceRange;
5581 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
5582 			0u,										// deUint32				baseMipLevel;
5583 			1u,										// deUint32				mipLevels;
5584 			0u,										// deUint32				baseArraySlice;
5585 			getArraySize(m_params.src.image)		// deUint32				arraySize;
5586 		}
5587 	};
5588 	const VkImageMemoryBarrier m_multisampledCopyImageBarrier =
5589 	{
5590 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5591 		DE_NULL,									// const void*				pNext;
5592 		0u,											// VkAccessFlags			srcAccessMask;
5593 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
5594 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
5595 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
5596 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5597 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5598 		m_multisampledCopyImage.get(),				// VkImage					image;
5599 		{											// VkImageSubresourceRange	subresourceRange;
5600 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
5601 			0u,										// deUint32				baseMipLevel;
5602 			1u,										// deUint32				mipLevels;
5603 			0u,										// deUint32				baseArraySlice;
5604 			getArraySize(m_params.dst.image)		// deUint32				arraySize;
5605 		}
5606 	};
5607 	const VkImageMemoryBarrier m_multisampledCopyImageNoCabBarrier =
5608 	{
5609 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5610 		DE_NULL,									// const void*				pNext;
5611 		0u,											// VkAccessFlags			srcAccessMask;
5612 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
5613 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
5614 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
5615 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5616 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5617 		m_multisampledCopyNoCabImage.get(),			// VkImage					image;
5618 		{											// VkImageSubresourceRange	subresourceRange;
5619 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
5620 			0u,										// deUint32				baseMipLevel;
5621 			1u,										// deUint32				mipLevels;
5622 			0u,										// deUint32				baseArraySlice;
5623 			getArraySize(m_params.dst.image)		// deUint32				arraySize;
5624 		}
5625 	};
5626 
5627 	// Only use one barrier if no options have been given.
5628 	if (m_options != DE_NULL)
5629 	{
5630 		srcImageBarriers.push_back(m_multisampledImageBarrier);
5631 		srcImageBarriers.push_back(m_multisampledCopyImageBarrier);
5632 		// Add the third barrier if option is as below.
5633 		if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
5634 			srcImageBarriers.push_back(m_multisampledCopyImageNoCabBarrier);
5635 	}
5636 	else
5637 	{
5638 		srcImageBarriers.push_back(m_multisampledImageBarrier);
5639 	}
5640 
5641 	// Create render pass.
5642 	{
5643 		const VkAttachmentDescription	attachmentDescriptions[1]	=
5644 		{
5645 			{
5646 				0u,											// VkAttachmentDescriptionFlags		flags;
5647 				m_params.src.image.format,					// VkFormat							format;
5648 				rasterizationSamples,						// VkSampleCountFlagBits			samples;
5649 				VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp				loadOp;
5650 				VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp;
5651 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp;
5652 				VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp;
5653 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout					initialLayout;
5654 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL		// VkImageLayout					finalLayout;
5655 			},
5656 		};
5657 
5658 		const VkAttachmentReference		colorAttachmentReference	=
5659 		{
5660 			0u,													// deUint32			attachment;
5661 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
5662 		};
5663 
5664 		const VkSubpassDescription		subpassDescription			=
5665 		{
5666 			0u,									// VkSubpassDescriptionFlags	flags;
5667 			VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint			pipelineBindPoint;
5668 			0u,									// deUint32						inputAttachmentCount;
5669 			DE_NULL,							// const VkAttachmentReference*	pInputAttachments;
5670 			1u,									// deUint32						colorAttachmentCount;
5671 			&colorAttachmentReference,			// const VkAttachmentReference*	pColorAttachments;
5672 			DE_NULL,							// const VkAttachmentReference*	pResolveAttachments;
5673 			DE_NULL,							// const VkAttachmentReference*	pDepthStencilAttachment;
5674 			0u,									// deUint32						preserveAttachmentCount;
5675 			DE_NULL								// const VkAttachmentReference*	pPreserveAttachments;
5676 		};
5677 
5678 		const VkRenderPassCreateInfo	renderPassParams			=
5679 		{
5680 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType					sType;
5681 			DE_NULL,									// const void*						pNext;
5682 			0u,											// VkRenderPassCreateFlags			flags;
5683 			1u,											// deUint32							attachmentCount;
5684 			attachmentDescriptions,						// const VkAttachmentDescription*	pAttachments;
5685 			1u,											// deUint32							subpassCount;
5686 			&subpassDescription,						// const VkSubpassDescription*		pSubpasses;
5687 			0u,											// deUint32							dependencyCount;
5688 			DE_NULL										// const VkSubpassDependency*		pDependencies;
5689 		};
5690 
5691 		renderPass	= createRenderPass(vk, vkDevice, &renderPassParams);
5692 	}
5693 
5694 	// Create pipeline layout
5695 	{
5696 		const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
5697 		{
5698 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
5699 			DE_NULL,											// const void*						pNext;
5700 			0u,													// VkPipelineLayoutCreateFlags		flags;
5701 			0u,													// deUint32							setLayoutCount;
5702 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
5703 			0u,													// deUint32							pushConstantRangeCount;
5704 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
5705 		};
5706 
5707 		pipelineLayout	= createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
5708 	}
5709 
5710 	// Create upper half triangle.
5711 	{
5712 		const tcu::Vec4	a	(-1.0, -1.0, 0.0, 1.0);
5713 		const tcu::Vec4	b	(1.0, -1.0, 0.0, 1.0);
5714 		const tcu::Vec4	c	(1.0, 1.0, 0.0, 1.0);
5715 		// Add triangle.
5716 		vertices.push_back(a);
5717 		vertices.push_back(c);
5718 		vertices.push_back(b);
5719 	}
5720 
5721 	// Create vertex buffer.
5722 	{
5723 		const VkDeviceSize			vertexDataSize		= vertices.size() * sizeof(tcu::Vec4);
5724 		const VkBufferCreateInfo	vertexBufferParams	=
5725 		{
5726 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
5727 			DE_NULL,									// const void*			pNext;
5728 			0u,											// VkBufferCreateFlags	flags;
5729 			vertexDataSize,								// VkDeviceSize			size;
5730 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
5731 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
5732 			1u,											// deUint32				queueFamilyIndexCount;
5733 			&queueFamilyIndex							// const deUint32*		pQueueFamilyIndices;
5734 		};
5735 
5736 		vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
5737 		vertexBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
5738 		VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
5739 
5740 		// Load vertices into vertex buffer.
5741 		deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
5742 		flushAlloc(vk, vkDevice, *vertexBufferAlloc);
5743 	}
5744 
5745 	{
5746 		Move<VkFramebuffer>		framebuffer;
5747 		Move<VkImageView>		sourceAttachmentView;
5748 
5749 		uint32_t baseArrayLayer = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : 0u;
5750 
5751 		// Create color attachment view.
5752 		{
5753 			const VkImageViewCreateInfo	colorAttachmentViewParams	=
5754 			{
5755 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,					// VkStructureType			sType;
5756 				DE_NULL,													// const void*				pNext;
5757 				0u,															// VkImageViewCreateFlags	flags;
5758 				*m_multisampledImage,										// VkImage					image;
5759 				VK_IMAGE_VIEW_TYPE_2D,										// VkImageViewType			viewType;
5760 				m_params.src.image.format,									// VkFormat					format;
5761 				componentMappingRGBA,										// VkComponentMapping		components;
5762 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, baseArrayLayer, 1u }	// VkImageSubresourceRange	subresourceRange;
5763 			};
5764 			sourceAttachmentView	= createImageView(vk, vkDevice, &colorAttachmentViewParams);
5765 		}
5766 
5767 		// Create framebuffer
5768 		{
5769 			const VkImageView				attachments[1]		=
5770 			{
5771 					*sourceAttachmentView,
5772 			};
5773 
5774 			const VkFramebufferCreateInfo	framebufferParams	=
5775 			{
5776 					VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
5777 					DE_NULL,											// const void*					pNext;
5778 					0u,													// VkFramebufferCreateFlags		flags;
5779 					*renderPass,										// VkRenderPass					renderPass;
5780 					1u,													// deUint32						attachmentCount;
5781 					attachments,										// const VkImageView*			pAttachments;
5782 					m_params.src.image.extent.width,					// deUint32						width;
5783 					m_params.src.image.extent.height,					// deUint32						height;
5784 					1u													// deUint32						layers;
5785 			};
5786 
5787 			framebuffer	= createFramebuffer(vk, vkDevice, &framebufferParams);
5788 		}
5789 
5790 		// Create pipeline
5791 		{
5792 			const std::vector<VkViewport>	viewports	(1, makeViewport(m_params.src.image.extent));
5793 			const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_params.src.image.extent));
5794 
5795 			const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
5796 			{
5797 				VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
5798 				DE_NULL,													// const void*								pNext;
5799 				0u,															// VkPipelineMultisampleStateCreateFlags	flags;
5800 				rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
5801 				VK_FALSE,													// VkBool32									sampleShadingEnable;
5802 				0.0f,														// float									minSampleShading;
5803 				DE_NULL,													// const VkSampleMask*						pSampleMask;
5804 				VK_FALSE,													// VkBool32									alphaToCoverageEnable;
5805 				VK_FALSE													// VkBool32									alphaToOneEnable;
5806 			};
5807 
5808 			graphicsPipeline = makeGraphicsPipeline(vk,										// const DeviceInterface&                        vk
5809 													vkDevice,								// const VkDevice                                device
5810 													*pipelineLayout,						// const VkPipelineLayout                        pipelineLayout
5811 													*vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
5812 													DE_NULL,								// const VkShaderModule                          tessellationControlModule
5813 													DE_NULL,								// const VkShaderModule                          tessellationEvalModule
5814 													DE_NULL,								// const VkShaderModule                          geometryShaderModule
5815 													*fragmentShaderModule,					// const VkShaderModule                          fragmentShaderModule
5816 													*renderPass,							// const VkRenderPass                            renderPass
5817 													viewports,								// const std::vector<VkViewport>&                viewports
5818 													scissors,								// const std::vector<VkRect2D>&                  scissors
5819 													VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
5820 													0u,										// const deUint32                                subpass
5821 													0u,										// const deUint32                                patchControlPoints
5822 													DE_NULL,								// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
5823 													DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
5824 													&multisampleStateParams);				// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
5825 		}
5826 
5827 		// Create command buffer
5828 		{
5829 			beginCommandBuffer(vk, *m_cmdBuffer, 0u);
5830 
5831 			// Change the image layouts.
5832 			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, uint32_t(srcImageBarriers.size()), srcImageBarriers.data());
5833 
5834 			if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
5835 			{
5836 				// Clear the 'm_multisampledImage'.
5837 				{
5838 					const VkClearColorValue clearValue = {{0.0f, 0.0f, 0.0f, 1.0f}};
5839 					const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
5840 					vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
5841 				}
5842 
5843 				// Clear the 'm_multisampledCopyImage' with different color.
5844 				{
5845 					const VkClearColorValue clearValue = {{1.0f, 1.0f, 1.0f, 1.0f}};
5846 					const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
5847 					vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
5848 
5849 					const auto postClearMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT);
5850 					vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 1u, &postClearMemoryBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 0u, (const VkImageMemoryBarrier*)DE_NULL);
5851 				}
5852 			}
5853 
5854 			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));
5855 
5856 			const VkDeviceSize	vertexBufferOffset	= 0u;
5857 
5858 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
5859 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
5860 			vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
5861 
5862 			endRenderPass(vk, *m_cmdBuffer);
5863 			endCommandBuffer(vk, *m_cmdBuffer);
5864 		}
5865 
5866 		// Queue submit.
5867 		{
5868 			const VkQueue	queue	= m_context.getUniversalQueue();
5869 			submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
5870 		}
5871 	}
5872 }
5873 
iterate(void)5874 tcu::TestStatus ResolveImageToImage::iterate (void)
5875 {
5876 	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
5877 	const tcu::TextureFormat		dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
5878 
5879 	// upload the destination image
5880 	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
5881 																			(int)m_params.dst.image.extent.width,
5882 																			(int)m_params.dst.image.extent.height,
5883 																			(int)m_params.dst.image.extent.depth));
5884 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
5885 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
5886 
5887 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
5888 																	(int)m_params.src.image.extent.width,
5889 																	(int)m_params.src.image.extent.height,
5890 																	(int)m_params.dst.image.extent.depth));
5891 
5892 	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);
5893 	generateExpectedResult();
5894 
5895 	VkImage		sourceImage		= m_multisampledImage.get();
5896 	deUint32	sourceArraySize	= getArraySize(m_params.src.image);
5897 
5898 	switch (m_options)
5899 	{
5900 		case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
5901 		case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
5902 			// Duplicate the multisampled image to a multisampled image array
5903 			sourceArraySize	= getArraySize(m_params.dst.image); // fall through
5904 		case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
5905 		case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
5906 		case COPY_MS_IMAGE_TO_MS_IMAGE:
5907 			copyMSImageToMSImage(sourceArraySize);
5908 			sourceImage	= m_multisampledCopyImage.get();
5909 			break;
5910 		default:
5911 			break;
5912 	}
5913 
5914 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
5915 	const VkDevice					vkDevice			= m_context.getDevice();
5916 	const VkQueue					queue				= m_context.getUniversalQueue();
5917 
5918 	std::vector<VkImageResolve>		imageResolves;
5919 	std::vector<VkImageResolve2KHR>	imageResolves2KHR;
5920 	for (CopyRegion region : m_params.regions)
5921 	{
5922 		// If copying multiple regions, make sure that the same regions are
5923 		// used for resolving as the ones used for copying.
5924 		if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
5925 		{
5926 			VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
5927 										getExtent3D(m_params.src.image).height / 2,
5928 										getExtent3D(m_params.src.image).depth};
5929 
5930 			const VkImageResolve imageResolve =
5931 			{
5932 				region.imageResolve.srcSubresource,		// VkImageSubresourceLayers	srcSubresource;
5933 				region.imageResolve.dstOffset,			// VkOffset3D				srcOffset;
5934 				region.imageResolve.dstSubresource,		// VkImageSubresourceLayers	dstSubresource;
5935 				region.imageResolve.dstOffset,			// VkOffset3D				dstOffset;
5936 				partialExtent,							// VkExtent3D				extent;
5937 			};
5938 
5939 			if (m_params.extensionUse == EXTENSION_USE_NONE)
5940 			{
5941 				imageResolves.push_back(imageResolve);
5942 			}
5943 			else
5944 			{
5945 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
5946 				imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(imageResolve));
5947 			}
5948 		}
5949 		else
5950 		{
5951 			if (m_params.extensionUse == EXTENSION_USE_NONE)
5952 			{
5953 				imageResolves.push_back(region.imageResolve);
5954 			}
5955 			else
5956 			{
5957 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
5958 				imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(region.imageResolve));
5959 			}
5960 		}
5961 	}
5962 
5963 	const VkImageMemoryBarrier	imageBarriers[]		=
5964 	{
5965 		// source image
5966 		{
5967 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5968 			DE_NULL,									// const void*				pNext;
5969 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
5970 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
5971 			m_options == NO_OPTIONAL_OPERATION ?
5972 			m_params.dst.image.operationLayout :
5973 			m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
5974 			m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
5975 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5976 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5977 			sourceImage,								// VkImage					image;
5978 			{											// VkImageSubresourceRange	subresourceRange;
5979 				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
5980 				0u,									// deUint32				baseMipLevel;
5981 				1u,									// deUint32				mipLevels;
5982 				0u,									// deUint32				baseArraySlice;
5983 				sourceArraySize						// deUint32				arraySize;
5984 			}
5985 		},
5986 		// destination image
5987 		{
5988 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5989 			DE_NULL,									// const void*				pNext;
5990 			0u,											// VkAccessFlags			srcAccessMask;
5991 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
5992 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
5993 			m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
5994 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5995 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5996 			m_destination.get(),						// VkImage					image;
5997 			{											// VkImageSubresourceRange	subresourceRange;
5998 				getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
5999 				0u,									// deUint32				baseMipLevel;
6000 				1u,									// deUint32				mipLevels;
6001 				0u,									// deUint32				baseArraySlice;
6002 				getArraySize(m_params.dst.image)	// deUint32				arraySize;
6003 			}
6004 		},
6005 	};
6006 
6007 	const VkImageMemoryBarrier postImageBarrier =
6008 	{
6009 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
6010 		DE_NULL,								// const void*				pNext;
6011 		VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			srcAccessMask;
6012 		VK_ACCESS_HOST_READ_BIT,				// VkAccessFlags			dstAccessMask;
6013 		m_params.dst.image.operationLayout,		// VkImageLayout			oldLayout;
6014 		m_params.dst.image.operationLayout,		// VkImageLayout			newLayout;
6015 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
6016 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
6017 		m_destination.get(),					// VkImage					image;
6018 		{										// VkImageSubresourceRange	subresourceRange;
6019 			getAspectFlags(dstTcuFormat),		// VkImageAspectFlags		aspectMask;
6020 			0u,									// deUint32					baseMipLevel;
6021 			1u,									// deUint32					mipLevels;
6022 			0u,									// deUint32					baseArraySlice;
6023 			getArraySize(m_params.dst.image)	// deUint32					arraySize;
6024 		}
6025 	};
6026 
6027 	beginCommandBuffer(vk, *m_cmdBuffer);
6028 	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);
6029 
6030 	if (m_params.extensionUse == EXTENSION_USE_NONE)
6031 	{
6032 		vk.cmdResolveImage(*m_cmdBuffer, sourceImage, m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)m_params.regions.size(), imageResolves.data());
6033 	}
6034 	else
6035 	{
6036 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6037 		const VkResolveImageInfo2KHR ResolveImageInfo2KHR =
6038 		{
6039 			VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
6040 			DE_NULL,									// const void*					pNext;
6041 			sourceImage,								// VkImage						srcImage;
6042 			m_params.src.image.operationLayout,			// VkImageLayout				srcImageLayout;
6043 			m_destination.get(),						// VkImage						dstImage;
6044 			m_params.dst.image.operationLayout,			// VkImageLayout				dstImageLayout;
6045 			(deUint32)m_params.regions.size(),			// uint32_t						regionCount;
6046 			imageResolves2KHR.data()					// const  VkImageResolve2KHR*	pRegions;
6047 		};
6048 		vk.cmdResolveImage2KHR(*m_cmdBuffer, &ResolveImageInfo2KHR);
6049 	}
6050 
6051 	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);
6052 	endCommandBuffer(vk, *m_cmdBuffer);
6053 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
6054 
6055 	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);
6056 
6057 	if (shouldVerifyIntermediateResults(m_options))
6058 	{
6059 		// Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
6060 		// resolving the image and giving every sample the same value.
6061 		const auto intermediateResult = checkIntermediateCopy();
6062 		if (intermediateResult.getCode() != QP_TEST_RESULT_PASS)
6063 			return intermediateResult;
6064 	}
6065 
6066 	return checkTestResult(resultTextureLevel->getAccess());
6067 }
6068 
checkTestResult(tcu::ConstPixelBufferAccess result)6069 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
6070 {
6071 	const tcu::ConstPixelBufferAccess	expected		= m_expectedTextureLevel[0]->getAccess();
6072 	const float							fuzzyThreshold	= 0.01f;
6073 
6074 	if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6075 	{
6076 		// Check that all the layers that have not been written to are solid white.
6077 		tcu::Vec4 expectedColor (1.0f, 1.0f, 1.0f, 1.0f);
6078 		for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image) - 1; ++arrayLayerNdx)
6079 		{
6080 			const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
6081 			if(resultSub.getPixel(0, 0) != expectedColor)
6082 				return tcu::TestStatus::fail("CopiesAndBlitting test. Layers image differs from initialized value.");
6083 		}
6084 
6085 		// Check that the layer that has been copied to is the same as the layer that has been copied from.
6086 		const tcu::ConstPixelBufferAccess	expectedSub	= getSubregion (expected, 0u, 0u, 2u, expected.getWidth(), expected.getHeight(), 1u);
6087 		const tcu::ConstPixelBufferAccess	resultSub	= getSubregion (result, 0u, 0u, 4u, result.getWidth(), result.getHeight(), 1u);
6088 		if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
6089 			return tcu::TestStatus::fail("CopiesAndBlitting test");
6090 	}
6091 	else
6092 	{
6093 		for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
6094 		{
6095 			const tcu::ConstPixelBufferAccess	expectedSub	= getSubregion (expected, 0u, 0u, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
6096 			const tcu::ConstPixelBufferAccess	resultSub	= getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
6097 			if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
6098 				return tcu::TestStatus::fail("CopiesAndBlitting test");
6099 		}
6100 	}
6101 
6102 	return tcu::TestStatus::pass("CopiesAndBlitting test");
6103 }
6104 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)6105 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
6106 {
6107 	DE_UNREF(mipLevel);
6108 
6109 	VkOffset3D srcOffset	= region.imageResolve.srcOffset;
6110 			srcOffset.z		= region.imageResolve.srcSubresource.baseArrayLayer;
6111 	VkOffset3D dstOffset	= region.imageResolve.dstOffset;
6112 			dstOffset.z		= region.imageResolve.dstSubresource.baseArrayLayer;
6113 	VkExtent3D extent		= region.imageResolve.extent;
6114 			extent.depth		= region.imageResolve.srcSubresource.layerCount;
6115 
6116 	const tcu::ConstPixelBufferAccess	srcSubRegion		= getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
6117 	// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
6118 	const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
6119 	const tcu::PixelBufferAccess		dstSubRegion		= getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
6120 
6121 	tcu::copy(dstSubRegion, srcSubRegion);
6122 }
6123 
checkIntermediateCopy(void)6124 tcu::TestStatus ResolveImageToImage::checkIntermediateCopy (void)
6125 {
6126 	const		auto&	vkd					= m_context.getDeviceInterface();
6127 	const		auto	device				= m_context.getDevice();
6128 	const		auto	queue				= m_context.getUniversalQueue();
6129 	const		auto	queueIndex			= m_context.getUniversalQueueFamilyIndex();
6130 				auto&	alloc				= m_context.getDefaultAllocator();
6131 	const		auto	currentLayout		= m_params.src.image.operationLayout;
6132 	const		auto	numDstLayers		= getArraySize(m_params.dst.image);
6133 	const		auto	numInputAttachments	= m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : numDstLayers + 1u; // For the source image.
6134 	constexpr	auto	numSets				= 2u; // 1 for the output buffer, 1 for the input attachments.
6135 	const		auto	fbWidth				= m_params.src.image.extent.width;
6136 	const		auto	fbHeight			= m_params.src.image.extent.height;
6137 
6138 	// Push constants.
6139 	const std::array<int, 3> pushConstantData =
6140 	{{
6141 		static_cast<int>(fbWidth),
6142 		static_cast<int>(fbHeight),
6143 		static_cast<int>(m_params.samples),
6144 	}};
6145 	const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
6146 
6147 	// Shader modules.
6148 	const auto vertexModule			= createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
6149 	const auto verificationModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("verify"), 0u);
6150 
6151 	// Descriptor sets.
6152 	DescriptorPoolBuilder poolBuilder;
6153 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
6154 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
6155 	const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
6156 
6157 	DescriptorSetLayoutBuilder layoutBuilderBuffer;
6158 	layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
6159 	const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
6160 
6161 	DescriptorSetLayoutBuilder layoutBuilderAttachments;
6162 	for (deUint32 i = 0u; i < numInputAttachments; ++i)
6163 		layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
6164 	const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
6165 
6166 	const auto descriptorSetBuffer		= makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
6167 	const auto descriptorSetAttachments	= makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
6168 
6169 	// Array with raw descriptor sets.
6170 	const std::array<VkDescriptorSet, numSets> descriptorSets =
6171 	{{
6172 		descriptorSetBuffer.get(),
6173 		descriptorSetAttachments.get(),
6174 	}};
6175 
6176 	// Pipeline layout.
6177 	const std::array<VkDescriptorSetLayout, numSets> setLayouts =
6178 	{{
6179 		outputBufferSetLayout.get(),
6180 		inputAttachmentsSetLayout.get(),
6181 	}};
6182 
6183 	const VkPushConstantRange pushConstantRange =
6184 	{
6185 		VK_SHADER_STAGE_FRAGMENT_BIT,	//	VkShaderStageFlags	stageFlags;
6186 		0u,								//	deUint32			offset;
6187 		pushConstantSize,				//	deUint32			size;
6188 	};
6189 
6190 	const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
6191 	{
6192 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	//	VkStructureType					sType;
6193 		nullptr,										//	const void*						pNext;
6194 		0u,												//	VkPipelineLayoutCreateFlags		flags;
6195 		static_cast<deUint32>(setLayouts.size()),		//	deUint32						setLayoutCount;
6196 		setLayouts.data(),								//	const VkDescriptorSetLayout*	pSetLayouts;
6197 		1u,												//	deUint32						pushConstantRangeCount;
6198 		&pushConstantRange,								//	const VkPushConstantRange*		pPushConstantRanges;
6199 	};
6200 
6201 	const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
6202 
6203 	// Render pass.
6204 	const VkAttachmentDescription commonAttachmentDescription =
6205 	{
6206 		0u,									//	VkAttachmentDescriptionFlags	flags;
6207 		m_params.src.image.format,			//	VkFormat						format;
6208 		m_params.samples,					//	VkSampleCountFlagBits			samples;
6209 		VK_ATTACHMENT_LOAD_OP_LOAD,			//	VkAttachmentLoadOp				loadOp;
6210 		VK_ATTACHMENT_STORE_OP_STORE,		//	VkAttachmentStoreOp				storeOp;
6211 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,	//	VkAttachmentLoadOp				stencilLoadOp;
6212 		VK_ATTACHMENT_STORE_OP_DONT_CARE,	//	VkAttachmentStoreOp				stencilStoreOp;
6213 		currentLayout,						//	VkImageLayout					initialLayout;
6214 		currentLayout,						//	VkImageLayout					finalLayout;
6215 	};
6216 	const std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
6217 
6218 	std::vector<VkAttachmentReference> inputAttachmentReferences;
6219 	inputAttachmentReferences.reserve(numInputAttachments);
6220 	for (deUint32 i = 0u; i < numInputAttachments; ++i)
6221 	{
6222 		const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
6223 		inputAttachmentReferences.push_back(reference);
6224 	}
6225 
6226 	const VkSubpassDescription subpassDescription =
6227 	{
6228 		0u,															//	VkSubpassDescriptionFlags		flags;
6229 		VK_PIPELINE_BIND_POINT_GRAPHICS,							//	VkPipelineBindPoint				pipelineBindPoint;
6230 		static_cast<deUint32>(inputAttachmentReferences.size()),	//	deUint32						inputAttachmentCount;
6231 		inputAttachmentReferences.data(),							//	const VkAttachmentReference*	pInputAttachments;
6232 		0u,															//	deUint32						colorAttachmentCount;
6233 		nullptr,													//	const VkAttachmentReference*	pColorAttachments;
6234 		nullptr,													//	const VkAttachmentReference*	pResolveAttachments;
6235 		nullptr,													//	const VkAttachmentReference*	pDepthStencilAttachment;
6236 		0u,															//	deUint32						preserveAttachmentCount;
6237 		nullptr,													//	const deUint32*					pPreserveAttachments;
6238 	};
6239 
6240 	const VkRenderPassCreateInfo renderPassInfo =
6241 	{
6242 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				//	VkStructureType					sType;
6243 		nullptr,												//	const void*						pNext;
6244 		0u,														//	VkRenderPassCreateFlags			flags;
6245 		static_cast<deUint32>(attachmentDescriptions.size()),	//	deUint32						attachmentCount;
6246 		attachmentDescriptions.data(),							//	const VkAttachmentDescription*	pAttachments;
6247 		1u,														//	deUint32						subpassCount;
6248 		&subpassDescription,									//	const VkSubpassDescription*		pSubpasses;
6249 		0u,														//	deUint32						dependencyCount;
6250 		nullptr,												//	const VkSubpassDependency*		pDependencies;
6251 	};
6252 
6253 	const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
6254 
6255 	// Framebuffer.
6256 	std::vector<Move<VkImageView>>	imageViews;
6257 	std::vector<VkImageView>		imageViewsRaw;
6258 
6259 
6260 	if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6261 	{
6262 		imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 2u, 1u)));
6263 		imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 4u, 1u)));
6264 	}
6265 	else
6266 	{
6267 		imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
6268 		for (deUint32 i = 0u; i < numDstLayers; ++i)
6269 		{
6270 			const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
6271 			imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
6272 		}
6273 	}
6274 
6275 
6276 	imageViewsRaw.reserve(imageViews.size());
6277 	std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
6278 
6279 	const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
6280 
6281 	// Storage buffer.
6282 	const auto			bufferCount	= static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
6283 	const auto			bufferSize	= static_cast<VkDeviceSize>(bufferCount * sizeof(deInt32));
6284 	BufferWithMemory	buffer		(vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
6285 	auto&				bufferAlloc	= buffer.getAllocation();
6286 	void*				bufferData	= bufferAlloc.getHostPtr();
6287 
6288 	// Update descriptor sets.
6289 	DescriptorSetUpdateBuilder updater;
6290 
6291 	const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
6292 	updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
6293 
6294 	std::vector<VkDescriptorImageInfo> imageInfos;
6295 	imageInfos.reserve(imageViewsRaw.size());
6296 	for (size_t i = 0; i < imageViewsRaw.size(); ++i)
6297 		imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
6298 
6299 	for (size_t i = 0; i < imageInfos.size(); ++i)
6300 		updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
6301 
6302 	updater.update(vkd, device);
6303 
6304 	// Vertex buffer.
6305 	std::vector<tcu::Vec4> fullScreenQuad;
6306 	{
6307 		// Full screen quad so every framebuffer pixel and sample location is verified by the shader.
6308 		const tcu::Vec4 topLeft		(-1.0f, -1.0f, 0.0f, 1.0f);
6309 		const tcu::Vec4 topRight	( 1.0f, -1.0f, 0.0f, 1.0f);
6310 		const tcu::Vec4 bottomLeft	(-1.0f,  1.0f, 0.0f, 1.0f);
6311 		const tcu::Vec4 bottomRight	( 1.0f,  1.0f, 0.0f, 1.0f);
6312 
6313 		fullScreenQuad.reserve(6u);
6314 		fullScreenQuad.push_back(topLeft);
6315 		fullScreenQuad.push_back(topRight);
6316 		fullScreenQuad.push_back(bottomRight);
6317 		fullScreenQuad.push_back(topLeft);
6318 		fullScreenQuad.push_back(bottomRight);
6319 		fullScreenQuad.push_back(bottomLeft);
6320 	}
6321 
6322 	const auto				vertexBufferSize	= static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
6323 	const auto				vertexBufferInfo	= makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
6324 	const BufferWithMemory	vertexBuffer		(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
6325 	const auto				vertexBufferHandler	= vertexBuffer.get();
6326 	auto&					vertexBufferAlloc	= vertexBuffer.getAllocation();
6327 	void*					vertexBufferData	= vertexBufferAlloc.getHostPtr();
6328 	const VkDeviceSize		vertexBufferOffset	= 0ull;
6329 
6330 	deMemcpy(vertexBufferData, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
6331 	flushAlloc(vkd, device, vertexBufferAlloc);
6332 
6333 	// Graphics pipeline.
6334 	const std::vector<VkViewport>	viewports	(1, makeViewport(m_params.src.image.extent));
6335 	const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_params.src.image.extent));
6336 
6337 	const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
6338 	{
6339 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
6340 		nullptr,													// const void*								pNext;
6341 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
6342 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
6343 		VK_FALSE,													// VkBool32									sampleShadingEnable;
6344 		0.0f,														// float									minSampleShading;
6345 		nullptr,													// const VkSampleMask*						pSampleMask;
6346 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
6347 		VK_FALSE													// VkBool32									alphaToOneEnable;
6348 	};
6349 
6350 	const auto graphicsPipeline = makeGraphicsPipeline(
6351 		vkd,									// const DeviceInterface&                        vk
6352 		device,									// const VkDevice                                device
6353 		pipelineLayout.get(),					// const VkPipelineLayout                        pipelineLayout
6354 		vertexModule.get(),						// const VkShaderModule                          vertexShaderModule
6355 		DE_NULL,								// const VkShaderModule                          tessellationControlModule
6356 		DE_NULL,								// const VkShaderModule                          tessellationEvalModule
6357 		DE_NULL,								// const VkShaderModule                          geometryShaderModule
6358 		verificationModule.get(),				// const VkShaderModule                          fragmentShaderModule
6359 		renderPass.get(),						// const VkRenderPass                            renderPass
6360 		viewports,								// const std::vector<VkViewport>&                viewports
6361 		scissors,								// const std::vector<VkRect2D>&                  scissors
6362 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
6363 		0u,										// const deUint32                                subpass
6364 		0u,										// const deUint32                                patchControlPoints
6365 		nullptr,								// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
6366 		nullptr,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6367 		&multisampleStateParams);				// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
6368 
6369 	// Command buffer.
6370 	const auto cmdPool		= makeCommandPool(vkd, device, queueIndex);
6371 	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6372 	const auto cmdBuffer	= cmdBufferPtr.get();
6373 
6374 	// Make sure multisample copy data is available to the fragment shader.
6375 	const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
6376 
6377 	// Make sure verification buffer data is available on the host.
6378 	const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6379 
6380 	// Record and submit command buffer.
6381 	beginCommandBuffer(vkd, cmdBuffer);
6382 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
6383 	beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_params.src.image.extent));
6384 	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
6385 	vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBufferHandler, &vertexBufferOffset);
6386 	vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
6387 	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
6388 	vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
6389 	endRenderPass(vkd, cmdBuffer);
6390 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
6391 	endCommandBuffer(vkd, cmdBuffer);
6392 	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6393 
6394 	// Verify intermediate results.
6395 	invalidateAlloc(vkd, device, bufferAlloc);
6396 	std::vector<deInt32> outputFlags (bufferCount, 0);
6397 	deMemcpy(outputFlags.data(), bufferData, static_cast<size_t>(bufferSize));
6398 
6399 	auto& log = m_context.getTestContext().getLog();
6400 	log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
6401 
6402 	const auto sampleCount = static_cast<deUint32>(m_params.samples);
6403 
6404 	for (deUint32 x = 0u; x < fbWidth; ++x)
6405 	for (deUint32 y = 0u; y < fbHeight; ++y)
6406 	for (deUint32 s = 0u; s < sampleCount; ++s)
6407 	{
6408 		const auto index = (y * fbWidth + x) * sampleCount + s;
6409 		if (!outputFlags[index])
6410 		{
6411 			std::ostringstream msg;
6412 			msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s;
6413 			return tcu::TestStatus::fail(msg.str());
6414 		}
6415 	}
6416 
6417 	log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
6418 	return tcu::TestStatus::pass("Pass");
6419 }
6420 
copyMSImageToMSImage(deUint32 copyArraySize)6421 void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
6422 {
6423 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
6424 	const VkDevice					vkDevice			= m_context.getDevice();
6425 	const VkQueue					queue				= m_context.getUniversalQueue();
6426 	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
6427 	std::vector<VkImageCopy>		imageCopies;
6428 	std::vector<VkImageCopy2KHR>	imageCopies2KHR;
6429 
6430 	if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6431 	{
6432 		const VkImageSubresourceLayers	sourceSubresourceLayers	=
6433 		{
6434 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
6435 			0u,								// deUint32				mipLevel;
6436 			2u,								// deUint32				baseArrayLayer;
6437 			1u								// deUint32				layerCount;
6438 		};
6439 
6440 		const VkImageSubresourceLayers	destinationSubresourceLayers	=
6441 		{
6442 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;//getAspectFlags(dstTcuFormat)
6443 			0u,								// deUint32				mipLevel;
6444 			4u,								// deUint32				baseArrayLayer;
6445 			1u								// deUint32				layerCount;
6446 		};
6447 
6448 		const VkImageCopy				imageCopy	=
6449 		{
6450 			sourceSubresourceLayers,			// VkImageSubresourceLayers	srcSubresource;
6451 			{0, 0, 0},							// VkOffset3D				srcOffset;
6452 			destinationSubresourceLayers,		// VkImageSubresourceLayers	dstSubresource;
6453 			{0, 0, 0},							// VkOffset3D				dstOffset;
6454 			getExtent3D(m_params.src.image),	// VkExtent3D				extent;
6455 		};
6456 
6457 		if (m_params.extensionUse == EXTENSION_USE_NONE)
6458 		{
6459 			imageCopies.push_back(imageCopy);
6460 		}
6461 		else
6462 		{
6463 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6464 			imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6465 		}
6466 	}
6467 	else if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6468 	{
6469 		VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
6470 									getExtent3D(m_params.src.image).height / 2,
6471 									getExtent3D(m_params.src.image).depth};
6472 
6473 		for (CopyRegion region : m_params.regions)
6474 		{
6475 			const VkImageCopy				imageCopy	=
6476 			{
6477 				region.imageResolve.srcSubresource,		// VkImageSubresourceLayers	srcSubresource;
6478 				region.imageResolve.srcOffset,			// VkOffset3D				srcOffset;
6479 				region.imageResolve.dstSubresource,		// VkImageSubresourceLayers	dstSubresource;
6480 				region.imageResolve.dstOffset,			// VkOffset3D				dstOffset;
6481 				partialExtent,							// VkExtent3D				extent;
6482 			};
6483 
6484 			if (m_params.extensionUse == EXTENSION_USE_NONE)
6485 			{
6486 				imageCopies.push_back(imageCopy);
6487 			}
6488 			else
6489 			{
6490 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6491 				imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6492 			}
6493 		}
6494 	}
6495 	else
6496 	{
6497 		for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
6498 		{
6499 			const VkImageSubresourceLayers	sourceSubresourceLayers	=
6500 			{
6501 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
6502 				0u,								// deUint32				mipLevel;
6503 				0u,								// deUint32				baseArrayLayer;
6504 				1u								// deUint32				layerCount;
6505 			};
6506 
6507 			const VkImageSubresourceLayers	destinationSubresourceLayers	=
6508 			{
6509 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;//getAspectFlags(dstTcuFormat)
6510 				0u,								// deUint32				mipLevel;
6511 				layerNdx,						// deUint32				baseArrayLayer;
6512 				1u								// deUint32				layerCount;
6513 			};
6514 
6515 			const VkImageCopy				imageCopy	=
6516 			{
6517 				sourceSubresourceLayers,			// VkImageSubresourceLayers	srcSubresource;
6518 				{0, 0, 0},							// VkOffset3D				srcOffset;
6519 				destinationSubresourceLayers,		// VkImageSubresourceLayers	dstSubresource;
6520 				{0, 0, 0},							// VkOffset3D				dstOffset;
6521 				getExtent3D(m_params.src.image),	// VkExtent3D				extent;
6522 			};
6523 
6524 			if (m_params.extensionUse == EXTENSION_USE_NONE)
6525 			{
6526 				imageCopies.push_back(imageCopy);
6527 			}
6528 			else
6529 			{
6530 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6531 				imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6532 			}
6533 		}
6534 	}
6535 
6536 	std::vector<VkImageMemoryBarrier> imageBarriers;
6537 
6538 	// m_multisampledImage
6539 	const VkImageMemoryBarrier m_multisampledImageBarrier =
6540 	{
6541 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6542 		DE_NULL,									// const void*				pNext;
6543 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
6544 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
6545 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
6546 		m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
6547 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6548 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6549 		m_multisampledImage.get(),					// VkImage					image;
6550 		{											// VkImageSubresourceRange	subresourceRange;
6551 			getAspectFlags(srcTcuFormat),			// VkImageAspectFlags	aspectMask;
6552 			0u,										// deUint32				baseMipLevel;
6553 			1u,										// deUint32				mipLevels;
6554 			0u,										// deUint32				baseArraySlice;
6555 			getArraySize(m_params.src.image)		// deUint32				arraySize;
6556 		}
6557 	};
6558 	// m_multisampledCopyImage
6559 	const VkImageMemoryBarrier m_multisampledCopyImageBarrier =
6560 	{
6561 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6562 		DE_NULL,									// const void*				pNext;
6563 		0,											// VkAccessFlags			srcAccessMask;
6564 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
6565 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
6566 		m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
6567 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6568 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6569 		m_multisampledCopyImage.get(),				// VkImage					image;
6570 		{											// VkImageSubresourceRange	subresourceRange;
6571 			getAspectFlags(srcTcuFormat),			// VkImageAspectFlags	aspectMask;
6572 			0u,										// deUint32				baseMipLevel;
6573 			1u,										// deUint32				mipLevels;
6574 			0u,										// deUint32				baseArraySlice;
6575 			copyArraySize							// deUint32				arraySize;
6576 		}
6577 	};
6578 	// m_multisampledCopyNoCabImage (no USAGE_COLOR_ATTACHMENT_BIT)
6579 	const VkImageMemoryBarrier m_multisampledCopyNoCabImageBarrier =
6580 	{
6581 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6582 		DE_NULL,									// const void*				pNext;
6583 		0,											// VkAccessFlags			srcAccessMask;
6584 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
6585 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
6586 		m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
6587 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6588 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6589 		m_multisampledCopyNoCabImage.get(),			// VkImage					image;
6590 		{											// VkImageSubresourceRange	subresourceRange;
6591 			getAspectFlags(srcTcuFormat),			// VkImageAspectFlags	aspectMask;
6592 			0u,										// deUint32				baseMipLevel;
6593 			1u,										// deUint32				mipLevels;
6594 			0u,										// deUint32				baseArraySlice;
6595 			copyArraySize							// deUint32				arraySize;
6596 		}
6597 	};
6598 
6599 	// Only use one barrier if no options have been given.
6600 	if (m_options != DE_NULL)
6601 	{
6602 		imageBarriers.push_back(m_multisampledImageBarrier);
6603 		imageBarriers.push_back(m_multisampledCopyImageBarrier);
6604 		// Add the third barrier if option is as below.
6605 		if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
6606 			imageBarriers.push_back(m_multisampledCopyNoCabImageBarrier);
6607 	}
6608 	else
6609 	{
6610 		imageBarriers.push_back(m_multisampledImageBarrier);
6611 	}
6612 
6613 	const VkImageMemoryBarrier	postImageBarriers		=
6614 	// destination image
6615 	{
6616 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6617 		DE_NULL,									// const void*				pNext;
6618 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
6619 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
6620 		m_params.dst.image.operationLayout,			// VkImageLayout			oldLayout;
6621 		m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
6622 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6623 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6624 		m_multisampledCopyImage.get(),				// VkImage					image;
6625 		{											// VkImageSubresourceRange	subresourceRange;
6626 			getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
6627 			0u,									// deUint32				baseMipLevel;
6628 			1u,									// deUint32				mipLevels;
6629 			0u,									// deUint32				baseArraySlice;
6630 			copyArraySize						// deUint32				arraySize;
6631 		}
6632 	};
6633 	const VkImageMemoryBarrier	betweenCopyImageBarrier		=
6634 	// destination image (no USAGE_COLOR_ATTACHMENT_BIT)
6635 	{
6636 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6637 		DE_NULL,									// const void*				pNext;
6638 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
6639 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
6640 		m_params.dst.image.operationLayout,			// VkImageLayout			oldLayout;
6641 		m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
6642 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6643 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6644 		m_multisampledCopyNoCabImage.get(),			// VkImage					image;
6645 		{											// VkImageSubresourceRange	subresourceRange;
6646 			getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
6647 			0u,									// deUint32				baseMipLevel;
6648 			1u,									// deUint32				mipLevels;
6649 			0u,									// deUint32				baseArraySlice;
6650 			copyArraySize						// deUint32				arraySize;
6651 		}
6652 	};
6653 
6654 	beginCommandBuffer(vk, *m_cmdBuffer);
6655 	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, uint32_t(imageBarriers.size()), imageBarriers.data());
6656 
6657 	if (m_params.extensionUse == EXTENSION_USE_NONE)
6658 	{
6659 		if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
6660 		{
6661 			vk.cmdCopyImage(*m_cmdBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout, m_multisampledCopyNoCabImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
6662 			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, &betweenCopyImageBarrier);
6663 			vk.cmdCopyImage(*m_cmdBuffer, m_multisampledCopyNoCabImage.get(), m_params.src.image.operationLayout, m_multisampledCopyImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
6664 		}
6665 		else
6666 		{
6667 			vk.cmdCopyImage(*m_cmdBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout, m_multisampledCopyImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
6668 		}
6669 	}
6670 	else
6671 	{
6672 		if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
6673 		{
6674 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6675 			const VkCopyImageInfo2KHR copyImageInfo2KHR =
6676 			{
6677 				VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
6678 				DE_NULL,									// const void*				pNext;
6679 				m_multisampledImage.get(),					// VkImage					srcImage;
6680 				m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
6681 				m_multisampledCopyNoCabImage.get(),			// VkImage					dstImage;
6682 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			dstImageLayout;
6683 				(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
6684 				imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
6685 			};
6686 			const VkCopyImageInfo2KHR copyImageInfo2KHRCopy =
6687 			{
6688 				VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
6689 				DE_NULL,									// const void*				pNext;
6690 				m_multisampledCopyNoCabImage.get(),			// VkImage					srcImage;
6691 				vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,	// VkImageLayout			srcImageLayout;
6692 				m_multisampledCopyImage.get(),				// VkImage					dstImage;
6693 				m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
6694 				(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
6695 				imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
6696 			};
6697 
6698 			vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
6699 			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, &betweenCopyImageBarrier);
6700 			vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHRCopy);
6701 		}
6702 		else
6703 		{
6704 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6705 			const VkCopyImageInfo2KHR copyImageInfo2KHR =
6706 			{
6707 				VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
6708 				DE_NULL,									// const void*				pNext;
6709 				m_multisampledImage.get(),					// VkImage					srcImage;
6710 				m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
6711 				m_multisampledCopyImage.get(),				// VkImage					dstImage;
6712 				m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
6713 				(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
6714 				imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
6715 			};
6716 
6717 			vk.cmdCopyImage2KHR(*m_cmdBuffer, &copyImageInfo2KHR);
6718 		}
6719 	}
6720 
6721 	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);
6722 	endCommandBuffer(vk, *m_cmdBuffer);
6723 
6724 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
6725 }
6726 
6727 class ResolveImageToImageTestCase : public vkt::TestCase
6728 {
6729 public:
ResolveImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params,const ResolveImageToImageOptions options=NO_OPTIONAL_OPERATION)6730 							ResolveImageToImageTestCase	(tcu::TestContext&					testCtx,
6731 														 const std::string&					name,
6732 														 const std::string&					description,
6733 														 const TestParams					params,
6734 														 const ResolveImageToImageOptions	options = NO_OPTIONAL_OPERATION)
6735 								: vkt::TestCase	(testCtx, name, description)
6736 								, m_params		(params)
6737 								, m_options		(options)
6738 	{}
6739 
6740 							virtual	void			initPrograms				(SourceCollections&		programCollection) const;
6741 
createInstance(Context & context) const6742 	virtual TestInstance*	createInstance				(Context&				context) const
6743 	{
6744 		return new ResolveImageToImage(context, m_params, m_options);
6745 	}
6746 
checkSupport(Context & context) const6747 	virtual void			checkSupport				(Context&				context) const
6748 	{
6749 		const VkSampleCountFlagBits	rasterizationSamples = m_params.samples;
6750 
6751 		// Intermediate result check uses fragmentStoresAndAtomics.
6752 		if (ResolveImageToImage::shouldVerifyIntermediateResults(m_options) && !context.getDeviceFeatures().fragmentStoresAndAtomics)
6753 		{
6754 			TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
6755 		}
6756 
6757 		if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
6758 			throw tcu::NotSupportedError("Unsupported number of rasterization samples");
6759 
6760 		VkImageFormatProperties properties;
6761 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
6762 																					m_params.src.image.format,
6763 																					m_params.src.image.imageType,
6764 																					VK_IMAGE_TILING_OPTIMAL,
6765 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
6766 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
6767 			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
6768 																					m_params.dst.image.format,
6769 																					m_params.dst.image.imageType,
6770 																					VK_IMAGE_TILING_OPTIMAL,
6771 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
6772 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
6773 		{
6774 			TCU_THROW(NotSupportedError, "Format not supported");
6775 		}
6776 
6777 		if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)	&&
6778 			(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
6779 		{
6780 			TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
6781 		}
6782 	}
6783 
6784 private:
6785 	TestParams							m_params;
6786 	const ResolveImageToImageOptions	m_options;
6787 };
6788 
initPrograms(SourceCollections & programCollection) const6789 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
6790 {
6791 	programCollection.glslSources.add("vert") << glu::VertexSource(
6792 		"#version 310 es\n"
6793 		"layout (location = 0) in highp vec4 a_position;\n"
6794 		"void main()\n"
6795 		"{\n"
6796 		"	gl_Position = a_position;\n"
6797 		"}\n");
6798 
6799 
6800 	programCollection.glslSources.add("frag") << glu::FragmentSource(
6801 		"#version 310 es\n"
6802 		"layout (location = 0) out highp vec4 o_color;\n"
6803 		"void main()\n"
6804 		"{\n"
6805 		"	o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6806 		"}\n");
6807 
6808 	if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE || m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6809 	{
6810 		// The shader verifies all layers in the copied image are the same as the source image.
6811 		// This needs an image view per layer in the copied image.
6812 		// Set 0 contains the output buffer.
6813 		// Set 1 contains the input attachments.
6814 
6815 		std::ostringstream verificationShader;
6816 
6817 		verificationShader
6818 			<< "#version 450\n"
6819 			<< "\n"
6820 			<< "layout (push_constant, std430) uniform PushConstants {\n"
6821 			<< "    int width;\n"
6822 			<< "    int height;\n"
6823 			<< "    int samples;\n"
6824 			<< "};\n"
6825 			<< "layout (set=0, binding=0) buffer VerificationResults {\n"
6826 			<< "    int verificationFlags[];\n"
6827 			<< "};\n"
6828 			<< "layout (input_attachment_index=0, set=1, binding=0) uniform subpassInputMS attachment0;\n"
6829 			;
6830 
6831 		const auto dstLayers = getArraySize(m_params.dst.image);
6832 
6833 		if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6834 		{
6835 			verificationShader << "layout (input_attachment_index=1, set=1, binding=1) uniform subpassInputMS attachment1;\n";
6836 		}
6837 		else
6838 		{
6839 			for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
6840 			{
6841 				const auto i = layerNdx + 1u;
6842 				verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
6843 			}
6844 		}
6845 
6846 		// Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
6847 		// created with a single sample.
6848 		verificationShader
6849 			<< "\n"
6850 			<< "void main() {\n"
6851 			<< "    for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
6852 			<< "        vec4 orig = subpassLoad(attachment0, sampleID);\n"
6853 			;
6854 
6855 		std::ostringstream testCondition;
6856 		if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6857 		{
6858 			verificationShader << "        vec4 copy = subpassLoad(attachment1, sampleID);\n";
6859 			testCondition << "orig == copy";
6860 		}
6861 		else
6862 		{
6863 			for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
6864 			{
6865 				const auto i = layerNdx + 1u;
6866 				verificationShader << "        vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
6867 			}
6868 
6869 			for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
6870 			{
6871 				const auto i = layerNdx + 1u;
6872 				testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
6873 			}
6874 		}
6875 
6876 		verificationShader
6877 			<< "\n"
6878 			<< "        ivec3 coords  = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
6879 			<< "        int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
6880 			<< "\n"
6881 			<< "        verificationFlags[bufferPos] = ((" << testCondition.str() << ") ? 1 : 0); \n"
6882 			<< "    }\n"
6883 			<< "}\n"
6884 			;
6885 
6886 		programCollection.glslSources.add("verify") << glu::FragmentSource(verificationShader.str());
6887 	}
6888 }
6889 
6890 struct BufferOffsetParams
6891 {
6892 	static constexpr deUint32 kMaxOffset = 8u;
6893 
6894 	deUint32 srcOffset;
6895 	deUint32 dstOffset;
6896 };
6897 
checkZerosAt(const std::vector<deUint8> & bufferData,deUint32 from,deUint32 count)6898 void checkZerosAt(const std::vector<deUint8>& bufferData, deUint32 from, deUint32 count)
6899 {
6900 	constexpr deUint8 zero{0};
6901 	for (deUint32 i = 0; i < count; ++i)
6902 	{
6903 		const auto& val = bufferData[from + i];
6904 		if (val != zero)
6905 		{
6906 			std::ostringstream msg;
6907 			msg << "Unexpected non-zero byte found at position " << (from + i) << ": " << static_cast<int>(val);
6908 			TCU_FAIL(msg.str());
6909 		}
6910 	}
6911 }
6912 
bufferOffsetTest(Context & ctx,BufferOffsetParams params)6913 tcu::TestStatus bufferOffsetTest (Context& ctx, BufferOffsetParams params)
6914 {
6915 	// Try to copy blocks of sizes 1 to kMaxOffset. Each copy region will use a block of kMaxOffset*2 bytes to take into account srcOffset and dstOffset.
6916 	constexpr auto kMaxOffset	= BufferOffsetParams::kMaxOffset;
6917 	constexpr auto kBlockSize	= kMaxOffset * 2u;
6918 	constexpr auto kBufferSize	= kMaxOffset * kBlockSize;
6919 
6920 	DE_ASSERT(params.srcOffset < kMaxOffset);
6921 	DE_ASSERT(params.dstOffset < kMaxOffset);
6922 
6923 	const auto&	vkd		= ctx.getDeviceInterface();
6924 	const auto	device	= ctx.getDevice();
6925 	auto&		alloc	= ctx.getDefaultAllocator();
6926 	const auto	qIndex	= ctx.getUniversalQueueFamilyIndex();
6927 	const auto	queue	= ctx.getUniversalQueue();
6928 
6929 	const auto srcBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
6930 	const auto dstBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
6931 
6932 	BufferWithMemory	srcBuffer	(vkd, device, alloc, srcBufferInfo, MemoryRequirement::HostVisible);
6933 	BufferWithMemory	dstBuffer	(vkd, device, alloc, dstBufferInfo, MemoryRequirement::HostVisible);
6934 	auto&				srcAlloc	= srcBuffer.getAllocation();
6935 	auto&				dstAlloc	= dstBuffer.getAllocation();
6936 
6937 	// Zero-out destination buffer.
6938 	deMemset(dstAlloc.getHostPtr(), 0, kBufferSize);
6939 	flushAlloc(vkd, device, dstAlloc);
6940 
6941 	// Fill source buffer with nonzero bytes.
6942 	std::vector<deUint8> srcData;
6943 	srcData.reserve(kBufferSize);
6944 	for (deUint32 i = 0; i < kBufferSize; ++i)
6945 		srcData.push_back(static_cast<deUint8>(100u + i));
6946 	deMemcpy(srcAlloc.getHostPtr(), srcData.data(), de::dataSize(srcData));
6947 	flushAlloc(vkd, device, srcAlloc);
6948 
6949 	// Copy regions.
6950 	std::vector<VkBufferCopy> copies;
6951 	copies.reserve(kMaxOffset);
6952 	for (deUint32 i = 0; i < kMaxOffset; ++i)
6953 	{
6954 		const auto blockStart	= kBlockSize * i;
6955 		const auto copySize		= i + 1u;
6956 		const auto bufferCopy	= makeBufferCopy(params.srcOffset + blockStart, params.dstOffset + blockStart, copySize);
6957 		copies.push_back(bufferCopy);
6958 	}
6959 
6960 	const auto cmdPool		= makeCommandPool(vkd, device, qIndex);
6961 	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6962 	const auto cmdBuffer	= cmdBufferPtr.get();
6963 
6964 	beginCommandBuffer(vkd, cmdBuffer);
6965 	vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), static_cast<deUint32>(copies.size()), copies.data());
6966 	const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6967 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
6968 	endCommandBuffer(vkd, cmdBuffer);
6969 	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6970 	invalidateAlloc(vkd, device, dstAlloc);
6971 
6972 	// Verify destination buffer data.
6973 	std::vector<deUint8> dstData(kBufferSize);
6974 	deMemcpy(dstData.data(), dstAlloc.getHostPtr(), de::dataSize(dstData));
6975 
6976 	for (deUint32 blockIdx = 0; blockIdx < kMaxOffset; ++blockIdx)
6977 	{
6978 		const auto blockStart	= kBlockSize * blockIdx;
6979 		const auto copySize		= blockIdx + 1u;
6980 
6981 		// Verify no data has been written before dstOffset.
6982 		checkZerosAt(dstData, blockStart, params.dstOffset);
6983 
6984 		// Verify copied block.
6985 		for (deUint32 i = 0; i < copySize; ++i)
6986 		{
6987 			const auto& dstVal = dstData[blockStart + params.dstOffset + i];
6988 			const auto& srcVal = srcData[blockStart + params.srcOffset + i];
6989 			if (dstVal != srcVal)
6990 			{
6991 				std::ostringstream msg;
6992 				msg << "Unexpected value found at position " << (blockStart + params.dstOffset + i) << ": expected " << static_cast<int>(srcVal) << " but found " << static_cast<int>(dstVal);
6993 				TCU_FAIL(msg.str());
6994 			}
6995 		}
6996 
6997 		// Verify no data has been written after copy block.
6998 		checkZerosAt(dstData, blockStart + params.dstOffset + copySize, kBlockSize - (params.dstOffset + copySize));
6999 	}
7000 
7001 	return tcu::TestStatus::pass("Pass");
7002 }
7003 
getSampleCountCaseName(VkSampleCountFlagBits sampleFlag)7004 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
7005 {
7006 	return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
7007 }
7008 
getFormatCaseName(VkFormat format)7009 std::string getFormatCaseName (VkFormat format)
7010 {
7011 	return de::toLower(de::toString(getFormatStr(format)).substr(10));
7012 }
7013 
getImageLayoutCaseName(VkImageLayout layout)7014 std::string getImageLayoutCaseName (VkImageLayout layout)
7015 {
7016 	switch (layout)
7017 	{
7018 		case VK_IMAGE_LAYOUT_GENERAL:
7019 			return "general";
7020 		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
7021 		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
7022 			return "optimal";
7023 		default:
7024 			DE_ASSERT(false);
7025 			return "";
7026 	}
7027 }
7028 
7029 const deInt32					defaultSize				= 64;
7030 const deInt32					defaultHalfSize			= defaultSize / 2;
7031 const deInt32					defaultFourthSize		= defaultSize / 4;
7032 const deInt32					defaultSixteenthSize	= defaultSize / 16;
7033 const VkExtent3D				defaultExtent			= {defaultSize, defaultSize, 1};
7034 const VkExtent3D				defaultHalfExtent		= {defaultHalfSize, defaultHalfSize, 1};
7035 const VkExtent3D				default1dExtent			= {defaultSize, 1, 1};
7036 const VkExtent3D				default3dExtent			= {defaultFourthSize, defaultFourthSize, defaultFourthSize};
7037 
7038 const VkImageSubresourceLayers	defaultSourceLayer		=
7039 {
7040 	VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
7041 	0u,							// deUint32				mipLevel;
7042 	0u,							// deUint32				baseArrayLayer;
7043 	1u,							// deUint32				layerCount;
7044 };
7045 
addImageToImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)7046 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7047 {
7048 	tcu::TestContext& testCtx	= group->getTestContext();
7049 
7050 	{
7051 		TestParams	params;
7052 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7053 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
7054 		params.src.image.extent				= defaultExtent;
7055 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7056 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7057 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7058 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
7059 		params.dst.image.extent				= defaultExtent;
7060 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7061 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7062 		params.allocationKind				= allocationKind;
7063 		params.extensionUse					= extensionUse;
7064 
7065 		{
7066 			const VkImageCopy				testCopy	=
7067 			{
7068 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
7069 				{0, 0, 0},			// VkOffset3D				srcOffset;
7070 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
7071 				{0, 0, 0},			// VkOffset3D				dstOffset;
7072 				defaultExtent,		// VkExtent3D				extent;
7073 			};
7074 
7075 			CopyRegion	imageCopy;
7076 			imageCopy.imageCopy	= testCopy;
7077 			params.regions.push_back(imageCopy);
7078 		}
7079 
7080 		group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
7081 	}
7082 
7083 	{
7084 		TestParams	params;
7085 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7086 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
7087 		params.src.image.extent				= defaultExtent;
7088 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7089 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7090 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7091 		params.dst.image.format				= VK_FORMAT_R32_UINT;
7092 		params.dst.image.extent				= defaultExtent;
7093 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7094 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7095 		params.allocationKind				= allocationKind;
7096 		params.extensionUse					= extensionUse;
7097 
7098 		{
7099 			const VkImageCopy				testCopy	=
7100 			{
7101 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
7102 				{0, 0, 0},			// VkOffset3D				srcOffset;
7103 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
7104 				{0, 0, 0},			// VkOffset3D				dstOffset;
7105 				defaultExtent,		// VkExtent3D				extent;
7106 			};
7107 
7108 			CopyRegion	imageCopy;
7109 			imageCopy.imageCopy = testCopy;
7110 			params.regions.push_back(imageCopy);
7111 		}
7112 
7113 		group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
7114 	}
7115 
7116 	{
7117 		TestParams	params;
7118 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7119 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
7120 		params.src.image.extent				= defaultExtent;
7121 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7122 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7123 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7124 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
7125 		params.dst.image.extent				= defaultExtent;
7126 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7127 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7128 		params.allocationKind				= allocationKind;
7129 		params.extensionUse					= extensionUse;
7130 
7131 		{
7132 			const VkImageCopy				testCopy	=
7133 			{
7134 				defaultSourceLayer,									// VkImageSubresourceLayers	srcSubresource;
7135 				{0, 0, 0},											// VkOffset3D				srcOffset;
7136 				defaultSourceLayer,									// VkImageSubresourceLayers	dstSubresource;
7137 				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
7138 				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
7139 			};
7140 
7141 			CopyRegion	imageCopy;
7142 			imageCopy.imageCopy = testCopy;
7143 			params.regions.push_back(imageCopy);
7144 		}
7145 
7146 		group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
7147 	}
7148 
7149 	static const struct
7150 	{
7151 		std::string		name;
7152 		vk::VkFormat	format1;
7153 		vk::VkFormat	format2;
7154 	} formats [] =
7155 	{
7156 		{ "diff_format",	vk::VK_FORMAT_R32_UINT,			vk::VK_FORMAT_R8G8B8A8_UNORM	},
7157 		{ "same_format",	vk::VK_FORMAT_R8G8B8A8_UNORM,	vk::VK_FORMAT_R8G8B8A8_UNORM	}
7158 	};
7159 	static const struct
7160 	{
7161 		std::string		name;
7162 		vk::VkBool32	clear;
7163 	} clears [] =
7164 	{
7165 		{ "clear",		VK_TRUE		},
7166 		{ "noclear",	VK_FALSE	}
7167 	};
7168 	static const struct
7169 	{
7170 		std::string		name;
7171 		VkExtent3D		extent;
7172 	} extents [] =
7173 	{
7174 		{ "npot",	{65u, 63u, 1u}	},
7175 		{ "pot",	{64u, 64u, 1u}	}
7176 	};
7177 
7178 	for (const auto& format : formats)
7179 	{
7180 		for (const auto& clear : clears)
7181 		{
7182 			for (const auto& extent : extents)
7183 			{
7184 				TestParams	params;
7185 				params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7186 				params.src.image.format				= format.format1;
7187 				params.src.image.extent				= extent.extent;
7188 				params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7189 				params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7190 				params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7191 				params.dst.image.format				= format.format2;
7192 				params.dst.image.extent				= extent.extent;
7193 				params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7194 				params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7195 				params.allocationKind				= allocationKind;
7196 				params.extensionUse					= extensionUse;
7197 				params.clearDestination				= clear.clear;
7198 
7199 				{
7200 					VkImageCopy	testCopy	=
7201 					{
7202 						defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
7203 						{34, 34, 0},		// VkOffset3D				srcOffset;
7204 						defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
7205 						{0, 0, 0},			// VkOffset3D				dstOffset;
7206 						{31, 29, 1}			// VkExtent3D				extent;
7207 					};
7208 
7209 					if (extent.name == "pot")
7210 					{
7211 						testCopy.srcOffset	= { 16, 16, 0 };
7212 						testCopy.extent		= { 32, 32, 1 };
7213 					}
7214 
7215 					CopyRegion	imageCopy;
7216 					imageCopy.imageCopy = testCopy;
7217 					params.regions.push_back(imageCopy);
7218 				}
7219 
7220 				// Example test case name: "partial_image_npot_diff_format_clear"
7221 				const std::string testCaseName = "partial_image_" + extent.name + "_" + format.name + "_" + clear.name;
7222 
7223 				group->addChild(new CopyImageToImageTestCase(testCtx, testCaseName, "", params));
7224 			}
7225 		}
7226 	}
7227 
7228 	{
7229 		TestParams	params;
7230 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7231 		params.src.image.format				= VK_FORMAT_D32_SFLOAT;
7232 		params.src.image.extent				= defaultExtent;
7233 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7234 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7235 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7236 		params.dst.image.format				= VK_FORMAT_D32_SFLOAT;
7237 		params.dst.image.extent				= defaultExtent;
7238 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7239 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7240 		params.allocationKind				= allocationKind;
7241 		params.extensionUse					= extensionUse;
7242 
7243 		{
7244 			const VkImageSubresourceLayers  sourceLayer =
7245 			{
7246 				VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
7247 				0u,							// deUint32				mipLevel;
7248 				0u,							// deUint32				baseArrayLayer;
7249 				1u							// deUint32				layerCount;
7250 			};
7251 			const VkImageCopy				testCopy	=
7252 			{
7253 				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
7254 				{0, 0, 0},											// VkOffset3D				srcOffset;
7255 				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
7256 				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
7257 				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
7258 			};
7259 
7260 			CopyRegion	imageCopy;
7261 			imageCopy.imageCopy = testCopy;
7262 			params.regions.push_back(imageCopy);
7263 		}
7264 
7265 		group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
7266 	}
7267 
7268 	{
7269 		TestParams	params;
7270 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
7271 		params.src.image.format				= VK_FORMAT_S8_UINT;
7272 		params.src.image.extent				= defaultExtent;
7273 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7274 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7275 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
7276 		params.dst.image.format				= VK_FORMAT_S8_UINT;
7277 		params.dst.image.extent				= defaultExtent;
7278 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
7279 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7280 		params.allocationKind				= allocationKind;
7281 		params.extensionUse					= extensionUse;
7282 
7283 		{
7284 			const VkImageSubresourceLayers  sourceLayer =
7285 			{
7286 				VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
7287 				0u,								// deUint32				mipLevel;
7288 				0u,								// deUint32				baseArrayLayer;
7289 				1u								// deUint32				layerCount;
7290 			};
7291 			const VkImageCopy				testCopy	=
7292 			{
7293 				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
7294 				{0, 0, 0},											// VkOffset3D				srcOffset;
7295 				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
7296 				{defaultFourthSize, defaultFourthSize / 2, 0},		// VkOffset3D				dstOffset;
7297 				{defaultFourthSize / 2, defaultFourthSize / 2, 1},	// VkExtent3D				extent;
7298 			};
7299 
7300 			CopyRegion	imageCopy;
7301 			imageCopy.imageCopy = testCopy;
7302 			params.regions.push_back(imageCopy);
7303 		}
7304 
7305 		group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
7306 	}
7307 }
7308 
7309 struct CopyColorTestParams
7310 {
7311 	TestParams		params;
7312 	const VkFormat*	compatibleFormats;
7313 };
7314 
addImageToImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,TestParams params)7315 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
7316 {
7317 	const VkImageLayout copySrcLayouts[]		=
7318 	{
7319 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
7320 		VK_IMAGE_LAYOUT_GENERAL
7321 	};
7322 	const VkImageLayout copyDstLayouts[]		=
7323 	{
7324 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
7325 		VK_IMAGE_LAYOUT_GENERAL
7326 	};
7327 
7328 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
7329 	{
7330 		params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
7331 
7332 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
7333 		{
7334 			params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
7335 
7336 			const std::string testName	= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
7337 										  getImageLayoutCaseName(params.dst.image.operationLayout);
7338 			const std::string description	= "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
7339 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
7340 			group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
7341 		}
7342 	}
7343 }
7344 
isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams & testParams)7345 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams& testParams)
7346 {
7347 	bool result = true;
7348 
7349 	if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
7350 	{
7351 		DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
7352 
7353 		result =
7354 			de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
7355 			de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
7356 	}
7357 
7358 	return result;
7359 }
7360 
addImageToImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,CopyColorTestParams testParams)7361 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
7362 {
7363 	// If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
7364 	const VkFormat	srcFormatOnly[2]	= { testParams.params.src.image.format, VK_FORMAT_UNDEFINED };
7365 	const VkFormat*	formatList			= (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);
7366 
7367 	for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
7368 	{
7369 		testParams.params.dst.image.format = formatList[dstFormatIndex];
7370 
7371 		const VkFormat		srcFormat	= testParams.params.src.image.format;
7372 		const VkFormat		dstFormat	= testParams.params.dst.image.format;
7373 
7374 		if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
7375 			continue;
7376 
7377 		if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
7378 			continue;
7379 
7380 		if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
7381 			if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) || (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
7382 				continue;
7383 
7384 		const std::string	description	= "Copy to destination format " + getFormatCaseName(dstFormat);
7385 		addTestGroup(group, getFormatCaseName(dstFormat), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
7386 	}
7387 }
7388 
7389 const VkFormat	compatibleFormats8Bit[]		=
7390 {
7391 	VK_FORMAT_R4G4_UNORM_PACK8,
7392 	VK_FORMAT_R8_UNORM,
7393 	VK_FORMAT_R8_SNORM,
7394 	VK_FORMAT_R8_USCALED,
7395 	VK_FORMAT_R8_SSCALED,
7396 	VK_FORMAT_R8_UINT,
7397 	VK_FORMAT_R8_SINT,
7398 	VK_FORMAT_R8_SRGB,
7399 
7400 	VK_FORMAT_UNDEFINED
7401 };
7402 const VkFormat	compatibleFormats16Bit[]	=
7403 {
7404 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
7405 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
7406 	VK_FORMAT_R5G6B5_UNORM_PACK16,
7407 	VK_FORMAT_B5G6R5_UNORM_PACK16,
7408 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
7409 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
7410 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
7411 	VK_FORMAT_R8G8_UNORM,
7412 	VK_FORMAT_R8G8_SNORM,
7413 	VK_FORMAT_R8G8_USCALED,
7414 	VK_FORMAT_R8G8_SSCALED,
7415 	VK_FORMAT_R8G8_UINT,
7416 	VK_FORMAT_R8G8_SINT,
7417 	VK_FORMAT_R8G8_SRGB,
7418 	VK_FORMAT_R16_UNORM,
7419 	VK_FORMAT_R16_SNORM,
7420 	VK_FORMAT_R16_USCALED,
7421 	VK_FORMAT_R16_SSCALED,
7422 	VK_FORMAT_R16_UINT,
7423 	VK_FORMAT_R16_SINT,
7424 	VK_FORMAT_R16_SFLOAT,
7425 	VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
7426 	VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
7427 
7428 	VK_FORMAT_UNDEFINED
7429 };
7430 const VkFormat	compatibleFormats24Bit[]	=
7431 {
7432 	VK_FORMAT_R8G8B8_UNORM,
7433 	VK_FORMAT_R8G8B8_SNORM,
7434 	VK_FORMAT_R8G8B8_USCALED,
7435 	VK_FORMAT_R8G8B8_SSCALED,
7436 	VK_FORMAT_R8G8B8_UINT,
7437 	VK_FORMAT_R8G8B8_SINT,
7438 	VK_FORMAT_R8G8B8_SRGB,
7439 	VK_FORMAT_B8G8R8_UNORM,
7440 	VK_FORMAT_B8G8R8_SNORM,
7441 	VK_FORMAT_B8G8R8_USCALED,
7442 	VK_FORMAT_B8G8R8_SSCALED,
7443 	VK_FORMAT_B8G8R8_UINT,
7444 	VK_FORMAT_B8G8R8_SINT,
7445 	VK_FORMAT_B8G8R8_SRGB,
7446 
7447 	VK_FORMAT_UNDEFINED
7448 };
7449 const VkFormat	compatibleFormats32Bit[]	=
7450 {
7451 	VK_FORMAT_R8G8B8A8_UNORM,
7452 	VK_FORMAT_R8G8B8A8_SNORM,
7453 	VK_FORMAT_R8G8B8A8_USCALED,
7454 	VK_FORMAT_R8G8B8A8_SSCALED,
7455 	VK_FORMAT_R8G8B8A8_UINT,
7456 	VK_FORMAT_R8G8B8A8_SINT,
7457 	VK_FORMAT_R8G8B8A8_SRGB,
7458 	VK_FORMAT_B8G8R8A8_UNORM,
7459 	VK_FORMAT_B8G8R8A8_SNORM,
7460 	VK_FORMAT_B8G8R8A8_USCALED,
7461 	VK_FORMAT_B8G8R8A8_SSCALED,
7462 	VK_FORMAT_B8G8R8A8_UINT,
7463 	VK_FORMAT_B8G8R8A8_SINT,
7464 	VK_FORMAT_B8G8R8A8_SRGB,
7465 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
7466 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
7467 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
7468 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
7469 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
7470 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
7471 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
7472 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
7473 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
7474 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
7475 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
7476 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
7477 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
7478 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
7479 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
7480 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
7481 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
7482 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
7483 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
7484 	VK_FORMAT_R16G16_UNORM,
7485 	VK_FORMAT_R16G16_SNORM,
7486 	VK_FORMAT_R16G16_USCALED,
7487 	VK_FORMAT_R16G16_SSCALED,
7488 	VK_FORMAT_R16G16_UINT,
7489 	VK_FORMAT_R16G16_SINT,
7490 	VK_FORMAT_R16G16_SFLOAT,
7491 	VK_FORMAT_R32_UINT,
7492 	VK_FORMAT_R32_SINT,
7493 	VK_FORMAT_R32_SFLOAT,
7494 
7495 	VK_FORMAT_UNDEFINED
7496 };
7497 const VkFormat	compatibleFormats48Bit[]	=
7498 {
7499 	VK_FORMAT_R16G16B16_UNORM,
7500 	VK_FORMAT_R16G16B16_SNORM,
7501 	VK_FORMAT_R16G16B16_USCALED,
7502 	VK_FORMAT_R16G16B16_SSCALED,
7503 	VK_FORMAT_R16G16B16_UINT,
7504 	VK_FORMAT_R16G16B16_SINT,
7505 	VK_FORMAT_R16G16B16_SFLOAT,
7506 
7507 	VK_FORMAT_UNDEFINED
7508 };
7509 const VkFormat	compatibleFormats64Bit[]	=
7510 {
7511 	VK_FORMAT_R16G16B16A16_UNORM,
7512 	VK_FORMAT_R16G16B16A16_SNORM,
7513 	VK_FORMAT_R16G16B16A16_USCALED,
7514 	VK_FORMAT_R16G16B16A16_SSCALED,
7515 	VK_FORMAT_R16G16B16A16_UINT,
7516 	VK_FORMAT_R16G16B16A16_SINT,
7517 	VK_FORMAT_R16G16B16A16_SFLOAT,
7518 	VK_FORMAT_R32G32_UINT,
7519 	VK_FORMAT_R32G32_SINT,
7520 	VK_FORMAT_R32G32_SFLOAT,
7521 	VK_FORMAT_R64_UINT,
7522 	VK_FORMAT_R64_SINT,
7523 	VK_FORMAT_R64_SFLOAT,
7524 
7525 	VK_FORMAT_BC1_RGB_UNORM_BLOCK,
7526 	VK_FORMAT_BC1_RGB_SRGB_BLOCK,
7527 	VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
7528 	VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
7529 	VK_FORMAT_BC4_UNORM_BLOCK,
7530 	VK_FORMAT_BC4_SNORM_BLOCK,
7531 
7532 	VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
7533 	VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
7534 	VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
7535 	VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
7536 
7537 	VK_FORMAT_EAC_R11_UNORM_BLOCK,
7538 	VK_FORMAT_EAC_R11_SNORM_BLOCK,
7539 
7540 	VK_FORMAT_UNDEFINED
7541 };
7542 const VkFormat	compatibleFormats96Bit[]	=
7543 {
7544 	VK_FORMAT_R32G32B32_UINT,
7545 	VK_FORMAT_R32G32B32_SINT,
7546 	VK_FORMAT_R32G32B32_SFLOAT,
7547 
7548 	VK_FORMAT_UNDEFINED
7549 };
7550 const VkFormat	compatibleFormats128Bit[]	=
7551 {
7552 	VK_FORMAT_R32G32B32A32_UINT,
7553 	VK_FORMAT_R32G32B32A32_SINT,
7554 	VK_FORMAT_R32G32B32A32_SFLOAT,
7555 	VK_FORMAT_R64G64_UINT,
7556 	VK_FORMAT_R64G64_SINT,
7557 	VK_FORMAT_R64G64_SFLOAT,
7558 
7559 	VK_FORMAT_BC2_UNORM_BLOCK,
7560 	VK_FORMAT_BC2_SRGB_BLOCK,
7561 	VK_FORMAT_BC3_UNORM_BLOCK,
7562 	VK_FORMAT_BC3_SRGB_BLOCK,
7563 	VK_FORMAT_BC5_UNORM_BLOCK,
7564 	VK_FORMAT_BC5_SNORM_BLOCK,
7565 	VK_FORMAT_BC6H_UFLOAT_BLOCK,
7566 	VK_FORMAT_BC6H_SFLOAT_BLOCK,
7567 	VK_FORMAT_BC7_UNORM_BLOCK,
7568 	VK_FORMAT_BC7_SRGB_BLOCK,
7569 
7570 	VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
7571 	VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
7572 
7573 	VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
7574 	VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
7575 
7576 	VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
7577 	VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
7578 	VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
7579 	VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
7580 	VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
7581 	VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
7582 	VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
7583 	VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
7584 	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
7585 	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
7586 	VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
7587 	VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
7588 	VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
7589 	VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
7590 	VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
7591 	VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
7592 	VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
7593 	VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
7594 	VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
7595 	VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
7596 	VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
7597 	VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
7598 	VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
7599 	VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
7600 	VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
7601 	VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
7602 	VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
7603 	VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
7604 
7605 	VK_FORMAT_UNDEFINED
7606 };
7607 const VkFormat	compatibleFormats192Bit[]	=
7608 {
7609 	VK_FORMAT_R64G64B64_UINT,
7610 	VK_FORMAT_R64G64B64_SINT,
7611 	VK_FORMAT_R64G64B64_SFLOAT,
7612 
7613 	VK_FORMAT_UNDEFINED
7614 };
7615 const VkFormat	compatibleFormats256Bit[]	=
7616 {
7617 	VK_FORMAT_R64G64B64A64_UINT,
7618 	VK_FORMAT_R64G64B64A64_SINT,
7619 	VK_FORMAT_R64G64B64A64_SFLOAT,
7620 
7621 	VK_FORMAT_UNDEFINED
7622 };
7623 
7624 const VkFormat*	colorImageFormatsToTest[]	=
7625 {
7626 	compatibleFormats8Bit,
7627 	compatibleFormats16Bit,
7628 	compatibleFormats24Bit,
7629 	compatibleFormats32Bit,
7630 	compatibleFormats48Bit,
7631 	compatibleFormats64Bit,
7632 	compatibleFormats96Bit,
7633 	compatibleFormats128Bit,
7634 	compatibleFormats192Bit,
7635 	compatibleFormats256Bit
7636 };
7637 
7638 const VkFormat	dedicatedAllocationImageToImageFormatsToTest[]	=
7639 {
7640 	// From compatibleFormats8Bit
7641 	VK_FORMAT_R4G4_UNORM_PACK8,
7642 	VK_FORMAT_R8_SRGB,
7643 
7644 	// From compatibleFormats16Bit
7645 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
7646 	VK_FORMAT_R16_SFLOAT,
7647 
7648 	// From compatibleFormats24Bit
7649 	VK_FORMAT_R8G8B8_UNORM,
7650 	VK_FORMAT_B8G8R8_SRGB,
7651 
7652 	// From compatibleFormats32Bit
7653 	VK_FORMAT_R8G8B8A8_UNORM,
7654 	VK_FORMAT_R32_SFLOAT,
7655 
7656 	// From compatibleFormats48Bit
7657 	VK_FORMAT_R16G16B16_UNORM,
7658 	VK_FORMAT_R16G16B16_SFLOAT,
7659 
7660 	// From compatibleFormats64Bit
7661 	VK_FORMAT_R16G16B16A16_UNORM,
7662 	VK_FORMAT_R64_SFLOAT,
7663 
7664 	// From compatibleFormats96Bit
7665 	VK_FORMAT_R32G32B32_UINT,
7666 	VK_FORMAT_R32G32B32_SFLOAT,
7667 
7668 	// From compatibleFormats128Bit
7669 	VK_FORMAT_R32G32B32A32_UINT,
7670 	VK_FORMAT_R64G64_SFLOAT,
7671 
7672 	// From compatibleFormats192Bit
7673 	VK_FORMAT_R64G64B64_UINT,
7674 	VK_FORMAT_R64G64B64_SFLOAT,
7675 
7676 	// From compatibleFormats256Bit
7677 	VK_FORMAT_R64G64B64A64_UINT,
7678 	VK_FORMAT_R64G64B64A64_SFLOAT,
7679 };
7680 
addImageToImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)7681 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7682 {
7683 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
7684 	{
7685 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7686 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
7687 			dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
7688 	}
7689 
7690 	// 2D tests.
7691 	{
7692 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
7693 
7694 		TestParams	params;
7695 		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
7696 		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
7697 		params.src.image.extent		= defaultExtent;
7698 		params.dst.image.extent		= defaultExtent;
7699 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
7700 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
7701 		params.allocationKind		= allocationKind;
7702 		params.extensionUse			= extensionUse;
7703 
7704 		for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
7705 		{
7706 			const VkImageCopy				testCopy =
7707 			{
7708 				defaultSourceLayer,								// VkImageSubresourceLayers	srcSubresource;
7709 				{0, 0, 0},										// VkOffset3D				srcOffset;
7710 				defaultSourceLayer,								// VkImageSubresourceLayers	dstSubresource;
7711 				{i, defaultSize - i - defaultFourthSize, 0},	// VkOffset3D				dstOffset;
7712 				{defaultFourthSize, defaultFourthSize, 1},		// VkExtent3D				extent;
7713 			};
7714 
7715 			CopyRegion	imageCopy;
7716 			imageCopy.imageCopy = testCopy;
7717 
7718 			params.regions.push_back(imageCopy);
7719 		}
7720 
7721 		const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7722 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7723 		{
7724 			const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
7725 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7726 			{
7727 				params.src.image.format = compatibleFormats[srcFormatIndex];
7728 				if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
7729 					continue;
7730 
7731 				CopyColorTestParams	testParams;
7732 				testParams.params				= params;
7733 				testParams.compatibleFormats	= compatibleFormats;
7734 
7735 				const std::string testName		= getFormatCaseName(params.src.image.format);
7736 				const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
7737 				addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
7738 			}
7739 		}
7740 
7741 		group->addChild(subGroup.release());
7742 	}
7743 
7744 	// 1D tests.
7745 	{
7746 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
7747 
7748 		TestParams	params;
7749 		params.src.image.imageType	= VK_IMAGE_TYPE_1D;
7750 		params.dst.image.imageType	= VK_IMAGE_TYPE_1D;
7751 		params.src.image.extent		= default1dExtent;
7752 		params.dst.image.extent		= default1dExtent;
7753 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
7754 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
7755 		params.allocationKind		= allocationKind;
7756 		params.extensionUse			= extensionUse;
7757 
7758 		for (deInt32 i = defaultFourthSize; i < defaultSize; i += defaultSize / 2)
7759 		{
7760 			const VkImageCopy				testCopy =
7761 			{
7762 				defaultSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
7763 				{0, 0, 0},					// VkOffset3D				srcOffset;
7764 				defaultSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
7765 				{i, 0, 0},					// VkOffset3D				dstOffset;
7766 				{defaultFourthSize, 1, 1},	// VkExtent3D				extent;
7767 			};
7768 
7769 			CopyRegion	imageCopy;
7770 			imageCopy.imageCopy = testCopy;
7771 
7772 			params.regions.push_back(imageCopy);
7773 		}
7774 
7775 		const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7776 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7777 		{
7778 			const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
7779 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7780 			{
7781 				params.src.image.format = compatibleFormats[srcFormatIndex];
7782 				if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
7783 					continue;
7784 
7785 				CopyColorTestParams	testParams;
7786 				testParams.params				= params;
7787 				testParams.compatibleFormats	= nullptr;
7788 
7789 				const std::string testName		= getFormatCaseName(params.src.image.format);
7790 				const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
7791 				addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
7792 			}
7793 		}
7794 
7795 		group->addChild(subGroup.release());
7796 	}
7797 
7798 	// 3D tests. Note we use smaller dimensions here for performance reasons.
7799 	{
7800 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
7801 
7802 		TestParams	params;
7803 		params.src.image.imageType	= VK_IMAGE_TYPE_3D;
7804 		params.dst.image.imageType	= VK_IMAGE_TYPE_3D;
7805 		params.src.image.extent		= default3dExtent;
7806 		params.dst.image.extent		= default3dExtent;
7807 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
7808 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
7809 		params.allocationKind		= allocationKind;
7810 		params.extensionUse			= extensionUse;
7811 
7812 		for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
7813 		{
7814 			const VkImageCopy				testCopy =
7815 			{
7816 				defaultSourceLayer,													// VkImageSubresourceLayers	srcSubresource;
7817 				{0, 0, 0},															// VkOffset3D				srcOffset;
7818 				defaultSourceLayer,													// VkImageSubresourceLayers	dstSubresource;
7819 				{i, defaultFourthSize - i - defaultSixteenthSize, i},				// VkOffset3D				dstOffset;
7820 				{defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize},	// VkExtent3D				extent;
7821 			};
7822 
7823 			CopyRegion	imageCopy;
7824 			imageCopy.imageCopy = testCopy;
7825 
7826 			params.regions.push_back(imageCopy);
7827 		}
7828 
7829 		const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7830 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7831 		{
7832 			const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
7833 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7834 			{
7835 				params.src.image.format = compatibleFormats[srcFormatIndex];
7836 				if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
7837 					continue;
7838 
7839 				CopyColorTestParams	testParams;
7840 				testParams.params				= params;
7841 				testParams.compatibleFormats	= nullptr;
7842 
7843 				const std::string testName		= getFormatCaseName(params.src.image.format);
7844 				const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
7845 				addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
7846 			}
7847 		}
7848 
7849 		group->addChild(subGroup.release());
7850 	}
7851 }
7852 
addImageToImageDimensionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)7853 void addImageToImageDimensionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7854 {
7855 	tcu::TestContext&		testCtx				= group->getTestContext();
7856 
7857 	const VkFormat			testFormats[][2]	=
7858 	{
7859 		// From compatibleFormats8Bit
7860 		{
7861 			VK_FORMAT_R4G4_UNORM_PACK8,
7862 			VK_FORMAT_R8_SRGB
7863 		},
7864 		// From compatibleFormats16Bit
7865 		{
7866 			VK_FORMAT_R4G4B4A4_UNORM_PACK16,
7867 			VK_FORMAT_R16_SFLOAT,
7868 		},
7869 		// From compatibleFormats24Bit
7870 		{
7871 			VK_FORMAT_R8G8B8_UNORM,
7872 			VK_FORMAT_B8G8R8_SRGB
7873 		},
7874 		// From compatibleFormats32Bit
7875 		{
7876 			VK_FORMAT_R8G8B8A8_UNORM,
7877 			VK_FORMAT_R32_SFLOAT
7878 		},
7879 		// From compatibleFormats48Bit
7880 		{
7881 			VK_FORMAT_R16G16B16_UNORM,
7882 			VK_FORMAT_R16G16B16_SFLOAT
7883 		},
7884 		// From compatibleFormats64Bit
7885 		{
7886 			VK_FORMAT_R16G16B16A16_UNORM,
7887 			VK_FORMAT_R64_SFLOAT
7888 		},
7889 		// From compatibleFormats96Bit
7890 		{
7891 			VK_FORMAT_R32G32B32_UINT,
7892 			VK_FORMAT_R32G32B32_SFLOAT
7893 		},
7894 		// From compatibleFormats128Bit
7895 		{
7896 			VK_FORMAT_R32G32B32A32_UINT,
7897 			VK_FORMAT_R64G64_SFLOAT
7898 		},
7899 		// From compatibleFormats192Bit
7900 		{
7901 			VK_FORMAT_R64G64B64_UINT,
7902 			VK_FORMAT_R64G64B64_SFLOAT,
7903 		},
7904 		// From compatibleFormats256Bit
7905 		{
7906 			VK_FORMAT_R64G64B64A64_UINT,
7907 			VK_FORMAT_R64G64B64A64_SFLOAT
7908 		}
7909 	};
7910 
7911 	const tcu::UVec2		imageDimensions[]	=
7912 	{
7913 		// large pot x small pot
7914 		tcu::UVec2(4096,	4u),
7915 		tcu::UVec2(8192,	4u),
7916 		tcu::UVec2(16384,	4u),
7917 		tcu::UVec2(32768,	4u),
7918 
7919 		// large pot x small npot
7920 		tcu::UVec2(4096,	6u),
7921 		tcu::UVec2(8192,	6u),
7922 		tcu::UVec2(16384,	6u),
7923 		tcu::UVec2(32768,	6u),
7924 
7925 		// small pot x large pot
7926 		tcu::UVec2(4u, 4096),
7927 		tcu::UVec2(4u, 8192),
7928 		tcu::UVec2(4u, 16384),
7929 		tcu::UVec2(4u, 32768),
7930 
7931 		// small npot x large pot
7932 		tcu::UVec2(6u, 4096),
7933 		tcu::UVec2(6u, 8192),
7934 		tcu::UVec2(6u, 16384),
7935 		tcu::UVec2(6u, 32768)
7936 	};
7937 
7938 	const VkImageLayout		copySrcLayouts[]	=
7939 	{
7940 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
7941 		VK_IMAGE_LAYOUT_GENERAL
7942 	};
7943 
7944 	const VkImageLayout		copyDstLayouts[]	=
7945 	{
7946 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
7947 		VK_IMAGE_LAYOUT_GENERAL
7948 	};
7949 
7950 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
7951 	{
7952 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
7953 			dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
7954 	}
7955 
7956 	// Image dimensions
7957 	for (size_t dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); dimensionNdx++)
7958 	{
7959 		CopyRegion				copyRegion;
7960 		CopyColorTestParams		testParams;
7961 
7962 		const VkExtent3D		extent			= { imageDimensions[dimensionNdx].x(), imageDimensions[dimensionNdx].y(), 1 };
7963 
7964 		const VkImageCopy		testCopy		=
7965 		{
7966 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
7967 			{0, 0, 0},			// VkOffset3D				srcOffset;
7968 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
7969 			{0, 0, 0},			// VkOffset3D				dstOffset;
7970 			extent,				// VkExtent3D				extent;
7971 		};
7972 
7973 		testParams.params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
7974 		testParams.params.src.image.imageType	= VK_IMAGE_TYPE_2D;
7975 		testParams.params.src.image.extent		= extent;
7976 
7977 		testParams.params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
7978 		testParams.params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
7979 		testParams.params.dst.image.extent		= extent;
7980 
7981 		copyRegion.imageCopy					= testCopy;
7982 		testParams.params.allocationKind		= allocationKind;
7983 		testParams.params.extensionUse			= extensionUse;
7984 
7985 		testParams.params.regions.push_back(copyRegion);
7986 
7987 		const std::string	dimensionStr		= "src" + de::toString(testParams.params.src.image.extent.width) + "x" + de::toString(testParams.params.src.image.extent.height)
7988 												  + "_dst" + de::toString(testParams.params.dst.image.extent.width) + "x" + de::toString(testParams.params.dst.image.extent.height);
7989 		tcu::TestCaseGroup*	imageSizeGroup		= new tcu::TestCaseGroup(testCtx, dimensionStr.c_str(), ("Image sizes " + dimensionStr).c_str());
7990 
7991 		// Compatible formats for copying
7992 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
7993 		{
7994 			const VkFormat* compatibleFormats = testFormats[compatibleFormatsIndex];
7995 
7996 			testParams.compatibleFormats = compatibleFormats;
7997 
7998 			// Source image format
7999 			for (int srcFormatIndex = 0; srcFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); srcFormatIndex++)
8000 			{
8001 				testParams.params.src.image.format = testParams.compatibleFormats[srcFormatIndex];
8002 
8003 				if (!isSupportedByFramework(testParams.params.src.image.format) && !isCompressedFormat(testParams.params.src.image.format))
8004 					continue;
8005 
8006 				const std::string	srcDescription	= "Copy from source format " + getFormatCaseName(testParams.params.src.image.format);
8007 				tcu::TestCaseGroup*	srcFormatGroup	= new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.src.image.format).c_str(), srcDescription.c_str());
8008 
8009 				// Destination image format
8010 				for (int dstFormatIndex = 0; dstFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); dstFormatIndex++)
8011 				{
8012 					testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
8013 
8014 					if (!isSupportedByFramework(testParams.params.dst.image.format) && !isCompressedFormat(testParams.params.dst.image.format))
8015 						continue;
8016 
8017 					if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
8018 						continue;
8019 
8020 					if (isCompressedFormat(testParams.params.src.image.format) && isCompressedFormat(testParams.params.dst.image.format))
8021 					{
8022 						if ((getBlockWidth(testParams.params.src.image.format) != getBlockWidth(testParams.params.dst.image.format))
8023 							|| (getBlockHeight(testParams.params.src.image.format) != getBlockHeight(testParams.params.dst.image.format)))
8024 							continue;
8025 					}
8026 
8027 					const std::string	dstDescription	= "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
8028 					tcu::TestCaseGroup*	dstFormatGroup	= new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.dst.image.format).c_str(), dstDescription.c_str());
8029 
8030 					// Source/destionation image layouts
8031 					for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); srcLayoutNdx++)
8032 					{
8033 						testParams.params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
8034 
8035 						for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); dstLayoutNdx++)
8036 						{
8037 							testParams.params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
8038 
8039 							const std::string	testName	= getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
8040 							const std::string	description	= "From layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
8041 							const TestParams	params		= testParams.params;
8042 
8043 							dstFormatGroup->addChild(new CopyImageToImageTestCase(testCtx, testName, description, params));
8044 						}
8045 					}
8046 
8047 					srcFormatGroup->addChild(dstFormatGroup);
8048 				}
8049 
8050 				imageSizeGroup->addChild(srcFormatGroup);
8051 			}
8052 		}
8053 
8054 		group->addChild(imageSizeGroup);
8055 	}
8056 }
8057 
addImageToImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)8058 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
8059 {
8060 	const VkImageLayout copySrcLayouts[]		=
8061 	{
8062 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
8063 		VK_IMAGE_LAYOUT_GENERAL
8064 	};
8065 	const VkImageLayout copyDstLayouts[]		=
8066 	{
8067 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
8068 		VK_IMAGE_LAYOUT_GENERAL
8069 	};
8070 
8071 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
8072 	{
8073 		params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
8074 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
8075 		{
8076 			params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
8077 
8078 			const std::string testName		= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
8079 											  getImageLayoutCaseName(params.dst.image.operationLayout);
8080 			const std::string description	= "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
8081 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
8082 			group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
8083 		}
8084 	}
8085 }
8086 
addImageToImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)8087 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8088 {
8089 	const VkFormat	depthAndStencilFormats[]	=
8090 	{
8091 		VK_FORMAT_D16_UNORM,
8092 		VK_FORMAT_X8_D24_UNORM_PACK32,
8093 		VK_FORMAT_D32_SFLOAT,
8094 		VK_FORMAT_S8_UINT,
8095 		VK_FORMAT_D16_UNORM_S8_UINT,
8096 		VK_FORMAT_D24_UNORM_S8_UINT,
8097 		VK_FORMAT_D32_SFLOAT_S8_UINT,
8098 	};
8099 
8100 	// 2D tests.
8101 	{
8102 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
8103 
8104 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
8105 		{
8106 			TestParams	params;
8107 			params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8108 			params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8109 			params.src.image.extent				= defaultExtent;
8110 			params.dst.image.extent				= defaultExtent;
8111 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
8112 			params.dst.image.format				= params.src.image.format;
8113 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8114 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8115 			params.allocationKind				= allocationKind;
8116 			params.extensionUse					= extensionUse;
8117 			params.separateDepthStencilLayouts	= DE_FALSE;
8118 
8119 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
8120 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
8121 
8122 			const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
8123 			const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
8124 			const VkImageSubresourceLayers		defaultDSSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
8125 
8126 			for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
8127 			{
8128 				CopyRegion			copyRegion;
8129 				const VkOffset3D	srcOffset	= {0, 0, 0};
8130 				const VkOffset3D	dstOffset	= {i, defaultSize - i - defaultFourthSize, 0};
8131 				const VkExtent3D	extent		= {defaultFourthSize, defaultFourthSize, 1};
8132 
8133 				if (hasDepth)
8134 				{
8135 					const VkImageCopy				testCopy	=
8136 					{
8137 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
8138 						srcOffset,					// VkOffset3D				srcOffset;
8139 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
8140 						dstOffset,					// VkOffset3D				dstOffset;
8141 						extent,						// VkExtent3D				extent;
8142 					};
8143 
8144 					copyRegion.imageCopy	= testCopy;
8145 					params.regions.push_back(copyRegion);
8146 				}
8147 				if (hasStencil)
8148 				{
8149 					const VkImageCopy				testCopy	=
8150 					{
8151 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
8152 						srcOffset,					// VkOffset3D				srcOffset;
8153 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
8154 						dstOffset,					// VkOffset3D				dstOffset;
8155 						extent,						// VkExtent3D				extent;
8156 					};
8157 
8158 					copyRegion.imageCopy	= testCopy;
8159 					params.regions.push_back(copyRegion);
8160 				}
8161 			}
8162 
8163 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
8164 			const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
8165 			addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8166 
8167 			if (hasDepth && hasStencil)
8168 			{
8169 				params.separateDepthStencilLayouts	= DE_TRUE;
8170 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
8171 				const std::string description2	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
8172 				addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8173 
8174 				// DS Image copy
8175 				{
8176 					params.separateDepthStencilLayouts	= DE_FALSE;
8177 					// Clear previous vkImageCopy elements
8178 					params.regions.clear();
8179 
8180 					for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
8181 					{
8182 						CopyRegion			copyRegion;
8183 						const VkOffset3D	srcOffset	= {0, 0, 0};
8184 						const VkOffset3D	dstOffset	= {i, defaultSize - i - defaultFourthSize, 0};
8185 						const VkExtent3D	extent		= {defaultFourthSize, defaultFourthSize, 1};
8186 
8187 						const VkImageCopy				testCopy	=
8188 						{
8189 							defaultDSSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
8190 							srcOffset,					// VkOffset3D				srcOffset;
8191 							defaultDSSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
8192 							dstOffset,					// VkOffset3D				dstOffset;
8193 							extent,						// VkExtent3D				extent;
8194 						};
8195 
8196 						copyRegion.imageCopy	= testCopy;
8197 						params.regions.push_back(copyRegion);
8198 					}
8199 
8200 					const std::string testName3		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
8201 					const std::string description3	= "Copy both depth and stencil aspects from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
8202 					addTestGroup(subGroup.get(), testName3, description3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8203 				}
8204 			}
8205 		}
8206 
8207 		group->addChild(subGroup.release());
8208 	}
8209 
8210 	// 1D tests.
8211 	{
8212 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
8213 
8214 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
8215 		{
8216 			TestParams	params;
8217 			params.src.image.imageType			= VK_IMAGE_TYPE_1D;
8218 			params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
8219 			params.src.image.extent				= default1dExtent;
8220 			params.dst.image.extent				= default1dExtent;
8221 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
8222 			params.dst.image.format				= params.src.image.format;
8223 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8224 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8225 			params.allocationKind				= allocationKind;
8226 			params.extensionUse					= extensionUse;
8227 
8228 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
8229 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
8230 
8231 			const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
8232 			const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
8233 
8234 			for (deInt32 i = defaultFourthSize; i < defaultSize; i += defaultSize / 2)
8235 			{
8236 				CopyRegion			copyRegion;
8237 				const VkOffset3D	srcOffset	= {0, 0, 0};
8238 				const VkOffset3D	dstOffset	= {i, 0, 0};
8239 				const VkExtent3D	extent		= {defaultFourthSize, 1, 1};
8240 
8241 				if (hasDepth)
8242 				{
8243 					const VkImageCopy				testCopy	=
8244 					{
8245 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
8246 						srcOffset,					// VkOffset3D				srcOffset;
8247 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
8248 						dstOffset,					// VkOffset3D				dstOffset;
8249 						extent,						// VkExtent3D				extent;
8250 					};
8251 
8252 					copyRegion.imageCopy	= testCopy;
8253 					params.regions.push_back(copyRegion);
8254 				}
8255 				if (hasStencil)
8256 				{
8257 					const VkImageCopy				testCopy	=
8258 					{
8259 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
8260 						srcOffset,					// VkOffset3D				srcOffset;
8261 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
8262 						dstOffset,					// VkOffset3D				dstOffset;
8263 						extent,						// VkExtent3D				extent;
8264 					};
8265 
8266 					copyRegion.imageCopy	= testCopy;
8267 					params.regions.push_back(copyRegion);
8268 				}
8269 			}
8270 
8271 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
8272 			const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
8273 			addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8274 
8275 			if (hasDepth && hasStencil)
8276 			{
8277 				params.separateDepthStencilLayouts	= DE_TRUE;
8278 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
8279 				const std::string description2	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
8280 				addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8281 			}
8282 		}
8283 
8284 		group->addChild(subGroup.release());
8285 	}
8286 
8287 	// 3D tests. Note we use smaller dimensions here for performance reasons.
8288 	{
8289 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
8290 
8291 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
8292 		{
8293 			TestParams	params;
8294 			params.src.image.imageType			= VK_IMAGE_TYPE_3D;
8295 			params.dst.image.imageType			= VK_IMAGE_TYPE_3D;
8296 			params.src.image.extent				= default3dExtent;
8297 			params.dst.image.extent				= default3dExtent;
8298 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
8299 			params.dst.image.format				= params.src.image.format;
8300 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8301 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8302 			params.allocationKind				= allocationKind;
8303 			params.extensionUse					= extensionUse;
8304 
8305 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
8306 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
8307 
8308 			const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
8309 			const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
8310 
8311 			for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
8312 			{
8313 				CopyRegion			copyRegion;
8314 				const VkOffset3D	srcOffset	= {0, 0, 0};
8315 				const VkOffset3D	dstOffset	= {i, defaultFourthSize - i - defaultSixteenthSize, i};
8316 				const VkExtent3D	extent		= {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
8317 
8318 				if (hasDepth)
8319 				{
8320 					const VkImageCopy				testCopy	=
8321 					{
8322 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
8323 						srcOffset,					// VkOffset3D				srcOffset;
8324 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
8325 						dstOffset,					// VkOffset3D				dstOffset;
8326 						extent,						// VkExtent3D				extent;
8327 					};
8328 
8329 					copyRegion.imageCopy	= testCopy;
8330 					params.regions.push_back(copyRegion);
8331 				}
8332 				if (hasStencil)
8333 				{
8334 					const VkImageCopy				testCopy	=
8335 					{
8336 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
8337 						srcOffset,					// VkOffset3D				srcOffset;
8338 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
8339 						dstOffset,					// VkOffset3D				dstOffset;
8340 						extent,						// VkExtent3D				extent;
8341 					};
8342 
8343 					copyRegion.imageCopy	= testCopy;
8344 					params.regions.push_back(copyRegion);
8345 				}
8346 			}
8347 
8348 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
8349 			const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
8350 			addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8351 
8352 			if (hasDepth && hasStencil)
8353 			{
8354 				params.separateDepthStencilLayouts	= DE_TRUE;
8355 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
8356 				const std::string description2	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
8357 				addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8358 			}
8359 		}
8360 
8361 		group->addChild(subGroup.release());
8362 	}
8363 }
8364 
addImageToImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)8365 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8366 {
8367 	addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind, extensionUse);
8368 	addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
8369 }
8370 
addImageToImage3dImagesTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)8371 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8372 {
8373 	tcu::TestContext& testCtx	= group->getTestContext();
8374 
8375 	{
8376 		TestParams	params3DTo2D;
8377 		const deUint32	slicesLayers			= 16u;
8378 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
8379 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8380 		params3DTo2D.src.image.extent			= defaultHalfExtent;
8381 		params3DTo2D.src.image.extent.depth		= slicesLayers;
8382 		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8383 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8384 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
8385 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8386 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
8387 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
8388 		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8389 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8390 		params3DTo2D.allocationKind				= allocationKind;
8391 		params3DTo2D.extensionUse				= extensionUse;
8392 
8393 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8394 		{
8395 			const VkImageSubresourceLayers	sourceLayer	=
8396 			{
8397 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8398 				0u,							// deUint32				mipLevel;
8399 				0u,							// deUint32				baseArrayLayer;
8400 				1u							// deUint32				layerCount;
8401 			};
8402 
8403 			const VkImageSubresourceLayers	destinationLayer	=
8404 			{
8405 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8406 				0u,							// deUint32				mipLevel;
8407 				slicesLayersNdx,			// deUint32				baseArrayLayer;
8408 				1u							// deUint32				layerCount;
8409 			};
8410 
8411 			const VkImageCopy				testCopy	=
8412 			{
8413 				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
8414 				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D				srcOffset;
8415 				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
8416 				{0, 0, 0},							// VkOffset3D				dstOffset;
8417 				defaultHalfExtent,					// VkExtent3D				extent;
8418 			};
8419 
8420 			CopyRegion	imageCopy;
8421 			imageCopy.imageCopy	= testCopy;
8422 
8423 			params3DTo2D.regions.push_back(imageCopy);
8424 		}
8425 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
8426 	}
8427 
8428 	{
8429 		TestParams	params2DTo3D;
8430 		const deUint32	slicesLayers			= 16u;
8431 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
8432 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8433 		params2DTo3D.src.image.extent			= defaultHalfExtent;
8434 		params2DTo3D.src.image.extent.depth		= slicesLayers;
8435 		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8436 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8437 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
8438 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8439 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
8440 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
8441 		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8442 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8443 		params2DTo3D.allocationKind				= allocationKind;
8444 		params2DTo3D.extensionUse				= extensionUse;
8445 
8446 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8447 		{
8448 			const VkImageSubresourceLayers	sourceLayer	=
8449 			{
8450 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8451 				0u,							// deUint32				mipLevel;
8452 				slicesLayersNdx,			// deUint32				baseArrayLayer;
8453 				1u							// deUint32				layerCount;
8454 			};
8455 
8456 			const VkImageSubresourceLayers	destinationLayer	=
8457 			{
8458 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8459 				0u,							// deUint32				mipLevel;
8460 				0u,							// deUint32				baseArrayLayer;
8461 				1u							// deUint32				layerCount;
8462 			};
8463 
8464 			const VkImageCopy				testCopy	=
8465 			{
8466 				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
8467 				{0, 0, 0},							// VkOffset3D				srcOffset;
8468 				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
8469 				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D				dstOffset;
8470 				defaultHalfExtent,					// VkExtent3D				extent;
8471 			};
8472 
8473 			CopyRegion	imageCopy;
8474 			imageCopy.imageCopy	= testCopy;
8475 
8476 			params2DTo3D.regions.push_back(imageCopy);
8477 		}
8478 
8479 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
8480 	}
8481 
8482 	{
8483 		TestParams	params3DTo2D;
8484 		const deUint32	slicesLayers			= 16u;
8485 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
8486 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8487 		params3DTo2D.src.image.extent			= defaultHalfExtent;
8488 		params3DTo2D.src.image.extent.depth		= slicesLayers;
8489 		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8490 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8491 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
8492 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8493 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
8494 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
8495 		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8496 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8497 		params3DTo2D.allocationKind				= allocationKind;
8498 		params3DTo2D.extensionUse				= extensionUse;
8499 
8500 		{
8501 			const VkImageSubresourceLayers	sourceLayer	=
8502 			{
8503 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8504 				0u,							// deUint32				mipLevel;
8505 				0u,							// deUint32				baseArrayLayer;
8506 				1u							// deUint32				layerCount;
8507 			};
8508 
8509 			const VkImageSubresourceLayers	destinationLayer	=
8510 			{
8511 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8512 				0u,							// deUint32				mipLevel;
8513 				0,							// deUint32				baseArrayLayer;
8514 				slicesLayers				// deUint32				layerCount;
8515 			};
8516 
8517 			const VkImageCopy				testCopy	=
8518 			{
8519 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
8520 				{0, 0, 0},						// VkOffset3D				srcOffset;
8521 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
8522 				{0, 0, 0},						// VkOffset3D				dstOffset;
8523 				params3DTo2D.src.image.extent	// VkExtent3D				extent;
8524 			};
8525 
8526 			CopyRegion	imageCopy;
8527 			imageCopy.imageCopy	= testCopy;
8528 
8529 			params3DTo2D.regions.push_back(imageCopy);
8530 		}
8531 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
8532 	}
8533 
8534 	{
8535 		TestParams	params2DTo3D;
8536 		const deUint32	slicesLayers			= 16u;
8537 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
8538 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8539 		params2DTo3D.src.image.extent			= defaultHalfExtent;
8540 		params2DTo3D.src.image.extent.depth		= slicesLayers;
8541 		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8542 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8543 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
8544 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8545 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
8546 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
8547 		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8548 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8549 		params2DTo3D.allocationKind				= allocationKind;
8550 		params2DTo3D.extensionUse				= extensionUse;
8551 
8552 		{
8553 			const VkImageSubresourceLayers	sourceLayer	=
8554 			{
8555 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8556 				0u,							// deUint32				mipLevel;
8557 				0u,							// deUint32				baseArrayLayer;
8558 				slicesLayers				// deUint32				layerCount;
8559 			};
8560 
8561 			const VkImageSubresourceLayers	destinationLayer	=
8562 			{
8563 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8564 				0u,							// deUint32				mipLevel;
8565 				0u,							// deUint32				baseArrayLayer;
8566 				1u							// deUint32				layerCount;
8567 			};
8568 
8569 			const VkImageCopy				testCopy	=
8570 			{
8571 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
8572 				{0, 0, 0},						// VkOffset3D				srcOffset;
8573 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
8574 				{0, 0, 0},						// VkOffset3D				dstOffset;
8575 				params2DTo3D.src.image.extent,	// VkExtent3D				extent;
8576 			};
8577 
8578 			CopyRegion	imageCopy;
8579 			imageCopy.imageCopy	= testCopy;
8580 
8581 			params2DTo3D.regions.push_back(imageCopy);
8582 		}
8583 
8584 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
8585 	}
8586 
8587 	{
8588 		TestParams	params3DTo2D;
8589 		const deUint32	slicesLayers			= 16u;
8590 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
8591 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8592 		params3DTo2D.src.image.extent			= defaultHalfExtent;
8593 		params3DTo2D.src.image.extent.depth		= slicesLayers;
8594 		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8595 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8596 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
8597 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8598 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
8599 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
8600 		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8601 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8602 		params3DTo2D.allocationKind				= allocationKind;
8603 		params3DTo2D.extensionUse				= extensionUse;
8604 
8605 		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
8606 		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;
8607 
8608 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8609 		{
8610 			const VkImageSubresourceLayers	sourceLayer	=
8611 			{
8612 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8613 				0u,							// deUint32				mipLevel;
8614 				0u,							// deUint32				baseArrayLayer;
8615 				1u							// deUint32				layerCount;
8616 			};
8617 
8618 			const VkImageSubresourceLayers	destinationLayer	=
8619 			{
8620 					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
8621 					0u,								// deUint32				mipLevel;
8622 					slicesLayersNdx,				// deUint32				baseArrayLayer;
8623 					1u								// deUint32				layerCount;
8624 			};
8625 
8626 
8627 			const VkImageCopy				testCopy	=
8628 			{
8629 				sourceLayer,															// VkImageSubresourceLayers	srcSubresource;
8630 				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx},	// VkOffset3D				srcOffset;
8631 					destinationLayer,													// VkImageSubresourceLayers	dstSubresource;
8632 					{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},						// VkOffset3D				dstOffset;
8633 					{
8634 						(defaultHalfExtent.width - regionWidth*slicesLayersNdx),
8635 						(defaultHalfExtent.height - regionHeight*slicesLayersNdx),
8636 						1
8637 					}																	// VkExtent3D				extent;
8638 			};
8639 
8640 			CopyRegion	imageCopy;
8641 			imageCopy.imageCopy = testCopy;
8642 			params3DTo2D.regions.push_back(imageCopy);
8643 		}
8644 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
8645 	}
8646 
8647 	{
8648 		TestParams	params2DTo3D;
8649 		const deUint32	slicesLayers			= 16u;
8650 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
8651 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8652 		params2DTo3D.src.image.extent			= defaultHalfExtent;
8653 		params2DTo3D.src.image.extent.depth		= slicesLayers;
8654 		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8655 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8656 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
8657 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8658 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
8659 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
8660 		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8661 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8662 		params2DTo3D.allocationKind				= allocationKind;
8663 		params2DTo3D.extensionUse				= extensionUse;
8664 
8665 		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
8666 		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;
8667 
8668 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8669 		{
8670 			const VkImageSubresourceLayers	sourceLayer	=
8671 			{
8672 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8673 				0u,							// deUint32				mipLevel;
8674 				slicesLayersNdx,			// deUint32				baseArrayLayer;
8675 				1u							// deUint32				layerCount;
8676 			};
8677 
8678 			const VkImageSubresourceLayers	destinationLayer	=
8679 			{
8680 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8681 				0u,							// deUint32				mipLevel;
8682 				0u,							// deUint32				baseArrayLayer;
8683 				1u							// deUint32				layerCount;
8684 			};
8685 
8686 			const VkImageCopy				testCopy	=
8687 			{
8688 				sourceLayer,																// VkImageSubresourceLayers	srcSubresource;
8689 				{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},								// VkOffset3D				srcOffset;
8690 				destinationLayer,															// VkImageSubresourceLayers	dstSubresource;
8691 				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)},	// VkOffset3D				dstOffset;
8692 				{
8693 					defaultHalfExtent.width - regionWidth*slicesLayersNdx,
8694 					defaultHalfExtent.height - regionHeight*slicesLayersNdx,
8695 					1
8696 				}																			// VkExtent3D				extent;
8697 			};
8698 
8699 			CopyRegion	imageCopy;
8700 			imageCopy.imageCopy	= testCopy;
8701 
8702 			params2DTo3D.regions.push_back(imageCopy);
8703 		}
8704 
8705 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
8706 	}
8707 }
8708 
addImageToImageCubeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)8709 void addImageToImageCubeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8710 {
8711 	tcu::TestContext& testCtx	= group->getTestContext();
8712 
8713 	{
8714 		TestParams	paramsCubeToArray;
8715 		const deUint32	arrayLayers					= 6u;
8716 		paramsCubeToArray.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8717 		paramsCubeToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
8718 		paramsCubeToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8719 		paramsCubeToArray.src.image.extent			= defaultHalfExtent;
8720 		paramsCubeToArray.src.image.extent.depth	= arrayLayers;
8721 		paramsCubeToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8722 		paramsCubeToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8723 		paramsCubeToArray.dst.image.createFlags		= 0;
8724 		paramsCubeToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
8725 		paramsCubeToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8726 		paramsCubeToArray.dst.image.extent			= defaultHalfExtent;
8727 		paramsCubeToArray.dst.image.extent.depth	= arrayLayers;
8728 		paramsCubeToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8729 		paramsCubeToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8730 		paramsCubeToArray.allocationKind			= allocationKind;
8731 		paramsCubeToArray.extensionUse				= extensionUse;
8732 
8733 		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8734 		{
8735 			const VkImageSubresourceLayers	sourceLayer	=
8736 				{
8737 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8738 					0u,							// deUint32				mipLevel;
8739 					arrayLayersNdx,				// deUint32				baseArrayLayer;
8740 					1u							// deUint32				layerCount;
8741 				};
8742 
8743 			const VkImageSubresourceLayers	destinationLayer	=
8744 				{
8745 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8746 					0u,							// deUint32				mipLevel;
8747 					arrayLayersNdx,				// deUint32				baseArrayLayer;
8748 					1u							// deUint32				layerCount;
8749 				};
8750 
8751 			const VkImageCopy				testCopy	=
8752 				{
8753 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
8754 					{0, 0, 0},					// VkOffset3D				srcOffset;
8755 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
8756 					{0, 0, 0},					// VkOffset3D				dstOffset;
8757 					defaultHalfExtent				// VkExtent3D				extent;
8758 				};
8759 
8760 			CopyRegion	imageCopy;
8761 			imageCopy.imageCopy	= testCopy;
8762 
8763 			paramsCubeToArray.regions.push_back(imageCopy);
8764 		}
8765 
8766 		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_layers", "copy cube compatible image to 2d layers layer by layer", paramsCubeToArray));
8767 	}
8768 
8769 	{
8770 		TestParams	paramsCubeToArray;
8771 		const deUint32	arrayLayers					= 6u;
8772 		paramsCubeToArray.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8773 		paramsCubeToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
8774 		paramsCubeToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8775 		paramsCubeToArray.src.image.extent			= defaultHalfExtent;
8776 		paramsCubeToArray.src.image.extent.depth	= arrayLayers;
8777 		paramsCubeToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8778 		paramsCubeToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8779 		paramsCubeToArray.dst.image.createFlags		= 0;
8780 		paramsCubeToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
8781 		paramsCubeToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8782 		paramsCubeToArray.dst.image.extent			= defaultHalfExtent;
8783 		paramsCubeToArray.dst.image.extent.depth	= arrayLayers;
8784 		paramsCubeToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8785 		paramsCubeToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8786 		paramsCubeToArray.allocationKind			= allocationKind;
8787 		paramsCubeToArray.extensionUse				= extensionUse;
8788 
8789 		{
8790 			const VkImageSubresourceLayers	sourceLayer	=
8791 				{
8792 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8793 					0u,							// deUint32				mipLevel;
8794 					0u,							// deUint32				baseArrayLayer;
8795 					arrayLayers					// deUint32				layerCount;
8796 				};
8797 
8798 			const VkImageSubresourceLayers	destinationLayer	=
8799 				{
8800 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8801 					0u,							// deUint32				mipLevel;
8802 					0u,							// deUint32				baseArrayLayer;
8803 					arrayLayers					// deUint32				layerCount;
8804 				};
8805 
8806 			const VkImageCopy				testCopy	=
8807 				{
8808 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
8809 					{0, 0, 0},					// VkOffset3D				srcOffset;
8810 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
8811 					{0, 0, 0},					// VkOffset3D				dstOffset;
8812 					defaultHalfExtent			// VkExtent3D				extent;
8813 				};
8814 
8815 			CopyRegion	imageCopy;
8816 			imageCopy.imageCopy	= testCopy;
8817 
8818 			paramsCubeToArray.regions.push_back(imageCopy);
8819 		}
8820 
8821 		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_whole", "copy cube compatible image to 2d layers all at once", paramsCubeToArray));
8822 	}
8823 
8824 	{
8825 		TestParams	paramsArrayToCube;
8826 		const deUint32	arrayLayers					= 6u;
8827 		paramsArrayToCube.src.image.createFlags		= 0;
8828 		paramsArrayToCube.src.image.imageType		= VK_IMAGE_TYPE_2D;
8829 		paramsArrayToCube.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8830 		paramsArrayToCube.src.image.extent			= defaultHalfExtent;
8831 		paramsArrayToCube.src.image.extent.depth	= arrayLayers;
8832 		paramsArrayToCube.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8833 		paramsArrayToCube.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8834 		paramsArrayToCube.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8835 		paramsArrayToCube.dst.image.imageType		= VK_IMAGE_TYPE_2D;
8836 		paramsArrayToCube.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8837 		paramsArrayToCube.dst.image.extent			= defaultHalfExtent;
8838 		paramsArrayToCube.dst.image.extent.depth	= arrayLayers;
8839 		paramsArrayToCube.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8840 		paramsArrayToCube.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8841 		paramsArrayToCube.allocationKind			= allocationKind;
8842 		paramsArrayToCube.extensionUse				= extensionUse;
8843 
8844 		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8845 		{
8846 			const VkImageSubresourceLayers	sourceLayer	=
8847 				{
8848 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8849 					0u,							// deUint32				mipLevel;
8850 					arrayLayersNdx,				// deUint32				baseArrayLayer;
8851 					1u							// deUint32				layerCount;
8852 				};
8853 
8854 			const VkImageSubresourceLayers	destinationLayer =
8855 				{
8856 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8857 					0u,							// deUint32				mipLevel;
8858 					arrayLayersNdx,				// deUint32				baseArrayLayer;
8859 					1u							// deUint32				layerCount;
8860 				};
8861 
8862 			const VkImageCopy				testCopy =
8863 				{
8864 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
8865 					{0, 0, 0},					// VkOffset3D				srcOffset;
8866 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
8867 					{0, 0, 0},					// VkOffset3D				dstOffset;
8868 					defaultHalfExtent			// VkExtent3D				extent;
8869 				};
8870 
8871 			CopyRegion	imageCopy;
8872 			imageCopy.imageCopy	= testCopy;
8873 
8874 			paramsArrayToCube.regions.push_back(imageCopy);
8875 		}
8876 
8877 		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_layers", "copy 2d layers to cube compatible image layer by layer", paramsArrayToCube));
8878 	}
8879 
8880 	{
8881 		TestParams	paramsArrayToCube;
8882 		const deUint32	arrayLayers					= 6u;
8883 		paramsArrayToCube.src.image.createFlags		= 0;
8884 		paramsArrayToCube.src.image.imageType		= VK_IMAGE_TYPE_2D;
8885 		paramsArrayToCube.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8886 		paramsArrayToCube.src.image.extent			= defaultHalfExtent;
8887 		paramsArrayToCube.src.image.extent.depth	= arrayLayers;
8888 		paramsArrayToCube.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8889 		paramsArrayToCube.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8890 		paramsArrayToCube.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8891 		paramsArrayToCube.dst.image.imageType		= VK_IMAGE_TYPE_2D;
8892 		paramsArrayToCube.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8893 		paramsArrayToCube.dst.image.extent			= defaultHalfExtent;
8894 		paramsArrayToCube.dst.image.extent.depth	= arrayLayers;
8895 		paramsArrayToCube.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8896 		paramsArrayToCube.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8897 		paramsArrayToCube.allocationKind			= allocationKind;
8898 		paramsArrayToCube.extensionUse				= extensionUse;
8899 
8900 		{
8901 			const VkImageSubresourceLayers sourceLayer =
8902 				{
8903 					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
8904 					0u,								// deUint32				mipLevel;
8905 					0u,								// deUint32				baseArrayLayer;
8906 					arrayLayers						// deUint32				layerCount;
8907 				};
8908 
8909 			const VkImageSubresourceLayers destinationLayer =
8910 				{
8911 					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
8912 					0u,								// deUint32				mipLevel;
8913 					0u,								// deUint32				baseArrayLayer;
8914 					arrayLayers						// deUint32				layerCount;
8915 				};
8916 
8917 			const VkImageCopy				testCopy =
8918 				{
8919 					sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
8920 					{0, 0, 0},						// VkOffset3D				srcOffset;
8921 					destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
8922 					{0, 0, 0},						// VkOffset3D				dstOffset;
8923 					defaultHalfExtent				// VkExtent3D				extent;
8924 				};
8925 
8926 			CopyRegion imageCopy;
8927 			imageCopy.imageCopy = testCopy;
8928 
8929 			paramsArrayToCube.regions.push_back(imageCopy);
8930 		}
8931 
8932 		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_whole", "copy 2d layers to cube compatible image all at once", paramsArrayToCube));
8933 	}
8934 
8935 	{
8936 		TestParams	paramsCubeToArray;
8937 		const deUint32	arrayLayers					= 6u;
8938 		paramsCubeToArray.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8939 		paramsCubeToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
8940 		paramsCubeToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8941 		paramsCubeToArray.src.image.extent			= defaultHalfExtent;
8942 		paramsCubeToArray.src.image.extent.depth	= arrayLayers;
8943 		paramsCubeToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8944 		paramsCubeToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8945 		paramsCubeToArray.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8946 		paramsCubeToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
8947 		paramsCubeToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8948 		paramsCubeToArray.dst.image.extent			= defaultHalfExtent;
8949 		paramsCubeToArray.dst.image.extent.depth	= arrayLayers;
8950 		paramsCubeToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
8951 		paramsCubeToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8952 		paramsCubeToArray.allocationKind			= allocationKind;
8953 		paramsCubeToArray.extensionUse				= extensionUse;
8954 
8955 		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8956 		{
8957 			const VkImageSubresourceLayers	sourceLayer	=
8958 				{
8959 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8960 					0u,							// deUint32				mipLevel;
8961 					arrayLayersNdx,				// deUint32				baseArrayLayer;
8962 					1u							// deUint32				layerCount;
8963 				};
8964 
8965 			const VkImageSubresourceLayers	destinationLayer	=
8966 				{
8967 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
8968 					0u,							// deUint32				mipLevel;
8969 					arrayLayersNdx,				// deUint32				baseArrayLayer;
8970 					1u							// deUint32				layerCount;
8971 				};
8972 
8973 			const VkImageCopy				testCopy	=
8974 				{
8975 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
8976 					{0, 0, 0},					// VkOffset3D				srcOffset;
8977 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
8978 					{0, 0, 0},					// VkOffset3D				dstOffset;
8979 					defaultHalfExtent				// VkExtent3D				extent;
8980 				};
8981 
8982 			CopyRegion	imageCopy;
8983 			imageCopy.imageCopy	= testCopy;
8984 
8985 			paramsCubeToArray.regions.push_back(imageCopy);
8986 		}
8987 
8988 		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_layers", "copy cube compatible image to cube compatible image layer by layer", paramsCubeToArray));
8989 	}
8990 
8991 	{
8992 		TestParams	paramsCubeToCube;
8993 		const deUint32	arrayLayers					= 6u;
8994 		paramsCubeToCube.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8995 		paramsCubeToCube.src.image.imageType		= VK_IMAGE_TYPE_2D;
8996 		paramsCubeToCube.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
8997 		paramsCubeToCube.src.image.extent			= defaultHalfExtent;
8998 		paramsCubeToCube.src.image.extent.depth		= arrayLayers;
8999 		paramsCubeToCube.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
9000 		paramsCubeToCube.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9001 		paramsCubeToCube.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
9002 		paramsCubeToCube.dst.image.imageType		= VK_IMAGE_TYPE_2D;
9003 		paramsCubeToCube.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
9004 		paramsCubeToCube.dst.image.extent			= defaultHalfExtent;
9005 		paramsCubeToCube.dst.image.extent.depth		= arrayLayers;
9006 		paramsCubeToCube.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
9007 		paramsCubeToCube.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9008 		paramsCubeToCube.allocationKind				= allocationKind;
9009 		paramsCubeToCube.extensionUse				= extensionUse;
9010 
9011 		{
9012 			const VkImageSubresourceLayers	sourceLayer	=
9013 				{
9014 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
9015 					0u,							// deUint32				mipLevel;
9016 					0u,							// deUint32				baseArrayLayer;
9017 					arrayLayers					// deUint32				layerCount;
9018 				};
9019 
9020 			const VkImageSubresourceLayers	destinationLayer	=
9021 				{
9022 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
9023 					0u,							// deUint32				mipLevel;
9024 					0u,							// deUint32				baseArrayLayer;
9025 					arrayLayers					// deUint32				layerCount;
9026 				};
9027 
9028 			const VkImageCopy				testCopy	=
9029 				{
9030 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
9031 					{0, 0, 0},					// VkOffset3D				srcOffset;
9032 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
9033 					{0, 0, 0},					// VkOffset3D				dstOffset;
9034 					defaultHalfExtent			// VkExtent3D				extent;
9035 				};
9036 
9037 			CopyRegion	imageCopy;
9038 			imageCopy.imageCopy	= testCopy;
9039 
9040 			paramsCubeToCube.regions.push_back(imageCopy);
9041 		}
9042 
9043 		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_whole", "copy cube compatible image to cube compatible image all at once", paramsCubeToCube));
9044 	}
9045 }
9046 
addImageToImageArrayTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9047 void addImageToImageArrayTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9048 {
9049 	tcu::TestContext& testCtx	= group->getTestContext();
9050 
9051 	{
9052 		TestParams	paramsArrayToArray;
9053 		const deUint32	arrayLayers					= 16u;
9054 		paramsArrayToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
9055 		paramsArrayToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
9056 		paramsArrayToArray.src.image.extent			= defaultHalfExtent;
9057 		paramsArrayToArray.src.image.extent.depth	= arrayLayers;
9058 		paramsArrayToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
9059 		paramsArrayToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9060 		paramsArrayToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
9061 		paramsArrayToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
9062 		paramsArrayToArray.dst.image.extent			= defaultHalfExtent;
9063 		paramsArrayToArray.dst.image.extent.depth	= arrayLayers;
9064 		paramsArrayToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
9065 		paramsArrayToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9066 		paramsArrayToArray.allocationKind			= allocationKind;
9067 		paramsArrayToArray.extensionUse				= extensionUse;
9068 
9069 		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
9070 		{
9071 			const VkImageSubresourceLayers	sourceLayer	=
9072 					{
9073 							VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
9074 							0u,							// deUint32				mipLevel;
9075 							arrayLayersNdx,				// deUint32				baseArrayLayer;
9076 							1u							// deUint32				layerCount;
9077 					};
9078 
9079 			const VkImageSubresourceLayers	destinationLayer =
9080 					{
9081 							VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
9082 							0u,							// deUint32				mipLevel;
9083 							arrayLayersNdx,				// deUint32				baseArrayLayer;
9084 							1u							// deUint32				layerCount;
9085 					};
9086 
9087 			const VkImageCopy				testCopy =
9088 					{
9089 							sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
9090 							{0, 0, 0},					// VkOffset3D				srcOffset;
9091 							destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
9092 							{0, 0, 0},					// VkOffset3D				dstOffset;
9093 							defaultHalfExtent			// VkExtent3D				extent;
9094 					};
9095 
9096 			CopyRegion	imageCopy;
9097 			imageCopy.imageCopy	= testCopy;
9098 
9099 			paramsArrayToArray.regions.push_back(imageCopy);
9100 		}
9101 
9102 		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_layers", "copy 2d array image to 2d array image layer by layer", paramsArrayToArray));
9103 	}
9104 
9105 	{
9106 		TestParams	paramsArrayToArray;
9107 		const deUint32	arrayLayers						= 16u;
9108 		paramsArrayToArray.src.image.imageType			= VK_IMAGE_TYPE_2D;
9109 		paramsArrayToArray.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
9110 		paramsArrayToArray.src.image.extent				= defaultHalfExtent;
9111 		paramsArrayToArray.src.image.extent.depth		= arrayLayers;
9112 		paramsArrayToArray.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9113 		paramsArrayToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9114 		paramsArrayToArray.dst.image.imageType			= VK_IMAGE_TYPE_2D;
9115 		paramsArrayToArray.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
9116 		paramsArrayToArray.dst.image.extent				= defaultHalfExtent;
9117 		paramsArrayToArray.dst.image.extent.depth		= arrayLayers;
9118 		paramsArrayToArray.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9119 		paramsArrayToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9120 		paramsArrayToArray.allocationKind				= allocationKind;
9121 		paramsArrayToArray.extensionUse					= extensionUse;
9122 
9123 		{
9124 			const VkImageSubresourceLayers sourceLayer =
9125 					{
9126 							VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
9127 							0u,								// deUint32				mipLevel;
9128 							0u,								// deUint32				baseArrayLayer;
9129 							arrayLayers						// deUint32				layerCount;
9130 					};
9131 
9132 			const VkImageSubresourceLayers destinationLayer =
9133 					{
9134 							VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
9135 							0u,								// deUint32				mipLevel;
9136 							0u,								// deUint32				baseArrayLayer;
9137 							arrayLayers						// deUint32				layerCount;
9138 					};
9139 
9140 			const VkImageCopy				testCopy =
9141 					{
9142 							sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
9143 							{0, 0, 0},						// VkOffset3D				srcOffset;
9144 							destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
9145 							{0, 0, 0},						// VkOffset3D				dstOffset;
9146 							defaultHalfExtent				// VkExtent3D				extent;
9147 					};
9148 
9149 			CopyRegion imageCopy;
9150 			imageCopy.imageCopy = testCopy;
9151 
9152 			paramsArrayToArray.regions.push_back(imageCopy);
9153 		}
9154 
9155 		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_whole", "copy 2d array image to 2d array image all at once", paramsArrayToArray));
9156 	}
9157 
9158 	{
9159 		TestParams	paramsArrayToArray;
9160 		const deUint32	arrayLayers						= 16u;
9161 		paramsArrayToArray.src.image.imageType			= VK_IMAGE_TYPE_2D;
9162 		paramsArrayToArray.src.image.extent				= defaultHalfExtent;
9163 		paramsArrayToArray.src.image.extent.depth		= arrayLayers;
9164 		paramsArrayToArray.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9165 		paramsArrayToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9166 		paramsArrayToArray.dst.image.imageType			= VK_IMAGE_TYPE_2D;
9167 		paramsArrayToArray.dst.image.extent				= defaultHalfExtent;
9168 		paramsArrayToArray.dst.image.extent.depth		= arrayLayers;
9169 		paramsArrayToArray.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9170 		paramsArrayToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9171 		paramsArrayToArray.allocationKind				= allocationKind;
9172 		paramsArrayToArray.extensionUse					= extensionUse;
9173 		paramsArrayToArray.mipLevels					= deLog2Floor32(deMinu32(defaultHalfExtent.width, defaultHalfExtent.height)) + 1u;
9174 
9175 		for (deUint32 mipLevelNdx = 0u; mipLevelNdx < paramsArrayToArray.mipLevels; mipLevelNdx++)
9176 		{
9177 			const VkImageSubresourceLayers sourceLayer =
9178 			{
9179 				VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
9180 				mipLevelNdx,					// deUint32				mipLevel;
9181 				0u,								// deUint32				baseArrayLayer;
9182 				arrayLayers						// deUint32				layerCount;
9183 			};
9184 
9185 			const VkImageSubresourceLayers destinationLayer =
9186 			{
9187 				VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
9188 				mipLevelNdx,					// deUint32				mipLevel;
9189 				0u,								// deUint32				baseArrayLayer;
9190 				arrayLayers						// deUint32				layerCount;
9191 			};
9192 
9193 			const VkExtent3D extent =
9194 			{
9195 				(deUint32)deMax(defaultHalfExtent.width >> mipLevelNdx, 1),		// deUint32    width;
9196 				(deUint32)deMax(defaultHalfExtent.height >> mipLevelNdx, 1),	// deUint32    height;
9197 				1u,																// deUint32    depth;
9198 			};
9199 
9200 			const VkImageCopy				testCopy =
9201 			{
9202 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
9203 				{0, 0, 0},						// VkOffset3D				srcOffset;
9204 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
9205 				{0, 0, 0},						// VkOffset3D				dstOffset;
9206 				extent							// VkExtent3D				extent;
9207 			};
9208 
9209 			CopyRegion imageCopy;
9210 			imageCopy.imageCopy = testCopy;
9211 
9212 			paramsArrayToArray.regions.push_back(imageCopy);
9213 		}
9214 
9215 		VkFormat imageFormats [] = { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_S8_UINT};
9216 
9217 		for (deUint32 imageFormatsNdx = 0; imageFormatsNdx < DE_LENGTH_OF_ARRAY(imageFormats); imageFormatsNdx++)
9218 		{
9219 			paramsArrayToArray.src.image.format = imageFormats[imageFormatsNdx];
9220 			paramsArrayToArray.dst.image.format = imageFormats[imageFormatsNdx];
9221 			for (deUint32 regionNdx = 0u; regionNdx < paramsArrayToArray.regions.size(); regionNdx++)
9222 			{
9223 				paramsArrayToArray.regions[regionNdx].imageCopy.srcSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
9224 				paramsArrayToArray.regions[regionNdx].imageCopy.dstSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
9225 			}
9226 			std::ostringstream testName;
9227 			const std::string formatName = getFormatName(imageFormats[imageFormatsNdx]);
9228 			testName << "array_to_array_whole_mipmap_" << de::toLower(formatName.substr(10));
9229 			group->addChild(new CopyImageToImageMipmapTestCase(testCtx, testName.str(), "copy 2d array mipmap image to 2d array mipmap image all at once", paramsArrayToArray));
9230 		}
9231 	}
9232 }
9233 
addImageToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9234 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9235 {
9236 	addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind, extensionUse);
9237 	addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind, extensionUse);
9238 	addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind, extensionUse);
9239 	addTestGroup(group, "dimensions", "Copying operations on different image dimensions", addImageToImageDimensionsTests, allocationKind, extensionUse);
9240 	addTestGroup(group, "cube", "Coping operations on cube compatible images", addImageToImageCubeTests, allocationKind, extensionUse);
9241 	addTestGroup(group, "array", "Copying operations on array of images", addImageToImageArrayTests, allocationKind, extensionUse);
9242 }
9243 
addImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9244 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9245 {
9246 	tcu::TestContext& testCtx	= group->getTestContext();
9247 
9248 	{
9249 		TestParams	params;
9250 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
9251 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9252 		params.src.image.extent				= defaultExtent;
9253 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9254 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9255 		params.dst.buffer.size				= defaultSize * defaultSize;
9256 		params.allocationKind				= allocationKind;
9257 		params.extensionUse					= extensionUse;
9258 
9259 		const VkBufferImageCopy	bufferImageCopy	=
9260 		{
9261 			0u,											// VkDeviceSize				bufferOffset;
9262 			0u,											// deUint32					bufferRowLength;
9263 			0u,											// deUint32					bufferImageHeight;
9264 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9265 			{0, 0, 0},									// VkOffset3D				imageOffset;
9266 			defaultExtent								// VkExtent3D				imageExtent;
9267 		};
9268 		CopyRegion	copyRegion;
9269 		copyRegion.bufferImageCopy	= bufferImageCopy;
9270 
9271 		params.regions.push_back(copyRegion);
9272 
9273 		group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
9274 	}
9275 
9276 	{
9277 		TestParams	params;
9278 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
9279 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9280 		params.src.image.extent				= defaultExtent;
9281 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9282 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9283 		params.dst.buffer.size				= defaultSize * defaultSize;
9284 		params.allocationKind				= allocationKind;
9285 		params.extensionUse					= extensionUse;
9286 
9287 		const VkBufferImageCopy	bufferImageCopy	=
9288 		{
9289 			defaultSize * defaultHalfSize,				// VkDeviceSize				bufferOffset;
9290 			0u,											// deUint32					bufferRowLength;
9291 			0u,											// deUint32					bufferImageHeight;
9292 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9293 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
9294 			defaultHalfExtent							// VkExtent3D				imageExtent;
9295 		};
9296 		CopyRegion	copyRegion;
9297 		copyRegion.bufferImageCopy	= bufferImageCopy;
9298 
9299 		params.regions.push_back(copyRegion);
9300 
9301 		group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
9302 	}
9303 
9304 	{
9305 		TestParams	params;
9306 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
9307 		params.src.image.format				= VK_FORMAT_R8_UNORM;
9308 		params.src.image.extent				= defaultExtent;
9309 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9310 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9311 		params.dst.buffer.size				= defaultSize * defaultSize;
9312 		params.allocationKind				= allocationKind;
9313 		params.extensionUse					= extensionUse;
9314 
9315 		const VkBufferImageCopy	bufferImageCopy	=
9316 		{
9317 			defaultSize * defaultHalfSize + 1u,		// VkDeviceSize				bufferOffset;
9318 			0u,											// deUint32					bufferRowLength;
9319 			0u,											// deUint32					bufferImageHeight;
9320 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9321 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
9322 			defaultHalfExtent							// VkExtent3D				imageExtent;
9323 		};
9324 		CopyRegion	copyRegion;
9325 		copyRegion.bufferImageCopy	= bufferImageCopy;
9326 
9327 		params.regions.push_back(copyRegion);
9328 
9329 		group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset_relaxed", "Copy from image to buffer with buffer offset not a multiple of 4", params));
9330 	}
9331 
9332 	{
9333 		TestParams	params;
9334 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
9335 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9336 		params.src.image.extent				= defaultExtent;
9337 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9338 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9339 		params.dst.buffer.size				= defaultSize * defaultSize;
9340 		params.allocationKind				= allocationKind;
9341 		params.extensionUse					= extensionUse;
9342 
9343 		const int			pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
9344 		const VkDeviceSize	bufferSize	= pixelSize * params.dst.buffer.size;
9345 		const VkDeviceSize	offsetSize	= pixelSize * defaultFourthSize * defaultFourthSize;
9346 		deUint32			divisor		= 1;
9347 		for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
9348 		{
9349 			const deUint32			bufferRowLength		= defaultFourthSize;
9350 			const deUint32			bufferImageHeight	= defaultFourthSize;
9351 			const VkExtent3D		imageExtent			= {defaultFourthSize / divisor, defaultFourthSize, 1};
9352 			DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
9353 			DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
9354 			DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
9355 
9356 			CopyRegion				region;
9357 			const VkBufferImageCopy	bufferImageCopy		=
9358 			{
9359 				offset,						// VkDeviceSize				bufferOffset;
9360 				bufferRowLength,			// deUint32					bufferRowLength;
9361 				bufferImageHeight,			// deUint32					bufferImageHeight;
9362 				defaultSourceLayer,			// VkImageSubresourceLayers	imageSubresource;
9363 				{0, 0, 0},					// VkOffset3D				imageOffset;
9364 				imageExtent					// VkExtent3D				imageExtent;
9365 			};
9366 			region.bufferImageCopy	= bufferImageCopy;
9367 			params.regions.push_back(region);
9368 		}
9369 
9370 		group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
9371 	}
9372 
9373 	{
9374 		TestParams				params;
9375 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
9376 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9377 		params.src.image.extent				= defaultExtent;
9378 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9379 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9380 		params.dst.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
9381 		params.allocationKind				= allocationKind;
9382 		params.extensionUse					= extensionUse;
9383 
9384 		const VkBufferImageCopy	bufferImageCopy	=
9385 		{
9386 			0u,											// VkDeviceSize				bufferOffset;
9387 			defaultSize,								// deUint32					bufferRowLength;
9388 			defaultSize,								// deUint32					bufferImageHeight;
9389 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9390 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
9391 			defaultHalfExtent							// VkExtent3D				imageExtent;
9392 		};
9393 		CopyRegion				copyRegion;
9394 		copyRegion.bufferImageCopy	= bufferImageCopy;
9395 
9396 		params.regions.push_back(copyRegion);
9397 
9398 		group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
9399 	}
9400 
9401 	{
9402 		TestParams				params;
9403 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
9404 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9405 		params.src.image.extent				= defaultExtent;
9406 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9407 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9408 		params.dst.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
9409 		params.allocationKind				= allocationKind;
9410 		params.extensionUse					= extensionUse;
9411 
9412 		const VkBufferImageCopy	bufferImageCopy	=
9413 		{
9414 			defaultFourthSize,							// VkDeviceSize				bufferOffset;
9415 			defaultSize,								// deUint32					bufferRowLength;
9416 			defaultSize,								// deUint32					bufferImageHeight;
9417 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9418 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
9419 			defaultHalfExtent							// VkExtent3D				imageExtent;
9420 		};
9421 		CopyRegion				copyRegion;
9422 		copyRegion.bufferImageCopy	= bufferImageCopy;
9423 
9424 		params.regions.push_back(copyRegion);
9425 
9426 		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));
9427 	}
9428 
9429 	{
9430 		TestParams				params;
9431 		deUint32				arrayLayers = 16u;
9432 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
9433 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9434 		params.src.image.extent				= defaultHalfExtent;
9435 		params.src.image.extent.depth		= arrayLayers;
9436 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9437 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9438 		params.dst.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
9439 		params.allocationKind				= allocationKind;
9440 		params.extensionUse					= extensionUse;
9441 
9442 		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
9443 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9444 		{
9445 			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9446 			const VkBufferImageCopy bufferImageCopy =
9447 				{
9448 					offset,													// VkDeviceSize				bufferOffset;
9449 					0u,														// deUint32					bufferRowLength;
9450 					0u,														// deUint32					bufferImageHeight;
9451 					{
9452 						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
9453 						0u,												// deUint32				mipLevel;
9454 						arrayLayerNdx,									// deUint32				baseArrayLayer;
9455 						1u,												// deUint32				layerCount;
9456 					},														// VkImageSubresourceLayers	imageSubresource;
9457 					{0, 0, 0},												// VkOffset3D				imageOffset;
9458 					defaultHalfExtent										// VkExtent3D				imageExtent;
9459 				};
9460 			CopyRegion copyRegion;
9461 			copyRegion.bufferImageCopy = bufferImageCopy;
9462 
9463 			params.regions.push_back(copyRegion);
9464 		}
9465 		group->addChild(new CopyImageToBufferTestCase(testCtx, "array", "Copy each layer from array to buffer", params));
9466 	}
9467 
9468 	{
9469 		TestParams				params;
9470 		deUint32				arrayLayers = 16u;
9471 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
9472 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9473 		params.src.image.extent				= defaultHalfExtent;
9474 		params.src.image.extent.depth		= arrayLayers;
9475 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9476 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9477 		params.dst.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
9478 		params.allocationKind				= allocationKind;
9479 		params.extensionUse					= extensionUse;
9480 
9481 		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
9482 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9483 		{
9484 			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9485 			const VkBufferImageCopy bufferImageCopy =
9486 				{
9487 					offset,													// VkDeviceSize				bufferOffset;
9488 					defaultHalfSize,										// deUint32					bufferRowLength;
9489 					defaultHalfSize,										// deUint32					bufferImageHeight;
9490 					{
9491 						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
9492 						0u,												// deUint32				mipLevel;
9493 						arrayLayerNdx,									// deUint32				baseArrayLayer;
9494 						1u,												// deUint32				layerCount;
9495 					},														// VkImageSubresourceLayers	imageSubresource;
9496 					{0, 0, 0},												// VkOffset3D				imageOffset;
9497 					defaultHalfExtent										// VkExtent3D				imageExtent;
9498 				};
9499 			CopyRegion copyRegion;
9500 			copyRegion.bufferImageCopy = bufferImageCopy;
9501 
9502 			params.regions.push_back(copyRegion);
9503 		}
9504 		group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
9505 	}
9506 }
9507 
addBufferToDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9508 void addBufferToDepthStencilTests(tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9509 {
9510 	tcu::TestContext& testCtx = group->getTestContext();
9511 
9512 	const struct
9513 	{
9514 		const char*		name;
9515 		const VkFormat	format;
9516 	} depthAndStencilFormats[] =
9517 	{
9518 		{ "d16_unorm",				VK_FORMAT_D16_UNORM				},
9519 		{ "x8_d24_unorm_pack32",	VK_FORMAT_X8_D24_UNORM_PACK32	},
9520 		{ "d32_sfloat",				VK_FORMAT_D32_SFLOAT			},
9521 		{ "d16_unorm_s8_uint",		VK_FORMAT_D16_UNORM_S8_UINT		},
9522 		{ "d24_unorm_s8_uint",		VK_FORMAT_D24_UNORM_S8_UINT		},
9523 		{ "d32_sfloat_s8_uint",		VK_FORMAT_D32_SFLOAT_S8_UINT	}
9524 	};
9525 
9526 	const VkImageSubresourceLayers	depthSourceLayer		=
9527 	{
9528 		VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
9529 		0u,							// deUint32				mipLevel;
9530 		0u,							// deUint32				baseArrayLayer;
9531 		1u,							// deUint32				layerCount;
9532 	};
9533 
9534 	const VkBufferImageCopy			bufferDepthCopy			=
9535 	{
9536 		0u,											// VkDeviceSize				bufferOffset;
9537 		0u,											// deUint32					bufferRowLength;
9538 		0u,											// deUint32					bufferImageHeight;
9539 		depthSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9540 		{0, 0, 0},									// VkOffset3D				imageOffset;
9541 		defaultExtent								// VkExtent3D				imageExtent;
9542 	};
9543 
9544 	const VkBufferImageCopy			bufferDepthCopyOffset	=
9545 	{
9546 		32,											// VkDeviceSize				bufferOffset;
9547 		defaultHalfSize + defaultFourthSize,		// deUint32					bufferRowLength;
9548 		defaultHalfSize + defaultFourthSize,		// deUint32					bufferImageHeight;
9549 		depthSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9550 		{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
9551 		defaultHalfExtent							// VkExtent3D				imageExtent;
9552 	};
9553 
9554 	const VkImageSubresourceLayers	stencilSourceLayer		=
9555 	{
9556 		VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
9557 		0u,								// deUint32				mipLevel;
9558 		0u,								// deUint32				baseArrayLayer;
9559 		1u,								// deUint32				layerCount;
9560 	};
9561 
9562 	const VkBufferImageCopy			bufferStencilCopy		=
9563 	{
9564 		0u,					// VkDeviceSize				bufferOffset;
9565 		0u,					// deUint32					bufferRowLength;
9566 		0u,					// deUint32					bufferImageHeight;
9567 		stencilSourceLayer,	// VkImageSubresourceLayers	imageSubresource;
9568 		{0, 0, 0},			// VkOffset3D				imageOffset;
9569 		defaultExtent		// VkExtent3D				imageExtent;
9570 	};
9571 
9572     const VkBufferImageCopy			bufferStencilCopyOffset	=
9573 	{
9574 		32,											// VkDeviceSize				bufferOffset;
9575 		defaultHalfSize + defaultFourthSize,		// deUint32					bufferRowLength;
9576 		defaultHalfSize + defaultFourthSize,		// deUint32					bufferImageHeight;
9577 		stencilSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9578 		{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
9579 		defaultHalfExtent							// VkExtent3D				imageExtent;
9580 	};
9581 
9582     const bool						useOffset[]				= {false, true};
9583 
9584 	// Note: Depth stencil tests I want to do
9585 	// Formats: D16, D24S8, D32FS8
9586 	// Test writing each component with separate CopyBufferToImage commands
9587 	// Test writing both components in one CopyBufferToImage command
9588 	// Swap order of writes of Depth & Stencil
9589 	// whole surface, subimages?
9590 	// Similar tests as BufferToImage?
9591 	for (const auto config : depthAndStencilFormats)
9592 		for (const auto offset : useOffset)
9593 		{
9594 			// TODO: Check that this format is supported before creating tests?
9595 			//if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
9596 
9597 			CopyRegion					copyDepthRegion;
9598 			CopyRegion					copyStencilRegion;
9599 			TestParams					params;
9600 			const tcu::TextureFormat	format		= mapVkFormat(config.format);
9601 			const bool					hasDepth	= tcu::hasDepthComponent(format.order);
9602 			const bool					hasStencil	= tcu::hasStencilComponent(format.order);
9603 			std::string					description	= config.name;
9604 
9605 			if (offset)
9606 			{
9607 				copyDepthRegion.bufferImageCopy = bufferDepthCopyOffset;
9608 				copyStencilRegion.bufferImageCopy = bufferStencilCopyOffset;
9609 				description = "buffer_offset_" + description;
9610 				params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
9611 			}
9612 			else
9613 			{
9614 				copyDepthRegion.bufferImageCopy = bufferDepthCopy;
9615 				copyStencilRegion.bufferImageCopy = bufferStencilCopy;
9616 				params.src.buffer.size = defaultSize * defaultSize;
9617 			}
9618 
9619 			params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9620 			params.dst.image.format = config.format;
9621 			params.dst.image.extent = defaultExtent;
9622 			params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9623 			params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9624 			params.allocationKind = allocationKind;
9625 			params.extensionUse = extensionUse;
9626 
9627 			if (hasDepth && hasStencil)
9628 			{
9629 				params.singleCommand = DE_TRUE;
9630 
9631 				params.regions.push_back(copyDepthRegion);
9632 				params.regions.push_back(copyStencilRegion);
9633 
9634 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_DS", "Copy from depth&stencil to image", params));
9635 
9636 				params.singleCommand = DE_FALSE;
9637 
9638 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D_S", "Copy from depth then stencil to image", params));
9639 
9640 				params.regions.clear();
9641 				params.regions.push_back(copyStencilRegion);
9642 				params.regions.push_back(copyDepthRegion);
9643 
9644 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S_D", "Copy from depth then stencil to image", params));
9645 
9646 				params.singleCommand = DE_TRUE;
9647 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_SD", "Copy from depth&stencil to image", params));
9648 			}
9649 
9650 			if (hasStencil)
9651 			{
9652 				params.regions.clear();
9653 				params.regions.push_back(copyStencilRegion);
9654 
9655 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S", "Copy from stencil to image", params));
9656 			}
9657 
9658 			if (hasDepth)
9659 			{
9660 				params.regions.clear();
9661 				params.regions.push_back(copyDepthRegion);
9662 
9663 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D", "Copy from depth to image", params));
9664 			}
9665 		}
9666 }
9667 
addBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9668 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9669 {
9670 	tcu::TestContext& testCtx	= group->getTestContext();
9671 
9672 	{
9673 		TestParams	params;
9674 		params.src.buffer.size				= defaultSize * defaultSize;
9675 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
9676 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
9677 		params.dst.image.extent				= defaultExtent;
9678 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9679 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9680 		params.allocationKind				= allocationKind;
9681 		params.extensionUse					= extensionUse;
9682 
9683 		const VkBufferImageCopy	bufferImageCopy	=
9684 		{
9685 			0u,											// VkDeviceSize				bufferOffset;
9686 			0u,											// deUint32					bufferRowLength;
9687 			0u,											// deUint32					bufferImageHeight;
9688 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9689 			{0, 0, 0},									// VkOffset3D				imageOffset;
9690 			defaultExtent								// VkExtent3D				imageExtent;
9691 		};
9692 		CopyRegion	copyRegion;
9693 		copyRegion.bufferImageCopy	= bufferImageCopy;
9694 
9695 		params.regions.push_back(copyRegion);
9696 
9697 		group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
9698 	}
9699 
9700 	{
9701 		TestParams	params;
9702 		params.src.buffer.size				= defaultSize * defaultSize;
9703 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
9704 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9705 		params.dst.image.extent				= defaultExtent;
9706 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9707 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9708 		params.allocationKind				= allocationKind;
9709 		params.extensionUse					= extensionUse;
9710 
9711 		CopyRegion	region;
9712 		deUint32	divisor	= 1;
9713 		for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
9714 		{
9715 			const VkBufferImageCopy	bufferImageCopy	=
9716 			{
9717 				0u,																// VkDeviceSize				bufferOffset;
9718 				0u,																// deUint32					bufferRowLength;
9719 				0u,																// deUint32					bufferImageHeight;
9720 				defaultSourceLayer,												// VkImageSubresourceLayers	imageSubresource;
9721 				{offset, defaultHalfSize, 0},									// VkOffset3D				imageOffset;
9722 				{defaultFourthSize / divisor, defaultFourthSize / divisor, 1}	// VkExtent3D				imageExtent;
9723 			};
9724 			region.bufferImageCopy	= bufferImageCopy;
9725 			params.regions.push_back(region);
9726 		}
9727 
9728 		group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
9729 	}
9730 
9731 	{
9732 		TestParams	params;
9733 		params.src.buffer.size				= defaultSize * defaultSize;
9734 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
9735 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9736 		params.dst.image.extent				= defaultExtent;
9737 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9738 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9739 		params.allocationKind				= allocationKind;
9740 		params.extensionUse					= extensionUse;
9741 
9742 		const VkBufferImageCopy	bufferImageCopy	=
9743 		{
9744 			defaultFourthSize,							// VkDeviceSize				bufferOffset;
9745 			defaultHalfSize + defaultFourthSize,		// deUint32					bufferRowLength;
9746 			defaultHalfSize + defaultFourthSize,		// deUint32					bufferImageHeight;
9747 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9748 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
9749 			defaultHalfExtent							// VkExtent3D				imageExtent;
9750 		};
9751 		CopyRegion	copyRegion;
9752 		copyRegion.bufferImageCopy	= bufferImageCopy;
9753 
9754 		params.regions.push_back(copyRegion);
9755 
9756 		group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
9757 	}
9758 
9759 	{
9760 		TestParams	params;
9761 		params.src.buffer.size				= defaultSize * defaultSize;
9762 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
9763 		params.dst.image.format				= VK_FORMAT_R8_UNORM;
9764 		params.dst.image.extent				= defaultExtent;
9765 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9766 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9767 		params.allocationKind				= allocationKind;
9768 		params.extensionUse					= extensionUse;
9769 
9770 		const VkBufferImageCopy	bufferImageCopy	=
9771 		{
9772 			defaultFourthSize + 1u,						// VkDeviceSize				bufferOffset;
9773 			defaultHalfSize + defaultFourthSize,		// deUint32					bufferRowLength;
9774 			defaultHalfSize + defaultFourthSize,		// deUint32					bufferImageHeight;
9775 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9776 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
9777 			defaultHalfExtent							// VkExtent3D				imageExtent;
9778 		};
9779 		CopyRegion	copyRegion;
9780 		copyRegion.bufferImageCopy	= bufferImageCopy;
9781 
9782 		params.regions.push_back(copyRegion);
9783 
9784 		group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset_relaxed", "Copy from buffer to image with buffer offset not a multiple of 4", params));
9785 	}
9786 
9787 	{
9788 		TestParams				params;
9789 		params.src.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
9790 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
9791 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9792 		params.dst.image.extent				= defaultExtent;
9793 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9794 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9795 		params.allocationKind				= allocationKind;
9796 		params.extensionUse					= extensionUse;
9797 
9798 		const VkBufferImageCopy	bufferImageCopy	=
9799 		{
9800 			0u,											// VkDeviceSize				bufferOffset;
9801 			defaultSize,								// deUint32					bufferRowLength;
9802 			defaultSize,								// deUint32					bufferImageHeight;
9803 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9804 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
9805 			defaultHalfExtent							// VkExtent3D				imageExtent;
9806 		};
9807 		CopyRegion				copyRegion;
9808 		copyRegion.bufferImageCopy	= bufferImageCopy;
9809 
9810 		params.regions.push_back(copyRegion);
9811 
9812 		group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from buffer that is just large enough to contain the accessed elements", params));
9813 	}
9814 
9815 	{
9816 		TestParams				params;
9817 		params.src.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
9818 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
9819 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9820 		params.dst.image.extent				= defaultExtent;
9821 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9822 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9823 		params.allocationKind				= allocationKind;
9824 		params.extensionUse					= extensionUse;
9825 
9826 		const VkBufferImageCopy	bufferImageCopy	=
9827 		{
9828 			defaultFourthSize,							// VkDeviceSize				bufferOffset;
9829 			defaultSize,								// deUint32					bufferRowLength;
9830 			defaultSize,								// deUint32					bufferImageHeight;
9831 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
9832 			{defaultFourthSize, defaultFourthSize, 0},	// VkOffset3D				imageOffset;
9833 			defaultHalfExtent							// VkExtent3D				imageExtent;
9834 		};
9835 		CopyRegion				copyRegion;
9836 		copyRegion.bufferImageCopy	= bufferImageCopy;
9837 
9838 		params.regions.push_back(copyRegion);
9839 
9840 		group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from buffer that is just large enough to contain the accessed elements", params));
9841 	}
9842 
9843 	{
9844 		TestParams				params;
9845 		deUint32				arrayLayers = 16u;
9846 		params.src.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
9847 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
9848 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9849 		params.dst.image.extent				= defaultHalfExtent;
9850 		params.dst.image.extent.depth		= arrayLayers;
9851 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9852 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9853 		params.allocationKind				= allocationKind;
9854 		params.extensionUse					= extensionUse;
9855 
9856 		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.dst.image.format));
9857 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9858 		{
9859 			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9860 			const VkBufferImageCopy bufferImageCopy =
9861 				{
9862 					offset,													// VkDeviceSize				bufferOffset;
9863 					0u,														// deUint32					bufferRowLength;
9864 					0u,														// deUint32					bufferImageHeight;
9865 					{
9866 						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
9867 						0u,												// deUint32				mipLevel;
9868 						arrayLayerNdx,									// deUint32				baseArrayLayer;
9869 						1u,												// deUint32				layerCount;
9870 					},														// VkImageSubresourceLayers	imageSubresource;
9871 					{0, 0, 0},												// VkOffset3D				imageOffset;
9872 					defaultHalfExtent										// VkExtent3D				imageExtent;
9873 				};
9874 			CopyRegion copyRegion;
9875 			copyRegion.bufferImageCopy = bufferImageCopy;
9876 
9877 			params.regions.push_back(copyRegion);
9878 		}
9879 		group->addChild(new CopyBufferToImageTestCase(testCtx, "array", "Copy from a different part of the buffer to each layer", params));
9880 	}
9881 
9882 	{
9883 		TestParams				params;
9884 		deUint32				arrayLayers = 16u;
9885 		params.src.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
9886 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
9887 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
9888 		params.dst.image.extent				= defaultHalfExtent;
9889 		params.dst.image.extent.depth		= arrayLayers;
9890 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9891 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9892 		params.allocationKind				= allocationKind;
9893 		params.extensionUse					= extensionUse;
9894 
9895 		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.dst.image.format));
9896 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9897 		{
9898 			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9899 			const VkBufferImageCopy bufferImageCopy =
9900 				{
9901 					offset,													// VkDeviceSize				bufferOffset;
9902 					defaultHalfSize,										// deUint32					bufferRowLength;
9903 					defaultHalfSize,										// deUint32					bufferImageHeight;
9904 					{
9905 						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
9906 						0u,												// deUint32				mipLevel;
9907 						arrayLayerNdx,									// deUint32				baseArrayLayer;
9908 						1u,												// deUint32				layerCount;
9909 					},														// VkImageSubresourceLayers	imageSubresource;
9910 					{0, 0, 0},												// VkOffset3D				imageOffset;
9911 					defaultHalfExtent										// VkExtent3D				imageExtent;
9912 				};
9913 			CopyRegion copyRegion;
9914 			copyRegion.bufferImageCopy = bufferImageCopy;
9915 
9916 			params.regions.push_back(copyRegion);
9917 		}
9918 		group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from different part of tightly sized buffer to each layer", params));
9919 	}
9920 }
9921 
addBufferToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9922 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9923 {
9924 	tcu::TestContext&				testCtx					= group->getTestContext();
9925 
9926 	{
9927 		TestParams			params;
9928 		params.src.buffer.size	= defaultSize;
9929 		params.dst.buffer.size	= defaultSize;
9930 		params.allocationKind	= allocationKind;
9931 		params.extensionUse		= extensionUse;
9932 
9933 		const VkBufferCopy	bufferCopy	=
9934 		{
9935 			0u,				// VkDeviceSize	srcOffset;
9936 			0u,				// VkDeviceSize	dstOffset;
9937 			defaultSize,	// VkDeviceSize	size;
9938 		};
9939 
9940 		CopyRegion	copyRegion;
9941 		copyRegion.bufferCopy	= bufferCopy;
9942 		params.regions.push_back(copyRegion);
9943 
9944 		group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
9945 	}
9946 
9947 	// Filter is VK_FILTER_NEAREST.
9948 	{
9949 		TestParams			params;
9950 		params.src.buffer.size	= defaultFourthSize;
9951 		params.dst.buffer.size	= defaultFourthSize;
9952 		params.allocationKind	= allocationKind;
9953 		params.extensionUse		= extensionUse;
9954 
9955 		const VkBufferCopy	bufferCopy	=
9956 		{
9957 			12u,	// VkDeviceSize	srcOffset;
9958 			4u,		// VkDeviceSize	dstOffset;
9959 			1u,		// VkDeviceSize	size;
9960 		};
9961 
9962 		CopyRegion	copyRegion;
9963 		copyRegion.bufferCopy = bufferCopy;
9964 		params.regions.push_back(copyRegion);
9965 
9966 		group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
9967 	}
9968 
9969 	{
9970 		const deUint32		size		= 16;
9971 		TestParams			params;
9972 		params.src.buffer.size	= size;
9973 		params.dst.buffer.size	= size * (size + 1);
9974 		params.allocationKind	= allocationKind;
9975 		params.extensionUse		= extensionUse;
9976 
9977 		// Copy region with size 1..size
9978 		for (unsigned int i = 1; i <= size; i++)
9979 		{
9980 			const VkBufferCopy	bufferCopy	=
9981 			{
9982 				0,			// VkDeviceSize	srcOffset;
9983 				i * size,	// VkDeviceSize	dstOffset;
9984 				i,			// VkDeviceSize	size;
9985 			};
9986 
9987 			CopyRegion	copyRegion;
9988 			copyRegion.bufferCopy = bufferCopy;
9989 			params.regions.push_back(copyRegion);
9990 		}
9991 
9992 		group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
9993 	}
9994 }
9995 
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,TestParams & params)9996 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, TestParams& params)
9997 {
9998 	tcu::TestContext& testCtx = group->getTestContext();
9999 
10000 	// Filter is VK_FILTER_NEAREST.
10001 	{
10002 		params.filter					= VK_FILTER_NEAREST;
10003 		const std::string description	= "Nearest filter";
10004 
10005 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
10006 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
10007 
10008 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
10009 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
10010 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
10011 
10012 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
10013 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
10014 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
10015 	}
10016 
10017 	// Filter is VK_FILTER_LINEAR.
10018 	{
10019 		params.filter					= VK_FILTER_LINEAR;
10020 		const std::string description	= "Linear filter";
10021 
10022 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
10023 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
10024 
10025 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
10026 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
10027 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
10028 
10029 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
10030 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
10031 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
10032 	}
10033 
10034 	// Filter is VK_FILTER_CUBIC_EXT.
10035 	// Cubic filtering can only be used with 2D images.
10036 	if (params.dst.image.imageType == VK_IMAGE_TYPE_2D)
10037 	{
10038 		params.filter					= VK_FILTER_CUBIC_EXT;
10039 		const std::string description	= "Cubic filter";
10040 
10041 		params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10042 		group->addChild(new BlitImageTestCase(testCtx, "cubic", description, params));
10043 
10044 		params.dst.image.format = VK_FORMAT_R32_SFLOAT;
10045 		const std::string	descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
10046 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToR32, params));
10047 
10048 		params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
10049 		const std::string	descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
10050 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToBGRA, params));
10051 	}
10052 }
10053 
addBlittingImageSimpleWholeTests(tcu::TestCaseGroup * group,TestParams params)10054 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, TestParams params)
10055 {
10056 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10057 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10058 	params.src.image.extent			= defaultExtent;
10059 	params.dst.image.extent			= defaultExtent;
10060 	params.src.image.extent.depth	= imageDepth;
10061 	params.dst.image.extent.depth	= imageDepth;
10062 
10063 	{
10064 		const VkImageBlit imageBlit =
10065 		{
10066 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10067 			{
10068 				{ 0, 0, 0 },
10069 				{ defaultSize, defaultSize, imageDepth }
10070 			},					// VkOffset3D				srcOffsets[2];
10071 
10072 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10073 			{
10074 				{ 0, 0, 0 },
10075 				{ defaultSize, defaultSize, imageDepth }
10076 			}					// VkOffset3D				dstOffset[2];
10077 		};
10078 
10079 		CopyRegion region;
10080 		region.imageBlit = imageBlit;
10081 		params.regions.push_back(region);
10082 	}
10083 
10084 	addBlittingImageSimpleTests(group, params);
10085 }
10086 
addBlittingImageSimpleMirrorXYTests(tcu::TestCaseGroup * group,TestParams params)10087 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, TestParams params)
10088 {
10089 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10090 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10091 	params.src.image.extent			= defaultExtent;
10092 	params.dst.image.extent			= defaultExtent;
10093 	params.src.image.extent.depth	= imageDepth;
10094 	params.dst.image.extent.depth	= imageDepth;
10095 
10096 	{
10097 		const VkImageBlit imageBlit =
10098 		{
10099 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10100 			{
10101 				{0, 0, 0},
10102 				{defaultSize, defaultSize, imageDepth}
10103 			},					// VkOffset3D				srcOffsets[2];
10104 
10105 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10106 			{
10107 				{defaultSize, defaultSize, 0},
10108 				{0, 0, imageDepth}
10109 			}					// VkOffset3D				dstOffset[2];
10110 		};
10111 
10112 		CopyRegion region;
10113 		region.imageBlit = imageBlit;
10114 		params.regions.push_back(region);
10115 	}
10116 
10117 	addBlittingImageSimpleTests(group, params);
10118 }
10119 
addBlittingImageSimpleMirrorXTests(tcu::TestCaseGroup * group,TestParams params)10120 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, TestParams params)
10121 {
10122 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10123 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10124 	params.src.image.extent			= defaultExtent;
10125 	params.dst.image.extent			= defaultExtent;
10126 	params.src.image.extent.depth	= imageDepth;
10127 	params.dst.image.extent.depth	= imageDepth;
10128 
10129 	{
10130 		const VkImageBlit imageBlit =
10131 		{
10132 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10133 			{
10134 				{0, 0, 0},
10135 				{defaultSize, defaultSize, imageDepth}
10136 			},					// VkOffset3D				srcOffsets[2];
10137 
10138 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10139 			{
10140 				{defaultSize, 0, 0},
10141 				{0, defaultSize, imageDepth}
10142 			}					// VkOffset3D				dstOffset[2];
10143 		};
10144 
10145 		CopyRegion region;
10146 		region.imageBlit = imageBlit;
10147 		params.regions.push_back(region);
10148 	}
10149 
10150 	addBlittingImageSimpleTests(group, params);
10151 }
10152 
addBlittingImageSimpleMirrorYTests(tcu::TestCaseGroup * group,TestParams params)10153 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, TestParams params)
10154 {
10155 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10156 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10157 	params.src.image.extent			= defaultExtent;
10158 	params.dst.image.extent			= defaultExtent;
10159 	params.src.image.extent.depth	= imageDepth;
10160 	params.dst.image.extent.depth	= imageDepth;
10161 
10162 	{
10163 		const VkImageBlit imageBlit =
10164 		{
10165 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10166 			{
10167 				{0, 0, 0},
10168 				{defaultSize, defaultSize, imageDepth}
10169 			},					// VkOffset3D				srcOffsets[2];
10170 
10171 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10172 			{
10173 				{0, defaultSize, 0},
10174 				{defaultSize, 0, imageDepth}
10175 			}					// VkOffset3D				dstOffset[2];
10176 		};
10177 
10178 		CopyRegion region;
10179 		region.imageBlit = imageBlit;
10180 		params.regions.push_back(region);
10181 	}
10182 
10183 	addBlittingImageSimpleTests(group, params);
10184 }
10185 
addBlittingImageSimpleMirrorZTests(tcu::TestCaseGroup * group,TestParams params)10186 void addBlittingImageSimpleMirrorZTests (tcu::TestCaseGroup* group, TestParams params)
10187 {
10188 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10189 	DE_ASSERT(params.src.image.imageType == VK_IMAGE_TYPE_3D);
10190 	params.src.image.extent			= defaultExtent;
10191 	params.dst.image.extent			= defaultExtent;
10192 	params.src.image.extent.depth	= defaultSize;
10193 	params.dst.image.extent.depth	= defaultSize;
10194 
10195 	{
10196 		const VkImageBlit imageBlit =
10197 		{
10198 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10199 			{
10200 				{0, 0, 0},
10201 				{defaultSize, defaultSize, defaultSize}
10202 			},					// VkOffset3D				srcOffsets[2];
10203 
10204 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10205 			{
10206 				{0, 0, defaultSize},
10207 				{defaultSize, defaultSize, 0}
10208 			}					// VkOffset3D				dstOffset[2];
10209 		};
10210 
10211 		CopyRegion region;
10212 		region.imageBlit = imageBlit;
10213 		params.regions.push_back(region);
10214 	}
10215 
10216 	addBlittingImageSimpleTests(group, params);
10217 }
10218 
addBlittingImageSimpleMirrorSubregionsTests(tcu::TestCaseGroup * group,TestParams params)10219 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, TestParams params)
10220 {
10221 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10222 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10223 	params.src.image.extent			= defaultExtent;
10224 	params.dst.image.extent			= defaultExtent;
10225 	params.src.image.extent.depth	= imageDepth;
10226 	params.dst.image.extent.depth	= imageDepth;
10227 
10228 	// No mirroring.
10229 	{
10230 		const VkImageBlit imageBlit =
10231 		{
10232 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10233 			{
10234 				{0, 0, 0},
10235 				{defaultHalfSize, defaultHalfSize, imageDepth}
10236 			},					// VkOffset3D				srcOffsets[2];
10237 
10238 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10239 			{
10240 				{0, 0, 0},
10241 				{defaultHalfSize, defaultHalfSize, imageDepth}
10242 			}					// VkOffset3D				dstOffset[2];
10243 		};
10244 
10245 		CopyRegion region;
10246 		region.imageBlit = imageBlit;
10247 		params.regions.push_back(region);
10248 	}
10249 
10250 	// Flipping y coordinates.
10251 	{
10252 		const VkImageBlit imageBlit =
10253 		{
10254 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10255 			{
10256 				{defaultHalfSize, 0, 0},
10257 				{defaultSize, defaultHalfSize, imageDepth}
10258 			},					// VkOffset3D				srcOffsets[2];
10259 
10260 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10261 			{
10262 				{defaultHalfSize, defaultHalfSize, 0},
10263 				{defaultSize, 0, imageDepth}
10264 			}					// VkOffset3D				dstOffset[2];
10265 		};
10266 		CopyRegion region;
10267 		region.imageBlit = imageBlit;
10268 		params.regions.push_back(region);
10269 	}
10270 
10271 	// Flipping x coordinates.
10272 	{
10273 		const VkImageBlit imageBlit =
10274 		{
10275 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10276 			{
10277 				{0, defaultHalfSize, 0},
10278 				{defaultHalfSize, defaultSize, imageDepth}
10279 			},					// VkOffset3D				srcOffsets[2];
10280 
10281 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10282 			{
10283 				{defaultHalfSize, defaultHalfSize, 0},
10284 				{0, defaultSize, imageDepth}
10285 			}					// VkOffset3D				dstOffset[2];
10286 		};
10287 
10288 		CopyRegion region;
10289 		region.imageBlit = imageBlit;
10290 		params.regions.push_back(region);
10291 	}
10292 
10293 	// Flipping x and y coordinates.
10294 	{
10295 		const VkImageBlit imageBlit =
10296 		{
10297 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10298 			{
10299 				{defaultHalfSize, defaultHalfSize, 0},
10300 				{defaultSize, defaultSize, imageDepth}
10301 			},					// VkOffset3D				srcOffsets[2];
10302 
10303 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10304 			{
10305 				{defaultSize, defaultSize, 0},
10306 				{defaultHalfSize, defaultHalfSize, imageDepth}
10307 			}					// VkOffset3D				dstOffset[2];
10308 		};
10309 
10310 		CopyRegion region;
10311 		region.imageBlit = imageBlit;
10312 		params.regions.push_back(region);
10313 	}
10314 
10315 	addBlittingImageSimpleTests(group, params);
10316 }
10317 
addBlittingImageSimpleScalingWhole1Tests(tcu::TestCaseGroup * group,TestParams params)10318 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, TestParams params)
10319 {
10320 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10321 	const deInt32	imageDepth		= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10322 	const deInt32	halfImageDepth	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
10323 	params.src.image.extent			= defaultExtent;
10324 	params.dst.image.extent			= defaultHalfExtent;
10325 	params.src.image.extent.depth	= imageDepth;
10326 	params.dst.image.extent.depth	= halfImageDepth;
10327 
10328 	{
10329 		const VkImageBlit imageBlit =
10330 		{
10331 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10332 			{
10333 				{0, 0, 0},
10334 				{defaultSize, defaultSize, imageDepth}
10335 			},					// VkOffset3D					srcOffsets[2];
10336 
10337 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10338 			{
10339 				{0, 0, 0},
10340 				{defaultHalfSize, defaultHalfSize, halfImageDepth}
10341 			}					// VkOffset3D					dstOffset[2];
10342 		};
10343 
10344 		CopyRegion region;
10345 		region.imageBlit = imageBlit;
10346 		params.regions.push_back(region);
10347 	}
10348 
10349 	addBlittingImageSimpleTests(group, params);
10350 }
10351 
addBlittingImageSimpleScalingWhole2Tests(tcu::TestCaseGroup * group,TestParams params)10352 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, TestParams params)
10353 {
10354 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10355 	const deInt32	imageDepth		= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10356 	const deInt32	halfImageDepth	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
10357 	params.src.image.extent			= defaultHalfExtent;
10358 	params.dst.image.extent			= defaultExtent;
10359 	params.src.image.extent.depth	= halfImageDepth;
10360 	params.dst.image.extent.depth	= imageDepth;
10361 
10362 	{
10363 		const VkImageBlit imageBlit =
10364 		{
10365 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10366 			{
10367 				{0, 0, 0},
10368 				{defaultHalfSize, defaultHalfSize, halfImageDepth}
10369 			},					// VkOffset3D					srcOffsets[2];
10370 
10371 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10372 			{
10373 				{0, 0, 0},
10374 				{defaultSize, defaultSize, imageDepth}
10375 			}					// VkOffset3D					dstOffset[2];
10376 		};
10377 
10378 		CopyRegion region;
10379 		region.imageBlit = imageBlit;
10380 		params.regions.push_back(region);
10381 	}
10382 
10383 	addBlittingImageSimpleTests(group, params);
10384 }
10385 
addBlittingImageSimpleScalingAndOffsetTests(tcu::TestCaseGroup * group,TestParams params)10386 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, TestParams params)
10387 {
10388 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10389 	const deInt32	imageDepth		= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10390 	const deInt32	srcDepthOffset	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultFourthSize : 0;
10391 	const deInt32	srcDepthSize	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultFourthSize * 3 : 1;
10392 	params.src.image.extent			= defaultExtent;
10393 	params.dst.image.extent			= defaultExtent;
10394 	params.src.image.extent.depth	= imageDepth;
10395 	params.dst.image.extent.depth	= imageDepth;
10396 
10397 	{
10398 		const VkImageBlit imageBlit =
10399 		{
10400 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10401 			{
10402 				{defaultFourthSize, defaultFourthSize, srcDepthOffset},
10403 				{defaultFourthSize*3, defaultFourthSize*3, srcDepthSize}
10404 			},					// VkOffset3D					srcOffsets[2];
10405 
10406 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10407 			{
10408 				{0, 0, 0},
10409 				{defaultSize, defaultSize, imageDepth}
10410 			}					// VkOffset3D					dstOffset[2];
10411 		};
10412 
10413 		CopyRegion region;
10414 		region.imageBlit = imageBlit;
10415 		params.regions.push_back(region);
10416 	}
10417 
10418 	addBlittingImageSimpleTests(group, params);
10419 }
10420 
addBlittingImageSimpleWithoutScalingPartialTests(tcu::TestCaseGroup * group,TestParams params)10421 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, TestParams params)
10422 {
10423 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10424 	const bool is3dBlit = params.src.image.imageType == VK_IMAGE_TYPE_3D;
10425 	params.src.image.extent	= defaultExtent;
10426 	params.dst.image.extent	= defaultExtent;
10427 
10428 	if (is3dBlit)
10429 	{
10430 		params.src.image.extent.depth = defaultSize;
10431 		params.dst.image.extent.depth = defaultSize;
10432 	}
10433 
10434 	{
10435 		CopyRegion region;
10436 		for (int i = 0; i < defaultSize; i += defaultFourthSize)
10437 		{
10438 			const VkImageBlit imageBlit =
10439 			{
10440 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
10441 				{
10442 					{defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, is3dBlit ? defaultSize - defaultFourthSize - i : 0},
10443 					{defaultSize - i, defaultSize - i, is3dBlit ? defaultSize - i : 1}
10444 				},					// VkOffset3D					srcOffsets[2];
10445 
10446 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
10447 				{
10448 					{i, i, is3dBlit ? i : 0},
10449 					{i + defaultFourthSize, i + defaultFourthSize, is3dBlit ? i + defaultFourthSize : 1}
10450 				}					// VkOffset3D					dstOffset[2];
10451 			};
10452 			region.imageBlit = imageBlit;
10453 			params.regions.push_back(region);
10454 		}
10455 	}
10456 
10457 	addBlittingImageSimpleTests(group, params);
10458 }
10459 
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10460 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10461 {
10462 	TestParams params;
10463 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
10464 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10465 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10466 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10467 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10468 	params.allocationKind				= allocationKind;
10469 	params.extensionUse					= extensionUse;
10470 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
10471 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
10472 	addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
10473 	addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, params);
10474 	addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, params);
10475 	addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, params);
10476 	addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
10477 	addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
10478 	addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
10479 	addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
10480 	addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
10481 
10482 	params.src.image.imageType			= VK_IMAGE_TYPE_3D;
10483 	params.dst.image.imageType			= VK_IMAGE_TYPE_3D;
10484 	addTestGroup(group, "whole_3d", "3D blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
10485 	addTestGroup(group, "mirror_xy_3d", "Flipping x and y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXYTests, params);
10486 	addTestGroup(group, "mirror_x_3d", "Flipping x coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXTests, params);
10487 	addTestGroup(group, "mirror_y_3d", "Flipping y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorYTests, params);
10488 	addTestGroup(group, "mirror_z_3d", "Flipping z coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorZTests, params);
10489 	addTestGroup(group, "mirror_subregions_3d", "Mirroring subregions in a 3D image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
10490 	addTestGroup(group, "scaling_whole1_3d", "3D blit a with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
10491 	addTestGroup(group, "scaling_whole2_3d", "3D blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
10492 	addTestGroup(group, "scaling_and_offset_3d", "3D blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
10493 	addTestGroup(group, "without_scaling_partial_3d", "3D blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
10494 }
10495 
10496 enum FilterMaskBits
10497 {
10498 	FILTER_MASK_NEAREST	= 0,			// Always tested.
10499 	FILTER_MASK_LINEAR	= (1u << 0),
10500 	FILTER_MASK_CUBIC	= (1u << 1),
10501 };
10502 
10503 using FilterMask = deUint32;
10504 
makeFilterMask(bool onlyNearest,bool discardCubicFilter)10505 FilterMask makeFilterMask (bool onlyNearest, bool discardCubicFilter)
10506 {
10507 	FilterMask mask = FILTER_MASK_NEAREST;
10508 
10509 	if (!onlyNearest)
10510 	{
10511 		mask |= FILTER_MASK_LINEAR;
10512 		if (!discardCubicFilter)
10513 			mask |= FILTER_MASK_CUBIC;
10514 	}
10515 
10516 	return mask;
10517 }
10518 
10519 struct BlitColorTestParams
10520 {
10521 	TestParams		params;
10522 	const VkFormat*	compatibleFormats;
10523 	FilterMask		testFilters;
10524 };
10525 
isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams & testParams)10526 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
10527 {
10528 	bool result = true;
10529 
10530 	if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
10531 	{
10532 		DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
10533 
10534 		result =
10535 			de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
10536 			de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
10537 	}
10538 
10539 	return result;
10540 }
10541 
10542 const VkFormat	linearOtherImageFormatsToTest[]	=
10543 {
10544 	// From compatibleFormats8Bit
10545 	VK_FORMAT_R4G4_UNORM_PACK8,
10546 	VK_FORMAT_R8_SRGB,
10547 
10548 	// From compatibleFormats16Bit
10549 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
10550 	VK_FORMAT_R16_SFLOAT,
10551 
10552 	// From compatibleFormats24Bit
10553 	VK_FORMAT_R8G8B8_UNORM,
10554 	VK_FORMAT_B8G8R8_SRGB,
10555 
10556 	// From compatibleFormats32Bit
10557 	VK_FORMAT_R8G8B8A8_UNORM,
10558 	VK_FORMAT_R32_SFLOAT,
10559 
10560 	// From compatibleFormats48Bit
10561 	VK_FORMAT_R16G16B16_UNORM,
10562 	VK_FORMAT_R16G16B16_SFLOAT,
10563 
10564 	// From compatibleFormats64Bit
10565 	VK_FORMAT_R16G16B16A16_UNORM,
10566 	VK_FORMAT_R64_SFLOAT,
10567 
10568 	// From compatibleFormats96Bit
10569 	VK_FORMAT_R32G32B32_UINT,
10570 	VK_FORMAT_R32G32B32_SFLOAT,
10571 
10572 	// From compatibleFormats128Bit
10573 	VK_FORMAT_R32G32B32A32_UINT,
10574 	VK_FORMAT_R64G64_SFLOAT,
10575 
10576 	// From compatibleFormats192Bit
10577 	VK_FORMAT_R64G64B64_UINT,
10578 	VK_FORMAT_R64G64B64_SFLOAT,
10579 
10580 	// From compatibleFormats256Bit
10581 	VK_FORMAT_R64G64B64A64_UINT,
10582 	VK_FORMAT_R64G64B64A64_SFLOAT,
10583 };
10584 
getBlitImageTilingLayoutCaseName(VkImageTiling tiling,VkImageLayout layout)10585 std::string getBlitImageTilingLayoutCaseName (VkImageTiling tiling, VkImageLayout layout)
10586 {
10587 	switch (tiling)
10588 	{
10589 		case VK_IMAGE_TILING_OPTIMAL:
10590 			return getImageLayoutCaseName(layout);
10591 		case VK_IMAGE_TILING_LINEAR:
10592 			return "linear";
10593 		default:
10594 			DE_ASSERT(false);
10595 			return "";
10596 	}
10597 }
10598 
addBlittingImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)10599 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
10600 {
10601 	tcu::TestContext& testCtx				= group->getTestContext();
10602 
10603 	FormatSet linearOtherImageFormatsToTestSet;
10604 	const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
10605 	for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter; ++otherImageFormatsIndex)
10606 		linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);
10607 
10608 	const VkImageTiling blitSrcTilings[]	=
10609 	{
10610 		VK_IMAGE_TILING_OPTIMAL,
10611 		VK_IMAGE_TILING_LINEAR,
10612 	};
10613 	const VkImageLayout blitSrcLayouts[]	=
10614 	{
10615 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
10616 		VK_IMAGE_LAYOUT_GENERAL
10617 	};
10618 	const VkImageTiling blitDstTilings[]	=
10619 	{
10620 		VK_IMAGE_TILING_OPTIMAL,
10621 		VK_IMAGE_TILING_LINEAR,
10622 	};
10623 	const VkImageLayout blitDstLayouts[]	=
10624 	{
10625 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
10626 		VK_IMAGE_LAYOUT_GENERAL
10627 	};
10628 
10629 	for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
10630 	{
10631 		testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];
10632 
10633 		for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
10634 		{
10635 			testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
10636 
10637 			// 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
10638 			if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
10639 				continue;
10640 
10641 			for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
10642 			{
10643 				testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];
10644 
10645 				for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
10646 				{
10647 					testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
10648 
10649 					// 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
10650 					if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
10651 						continue;
10652 
10653 					if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
10654 					    (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
10655 						continue;
10656 
10657 					testParams.params.filter			= VK_FILTER_NEAREST;
10658 					const std::string testName			= getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) + "_" +
10659 														  getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
10660 					const std::string description		= "Blit from layout " + getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) +
10661 														  " to " + getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
10662 					group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params));
10663 
10664 					if (testParams.testFilters & FILTER_MASK_LINEAR)
10665 					{
10666 						testParams.params.filter = VK_FILTER_LINEAR;
10667 						group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params));
10668 					}
10669 
10670 					if (testParams.testFilters & FILTER_MASK_CUBIC)
10671 					{
10672 						testParams.params.filter = VK_FILTER_CUBIC_EXT;
10673 						group->addChild(new BlitImageTestCase(testCtx, testName + "_cubic", description, testParams.params));
10674 					}
10675 
10676 					if ((testParams.params.src.image.imageType == VK_IMAGE_TYPE_3D) && !isCompressedFormat(testParams.params.src.image.format))
10677 					{
10678 						const struct
10679 						{
10680 							FillMode	mode;
10681 							const char*	name;
10682 						} modeList[] =
10683 						{
10684 							{ FILL_MODE_BLUE_RED_X, "x" },
10685 							{ FILL_MODE_BLUE_RED_Y, "y" },
10686 							{ FILL_MODE_BLUE_RED_Z, "z" },
10687 						};
10688 
10689 						auto otherParams = testParams;
10690 						otherParams.params.dst.image.fillMode = FILL_MODE_WHITE;
10691 
10692 						for (int i = 0; i < DE_LENGTH_OF_ARRAY(modeList); ++i)
10693 						{
10694 							otherParams.params.src.image.fillMode = modeList[i].mode;
10695 
10696 							otherParams.params.filter = VK_FILTER_LINEAR;
10697 							group->addChild(new BlitImageTestCase(testCtx, testName + "_linear_stripes_" + modeList[i].name, description, otherParams.params));
10698 
10699 							otherParams.params.filter = VK_FILTER_NEAREST;
10700 							group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest_stripes_" + modeList[i].name, description, otherParams.params));
10701 						}
10702 					}
10703 				}
10704 			}
10705 		}
10706 	}
10707 }
10708 
addBlittingImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)10709 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
10710 {
10711 	VkFormat srcFormat = testParams.params.src.image.format;
10712 
10713 	if (testParams.compatibleFormats)
10714 	{
10715 		for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
10716 		{
10717 			testParams.params.dst.image.format	= testParams.compatibleFormats[dstFormatIndex];
10718 			if (!isSupportedByFramework(testParams.params.dst.image.format))
10719 				continue;
10720 
10721 			if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
10722 				continue;
10723 
10724 			const std::string description	= "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
10725 			addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
10726 		}
10727 	}
10728 
10729 	// If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format
10730 	// When testParams.compatibleFormats is not nullptr but format is compressed we also need to add that format
10731 	// as it is not on compatibleFormats list
10732 	if (!testParams.compatibleFormats || isCompressedFormat(srcFormat))
10733 	{
10734 		testParams.params.dst.image.format = srcFormat;
10735 
10736 		const std::string description = "Blit destination format " + getFormatCaseName(srcFormat);
10737 		addTestGroup(group, getFormatCaseName(srcFormat), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
10738 	}
10739 }
10740 
10741 const VkFormat	compatibleFormatsUInts[]	=
10742 {
10743 	VK_FORMAT_R8_UINT,
10744 	VK_FORMAT_R8G8_UINT,
10745 	VK_FORMAT_R8G8B8_UINT,
10746 	VK_FORMAT_B8G8R8_UINT,
10747 	VK_FORMAT_R8G8B8A8_UINT,
10748 	VK_FORMAT_B8G8R8A8_UINT,
10749 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
10750 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
10751 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
10752 	VK_FORMAT_R16_UINT,
10753 	VK_FORMAT_R16G16_UINT,
10754 	VK_FORMAT_R16G16B16_UINT,
10755 	VK_FORMAT_R16G16B16A16_UINT,
10756 	VK_FORMAT_R32_UINT,
10757 	VK_FORMAT_R32G32_UINT,
10758 	VK_FORMAT_R32G32B32_UINT,
10759 	VK_FORMAT_R32G32B32A32_UINT,
10760 	VK_FORMAT_R64_UINT,
10761 	VK_FORMAT_R64G64_UINT,
10762 	VK_FORMAT_R64G64B64_UINT,
10763 	VK_FORMAT_R64G64B64A64_UINT,
10764 
10765 	VK_FORMAT_UNDEFINED
10766 };
10767 const VkFormat	compatibleFormatsSInts[]	=
10768 {
10769 	VK_FORMAT_R8_SINT,
10770 	VK_FORMAT_R8G8_SINT,
10771 	VK_FORMAT_R8G8B8_SINT,
10772 	VK_FORMAT_B8G8R8_SINT,
10773 	VK_FORMAT_R8G8B8A8_SINT,
10774 	VK_FORMAT_B8G8R8A8_SINT,
10775 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
10776 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
10777 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
10778 	VK_FORMAT_R16_SINT,
10779 	VK_FORMAT_R16G16_SINT,
10780 	VK_FORMAT_R16G16B16_SINT,
10781 	VK_FORMAT_R16G16B16A16_SINT,
10782 	VK_FORMAT_R32_SINT,
10783 	VK_FORMAT_R32G32_SINT,
10784 	VK_FORMAT_R32G32B32_SINT,
10785 	VK_FORMAT_R32G32B32A32_SINT,
10786 	VK_FORMAT_R64_SINT,
10787 	VK_FORMAT_R64G64_SINT,
10788 	VK_FORMAT_R64G64B64_SINT,
10789 	VK_FORMAT_R64G64B64A64_SINT,
10790 
10791 	VK_FORMAT_UNDEFINED
10792 };
10793 const VkFormat	compatibleFormatsFloats[]	=
10794 {
10795 	VK_FORMAT_R4G4_UNORM_PACK8,
10796 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
10797 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
10798 	VK_FORMAT_R5G6B5_UNORM_PACK16,
10799 	VK_FORMAT_B5G6R5_UNORM_PACK16,
10800 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
10801 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
10802 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
10803 	VK_FORMAT_R8_UNORM,
10804 	VK_FORMAT_R8_SNORM,
10805 	VK_FORMAT_R8_USCALED,
10806 	VK_FORMAT_R8_SSCALED,
10807 	VK_FORMAT_R8G8_UNORM,
10808 	VK_FORMAT_R8G8_SNORM,
10809 	VK_FORMAT_R8G8_USCALED,
10810 	VK_FORMAT_R8G8_SSCALED,
10811 	VK_FORMAT_R8G8B8_UNORM,
10812 	VK_FORMAT_R8G8B8_SNORM,
10813 	VK_FORMAT_R8G8B8_USCALED,
10814 	VK_FORMAT_R8G8B8_SSCALED,
10815 	VK_FORMAT_B8G8R8_UNORM,
10816 	VK_FORMAT_B8G8R8_SNORM,
10817 	VK_FORMAT_B8G8R8_USCALED,
10818 	VK_FORMAT_B8G8R8_SSCALED,
10819 	VK_FORMAT_R8G8B8A8_UNORM,
10820 	VK_FORMAT_R8G8B8A8_SNORM,
10821 	VK_FORMAT_R8G8B8A8_USCALED,
10822 	VK_FORMAT_R8G8B8A8_SSCALED,
10823 	VK_FORMAT_B8G8R8A8_UNORM,
10824 	VK_FORMAT_B8G8R8A8_SNORM,
10825 	VK_FORMAT_B8G8R8A8_USCALED,
10826 	VK_FORMAT_B8G8R8A8_SSCALED,
10827 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
10828 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
10829 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
10830 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
10831 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
10832 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
10833 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
10834 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
10835 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
10836 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
10837 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
10838 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
10839 	VK_FORMAT_R16_UNORM,
10840 	VK_FORMAT_R16_SNORM,
10841 	VK_FORMAT_R16_USCALED,
10842 	VK_FORMAT_R16_SSCALED,
10843 	VK_FORMAT_R16_SFLOAT,
10844 	VK_FORMAT_R16G16_UNORM,
10845 	VK_FORMAT_R16G16_SNORM,
10846 	VK_FORMAT_R16G16_USCALED,
10847 	VK_FORMAT_R16G16_SSCALED,
10848 	VK_FORMAT_R16G16_SFLOAT,
10849 	VK_FORMAT_R16G16B16_UNORM,
10850 	VK_FORMAT_R16G16B16_SNORM,
10851 	VK_FORMAT_R16G16B16_USCALED,
10852 	VK_FORMAT_R16G16B16_SSCALED,
10853 	VK_FORMAT_R16G16B16_SFLOAT,
10854 	VK_FORMAT_R16G16B16A16_UNORM,
10855 	VK_FORMAT_R16G16B16A16_SNORM,
10856 	VK_FORMAT_R16G16B16A16_USCALED,
10857 	VK_FORMAT_R16G16B16A16_SSCALED,
10858 	VK_FORMAT_R16G16B16A16_SFLOAT,
10859 	VK_FORMAT_R32_SFLOAT,
10860 	VK_FORMAT_R32G32_SFLOAT,
10861 	VK_FORMAT_R32G32B32_SFLOAT,
10862 	VK_FORMAT_R32G32B32A32_SFLOAT,
10863 	VK_FORMAT_R64_SFLOAT,
10864 	VK_FORMAT_R64G64_SFLOAT,
10865 	VK_FORMAT_R64G64B64_SFLOAT,
10866 	VK_FORMAT_R64G64B64A64_SFLOAT,
10867 	VK_FORMAT_B10G11R11_UFLOAT_PACK32,
10868 	VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
10869 
10870 	VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
10871 	VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
10872 
10873 	VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
10874 
10875 	VK_FORMAT_UNDEFINED
10876 };
10877 
10878 const VkFormat	compressedFormatsFloats[] =
10879 {
10880 	VK_FORMAT_BC1_RGB_UNORM_BLOCK,
10881 	VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
10882 	VK_FORMAT_BC2_UNORM_BLOCK,
10883 	VK_FORMAT_BC3_UNORM_BLOCK,
10884 	VK_FORMAT_BC4_UNORM_BLOCK,
10885 	VK_FORMAT_BC4_SNORM_BLOCK,
10886 	VK_FORMAT_BC5_UNORM_BLOCK,
10887 	VK_FORMAT_BC5_SNORM_BLOCK,
10888 	VK_FORMAT_BC6H_UFLOAT_BLOCK,
10889 	VK_FORMAT_BC6H_SFLOAT_BLOCK,
10890 	VK_FORMAT_BC7_UNORM_BLOCK,
10891 	VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
10892 	VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
10893 	VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
10894 	VK_FORMAT_EAC_R11_UNORM_BLOCK,
10895 	VK_FORMAT_EAC_R11_SNORM_BLOCK,
10896 	VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
10897 	VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
10898 	VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
10899 	VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
10900 	VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
10901 	VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
10902 	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
10903 	VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
10904 	VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
10905 	VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
10906 	VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
10907 	VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
10908 	VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
10909 	VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
10910 	VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
10911 	VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
10912 
10913 	VK_FORMAT_UNDEFINED
10914 };
10915 
10916 const VkFormat	compatibleFormatsSrgb[]		=
10917 {
10918 	VK_FORMAT_R8_SRGB,
10919 	VK_FORMAT_R8G8_SRGB,
10920 	VK_FORMAT_R8G8B8_SRGB,
10921 	VK_FORMAT_B8G8R8_SRGB,
10922 	VK_FORMAT_R8G8B8A8_SRGB,
10923 	VK_FORMAT_B8G8R8A8_SRGB,
10924 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
10925 
10926 	VK_FORMAT_UNDEFINED
10927 };
10928 
10929 const VkFormat	compressedFormatsSrgb[] =
10930 {
10931 	VK_FORMAT_BC1_RGB_SRGB_BLOCK,
10932 	VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
10933 	VK_FORMAT_BC2_SRGB_BLOCK,
10934 	VK_FORMAT_BC3_SRGB_BLOCK,
10935 	VK_FORMAT_BC7_SRGB_BLOCK,
10936 	VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
10937 	VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
10938 	VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
10939 	VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
10940 	VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
10941 	VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
10942 	VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
10943 	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
10944 	VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
10945 	VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
10946 	VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
10947 	VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
10948 	VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
10949 	VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
10950 	VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
10951 	VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
10952 	VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
10953 
10954 	VK_FORMAT_UNDEFINED
10955 };
10956 
10957 const VkFormat	dedicatedAllocationBlittingFormatsToTest[]	=
10958 {
10959 	// compatibleFormatsUInts
10960 	VK_FORMAT_R8_UINT,
10961 	VK_FORMAT_R64G64B64A64_UINT,
10962 
10963 	// compatibleFormatsSInts
10964 	VK_FORMAT_R8_SINT,
10965 	VK_FORMAT_R64G64B64A64_SINT,
10966 
10967 	// compatibleFormatsFloats
10968 	VK_FORMAT_R4G4_UNORM_PACK8,
10969 	VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
10970 
10971 	// compatibleFormatsSrgb
10972 	VK_FORMAT_R8_SRGB,
10973 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
10974 };
10975 
10976 // skip cubic filtering test for the following data formats
10977 const FormatSet	onlyNearestAndLinearFormatsToTest =
10978 {
10979 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
10980 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
10981 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
10982 	VK_FORMAT_A8B8G8R8_SINT_PACK32
10983 };
10984 
10985 // astc formats have diferent block sizes and thus require diferent resolutions for images
10986 enum class AstcImageSizeType
10987 {
10988 	SIZE_64_64 = 0,
10989 	SIZE_60_64,
10990 	SIZE_64_60,
10991 	SIZE_60_60,
10992 };
10993 
10994 const std::map<VkFormat, AstcImageSizeType> astcSizes
10995 {
10996 	{ VK_FORMAT_ASTC_4x4_SRGB_BLOCK,	AstcImageSizeType::SIZE_64_64 },
10997 	{ VK_FORMAT_ASTC_4x4_UNORM_BLOCK,	AstcImageSizeType::SIZE_64_64 },
10998 	{ VK_FORMAT_ASTC_5x4_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_64 },
10999 	{ VK_FORMAT_ASTC_5x4_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_64 },
11000 	{ VK_FORMAT_ASTC_5x5_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11001 	{ VK_FORMAT_ASTC_5x5_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11002 	{ VK_FORMAT_ASTC_6x5_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11003 	{ VK_FORMAT_ASTC_6x5_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11004 	{ VK_FORMAT_ASTC_6x6_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11005 	{ VK_FORMAT_ASTC_6x6_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11006 	{ VK_FORMAT_ASTC_8x5_SRGB_BLOCK,	AstcImageSizeType::SIZE_64_60 },
11007 	{ VK_FORMAT_ASTC_8x5_UNORM_BLOCK,	AstcImageSizeType::SIZE_64_60 },
11008 	{ VK_FORMAT_ASTC_8x6_SRGB_BLOCK,	AstcImageSizeType::SIZE_64_60 },
11009 	{ VK_FORMAT_ASTC_8x6_UNORM_BLOCK,	AstcImageSizeType::SIZE_64_60 },
11010 	{ VK_FORMAT_ASTC_8x8_SRGB_BLOCK,	AstcImageSizeType::SIZE_64_64 },
11011 	{ VK_FORMAT_ASTC_8x8_UNORM_BLOCK,	AstcImageSizeType::SIZE_64_64 },
11012 	{ VK_FORMAT_ASTC_10x5_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11013 	{ VK_FORMAT_ASTC_10x5_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11014 	{ VK_FORMAT_ASTC_10x6_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11015 	{ VK_FORMAT_ASTC_10x6_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11016 	{ VK_FORMAT_ASTC_10x8_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_64 },
11017 	{ VK_FORMAT_ASTC_10x8_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_64 },
11018 	{ VK_FORMAT_ASTC_10x10_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11019 	{ VK_FORMAT_ASTC_10x10_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11020 	{ VK_FORMAT_ASTC_12x10_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11021 	{ VK_FORMAT_ASTC_12x10_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11022 	{ VK_FORMAT_ASTC_12x12_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
11023 	{ VK_FORMAT_ASTC_12x12_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 }
11024 };
11025 
create2DCopyRegions(deInt32 srcWidth,deInt32 srcHeight,deInt32 dstWidth,deInt32 dstHeight)11026 std::vector<CopyRegion> create2DCopyRegions(deInt32 srcWidth, deInt32 srcHeight, deInt32 dstWidth, deInt32 dstHeight)
11027 {
11028 	CopyRegion				region;
11029 	std::vector<CopyRegion>	regionsVector;
11030 
11031 	deInt32					fourthOfSrcWidth	= srcWidth / 4;
11032 	deInt32					fourthOfSrcHeight	= srcHeight / 4;
11033 	deInt32					fourthOfDstWidth	= dstWidth / 4;
11034 	deInt32					fourthOfDstHeight	= dstHeight / 4;
11035 
11036 	// to the top of resulting image copy whole source image but with increasingly smaller sizes
11037 	for (int i = 0, j = 1; (i + fourthOfDstWidth / j < dstWidth) && (fourthOfDstWidth > j); i += fourthOfDstWidth / j++)
11038 	{
11039 		region.imageBlit =
11040 		{
11041 			defaultSourceLayer,						// VkImageSubresourceLayers		srcSubresource;
11042 			{
11043 				{0, 0, 0},
11044 				{srcWidth, srcHeight, 1}
11045 			},										// VkOffset3D					srcOffsets[2];
11046 
11047 			defaultSourceLayer,						// VkImageSubresourceLayers		dstSubresource;
11048 			{
11049 				{i, 0, 0},
11050 				{i + fourthOfDstWidth / j, fourthOfDstHeight / j, 1}
11051 			}										// VkOffset3D					dstOffset[2];
11052 		};
11053 		regionsVector.push_back(region);
11054 	}
11055 
11056 	// to the bottom of resulting image copy parts of source image;
11057 	for (int i = 0; i < 4; ++i)
11058 	{
11059 		int srcX = i * fourthOfSrcWidth;
11060 		int srcY = i * fourthOfSrcHeight;
11061 		int dstX = i * fourthOfDstWidth;
11062 
11063 		region.imageBlit =
11064 		{
11065 			defaultSourceLayer,						// VkImageSubresourceLayers		srcSubresource;
11066 			{
11067 				{srcX, srcY, 0},
11068 				{srcX + fourthOfSrcWidth, srcY + fourthOfSrcHeight, 1}
11069 			},										// VkOffset3D					srcOffsets[2];
11070 
11071 			defaultSourceLayer,						// VkImageSubresourceLayers		dstSubresource;
11072 			{
11073 				{dstX, 2 * fourthOfDstHeight, 0},
11074 				{dstX + fourthOfDstWidth, 3 * fourthOfDstHeight, 1}
11075 			}										// VkOffset3D					dstOffset[2];
11076 		};
11077 
11078 		regionsVector.push_back(region);
11079 	}
11080 
11081 	return regionsVector;
11082 }
11083 
addBlittingImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11084 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11085 {
11086 	const struct {
11087 		const VkFormat*	sourceFormats;
11088 		const VkFormat*	destinationFormats;
11089 		const bool		onlyNearest;
11090 	}	colorImageFormatsToTestBlit[] =
11091 	{
11092 		{ compatibleFormatsUInts,	compatibleFormatsUInts,		true	},
11093 		{ compatibleFormatsSInts,	compatibleFormatsSInts,		true	},
11094 		{ compatibleFormatsFloats,	compatibleFormatsFloats,	false	},
11095 		{ compressedFormatsFloats,	compatibleFormatsFloats,	false	},
11096 		{ compatibleFormatsSrgb,	compatibleFormatsSrgb,		false	},
11097 		{ compressedFormatsSrgb,	compatibleFormatsSrgb,		false	},
11098 	};
11099 
11100 	const int	numOfColorImageFormatsToTest		= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
11101 
11102 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
11103 	{
11104 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
11105 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
11106 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
11107 	}
11108 
11109 	// 2D tests.
11110 	{
11111 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
11112 
11113 		TestParams	params;
11114 		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
11115 		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
11116 		params.src.image.extent		= defaultExtent;
11117 		params.dst.image.extent		= defaultExtent;
11118 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
11119 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
11120 		params.allocationKind		= allocationKind;
11121 		params.extensionUse			= extensionUse;
11122 
11123 		// create all required copy regions
11124 		const std::map<AstcImageSizeType, std::vector<CopyRegion> > imageRegions
11125 		{
11126 			{ AstcImageSizeType::SIZE_64_64, create2DCopyRegions(64, 64,	64, 64) },
11127 			{ AstcImageSizeType::SIZE_60_64, create2DCopyRegions(60, 64,	60, 64) },
11128 			{ AstcImageSizeType::SIZE_64_60, create2DCopyRegions(64, 60,	64, 60) },
11129 			{ AstcImageSizeType::SIZE_60_60, create2DCopyRegions(60, 60,	60, 60) },
11130 		};
11131 
11132 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11133 		{
11134 			const VkFormat*	sourceFormats		= colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
11135 			const VkFormat*	destinationFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].destinationFormats;
11136 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11137 			for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11138 			{
11139 				VkFormat srcFormat		= sourceFormats[srcFormatIndex];
11140 				params.src.image.format = srcFormat;
11141 
11142 				const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
11143 
11144 				// most of tests are using regions caluculated for 64x64 size but astc formats require custom regions
11145 				params.regions = imageRegions.at(AstcImageSizeType::SIZE_64_64);
11146 				if (isCompressedFormat(srcFormat) && isAstcFormat(mapVkCompressedFormat(srcFormat)))
11147 					params.regions = imageRegions.at(astcSizes.at(srcFormat));
11148 
11149 				// use the fact that first region contains the size of full source image
11150 				// and make source and destination the same size - this is needed for astc formats
11151 				const VkOffset3D&	srcImageSize	= params.regions[0].imageBlit.srcOffsets[1];
11152 				VkExtent3D&			srcImageExtent	= params.src.image.extent;
11153 				VkExtent3D&			dstImageExtent	= params.dst.image.extent;
11154 				srcImageExtent.width	= srcImageSize.x;
11155 				srcImageExtent.height	= srcImageSize.y;
11156 				dstImageExtent.width	= srcImageSize.x;
11157 				dstImageExtent.height	= srcImageSize.y;
11158 
11159 				BlitColorTestParams testParams
11160 				{
11161 					params,
11162 					destinationFormats,
11163 					makeFilterMask(onlyNearest, onlyNearestAndLinear)
11164 				};
11165 
11166 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
11167 				addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
11168 			}
11169 		}
11170 
11171 		group->addChild(subGroup.release());
11172 	}
11173 
11174 	// 1D tests.
11175 	{
11176 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
11177 
11178 		TestParams	params;
11179 		params.src.image.imageType	= VK_IMAGE_TYPE_1D;
11180 		params.dst.image.imageType	= VK_IMAGE_TYPE_1D;
11181 		params.src.image.extent		= default1dExtent;
11182 		params.dst.image.extent		= default1dExtent;
11183 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
11184 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
11185 		params.allocationKind		= allocationKind;
11186 		params.extensionUse			= extensionUse;
11187 
11188 		CopyRegion	region;
11189 		for (int i = 0; i < defaultSize; i += defaultSize / 2)
11190 		{
11191 			const VkImageBlit			imageBlit	=
11192 			{
11193 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
11194 				{
11195 					{0, 0, 0},
11196 					{defaultSize, 1, 1}
11197 				},					// VkOffset3D					srcOffsets[2];
11198 
11199 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
11200 				{
11201 					{i, 0, 0},
11202 					{i + defaultFourthSize, 1, 1}
11203 				}					// VkOffset3D					dstOffset[2];
11204 			};
11205 			region.imageBlit	= imageBlit;
11206 			params.regions.push_back(region);
11207 		}
11208 
11209 		{
11210 			const VkImageBlit			imageBlit	=
11211 			{
11212 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
11213 				{
11214 					{0, 0, 0},
11215 					{defaultFourthSize, 1, 1}
11216 				},					// VkOffset3D					srcOffsets[2];
11217 
11218 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
11219 				{
11220 					{defaultFourthSize, 0, 0},
11221 					{2 * defaultFourthSize, 1, 1}
11222 				}					// VkOffset3D					dstOffset[2];
11223 			};
11224 			region.imageBlit	= imageBlit;
11225 			params.regions.push_back(region);
11226 		}
11227 
11228 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11229 		{
11230 			const VkFormat*	sourceFormats		= colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
11231 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11232 			for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11233 			{
11234 				params.src.image.format	= sourceFormats[srcFormatIndex];
11235 				if (!isSupportedByFramework(params.src.image.format))
11236 					continue;
11237 
11238 				// Cubic filtering can only be used with 2D images.
11239 				const bool onlyNearestAndLinear	= true;
11240 
11241 				BlitColorTestParams testParams
11242 				{
11243 					params,
11244 					nullptr,
11245 					makeFilterMask(onlyNearest, onlyNearestAndLinear)
11246 				};
11247 
11248 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
11249 				addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
11250 			}
11251 		}
11252 
11253 		group->addChild(subGroup.release());
11254 	}
11255 
11256 	// 3D tests. Note we use smaller dimensions here for performance reasons.
11257 	{
11258 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
11259 
11260 		TestParams	params;
11261 		params.src.image.imageType	= VK_IMAGE_TYPE_3D;
11262 		params.dst.image.imageType	= VK_IMAGE_TYPE_3D;
11263 		params.src.image.extent		= default3dExtent;
11264 		params.dst.image.extent		= default3dExtent;
11265 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
11266 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
11267 		params.allocationKind		= allocationKind;
11268 		params.extensionUse			= extensionUse;
11269 
11270 		CopyRegion	region;
11271 		for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultFourthSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
11272 		{
11273 			const VkImageBlit			imageBlit	=
11274 			{
11275 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
11276 				{
11277 					{0, 0, 0},
11278 					{defaultFourthSize, defaultFourthSize, defaultFourthSize}
11279 				},					// VkOffset3D					srcOffsets[2];
11280 
11281 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
11282 				{
11283 					{i, 0, i},
11284 					{i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j}
11285 				}					// VkOffset3D					dstOffset[2];
11286 			};
11287 			region.imageBlit	= imageBlit;
11288 			params.regions.push_back(region);
11289 		}
11290 		for (int i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
11291 		{
11292 			const VkImageBlit			imageBlit	=
11293 			{
11294 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
11295 				{
11296 					{i, i, i},
11297 					{i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize}
11298 				},					// VkOffset3D					srcOffsets[2];
11299 
11300 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
11301 				{
11302 					{i, defaultFourthSize / 2, i},
11303 					{i + defaultSixteenthSize, defaultFourthSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize}
11304 				}					// VkOffset3D					dstOffset[2];
11305 			};
11306 			region.imageBlit	= imageBlit;
11307 			params.regions.push_back(region);
11308 		}
11309 
11310 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11311 		{
11312 			const VkFormat*	sourceFormats		= colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
11313 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11314 			for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11315 			{
11316 				params.src.image.format	= sourceFormats[srcFormatIndex];
11317 				if (!isSupportedByFramework(params.src.image.format))
11318 					continue;
11319 
11320 				// Cubic filtering can only be used with 2D images.
11321 				const bool onlyNearestAndLinear	= true;
11322 
11323 				BlitColorTestParams testParams
11324 				{
11325 					params,
11326 					nullptr,
11327 					makeFilterMask(onlyNearest, onlyNearestAndLinear)
11328 				};
11329 
11330 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
11331 				addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
11332 			}
11333 		}
11334 
11335 		group->addChild(subGroup.release());
11336 	}
11337 }
11338 
addBlittingImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)11339 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
11340 {
11341 	const VkImageLayout blitSrcLayouts[]	=
11342 	{
11343 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
11344 		VK_IMAGE_LAYOUT_GENERAL
11345 	};
11346 	const VkImageLayout blitDstLayouts[]	=
11347 	{
11348 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
11349 		VK_IMAGE_LAYOUT_GENERAL
11350 	};
11351 
11352 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
11353 	{
11354 		params.src.image.operationLayout	= blitSrcLayouts[srcLayoutNdx];
11355 
11356 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
11357 		{
11358 			params.dst.image.operationLayout	= blitDstLayouts[dstLayoutNdx];
11359 			params.filter						= VK_FILTER_NEAREST;
11360 
11361 			const std::string testName		= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
11362 											  getImageLayoutCaseName(params.dst.image.operationLayout);
11363 			const std::string description	= "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
11364 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
11365 
11366 			group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params));
11367 		}
11368 	}
11369 }
11370 
addBlittingImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11371 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11372 {
11373 	const VkFormat	depthAndStencilFormats[]	=
11374 	{
11375 		VK_FORMAT_D16_UNORM,
11376 		VK_FORMAT_X8_D24_UNORM_PACK32,
11377 		VK_FORMAT_D32_SFLOAT,
11378 		VK_FORMAT_S8_UINT,
11379 		VK_FORMAT_D16_UNORM_S8_UINT,
11380 		VK_FORMAT_D24_UNORM_S8_UINT,
11381 		VK_FORMAT_D32_SFLOAT_S8_UINT,
11382 	};
11383 
11384 	const VkImageSubresourceLayers	defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
11385 	const VkImageSubresourceLayers	defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
11386 	const VkImageSubresourceLayers	defaultDSSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
11387 
11388 	// 2D tests
11389 	{
11390 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
11391 
11392 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
11393 		{
11394 			TestParams	params;
11395 			params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11396 			params.src.image.extent				= defaultExtent;
11397 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11398 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
11399 			params.dst.image.extent				= defaultExtent;
11400 			params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11401 			params.dst.image.format				= params.src.image.format;
11402 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11403 			params.allocationKind				= allocationKind;
11404 			params.extensionUse					= extensionUse;
11405 			params.separateDepthStencilLayouts	= DE_FALSE;
11406 
11407 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11408 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11409 
11410 			CopyRegion	region;
11411 			for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
11412 			{
11413 				const VkOffset3D	srcOffset0	= {0, 0, 0};
11414 				const VkOffset3D	srcOffset1	= {defaultSize, defaultSize, 1};
11415 				const VkOffset3D	dstOffset0	= {i, 0, 0};
11416 				const VkOffset3D	dstOffset1	= {i + defaultFourthSize / j, defaultFourthSize / j, 1};
11417 
11418 				if (hasDepth)
11419 				{
11420 					const VkImageBlit			imageBlit	=
11421 					{
11422 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
11423 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
11424 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
11425 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
11426 					};
11427 					region.imageBlit	= imageBlit;
11428 					params.regions.push_back(region);
11429 				}
11430 				if (hasStencil)
11431 				{
11432 					const VkImageBlit			imageBlit	=
11433 					{
11434 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
11435 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
11436 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
11437 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
11438 					};
11439 					region.imageBlit	= imageBlit;
11440 					params.regions.push_back(region);
11441 				}
11442 			}
11443 			for (int i = 0; i < defaultSize; i += defaultFourthSize)
11444 			{
11445 				const VkOffset3D	srcOffset0	= {i, i, 0};
11446 				const VkOffset3D	srcOffset1	= {i + defaultFourthSize, i + defaultFourthSize, 1};
11447 				const VkOffset3D	dstOffset0	= {i, defaultSize / 2, 0};
11448 				const VkOffset3D	dstOffset1	= {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};
11449 
11450 				if (hasDepth)
11451 				{
11452 					const VkImageBlit			imageBlit	=
11453 					{
11454 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
11455 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
11456 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
11457 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
11458 					};
11459 					region.imageBlit	= imageBlit;
11460 					params.regions.push_back(region);
11461 				}
11462 				if (hasStencil)
11463 				{
11464 					const VkImageBlit			imageBlit	=
11465 					{
11466 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
11467 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
11468 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
11469 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
11470 					};
11471 					region.imageBlit	= imageBlit;
11472 					params.regions.push_back(region);
11473 				}
11474 				if (hasDepth && hasStencil)
11475 				{
11476 					const VkOffset3D			dstDSOffset0	= {i, 3 * defaultFourthSize, 0};
11477 					const VkOffset3D			dstDSOffset1	= {i + defaultFourthSize, defaultSize, 1};
11478 					const VkImageBlit			imageBlit	=
11479 					{
11480 						defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
11481 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
11482 						defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
11483 						{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
11484 					};
11485 					region.imageBlit	= imageBlit;
11486 					params.regions.push_back(region);
11487 				}
11488 			}
11489 
11490 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11491 			const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
11492 											" to " + getFormatCaseName(params.dst.image.format);
11493 			addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11494 
11495 			if (hasDepth && hasStencil)
11496 			{
11497 				params.separateDepthStencilLayouts	= DE_TRUE;
11498 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" +
11499 												getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11500 				const std::string description2	= "Blit from " + getFormatCaseName(params.src.image.format) +
11501 												" to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
11502 				addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11503 			}
11504 		}
11505 
11506 		group->addChild(subGroup.release());
11507 	}
11508 
11509 	// 1D tests
11510 	{
11511 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
11512 
11513 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
11514 		{
11515 			TestParams	params;
11516 			params.src.image.imageType			= VK_IMAGE_TYPE_1D;
11517 			params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
11518 			params.src.image.extent				= default1dExtent;
11519 			params.dst.image.extent				= default1dExtent;
11520 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
11521 			params.dst.image.format				= params.src.image.format;
11522 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11523 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11524 			params.allocationKind				= allocationKind;
11525 			params.extensionUse					= extensionUse;
11526 
11527 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11528 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11529 
11530 			CopyRegion	region;
11531 			for (int i = 0; i < defaultSize; i += defaultSize / 2)
11532 			{
11533 				const VkOffset3D	srcOffset0	= {0, 0, 0};
11534 				const VkOffset3D	srcOffset1	= {defaultSize, 1, 1};
11535 				const VkOffset3D	dstOffset0	= {i, 0, 0};
11536 				const VkOffset3D	dstOffset1	= {i + defaultFourthSize, 1, 1};
11537 
11538 				if (hasDepth)
11539 				{
11540 					const VkImageBlit			imageBlit	=
11541 					{
11542 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
11543 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
11544 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
11545 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
11546 					};
11547 					region.imageBlit	= imageBlit;
11548 					params.regions.push_back(region);
11549 				}
11550 				if (hasStencil)
11551 				{
11552 					const VkImageBlit			imageBlit	=
11553 					{
11554 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
11555 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
11556 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
11557 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
11558 					};
11559 					region.imageBlit	= imageBlit;
11560 					params.regions.push_back(region);
11561 				}
11562 			}
11563 
11564 			{
11565 				const VkOffset3D	srcOffset0	= {0, 0, 0};
11566 				const VkOffset3D	srcOffset1	= {defaultFourthSize, 1, 1};
11567 				const VkOffset3D	dstOffset0	= {defaultFourthSize, 0, 0};
11568 				const VkOffset3D	dstOffset1	= {2 * defaultFourthSize, 1, 1};
11569 
11570 				if (hasDepth)
11571 				{
11572 					const VkImageBlit			imageBlit	=
11573 					{
11574 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
11575 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
11576 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
11577 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
11578 					};
11579 					region.imageBlit	= imageBlit;
11580 					params.regions.push_back(region);
11581 				}
11582 				if (hasStencil)
11583 				{
11584 					const VkImageBlit			imageBlit	=
11585 					{
11586 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
11587 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
11588 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
11589 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
11590 					};
11591 					region.imageBlit	= imageBlit;
11592 					params.regions.push_back(region);
11593 				}
11594 				if (hasDepth && hasStencil)
11595 				{
11596 					const VkOffset3D			dstDSOffset0	= {3 * defaultFourthSize, 0, 0};
11597 					const VkOffset3D			dstDSOffset1	= {3 * defaultFourthSize + defaultFourthSize / 2, 1, 1};
11598 					const VkImageBlit			imageBlit	=
11599 					{
11600 						defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
11601 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
11602 						defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
11603 						{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
11604 					};
11605 					region.imageBlit	= imageBlit;
11606 					params.regions.push_back(region);
11607 				}
11608 			}
11609 
11610 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11611 			const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
11612 											" to " + getFormatCaseName(params.dst.image.format);
11613 			addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11614 
11615 			if (hasDepth && hasStencil)
11616 			{
11617 				params.separateDepthStencilLayouts	= DE_TRUE;
11618 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" +
11619 												getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11620 				const std::string description2	= "Blit from " + getFormatCaseName(params.src.image.format) +
11621 												" to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
11622 				addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11623 			}
11624 		}
11625 
11626 		group->addChild(subGroup.release());
11627 	}
11628 
11629 	// 3D tests. Note we use smaller dimensions here for performance reasons.
11630 	{
11631 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
11632 
11633 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
11634 		{
11635 			TestParams	params;
11636 			params.src.image.imageType			= VK_IMAGE_TYPE_3D;
11637 			params.dst.image.imageType			= VK_IMAGE_TYPE_3D;
11638 			params.src.image.extent				= default3dExtent;
11639 			params.dst.image.extent				= default3dExtent;
11640 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
11641 			params.dst.image.format				= params.src.image.format;
11642 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11643 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11644 			params.allocationKind				= allocationKind;
11645 			params.extensionUse					= extensionUse;
11646 
11647 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11648 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11649 
11650 			CopyRegion	region;
11651 			for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultFourthSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
11652 			{
11653 				const VkOffset3D	srcOffset0	= {0, 0, 0};
11654 				const VkOffset3D	srcOffset1	= {defaultFourthSize, defaultFourthSize, defaultFourthSize};
11655 				const VkOffset3D	dstOffset0	= {i, 0, i};
11656 				const VkOffset3D	dstOffset1	= {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j};
11657 
11658 				if (hasDepth)
11659 				{
11660 					const VkImageBlit			imageBlit	=
11661 					{
11662 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
11663 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
11664 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
11665 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
11666 					};
11667 					region.imageBlit	= imageBlit;
11668 					params.regions.push_back(region);
11669 				}
11670 				if (hasStencil)
11671 				{
11672 					const VkImageBlit			imageBlit	=
11673 					{
11674 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
11675 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
11676 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
11677 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
11678 					};
11679 					region.imageBlit	= imageBlit;
11680 					params.regions.push_back(region);
11681 				}
11682 			}
11683 			for (int i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
11684 			{
11685 				const VkOffset3D	srcOffset0	= {i, i, i};
11686 				const VkOffset3D	srcOffset1	= {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize};
11687 				const VkOffset3D	dstOffset0	= {i, defaultFourthSize / 2, i};
11688 				const VkOffset3D	dstOffset1	= {i + defaultSixteenthSize, defaultFourthSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize};
11689 
11690 				if (hasDepth)
11691 				{
11692 					const VkImageBlit			imageBlit	=
11693 					{
11694 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
11695 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
11696 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
11697 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
11698 					};
11699 					region.imageBlit	= imageBlit;
11700 					params.regions.push_back(region);
11701 				}
11702 				if (hasStencil)
11703 				{
11704 					const VkImageBlit			imageBlit	=
11705 					{
11706 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
11707 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
11708 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
11709 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
11710 					};
11711 					region.imageBlit	= imageBlit;
11712 					params.regions.push_back(region);
11713 				}
11714 				if (hasDepth && hasStencil)
11715 				{
11716 					const VkOffset3D			dstDSOffset0	= {i, 3 * defaultSixteenthSize, i};
11717 					const VkOffset3D			dstDSOffset1	= {i + defaultSixteenthSize, defaultFourthSize, i + defaultSixteenthSize};
11718 					const VkImageBlit			imageBlit	=
11719 					{
11720 						defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
11721 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
11722 						defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
11723 						{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
11724 					};
11725 					region.imageBlit	= imageBlit;
11726 					params.regions.push_back(region);
11727 				}
11728 			}
11729 
11730 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11731 			const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
11732 											" to " + getFormatCaseName(params.dst.image.format);
11733 			addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11734 
11735 			if (hasDepth && hasStencil)
11736 			{
11737 				params.separateDepthStencilLayouts	= DE_TRUE;
11738 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" +
11739 												getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11740 				const std::string description2	= "Blit from " + getFormatCaseName(params.src.image.format) +
11741 												" to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
11742 				addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11743 			}
11744 		}
11745 
11746 		group->addChild(subGroup.release());
11747 	}
11748 }
11749 
addBlittingImageAllFormatsMipmapFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)11750 void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
11751 {
11752 	tcu::TestContext& testCtx				= group->getTestContext();
11753 
11754 	const VkImageLayout blitSrcLayouts[]	=
11755 	{
11756 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
11757 		VK_IMAGE_LAYOUT_GENERAL
11758 	};
11759 	const VkImageLayout blitDstLayouts[]	=
11760 	{
11761 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
11762 		VK_IMAGE_LAYOUT_GENERAL
11763 	};
11764 
11765 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
11766 	{
11767 		testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
11768 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
11769 		{
11770 			testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
11771 
11772 			testParams.params.filter			= VK_FILTER_NEAREST;
11773 			const std::string testName			= getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
11774 												  getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
11775 			const std::string description		= "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
11776 												  " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
11777 			group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params));
11778 
11779 			if (testParams.testFilters & FILTER_MASK_LINEAR)
11780 			{
11781 				testParams.params.filter = VK_FILTER_LINEAR;
11782 				group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params));
11783 			}
11784 
11785 			if (testParams.testFilters & FILTER_MASK_CUBIC)
11786 			{
11787 				testParams.params.filter = VK_FILTER_CUBIC_EXT;
11788 				group->addChild(new BlitMipmapTestCase(testCtx, testName + "_cubic", description, testParams.params));
11789 			}
11790 		}
11791 	}
11792 }
11793 
addBlittingImageAllFormatsBaseLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11794 void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11795 {
11796 	const struct
11797 	{
11798 		const VkFormat* const	compatibleFormats;
11799 		const bool				onlyNearest;
11800 	}	colorImageFormatsToTestBlit[]			=
11801 	{
11802 		{ compatibleFormatsUInts,	true	},
11803 		{ compatibleFormatsSInts,	true	},
11804 		{ compatibleFormatsFloats,	false	},
11805 		{ compatibleFormatsSrgb,	false	},
11806 	};
11807 
11808 	const int	numOfColorImageFormatsToTest	= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
11809 
11810 	const int	layerCountsToTest[]				=
11811 	{
11812 		1,
11813 		6
11814 	};
11815 
11816 	TestParams	params;
11817 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
11818 	params.src.image.extent		= defaultExtent;
11819 	params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
11820 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
11821 	params.dst.image.extent		= defaultExtent;
11822 	params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
11823 	params.allocationKind		= allocationKind;
11824 	params.extensionUse			= extensionUse;
11825 	params.mipLevels			= deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
11826 	params.singleCommand		= DE_TRUE;
11827 
11828 	CopyRegion	region;
11829 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
11830 	{
11831 		VkImageSubresourceLayers	destLayer	= defaultSourceLayer;
11832 		destLayer.mipLevel = mipLevelNdx;
11833 
11834 		const VkImageBlit			imageBlit	=
11835 		{
11836 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
11837 			{
11838 				{0, 0, 0},
11839 				{defaultSize, defaultSize, 1}
11840 			},					// VkOffset3D					srcOffsets[2];
11841 
11842 			destLayer,			// VkImageSubresourceLayers	dstSubresource;
11843 			{
11844 				{0, 0, 0},
11845 				{defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
11846 			}					// VkOffset3D					dstOffset[2];
11847 		};
11848 		region.imageBlit	= imageBlit;
11849 		params.regions.push_back(region);
11850 	}
11851 
11852 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
11853 	{
11854 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
11855 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
11856 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
11857 	}
11858 
11859 	for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
11860 	{
11861 		const int						layerCount		= layerCountsToTest[layerCountIndex];
11862 		const std::string				layerGroupName	= "layercount_" + de::toString(layerCount);
11863 		const std::string				layerGroupDesc	= "Blit mipmaps with layerCount = " + de::toString(layerCount);
11864 
11865 		de::MovePtr<tcu::TestCaseGroup>	layerCountGroup	(new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
11866 
11867 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11868 		{
11869 			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
11870 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11871 
11872 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11873 			{
11874 				params.src.image.format	= compatibleFormats[srcFormatIndex];
11875 				params.dst.image.format	= compatibleFormats[srcFormatIndex];
11876 
11877 				if (!isSupportedByFramework(params.src.image.format))
11878 					continue;
11879 
11880 				const bool onlyNearestAndLinear	= de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
11881 
11882 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
11883 
11884 				BlitColorTestParams testParams;
11885 				testParams.params				= params;
11886 				testParams.compatibleFormats	= compatibleFormats;
11887 				testParams.testFilters			= makeFilterMask(onlyNearest, onlyNearestAndLinear);
11888 
11889 				testParams.params.src.image.extent.depth = layerCount;
11890 				testParams.params.dst.image.extent.depth = layerCount;
11891 
11892 				for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
11893 				{
11894 					testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
11895 					testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
11896 				}
11897 
11898 				addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
11899 			}
11900 		}
11901 		group->addChild(layerCountGroup.release());
11902 	}
11903 }
11904 
addBlittingImageAllFormatsPreviousLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11905 void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11906 {
11907 	const struct
11908 	{
11909 		const VkFormat* const	compatibleFormats;
11910 		const bool				onlyNearest;
11911 	}	colorImageFormatsToTestBlit[]			=
11912 	{
11913 		{ compatibleFormatsUInts,	true	},
11914 		{ compatibleFormatsSInts,	true	},
11915 		{ compatibleFormatsFloats,	false	},
11916 		{ compatibleFormatsSrgb,	false	},
11917 	};
11918 
11919 	const int	numOfColorImageFormatsToTest	= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
11920 
11921 	const int	layerCountsToTest[]				=
11922 	{
11923 		1,
11924 		6
11925 	};
11926 
11927 	TestParams	params;
11928 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
11929 	params.src.image.extent		= defaultExtent;
11930 	params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
11931 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
11932 	params.dst.image.extent		= defaultExtent;
11933 	params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
11934 	params.allocationKind		= allocationKind;
11935 	params.extensionUse			= extensionUse;
11936 	params.mipLevels			= deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
11937 	params.singleCommand		= DE_FALSE;
11938 
11939 	CopyRegion	region;
11940 	for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
11941 	{
11942 		VkImageSubresourceLayers	srcLayer	= defaultSourceLayer;
11943 		VkImageSubresourceLayers	destLayer	= defaultSourceLayer;
11944 
11945 		srcLayer.mipLevel	= mipLevelNdx - 1u;
11946 		destLayer.mipLevel	= mipLevelNdx;
11947 
11948 		const VkImageBlit			imageBlit	=
11949 		{
11950 			srcLayer,			// VkImageSubresourceLayers	srcSubresource;
11951 			{
11952 				{0, 0, 0},
11953 				{defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}
11954 			},					// VkOffset3D					srcOffsets[2];
11955 
11956 			destLayer,			// VkImageSubresourceLayers	dstSubresource;
11957 			{
11958 				{0, 0, 0},
11959 				{defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
11960 			}					// VkOffset3D					dstOffset[2];
11961 		};
11962 		region.imageBlit	= imageBlit;
11963 		params.regions.push_back(region);
11964 	}
11965 
11966 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
11967 	{
11968 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
11969 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
11970 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
11971 	}
11972 
11973 	for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
11974 	{
11975 		const int						layerCount		= layerCountsToTest[layerCountIndex];
11976 		const std::string				layerGroupName	= "layercount_" + de::toString(layerCount);
11977 		const std::string				layerGroupDesc	= "Blit mipmaps with layerCount = " + de::toString(layerCount);
11978 
11979 		de::MovePtr<tcu::TestCaseGroup>	layerCountGroup	(new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
11980 
11981 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11982 		{
11983 			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
11984 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11985 
11986 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11987 			{
11988 				params.src.image.format						= compatibleFormats[srcFormatIndex];
11989 				params.dst.image.format						= compatibleFormats[srcFormatIndex];
11990 
11991 				if (!isSupportedByFramework(params.src.image.format))
11992 					continue;
11993 
11994 				const bool			onlyNearestAndLinear	= de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
11995 
11996 				const std::string	description				= "Blit source format " + getFormatCaseName(params.src.image.format);
11997 
11998 				BlitColorTestParams	testParams;
11999 				testParams.params							= params;
12000 				testParams.compatibleFormats				= compatibleFormats;
12001 				testParams.testFilters						= makeFilterMask(onlyNearest, onlyNearestAndLinear);
12002 
12003 				testParams.params.src.image.extent.depth	= layerCount;
12004 				testParams.params.dst.image.extent.depth	= layerCount;
12005 
12006 				for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
12007 				{
12008 					testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
12009 					testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
12010 				}
12011 
12012 				addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
12013 			}
12014 		}
12015 		group->addChild(layerCountGroup.release());
12016 	}
12017 
12018 	for (int multiLayer = 0; multiLayer < 2; multiLayer++)
12019 	{
12020 		const int layerCount = multiLayer ? 6 : 1;
12021 
12022 		for (int barrierCount = 1; barrierCount < 4; barrierCount++)
12023 		{
12024 			if (layerCount != 1 || barrierCount != 1)
12025 			{
12026 				const std::string				barrierGroupName = (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
12027 				const std::string				barrierGroupDesc = "Use " + de::toString(barrierCount) + " image barriers";
12028 
12029 				de::MovePtr<tcu::TestCaseGroup>	barrierCountGroup(new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str(), barrierGroupDesc.c_str()));
12030 
12031 				params.barrierCount = barrierCount;
12032 
12033 				// Only go through a few common formats
12034 				for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
12035 				{
12036 					params.src.image.format						= compatibleFormatsUInts[srcFormatIndex];
12037 					params.dst.image.format						= compatibleFormatsUInts[srcFormatIndex];
12038 
12039 					if (!isSupportedByFramework(params.src.image.format))
12040 						continue;
12041 
12042 					const std::string description				= "Blit source format " + getFormatCaseName(params.src.image.format);
12043 
12044 					BlitColorTestParams testParams;
12045 					testParams.params							= params;
12046 					testParams.compatibleFormats				= compatibleFormatsUInts;
12047 					testParams.testFilters						= FILTER_MASK_NEAREST;
12048 
12049 					testParams.params.src.image.extent.depth	= layerCount;
12050 					testParams.params.dst.image.extent.depth	= layerCount;
12051 
12052 					for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
12053 					{
12054 						testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
12055 						testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
12056 					}
12057 
12058 					addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
12059 				}
12060 				group->addChild(barrierCountGroup.release());
12061 			}
12062 		}
12063 	}
12064 }
12065 
addBlittingImageAllFormatsMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12066 void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12067 {
12068 	addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind, extensionUse);
12069 	addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind, extensionUse);
12070 }
12071 
addBlittingImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12072 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12073 {
12074 	addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind, extensionUse);
12075 	addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
12076 	addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind, extensionUse);
12077 }
12078 
addBlittingImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12079 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12080 {
12081 	addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind, extensionUse);
12082 	addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind, extensionUse);
12083 }
12084 
12085 const VkSampleCountFlagBits	samples[]		=
12086 {
12087 	VK_SAMPLE_COUNT_2_BIT,
12088 	VK_SAMPLE_COUNT_4_BIT,
12089 	VK_SAMPLE_COUNT_8_BIT,
12090 	VK_SAMPLE_COUNT_16_BIT,
12091 	VK_SAMPLE_COUNT_32_BIT,
12092 	VK_SAMPLE_COUNT_64_BIT
12093 };
12094 const VkExtent3D			resolveExtent	= {256u, 256u, 1};
12095 
addResolveImageWholeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12096 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12097 {
12098 	TestParams	params;
12099 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12100 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12101 	params.src.image.extent				= resolveExtent;
12102 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12103 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12104 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12105 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12106 	params.dst.image.extent				= resolveExtent;
12107 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12108 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12109 	params.allocationKind				= allocationKind;
12110 	params.extensionUse					= extensionUse;
12111 
12112 	{
12113 		const VkImageSubresourceLayers	sourceLayer	=
12114 		{
12115 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
12116 			0u,							// deUint32				mipLevel;
12117 			0u,							// deUint32				baseArrayLayer;
12118 			1u							// deUint32				layerCount;
12119 		};
12120 		const VkImageResolve			testResolve	=
12121 		{
12122 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12123 			{0, 0, 0},		// VkOffset3D				srcOffset;
12124 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12125 			{0, 0, 0},		// VkOffset3D				dstOffset;
12126 			resolveExtent,	// VkExtent3D				extent;
12127 		};
12128 
12129 		CopyRegion	imageResolve;
12130 		imageResolve.imageResolve	= testResolve;
12131 		params.regions.push_back(imageResolve);
12132 	}
12133 
12134 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12135 	{
12136 		params.samples					= samples[samplesIndex];
12137 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
12138 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
12139 	}
12140 }
12141 
addResolveImagePartialTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12142 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12143 {
12144 	TestParams	params;
12145 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12146 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12147 	params.src.image.extent				= resolveExtent;
12148 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12149 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12150 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12151 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12152 	params.dst.image.extent				= resolveExtent;
12153 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12154 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12155 	params.allocationKind				= allocationKind;
12156 	params.extensionUse					= extensionUse;
12157 
12158 	{
12159 		const VkImageSubresourceLayers	sourceLayer	=
12160 		{
12161 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
12162 			0u,							// deUint32				mipLevel;
12163 			0u,							// deUint32				baseArrayLayer;
12164 			1u							// deUint32				layerCount;
12165 		};
12166 		const VkImageResolve			testResolve	=
12167 		{
12168 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12169 			{0, 0, 0},		// VkOffset3D				srcOffset;
12170 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12171 			{64u, 64u, 0},		// VkOffset3D				dstOffset;
12172 			{128u, 128u, 1u},	// VkExtent3D				extent;
12173 		};
12174 
12175 		CopyRegion	imageResolve;
12176 		imageResolve.imageResolve = testResolve;
12177 		params.regions.push_back(imageResolve);
12178 	}
12179 
12180 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12181 	{
12182 		params.samples					= samples[samplesIndex];
12183 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
12184 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
12185 	}
12186 }
12187 
addResolveImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12188 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12189 {
12190 	TestParams	params;
12191 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12192 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12193 	params.src.image.extent				= resolveExtent;
12194 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12195 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12196 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12197 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12198 	params.dst.image.extent				= resolveExtent;
12199 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12200 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12201 	params.allocationKind				= allocationKind;
12202 	params.extensionUse					= extensionUse;
12203 
12204 	{
12205 		const VkImageSubresourceLayers	sourceLayer	=
12206 		{
12207 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
12208 			0u,							// deUint32				mipLevel;
12209 			0u,							// deUint32				baseArrayLayer;
12210 			1u							// deUint32				layerCount;
12211 		};
12212 
12213 		for (int i = 0; i < 256; i += 64)
12214 		{
12215 			const VkImageResolve			testResolve	=
12216 			{
12217 				sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12218 				{i, i, 0},		// VkOffset3D				srcOffset;
12219 				sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12220 				{i, 0, 0},		// VkOffset3D				dstOffset;
12221 				{64u, 64u, 1u},	// VkExtent3D				extent;
12222 			};
12223 
12224 			CopyRegion	imageResolve;
12225 			imageResolve.imageResolve = testResolve;
12226 			params.regions.push_back(imageResolve);
12227 		}
12228 	}
12229 
12230 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12231 	{
12232 		params.samples					= samples[samplesIndex];
12233 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
12234 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
12235 	}
12236 }
12237 
addResolveImageWholeCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12238 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12239 {
12240 	TestParams	params;
12241 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12242 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12243 	params.src.image.extent				= defaultExtent;
12244 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12245 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12246 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12247 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12248 	params.dst.image.extent				= defaultExtent;
12249 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12250 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12251 	params.allocationKind				= allocationKind;
12252 	params.extensionUse					= extensionUse;
12253 
12254 	{
12255 		const VkImageSubresourceLayers	sourceLayer	=
12256 		{
12257 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
12258 			0u,							// deUint32				mipLevel;
12259 			0u,							// deUint32				baseArrayLayer;
12260 			1u							// deUint32				layerCount;
12261 		};
12262 
12263 		const VkImageResolve			testResolve	=
12264 		{
12265 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
12266 			{0, 0, 0},			// VkOffset3D				srcOffset;
12267 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
12268 			{0, 0, 0},			// VkOffset3D				dstOffset;
12269 			defaultExtent,		// VkExtent3D				extent;
12270 		};
12271 
12272 		CopyRegion	imageResolve;
12273 		imageResolve.imageResolve	= testResolve;
12274 		params.regions.push_back(imageResolve);
12275 	}
12276 
12277 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12278 	{
12279 		params.samples					= samples[samplesIndex];
12280 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
12281 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
12282 	}
12283 }
12284 
addResolveImageWholeCopyWithoutCabBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12285 void addResolveImageWholeCopyWithoutCabBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12286 {
12287 	TestParams	params;
12288 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12289 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12290 	params.src.image.extent				= defaultExtent;
12291 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12292 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12293 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12294 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12295 	params.dst.image.extent				= defaultExtent;
12296 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12297 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12298 	params.allocationKind				= allocationKind;
12299 	params.extensionUse					= extensionUse;
12300 
12301 	{
12302 		const VkImageSubresourceLayers	sourceLayer	=
12303 		{
12304 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
12305 			0u,							// deUint32				mipLevel;
12306 			0u,							// deUint32				baseArrayLayer;
12307 			1u							// deUint32				layerCount;
12308 		};
12309 
12310 		const VkImageResolve			testResolve	=
12311 		{
12312 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
12313 			{0, 0, 0},			// VkOffset3D				srcOffset;
12314 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
12315 			{0, 0, 0},			// VkOffset3D				dstOffset;
12316 			defaultExtent,		// VkExtent3D				extent;
12317 		};
12318 
12319 		CopyRegion	imageResolve;
12320 		imageResolve.imageResolve	= testResolve;
12321 		params.regions.push_back(imageResolve);
12322 	}
12323 
12324 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12325 	{
12326 		params.samples					= samples[samplesIndex];
12327 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
12328 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
12329 	}
12330 }
12331 
addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12332 void addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12333 {
12334 	TestParams	params;
12335 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12336 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12337 	params.src.image.extent				= defaultExtent;
12338 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12339 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12340 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12341 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12342 	params.dst.image.extent				= defaultExtent;
12343 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12344 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12345 	params.allocationKind				= allocationKind;
12346 	params.extensionUse					= extensionUse;
12347 
12348 	{
12349 		const VkImageSubresourceLayers	sourceLayer	=
12350 		{
12351 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
12352 			0u,							// deUint32				mipLevel;
12353 			0u,							// deUint32				baseArrayLayer;
12354 			1u							// deUint32				layerCount;
12355 		};
12356 
12357 		const VkImageResolve			testResolve	=
12358 		{
12359 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
12360 			{0, 0, 0},			// VkOffset3D				srcOffset;
12361 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
12362 			{0, 0, 0},			// VkOffset3D				dstOffset;
12363 			defaultExtent,		// VkExtent3D				extent;
12364 		};
12365 
12366 		CopyRegion	imageResolve;
12367 		imageResolve.imageResolve	= testResolve;
12368 		params.regions.push_back(imageResolve);
12369 	}
12370 
12371 	const struct
12372 	{
12373 		VkImageLayout	layout;
12374 		std::string		name;
12375 	}	imageLayouts[]			=
12376 	{
12377 		{ VK_IMAGE_LAYOUT_GENERAL,					"general"							},
12378 		{ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		"transfer_src_optimal"				},
12379 		{ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		"transfer_dst_optimal"				}
12380 	};
12381 
12382 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12383 	for (int srcLayoutIndex = 0; srcLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++srcLayoutIndex)
12384 	for (int dstLayoutIndex = 0; dstLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++dstLayoutIndex)
12385 	{
12386 		params.src.image.operationLayout	= imageLayouts[srcLayoutIndex].layout;
12387 		params.dst.image.operationLayout	= imageLayouts[dstLayoutIndex].layout;
12388 		if (params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
12389 			params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
12390 			continue;
12391 		params.samples						= samples[samplesIndex];
12392 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
12393 		std::string testName = getSampleCountCaseName(samples[samplesIndex]) + "_" + imageLayouts[srcLayoutIndex].name + "_" + imageLayouts[dstLayoutIndex].name;
12394 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName, description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
12395 	}
12396 }
12397 
addResolveImageLayerCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12398 void addResolveImageLayerCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12399 {
12400 	TestParams	params;
12401 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12402 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12403 	params.src.image.extent				= defaultExtent;
12404 	params.src.image.extent.depth		= 5u;
12405 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12406 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12407 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12408 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12409 	params.dst.image.extent				= defaultExtent;
12410 	params.dst.image.extent.depth		= 5u;
12411 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12412 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12413 	params.allocationKind				= allocationKind;
12414 	params.extensionUse					= extensionUse;
12415 
12416 	for (deUint32 layerNdx=0; layerNdx < params.src.image.extent.depth; ++layerNdx)
12417 	{
12418 		const VkImageSubresourceLayers	sourceLayer	=
12419 		{
12420 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
12421 			0u,								// deUint32				mipLevel;
12422 			layerNdx,						// deUint32				baseArrayLayer;
12423 			1u								// deUint32				layerCount;
12424 		};
12425 
12426 		const VkImageResolve			testResolve	=
12427 		{
12428 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
12429 			{0, 0, 0},			// VkOffset3D				srcOffset;
12430 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
12431 			{0, 0, 0},			// VkOffset3D				dstOffset;
12432 			defaultExtent,		// VkExtent3D				extent;
12433 		};
12434 
12435 		CopyRegion	imageResolve;
12436 		imageResolve.imageResolve	= testResolve;
12437 		params.regions.push_back(imageResolve);
12438 	}
12439 
12440 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12441 	{
12442 		params.samples					= samples[samplesIndex];
12443 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
12444 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
12445 	}
12446 }
12447 
addResolveCopyImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12448 void addResolveCopyImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12449 {
12450 	TestParams	params;
12451 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12452 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12453 	params.src.image.extent				= resolveExtent;
12454 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12455 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12456 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12457 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12458 	params.dst.image.extent				= resolveExtent;
12459 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12460 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12461 	params.allocationKind				= allocationKind;
12462 	params.extensionUse					= extensionUse;
12463 
12464 	int32_t		imageHalfWidth	= getExtent3D(params.src.image).width / 2;
12465 	int32_t		imageHalfHeight	= getExtent3D(params.src.image).height / 2;
12466 	VkExtent3D	halfImageExtent	= {resolveExtent.width / 2, resolveExtent.height / 2, 1u};
12467 
12468 	// Lower right corner to lower left corner.
12469 	{
12470 		const VkImageSubresourceLayers	sourceLayer	=
12471 		{
12472 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
12473 			0u,								// deUint32				mipLevel;
12474 			0u,								// deUint32				baseArrayLayer;
12475 			1u								// deUint32				layerCount;
12476 		};
12477 
12478 		const VkImageResolve			testResolve	=
12479 		{
12480 			sourceLayer,							// VkImageSubresourceLayers	srcSubresource;
12481 			{imageHalfWidth, imageHalfHeight, 0},	// VkOffset3D				srcOffset;
12482 			sourceLayer,							// VkImageSubresourceLayers	dstSubresource;
12483 			{0, imageHalfHeight, 0},				// VkOffset3D				dstOffset;
12484 			halfImageExtent,									// VkExtent3D				extent;
12485 		};
12486 
12487 		CopyRegion	imageResolve;
12488 		imageResolve.imageResolve	= testResolve;
12489 		params.regions.push_back(imageResolve);
12490 	}
12491 
12492 	// Upper right corner to lower right corner.
12493 	{
12494 		const VkImageSubresourceLayers	sourceLayer	=
12495 		{
12496 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
12497 			0u,								// deUint32				mipLevel;
12498 			0u,								// deUint32				baseArrayLayer;
12499 			1u								// deUint32				layerCount;
12500 		};
12501 
12502 		const VkImageResolve			testResolve	=
12503 		{
12504 			sourceLayer,							// VkImageSubresourceLayers	srcSubresource;
12505 			{imageHalfWidth, 0, 0},					// VkOffset3D				srcOffset;
12506 			sourceLayer,							// VkImageSubresourceLayers	dstSubresource;
12507 			{imageHalfWidth, imageHalfHeight, 0},	// VkOffset3D				dstOffset;
12508 			halfImageExtent,									// VkExtent3D				extent;
12509 		};
12510 
12511 		CopyRegion	imageResolve;
12512 		imageResolve.imageResolve	= testResolve;
12513 		params.regions.push_back(imageResolve);
12514 	}
12515 
12516 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12517 	{
12518 		params.samples					= samples[samplesIndex];
12519 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
12520 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
12521 	}
12522 }
12523 
addResolveImageWholeArrayImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12524 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12525 {
12526 	TestParams	params;
12527 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12528 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12529 	params.src.image.extent				= defaultExtent;
12530 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12531 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12532 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12533 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12534 	params.dst.image.extent				= defaultExtent;
12535 	params.dst.image.extent.depth		= 5u;
12536 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12537 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12538 	params.allocationKind				= allocationKind;
12539 	params.extensionUse					= extensionUse;
12540 
12541 	for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
12542 	{
12543 		const VkImageSubresourceLayers	sourceLayer	=
12544 		{
12545 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
12546 			0u,								// deUint32				mipLevel;
12547 			layerNdx,						// deUint32				baseArrayLayer;
12548 			1u								// deUint32				layerCount;
12549 		};
12550 
12551 		const VkImageResolve			testResolve	=
12552 		{
12553 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
12554 			{0, 0, 0},			// VkOffset3D				srcOffset;
12555 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
12556 			{0, 0, 0},			// VkOffset3D				dstOffset;
12557 			defaultExtent,		// VkExtent3D				extent;
12558 		};
12559 
12560 		CopyRegion	imageResolve;
12561 		imageResolve.imageResolve	= testResolve;
12562 		params.regions.push_back(imageResolve);
12563 	}
12564 
12565 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12566 	{
12567 		params.samples					= samples[samplesIndex];
12568 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
12569 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
12570 	}
12571 }
12572 
addResolveImageWholeArrayImageSingleRegionTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12573 void addResolveImageWholeArrayImageSingleRegionTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12574 {
12575 	TestParams	params;
12576 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12577 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12578 	params.src.image.extent				= defaultExtent;
12579 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12580 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12581 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12582 	params.dst.image.extent				= defaultExtent;
12583 	params.dst.image.extent.depth		= 5u;
12584 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12585 	params.allocationKind				= allocationKind;
12586 	params.extensionUse					= extensionUse;
12587 
12588 	const VkImageSubresourceLayers	sourceLayer	=
12589 	{
12590 		VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
12591 		0u,								// uint32_t				mipLevel;
12592 		0,						// uint32_t				baseArrayLayer;
12593 		params.dst.image.extent.depth			// uint32_t				layerCount;
12594 	};
12595 
12596 	const VkImageResolve			testResolve	=
12597 	{
12598 		sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
12599 		{0, 0, 0},			// VkOffset3D				srcOffset;
12600 		sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
12601 		{0, 0, 0},			// VkOffset3D				dstOffset;
12602 		defaultExtent,		// VkExtent3D				extent;
12603 	};
12604 
12605 	CopyRegion	imageResolve;
12606 	imageResolve.imageResolve	= testResolve;
12607 	params.regions.push_back(imageResolve);
12608 
12609 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12610 	{
12611 		params.samples					= samples[samplesIndex];
12612 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
12613 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
12614 	}
12615 }
12616 
addResolveImageDiffImageSizeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12617 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12618 {
12619 	tcu::TestContext&	testCtx			= group->getTestContext();
12620 	TestParams			params;
12621 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12622 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12623 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12624 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12625 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12626 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12627 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12628 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12629 	params.allocationKind				= allocationKind;
12630 	params.extensionUse					= extensionUse;
12631 
12632 	{
12633 		const VkImageSubresourceLayers	sourceLayer	=
12634 		{
12635 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
12636 			0u,							// deUint32				mipLevel;
12637 			0u,							// deUint32				baseArrayLayer;
12638 			1u							// deUint32				layerCount;
12639 		};
12640 		const VkImageResolve			testResolve	=
12641 		{
12642 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12643 			{0, 0, 0},		// VkOffset3D				srcOffset;
12644 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12645 			{0, 0, 0},		// VkOffset3D				dstOffset;
12646 			resolveExtent,	// VkExtent3D				extent;
12647 		};
12648 		CopyRegion	imageResolve;
12649 		imageResolve.imageResolve	= testResolve;
12650 		params.regions.push_back(imageResolve);
12651 	}
12652 
12653 	const VkExtent3D imageExtents[]		=
12654 	{
12655 		{ resolveExtent.width + 10,	resolveExtent.height,		resolveExtent.depth },
12656 		{ resolveExtent.width,		resolveExtent.height * 2,	resolveExtent.depth },
12657 		{ resolveExtent.width,		resolveExtent.height,		resolveExtent.depth + 10 }
12658 	};
12659 
12660 	for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
12661 	{
12662 		const VkExtent3D&	srcImageSize	= imageExtents[srcImageExtentIndex];
12663 		params.src.image.extent				= srcImageSize;
12664 		params.dst.image.extent				= resolveExtent;
12665 		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12666 		{
12667 			params.samples	= samples[samplesIndex];
12668 			std::ostringstream testName;
12669 			testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
12670 			std::ostringstream description;
12671 			description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
12672 						<< srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
12673 			group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
12674 		}
12675 	}
12676 	for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
12677 	{
12678 		const VkExtent3D&	dstImageSize	= imageExtents[dstImageExtentIndex];
12679 		params.src.image.extent				= resolveExtent;
12680 		params.dst.image.extent				= dstImageSize;
12681 		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12682 		{
12683 			params.samples	= samples[samplesIndex];
12684 			std::ostringstream testName;
12685 			testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
12686 			std::ostringstream description;
12687 			description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
12688 						<< dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
12689 			group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
12690 		}
12691 	}
12692 }
12693 
addBufferCopyOffsetTests(tcu::TestCaseGroup * group)12694 void addBufferCopyOffsetTests (tcu::TestCaseGroup* group)
12695 {
12696 	de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer_to_buffer_with_offset", "Copy from buffer to buffer using different offsets in the source and destination buffers"));
12697 
12698 	for (deUint32 srcOffset = 0u; srcOffset < BufferOffsetParams::kMaxOffset; ++srcOffset)
12699 	for (deUint32 dstOffset = 0u; dstOffset < BufferOffsetParams::kMaxOffset; ++dstOffset)
12700 	{
12701 		BufferOffsetParams params{srcOffset, dstOffset};
12702 		addFunctionCase(subGroup.get(), de::toString(srcOffset) + "_" + de::toString(dstOffset), "", bufferOffsetTest, params);
12703 	}
12704 
12705 	group->addChild(subGroup.release());
12706 }
12707 
addResolveImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12708 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12709 {
12710 	addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind, extensionUse);
12711 	addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind, extensionUse);
12712 	addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind, extensionUse);
12713 	addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind, extensionUse);
12714 	addTestGroup(group, "whole_copy_before_resolving_no_cab", "Resolve from image to image without using USAGE_COLOR_ATTACHMENT_BIT (whole copy before resolving)", addResolveImageWholeCopyWithoutCabBeforeResolvingTests, allocationKind, extensionUse);
12715 	addTestGroup(group, "diff_layout_copy_before_resolving", "Resolve from image to image (whole copy before resolving with different layouts)", addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests, allocationKind, extensionUse);
12716 	addTestGroup(group, "layer_copy_before_resolving", "Resolve from image to image (layer copy before resolving)", addResolveImageLayerCopyBeforeResolvingTests, allocationKind, extensionUse);
12717 	addTestGroup(group, "copy_with_regions_before_resolving", "Resolve from image to image (region copy before resolving)", addResolveCopyImageWithRegionsTests, allocationKind, extensionUse);
12718 	addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind, extensionUse);
12719 	addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind, extensionUse);
12720 	addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind, extensionUse);
12721 }
12722 
addCopiesAndBlittingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12723 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12724 {
12725 	addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind, extensionUse);
12726 	addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind, extensionUse);
12727 	addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind, extensionUse);
12728 	addTestGroup(group, "buffer_to_depthstencil", "Copy from buffer to depth/Stencil", addBufferToDepthStencilTests, allocationKind, extensionUse);
12729 	addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind, extensionUse);
12730 	addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind, extensionUse);
12731 	addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind, extensionUse);
12732 }
12733 
addCoreCopiesAndBlittingTests(tcu::TestCaseGroup * group)12734 void addCoreCopiesAndBlittingTests(tcu::TestCaseGroup* group)
12735 {
12736 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED, EXTENSION_USE_NONE);
12737 	addBufferCopyOffsetTests(group);
12738 }
12739 
12740 
addDedicatedAllocationCopiesAndBlittingTests(tcu::TestCaseGroup * group)12741 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
12742 {
12743 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_NONE);
12744 }
12745 
addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup * group)12746 void addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup* group)
12747 {
12748 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_COPY_COMMANDS2);
12749 }
12750 
12751 } // anonymous
12752 
createCopiesAndBlittingTests(tcu::TestContext & testCtx)12753 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
12754 {
12755 	de::MovePtr<tcu::TestCaseGroup>	copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
12756 
12757 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", "Core Copies And Blitting Tests", addCoreCopiesAndBlittingTests));
12758 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation",	"Copies And Blitting Tests For Dedicated Memory Allocation",	addDedicatedAllocationCopiesAndBlittingTests));
12759 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "copy_commands2", "Copies And Blitting Tests using KHR_copy_commands2", addExtensionCopiesAndBlittingTests));
12760 
12761 	return copiesAndBlittingTests.release();
12762 }
12763 
12764 } // api
12765 } // vkt
12766