• 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 #include "tcuCommandLine.hpp"
40 
41 #include "vkImageUtil.hpp"
42 #include "vkMemUtil.hpp"
43 #include "vkPrograms.hpp"
44 #include "vkQueryUtil.hpp"
45 #include "vkDeviceUtil.hpp"
46 #include "vkRefUtil.hpp"
47 #include "vktTestCase.hpp"
48 #include "vktTestCaseUtil.hpp"
49 #include "vktTestGroupUtil.hpp"
50 #include "vkTypeUtil.hpp"
51 #include "vkCmdUtil.hpp"
52 #include "vkObjUtil.hpp"
53 #include "vkBuilderUtil.hpp"
54 #include "vkBufferWithMemory.hpp"
55 #include "vkBarrierUtil.hpp"
56 
57 #include "pipeline/vktPipelineImageUtil.hpp"		// required for compressed image blit
58 #include "vktCustomInstancesDevices.hpp"
59 #include "vkSafetyCriticalUtil.hpp"
60 
61 #include <set>
62 #include <array>
63 #include <algorithm>
64 #include <iterator>
65 #include <limits>
66 #include <sstream>
67 
68 namespace vkt
69 {
70 
71 namespace api
72 {
73 
74 namespace
75 {
76 
77 enum FillMode
78 {
79 	FILL_MODE_GRADIENT = 0,
80 	FILL_MODE_WHITE,
81 	FILL_MODE_BLACK,
82 	FILL_MODE_RED,
83 	FILL_MODE_MULTISAMPLE,
84 	FILL_MODE_BLUE_RED_X,
85 	FILL_MODE_BLUE_RED_Y,
86 	FILL_MODE_BLUE_RED_Z,
87 
88 	FILL_MODE_LAST
89 };
90 
91 enum MirrorModeBits
92 {
93 	MIRROR_MODE_X		= (1<<0),
94 	MIRROR_MODE_Y		= (1<<1),
95 	MIRROR_MODE_Z		= (1<<2),
96 	MIRROR_MODE_LAST	= (1<<3),
97 };
98 
99 using MirrorMode = deUint32;
100 
101 enum AllocationKind
102 {
103 	ALLOCATION_KIND_SUBALLOCATED,
104 	ALLOCATION_KIND_DEDICATED,
105 };
106 
107 enum ExtensionUse
108 {
109 	EXTENSION_USE_NONE,
110 	EXTENSION_USE_COPY_COMMANDS2,
111 };
112 
113 template <typename Type>
114 class BinaryCompare
115 {
116 public:
operator ()(const Type & a,const Type & b) const117 	bool operator() (const Type& a, const Type& b) const
118 	{
119 		return deMemCmp(&a, &b, sizeof(Type)) < 0;
120 	}
121 };
122 
123 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> >	FormatSet;
124 
125 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
126 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
127 
128 using namespace vk;
129 
130 const deInt32					defaultSize				= 64;
131 const deInt32					defaultHalfSize			= defaultSize / 2;
132 const deInt32					defaultQuarterSize		= defaultSize / 4;
133 const deInt32					defaultSixteenthSize	= defaultSize / 16;
134 const VkExtent3D				defaultExtent			= {defaultSize, defaultSize, 1};
135 const VkExtent3D				defaultHalfExtent		= {defaultHalfSize, defaultHalfSize, 1};
136 const VkExtent3D				default1dExtent			= {defaultSize, 1, 1};
137 const VkExtent3D				default3dExtent			= {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize};
138 
139 const VkImageSubresourceLayers	defaultSourceLayer		=
140 {
141 	VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
142 	0u,							// deUint32				mipLevel;
143 	0u,							// deUint32				baseArrayLayer;
144 	1u,							// deUint32				layerCount;
145 };
146 
convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)147 VkImageCopy2KHR convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)
148 {
149 	const VkImageCopy2KHR	imageCopy2 =
150 	{
151 		VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR,		// VkStructureType				sType;
152 		DE_NULL,								// const void*					pNext;
153 		imageCopy.srcSubresource,				// VkImageSubresourceLayers		srcSubresource;
154 		imageCopy.srcOffset,					// VkOffset3D					srcOffset;
155 		imageCopy.dstSubresource,				// VkImageSubresourceLayers		dstSubresource;
156 		imageCopy.dstOffset,					// VkOffset3D					dstOffset;
157 		imageCopy.extent						// VkExtent3D					extent;
158 	};
159 	return imageCopy2;
160 }
convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)161 VkBufferCopy2KHR convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)
162 {
163 	const VkBufferCopy2KHR	bufferCopy2 =
164 	{
165 		VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR,	// VkStructureType				sType;
166 		DE_NULL,								// const void*					pNext;
167 		bufferCopy.srcOffset,					// VkDeviceSize					srcOffset;
168 		bufferCopy.dstOffset,					// VkDeviceSize					dstOffset;
169 		bufferCopy.size,						// VkDeviceSize					size;
170 	};
171 	return bufferCopy2;
172 }
173 
convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)174 VkBufferImageCopy2KHR convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)
175 {
176 	const VkBufferImageCopy2KHR	bufferImageCopy2 =
177 	{
178 		VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR,	// VkStructureType				sType;
179 		DE_NULL,									// const void*					pNext;
180 		bufferImageCopy.bufferOffset,				// VkDeviceSize					bufferOffset;
181 		bufferImageCopy.bufferRowLength,			// uint32_t						bufferRowLength;
182 		bufferImageCopy.bufferImageHeight,			// uint32_t						bufferImageHeight;
183 		bufferImageCopy.imageSubresource,			// VkImageSubresourceLayers		imageSubresource;
184 		bufferImageCopy.imageOffset,				// VkOffset3D					imageOffset;
185 		bufferImageCopy.imageExtent					// VkExtent3D					imageExtent;
186 	};
187 	return bufferImageCopy2;
188 }
189 
convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)190 VkImageBlit2KHR convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)
191 {
192 	const VkImageBlit2KHR	imageBlit2 =
193 	{
194 		VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR,			// VkStructureType				sType;
195 		DE_NULL,									// const void*					pNext;
196 		imageBlit.srcSubresource,					// VkImageSubresourceLayers		srcSubresource;
197 		{											// VkOffset3D					srcOffsets[2];
198 			{
199 				imageBlit.srcOffsets[0].x,				// VkOffset3D			srcOffsets[0].x;
200 				imageBlit.srcOffsets[0].y,				// VkOffset3D			srcOffsets[0].y;
201 				imageBlit.srcOffsets[0].z				// VkOffset3D			srcOffsets[0].z;
202 			},
203 			{
204 				imageBlit.srcOffsets[1].x,				// VkOffset3D			srcOffsets[1].x;
205 				imageBlit.srcOffsets[1].y,				// VkOffset3D			srcOffsets[1].y;
206 				imageBlit.srcOffsets[1].z				// VkOffset3D			srcOffsets[1].z;
207 			}
208 		},
209 		imageBlit.dstSubresource,					// VkImageSubresourceLayers		dstSubresource;
210 		{											// VkOffset3D					srcOffsets[2];
211 			{
212 				imageBlit.dstOffsets[0].x,				// VkOffset3D			dstOffsets[0].x;
213 				imageBlit.dstOffsets[0].y,				// VkOffset3D			dstOffsets[0].y;
214 				imageBlit.dstOffsets[0].z				// VkOffset3D			dstOffsets[0].z;
215 			},
216 			{
217 				imageBlit.dstOffsets[1].x,				// VkOffset3D			dstOffsets[1].x;
218 				imageBlit.dstOffsets[1].y,				// VkOffset3D			dstOffsets[1].y;
219 				imageBlit.dstOffsets[1].z				// VkOffset3D			dstOffsets[1].z;
220 			}
221 		}
222 	};
223 	return imageBlit2;
224 }
225 
convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)226 VkImageResolve2KHR convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)
227 {
228 	const VkImageResolve2KHR	imageResolve2 =
229 	{
230 		VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,		// VkStructureType				sType;
231 		DE_NULL,									// const void*					pNext;
232 		imageResolve.srcSubresource,				// VkImageSubresourceLayers		srcSubresource;
233 		imageResolve.srcOffset,						// VkOffset3D					srcOffset;
234 		imageResolve.dstSubresource,				// VkImageSubresourceLayers		dstSubresource;
235 		imageResolve.dstOffset,						// VkOffset3D					dstOffset;
236 		imageResolve.extent							// VkExtent3D					extent;
237 	};
238 	return imageResolve2;
239 }
240 
getAspectFlags(tcu::TextureFormat format)241 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
242 {
243 	VkImageAspectFlags	aspectFlag	= 0;
244 	aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
245 	aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
246 
247 	if (!aspectFlag)
248 		aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
249 
250 	return aspectFlag;
251 }
252 
getAspectFlags(VkFormat format)253 VkImageAspectFlags getAspectFlags (VkFormat format)
254 {
255 	if (isCompressedFormat(format))
256 		return VK_IMAGE_ASPECT_COLOR_BIT;
257 	else
258 		return getAspectFlags(mapVkFormat(format));
259 }
260 
getSizeCompatibleTcuTextureFormat(VkFormat format)261 tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
262 {
263 	if (isCompressedFormat(format))
264 		return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
265 	else
266 		return mapVkFormat(format);
267 }
268 
269 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
270 // except that it supports some formats that are not mappable to VkFormat.
271 // When we are checking combined depth and stencil formats, each aspect is
272 // checked separately, and in some cases we construct PBA with a format that
273 // is not mappable to VkFormat.
isFloatFormat(tcu::TextureFormat format)274 bool isFloatFormat (tcu::TextureFormat format)
275 {
276 	return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
277 }
278 
279 union CopyRegion
280 {
281 	VkBufferCopy			bufferCopy;
282 	VkImageCopy				imageCopy;
283 	VkBufferImageCopy		bufferImageCopy;
284 	VkImageBlit				imageBlit;
285 	VkImageResolve			imageResolve;
286 };
287 
288 struct ImageParms
289 {
290 	VkImageType			imageType;
291 	VkFormat			format;
292 	VkExtent3D			extent;
293 	VkImageTiling		tiling;
294 	VkImageLayout		operationLayout;
295 	VkImageCreateFlags	createFlags;
296 	FillMode			fillMode;
297 };
298 
299 struct TestParams
300 {
301 	union Data
302 	{
303 		struct Buffer
304 		{
305 			VkDeviceSize	size;
306 		} buffer;
307 
308 		ImageParms	image;
309 	} src, dst;
310 
311 	std::vector<CopyRegion>	regions;
312 
313 	union
314 	{
315 		VkFilter				filter;
316 		VkSampleCountFlagBits	samples;
317 	};
318 
319 	AllocationKind	allocationKind;
320 	ExtensionUse	extensionUse;
321 	deUint32		mipLevels;
322 	deBool			singleCommand;
323 	deUint32		barrierCount;
324 	deBool			separateDepthStencilLayouts;
325 	deBool			clearDestination;
326 	deBool			imageOffset;
327 
TestParamsvkt::api::__anon4493ca420111::TestParams328 	TestParams (void)
329 	{
330 		allocationKind				= ALLOCATION_KIND_DEDICATED;
331 		extensionUse				= EXTENSION_USE_NONE;
332 		mipLevels					= 1u;
333 		singleCommand				= DE_TRUE;
334 		barrierCount				= 1u;
335 		separateDepthStencilLayouts	= DE_FALSE;
336 		src.image.createFlags		= VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
337 		dst.image.createFlags		= VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
338 		src.image.fillMode			= FILL_MODE_GRADIENT;
339 		dst.image.fillMode			= FILL_MODE_WHITE;
340 		clearDestination			= DE_FALSE;
341 		samples						= VK_SAMPLE_COUNT_1_BIT;
342 		imageOffset					= false;
343 	}
344 };
345 
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)346 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&	vki,
347 										const DeviceInterface&		vkd,
348 										const VkPhysicalDevice&		physDevice,
349 										const VkDevice				device,
350 										const VkBuffer&				buffer,
351 										const MemoryRequirement		requirement,
352 										Allocator&					allocator,
353 										AllocationKind				allocationKind)
354 {
355 	switch (allocationKind)
356 	{
357 		case ALLOCATION_KIND_SUBALLOCATED:
358 		{
359 			const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
360 
361 			return allocator.allocate(memoryRequirements, requirement);
362 		}
363 
364 		case ALLOCATION_KIND_DEDICATED:
365 		{
366 			return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
367 		}
368 
369 		default:
370 		{
371 			TCU_THROW(InternalError, "Invalid allocation kind");
372 		}
373 	}
374 }
375 
allocateImage(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkImage & image,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind,const deUint32 offset)376 de::MovePtr<Allocation> allocateImage (const InstanceInterface&		vki,
377 									   const DeviceInterface&		vkd,
378 									   const VkPhysicalDevice&		physDevice,
379 									   const VkDevice				device,
380 									   const VkImage&				image,
381 									   const MemoryRequirement		requirement,
382 									   Allocator&					allocator,
383 									   AllocationKind				allocationKind,
384 									   const deUint32				offset)
385 {
386 	switch (allocationKind)
387 	{
388 		case ALLOCATION_KIND_SUBALLOCATED:
389 		{
390 			VkMemoryRequirements memoryRequirements	= getImageMemoryRequirements(vkd, device, image);
391 			memoryRequirements.size += offset;
392 
393 			return allocator.allocate(memoryRequirements, requirement);
394 		}
395 
396 		case ALLOCATION_KIND_DEDICATED:
397 		{
398 			VkMemoryRequirements					memoryRequirements		= getImageMemoryRequirements(vkd, device, image);
399 			memoryRequirements.size += offset;
400 
401 			const VkMemoryDedicatedAllocateInfo		dedicatedAllocationInfo	=
402 			{
403 				VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,				// VkStructureType		sType
404 				DE_NULL,														// const void*			pNext
405 				image,															// VkImage				image
406 				DE_NULL															// VkBuffer				buffer
407 			};
408 
409 			return allocateExtended(vki, vkd, physDevice, device, memoryRequirements, requirement, &dedicatedAllocationInfo);
410 		}
411 
412 		default:
413 		{
414 			TCU_THROW(InternalError, "Invalid allocation kind");
415 		}
416 	}
417 }
418 
419 
getArraySize(const ImageParms & parms)420 inline deUint32 getArraySize(const ImageParms& parms)
421 {
422 	return (parms.imageType != VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u;
423 }
424 
getCreateFlags(const ImageParms & parms)425 inline VkImageCreateFlags  getCreateFlags(const ImageParms& parms)
426 {
427 	if (parms.createFlags == VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM)
428 		return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
429 	else
430 		return parms.createFlags;
431 }
432 
getExtent3D(const ImageParms & parms,deUint32 mipLevel=0u)433 inline VkExtent3D getExtent3D(const ImageParms& parms, deUint32 mipLevel = 0u)
434 {
435 	const bool			isCompressed	= isCompressedFormat(parms.format);
436 	const deUint32		blockWidth		= (isCompressed) ? getBlockWidth(parms.format) : 1u;
437 	const deUint32		blockHeight		= (isCompressed) ? getBlockHeight(parms.format) : 1u;
438 
439 	if (isCompressed && mipLevel != 0u)
440 		DE_FATAL("Not implemented");
441 
442 	const VkExtent3D	extent			=
443 	{
444 		(parms.extent.width >> mipLevel) * blockWidth,
445 		(parms.imageType != VK_IMAGE_TYPE_1D) ? ((parms.extent.height >> mipLevel) * blockHeight) : 1u,
446 		(parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
447 	};
448 	return extent;
449 }
450 
mapCombinedToDepthTransferFormat(const tcu::TextureFormat & combinedFormat)451 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
452 {
453 	tcu::TextureFormat format;
454 	switch (combinedFormat.type)
455 	{
456 		case tcu::TextureFormat::UNORM_INT16:
457 		case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
458 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
459 			break;
460 		case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
461 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
462 			break;
463 		case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
464 		case tcu::TextureFormat::FLOAT:
465 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
466 			break;
467 		default:
468 			DE_ASSERT(false);
469 			break;
470 	}
471 	return format;
472 }
473 
474 class CopiesAndBlittingTestInstance : public vkt::TestInstance
475 {
476 public:
477 										CopiesAndBlittingTestInstance		(Context&	context,
478 																			 TestParams	testParams);
479 	virtual tcu::TestStatus				iterate								(void) = 0;
480 
481 protected:
482 	const TestParams					m_params;
483 
484 	VkDevice							m_device;
485 	VkQueue								m_queue;
486 	Allocator*							m_allocator;
487 	Move<VkCommandPool>					m_cmdPool;
488 	Move<VkCommandBuffer>				m_cmdBuffer;
489 	de::MovePtr<tcu::TextureLevel>		m_sourceTextureLevel;
490 	de::MovePtr<tcu::TextureLevel>		m_destinationTextureLevel;
491 	de::MovePtr<tcu::TextureLevel>		m_expectedTextureLevel[16];
492 
493 	void								generateBuffer						(tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
494 	virtual void						generateExpectedResult				(void);
495 	void								uploadBuffer						(const tcu::ConstPixelBufferAccess& bufferAccess, const Allocation& bufferAlloc);
496 	void								uploadImage							(const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u);
497 	virtual tcu::TestStatus				checkTestResult						(tcu::ConstPixelBufferAccess result);
498 	virtual void						copyRegionToTextureLevel			(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u) = 0;
calculateSize(tcu::ConstPixelBufferAccess src) const499 	deUint32							calculateSize						(tcu::ConstPixelBufferAccess src) const
500 										{
501 											return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
502 										}
503 
504 	de::MovePtr<tcu::TextureLevel>		readImage							(vk::VkImage				image,
505 																			 const ImageParms&			imageParms,
506 																			 const deUint32				mipLevel = 0u);
507 
508 private:
509 	void								uploadImageAspect					(const tcu::ConstPixelBufferAccess&	src,
510 																			 const VkImage&						dst,
511 																			 const ImageParms&					parms,
512 																			 const deUint32						mipLevels = 1u);
513 	void								readImageAspect						(vk::VkImage						src,
514 																			 const tcu::PixelBufferAccess&		dst,
515 																			 const ImageParms&					parms,
516 																			 const deUint32						mipLevel = 0u);
517 };
518 
CopiesAndBlittingTestInstance(Context & context,TestParams testParams)519 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
520 	: vkt::TestInstance	(context)
521 	, m_params			(testParams)
522 {
523 	// Store default device, queue and allocator. Some tests override these with custom device and queue.
524 	m_device		= context.getDevice();
525 	m_queue			= context.getUniversalQueue();
526 	m_allocator		= &context.getDefaultAllocator();
527 	const DeviceInterface&		vk					= context.getDeviceInterface();
528 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
529 
530 	// Create command pool
531 	m_cmdPool = createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
532 
533 	// Create command buffer
534 	m_cmdBuffer = allocateCommandBuffer(vk, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
535 }
536 
generateBuffer(tcu::PixelBufferAccess buffer,int width,int height,int depth,FillMode mode)537 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
538 {
539 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(buffer.getFormat().type);
540 	tcu::Vec4						maxValue		(1.0f);
541 
542 	if (buffer.getFormat().order == tcu::TextureFormat::S)
543 	{
544 		// Stencil-only is stored in the first component. Stencil is always 8 bits.
545 		maxValue.x() = 1 << 8;
546 	}
547 	else if (buffer.getFormat().order == tcu::TextureFormat::DS)
548 	{
549 		// In a combined format, fillWithComponentGradients expects stencil in the fourth component.
550 		maxValue.w() = 1 << 8;
551 	}
552 	else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
553 	{
554 		// The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
555 		const tcu::IVec4	bits	= tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
556 		const int			signBit	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
557 
558 		for (int i = 0; i < 4; ++i)
559 		{
560 			if (bits[i] != 0)
561 				maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1);
562 		}
563 	}
564 
565 	if (mode == FILL_MODE_GRADIENT)
566 	{
567 		tcu::fillWithComponentGradients2(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
568 		return;
569 	}
570 
571 	const tcu::Vec4		redColor	(maxValue.x(),	0.0,			0.0,			maxValue.w());
572 	const tcu::Vec4		greenColor	(0.0,			maxValue.y(),	0.0,			maxValue.w());
573 	const tcu::Vec4		blueColor	(0.0,			0.0,			maxValue.z(),	maxValue.w());
574 	const tcu::Vec4		whiteColor	(maxValue.x(),	maxValue.y(),	maxValue.z(),	maxValue.w());
575 	const tcu::Vec4		blackColor	(0.0f,			0.0f,			0.0f,			0.0f);
576 
577 	for (int z = 0; z < depth;  ++z)
578 	for (int y = 0; y < height; ++y)
579 	for (int x = 0; x < width;  ++x)
580 	{
581 		switch (mode)
582 		{
583 			case FILL_MODE_WHITE:
584 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
585 				{
586 					buffer.setPixDepth(1.0f, x, y, z);
587 					if (tcu::hasStencilComponent(buffer.getFormat().order))
588 						buffer.setPixStencil(255, x, y, z);
589 				}
590 				else
591 					buffer.setPixel(whiteColor, x, y, z);
592 				break;
593 
594 			case FILL_MODE_BLACK:
595 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
596 				{
597 					buffer.setPixDepth(0.0f, x, y, z);
598 					if (tcu::hasStencilComponent(buffer.getFormat().order))
599 						buffer.setPixStencil(0, x, y, z);
600 				}
601 				else
602 					buffer.setPixel(blackColor, x, y, z);
603 				break;
604 
605 			case FILL_MODE_RED:
606 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
607 				{
608 					buffer.setPixDepth(redColor[0], x, y, z);
609 					if (tcu::hasStencilComponent(buffer.getFormat().order))
610 						buffer.setPixStencil((int)redColor[3], x, y, z);
611 				}
612 				else
613 					buffer.setPixel(redColor, x, y, z);
614 				break;
615 
616 			case FILL_MODE_BLUE_RED_X:
617 			case FILL_MODE_BLUE_RED_Y:
618 			case FILL_MODE_BLUE_RED_Z:
619 				bool useBlue;
620 				switch (mode)
621 				{
622 					case FILL_MODE_BLUE_RED_X: useBlue = (x & 1); break;
623 					case FILL_MODE_BLUE_RED_Y: useBlue = (y & 1); break;
624 					case FILL_MODE_BLUE_RED_Z: useBlue = (z & 1); break;
625 					default: DE_ASSERT(false); break;
626 				}
627 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
628 				{
629 					buffer.setPixDepth((useBlue ? blueColor[0] : redColor[0]), x, y, z);
630 					if (tcu::hasStencilComponent(buffer.getFormat().order))
631 						buffer.setPixStencil((useBlue ? (int) blueColor[3] : (int)redColor[3]), x, y, z);
632 				}
633 				else
634 					buffer.setPixel((useBlue ? blueColor : redColor), x, y, z);
635 				break;
636 
637 			case FILL_MODE_MULTISAMPLE:
638 			{
639 				float xScaled = static_cast<float>(x) / static_cast<float>(width);
640 				float yScaled = static_cast<float>(y) / static_cast<float>(height);
641 				buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
642 				break;
643 			}
644 
645 			default:
646 				break;
647 		}
648 	}
649 }
650 
uploadBuffer(const tcu::ConstPixelBufferAccess & bufferAccess,const Allocation & bufferAlloc)651 void CopiesAndBlittingTestInstance::uploadBuffer (const tcu::ConstPixelBufferAccess& bufferAccess, const Allocation& bufferAlloc)
652 {
653 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
654 	const deUint32				bufferSize	= calculateSize(bufferAccess);
655 
656 	// Write buffer data
657 	deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
658 	flushAlloc(vk, m_device, bufferAlloc);
659 }
660 
uploadImageAspect(const tcu::ConstPixelBufferAccess & imageAccess,const VkImage & image,const ImageParms & parms,const deUint32 mipLevels)661 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels)
662 {
663 	const InstanceInterface&		vki					= m_context.getInstanceInterface();
664 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
665 	const VkPhysicalDevice			vkPhysDevice		= m_context.getPhysicalDevice();
666 	const VkDevice					vkDevice			= m_device;
667 	const VkQueue					queue				= m_queue;
668 	Allocator&						memAlloc			= *m_allocator;
669 	Move<VkBuffer>					buffer;
670 	const deUint32					bufferSize			= calculateSize(imageAccess);
671 	de::MovePtr<Allocation>			bufferAlloc;
672 	const deUint32					arraySize			= getArraySize(parms);
673 	const VkExtent3D				imageExtent			= getExtent3D(parms);
674 	std::vector <VkBufferImageCopy>	copyRegions;
675 
676 	// Create source buffer
677 	{
678 		const VkBufferCreateInfo	bufferParams		=
679 		{
680 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
681 			DE_NULL,									// const void*			pNext;
682 			0u,											// VkBufferCreateFlags	flags;
683 			bufferSize,									// VkDeviceSize			size;
684 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
685 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
686 			0u,											// deUint32				queueFamilyIndexCount;
687 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
688 		};
689 
690 		buffer		= createBuffer(vk, vkDevice, &bufferParams);
691 		bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
692 		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
693 	}
694 
695 	// Barriers for copying buffer to image
696 	const VkBufferMemoryBarrier		preBufferBarrier	=
697 	{
698 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
699 		DE_NULL,										// const void*		pNext;
700 		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
701 		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
702 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
703 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
704 		*buffer,										// VkBuffer			buffer;
705 		0u,												// VkDeviceSize		offset;
706 		bufferSize										// VkDeviceSize		size;
707 	};
708 
709 	const VkImageAspectFlags		formatAspect		= (m_params.separateDepthStencilLayouts) ? getAspectFlags(imageAccess.getFormat()) : getAspectFlags(parms.format);
710 	const bool						skipPreImageBarrier	= (m_params.separateDepthStencilLayouts) ? false : ((formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
711 														  getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT));
712 
713 	const VkImageMemoryBarrier		preImageBarrier		=
714 	{
715 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
716 		DE_NULL,										// const void*				pNext;
717 		0u,												// VkAccessFlags			srcAccessMask;
718 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
719 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
720 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
721 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
722 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
723 		image,											// VkImage					image;
724 		{												// VkImageSubresourceRange	subresourceRange;
725 			formatAspect,	// VkImageAspectFlags	aspect;
726 			0u,				// deUint32				baseMipLevel;
727 			mipLevels,		// deUint32				mipLevels;
728 			0u,				// deUint32				baseArraySlice;
729 			arraySize,		// deUint32				arraySize;
730 		}
731 	};
732 
733 	const VkImageMemoryBarrier		postImageBarrier	=
734 	{
735 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
736 		DE_NULL,										// const void*				pNext;
737 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
738 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
739 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
740 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
741 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
742 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
743 		image,											// VkImage					image;
744 		{												// VkImageSubresourceRange	subresourceRange;
745 			formatAspect,				// VkImageAspectFlags	aspect;
746 			0u,							// deUint32				baseMipLevel;
747 			mipLevels,					// deUint32				mipLevels;
748 			0u,							// deUint32				baseArraySlice;
749 			arraySize,					// deUint32				arraySize;
750 		}
751 	};
752 
753 	for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
754 	{
755 		const VkExtent3D		copyExtent	=
756 		{
757 			imageExtent.width	>> mipLevelNdx,
758 			imageExtent.height	>> mipLevelNdx,
759 			imageExtent.depth
760 		};
761 
762 		const bool		isCompressed	= isCompressedFormat(parms.format);
763 		const deUint32	blockWidth		= (isCompressed) ? getBlockWidth(parms.format) : 1u;
764 		const deUint32	blockHeight		= (isCompressed) ? getBlockHeight(parms.format) : 1u;
765 		deUint32 rowLength		= ((copyExtent.width + blockWidth-1) / blockWidth) * blockWidth;
766 		deUint32 imageHeight	= ((copyExtent.height + blockHeight-1) / blockHeight) * blockHeight;
767 
768 		const VkBufferImageCopy	copyRegion	=
769 		{
770 			0u,												// VkDeviceSize				bufferOffset;
771 			rowLength,										// deUint32					bufferRowLength;
772 			imageHeight,									// deUint32					bufferImageHeight;
773 			{
774 				getAspectFlags(imageAccess.getFormat()),		// VkImageAspectFlags	aspect;
775 				mipLevelNdx,									// deUint32				mipLevel;
776 				0u,												// deUint32				baseArrayLayer;
777 				arraySize,										// deUint32				layerCount;
778 			},												// VkImageSubresourceLayers	imageSubresource;
779 			{ 0, 0, 0 },									// VkOffset3D				imageOffset;
780 			copyExtent										// VkExtent3D				imageExtent;
781 		};
782 
783 		copyRegions.push_back(copyRegion);
784 	}
785 
786 	// Write buffer data
787 	deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
788 	flushAlloc(vk, vkDevice, *bufferAlloc);
789 
790 	// Copy buffer to image
791 	beginCommandBuffer(vk, *m_cmdBuffer);
792 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
793 						  1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
794 	vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), &copyRegions[0]);
795 	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);
796 	endCommandBuffer(vk, *m_cmdBuffer);
797 
798 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
799 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
800 }
801 
uploadImage(const tcu::ConstPixelBufferAccess & src,VkImage dst,const ImageParms & parms,const deUint32 mipLevels)802 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels)
803 {
804 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
805 	{
806 		if (tcu::hasDepthComponent(src.getFormat().order))
807 		{
808 			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
809 			tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
810 			uploadImageAspect(depthTexture.getAccess(), dst, parms, mipLevels);
811 		}
812 
813 		if (tcu::hasStencilComponent(src.getFormat().order))
814 		{
815 			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
816 			tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
817 			uploadImageAspect(stencilTexture.getAccess(), dst, parms, mipLevels);
818 		}
819 	}
820 	else
821 		uploadImageAspect(src, dst, parms, mipLevels);
822 }
823 
checkTestResult(tcu::ConstPixelBufferAccess result)824 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
825 {
826 	const tcu::ConstPixelBufferAccess	expected	= m_expectedTextureLevel[0]->getAccess();
827 
828 	if (isFloatFormat(result.getFormat()))
829 	{
830 		const tcu::Vec4	threshold (0.0f);
831 		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
832 			return tcu::TestStatus::fail("CopiesAndBlitting test");
833 	}
834 	else
835 	{
836 		const tcu::UVec4 threshold (0u);
837 		if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
838 		{
839 			if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, 0.1f, tcu::COMPARE_LOG_RESULT))
840 				return tcu::TestStatus::fail("CopiesAndBlitting test");
841 		}
842 		else
843 		{
844 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
845 				return tcu::TestStatus::fail("CopiesAndBlitting test");
846 		}
847 	}
848 
849 	return tcu::TestStatus::pass("CopiesAndBlitting test");
850 }
851 
generateExpectedResult(void)852 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
853 {
854 	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
855 	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
856 
857 	m_expectedTextureLevel[0]	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
858 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
859 
860 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
861 		copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
862 }
863 
readImageAspect(vk::VkImage image,const tcu::PixelBufferAccess & dst,const ImageParms & imageParms,const deUint32 mipLevel)864 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage					image,
865 													 const tcu::PixelBufferAccess&	dst,
866 													 const ImageParms&				imageParms,
867 													 const deUint32					mipLevel)
868 {
869 	const InstanceInterface&	vki					= m_context.getInstanceInterface();
870 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
871 	const VkPhysicalDevice		physDevice			= m_context.getPhysicalDevice();
872 	const VkDevice				device				= m_device;
873 	const VkQueue				queue				= m_queue;
874 	Allocator&					allocator			= *m_allocator;
875 
876 	Move<VkBuffer>				buffer;
877 	de::MovePtr<Allocation>		bufferAlloc;
878 	const VkDeviceSize			pixelDataSize		= calculateSize(dst);
879 	const VkExtent3D			imageExtent			= getExtent3D(imageParms, mipLevel);
880 
881 	// Create destination buffer
882 	{
883 		const VkBufferCreateInfo			bufferParams			=
884 		{
885 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
886 			DE_NULL,									// const void*			pNext;
887 			0u,											// VkBufferCreateFlags	flags;
888 			pixelDataSize,								// VkDeviceSize			size;
889 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
890 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
891 			0u,											// deUint32				queueFamilyIndexCount;
892 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
893 		};
894 
895 		buffer		= createBuffer(vk, device, &bufferParams);
896 		bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
897 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
898 
899 		deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
900 		flushAlloc(vk, device, *bufferAlloc);
901 	}
902 
903 	// Barriers for copying image to buffer
904 	const VkImageAspectFlags				formatAspect			= getAspectFlags(imageParms.format);
905 	const VkImageMemoryBarrier				imageBarrier			=
906 	{
907 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
908 		DE_NULL,									// const void*				pNext;
909 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
910 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
911 		imageParms.operationLayout,					// VkImageLayout			oldLayout;
912 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
913 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
914 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
915 		image,										// VkImage					image;
916 		{											// VkImageSubresourceRange	subresourceRange;
917 			formatAspect,			// VkImageAspectFlags	aspectMask;
918 			mipLevel,				// deUint32				baseMipLevel;
919 			1u,						// deUint32				mipLevels;
920 			0u,						// deUint32				baseArraySlice;
921 			getArraySize(imageParms)// deUint32				arraySize;
922 		}
923 	};
924 
925 	const VkBufferMemoryBarrier				bufferBarrier			=
926 	{
927 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
928 		DE_NULL,									// const void*		pNext;
929 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
930 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
931 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
932 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
933 		*buffer,									// VkBuffer			buffer;
934 		0u,											// VkDeviceSize		offset;
935 		pixelDataSize								// VkDeviceSize		size;
936 	};
937 
938 	const VkImageMemoryBarrier				postImageBarrier		=
939 	{
940 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
941 		DE_NULL,									// const void*				pNext;
942 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
943 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
944 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			oldLayout;
945 		imageParms.operationLayout,					// VkImageLayout			newLayout;
946 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
947 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
948 		image,										// VkImage					image;
949 		{
950 			formatAspect,								// VkImageAspectFlags	aspectMask;
951 			mipLevel,									// deUint32				baseMipLevel;
952 			1u,											// deUint32				mipLevels;
953 			0u,											// deUint32				baseArraySlice;
954 			getArraySize(imageParms)					// deUint32				arraySize;
955 		}											// VkImageSubresourceRange	subresourceRange;
956 	};
957 
958 	// Copy image to buffer
959 	const bool		isCompressed	= isCompressedFormat(imageParms.format);
960 	const deUint32	blockWidth		= (isCompressed) ? getBlockWidth(imageParms.format) : 1u;
961 	const deUint32	blockHeight		= (isCompressed) ? getBlockHeight(imageParms.format) : 1u;
962 	deUint32 rowLength		= ((imageExtent.width + blockWidth-1) / blockWidth) * blockWidth;
963 	deUint32 imageHeight	= ((imageExtent.height + blockHeight-1) / blockHeight) * blockHeight;
964 
965 	// Copy image to buffer - note that there are cases where m_params.dst.image.format is not the same as dst.getFormat()
966 	const VkImageAspectFlags	aspect			= isCompressedFormat(m_params.dst.image.format) ?
967 													static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) : getAspectFlags(dst.getFormat());
968 	const VkBufferImageCopy		copyRegion		=
969 	{
970 		0u,								// VkDeviceSize				bufferOffset;
971 		rowLength,						// deUint32					bufferRowLength;
972 		imageHeight,					// deUint32					bufferImageHeight;
973 		{
974 			aspect,							// VkImageAspectFlags		aspect;
975 			mipLevel,						// deUint32					mipLevel;
976 			0u,								// deUint32					baseArrayLayer;
977 			getArraySize(imageParms),		// deUint32					layerCount;
978 		},								// VkImageSubresourceLayers	imageSubresource;
979 		{ 0, 0, 0 },					// VkOffset3D				imageOffset;
980 		imageExtent						// VkExtent3D				imageExtent;
981 	};
982 
983 	beginCommandBuffer(vk, *m_cmdBuffer);
984 	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);
985 	vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
986 	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);
987 	endCommandBuffer(vk, *m_cmdBuffer);
988 
989 	submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
990 	m_context.resetCommandPoolForVKSC(device, *m_cmdPool);
991 
992 	// Read buffer data
993 	invalidateAlloc(vk, device, *bufferAlloc);
994 	tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
995 }
996 
readImage(vk::VkImage image,const ImageParms & parms,const deUint32 mipLevel)997 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage	(vk::VkImage		image,
998 																		 const ImageParms&	parms,
999 																		 const deUint32		mipLevel)
1000 {
1001 	const tcu::TextureFormat		imageFormat	= getSizeCompatibleTcuTextureFormat(parms.format);
1002 	de::MovePtr<tcu::TextureLevel>	resultLevel	(new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
1003 
1004 	if (tcu::isCombinedDepthStencilType(imageFormat.type))
1005 	{
1006 		if (tcu::hasDepthComponent(imageFormat.order))
1007 		{
1008 			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
1009 			readImageAspect(image, depthTexture.getAccess(), parms, mipLevel);
1010 			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
1011 		}
1012 
1013 		if (tcu::hasStencilComponent(imageFormat.order))
1014 		{
1015 			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
1016 			readImageAspect(image, stencilTexture.getAccess(), parms, mipLevel);
1017 			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
1018 		}
1019 	}
1020 	else
1021 		readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
1022 
1023 	return resultLevel;
1024 }
1025 
1026 // Copy from image to image.
1027 
1028 class CopyImageToImage : public CopiesAndBlittingTestInstance
1029 {
1030 public:
1031 										CopyImageToImage			(Context&	context,
1032 																	 TestParams params);
1033 	virtual tcu::TestStatus				iterate						(void);
1034 
1035 protected:
1036 	virtual tcu::TestStatus				checkTestResult				(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
1037 
1038 private:
1039 	Move<VkImage>						m_source;
1040 	de::MovePtr<Allocation>				m_sourceImageAlloc;
1041 	Move<VkImage>						m_destination;
1042 	de::MovePtr<Allocation>				m_destinationImageAlloc;
1043 
1044 	virtual void						copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1045 };
1046 
CopyImageToImage(Context & context,TestParams params)1047 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
1048 	: CopiesAndBlittingTestInstance(context, params)
1049 {
1050 	const InstanceInterface&	vki					= context.getInstanceInterface();
1051 	const DeviceInterface&		vk					= context.getDeviceInterface();
1052 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
1053 	const VkDevice				vkDevice			= m_device;
1054 	Allocator&					memAlloc			= context.getDefaultAllocator();
1055 
1056 	// Create source image
1057 	{
1058 		const VkImageCreateInfo	sourceImageParams		=
1059 		{
1060 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1061 			DE_NULL,								// const void*			pNext;
1062 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
1063 			m_params.src.image.imageType,			// VkImageType			imageType;
1064 			m_params.src.image.format,				// VkFormat				format;
1065 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
1066 			1u,										// deUint32				mipLevels;
1067 			getArraySize(m_params.src.image),		// deUint32				arraySize;
1068 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1069 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1070 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1071 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1072 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1073 			0u,										// deUint32				queueFamilyIndexCount;
1074 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
1075 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1076 		};
1077 
1078 		m_source				= createImage(vk, vkDevice, &sourceImageParams);
1079 		m_sourceImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1080 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1081 	}
1082 
1083 	// Create destination image
1084 	{
1085 		const VkImageCreateInfo	destinationImageParams	=
1086 		{
1087 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1088 			DE_NULL,								// const void*			pNext;
1089 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
1090 			m_params.dst.image.imageType,			// VkImageType			imageType;
1091 			m_params.dst.image.format,				// VkFormat				format;
1092 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
1093 			1u,										// deUint32				mipLevels;
1094 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
1095 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1096 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1097 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1098 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1099 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1100 			0u,										// deUint32				queueFamilyIndexCount;
1101 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
1102 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1103 		};
1104 
1105 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
1106 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1107 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1108 	}
1109 }
1110 
iterate(void)1111 tcu::TestStatus CopyImageToImage::iterate (void)
1112 {
1113 	const bool					srcCompressed		= isCompressedFormat(m_params.src.image.format);
1114 	const bool					dstCompressed		= isCompressedFormat(m_params.dst.image.format);
1115 
1116 	const tcu::TextureFormat	srcTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1117 	const tcu::TextureFormat	dstTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1118 
1119 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1120 																				(int)m_params.src.image.extent.width,
1121 																				(int)m_params.src.image.extent.height,
1122 																				(int)m_params.src.image.extent.depth));
1123 	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);
1124 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1125 																				(int)m_params.dst.image.extent.width,
1126 																				(int)m_params.dst.image.extent.height,
1127 																				(int)m_params.dst.image.extent.depth));
1128 	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);
1129 	generateExpectedResult();
1130 
1131 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1132 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1133 
1134 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
1135 	const VkDevice				vkDevice			= m_device;
1136 	const VkQueue				queue				= m_queue;
1137 
1138 	std::vector<VkImageCopy>		imageCopies;
1139 	std::vector<VkImageCopy2KHR>	imageCopies2KHR;
1140 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1141 	{
1142 		VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1143 
1144 		// When copying between compressed and uncompressed formats the extent
1145 		// members represent the texel dimensions of the source image.
1146 		if (srcCompressed)
1147 		{
1148 			const deUint32	blockWidth	= getBlockWidth(m_params.src.image.format);
1149 			const deUint32	blockHeight	= getBlockHeight(m_params.src.image.format);
1150 
1151 			imageCopy.srcOffset.x *= blockWidth;
1152 			imageCopy.extent.width *= blockWidth;
1153 
1154 			// VUID-vkCmdCopyImage-srcImage-00146
1155 			if (m_params.src.image.imageType != vk::VK_IMAGE_TYPE_1D)
1156 			{
1157 				imageCopy.srcOffset.y *= blockHeight;
1158 				imageCopy.extent.height *= blockHeight;
1159 			}
1160 		}
1161 
1162 		if (dstCompressed)
1163 		{
1164 			const deUint32	blockWidth	= getBlockWidth(m_params.dst.image.format);
1165 			const deUint32	blockHeight	= getBlockHeight(m_params.dst.image.format);
1166 
1167 			imageCopy.dstOffset.x *= blockWidth;
1168 
1169 			// VUID-vkCmdCopyImage-dstImage-00152
1170 			if (m_params.dst.image.imageType != vk::VK_IMAGE_TYPE_1D)
1171 			{
1172 				imageCopy.dstOffset.y *= blockHeight;
1173 			}
1174 		}
1175 
1176 		if (m_params.extensionUse == EXTENSION_USE_NONE)
1177 		{
1178 			imageCopies.push_back(imageCopy);
1179 		}
1180 		else
1181 		{
1182 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1183 			imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1184 		}
1185 	}
1186 
1187 	VkImageMemoryBarrier	imageBarriers[]		=
1188 	{
1189 		// source image
1190 		{
1191 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1192 			DE_NULL,									// const void*				pNext;
1193 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1194 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
1195 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1196 			m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
1197 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1198 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1199 			m_source.get(),								// VkImage					image;
1200 			{											// VkImageSubresourceRange	subresourceRange;
1201 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
1202 				0u,								// deUint32				baseMipLevel;
1203 				1u,								// deUint32				mipLevels;
1204 				0u,								// deUint32				baseArraySlice;
1205 				getArraySize(m_params.src.image)// deUint32				arraySize;
1206 			}
1207 		},
1208 		// destination image
1209 		{
1210 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1211 			DE_NULL,									// const void*				pNext;
1212 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1213 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
1214 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1215 			m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
1216 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1217 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1218 			m_destination.get(),						// VkImage					image;
1219 			{											// VkImageSubresourceRange	subresourceRange;
1220 				getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
1221 				0u,								// deUint32				baseMipLevel;
1222 				1u,								// deUint32				mipLevels;
1223 				0u,								// deUint32				baseArraySlice;
1224 				getArraySize(m_params.dst.image)// deUint32				arraySize;
1225 			}
1226 		},
1227 	};
1228 
1229 	beginCommandBuffer(vk, *m_cmdBuffer);
1230 	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);
1231 
1232 	if (m_params.clearDestination)
1233 	{
1234 		VkImageSubresourceRange	range		= { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
1235 		VkClearColorValue		clearColor;
1236 
1237 		clearColor.float32[0] = 1.0f;
1238 		clearColor.float32[1] = 1.0f;
1239 		clearColor.float32[2] = 1.0f;
1240 		clearColor.float32[3] = 1.0f;
1241 		vk.cmdClearColorImage(*m_cmdBuffer, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u, &range);
1242 		imageBarriers[0].oldLayout = imageBarriers[0].newLayout;
1243 		imageBarriers[1].oldLayout = imageBarriers[1].newLayout;
1244 		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);
1245 	}
1246 
1247 	if (m_params.extensionUse == EXTENSION_USE_NONE)
1248 	{
1249 		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());
1250 	}
1251 #ifndef CTS_USES_VULKANSC
1252 	else
1253 	{
1254 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1255 		const VkCopyImageInfo2KHR copyImageInfo2KHR =
1256 		{
1257 			VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
1258 			DE_NULL,									// const void*				pNext;
1259 			m_source.get(),								// VkImage					srcImage;
1260 			m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
1261 			m_destination.get(),						// VkImage					dstImage;
1262 			m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
1263 			(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
1264 			imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
1265 		};
1266 
1267 		vk.cmdCopyImage2(*m_cmdBuffer, &copyImageInfo2KHR);
1268 	}
1269 #endif // CTS_USES_VULKANSC
1270 
1271 	endCommandBuffer(vk, *m_cmdBuffer);
1272 
1273 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1274 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
1275 
1276 	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);
1277 
1278 	return checkTestResult(resultTextureLevel->getAccess());
1279 }
1280 
checkTestResult(tcu::ConstPixelBufferAccess result)1281 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
1282 {
1283 	const tcu::Vec4	fThreshold (0.0f);
1284 	const tcu::UVec4 uThreshold (0u);
1285 
1286 	if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1287 	{
1288 		if (tcu::hasDepthComponent(result.getFormat().order))
1289 		{
1290 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
1291 			const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
1292 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1293 
1294 			if (isFloatFormat(result.getFormat()))
1295 			{
1296 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1297 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1298 			}
1299 			else
1300 			{
1301 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1302 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1303 			}
1304 		}
1305 
1306 		if (tcu::hasStencilComponent(result.getFormat().order))
1307 		{
1308 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
1309 			const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
1310 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1311 
1312 			if (isFloatFormat(result.getFormat()))
1313 			{
1314 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1315 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1316 			}
1317 			else
1318 			{
1319 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1320 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1321 			}
1322 		}
1323 	}
1324 	else
1325 	{
1326 		if (isFloatFormat(result.getFormat()))
1327 		{
1328 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1329 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1330 		}
1331 		else
1332 		{
1333 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1334 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1335 		}
1336 	}
1337 
1338 	return tcu::TestStatus::pass("CopiesAndBlitting test");
1339 }
1340 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1341 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1342 {
1343 	DE_UNREF(mipLevel);
1344 
1345 	VkOffset3D	srcOffset	= region.imageCopy.srcOffset;
1346 	VkOffset3D	dstOffset	= region.imageCopy.dstOffset;
1347 	VkExtent3D	extent		= region.imageCopy.extent;
1348 
1349 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1350 	{
1351 		dstOffset.z = srcOffset.z;
1352 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1353 	}
1354 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1355 	{
1356 		srcOffset.z = dstOffset.z;
1357 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1358 	}
1359 
1360 
1361 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1362 	{
1363 		DE_ASSERT(src.getFormat() == dst.getFormat());
1364 
1365 		// Copy depth.
1366 		if (tcu::hasDepthComponent(src.getFormat().order))
1367 		{
1368 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1369 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1370 			tcu::copy(dstSubRegion, srcSubRegion);
1371 		}
1372 
1373 		// Copy stencil.
1374 		if (tcu::hasStencilComponent(src.getFormat().order))
1375 		{
1376 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1377 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1378 			tcu::copy(dstSubRegion, srcSubRegion);
1379 		}
1380 	}
1381 	else
1382 	{
1383 		const tcu::ConstPixelBufferAccess	srcSubRegion		= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1384 		// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1385 		const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1386 		const tcu::PixelBufferAccess		dstSubRegion		= tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1387 
1388 		tcu::copy(dstSubRegion, srcSubRegion);
1389 	}
1390 }
1391 
1392 class CopyImageToImageTestCase : public vkt::TestCase
1393 {
1394 public:
CopyImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1395 							CopyImageToImageTestCase	(tcu::TestContext&				testCtx,
1396 														 const std::string&				name,
1397 														 const std::string&				description,
1398 														 const TestParams				params)
1399 								: vkt::TestCase	(testCtx, name, description)
1400 								, m_params		(params)
1401 	{}
1402 
createInstance(Context & context) const1403 	virtual TestInstance*	createInstance				(Context&						context) const
1404 	{
1405 		return new CopyImageToImage(context, m_params);
1406 	}
1407 
checkSupport(Context & context) const1408 	virtual void			checkSupport				(Context&						context) const
1409 	{
1410 		if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1411 		{
1412 			if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1413 				TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1414 		}
1415 
1416 		if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1417 		{
1418 			if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1419 				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1420 		}
1421 
1422 		if (m_params.separateDepthStencilLayouts)
1423 			if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1424 				TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1425 
1426 		if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1427 			(m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1428 		{
1429 			if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1430 				TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1431 		}
1432 
1433 		const VkPhysicalDeviceLimits	limits		= context.getDeviceProperties().limits;
1434 		VkImageFormatProperties			properties;
1435 
1436 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1437 																					m_params.src.image.format,
1438 																					m_params.src.image.imageType,
1439 																					VK_IMAGE_TILING_OPTIMAL,
1440 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1441 																					0,
1442 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1443 			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1444 																					m_params.dst.image.format,
1445 																					m_params.dst.image.imageType,
1446 																					VK_IMAGE_TILING_OPTIMAL,
1447 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1448 																					0,
1449 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1450 		{
1451 			TCU_THROW(NotSupportedError, "Format not supported");
1452 		}
1453 
1454 		// Check maxImageDimension1D
1455 		{
1456 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1457 				TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1458 
1459 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1460 				TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1461 		}
1462 
1463 		// Check maxImageDimension2D
1464 		{
1465 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1466 				|| m_params.src.image.extent.height > limits.maxImageDimension2D))
1467 			{
1468 				TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1469 			}
1470 
1471 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1472 				|| m_params.dst.image.extent.height > limits.maxImageDimension2D))
1473 			{
1474 				TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1475 			}
1476 		}
1477 
1478 		// Check maxImageDimension3D
1479 		{
1480 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1481 				|| m_params.src.image.extent.height > limits.maxImageDimension3D
1482 				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
1483 			{
1484 				TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1485 			}
1486 
1487 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1488 				|| m_params.dst.image.extent.height > limits.maxImageDimension3D
1489 				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
1490 			{
1491 				TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1492 			}
1493 		}
1494 	}
1495 
1496 private:
1497 	TestParams				m_params;
1498 };
1499 
1500 class CopyImageToImageMipmap : public CopiesAndBlittingTestInstance
1501 {
1502 public:
1503 										CopyImageToImageMipmap		(Context&	context,
1504 																	 TestParams params);
1505 	virtual tcu::TestStatus				iterate						(void);
1506 
1507 protected:
1508 	tcu::TestStatus						checkResult					(tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected);
1509 
1510 private:
1511 	Move<VkImage>						m_source;
1512 	de::MovePtr<Allocation>				m_sourceImageAlloc;
1513 	Move<VkImage>						m_destination;
1514 	de::MovePtr<Allocation>				m_destinationImageAlloc;
1515 
1516 	virtual void						copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1517 
1518 };
1519 
CopyImageToImageMipmap(Context & context,TestParams params)1520 CopyImageToImageMipmap::CopyImageToImageMipmap (Context& context, TestParams params)
1521 	: CopiesAndBlittingTestInstance(context, params)
1522 {
1523 	const InstanceInterface&	vki					= context.getInstanceInterface();
1524 	const DeviceInterface&		vk					= context.getDeviceInterface();
1525 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
1526 	const VkDevice				vkDevice			= m_device;
1527 	Allocator&					memAlloc			= context.getDefaultAllocator();
1528 
1529 	// Create source image
1530 	{
1531 		const VkImageCreateInfo	sourceImageParams		=
1532 		{
1533 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1534 			DE_NULL,								// const void*			pNext;
1535 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
1536 			m_params.src.image.imageType,			// VkImageType			imageType;
1537 			m_params.src.image.format,				// VkFormat				format;
1538 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
1539 			params.mipLevels,						// deUint32				mipLevels;
1540 			getArraySize(m_params.src.image),		// deUint32				arraySize;
1541 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1542 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1543 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1544 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1545 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1546 			0u,										// deUint32				queueFamilyIndexCount;
1547 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
1548 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1549 		};
1550 
1551 		m_source				= createImage(vk, vkDevice, &sourceImageParams);
1552 		m_sourceImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1553 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1554 	}
1555 
1556 	// Create destination image
1557 	{
1558 		const VkImageCreateInfo	destinationImageParams	=
1559 		{
1560 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1561 			DE_NULL,								// const void*			pNext;
1562 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
1563 			m_params.dst.image.imageType,			// VkImageType			imageType;
1564 			m_params.dst.image.format,				// VkFormat				format;
1565 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
1566 			params.mipLevels,						// deUint32				mipLevels;
1567 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
1568 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1569 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1570 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1571 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1572 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1573 			0u,										// deUint32				queueFamilyIndexCount;
1574 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
1575 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1576 		};
1577 
1578 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
1579 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1580 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1581 	}
1582 }
1583 
iterate(void)1584 tcu::TestStatus CopyImageToImageMipmap::iterate (void)
1585 {
1586 	const bool					srcCompressed		= isCompressedFormat(m_params.src.image.format);
1587 	const bool					dstCompressed		= isCompressedFormat(m_params.dst.image.format);
1588 
1589 	const tcu::TextureFormat	srcTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1590 	const tcu::TextureFormat	dstTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1591 
1592 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1593 																				(int)m_params.src.image.extent.width,
1594 																				(int)m_params.src.image.extent.height,
1595 																				(int)m_params.src.image.extent.depth));
1596 	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);
1597 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image, m_params.mipLevels);
1598 
1599 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1600 																					 (int)m_params.dst.image.extent.width,
1601 																					 (int)m_params.dst.image.extent.height,
1602 																					 (int)m_params.dst.image.extent.depth));
1603 	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);
1604 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
1605 
1606 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
1607 	const VkDevice				vkDevice			= m_device;
1608 	const VkQueue				queue				= m_queue;
1609 
1610 	std::vector<VkImageCopy>		imageCopies;
1611 	std::vector<VkImageCopy2KHR>	imageCopies2KHR;
1612 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1613 	{
1614 		VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1615 
1616 		// When copying between compressed and uncompressed formats the extent
1617 		// members represent the texel dimensions of the source image.
1618 		if (srcCompressed)
1619 		{
1620 			const deUint32	blockWidth	= getBlockWidth(m_params.src.image.format);
1621 			const deUint32	blockHeight	= getBlockHeight(m_params.src.image.format);
1622 
1623 			imageCopy.srcOffset.x *= blockWidth;
1624 			imageCopy.srcOffset.y *= blockHeight;
1625 			imageCopy.extent.width *= blockWidth;
1626 			imageCopy.extent.height *= blockHeight;
1627 		}
1628 
1629 		if (dstCompressed)
1630 		{
1631 			const deUint32	blockWidth	= getBlockWidth(m_params.dst.image.format);
1632 			const deUint32	blockHeight	= getBlockHeight(m_params.dst.image.format);
1633 
1634 			imageCopy.dstOffset.x *= blockWidth;
1635 			imageCopy.dstOffset.y *= blockHeight;
1636 		}
1637 
1638 		if (m_params.extensionUse == EXTENSION_USE_NONE)
1639 		{
1640 			imageCopies.push_back(imageCopy);
1641 		}
1642 		else
1643 		{
1644 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1645 			imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1646 		}
1647 	}
1648 
1649 	VkImageMemoryBarrier	imageBarriers[]		=
1650 	{
1651 		// source image
1652 		{
1653 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1654 			DE_NULL,									// const void*				pNext;
1655 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1656 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
1657 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1658 			m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
1659 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1660 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1661 			m_source.get(),								// VkImage					image;
1662 			{											// VkImageSubresourceRange	subresourceRange;
1663 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
1664 				0u,								// deUint32				baseMipLevel;
1665 				m_params.mipLevels,				// deUint32				mipLevels;
1666 				0u,								// deUint32				baseArraySlice;
1667 				getArraySize(m_params.src.image)// deUint32				arraySize;
1668 			}
1669 		},
1670 		// destination image
1671 		{
1672 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1673 			DE_NULL,									// const void*				pNext;
1674 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1675 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
1676 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1677 			m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
1678 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1679 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1680 			m_destination.get(),						// VkImage					image;
1681 			{											// VkImageSubresourceRange	subresourceRange;
1682 				getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
1683 				0u,								// deUint32				baseMipLevel;
1684 				m_params.mipLevels,				// deUint32				mipLevels;
1685 				0u,								// deUint32				baseArraySlice;
1686 				getArraySize(m_params.dst.image)// deUint32				arraySize;
1687 			}
1688 		},
1689 	};
1690 
1691 	beginCommandBuffer(vk, *m_cmdBuffer);
1692 	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);
1693 
1694 	if (m_params.extensionUse == EXTENSION_USE_NONE)
1695 	{
1696 		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());
1697 	}
1698 #ifndef CTS_USES_VULKANSC
1699 	else
1700 	{
1701 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1702 		const VkCopyImageInfo2KHR copyImageInfo2KHR =
1703 		{
1704 			VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
1705 			DE_NULL,									// const void*				pNext;
1706 			m_source.get(),								// VkImage					srcImage;
1707 			m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
1708 			m_destination.get(),						// VkImage					dstImage;
1709 			m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
1710 			(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
1711 			imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
1712 		};
1713 
1714 		vk.cmdCopyImage2(*m_cmdBuffer, &copyImageInfo2KHR);
1715 	}
1716 #endif // CTS_USES_VULKANSC
1717 
1718 	endCommandBuffer(vk, *m_cmdBuffer);
1719 
1720 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1721 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
1722 
1723 	for (deUint32 miplevel = 0; miplevel < m_params.mipLevels; miplevel++)
1724 	{
1725 		de::MovePtr<tcu::TextureLevel>	resultTextureLevel		= readImage(*m_destination, m_params.dst.image, miplevel);
1726 		de::MovePtr<tcu::TextureLevel>	expectedTextureLevel	= readImage(*m_source, m_params.src.image, miplevel);
1727 
1728 		tcu::TestStatus result = checkResult(resultTextureLevel->getAccess(), expectedTextureLevel->getAccess());
1729 		if (result.getCode() != QP_TEST_RESULT_PASS)
1730 			return result;
1731 	}
1732 	return tcu::TestStatus::pass("Pass");
1733 }
1734 
checkResult(tcu::ConstPixelBufferAccess result,tcu::ConstPixelBufferAccess expected)1735 tcu::TestStatus CopyImageToImageMipmap::checkResult (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected)
1736 {
1737 	const tcu::Vec4	fThreshold (0.0f);
1738 	const tcu::UVec4 uThreshold (0u);
1739 
1740 	if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1741 	{
1742 		if (tcu::hasDepthComponent(result.getFormat().order))
1743 		{
1744 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
1745 			const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
1746 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(expected, mode);
1747 
1748 			if (isFloatFormat(result.getFormat()))
1749 			{
1750 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1751 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1752 			}
1753 			else
1754 			{
1755 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1756 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1757 			}
1758 		}
1759 
1760 		if (tcu::hasStencilComponent(result.getFormat().order))
1761 		{
1762 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
1763 			const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
1764 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(expected, mode);
1765 
1766 			if (isFloatFormat(result.getFormat()))
1767 			{
1768 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1769 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1770 			}
1771 			else
1772 			{
1773 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1774 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1775 			}
1776 		}
1777 	}
1778 	else
1779 	{
1780 		if (isFloatFormat(result.getFormat()))
1781 		{
1782 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, fThreshold, tcu::COMPARE_LOG_RESULT))
1783 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1784 		}
1785 		else if (isSnormFormat(mapTextureFormat(result.getFormat())))
1786 		{
1787 			// There may be an ambiguity between two possible binary representations of 1.0.
1788 			// Get rid of that by expanding the data to floats and re-normalizing again.
1789 
1790 			tcu::TextureLevel resultSnorm	(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
1791 			{
1792 				tcu::TextureLevel resultFloat	(tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
1793 
1794 				tcu::copy(resultFloat.getAccess(), result);
1795 				tcu::copy(resultSnorm, resultFloat.getAccess());
1796 			}
1797 
1798 			tcu::TextureLevel expectedSnorm	(expected.getFormat(), expected.getWidth(), expected.getHeight(), expected.getDepth());
1799 
1800 			{
1801 				tcu::TextureLevel expectedFloat	(tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
1802 
1803 				tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess());
1804 				tcu::copy(expectedSnorm, expectedFloat.getAccess());
1805 			}
1806 
1807 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT))
1808 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1809 		}
1810 		else
1811 		{
1812 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, uThreshold, tcu::COMPARE_LOG_RESULT))
1813 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1814 		}
1815 	}
1816 
1817 	return tcu::TestStatus::pass("CopiesAndBlitting test");
1818 }
1819 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1820 void CopyImageToImageMipmap::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1821 {
1822 	DE_UNREF(mipLevel);
1823 
1824 	VkOffset3D	srcOffset	= region.imageCopy.srcOffset;
1825 	VkOffset3D	dstOffset	= region.imageCopy.dstOffset;
1826 	VkExtent3D	extent		= region.imageCopy.extent;
1827 
1828 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1829 	{
1830 		dstOffset.z = srcOffset.z;
1831 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1832 	}
1833 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1834 	{
1835 		srcOffset.z = dstOffset.z;
1836 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1837 	}
1838 
1839 
1840 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1841 	{
1842 		DE_ASSERT(src.getFormat() == dst.getFormat());
1843 
1844 		// Copy depth.
1845 		if (tcu::hasDepthComponent(src.getFormat().order))
1846 		{
1847 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1848 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1849 			tcu::copy(dstSubRegion, srcSubRegion);
1850 		}
1851 
1852 		// Copy stencil.
1853 		if (tcu::hasStencilComponent(src.getFormat().order))
1854 		{
1855 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1856 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1857 			tcu::copy(dstSubRegion, srcSubRegion);
1858 		}
1859 	}
1860 	else
1861 	{
1862 		const tcu::ConstPixelBufferAccess	srcSubRegion		= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1863 		// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1864 		const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1865 		const tcu::PixelBufferAccess		dstSubRegion		= tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1866 
1867 		tcu::copy(dstSubRegion, srcSubRegion);
1868 	}
1869 }
1870 
1871 class CopyImageToImageMipmapTestCase : public vkt::TestCase
1872 {
1873 public:
CopyImageToImageMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1874 							CopyImageToImageMipmapTestCase	(tcu::TestContext&				testCtx,
1875 															 const std::string&				name,
1876 															 const std::string&				description,
1877 															 const TestParams				params)
1878 								: vkt::TestCase	(testCtx, name, description)
1879 								, m_params		(params)
1880 	{}
1881 
createInstance(Context & context) const1882 	virtual TestInstance*	createInstance				(Context&						context) const
1883 	{
1884 		return new CopyImageToImageMipmap(context, m_params);
1885 	}
1886 
checkSupport(Context & context) const1887 	virtual void			checkSupport				(Context&						context) const
1888 	{
1889 		if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1890 		{
1891 			if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1892 				TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1893 		}
1894 
1895 		if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1896 		{
1897 			if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1898 				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1899 		}
1900 
1901 		if (m_params.separateDepthStencilLayouts)
1902 			if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1903 				TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1904 
1905 		if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1906 			(m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1907 		{
1908 			if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1909 				TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1910 		}
1911 
1912 		const VkPhysicalDeviceLimits	limits		= context.getDeviceProperties().limits;
1913 		VkImageFormatProperties			properties;
1914 
1915 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1916 																					m_params.src.image.format,
1917 																					m_params.src.image.imageType,
1918 																					VK_IMAGE_TILING_OPTIMAL,
1919 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1920 																					0,
1921 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1922 			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1923 																					m_params.dst.image.format,
1924 																					m_params.dst.image.imageType,
1925 																					VK_IMAGE_TILING_OPTIMAL,
1926 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1927 																					0,
1928 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1929 		{
1930 			TCU_THROW(NotSupportedError, "Format not supported");
1931 		}
1932 
1933 		// Check maxImageDimension1D
1934 		{
1935 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1936 				TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1937 
1938 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1939 				TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1940 		}
1941 
1942 		// Check maxImageDimension2D
1943 		{
1944 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1945 				|| m_params.src.image.extent.height > limits.maxImageDimension2D))
1946 			{
1947 				TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1948 			}
1949 
1950 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1951 				|| m_params.dst.image.extent.height > limits.maxImageDimension2D))
1952 			{
1953 				TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1954 			}
1955 		}
1956 
1957 		// Check maxImageDimension3D
1958 		{
1959 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1960 				|| m_params.src.image.extent.height > limits.maxImageDimension3D
1961 				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
1962 			{
1963 				TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1964 			}
1965 
1966 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1967 				|| m_params.dst.image.extent.height > limits.maxImageDimension3D
1968 				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
1969 			{
1970 				TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1971 			}
1972 		}
1973 	}
1974 
1975 private:
1976 	TestParams				m_params;
1977 };
1978 
1979 // Copy from buffer to buffer.
1980 
1981 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
1982 {
1983 public:
1984 								CopyBufferToBuffer			(Context& context, TestParams params);
1985 	virtual tcu::TestStatus		iterate						(void);
1986 private:
1987 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion, deUint32 mipLevel = 0u);
1988 	Move<VkBuffer>				m_source;
1989 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
1990 	Move<VkBuffer>				m_destination;
1991 	de::MovePtr<Allocation>		m_destinationBufferAlloc;
1992 };
1993 
CopyBufferToBuffer(Context & context,TestParams params)1994 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
1995 	: CopiesAndBlittingTestInstance	(context, params)
1996 {
1997 	const InstanceInterface&	vki					= context.getInstanceInterface();
1998 	const DeviceInterface&		vk					= context.getDeviceInterface();
1999 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
2000 	const VkDevice				vkDevice			= m_device;
2001 	Allocator&					memAlloc			= context.getDefaultAllocator();
2002 
2003 	// Create source buffer
2004 	{
2005 		const VkBufferCreateInfo	sourceBufferParams		=
2006 		{
2007 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2008 			DE_NULL,									// const void*			pNext;
2009 			0u,											// VkBufferCreateFlags	flags;
2010 			m_params.src.buffer.size,					// VkDeviceSize			size;
2011 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
2012 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2013 			0u,											// deUint32				queueFamilyIndexCount;
2014 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
2015 		};
2016 
2017 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
2018 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2019 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2020 	}
2021 
2022 	// Create destination buffer
2023 	{
2024 		const VkBufferCreateInfo	destinationBufferParams	=
2025 		{
2026 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2027 			DE_NULL,									// const void*			pNext;
2028 			0u,											// VkBufferCreateFlags	flags;
2029 			m_params.dst.buffer.size,					// VkDeviceSize			size;
2030 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
2031 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2032 			0u,											// deUint32				queueFamilyIndexCount;
2033 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
2034 		};
2035 
2036 		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
2037 		m_destinationBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2038 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2039 	}
2040 }
2041 
iterate(void)2042 tcu::TestStatus CopyBufferToBuffer::iterate (void)
2043 {
2044 	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
2045 	m_sourceTextureLevel		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
2046 	generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
2047 
2048 	const int dstLevelWidth		= (int)(m_params.dst.buffer.size/4);
2049 	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2050 	generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_BLACK);
2051 
2052 	generateExpectedResult();
2053 
2054 	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2055 	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2056 
2057 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
2058 	const VkDevice				vkDevice	= m_device;
2059 	const VkQueue				queue		= m_queue;
2060 
2061 	const VkBufferMemoryBarrier		srcBufferBarrier	=
2062 	{
2063 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2064 		DE_NULL,									// const void*		pNext;
2065 		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
2066 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
2067 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
2068 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
2069 		*m_source,									// VkBuffer			buffer;
2070 		0u,											// VkDeviceSize		offset;
2071 		m_params.src.buffer.size					// VkDeviceSize		size;
2072 	};
2073 
2074 	const VkBufferMemoryBarrier		dstBufferBarrier	=
2075 	{
2076 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2077 		DE_NULL,									// const void*		pNext;
2078 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
2079 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
2080 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
2081 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
2082 		*m_destination,								// VkBuffer			buffer;
2083 		0u,											// VkDeviceSize		offset;
2084 		m_params.dst.buffer.size					// VkDeviceSize		size;
2085 	};
2086 
2087 	std::vector<VkBufferCopy>		bufferCopies;
2088 	std::vector<VkBufferCopy2KHR>	bufferCopies2KHR;
2089 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2090 	{
2091 		if (m_params.extensionUse == EXTENSION_USE_NONE)
2092 		{
2093 			bufferCopies.push_back(m_params.regions[i].bufferCopy);
2094 		}
2095 		else
2096 		{
2097 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2098 			bufferCopies2KHR.push_back(convertvkBufferCopyTovkBufferCopy2KHR(m_params.regions[i].bufferCopy));
2099 		}
2100 	}
2101 
2102 	beginCommandBuffer(vk, *m_cmdBuffer);
2103 	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);
2104 
2105 	if (m_params.extensionUse == EXTENSION_USE_NONE)
2106 	{
2107 		vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
2108 	}
2109 #ifndef CTS_USES_VULKANSC
2110 	else
2111 	{
2112 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2113 		const VkCopyBufferInfo2KHR copyBufferInfo2KHR =
2114 		{
2115 			VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR,	// VkStructureType			sType;
2116 			DE_NULL,									// const void*				pNext;
2117 			m_source.get(),								// VkBuffer					srcBuffer;
2118 			m_destination.get(),						// VkBuffer					dstBuffer;
2119 			(deUint32)m_params.regions.size(),			// uint32_t					regionCount;
2120 			&bufferCopies2KHR[0]						// const VkBufferCopy2KHR*	pRegions;
2121 		};
2122 
2123 		vk.cmdCopyBuffer2(*m_cmdBuffer, &copyBufferInfo2KHR);
2124 	}
2125 #endif // CTS_USES_VULKANSC
2126 
2127 	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);
2128 	endCommandBuffer(vk, *m_cmdBuffer);
2129 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2130 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2131 
2132 	// Read buffer data
2133 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2134 	invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2135 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2136 
2137 	return checkTestResult(resultLevel->getAccess());
2138 }
2139 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2140 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2141 {
2142 	DE_UNREF(mipLevel);
2143 
2144 	deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
2145 			 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
2146 			 (size_t)region.bufferCopy.size);
2147 }
2148 
2149 class BufferToBufferTestCase : public vkt::TestCase
2150 {
2151 public:
BufferToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2152 							BufferToBufferTestCase	(tcu::TestContext&	testCtx,
2153 													 const std::string&	name,
2154 													 const std::string&	description,
2155 													 const TestParams	params)
2156 								: vkt::TestCase	(testCtx, name, description)
2157 								, m_params		(params)
2158 							{}
2159 
createInstance(Context & context) const2160 	virtual TestInstance*	createInstance			(Context& context) const
2161 							{
2162 								return new CopyBufferToBuffer(context, m_params);
2163 							}
2164 
checkSupport(Context & context) const2165 	virtual void			checkSupport(Context&	context) const
2166 	{
2167 							if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
2168 							{
2169 								if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
2170 								{
2171 									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2172 								}
2173 							}
2174 	}
2175 
2176 	private:
2177 	TestParams				m_params;
2178 };
2179 
2180 // Copy from image to buffer.
2181 
2182 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
2183 {
2184 public:
2185 								CopyImageToBuffer			(Context&	context,
2186 															 TestParams	testParams);
2187 	virtual tcu::TestStatus		iterate						(void);
2188 private:
2189 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2190 
2191 	tcu::TextureFormat			m_textureFormat;
2192 	VkDeviceSize				m_bufferSize;
2193 
2194 	Move<VkImage>				m_source;
2195 	de::MovePtr<Allocation>		m_sourceImageAlloc;
2196 	Move<VkBuffer>				m_destination;
2197 	de::MovePtr<Allocation>		m_destinationBufferAlloc;
2198 };
2199 
CopyImageToBuffer(Context & context,TestParams testParams)2200 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
2201 	: CopiesAndBlittingTestInstance(context, testParams)
2202 	, m_textureFormat(mapVkFormat(testParams.src.image.format))
2203 	, m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
2204 {
2205 	const InstanceInterface&	vki					= context.getInstanceInterface();
2206 	const DeviceInterface&		vk					= context.getDeviceInterface();
2207 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
2208 	const VkDevice				vkDevice			= m_device;
2209 	Allocator&					memAlloc			= context.getDefaultAllocator();
2210 
2211 	// Create source image
2212 	{
2213 		const VkImageCreateInfo		sourceImageParams		=
2214 		{
2215 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
2216 			DE_NULL,								// const void*			pNext;
2217 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
2218 			m_params.src.image.imageType,			// VkImageType			imageType;
2219 			m_params.src.image.format,				// VkFormat				format;
2220 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
2221 			1u,										// deUint32				mipLevels;
2222 			getArraySize(m_params.src.image),		// deUint32				arraySize;
2223 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
2224 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
2225 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2226 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
2227 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2228 			0u,										// deUint32				queueFamilyIndexCount;
2229 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
2230 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
2231 		};
2232 
2233 		m_source			= createImage(vk, vkDevice, &sourceImageParams);
2234 		m_sourceImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
2235 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
2236 	}
2237 
2238 	// Create destination buffer
2239 	{
2240 		const VkBufferCreateInfo	destinationBufferParams	=
2241 		{
2242 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2243 			DE_NULL,									// const void*			pNext;
2244 			0u,											// VkBufferCreateFlags	flags;
2245 			m_bufferSize,								// VkDeviceSize			size;
2246 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
2247 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2248 			0u,											// deUint32				queueFamilyIndexCount;
2249 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
2250 		};
2251 
2252 		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
2253 		m_destinationBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2254 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2255 	}
2256 }
2257 
iterate(void)2258 tcu::TestStatus CopyImageToBuffer::iterate (void)
2259 {
2260 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2261 																				m_params.src.image.extent.width,
2262 																				m_params.src.image.extent.height,
2263 																				m_params.src.image.extent.depth));
2264 	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
2265 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2266 	generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
2267 
2268 	generateExpectedResult();
2269 
2270 	uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
2271 	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2272 
2273 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
2274 	const VkDevice				vkDevice	= m_device;
2275 	const VkQueue				queue		= m_queue;
2276 
2277 	// Barriers for copying image to buffer
2278 	const VkImageMemoryBarrier		imageBarrier		=
2279 	{
2280 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2281 		DE_NULL,									// const void*				pNext;
2282 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2283 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
2284 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
2285 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
2286 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2287 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2288 		*m_source,									// VkImage					image;
2289 		{											// VkImageSubresourceRange	subresourceRange;
2290 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
2291 			0u,									// deUint32				baseMipLevel;
2292 			1u,									// deUint32				mipLevels;
2293 			0u,									// deUint32				baseArraySlice;
2294 			getArraySize(m_params.src.image)	// deUint32				arraySize;
2295 		}
2296 	};
2297 
2298 	const VkBufferMemoryBarrier		bufferBarrier		=
2299 	{
2300 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2301 		DE_NULL,									// const void*		pNext;
2302 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
2303 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
2304 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
2305 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
2306 		*m_destination,								// VkBuffer			buffer;
2307 		0u,											// VkDeviceSize		offset;
2308 		m_bufferSize								// VkDeviceSize		size;
2309 	};
2310 
2311 	// Copy from image to buffer
2312 	std::vector<VkBufferImageCopy>		bufferImageCopies;
2313 	std::vector<VkBufferImageCopy2KHR>	bufferImageCopies2KHR;
2314 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2315 	{
2316 		if (m_params.extensionUse == EXTENSION_USE_NONE)
2317 		{
2318 			bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2319 		}
2320 		else
2321 		{
2322 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2323 			bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2324 		}
2325 	}
2326 
2327 	beginCommandBuffer(vk, *m_cmdBuffer);
2328 	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);
2329 
2330 	if (m_params.extensionUse == EXTENSION_USE_NONE)
2331 	{
2332 		vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
2333 	}
2334 #ifndef CTS_USES_VULKANSC
2335 	else
2336 	{
2337 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2338 		const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR =
2339 		{
2340 			VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR,	// VkStructureType				sType;
2341 			DE_NULL,											// const void*					pNext;
2342 			m_source.get(),										// VkImage						srcImage;
2343 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,				// VkImageLayout				srcImageLayout;
2344 			m_destination.get(),								// VkBuffer						dstBuffer;
2345 			(deUint32)m_params.regions.size(),					// uint32_t						regionCount;
2346 			&bufferImageCopies2KHR[0]							// const VkBufferImageCopy2KHR*	pRegions;
2347 		};
2348 
2349 		vk.cmdCopyImageToBuffer2(*m_cmdBuffer, &copyImageToBufferInfo2KHR);
2350 	}
2351 #endif // CTS_USES_VULKANSC
2352 
2353 	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);
2354 	endCommandBuffer(vk, *m_cmdBuffer);
2355 
2356 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2357 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2358 
2359 	// Read buffer data
2360 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2361 	invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2362 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2363 
2364 	return checkTestResult(resultLevel->getAccess());
2365 }
2366 
2367 class CopyImageToBufferTestCase : public vkt::TestCase
2368 {
2369 public:
CopyImageToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2370 							CopyImageToBufferTestCase	(tcu::TestContext&		testCtx,
2371 														 const std::string&		name,
2372 														 const std::string&		description,
2373 														 const TestParams		params)
2374 								: vkt::TestCase	(testCtx, name, description)
2375 								, m_params		(params)
2376 							{}
2377 
createInstance(Context & context) const2378 	virtual TestInstance*	createInstance				(Context&				context) const
2379 							{
2380 								return new CopyImageToBuffer(context, m_params);
2381 							}
2382 
checkSupport(Context & context) const2383 	virtual void			checkSupport				(Context&				context) const
2384 							{
2385 								if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2386 									(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2387 								{
2388 									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2389 								}
2390 							}
2391 
2392 private:
2393 	TestParams				m_params;
2394 };
2395 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2396 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2397 {
2398 	DE_UNREF(mipLevel);
2399 
2400 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
2401 	if (!rowLength)
2402 		rowLength = region.bufferImageCopy.imageExtent.width;
2403 
2404 	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
2405 	if (!imageHeight)
2406 		imageHeight = region.bufferImageCopy.imageExtent.height;
2407 
2408 	const int			texelSize		= src.getFormat().getPixelSize();
2409 	const VkExtent3D	extent			= region.bufferImageCopy.imageExtent;
2410 	const VkOffset3D	srcOffset		= region.bufferImageCopy.imageOffset;
2411 	const int			texelOffset		= (int) region.bufferImageCopy.bufferOffset / texelSize;
2412 	const deUint32		baseArrayLayer	= region.bufferImageCopy.imageSubresource.baseArrayLayer;
2413 
2414 	for (deUint32 z = 0; z < extent.depth; z++)
2415 	{
2416 		for (deUint32 y = 0; y < extent.height; y++)
2417 		{
2418 			int									texelIndex		= texelOffset + (z * imageHeight + y) *	rowLength;
2419 			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z + baseArrayLayer,
2420 																					region.bufferImageCopy.imageExtent.width, 1, 1);
2421 			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2422 			tcu::copy(dstSubRegion, srcSubRegion);
2423 		}
2424 	}
2425 }
2426 
2427 // Copy from buffer to image.
2428 
2429 class CopyBufferToImage : public CopiesAndBlittingTestInstance
2430 {
2431 public:
2432 								CopyBufferToImage			(Context&	context,
2433 															 TestParams	testParams);
2434 	virtual tcu::TestStatus		iterate						(void);
2435 
2436 private:
2437 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2438 
2439 	tcu::TextureFormat			m_textureFormat;
2440 	VkDeviceSize				m_bufferSize;
2441 
2442 	Move<VkBuffer>				m_source;
2443 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
2444 	Move<VkImage>				m_destination;
2445 	de::MovePtr<Allocation>		m_destinationImageAlloc;
2446 };
2447 
CopyBufferToImage(Context & context,TestParams testParams)2448 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
2449 	: CopiesAndBlittingTestInstance(context, testParams)
2450 	, m_textureFormat(mapVkFormat(testParams.dst.image.format))
2451 	, m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
2452 {
2453 	const InstanceInterface&	vki					= context.getInstanceInterface();
2454 	const DeviceInterface&		vk					= context.getDeviceInterface();
2455 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
2456 	const VkDevice				vkDevice			= m_device;
2457 	Allocator&					memAlloc			= context.getDefaultAllocator();
2458 
2459 	// Create source buffer
2460 	{
2461 		const VkBufferCreateInfo	sourceBufferParams		=
2462 		{
2463 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2464 			DE_NULL,									// const void*			pNext;
2465 			0u,											// VkBufferCreateFlags	flags;
2466 			m_bufferSize,								// VkDeviceSize			size;
2467 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
2468 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2469 			0u,											// deUint32				queueFamilyIndexCount;
2470 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
2471 		};
2472 
2473 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
2474 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2475 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2476 	}
2477 
2478 	// Create destination image
2479 	{
2480 		const VkImageCreateInfo		destinationImageParams	=
2481 		{
2482 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
2483 			DE_NULL,								// const void*			pNext;
2484 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
2485 			m_params.dst.image.imageType,			// VkImageType			imageType;
2486 			m_params.dst.image.format,				// VkFormat				format;
2487 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
2488 			1u,										// deUint32				mipLevels;
2489 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
2490 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
2491 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
2492 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2493 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
2494 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2495 			0u,										// deUint32				queueFamilyIndexCount;
2496 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
2497 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
2498 		};
2499 
2500 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
2501 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
2502 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2503 	}
2504 }
2505 
iterate(void)2506 tcu::TestStatus CopyBufferToImage::iterate (void)
2507 {
2508 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2509 	generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2510 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2511 																					m_params.dst.image.extent.width,
2512 																					m_params.dst.image.extent.height,
2513 																					m_params.dst.image.extent.depth));
2514 
2515 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2516 
2517 	generateExpectedResult();
2518 
2519 	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2520 	uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2521 
2522 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
2523 	const VkDevice				vkDevice	= m_device;
2524 	const VkQueue				queue		= m_queue;
2525 
2526 	const VkImageMemoryBarrier	imageBarrier	=
2527 	{
2528 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2529 		DE_NULL,									// const void*				pNext;
2530 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2531 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
2532 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
2533 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
2534 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2535 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2536 		*m_destination,								// VkImage					image;
2537 		{											// VkImageSubresourceRange	subresourceRange;
2538 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
2539 			0u,								// deUint32				baseMipLevel;
2540 			1u,								// deUint32				mipLevels;
2541 			0u,								// deUint32				baseArraySlice;
2542 			getArraySize(m_params.dst.image)								// deUint32				arraySize;
2543 		}
2544 	};
2545 
2546 	// Copy from buffer to image
2547 	std::vector<VkBufferImageCopy>		bufferImageCopies;
2548 	std::vector<VkBufferImageCopy2KHR>	bufferImageCopies2KHR;
2549 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2550 	{
2551 		if (m_params.extensionUse == EXTENSION_USE_NONE)
2552 		{
2553 			bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2554 		}
2555 		else
2556 		{
2557 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2558 			bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2559 		}
2560 	}
2561 
2562 	beginCommandBuffer(vk, *m_cmdBuffer);
2563 	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);
2564 
2565 	if (m_params.extensionUse == EXTENSION_USE_NONE)
2566 	{
2567 		vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2568 	}
2569 #ifndef CTS_USES_VULKANSC
2570 	else
2571 	{
2572 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2573 		const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2574 		{
2575 			VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
2576 			DE_NULL,											// const void*					pNext;
2577 			m_source.get(),										// VkBuffer						srcBuffer;
2578 			m_destination.get(),								// VkImage						dstImage;
2579 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout				dstImageLayout;
2580 			(deUint32)m_params.regions.size(),					// uint32_t						regionCount;
2581 			bufferImageCopies2KHR.data()						// const VkBufferImageCopy2KHR*	pRegions;
2582 		};
2583 
2584 		vk.cmdCopyBufferToImage2(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2585 	}
2586 #endif // CTS_USES_VULKANSC
2587 
2588 	endCommandBuffer(vk, *m_cmdBuffer);
2589 
2590 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2591 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2592 
2593 	de::MovePtr<tcu::TextureLevel>	resultLevel	= readImage(*m_destination, m_params.dst.image);
2594 
2595 	return checkTestResult(resultLevel->getAccess());
2596 }
2597 
2598 class CopyBufferToImageTestCase : public vkt::TestCase
2599 {
2600 public:
CopyBufferToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2601 							CopyBufferToImageTestCase	(tcu::TestContext&		testCtx,
2602 														 const std::string&		name,
2603 														 const std::string&		description,
2604 														 const TestParams		params)
2605 								: vkt::TestCase	(testCtx, name, description)
2606 								, m_params		(params)
2607 							{}
2608 
~CopyBufferToImageTestCase(void)2609 	virtual					~CopyBufferToImageTestCase	(void) {}
2610 
createInstance(Context & context) const2611 	virtual TestInstance*	createInstance				(Context&				context) const
2612 							{
2613 								return new CopyBufferToImage(context, m_params);
2614 							}
2615 
checkSupport(Context & context) const2616 	virtual void			checkSupport				(Context&				context) const
2617 							{
2618 								if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2619 									(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2620 								{
2621 									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2622 								}
2623 							}
2624 
2625 
2626 private:
2627 	TestParams				m_params;
2628 };
2629 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2630 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2631 {
2632 	DE_UNREF(mipLevel);
2633 
2634 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
2635 	if (!rowLength)
2636 		rowLength = region.bufferImageCopy.imageExtent.width;
2637 
2638 	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
2639 	if (!imageHeight)
2640 		imageHeight = region.bufferImageCopy.imageExtent.height;
2641 
2642 	const int			texelSize		= dst.getFormat().getPixelSize();
2643 	const VkExtent3D	extent			= region.bufferImageCopy.imageExtent;
2644 	const VkOffset3D	dstOffset		= region.bufferImageCopy.imageOffset;
2645 	const int			texelOffset		= (int) region.bufferImageCopy.bufferOffset / texelSize;
2646 	const deUint32		baseArrayLayer	= region.bufferImageCopy.imageSubresource.baseArrayLayer;
2647 
2648 	for (deUint32 z = 0; z < extent.depth; z++)
2649 	{
2650 		for (deUint32 y = 0; y < extent.height; y++)
2651 		{
2652 			int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2653 			const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2654 			const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z + baseArrayLayer,
2655 																		  region.bufferImageCopy.imageExtent.width, 1, 1);
2656 			tcu::copy(dstSubRegion, srcSubRegion);
2657 		}
2658 	}
2659 }
2660 
2661 class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
2662 {
2663 public:
2664 								CopyBufferToDepthStencil	(Context& context,
2665 															 TestParams	testParams);
2666 	virtual tcu::TestStatus		iterate						(void);
2667 private:
2668 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2669 
2670 	tcu::TextureFormat			m_textureFormat;
2671 	VkDeviceSize				m_bufferSize;
2672 
2673 	Move<VkBuffer>				m_source;
2674 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
2675 	Move<VkImage>				m_destination;
2676 	de::MovePtr<Allocation>		m_destinationImageAlloc;
2677 };
2678 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2679 void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2680 {
2681 	DE_UNREF(mipLevel);
2682 
2683 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
2684 	if (!rowLength)
2685 		rowLength = region.bufferImageCopy.imageExtent.width;
2686 
2687 	deUint32			imageHeight = region.bufferImageCopy.bufferImageHeight;
2688 	if (!imageHeight)
2689 		imageHeight = region.bufferImageCopy.imageExtent.height;
2690 
2691 	const int			texelSize	= dst.getFormat().getPixelSize();
2692 	const VkExtent3D	extent		= region.bufferImageCopy.imageExtent;
2693 	const VkOffset3D	dstOffset	= region.bufferImageCopy.imageOffset;
2694 	const int			texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
2695 
2696 	for (deUint32 z = 0; z < extent.depth; z++)
2697 	{
2698 		for (deUint32 y = 0; y < extent.height; y++)
2699 		{
2700 			int									texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2701 			const tcu::ConstPixelBufferAccess	srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2702 			const tcu::PixelBufferAccess		dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
2703 				region.bufferImageCopy.imageExtent.width, 1, 1);
2704 
2705 			if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
2706 			{
2707 				tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH), DE_FALSE);
2708 			}
2709 			else
2710 			{
2711 				tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL), DE_FALSE);
2712 			}
2713 		}
2714 	}
2715 }
2716 
isSupportedDepthStencilFormat(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat format)2717 bool isSupportedDepthStencilFormat(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
2718 {
2719 	VkFormatProperties formatProps;
2720 	vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
2721 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
2722 }
2723 
CopyBufferToDepthStencil(Context & context,TestParams testParams)2724 CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context& context, TestParams testParams)
2725 	: CopiesAndBlittingTestInstance(context, testParams)
2726 	, m_textureFormat(mapVkFormat(testParams.dst.image.format))
2727 	, m_bufferSize(0)
2728 {
2729 	const InstanceInterface&	vki					= context.getInstanceInterface();
2730 	const DeviceInterface&		vk					= context.getDeviceInterface();
2731 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
2732 	const VkDevice				vkDevice			= m_device;
2733 	Allocator&					memAlloc			= context.getDefaultAllocator();
2734 	const bool					hasDepth			= tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
2735 	const bool					hasStencil			= tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
2736 
2737 	if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
2738 	{
2739 		TCU_THROW(NotSupportedError, "Image format not supported.");
2740 	}
2741 
2742 	if (hasDepth)
2743 	{
2744 		glw::GLuint texelSize = m_textureFormat.getPixelSize();
2745 		if (texelSize > sizeof(float))
2746 		{
2747 			// We must have D32F_S8 format, depth must be packed so we only need
2748 			// to allocate space for the D32F part. Stencil will be separate
2749 			texelSize = sizeof(float);
2750 		}
2751 		m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height) * static_cast<VkDeviceSize>(texelSize);
2752 	}
2753 	if (hasStencil)
2754 	{
2755 		// Stencil is always 8bits and packed.
2756 		m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
2757 	}
2758 
2759 	// Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
2760 	{
2761 		const VkBufferCreateInfo	sourceBufferParams		=
2762 		{
2763 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2764 			DE_NULL,									// const void*			pNext;
2765 			0u,											// VkBufferCreateFlags	flags;
2766 			m_bufferSize,								// VkDeviceSize			size;
2767 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
2768 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2769 			0u,											// deUint32				queueFamilyIndexCount;
2770 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
2771 		};
2772 
2773 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
2774 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2775 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2776 	}
2777 
2778 	// Create destination image
2779 	{
2780 		const VkImageCreateInfo		destinationImageParams	=
2781 		{
2782 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
2783 			DE_NULL,								// const void*			pNext;
2784 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
2785 			m_params.dst.image.imageType,			// VkImageType			imageType;
2786 			m_params.dst.image.format,				// VkFormat				format;
2787 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
2788 			1u,										// deUint32				mipLevels;
2789 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
2790 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
2791 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
2792 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2793 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
2794 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2795 			0u,										// deUint32				queueFamilyIndexCount;
2796 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
2797 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
2798 		};
2799 
2800 		m_destination				= createImage(vk, vkDevice, &destinationImageParams);
2801 		m_destinationImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
2802 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2803 	}
2804 }
2805 
iterate(void)2806 tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
2807 {
2808 	// Create source depth/stencil content. Treat as 1D texture to get different pattern
2809 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2810 	// Fill buffer with linear gradiant
2811 	generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2812 
2813 	// Create image layer for depth/stencil
2814 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2815 		m_params.dst.image.extent.width,
2816 		m_params.dst.image.extent.height,
2817 		m_params.dst.image.extent.depth));
2818 
2819 	// Fill image layer with 2D gradiant
2820 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2821 
2822 	// Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
2823 	// Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
2824 	// This emulates what the HW will be doing.
2825 	generateExpectedResult();
2826 
2827 	// Upload our source depth/stencil content to the source buffer
2828 	// This is the buffer that will be used by region commands
2829 	std::vector<VkBufferImageCopy>		bufferImageCopies;
2830 	std::vector<VkBufferImageCopy2KHR>	bufferImageCopies2KHR;
2831 	VkDeviceSize					bufferOffset	= 0;
2832 	const VkDevice					vkDevice		= m_device;
2833 	const DeviceInterface&			vk				= m_context.getDeviceInterface();
2834 	const VkQueue					queue			= m_queue;
2835 	char*							dstPtr			= reinterpret_cast<char*>(m_sourceBufferAlloc->getHostPtr());
2836 	bool							depthLoaded		= DE_FALSE;
2837 	bool							stencilLoaded	= DE_FALSE;
2838 	VkDeviceSize					depthOffset		= 0;
2839 	VkDeviceSize					stencilOffset	= 0;
2840 
2841 	// To be able to test ordering depth & stencil differently
2842 	// we take the given copy regions and use that as the desired order
2843 	// and copy the appropriate data into place and compute the appropriate
2844 	// data offsets to be used in the copy command.
2845 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2846 	{
2847 		tcu::ConstPixelBufferAccess bufferAccess	= m_sourceTextureLevel->getAccess();
2848 		deUint32					bufferSize		= bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
2849 		VkBufferImageCopy			copyData		= m_params.regions[i].bufferImageCopy;
2850 		char*						srcPtr;
2851 
2852 		if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
2853 		{
2854 			// Create level that is same component as depth buffer (e.g. D16, D24, D32F)
2855 			tcu::TextureLevel	depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2856 			bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
2857 			// Copy depth component only from source data. This gives us packed depth-only data.
2858 			tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
2859 			srcPtr = (char*)depthTexture.getAccess().getDataPtr();
2860 			// Copy packed depth-only data to output buffer
2861 			deMemcpy(dstPtr, srcPtr, bufferSize);
2862 			depthLoaded = DE_TRUE;
2863 			depthOffset = bufferOffset;
2864 			dstPtr += bufferSize;
2865 			bufferOffset += bufferSize;
2866 			copyData.bufferOffset += depthOffset;
2867 		}
2868 		else if (!stencilLoaded)
2869 		{
2870 			// Create level that is same component as stencil buffer (always 8-bits)
2871 			tcu::TextureLevel	stencilTexture(tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2872 			// Copy stencil component only from source data. This gives us packed stencil-only data.
2873 			tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
2874 			srcPtr = (char*)stencilTexture.getAccess().getDataPtr();
2875 			// Copy packed stencil-only data to output buffer
2876 			deMemcpy(dstPtr, srcPtr, bufferSize);
2877 			stencilLoaded = DE_TRUE;
2878 			stencilOffset = bufferOffset;
2879 			dstPtr += bufferSize;
2880 			bufferOffset += bufferSize;
2881 
2882 			// Reference image generation uses pixel offsets based on buffer offset.
2883 			// We need to adjust the offset now that the stencil data is not interleaved.
2884 			copyData.bufferOffset /= tcu::getPixelSize(m_textureFormat);
2885 
2886 			copyData.bufferOffset += stencilOffset;
2887 		}
2888 
2889 		if (m_params.extensionUse == EXTENSION_USE_NONE)
2890 		{
2891 			bufferImageCopies.push_back(copyData);
2892 		}
2893 		else
2894 		{
2895 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2896 			bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyData));
2897 		}
2898 	}
2899 
2900 	flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
2901 
2902 	// Upload the depth/stencil data from m_destinationTextureLevel to initialize
2903 	// depth and stencil to known values.
2904 	// Uses uploadImageAspect so makes its own buffers for depth and stencil
2905 	// aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
2906 	uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2907 
2908 	const VkImageMemoryBarrier	imageBarrier	=
2909 	{
2910 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2911 		DE_NULL,									// const void*				pNext;
2912 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2913 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
2914 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
2915 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
2916 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2917 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2918 		*m_destination,								// VkImage					image;
2919 		{											// VkImageSubresourceRange	subresourceRange;
2920 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
2921 			0u,								// deUint32				baseMipLevel;
2922 			1u,								// deUint32				mipLevels;
2923 			0u,								// deUint32				baseArraySlice;
2924 			1u								// deUint32				arraySize;
2925 		}
2926 	};
2927 
2928 	// Copy from buffer to depth/stencil image
2929 
2930 	beginCommandBuffer(vk, *m_cmdBuffer);
2931 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
2932 
2933 	if (m_params.extensionUse == EXTENSION_USE_NONE)
2934 	{
2935 		if (m_params.singleCommand)
2936 		{
2937 			// Issue a single copy command with regions defined by the test.
2938 			vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2939 		}
2940 		else
2941 		{
2942 			// Issue a a copy command per region defined by the test.
2943 			for (deUint32 i = 0; i < bufferImageCopies.size(); i++)
2944 			{
2945 				vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
2946 			}
2947 		}
2948 	}
2949 #ifndef CTS_USES_VULKANSC
2950 	else
2951 	{
2952 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2953 
2954 		if (m_params.singleCommand)
2955 		{
2956 			// Issue a single copy command with regions defined by the test.
2957 			const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2958 			{
2959 				VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
2960 				DE_NULL,											// const void*					pNext;
2961 				m_source.get(),										// VkBuffer						srcBuffer;
2962 				m_destination.get(),								// VkImage						dstImage;
2963 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout				dstImageLayout;
2964 				(deUint32)m_params.regions.size(),					// uint32_t						regionCount;
2965 				bufferImageCopies2KHR.data()						// const VkBufferImageCopy2KHR*	pRegions;
2966 			};
2967 			vk.cmdCopyBufferToImage2(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2968 		}
2969 		else
2970 		{
2971 			// Issue a a copy command per region defined by the test.
2972 			for (deUint32 i = 0; i < bufferImageCopies2KHR.size(); i++)
2973 			{
2974 				const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2975 				{
2976 					VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
2977 					DE_NULL,											// const void*					pNext;
2978 					m_source.get(),										// VkBuffer						srcBuffer;
2979 					m_destination.get(),								// VkImage						dstImage;
2980 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout				dstImageLayout;
2981 					1,													// uint32_t						regionCount;
2982 					&bufferImageCopies2KHR[i]							// const VkBufferImageCopy2KHR*	pRegions;
2983 				};
2984 				// Issue a single copy command with regions defined by the test.
2985 				vk.cmdCopyBufferToImage2(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2986 			}
2987 		}
2988 	}
2989 #endif // CTS_USES_VULKANSC
2990 
2991 	endCommandBuffer(vk, *m_cmdBuffer);
2992 
2993 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2994 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2995 
2996 	de::MovePtr<tcu::TextureLevel>	resultLevel = readImage(*m_destination, m_params.dst.image);
2997 
2998 	// For combined depth/stencil formats both aspects are checked even when the test only
2999 	// copies one. Clear such aspects here for both the result and the reference.
3000 	if (tcu::hasDepthComponent(m_textureFormat.order) && !depthLoaded)
3001 	{
3002 		tcu::clearDepth(m_expectedTextureLevel[0]->getAccess(), 0.0f);
3003 		tcu::clearDepth(resultLevel->getAccess(), 0.0f);
3004 	}
3005 	if (tcu::hasStencilComponent(m_textureFormat.order) && !stencilLoaded)
3006 	{
3007 		tcu::clearStencil(m_expectedTextureLevel[0]->getAccess(), 0);
3008 		tcu::clearStencil(resultLevel->getAccess(), 0);
3009 	}
3010 
3011 	return checkTestResult(resultLevel->getAccess());
3012 }
3013 
3014 class CopyBufferToDepthStencilTestCase : public vkt::TestCase
3015 {
3016 public:
CopyBufferToDepthStencilTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)3017 							CopyBufferToDepthStencilTestCase	(tcu::TestContext&		testCtx,
3018 																 const std::string&		name,
3019 																 const std::string&		description,
3020 																 const TestParams		params)
3021 								: vkt::TestCase(testCtx, name, description)
3022 								, m_params(params)
3023 							{}
3024 
~CopyBufferToDepthStencilTestCase(void)3025 	virtual					~CopyBufferToDepthStencilTestCase	(void) {}
3026 
createInstance(Context & context) const3027 	virtual TestInstance*	createInstance						(Context&				context) const
3028 							{
3029 								return new CopyBufferToDepthStencil(context, m_params);
3030 							}
3031 
checkSupport(Context & context) const3032 	virtual void			checkSupport						(Context&				context) const
3033 							{
3034 								if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
3035 									(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
3036 								{
3037 									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
3038 								}
3039 							}
3040 
3041 private:
3042 	TestParams				m_params;
3043 };
3044 
3045 // CompressedTextureForBlit is a helper class that stores compressed texture data.
3046 // Implementation is based on pipeline::TestTexture2D but it allocates only one level
3047 // and has special cases needed for blits to some formats.
3048 
3049 class CompressedTextureForBlit
3050 {
3051 public:
3052 	CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth);
3053 
3054 	tcu::PixelBufferAccess			getDecompressedAccess() const;
3055 	const tcu::CompressedTexture&	getCompressedTexture() const;
3056 
3057 protected:
3058 
3059 	tcu::CompressedTexture		m_compressedTexture;
3060 	de::ArrayBuffer<deUint8>	m_decompressedData;
3061 	tcu::PixelBufferAccess		m_decompressedAccess;
3062 };
3063 
CompressedTextureForBlit(const tcu::CompressedTexFormat & srcFormat,int width,int height,int depth)3064 CompressedTextureForBlit::CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth)
3065 	: m_compressedTexture(srcFormat, width, height, depth)
3066 {
3067 	de::Random			random					(123);
3068 
3069 	const int			compressedDataSize		(m_compressedTexture.getDataSize());
3070 	deUint8*			compressedData			((deUint8*)m_compressedTexture.getData());
3071 
3072 	tcu::TextureFormat	decompressedSrcFormat	(tcu::getUncompressedFormat(srcFormat));
3073 	const int			decompressedDataSize	(tcu::getPixelSize(decompressedSrcFormat) * width * height * depth);
3074 
3075 	// generate random data for compresed textre
3076 	if (tcu::isAstcFormat(srcFormat))
3077 	{
3078 		// comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
3079 		tcu::astc::generateRandomValidBlocks(compressedData, compressedDataSize / tcu::astc::BLOCK_SIZE_BYTES,
3080 											 srcFormat, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
3081 	}
3082 	else if ((srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK) ||
3083 			 (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
3084 	{
3085 		// special case - when we are blitting compressed floating-point image we can't have both big and small values
3086 		// in compressed image; to resolve this we are constructing source texture out of set of predefined compressed
3087 		// blocks that after decompression will have components in proper range
3088 
3089 		struct BC6HBlock
3090 		{
3091 			deUint32 data[4];
3092 		};
3093 		std::vector<BC6HBlock> validBlocks;
3094 
3095 		if (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)
3096 		{
3097 			// define set of few valid blocks that contain values from <0; 1> range
3098 			validBlocks =
3099 			{
3100 				{ { 1686671500, 3957317723, 3010132342, 2420137890 } },
3101 				{ { 3538027716, 298848033, 1925786021, 2022072301 } },
3102 				{ { 2614043466, 1636155440, 1023731774, 1894349986 } },
3103 				{ { 3433039318, 1294346072, 1587319645, 1738449906 } },
3104 				{ { 1386298160, 1639492154, 1273285776, 361562050 } },
3105 				{ { 1310110688, 526460754, 3630858047, 537617591 } },
3106 				{ { 3270356556, 2432993217, 2415924417, 1792488857 } },
3107 				{ { 1204947583, 353249154, 3739153467, 2068076443 } },
3108 			};
3109 		}
3110 		else
3111 		{
3112 			// define set of few valid blocks that contain values from <-1; 1> range
3113 			validBlocks =
3114 			{
3115 				{ { 2120678840, 3264271120, 4065378848, 3479743703 } },
3116 				{ { 1479697556, 3480872527, 3369382558, 568252340 } },
3117 				{ { 1301480032, 1607738094, 3055221704, 3663953681 } },
3118 				{ { 3531657186, 2285472028, 1429601507, 1969308187 } },
3119 				{ { 73229044, 650504649, 1120954865, 2626631975 } },
3120 				{ { 3872486086, 15326178, 2565171269, 2857722432 } },
3121 				{ { 1301480032, 1607738094, 3055221704, 3663953681 } },
3122 				{ { 73229044, 650504649, 1120954865, 2626631975 } },
3123 			};
3124 		}
3125 
3126 		deUint32*	compressedDataUint32	= reinterpret_cast<deUint32*>(compressedData);
3127 		const int	blocksCount				= compressedDataSize / static_cast<int>(sizeof(BC6HBlock));
3128 
3129 		// fill data using randomly selected valid blocks
3130 		for (int blockNdx = 0; blockNdx < blocksCount; blockNdx++)
3131 		{
3132 			deUint32 selectedBlock = random.getUint32() % static_cast<deUint32>(validBlocks.size());
3133 			deMemcpy(compressedDataUint32, validBlocks[selectedBlock].data, sizeof(BC6HBlock));
3134 			compressedDataUint32 += 4;
3135 		}
3136 	}
3137 	else if (srcFormat != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
3138 	{
3139 		// random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
3140 		for (int byteNdx = 0; byteNdx < compressedDataSize; byteNdx++)
3141 			compressedData[byteNdx] = 0xFF & random.getUint32();
3142 	}
3143 
3144 	// alocate space for decompressed texture
3145 	m_decompressedData.setStorage(decompressedDataSize);
3146 	m_decompressedAccess = tcu::PixelBufferAccess(decompressedSrcFormat, width, height, depth, m_decompressedData.getPtr());
3147 
3148 	// store decompressed data
3149 	m_compressedTexture.decompress(m_decompressedAccess, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
3150 }
3151 
getDecompressedAccess() const3152 tcu::PixelBufferAccess CompressedTextureForBlit::getDecompressedAccess() const
3153 {
3154 	return m_decompressedAccess;
3155 }
3156 
getCompressedTexture() const3157 const tcu::CompressedTexture& CompressedTextureForBlit::getCompressedTexture() const
3158 {
3159 	return m_compressedTexture;
3160 }
3161 
3162 // Copy from image to image with scaling.
3163 
3164 class BlittingImages : public CopiesAndBlittingTestInstance
3165 {
3166 public:
3167 											BlittingImages					(Context&	context,
3168 																			 TestParams params);
3169 	virtual tcu::TestStatus					iterate							(void);
3170 protected:
3171 	virtual tcu::TestStatus					checkTestResult							(tcu::ConstPixelBufferAccess	result);
3172 	virtual void							copyRegionToTextureLevel				(tcu::ConstPixelBufferAccess	src,
3173 																					 tcu::PixelBufferAccess			dst,
3174 																					 CopyRegion						region,
3175 																					 deUint32						mipLevel = 0u);
3176 	virtual void							generateExpectedResult					(void);
3177 	void									uploadCompressedImage					(const VkImage& image, const ImageParms& parms);
3178 private:
3179 	bool									checkNonNearestFilteredResult			(const tcu::ConstPixelBufferAccess&	result,
3180 																					 const tcu::ConstPixelBufferAccess&	clampedReference,
3181 																					 const tcu::ConstPixelBufferAccess&	unclampedReference,
3182 																					 const tcu::TextureFormat&			sourceFormat);
3183 	bool									checkNearestFilteredResult				(const tcu::ConstPixelBufferAccess&	result,
3184 																					 const tcu::ConstPixelBufferAccess&	source);
3185 
3186 	bool									checkCompressedNonNearestFilteredResult	(const tcu::ConstPixelBufferAccess&	result,
3187 																					 const tcu::ConstPixelBufferAccess&	clampedReference,
3188 																					 const tcu::ConstPixelBufferAccess&	unclampedReference,
3189 																					 const tcu::CompressedTexFormat		format);
3190 	bool									checkCompressedNearestFilteredResult	(const tcu::ConstPixelBufferAccess&	result,
3191 																					 const tcu::ConstPixelBufferAccess&	source,
3192 																					 const tcu::CompressedTexFormat		format);
3193 
3194 
3195 	Move<VkImage>						m_source;
3196 	de::MovePtr<Allocation>				m_sourceImageAlloc;
3197 	Move<VkImage>						m_destination;
3198 	de::MovePtr<Allocation>				m_destinationImageAlloc;
3199 
3200 	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel;
3201 
3202 	// helper used only when bliting from compressed formats
3203 	typedef de::SharedPtr<CompressedTextureForBlit> CompressedTextureForBlitSp;
3204 	CompressedTextureForBlitSp			m_sourceCompressedTexture;
3205 	CompressedTextureForBlitSp			m_destinationCompressedTexture;
3206 };
3207 
BlittingImages(Context & context,TestParams params)3208 BlittingImages::BlittingImages (Context& context, TestParams params)
3209 	: CopiesAndBlittingTestInstance(context, params)
3210 {
3211 	const InstanceInterface&	vki					= context.getInstanceInterface();
3212 	const DeviceInterface&		vk					= context.getDeviceInterface();
3213 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
3214 	const VkDevice				vkDevice			= m_device;
3215 	Allocator&					memAlloc			= context.getDefaultAllocator();
3216 
3217 	// Create source image
3218 	{
3219 		const VkImageCreateInfo		sourceImageParams		=
3220 		{
3221 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
3222 			DE_NULL,								// const void*			pNext;
3223 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
3224 			m_params.src.image.imageType,			// VkImageType			imageType;
3225 			m_params.src.image.format,				// VkFormat				format;
3226 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
3227 			1u,										// deUint32				mipLevels;
3228 			getArraySize(m_params.src.image),		// deUint32				arraySize;
3229 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
3230 			m_params.src.image.tiling,				// VkImageTiling		tiling;
3231 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3232 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
3233 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
3234 			0u,										// deUint32				queueFamilyIndexCount;
3235 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
3236 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
3237 		};
3238 
3239 		m_source = createImage(vk, vkDevice, &sourceImageParams);
3240 		m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
3241 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
3242 	}
3243 
3244 	// Create destination image
3245 	{
3246 		const VkImageCreateInfo		destinationImageParams	=
3247 		{
3248 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
3249 			DE_NULL,								// const void*			pNext;
3250 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
3251 			m_params.dst.image.imageType,			// VkImageType			imageType;
3252 			m_params.dst.image.format,				// VkFormat				format;
3253 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
3254 			1u,										// deUint32				mipLevels;
3255 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
3256 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
3257 			m_params.dst.image.tiling,				// VkImageTiling		tiling;
3258 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3259 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
3260 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
3261 			0u,										// deUint32				queueFamilyIndexCount;
3262 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
3263 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
3264 		};
3265 
3266 		m_destination = createImage(vk, vkDevice, &destinationImageParams);
3267 		m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
3268 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
3269 	}
3270 }
3271 
iterate(void)3272 tcu::TestStatus BlittingImages::iterate (void)
3273 {
3274 	const DeviceInterface&		vk				= m_context.getDeviceInterface();
3275 	const VkDevice				vkDevice		= m_device;
3276 	const VkQueue				queue			= m_queue;
3277 
3278 	const ImageParms&			srcImageParams	= m_params.src.image;
3279 	const int					srcWidth		= static_cast<int>(srcImageParams.extent.width);
3280 	const int					srcHeight		= static_cast<int>(srcImageParams.extent.height);
3281 	const int					srcDepth		= static_cast<int>(srcImageParams.extent.depth);
3282 	const ImageParms&			dstImageParams	= m_params.dst.image;
3283 	const int					dstWidth		= static_cast<int>(dstImageParams.extent.width);
3284 	const int					dstHeight		= static_cast<int>(dstImageParams.extent.height);
3285 	const int					dstDepth		= static_cast<int>(dstImageParams.extent.depth);
3286 
3287 	std::vector<VkImageBlit>		regions;
3288 	std::vector<VkImageBlit2KHR>	regions2KHR;
3289 
3290 	// setup blit regions - they are also needed for reference generation
3291 	if (m_params.extensionUse == EXTENSION_USE_NONE)
3292 	{
3293 		regions.reserve(m_params.regions.size());
3294 		for (const auto& r : m_params.regions)
3295 			regions.push_back(r.imageBlit);
3296 	}
3297 	else
3298 	{
3299 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3300 		regions2KHR.reserve(m_params.regions.size());
3301 		for (const auto& r : m_params.regions)
3302 			regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(r.imageBlit));
3303 	}
3304 
3305 	// generate source image
3306 	if (isCompressedFormat(srcImageParams.format))
3307 	{
3308 		// for compressed images srcImageParams.fillMode is not used - we are using random data
3309 		tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(srcImageParams.format);
3310 		m_sourceCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth));
3311 		uploadCompressedImage(m_source.get(), srcImageParams);
3312 	}
3313 	else
3314 	{
3315 		// non-compressed image is filled with selected fillMode
3316 		const tcu::TextureFormat srcTcuFormat = mapVkFormat(srcImageParams.format);
3317 		m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, srcWidth, srcHeight, srcDepth));
3318 		generateBuffer(m_sourceTextureLevel->getAccess(), srcWidth, srcHeight, srcDepth, srcImageParams.fillMode);
3319 		uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), srcImageParams);
3320 	}
3321 
3322 	// generate destination image
3323 	if (isCompressedFormat(dstImageParams.format))
3324 	{
3325 		// compressed images are filled with random data
3326 		tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(dstImageParams.format);
3327 		m_destinationCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth));
3328 		uploadCompressedImage(m_destination.get(), dstImageParams);
3329 	}
3330 	else
3331 	{
3332 		// non-compressed image is filled with white background
3333 		const tcu::TextureFormat dstTcuFormat = mapVkFormat(dstImageParams.format);
3334 		m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, dstWidth, dstHeight, dstDepth));
3335 		generateBuffer(m_destinationTextureLevel->getAccess(), dstWidth, dstHeight, dstDepth, dstImageParams.fillMode);
3336 		uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), dstImageParams);
3337 	}
3338 
3339 	generateExpectedResult();
3340 
3341 	// Barriers for copying images to buffer
3342 	const VkImageMemoryBarrier imageBarriers[]
3343 	{
3344 		{
3345 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3346 			DE_NULL,									// const void*				pNext;
3347 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
3348 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
3349 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
3350 			srcImageParams.operationLayout,				// VkImageLayout			newLayout;
3351 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3352 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3353 			m_source.get(),								// VkImage					image;
3354 			{											// VkImageSubresourceRange	subresourceRange;
3355 				getAspectFlags(srcImageParams.format),	//   VkImageAspectFlags		aspectMask;
3356 				0u,										//   deUint32				baseMipLevel;
3357 				1u,										//   deUint32				mipLevels;
3358 				0u,										//   deUint32				baseArraySlice;
3359 				1u										//   deUint32				arraySize;
3360 			}
3361 		},
3362 		{
3363 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3364 			DE_NULL,									// const void*				pNext;
3365 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
3366 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
3367 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
3368 			dstImageParams.operationLayout,				// VkImageLayout			newLayout;
3369 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3370 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3371 			m_destination.get(),						// VkImage					image;
3372 			{											// VkImageSubresourceRange	subresourceRange;
3373 				getAspectFlags(dstImageParams.format),	//   VkImageAspectFlags		aspectMask;
3374 				0u,										//   deUint32				baseMipLevel;
3375 				1u,										//   deUint32				mipLevels;
3376 				0u,										//   deUint32				baseArraySlice;
3377 				1u										//   deUint32				arraySize;
3378 			}
3379 		}
3380 	};
3381 
3382 	beginCommandBuffer(vk, *m_cmdBuffer);
3383 	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);
3384 
3385 	if (m_params.extensionUse == EXTENSION_USE_NONE)
3386 	{
3387 		vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), srcImageParams.operationLayout, m_destination.get(), dstImageParams.operationLayout, (deUint32)m_params.regions.size(), &regions[0], m_params.filter);
3388 	}
3389 #ifndef CTS_USES_VULKANSC
3390 	else
3391 	{
3392 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3393 		const VkBlitImageInfo2KHR blitImageInfo2KHR
3394 		{
3395 			VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
3396 			DE_NULL,									// const void*					pNext;
3397 			m_source.get(),								// VkImage						srcImage;
3398 			srcImageParams.operationLayout,				// VkImageLayout				srcImageLayout;
3399 			m_destination.get(),						// VkImage						dstImage;
3400 			dstImageParams.operationLayout,				// VkImageLayout				dstImageLayout;
3401 			(deUint32)m_params.regions.size(),			// uint32_t						regionCount;
3402 			&regions2KHR[0],							// const VkImageBlit2KHR*		pRegions;
3403 			m_params.filter,							// VkFilter						filter;
3404 		};
3405 		vk.cmdBlitImage2(*m_cmdBuffer, &blitImageInfo2KHR);
3406 	}
3407 #endif // CTS_USES_VULKANSC
3408 
3409 	endCommandBuffer(vk, *m_cmdBuffer);
3410 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
3411 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
3412 
3413 	de::MovePtr<tcu::TextureLevel>	resultLevel		= readImage(*m_destination, dstImageParams);
3414 	tcu::PixelBufferAccess			resultAccess	= resultLevel->getAccess();
3415 
3416 	// if blit was done to a compressed format we need to decompress it to be able to verify it
3417 	if (m_destinationCompressedTexture)
3418 	{
3419 		deUint8* const					compressedDataSrc	(static_cast<deUint8*>(resultAccess.getDataPtr()));
3420 		const tcu::CompressedTexFormat	dstCompressedFormat (mapVkCompressedFormat(dstImageParams.format));
3421 		tcu::TextureLevel				decompressedLevel	(getUncompressedFormat(dstCompressedFormat), dstWidth, dstHeight, dstDepth);
3422 		tcu::PixelBufferAccess			decompressedAccess	(decompressedLevel.getAccess());
3423 
3424 		tcu::decompress(decompressedAccess, dstCompressedFormat, compressedDataSrc);
3425 
3426 		return checkTestResult(decompressedAccess);
3427 	}
3428 
3429 	return checkTestResult(resultAccess);
3430 }
3431 
calculateFloatConversionError(int srcBits)3432 static float calculateFloatConversionError (int srcBits)
3433 {
3434 	if (srcBits > 0)
3435 	{
3436 		const int	clampedBits	= de::clamp<int>(srcBits, 0, 32);
3437 		const float	srcMaxValue	= de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
3438 		const float	error		= 1.0f / srcMaxValue;
3439 
3440 		return de::clamp<float>(error, 0.0f, 1.0f);
3441 	}
3442 	else
3443 		return 1.0f;
3444 }
3445 
getFormatThreshold(const tcu::TextureFormat & format)3446 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
3447 {
3448 	tcu::Vec4 threshold(0.01f);
3449 
3450 	switch (format.type)
3451 	{
3452 	case tcu::TextureFormat::HALF_FLOAT:
3453 		threshold = tcu::Vec4(0.005f);
3454 		break;
3455 
3456 	case tcu::TextureFormat::FLOAT:
3457 	case tcu::TextureFormat::FLOAT64:
3458 		threshold = tcu::Vec4(0.001f);
3459 		break;
3460 
3461 	case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
3462 		threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
3463 		break;
3464 
3465 	case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
3466 		threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
3467 		break;
3468 
3469 	case tcu::TextureFormat::UNORM_INT_1010102_REV:
3470 		threshold = tcu::Vec4(0.002f, 0.002f, 0.002f, 0.3f);
3471 		break;
3472 
3473 	case tcu:: TextureFormat::UNORM_INT8:
3474 		threshold = tcu::Vec4(0.008f, 0.008f, 0.008f, 0.008f);
3475 		break;
3476 
3477 	default:
3478 		const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
3479 		threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
3480 				      calculateFloatConversionError(bits.y()),
3481 				      calculateFloatConversionError(bits.z()),
3482 				      calculateFloatConversionError(bits.w()));
3483 	}
3484 
3485 	// Return value matching the channel order specified by the format
3486 	if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
3487 		return threshold.swizzle(2, 1, 0, 3);
3488 	else
3489 		return threshold;
3490 }
3491 
getCompressedFormatThreshold(const tcu::CompressedTexFormat & format)3492 tcu::Vec4 getCompressedFormatThreshold(const tcu::CompressedTexFormat& format)
3493 {
3494 	bool		isSigned(false);
3495 	tcu::IVec4	bitDepth(0);
3496 
3497 	switch (format)
3498 	{
3499 	case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
3500 		bitDepth = { 7, 0, 0, 0 };
3501 		isSigned = true;
3502 		break;
3503 
3504 	case tcu::COMPRESSEDTEXFORMAT_EAC_R11:
3505 		bitDepth = { 8, 0, 0, 0 };
3506 		break;
3507 
3508 	case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
3509 		bitDepth = { 7, 7, 0, 0 };
3510 		isSigned = true;
3511 		break;
3512 
3513 	case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:
3514 		bitDepth = { 8, 8, 0, 0 };
3515 		break;
3516 
3517 	case tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8:
3518 	case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:
3519 	case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:
3520 		bitDepth = { 8, 8, 8, 0 };
3521 		break;
3522 
3523 	case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
3524 	case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
3525 		bitDepth = { 8, 8, 8, 1 };
3526 		break;
3527 
3528 	case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
3529 	case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
3530 	case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
3531 	case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
3532 	case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
3533 	case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
3534 	case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
3535 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
3536 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
3537 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
3538 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
3539 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
3540 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
3541 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
3542 	case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
3543 	case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
3544 	case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
3545 	case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
3546 	case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
3547 	case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
3548 	case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
3549 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
3550 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
3551 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
3552 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
3553 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
3554 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
3555 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
3556 	case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
3557 	case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
3558 		bitDepth = { 8, 8, 8, 8 };
3559 		break;
3560 
3561 	case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
3562 	case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
3563 	case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
3564 	case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
3565 	case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
3566 	case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
3567 		bitDepth = { 5, 6, 5, 0 };
3568 		break;
3569 
3570 	case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
3571 	case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
3572 	case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
3573 	case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
3574 		bitDepth = { 5, 5, 5, 1 };
3575 		break;
3576 
3577 	case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
3578 		bitDepth = { 7, 0, 0, 0 };
3579 		isSigned = true;
3580 		break;
3581 
3582 	case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
3583 		bitDepth = { 8, 0, 0, 0 };
3584 		break;
3585 
3586 	case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
3587 		bitDepth = { 7, 7, 0, 0 };
3588 		isSigned = true;
3589 		break;
3590 
3591 	case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
3592 		bitDepth = { 8, 8, 0, 0 };
3593 		break;
3594 
3595 	case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
3596 		return tcu::Vec4(0.01f);
3597 	case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
3598 		return tcu::Vec4(0.005f);
3599 
3600 	default:
3601 		DE_ASSERT(DE_FALSE);
3602 	}
3603 
3604 	const float	range = isSigned ? 1.0f - (-1.0f)
3605 								 : 1.0f - 0.0f;
3606 	tcu::Vec4 v;
3607 	for (int i = 0; i < 4; ++i)
3608 	{
3609 		if (bitDepth[i] == 0)
3610 			v[i] = 1.0f;
3611 		else
3612 			v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3613 	}
3614 	return v;
3615 }
3616 
checkNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedExpected,const tcu::ConstPixelBufferAccess & unclampedExpected,const tcu::TextureFormat & srcFormat)3617 bool BlittingImages::checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
3618 													const tcu::ConstPixelBufferAccess&	clampedExpected,
3619 													const tcu::ConstPixelBufferAccess&	unclampedExpected,
3620 													const tcu::TextureFormat&			srcFormat)
3621 {
3622 	tcu::TestLog&					log				(m_context.getTestContext().getLog());
3623 	const tcu::TextureFormat		dstFormat		= result.getFormat();
3624 	const tcu::TextureChannelClass	dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3625 	const tcu::TextureChannelClass	srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3626 	bool							isOk			= false;
3627 
3628 	log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3629 
3630 	// if either of srcImage or dstImage stores values as a signed/unsigned integer,
3631 	// the other must also store values a signed/unsigned integer
3632 	// e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3633 	// despite the fact that both formats are sampled as floats
3634 	bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3635 							  dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3636 	bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3637 							  srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3638 	if (dstImageIsIntClass != srcImageIsIntClass)
3639 	{
3640 		log << tcu::TestLog::EndSection;
3641 		return false;
3642 	}
3643 
3644 	if (isFloatFormat(dstFormat))
3645 	{
3646 		const bool		srcIsSRGB	= tcu::isSRGB(srcFormat);
3647 		const tcu::Vec4	srcMaxDiff	= getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
3648 		const tcu::Vec4	dstMaxDiff	= getFormatThreshold(dstFormat);
3649 		const tcu::Vec4	threshold	= ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
3650 
3651 		isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3652 		log << tcu::TestLog::EndSection;
3653 
3654 		if (!isOk)
3655 		{
3656 			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3657 			isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3658 			log << tcu::TestLog::EndSection;
3659 		}
3660 	}
3661 	else
3662 	{
3663 		tcu::UVec4	threshold;
3664 		// Calculate threshold depending on channel width of destination format.
3665 		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
3666 		const tcu::IVec4	srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
3667 		for (deUint32 i = 0; i < 4; ++i)
3668 		{
3669 			DE_ASSERT(dstBitDepth[i] < std::numeric_limits<uint64_t>::digits);
3670 			DE_ASSERT(srcBitDepth[i] < std::numeric_limits<uint64_t>::digits);
3671 			deUint64 threshold64 = 1 + de::max( ( ( UINT64_C(1) << dstBitDepth[i] ) - 1 ) / de::clamp((UINT64_C(1) << srcBitDepth[i]) - 1, UINT64_C(1), UINT64_C(256)), UINT64_C(1));
3672 			DE_ASSERT(threshold64 <= std::numeric_limits<uint32_t>::max());
3673 			threshold[i] = static_cast<deUint32>(threshold64);
3674 		}
3675 
3676 		isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3677 		log << tcu::TestLog::EndSection;
3678 
3679 		if (!isOk)
3680 		{
3681 			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3682 			isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3683 			log << tcu::TestLog::EndSection;
3684 		}
3685 	}
3686 
3687 	return isOk;
3688 }
3689 
checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedReference,const tcu::ConstPixelBufferAccess & unclampedReference,const tcu::CompressedTexFormat format)3690 bool BlittingImages::checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess&	result,
3691 															 const tcu::ConstPixelBufferAccess&	clampedReference,
3692 															 const tcu::ConstPixelBufferAccess&	unclampedReference,
3693 															 const tcu::CompressedTexFormat		format)
3694 {
3695 	tcu::TestLog&				log				= m_context.getTestContext().getLog();
3696 	const tcu::TextureFormat	dstFormat		= result.getFormat();
3697 
3698 	// there are rare cases wher one or few pixels have slightly bigger error
3699 	// in one of channels this accepted error allows those casses to pass
3700 	const tcu::Vec4				acceptedError	(0.06f);
3701 
3702 	const tcu::Vec4				srcMaxDiff		= getCompressedFormatThreshold(format);
3703 	const tcu::Vec4				dstMaxDiff		= m_destinationCompressedTexture ?
3704 													getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
3705 													getFormatThreshold(dstFormat);
3706 	const tcu::Vec4				threshold		= (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f) + acceptedError;
3707 
3708 	bool						filteredResultVerification(false);
3709 	tcu::Vec4					filteredResultMinValue(-6e6);
3710 	tcu::Vec4					filteredResultMaxValue(6e6);
3711 	tcu::TextureLevel			filteredResult;
3712 	tcu::TextureLevel			filteredClampedReference;
3713 	tcu::TextureLevel			filteredUnclampedReference;
3714 
3715 	if (((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
3716 		(format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)))
3717 	{
3718 		if ((dstFormat.type == tcu::TextureFormat::FLOAT) ||
3719 			(dstFormat.type == tcu::TextureFormat::HALF_FLOAT))
3720 		{
3721 			// for compressed formats we are using random data and for bc6h formats
3722 			// this will give us also large color values; when we are bliting to
3723 			// a format that accepts large values we can end up with large diferences
3724 			// betwean filtered result and reference; to avoid that we need to remove
3725 			// values that are to big from verification
3726 			filteredResultVerification	= true;
3727 			filteredResultMinValue		= tcu::Vec4(-10.0f);
3728 			filteredResultMaxValue		= tcu::Vec4( 10.0f);
3729 		}
3730 		else if (dstFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
3731 		{
3732 			// we need to clamp some formats to <0;1> range as it has
3733 			// small precision for big numbers compared to reference
3734 			filteredResultVerification	= true;
3735 			filteredResultMinValue		= tcu::Vec4(0.0f);
3736 			filteredResultMaxValue		= tcu::Vec4(1.0f);
3737 		}
3738 		// else don't use filtered verification
3739 	}
3740 
3741 	if (filteredResultVerification)
3742 	{
3743 		filteredResult.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3744 		tcu::PixelBufferAccess filteredResultAcccess(filteredResult.getAccess());
3745 
3746 		filteredClampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3747 		tcu::PixelBufferAccess filteredClampedAcccess(filteredClampedReference.getAccess());
3748 
3749 		filteredUnclampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3750 		tcu::PixelBufferAccess filteredUnclampedResultAcccess(filteredUnclampedReference.getAccess());
3751 
3752 		for (deInt32 z = 0; z < result.getDepth(); z++)
3753 		for (deInt32 y = 0; y < result.getHeight(); y++)
3754 		for (deInt32 x = 0; x < result.getWidth(); x++)
3755 		{
3756 			tcu::Vec4 resultTexel				= result.getPixel(x, y, z);
3757 			tcu::Vec4 clampedReferenceTexel		= clampedReference.getPixel(x, y, z);
3758 			tcu::Vec4 unclampedReferenceTexel	= unclampedReference.getPixel(x, y, z);
3759 
3760 			resultTexel				= tcu::clamp(resultTexel, filteredResultMinValue, filteredResultMaxValue);
3761 			clampedReferenceTexel	= tcu::clamp(clampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3762 			unclampedReferenceTexel	= tcu::clamp(unclampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3763 
3764 			filteredResultAcccess.setPixel(resultTexel, x, y, z);
3765 			filteredClampedAcccess.setPixel(clampedReferenceTexel, x, y, z);
3766 			filteredUnclampedResultAcccess.setPixel(unclampedReferenceTexel, x, y, z);
3767 		}
3768 	}
3769 
3770 	const tcu::ConstPixelBufferAccess clampedRef	= filteredResultVerification ? filteredClampedReference.getAccess() : clampedReference;
3771 	const tcu::ConstPixelBufferAccess res			= filteredResultVerification ? filteredResult.getAccess() : result;
3772 
3773 	log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3774 	bool isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3775 	log << tcu::TestLog::EndSection;
3776 
3777 	if (!isOk)
3778 	{
3779 		const tcu::ConstPixelBufferAccess unclampedRef = filteredResultVerification ? filteredUnclampedReference.getAccess() : unclampedReference;
3780 
3781 		log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3782 		isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3783 		log << tcu::TestLog::EndSection;
3784 	}
3785 
3786 	return isOk;
3787 }
3788 
3789 //! Utility to encapsulate coordinate computation and loops.
3790 struct CompareEachPixelInEachRegion
3791 {
~CompareEachPixelInEachRegionvkt::api::__anon4493ca420111::CompareEachPixelInEachRegion3792 	virtual		 ~CompareEachPixelInEachRegion  (void) {}
3793 	virtual bool compare								(const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const = 0;
3794 
forEachvkt::api::__anon4493ca420111::CompareEachPixelInEachRegion3795 	bool forEach (const void*							pUserData,
3796 				  const std::vector<CopyRegion>&		regions,
3797 				  const int								sourceWidth,
3798 				  const int								sourceHeight,
3799 				  const int								sourceDepth,
3800 				  const tcu::PixelBufferAccess&			errorMask) const
3801 	{
3802 		bool compareOk = true;
3803 
3804 		for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
3805 		{
3806 			const VkImageBlit& blit = regionIter->imageBlit;
3807 
3808 			const int	xStart	= deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3809 			const int	yStart	= deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3810 			const int	zStart	= deMin32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3811 			const int	xEnd	= deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3812 			const int	yEnd	= deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3813 			const int	zEnd	= deMax32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3814 			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);
3815 			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);
3816 			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);
3817 			const float srcInvW	= 1.0f / static_cast<float>(sourceWidth);
3818 			const float srcInvH	= 1.0f / static_cast<float>(sourceHeight);
3819 			const float srcInvD	= 1.0f / static_cast<float>(sourceDepth);
3820 
3821 			for (int z = zStart; z < zEnd; z++)
3822 			for (int y = yStart; y < yEnd; y++)
3823 			for (int x = xStart; x < xEnd; x++)
3824 			{
3825 				const tcu::Vec3 srcNormCoord
3826 				(
3827 					(xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
3828 					(yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH,
3829 					(zScale * (static_cast<float>(z - blit.dstOffsets[0].z) + 0.5f) + static_cast<float>(blit.srcOffsets[0].z)) * srcInvD
3830 				);
3831 
3832 				if (!compare(pUserData, x, y, z, srcNormCoord))
3833 				{
3834 					errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
3835 					compareOk = false;
3836 				}
3837 			}
3838 		}
3839 		return compareOk;
3840 	}
3841 };
3842 
getFloatOrFixedPointFormatThreshold(const tcu::TextureFormat & format)3843 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
3844 {
3845 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
3846 	const tcu::IVec4				bitDepth		= tcu::getTextureFormatBitDepth(format);
3847 
3848 	if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
3849 	{
3850 		return getFormatThreshold(format);
3851 	}
3852 	else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
3853 			 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
3854 	{
3855 		const bool	isSigned	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
3856 		const float	range		= isSigned ? 1.0f - (-1.0f)
3857 										   : 1.0f -   0.0f;
3858 
3859 		tcu::Vec4 v;
3860 		for (int i = 0; i < 4; ++i)
3861 		{
3862 			if (bitDepth[i] == 0)
3863 				v[i] = 1.0f;
3864 			else
3865 				v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3866 		}
3867 		return v;
3868 	}
3869 	else
3870 	{
3871 		DE_ASSERT(0);
3872 		return tcu::Vec4();
3873 	}
3874 }
3875 
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)3876 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess&	source,
3877 							  const tcu::ConstPixelBufferAccess&	result,
3878 							  const tcu::Vec4&						sourceThreshold,
3879 							  const tcu::Vec4&						resultThreshold,
3880 							  const tcu::PixelBufferAccess&			errorMask,
3881 							  const std::vector<CopyRegion>&		regions)
3882 {
3883 	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,
3884 										 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
3885 	const tcu::IVec4		dstBitDepth (tcu::getTextureFormatBitDepth(result.getFormat()));
3886 	tcu::LookupPrecision	precision;
3887 
3888 	precision.colorMask		 = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
3889 	precision.colorThreshold = tcu::max(sourceThreshold, resultThreshold);
3890 
3891 	const struct Capture
3892 	{
3893 		const tcu::ConstPixelBufferAccess&	source;
3894 		const tcu::ConstPixelBufferAccess&	result;
3895 		const tcu::Sampler&					sampler;
3896 		const tcu::LookupPrecision&			precision;
3897 		const bool							isSRGB;
3898 	} capture =
3899 	{
3900 		source, result, sampler, precision, tcu::isSRGB(result.getFormat())
3901 	};
3902 
3903 	const struct Loop : CompareEachPixelInEachRegion
3904 	{
3905 		Loop (void) {}
3906 
3907 		bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3908 		{
3909 			const Capture&					c					= *static_cast<const Capture*>(pUserData);
3910 			const tcu::TexLookupScaleMode	lookupScaleDontCare	= tcu::TEX_LOOKUP_SCALE_MINIFY;
3911 			tcu::Vec4						dstColor			= c.result.getPixel(x, y, z);
3912 
3913 			// TexLookupVerifier performs a conversion to linear space, so we have to as well
3914 			if (c.isSRGB)
3915 				dstColor = tcu::sRGBToLinear(dstColor);
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 
intNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask,const std::vector<CopyRegion> & regions)3924 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess&	source,
3925 							const tcu::ConstPixelBufferAccess&	result,
3926 							const tcu::PixelBufferAccess&		errorMask,
3927 							const std::vector<CopyRegion>&		regions)
3928 {
3929 	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,
3930 										 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
3931 	tcu::IntLookupPrecision	precision;
3932 
3933 	{
3934 		const tcu::IVec4	srcBitDepth	= tcu::getTextureFormatBitDepth(source.getFormat());
3935 		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(result.getFormat());
3936 
3937 		for (deUint32 i = 0; i < 4; ++i) {
3938 			precision.colorThreshold[i]	= de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
3939 			precision.colorMask[i]		= dstBitDepth[i] != 0;
3940 		}
3941 	}
3942 
3943 	// Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
3944 	// does the conversion on the fly without wasting memory, but this approach is more straightforward.
3945 	tcu::TextureLevel				convertedSourceTexture	(result.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
3946 	const tcu::PixelBufferAccess	convertedSource			= convertedSourceTexture.getAccess();
3947 
3948 	for (int z = 0; z < source.getDepth();	++z)
3949 	for (int y = 0; y < source.getHeight(); ++y)
3950 	for (int x = 0; x < source.getWidth();  ++x)
3951 		convertedSource.setPixel(source.getPixelInt(x, y, z), x, y, z);	// will be clamped to max. representable value
3952 
3953 	const struct Capture
3954 	{
3955 		const tcu::ConstPixelBufferAccess&	source;
3956 		const tcu::ConstPixelBufferAccess&	result;
3957 		const tcu::Sampler&					sampler;
3958 		const tcu::IntLookupPrecision&		precision;
3959 	} capture =
3960 	{
3961 		convertedSource, result, sampler, precision
3962 	};
3963 
3964 	const struct Loop : CompareEachPixelInEachRegion
3965 	{
3966 		Loop (void) {}
3967 
3968 		bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3969 		{
3970 			const Capture&					c					= *static_cast<const Capture*>(pUserData);
3971 			const tcu::TexLookupScaleMode	lookupScaleDontCare	= tcu::TEX_LOOKUP_SCALE_MINIFY;
3972 			const tcu::IVec4				dstColor			= c.result.getPixelInt(x, y, z);
3973 
3974 			return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3975 		}
3976 	} loop;
3977 
3978 	return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3979 }
3980 
checkNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source)3981 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
3982 												 const tcu::ConstPixelBufferAccess& source)
3983 {
3984 	tcu::TestLog&					log				(m_context.getTestContext().getLog());
3985 	const tcu::TextureFormat		dstFormat		= result.getFormat();
3986 	const tcu::TextureFormat		srcFormat		= source.getFormat();
3987 	const tcu::TextureChannelClass	dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3988 	const tcu::TextureChannelClass	srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3989 
3990 	tcu::TextureLevel		errorMaskStorage	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
3991 	tcu::PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
3992 	tcu::Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
3993 	tcu::Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
3994 	bool					ok					= false;
3995 
3996 	tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3997 
3998 	// if either of srcImage or dstImage stores values as a signed/unsigned integer,
3999 	// the other must also store values a signed/unsigned integer
4000 	// e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
4001 	// despite the fact that both formats are sampled as floats
4002 	bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
4003 							  dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4004 	bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
4005 							  srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4006 	if (dstImageIsIntClass != srcImageIsIntClass)
4007 		return false;
4008 
4009 	if (dstImageIsIntClass)
4010 	{
4011 		ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
4012 	}
4013 	else
4014 	{
4015 		const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
4016 		const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
4017 		ok = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions);
4018 	}
4019 
4020 	if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4021 		tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4022 
4023 	if (!ok)
4024 	{
4025 		log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4026 			<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
4027 			<< tcu::TestLog::Image("ErrorMask",	"Error mask", errorMask)
4028 			<< tcu::TestLog::EndImageSet;
4029 	}
4030 	else
4031 	{
4032 		log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4033 			<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
4034 			<< tcu::TestLog::EndImageSet;
4035 	}
4036 
4037 	return ok;
4038 }
4039 
checkCompressedNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source,const tcu::CompressedTexFormat format)4040 bool BlittingImages::checkCompressedNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
4041 														   const tcu::ConstPixelBufferAccess&	source,
4042 														   const tcu::CompressedTexFormat		format)
4043 {
4044 	tcu::TestLog&				log					(m_context.getTestContext().getLog());
4045 	tcu::TextureFormat			errorMaskFormat		(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8);
4046 	tcu::TextureLevel			errorMaskStorage	(errorMaskFormat, result.getWidth(), result.getHeight(), result.getDepth());
4047 	tcu::PixelBufferAccess		errorMask			(errorMaskStorage.getAccess());
4048 	tcu::Vec4					pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
4049 	tcu::Vec4					pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
4050 	const tcu::TextureFormat&	resultFormat		(result.getFormat());
4051 	VkFormat					nativeResultFormat	(mapTextureFormat(resultFormat));
4052 
4053 	// there are rare cases wher one or few pixels have slightly bigger error
4054 	// in one of channels this accepted error allows those casses to pass
4055 	const tcu::Vec4				acceptedError		(0.04f);
4056 	const tcu::Vec4				srcMaxDiff			(acceptedError + getCompressedFormatThreshold(format));
4057 	const tcu::Vec4				dstMaxDiff			(acceptedError + (m_destinationCompressedTexture ?
4058 														getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
4059 														getFloatOrFixedPointFormatThreshold(resultFormat)));
4060 
4061 	tcu::TextureLevel			clampedSourceLevel;
4062 	bool						clampSource			(false);
4063 	tcu::Vec4					clampSourceMinValue	(-1.0f);
4064 	tcu::Vec4					clampSourceMaxValue	(1.0f);
4065 	tcu::TextureLevel			clampedResultLevel;
4066 	bool						clampResult			(false);
4067 
4068 	tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
4069 
4070 	if (resultFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4071 		tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4072 
4073 	log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4074 		<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias);
4075 
4076 	// for compressed formats source buffer access is not actual compressed format
4077 	// but equivalent uncompressed format that is some cases needs additional
4078 	// modifications so that sampling it will produce valid reference
4079 	if ((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
4080 		(format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK))
4081 	{
4082 		if (resultFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
4083 		{
4084 			// for compressed formats we are using random data and for some formats it
4085 			// can be outside of <-1;1> range - for cases where result is not a float
4086 			// format we need to clamp source to <-1;1> range as this will be done on
4087 			// the device but not in software sampler in framework
4088 			clampSource = true;
4089 			// for this format we also need to clamp the result as precision of
4090 			// this format is smaller then precision of calculations in framework;
4091 			// the biger color valus are the bigger errors can be
4092 			clampResult = true;
4093 
4094 			if (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)
4095 				clampSourceMinValue = tcu::Vec4(0.0f);
4096 		}
4097 		else if ((resultFormat.type != tcu::TextureFormat::FLOAT) &&
4098 				 (resultFormat.type != tcu::TextureFormat::HALF_FLOAT))
4099 		{
4100 			// clamp source for all non float formats
4101 			clampSource = true;
4102 		}
4103 	}
4104 
4105 	if (isUnormFormat(nativeResultFormat) || isUfloatFormat(nativeResultFormat))
4106 	{
4107 		// when tested compressed format is signed but the result format
4108 		// is unsigned we need to clamp source to <0; x> so that proper
4109 		// reference is calculated
4110 		if ((format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11) ||
4111 			(format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11) ||
4112 			(format == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK) ||
4113 			(format == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK) ||
4114 			(format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
4115 		{
4116 			clampSource			= true;
4117 			clampSourceMinValue	= tcu::Vec4(0.0f);
4118 		}
4119 	}
4120 
4121 	if (clampSource || clampResult)
4122 	{
4123 		if (clampSource)
4124 		{
4125 			clampedSourceLevel.setStorage(source.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
4126 			tcu::PixelBufferAccess clampedSourceAcccess(clampedSourceLevel.getAccess());
4127 
4128 			for (deInt32 z = 0; z < source.getDepth() ; z++)
4129 			for (deInt32 y = 0; y < source.getHeight() ; y++)
4130 			for (deInt32 x = 0; x < source.getWidth() ; x++)
4131 			{
4132 				tcu::Vec4 texel = source.getPixel(x, y, z);
4133 				texel = tcu::clamp(texel, tcu::Vec4(clampSourceMinValue), tcu::Vec4(clampSourceMaxValue));
4134 				clampedSourceAcccess.setPixel(texel, x, y, z);
4135 			}
4136 		}
4137 
4138 		if (clampResult)
4139 		{
4140 			clampedResultLevel.setStorage(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
4141 			tcu::PixelBufferAccess clampedResultAcccess(clampedResultLevel.getAccess());
4142 
4143 			for (deInt32 z = 0; z < result.getDepth() ; z++)
4144 			for (deInt32 y = 0; y < result.getHeight() ; y++)
4145 			for (deInt32 x = 0; x < result.getWidth() ; x++)
4146 			{
4147 				tcu::Vec4 texel = result.getPixel(x, y, z);
4148 				texel = tcu::clamp(texel, tcu::Vec4(-1.0f), tcu::Vec4(1.0f));
4149 				clampedResultAcccess.setPixel(texel, x, y, z);
4150 			}
4151 		}
4152 	}
4153 
4154 	const tcu::ConstPixelBufferAccess src = clampSource ? clampedSourceLevel.getAccess() : source;
4155 	const tcu::ConstPixelBufferAccess res = clampResult ? clampedResultLevel.getAccess() : result;
4156 
4157 	if (floatNearestBlitCompare(src, res, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions))
4158 	{
4159 		log << tcu::TestLog::EndImageSet;
4160 		return true;
4161 	}
4162 
4163 	log << tcu::TestLog::Image("ErrorMask",	"Error mask", errorMask)
4164 		<< tcu::TestLog::EndImageSet;
4165 	return false;
4166 }
4167 
checkTestResult(tcu::ConstPixelBufferAccess result)4168 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
4169 {
4170 	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
4171 	const std::string failMessage("Result image is incorrect");
4172 
4173 	if (m_params.filter != VK_FILTER_NEAREST)
4174 	{
4175 		if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4176 		{
4177 			if (tcu::hasDepthComponent(result.getFormat().order))
4178 			{
4179 				const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
4180 				const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
4181 				const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4182 				const tcu::ConstPixelBufferAccess		unclampedExpected	= tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4183 				const tcu::TextureFormat				sourceFormat		= tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4184 
4185 				if (!checkNonNearestFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
4186 					return tcu::TestStatus::fail(failMessage);
4187 			}
4188 
4189 			if (tcu::hasStencilComponent(result.getFormat().order))
4190 			{
4191 				const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
4192 				const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
4193 				const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4194 				const tcu::ConstPixelBufferAccess		unclampedExpected	= tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4195 				const tcu::TextureFormat				sourceFormat		= tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4196 
4197 				if (!checkNonNearestFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
4198 					return tcu::TestStatus::fail(failMessage);
4199 			}
4200 		}
4201 		else if (m_sourceCompressedTexture)
4202 		{
4203 			const tcu::CompressedTexture& compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4204 			if (!checkCompressedNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), compressedLevel.getFormat()))
4205 				return tcu::TestStatus::fail(failMessage);
4206 		}
4207 		else
4208 		{
4209 			const tcu::TextureFormat sourceFormat = mapVkFormat(m_params.src.image.format);
4210 			if (!checkNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
4211 				return tcu::TestStatus::fail(failMessage);
4212 		}
4213 	}
4214 	else // NEAREST filtering
4215 	{
4216 		if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4217 		{
4218 			if (tcu::hasDepthComponent(result.getFormat().order))
4219 			{
4220 				const tcu::Sampler::DepthStencilMode	mode			= tcu::Sampler::MODE_DEPTH;
4221 				const tcu::ConstPixelBufferAccess		depthResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
4222 				const tcu::ConstPixelBufferAccess		depthSource		= tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4223 
4224 				if (!checkNearestFilteredResult(depthResult, depthSource))
4225 					return tcu::TestStatus::fail(failMessage);
4226 			}
4227 
4228 			if (tcu::hasStencilComponent(result.getFormat().order))
4229 			{
4230 				const tcu::Sampler::DepthStencilMode	mode			= tcu::Sampler::MODE_STENCIL;
4231 				const tcu::ConstPixelBufferAccess		stencilResult	= tcu::getEffectiveDepthStencilAccess(result, mode);
4232 				const tcu::ConstPixelBufferAccess		stencilSource	= tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4233 
4234 				if (!checkNearestFilteredResult(stencilResult, stencilSource))
4235 					return tcu::TestStatus::fail(failMessage);
4236 			}
4237 		}
4238 		else if (m_sourceCompressedTexture)
4239 		{
4240 			const tcu::CompressedTexture& compressedLevel	= m_sourceCompressedTexture->getCompressedTexture();
4241 			const tcu::PixelBufferAccess& decompressedLevel	= m_sourceCompressedTexture->getDecompressedAccess();
4242 
4243 			if (!checkCompressedNearestFilteredResult(result, decompressedLevel, compressedLevel.getFormat()))
4244 				return tcu::TestStatus::fail(failMessage);
4245 		}
4246 		else if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
4247 			return tcu::TestStatus::fail(failMessage);
4248 	}
4249 
4250 	return tcu::TestStatus::pass("Pass");
4251 }
4252 
linearToSRGBIfNeeded(const tcu::TextureFormat & format,const tcu::Vec4 & color)4253 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
4254 {
4255 	return isSRGB(format) ? linearToSRGB(color) : color;
4256 }
4257 
scaleFromWholeSrcBuffer(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const VkOffset3D regionOffset,const VkOffset3D regionExtent,tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode=0u)4258 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = 0u)
4259 {
4260 	DE_ASSERT(filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4261 
4262 	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4263 					filter, filter, 0.0f, false, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
4264 
4265 	float sX = (float)regionExtent.x / (float)dst.getWidth();
4266 	float sY = (float)regionExtent.y / (float)dst.getHeight();
4267 	float sZ = (float)regionExtent.z / (float)dst.getDepth();
4268 
4269 	for (int z = 0; z < dst.getDepth(); z++)
4270 	for (int y = 0; y < dst.getHeight(); y++)
4271 	for (int x = 0; x < dst.getWidth(); x++)
4272 	{
4273 		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;
4274 		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;
4275 		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;
4276 		if (dst.getDepth() > 1)
4277 			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, srcX, srcY, srcZ)), x, y, z);
4278 		else
4279 			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x, y);
4280 	}
4281 }
4282 
blit(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode)4283 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
4284 {
4285 	DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4286 
4287 	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4288 			filter, filter, 0.0f, false, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
4289 
4290 	const float sX = (float)src.getWidth() / (float)dst.getWidth();
4291 	const float sY = (float)src.getHeight() / (float)dst.getHeight();
4292 	const float sZ = (float)src.getDepth() / (float)dst.getDepth();
4293 
4294 	const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
4295 	const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
4296 	const int zOffset = (mirrorMode & MIRROR_MODE_Z) ? dst.getDepth() - 1 : 0;
4297 
4298 	const int xScale = (mirrorMode & MIRROR_MODE_X) ? -1 : 1;
4299 	const int yScale = (mirrorMode & MIRROR_MODE_Y) ? -1 : 1;
4300 	const int zScale = (mirrorMode & MIRROR_MODE_Z) ? -1 : 1;
4301 
4302 	for (int z = 0; z < dst.getDepth(); ++z)
4303 	for (int y = 0; y < dst.getHeight(); ++y)
4304 	for (int x = 0; x < dst.getWidth(); ++x)
4305 	{
4306 		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);
4307 	}
4308 }
4309 
flipCoordinates(CopyRegion & region,const MirrorMode mirrorMode)4310 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
4311 {
4312 	const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
4313 	const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
4314 	const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
4315 	const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
4316 
4317 	if (mirrorMode != 0u)
4318 	{
4319 		//sourceRegion
4320 		region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
4321 		region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
4322 		region.imageBlit.srcOffsets[0].z = std::min(srcOffset0.z, srcOffset1.z);
4323 
4324 		region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
4325 		region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
4326 		region.imageBlit.srcOffsets[1].z = std::max(srcOffset0.z, srcOffset1.z);
4327 
4328 		//destinationRegion
4329 		region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
4330 		region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
4331 		region.imageBlit.dstOffsets[0].z = std::min(dstOffset0.z, dstOffset1.z);
4332 
4333 		region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
4334 		region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
4335 		region.imageBlit.dstOffsets[1].z = std::max(dstOffset0.z, dstOffset1.z);
4336 	}
4337 }
4338 
4339 // Mirror X, Y and Z as required by the offset values in the 3 axes.
getMirrorMode(const VkOffset3D from,const VkOffset3D to)4340 MirrorMode getMirrorMode(const VkOffset3D from, const VkOffset3D to)
4341 {
4342 	MirrorMode mode = 0u;
4343 
4344 	if (from.x > to.x)
4345 		mode |= MIRROR_MODE_X;
4346 
4347 	if (from.y > to.y)
4348 		mode |= MIRROR_MODE_Y;
4349 
4350 	if (from.z > to.z)
4351 		mode |= MIRROR_MODE_Z;
4352 
4353 	return mode;
4354 }
4355 
4356 // 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)4357 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
4358 {
4359 	static const MirrorModeBits kBits[] = { MIRROR_MODE_X, MIRROR_MODE_Y, MIRROR_MODE_Z };
4360 
4361 	const MirrorMode source		 = getMirrorMode(s1, s2);
4362 	const MirrorMode destination = getMirrorMode(d1, d2);
4363 
4364 	MirrorMode mode = 0u;
4365 
4366 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(kBits); ++i)
4367 	{
4368 		const MirrorModeBits bit = kBits[i];
4369 		if ((source & bit) != (destination & bit))
4370 			mode |= bit;
4371 	}
4372 
4373 	return mode;
4374 }
4375 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)4376 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
4377 {
4378 	DE_UNREF(mipLevel);
4379 
4380 	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
4381 												region.imageBlit.srcOffsets[1],
4382 												region.imageBlit.dstOffsets[0],
4383 												region.imageBlit.dstOffsets[1]);
4384 
4385 	flipCoordinates(region, mirrorMode);
4386 
4387 	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
4388 	const VkOffset3D					srcExtent		=
4389 	{
4390 		region.imageBlit.srcOffsets[1].x - srcOffset.x,
4391 		region.imageBlit.srcOffsets[1].y - srcOffset.y,
4392 		region.imageBlit.srcOffsets[1].z - srcOffset.z,
4393 	};
4394 	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
4395 	const VkOffset3D					dstExtent		=
4396 	{
4397 		region.imageBlit.dstOffsets[1].x - dstOffset.x,
4398 		region.imageBlit.dstOffsets[1].y - dstOffset.y,
4399 		region.imageBlit.dstOffsets[1].z - dstOffset.z,
4400 	};
4401 
4402 	tcu::Sampler::FilterMode		filter;
4403 	switch (m_params.filter)
4404 	{
4405 		case VK_FILTER_LINEAR:		filter = tcu::Sampler::LINEAR; break;
4406 		case VK_FILTER_CUBIC_EXT:	filter = tcu::Sampler::CUBIC;  break;
4407 		case VK_FILTER_NEAREST:
4408 		default:					filter = tcu::Sampler::NEAREST;  break;
4409 	}
4410 
4411 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
4412 	{
4413 		DE_ASSERT(src.getFormat() == dst.getFormat());
4414 
4415 		// Scale depth.
4416 		if (tcu::hasDepthComponent(src.getFormat().order))
4417 		{
4418 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_DEPTH);
4419 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
4420 			tcu::scale(dstSubRegion, srcSubRegion, filter);
4421 
4422 			if (filter != tcu::Sampler::NEAREST)
4423 			{
4424 				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
4425 				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);
4426 				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
4427 			}
4428 		}
4429 
4430 		// Scale stencil.
4431 		if (tcu::hasStencilComponent(src.getFormat().order))
4432 		{
4433 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_STENCIL);
4434 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
4435 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4436 
4437 			if (filter != tcu::Sampler::NEAREST)
4438 			{
4439 				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
4440 				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);
4441 				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
4442 			}
4443 		}
4444 	}
4445 	else
4446 	{
4447 		const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z);
4448 		const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4449 		blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4450 
4451 		if (filter != tcu::Sampler::NEAREST)
4452 		{
4453 			const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4454 			scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
4455 		}
4456 	}
4457 }
4458 
generateExpectedResult(void)4459 void BlittingImages::generateExpectedResult (void)
4460 {
4461 	const tcu::ConstPixelBufferAccess src = m_sourceCompressedTexture ? m_sourceCompressedTexture->getDecompressedAccess() : m_sourceTextureLevel->getAccess();
4462 	const tcu::ConstPixelBufferAccess dst = m_destinationCompressedTexture ? m_destinationCompressedTexture->getDecompressedAccess() : m_destinationTextureLevel->getAccess();
4463 
4464 	m_expectedTextureLevel[0]		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4465 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
4466 
4467 	if (m_params.filter != VK_FILTER_NEAREST)
4468 	{
4469 		m_unclampedExpectedTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4470 		tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
4471 	}
4472 
4473 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
4474 	{
4475 		CopyRegion region = m_params.regions[i];
4476 		copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
4477 	}
4478 }
4479 
uploadCompressedImage(const VkImage & image,const ImageParms & parms)4480 void BlittingImages::uploadCompressedImage (const VkImage& image, const ImageParms& parms)
4481 {
4482 	DE_ASSERT(m_sourceCompressedTexture);
4483 
4484 	const InstanceInterface&		vki					= m_context.getInstanceInterface();
4485 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
4486 	const VkPhysicalDevice			vkPhysDevice		= m_context.getPhysicalDevice();
4487 	const VkDevice					vkDevice			= m_device;
4488 	const VkQueue					queue				= m_queue;
4489 	Allocator&						memAlloc			= *m_allocator;
4490 	Move<VkBuffer>					buffer;
4491 	const deUint32					bufferSize			= m_sourceCompressedTexture->getCompressedTexture().getDataSize();
4492 	de::MovePtr<Allocation>			bufferAlloc;
4493 	const deUint32					arraySize			= getArraySize(parms);
4494 	const VkExtent3D				imageExtent
4495 	{
4496 		parms.extent.width,
4497 		(parms.imageType != VK_IMAGE_TYPE_1D) ? parms.extent.height : 1u,
4498 		(parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
4499 	};
4500 
4501 	// Create source buffer
4502 	{
4503 		const VkBufferCreateInfo bufferParams
4504 		{
4505 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
4506 			DE_NULL,									// const void*			pNext;
4507 			0u,											// VkBufferCreateFlags	flags;
4508 			bufferSize,									// VkDeviceSize			size;
4509 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
4510 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
4511 			0u,											// deUint32				queueFamilyIndexCount;
4512 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
4513 		};
4514 
4515 		buffer		= createBuffer(vk, vkDevice, &bufferParams);
4516 		bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
4517 		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
4518 	}
4519 
4520 	// Barriers for copying buffer to image
4521 	const VkBufferMemoryBarrier preBufferBarrier
4522 	{
4523 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
4524 		DE_NULL,										// const void*		pNext;
4525 		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
4526 		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
4527 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
4528 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
4529 		*buffer,										// VkBuffer			buffer;
4530 		0u,												// VkDeviceSize		offset;
4531 		bufferSize										// VkDeviceSize		size;
4532 	};
4533 
4534 	const VkImageMemoryBarrier preImageBarrier
4535 	{
4536 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
4537 		DE_NULL,										// const void*				pNext;
4538 		0u,												// VkAccessFlags			srcAccessMask;
4539 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
4540 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
4541 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
4542 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
4543 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
4544 		image,											// VkImage					image;
4545 		{												// VkImageSubresourceRange	subresourceRange;
4546 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspect;
4547 			0u,							// deUint32				baseMipLevel;
4548 			1u,							// deUint32				mipLevels;
4549 			0u,							// deUint32				baseArraySlice;
4550 			arraySize,					// deUint32				arraySize;
4551 		}
4552 	};
4553 
4554 	const VkImageMemoryBarrier postImageBarrier
4555 	{
4556 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
4557 		DE_NULL,										// const void*				pNext;
4558 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
4559 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
4560 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
4561 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
4562 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
4563 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
4564 		image,											// VkImage					image;
4565 		{												// VkImageSubresourceRange	subresourceRange;
4566 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspect;
4567 			0u,								// deUint32				baseMipLevel;
4568 			1u,								// deUint32				mipLevels;
4569 			0u,								// deUint32				baseArraySlice;
4570 			arraySize,						// deUint32				arraySize;
4571 		}
4572 	};
4573 
4574 	const VkExtent3D copyExtent
4575 	{
4576 		imageExtent.width,
4577 		imageExtent.height,
4578 		imageExtent.depth
4579 	};
4580 
4581 	VkBufferImageCopy copyRegion
4582 	{
4583 		0u,												// VkDeviceSize				bufferOffset;
4584 		copyExtent.width,								// deUint32					bufferRowLength;
4585 		copyExtent.height,								// deUint32					bufferImageHeight;
4586 		{
4587 			VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspect;
4588 			0u,												// deUint32				mipLevel;
4589 			0u,												// deUint32				baseArrayLayer;
4590 			arraySize,										// deUint32				layerCount;
4591 		},												// VkImageSubresourceLayers	imageSubresource;
4592 		{ 0, 0, 0 },									// VkOffset3D				imageOffset;
4593 		copyExtent										// VkExtent3D				imageExtent;
4594 	};
4595 
4596 	// Write buffer data
4597 	deMemcpy(bufferAlloc->getHostPtr(), m_sourceCompressedTexture->getCompressedTexture().getData(), bufferSize);
4598 	flushAlloc(vk, vkDevice, *bufferAlloc);
4599 
4600 	// Copy buffer to image
4601 	beginCommandBuffer(vk, *m_cmdBuffer);
4602 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
4603 						  1, &preBufferBarrier, 1, &preImageBarrier);
4604 	vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
4605 	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);
4606 	endCommandBuffer(vk, *m_cmdBuffer);
4607 
4608 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4609 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
4610 }
4611 
4612 
4613 class BlitImageTestCase : public vkt::TestCase
4614 {
4615 public:
BlitImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)4616 							BlitImageTestCase		(tcu::TestContext&				testCtx,
4617 													 const std::string&				name,
4618 													 const std::string&				description,
4619 													 const TestParams				params)
4620 								: vkt::TestCase	(testCtx, name, description)
4621 								, m_params		(params)
4622 	{}
4623 
createInstance(Context & context) const4624 	virtual TestInstance*	createInstance			(Context&						context) const
4625 	{
4626 		return new BlittingImages(context, m_params);
4627 	}
4628 
checkSupport(Context & context) const4629 	virtual void			checkSupport			(Context&						context) const
4630 	{
4631 		VkImageFormatProperties properties;
4632 		if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4633 																					m_params.src.image.format,
4634 																					m_params.src.image.imageType,
4635 																					m_params.src.image.tiling,
4636 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
4637 																					0,
4638 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4639 		{
4640 			TCU_THROW(NotSupportedError, "Source format not supported");
4641 		}
4642 		if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4643 																					m_params.dst.image.format,
4644 																					m_params.dst.image.imageType,
4645 																					m_params.dst.image.tiling,
4646 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4647 																					0,
4648 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4649 		{
4650 			TCU_THROW(NotSupportedError, "Destination format not supported");
4651 		}
4652 
4653 		VkFormatProperties srcFormatProperties;
4654 		context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
4655 		VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ? srcFormatProperties.linearTilingFeatures : srcFormatProperties.optimalTilingFeatures;
4656 		if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
4657 		{
4658 			TCU_THROW(NotSupportedError, "Format feature blit source not supported");
4659 		}
4660 
4661 		VkFormatProperties dstFormatProperties;
4662 		context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
4663 		VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ? dstFormatProperties.linearTilingFeatures : dstFormatProperties.optimalTilingFeatures;
4664 		if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
4665 		{
4666 			TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
4667 		}
4668 
4669 		if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
4670 		{
4671 			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
4672 		}
4673 
4674 		if (m_params.filter == VK_FILTER_CUBIC_EXT)
4675 		{
4676 			context.requireDeviceFunctionality("VK_EXT_filter_cubic");
4677 
4678 			if (!(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
4679 			{
4680 				TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
4681 			}
4682 		}
4683 
4684 		if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
4685 		{
4686 			if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
4687 			{
4688 				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
4689 			}
4690 		}
4691 	}
4692 
4693 private:
4694 	TestParams				m_params;
4695 };
4696 
4697 class BlittingMipmaps : public CopiesAndBlittingTestInstance
4698 {
4699 public:
4700 										BlittingMipmaps					(Context&   context,
4701 																		 TestParams params);
4702 	virtual tcu::TestStatus				iterate							(void);
4703 protected:
4704 	virtual tcu::TestStatus				checkTestResult					(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
4705 	virtual void						copyRegionToTextureLevel		(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
4706 	virtual void						generateExpectedResult			(void);
4707 private:
4708 	bool								checkNonNearestFilteredResult	(void);
4709 	bool								checkNearestFilteredResult		(void);
4710 
4711 	Move<VkImage>						m_source;
4712 	de::MovePtr<Allocation>				m_sourceImageAlloc;
4713 	Move<VkImage>						m_destination;
4714 	de::MovePtr<Allocation>				m_destinationImageAlloc;
4715 
4716 	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel[16];
4717 };
4718 
BlittingMipmaps(Context & context,TestParams params)4719 BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params)
4720 	: CopiesAndBlittingTestInstance (context, params)
4721 {
4722 	const InstanceInterface&	vki					= context.getInstanceInterface();
4723 	const DeviceInterface&		vk					= context.getDeviceInterface();
4724 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
4725 	const VkDevice				vkDevice			= m_device;
4726 	Allocator&					memAlloc			= context.getDefaultAllocator();
4727 
4728 	// Create source image
4729 	{
4730 		const VkImageCreateInfo		sourceImageParams		=
4731 		{
4732 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
4733 			DE_NULL,								// const void*			pNext;
4734 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
4735 			m_params.src.image.imageType,			// VkImageType			imageType;
4736 			m_params.src.image.format,				// VkFormat				format;
4737 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
4738 			1u,										// deUint32				mipLevels;
4739 			getArraySize(m_params.src.image),		// deUint32				arraySize;
4740 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
4741 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
4742 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4743 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
4744 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
4745 			0u,										// deUint32				queueFamilyIndexCount;
4746 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
4747 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
4748 		};
4749 
4750 		m_source = createImage(vk, vkDevice, &sourceImageParams);
4751 		m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
4752 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
4753 	}
4754 
4755 	// Create destination image
4756 	{
4757 		const VkImageCreateInfo		destinationImageParams  =
4758 		{
4759 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
4760 			DE_NULL,								// const void*			pNext;
4761 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
4762 			m_params.dst.image.imageType,			// VkImageType			imageType;
4763 			m_params.dst.image.format,				// VkFormat				format;
4764 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
4765 			m_params.mipLevels,						// deUint32				mipLevels;
4766 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
4767 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
4768 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
4769 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4770 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
4771 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
4772 			0u,										// deUint32				queueFamilyIndexCount;
4773 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
4774 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
4775 		};
4776 
4777 		m_destination = createImage(vk, vkDevice, &destinationImageParams);
4778 		m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
4779 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
4780 	}
4781 }
4782 
iterate(void)4783 tcu::TestStatus BlittingMipmaps::iterate (void)
4784 {
4785 	const tcu::TextureFormat	srcTcuFormat		= mapVkFormat(m_params.src.image.format);
4786 	const tcu::TextureFormat	dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
4787 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
4788 																				m_params.src.image.extent.width,
4789 																				m_params.src.image.extent.height,
4790 																				m_params.src.image.extent.depth));
4791 	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);
4792 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
4793 																						(int)m_params.dst.image.extent.width,
4794 																						(int)m_params.dst.image.extent.height,
4795 																						(int)m_params.dst.image.extent.depth));
4796 	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);
4797 	generateExpectedResult();
4798 
4799 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
4800 
4801 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
4802 
4803 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
4804 	const VkDevice				vkDevice			= m_device;
4805 	const VkQueue				queue				= m_queue;
4806 
4807 	std::vector<VkImageBlit>		regions;
4808 	std::vector<VkImageBlit2KHR>	regions2KHR;
4809 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
4810 	{
4811 		if (m_params.extensionUse == EXTENSION_USE_NONE)
4812 		{
4813 			regions.push_back(m_params.regions[i].imageBlit);
4814 		}
4815 		else
4816 		{
4817 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4818 			regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
4819 		}
4820 	}
4821 
4822 	// Copy source image to mip level 0 when generating mipmaps with multiple blit commands
4823 	if (!m_params.singleCommand)
4824 		uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
4825 
4826 	beginCommandBuffer(vk, *m_cmdBuffer);
4827 
4828 	// Blit all mip levels with a single blit command
4829 	if (m_params.singleCommand)
4830 	{
4831 		{
4832 			// Source image layout
4833 			const VkImageMemoryBarrier		srcImageBarrier		=
4834 			{
4835 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4836 				DE_NULL,									// const void*				pNext;
4837 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4838 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
4839 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
4840 				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
4841 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4842 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4843 				m_source.get(),								// VkImage					image;
4844 				{											// VkImageSubresourceRange	subresourceRange;
4845 					getAspectFlags(srcTcuFormat),		// VkImageAspectFlags   aspectMask;
4846 					0u,									// deUint32				baseMipLevel;
4847 					1u,									// deUint32				mipLevels;
4848 					0u,									// deUint32				baseArraySlice;
4849 					getArraySize(m_params.src.image)	// deUint32				arraySize;
4850 				}
4851 			};
4852 
4853 			// Destination image layout
4854 			const VkImageMemoryBarrier		dstImageBarrier		=
4855 			{
4856 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4857 				DE_NULL,									// const void*				pNext;
4858 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4859 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
4860 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
4861 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
4862 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4863 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4864 				m_destination.get(),						// VkImage					image;
4865 				{											// VkImageSubresourceRange	subresourceRange;
4866 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags   aspectMask;
4867 					0u,									// deUint32				baseMipLevel;
4868 					m_params.mipLevels,					// deUint32				mipLevels;
4869 					0u,									// deUint32				baseArraySlice;
4870 					getArraySize(m_params.dst.image)	// deUint32				arraySize;
4871 				}
4872 			};
4873 
4874 			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);
4875 			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);
4876 
4877 			if (m_params.extensionUse == EXTENSION_USE_NONE)
4878 			{
4879 				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);
4880 			}
4881 #ifndef CTS_USES_VULKANSC
4882 			else
4883 			{
4884 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4885 				const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4886 				{
4887 					VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
4888 					DE_NULL,									// const void*					pNext;
4889 					m_source.get(),								// VkImage						srcImage;
4890 					m_params.src.image.operationLayout,			// VkImageLayout				srcImageLayout;
4891 					m_destination.get(),						// VkImage						dstImage;
4892 					m_params.dst.image.operationLayout,			// VkImageLayout				dstImageLayout;
4893 					(deUint32)m_params.regions.size(),			// uint32_t						regionCount;
4894 					&regions2KHR[0],							// const VkImageBlit2KHR*		pRegions;
4895 					m_params.filter								// VkFilter						filter;
4896 				};
4897 				vk.cmdBlitImage2(*m_cmdBuffer, &BlitImageInfo2KHR);
4898 			}
4899 #endif // CTS_USES_VULKANSC
4900 		}
4901 	}
4902 	// Blit mip levels with multiple blit commands
4903 	else
4904 	{
4905 		// Prepare all mip levels for reading
4906 		{
4907 			for (deUint32 barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
4908 			{
4909 				VkImageMemoryBarrier preImageBarrier =
4910 				{
4911 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType	sType;
4912 					DE_NULL,																// const void*		pNext;
4913 					VK_ACCESS_TRANSFER_WRITE_BIT,											// VkAccessFlags	srcAccessMask;
4914 					VK_ACCESS_TRANSFER_READ_BIT,											// VkAccessFlags	dstAccessMask;
4915 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,									// VkImageLayout	oldLayout;
4916 					m_params.src.image.operationLayout,										// VkImageLayout	newLayout;
4917 					VK_QUEUE_FAMILY_IGNORED,												// deUint32			srcQueueFamilyIndex;
4918 					VK_QUEUE_FAMILY_IGNORED,												// deUint32			dstQueueFamilyIndex;
4919 					m_destination.get(),													// VkImage			image;
4920 					{																		// VkImageSubresourceRange	subresourceRange;
4921 						getAspectFlags(dstTcuFormat),										// VkImageAspectFlags	aspectMask;
4922 							0u,																// deUint32				baseMipLevel;
4923 							VK_REMAINING_MIP_LEVELS,										// deUint32				mipLevels;
4924 							0u,																// deUint32				baseArraySlice;
4925 							getArraySize(m_params.src.image)								// deUint32				arraySize;
4926 					}
4927 				};
4928 
4929 				if (getArraySize(m_params.src.image) == 1)
4930 				{
4931 					DE_ASSERT(barrierno < m_params.mipLevels);
4932 					preImageBarrier.subresourceRange.baseMipLevel	= barrierno;
4933 					preImageBarrier.subresourceRange.levelCount		= (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
4934 				}
4935 				else
4936 				{
4937 					preImageBarrier.subresourceRange.baseArrayLayer	= barrierno;
4938 					preImageBarrier.subresourceRange.layerCount		= (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
4939 				}
4940 				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);
4941 			}
4942 		}
4943 
4944 		for (deUint32 regionNdx = 0u; regionNdx < (deUint32)m_params.regions.size(); regionNdx++)
4945 		{
4946 			const deUint32	mipLevel	= m_params.regions[regionNdx].imageBlit.dstSubresource.mipLevel;
4947 
4948 			// Prepare single mip level for writing
4949 			const VkImageMemoryBarrier		preImageBarrier		=
4950 			{
4951 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4952 				DE_NULL,									// const void*					pNext;
4953 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
4954 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
4955 				m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
4956 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
4957 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4958 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4959 				m_destination.get(),						// VkImage					image;
4960 				{											// VkImageSubresourceRange	subresourceRange;
4961 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
4962 					mipLevel,							// deUint32				baseMipLevel;
4963 					1u,									// deUint32				mipLevels;
4964 					0u,									// deUint32				baseArraySlice;
4965 					getArraySize(m_params.dst.image)	// deUint32				arraySize;
4966 				}
4967 			};
4968 
4969 			// Prepare single mip level for reading
4970 			const VkImageMemoryBarrier		postImageBarrier	=
4971 			{
4972 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4973 				DE_NULL,									// const void*				pNext;
4974 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4975 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
4976 				m_params.dst.image.operationLayout,			// VkImageLayout			oldLayout;
4977 				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
4978 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4979 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4980 				m_destination.get(),						// VkImage					image;
4981 				{											// VkImageSubresourceRange	subresourceRange;
4982 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
4983 					mipLevel,							// deUint32				baseMipLevel;
4984 					1u,									// deUint32				mipLevels;
4985 					0u,									// deUint32				baseArraySlice;
4986 					getArraySize(m_params.src.image)	// deUint32				arraySize;
4987 				}
4988 			};
4989 
4990 			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);
4991 
4992 			if (m_params.extensionUse == EXTENSION_USE_NONE)
4993 			{
4994 				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);
4995 			}
4996 #ifndef CTS_USES_VULKANSC
4997 			else
4998 			{
4999 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
5000 				const VkBlitImageInfo2KHR BlitImageInfo2KHR =
5001 				{
5002 					VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
5003 					DE_NULL,									// const void*					pNext;
5004 					m_destination.get(),						// VkImage						srcImage;
5005 					m_params.src.image.operationLayout,			// VkImageLayout				srcImageLayout;
5006 					m_destination.get(),						// VkImage						dstImage;
5007 					m_params.dst.image.operationLayout,			// VkImageLayout				dstImageLayout;
5008 					1u,											// uint32_t						regionCount;
5009 					&regions2KHR[regionNdx],					// const VkImageBlit2KHR*		pRegions;
5010 					m_params.filter								// VkFilter						filter;
5011 				};
5012 				vk.cmdBlitImage2(*m_cmdBuffer, &BlitImageInfo2KHR);
5013 			}
5014 #endif // CTS_USES_VULKANSC
5015 
5016 			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);
5017 		}
5018 
5019 		// Prepare all mip levels for writing
5020 		{
5021 			const VkImageMemoryBarrier		postImageBarrier		=
5022 			{
5023 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5024 				DE_NULL,									// const void*				pNext;
5025 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
5026 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
5027 				m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
5028 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
5029 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5030 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5031 				m_destination.get(),						// VkImage					image;
5032 				{											// VkImageSubresourceRange	subresourceRange;
5033 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
5034 					0u,									// deUint32				baseMipLevel;
5035 					VK_REMAINING_MIP_LEVELS,			// deUint32				mipLevels;
5036 					0u,									// deUint32				baseArraySlice;
5037 					getArraySize(m_params.dst.image)	// deUint32				arraySize;
5038 				}
5039 			};
5040 
5041 			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);
5042 		}
5043 	}
5044 
5045 	endCommandBuffer(vk, *m_cmdBuffer);
5046 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
5047 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
5048 
5049 	return checkTestResult();
5050 }
5051 
checkNonNearestFilteredResult(void)5052 bool BlittingMipmaps::checkNonNearestFilteredResult (void)
5053 {
5054 	tcu::TestLog&				log				(m_context.getTestContext().getLog());
5055 	bool						allLevelsOk		= true;
5056 
5057 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5058 	{
5059 		// Update reference results with previous results that have been verified.
5060 		// This needs to be done such that accumulated errors don't exceed the fixed threshold.
5061 		for (deUint32 i = 0; i < m_params.regions.size(); i++)
5062 		{
5063 			const CopyRegion region = m_params.regions[i];
5064 			const deUint32 srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
5065 			const deUint32 dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
5066 			de::MovePtr<tcu::TextureLevel>	prevResultLevel;
5067 			tcu::ConstPixelBufferAccess src;
5068 			if (srcMipLevel < mipLevelNdx)
5069 			{
5070 				// Generate expected result from rendered result that was previously verified
5071 				prevResultLevel	= readImage(*m_destination, m_params.dst.image, srcMipLevel);
5072 				src = prevResultLevel->getAccess();
5073 			}
5074 			else
5075 			{
5076 				// Previous reference mipmaps might have changed, so recompute expected result
5077 				src = m_expectedTextureLevel[srcMipLevel]->getAccess();
5078 			}
5079 			copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
5080 		}
5081 
5082 		de::MovePtr<tcu::TextureLevel>			resultLevel			= readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5083 		const tcu::ConstPixelBufferAccess&		resultAccess		= resultLevel->getAccess();
5084 
5085 		const tcu::Sampler::DepthStencilMode	mode				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::Sampler::MODE_DEPTH :
5086 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
5087 																																	tcu::Sampler::MODE_LAST;
5088 		const tcu::ConstPixelBufferAccess		result				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5089 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5090 																																	resultAccess;
5091 		const tcu::ConstPixelBufferAccess		clampedLevel		= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5092 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5093 																																	m_expectedTextureLevel[mipLevelNdx]->getAccess();
5094 		const tcu::ConstPixelBufferAccess		unclampedLevel		= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5095 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5096 																																	m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
5097 		const tcu::TextureFormat				srcFormat			= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5098 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5099 																																	mapVkFormat(m_params.src.image.format);
5100 
5101 		const tcu::TextureFormat				dstFormat			= result.getFormat();
5102 		bool									singleLevelOk		= false;
5103 		std::vector <CopyRegion>				mipLevelRegions;
5104 
5105 		for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5106 			if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5107 				mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5108 
5109 		log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
5110 
5111 		if (isFloatFormat(dstFormat))
5112 		{
5113 			const bool		srcIsSRGB   = tcu::isSRGB(srcFormat);
5114 			const tcu::Vec4 srcMaxDiff  = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
5115 			const tcu::Vec4 dstMaxDiff  = getFormatThreshold(dstFormat);
5116 			const tcu::Vec4 threshold   = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT)? 1.5f : 1.0f);
5117 
5118 			singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5119 			log << tcu::TestLog::EndSection;
5120 
5121 			if (!singleLevelOk)
5122 			{
5123 				log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5124 				singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5125 				log << tcu::TestLog::EndSection;
5126 			}
5127 		}
5128 		else
5129 		{
5130 			tcu::UVec4  threshold;
5131 			// Calculate threshold depending on channel width of destination format.
5132 			const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
5133 			const tcu::IVec4	srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
5134 			for (deUint32 i = 0; i < 4; ++i)
5135 			{
5136 				DE_ASSERT(dstBitDepth[i] < std::numeric_limits<uint64_t>::digits);
5137 				DE_ASSERT(srcBitDepth[i] < std::numeric_limits<uint64_t>::digits);
5138 				deUint64 threshold64 = 1 + de::max( ( ( UINT64_C(1) << dstBitDepth[i] ) - 1 ) / de::clamp((UINT64_C(1) << srcBitDepth[i]) - 1, UINT64_C(1), UINT64_C(256)), UINT64_C(1));
5139 				DE_ASSERT(threshold64 <= std::numeric_limits<uint32_t>::max());
5140 				threshold[i] = static_cast<deUint32>(threshold64);
5141 			}
5142 
5143 			singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5144 			log << tcu::TestLog::EndSection;
5145 
5146 			if (!singleLevelOk)
5147 			{
5148 				log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5149 				singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5150 				log << tcu::TestLog::EndSection;
5151 			}
5152 		}
5153 		allLevelsOk &= singleLevelOk;
5154 	}
5155 
5156 	return allLevelsOk;
5157 }
5158 
checkNearestFilteredResult(void)5159 bool BlittingMipmaps::checkNearestFilteredResult (void)
5160 {
5161 	bool						allLevelsOk		= true;
5162 	tcu::TestLog&				log				(m_context.getTestContext().getLog());
5163 
5164 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5165 	{
5166 		de::MovePtr<tcu::TextureLevel>			resultLevel			= readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5167 		const tcu::ConstPixelBufferAccess&		resultAccess		= resultLevel->getAccess();
5168 
5169 		const tcu::Sampler::DepthStencilMode	mode				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::Sampler::MODE_DEPTH :
5170 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
5171 																																	tcu::Sampler::MODE_LAST;
5172 		const tcu::ConstPixelBufferAccess		result				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5173 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5174 																																	resultAccess;
5175 		const tcu::ConstPixelBufferAccess		source				= (m_params.singleCommand || mipLevelNdx == 0) ?			//  Read from source image
5176 																	  tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5177 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5178 																																	m_sourceTextureLevel->getAccess()
5179 																																//  Read from destination image
5180 																	: tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5181 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5182 																																	m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
5183 		const tcu::TextureFormat				dstFormat			= result.getFormat();
5184 		const tcu::TextureChannelClass			dstChannelClass		= tcu::getTextureChannelClass(dstFormat.type);
5185 		bool									singleLevelOk		= false;
5186 		std::vector <CopyRegion>				mipLevelRegions;
5187 
5188 		for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5189 			if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5190 				mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5191 
5192 		tcu::TextureLevel				errorMaskStorage	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
5193 		tcu::PixelBufferAccess			errorMask			= errorMaskStorage.getAccess();
5194 		tcu::Vec4						pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
5195 		tcu::Vec4						pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
5196 
5197 		tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
5198 
5199 		if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
5200 			dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
5201 		{
5202 			singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions);
5203 		}
5204 		else
5205 		{
5206 			const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
5207 			const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
5208 
5209 			singleLevelOk = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, mipLevelRegions);
5210 		}
5211 
5212 		if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
5213 			tcu::computePixelScaleBias(result, pixelScale, pixelBias);
5214 
5215 		if (!singleLevelOk)
5216 		{
5217 			log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5218 				<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5219 				<< tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
5220 				<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
5221 				<< tcu::TestLog::EndImageSet;
5222 		}
5223 		else
5224 		{
5225 			log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5226 				<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5227 				<< tcu::TestLog::EndImageSet;
5228 		}
5229 
5230 		allLevelsOk &= singleLevelOk;
5231 	}
5232 
5233 	return allLevelsOk;
5234 }
5235 
checkTestResult(tcu::ConstPixelBufferAccess result)5236 tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result)
5237 {
5238 	DE_UNREF(result);
5239 	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
5240 	const std::string failMessage("Result image is incorrect");
5241 
5242 	if (m_params.filter != VK_FILTER_NEAREST)
5243 	{
5244 		if (!checkNonNearestFilteredResult())
5245 			return tcu::TestStatus::fail(failMessage);
5246 	}
5247 	else // NEAREST filtering
5248 	{
5249 		if (!checkNearestFilteredResult())
5250 			return tcu::TestStatus::fail(failMessage);
5251 	}
5252 
5253 	return tcu::TestStatus::pass("Pass");
5254 }
5255 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)5256 void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
5257 {
5258 	DE_ASSERT(src.getDepth() == dst.getDepth());
5259 
5260 	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
5261 												region.imageBlit.srcOffsets[1],
5262 												region.imageBlit.dstOffsets[0],
5263 												region.imageBlit.dstOffsets[1]);
5264 
5265 	flipCoordinates(region, mirrorMode);
5266 
5267 	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
5268 	const VkOffset3D					srcExtent		=
5269 	{
5270 		region.imageBlit.srcOffsets[1].x - srcOffset.x,
5271 		region.imageBlit.srcOffsets[1].y - srcOffset.y,
5272 		region.imageBlit.srcOffsets[1].z - srcOffset.z
5273 	};
5274 	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
5275 	const VkOffset3D					dstExtent		=
5276 	{
5277 		region.imageBlit.dstOffsets[1].x - dstOffset.x,
5278 		region.imageBlit.dstOffsets[1].y - dstOffset.y,
5279 		region.imageBlit.dstOffsets[1].z - dstOffset.z
5280 	};
5281 
5282 	tcu::Sampler::FilterMode		filter;
5283 	switch (m_params.filter)
5284 	{
5285 	case VK_FILTER_LINEAR:		filter = tcu::Sampler::LINEAR; break;
5286 	case VK_FILTER_CUBIC_EXT:	filter = tcu::Sampler::CUBIC;  break;
5287 	case VK_FILTER_NEAREST:
5288 	default:					filter = tcu::Sampler::NEAREST;  break;
5289 	}
5290 
5291 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
5292 	{
5293 		DE_ASSERT(src.getFormat() == dst.getFormat());
5294 		// Scale depth.
5295 		if (tcu::hasDepthComponent(src.getFormat().order))
5296 		{
5297 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
5298 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5299 			tcu::scale(dstSubRegion, srcSubRegion, filter);
5300 
5301 			if (filter != tcu::Sampler::NEAREST)
5302 			{
5303 				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
5304 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5305 				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
5306 			}
5307 		}
5308 
5309 		// Scale stencil.
5310 		if (tcu::hasStencilComponent(src.getFormat().order))
5311 		{
5312 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
5313 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5314 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5315 
5316 			if (filter != tcu::Sampler::NEAREST)
5317 			{
5318 				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
5319 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5320 				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
5321 			}
5322 		}
5323 	}
5324 	else
5325 	{
5326 		for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
5327 		{
5328 			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
5329 			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5330 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5331 
5332 			if (filter != tcu::Sampler::NEAREST)
5333 			{
5334 				const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5335 				scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
5336 			}
5337 		}
5338 	}
5339 }
5340 
generateExpectedResult(void)5341 void BlittingMipmaps::generateExpectedResult (void)
5342 {
5343 	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
5344 	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
5345 
5346 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5347 		m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5348 
5349 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
5350 
5351 	if (m_params.filter != VK_FILTER_NEAREST)
5352 	{
5353 		for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5354 			m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5355 
5356 		tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
5357 	}
5358 
5359 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
5360 	{
5361 		CopyRegion region = m_params.regions[i];
5362 		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);
5363 	}
5364 }
5365 
5366 class BlitMipmapTestCase : public vkt::TestCase
5367 {
5368 public:
BlitMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)5369 							BlitMipmapTestCase		(tcu::TestContext&				testCtx,
5370 													 const std::string&				name,
5371 													 const std::string&				description,
5372 													 const TestParams				params)
5373 								: vkt::TestCase	(testCtx, name, description)
5374 								, m_params		(params)
5375 	{}
5376 
createInstance(Context & context) const5377 	virtual TestInstance*	createInstance			(Context&						context) const
5378 	{
5379 		return new BlittingMipmaps(context, m_params);
5380 	}
5381 
checkSupport(Context & context) const5382 	virtual void			checkSupport			(Context&						context) const
5383 	{
5384 		const InstanceInterface&	vki					= context.getInstanceInterface();
5385 		const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
5386 		{
5387 			VkImageFormatProperties	properties;
5388 			if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5389 																						m_params.src.image.format,
5390 																						VK_IMAGE_TYPE_2D,
5391 																						VK_IMAGE_TILING_OPTIMAL,
5392 																						VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
5393 																						0,
5394 																						&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5395 			{
5396 				TCU_THROW(NotSupportedError, "Format not supported");
5397 			}
5398 			else if ((m_params.src.image.extent.width	> properties.maxExtent.width)	||
5399 						(m_params.src.image.extent.height	> properties.maxExtent.height)	||
5400 						(m_params.src.image.extent.depth	> properties.maxArrayLayers))
5401 			{
5402 				TCU_THROW(NotSupportedError, "Image size not supported");
5403 			}
5404 		}
5405 
5406 		{
5407 			VkImageFormatProperties	properties;
5408 			if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5409 																						m_params.dst.image.format,
5410 																						VK_IMAGE_TYPE_2D,
5411 																						VK_IMAGE_TILING_OPTIMAL,
5412 																						VK_IMAGE_USAGE_TRANSFER_DST_BIT,
5413 																						0,
5414 																						&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5415 			{
5416 				TCU_THROW(NotSupportedError, "Format not supported");
5417 			}
5418 			else if ((m_params.dst.image.extent.width	> properties.maxExtent.width)	||
5419 						(m_params.dst.image.extent.height	> properties.maxExtent.height)	||
5420 						(m_params.dst.image.extent.depth	> properties.maxArrayLayers))
5421 			{
5422 				TCU_THROW(NotSupportedError, "Image size not supported");
5423 			}
5424 			else if (m_params.mipLevels > properties.maxMipLevels)
5425 			{
5426 				TCU_THROW(NotSupportedError, "Number of mip levels not supported");
5427 			}
5428 			else if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)	&&
5429 					 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
5430 			{
5431 				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
5432 			}
5433 		}
5434 
5435 		const VkFormatProperties	srcFormatProperties	= getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format);
5436 		if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
5437 		{
5438 			TCU_THROW(NotSupportedError, "Format feature blit source not supported");
5439 		}
5440 
5441 		const VkFormatProperties	dstFormatProperties	= getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format);
5442 		if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
5443 		{
5444 			TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
5445 		}
5446 
5447 		if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
5448 			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
5449 
5450 		if (m_params.filter == VK_FILTER_CUBIC_EXT)
5451 		{
5452 			context.requireDeviceFunctionality("VK_EXT_filter_cubic");
5453 
5454 			if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
5455 			{
5456 				TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
5457 			}
5458 		}
5459 	}
5460 
5461 private:
5462 	TestParams				m_params;
5463 };
5464 
5465 // Resolve image to image.
5466 
5467 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION = 0,
5468 								COPY_MS_IMAGE_TO_MS_IMAGE,
5469 								COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE,
5470 								COPY_MS_IMAGE_LAYER_TO_MS_IMAGE,
5471 								COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION,
5472 								COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB,
5473 								COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE,
5474 								COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER};
5475 
removeExtensions(const std::vector<std::string> & a,const std::vector<const char * > & b)5476 std::vector<std::string> removeExtensions (const std::vector<std::string>& a, const std::vector<const char*>& b)
5477 {
5478 	std::vector<std::string>	res;
5479 	std::set<std::string>		removeExts	(b.begin(), b.end());
5480 
5481 	for (const auto & aIter : a)
5482 	{
5483 		if (!de::contains(removeExts, aIter))
5484 			res.push_back(aIter);
5485 	}
5486 
5487 	return res;
5488 }
5489 
5490 
5491 // Creates a device that has queues for graphics/compute capabilities and compute or transfer capabilities without graphics.
createCustomDevice(Context & context,const ResolveImageToImageOptions imageCreateOptions,const CustomInstance & customInstance,uint32_t & queueFamilyIndex)5492 Move<VkDevice> createCustomDevice (Context&								context,
5493 								   const ResolveImageToImageOptions		imageCreateOptions,
5494 #ifdef CTS_USES_VULKANSC
5495 								   const CustomInstance&				customInstance,
5496 #endif // CTS_USES_VULKANSC
5497 								   uint32_t&							queueFamilyIndex)
5498 {
5499 #ifdef CTS_USES_VULKANSC
5500 	const InstanceInterface&	instanceDriver		= customInstance.getDriver();
5501 	const VkPhysicalDevice		physicalDevice		= chooseDevice(instanceDriver, customInstance, context.getTestContext().getCommandLine());
5502 #else
5503 	const InstanceInterface&	instanceDriver		= context.getInstanceInterface();
5504 	const VkPhysicalDevice		physicalDevice		= context.getPhysicalDevice();
5505 #endif // CTS_USES_VULKANSC
5506 
5507 	// This function can only be used to create a device with compute only or transfer only queue.
5508 	DE_ASSERT(imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER);
5509 
5510 	// When testing with compute or transfer queue, find a queue family that supports compute or transfer queue, but does NOT support graphics queue.
5511 	const std::vector<VkQueueFamilyProperties>	queueFamilies = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
5512 
5513 	queueFamilyIndex = 0;
5514 	for (const auto &queueFamily: queueFamilies)
5515 	{
5516 		if (imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE)
5517 		{
5518 			if (queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
5519 				break;
5520 			else
5521 				queueFamilyIndex++;
5522 		}
5523 		else if (imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
5524 		{
5525 			if (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT && !(queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT) && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
5526 				break;
5527 			else
5528 				queueFamilyIndex++;
5529 		}
5530 	}
5531 
5532 	// One should be found, because this is checked in "checkSupport" function.
5533 	DE_ASSERT(queueFamilyIndex < queueFamilies.size());
5534 
5535 	const float queuePriority = 1.0f;
5536 	const VkDeviceQueueCreateInfo deviceQueueCreateInfos[] = {
5537 		{
5538 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,		// VkStructureType				sType;
5539 			DE_NULL,										// const void*					pNext;
5540 			(VkDeviceQueueCreateFlags)0u,					// VkDeviceQueueCreateFlags		flags;
5541 			context.getUniversalQueueFamilyIndex(),			// uint32_t						queueFamilyIndex;
5542 			1u,												// uint32_t						queueCount;
5543 			&queuePriority,									// const float*					pQueuePriorities;
5544 		},
5545 		{
5546 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,		// VkStructureType				sType;
5547 			DE_NULL,										// const void*					pNext;
5548 			(VkDeviceQueueCreateFlags)0u,					// VkDeviceQueueCreateFlags		flags;
5549 			queueFamilyIndex,								// uint32_t						queueFamilyIndex;
5550 			1u,												// uint32_t						queueCount;
5551 			&queuePriority,									// const float*					pQueuePriorities;
5552 		}
5553 	};
5554 
5555 	// context.getDeviceExtensions() returns supported device extension including extensions that have been promoted to
5556 	// Vulkan core. The core extensions must be removed from the list.
5557 	std::vector<const char*>	coreExtensions;
5558 	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
5559 	std::vector<std::string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));
5560 
5561 	std::vector<const char*>	extensionNames;
5562 	extensionNames.reserve(nonCoreExtensions.size());
5563 	for (const std::string& extension : nonCoreExtensions)
5564 		extensionNames.push_back(extension.c_str());
5565 
5566 	const auto& deviceFeatures2 = context.getDeviceFeatures2();
5567 
5568 	const void *pNext = &deviceFeatures2;
5569 #ifdef CTS_USES_VULKANSC
5570 	VkDeviceObjectReservationCreateInfo memReservationInfo = context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
5571 	memReservationInfo.pNext = pNext;
5572 	pNext = &memReservationInfo;
5573 
5574 	VkPipelineCacheCreateInfo			pcCI;
5575 	std::vector<VkPipelinePoolSize>		poolSizes;
5576 	if (context.getTestContext().getCommandLine().isSubProcess())
5577 	{
5578 		if (context.getResourceInterface()->getCacheDataSize() > 0)
5579 		{
5580 			pcCI =
5581 			{
5582 				VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,			// VkStructureType				sType;
5583 				DE_NULL,												// const void*					pNext;
5584 				VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
5585 					VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
5586 				context.getResourceInterface()->getCacheDataSize(),	// deUintptr					initialDataSize;
5587 				context.getResourceInterface()->getCacheData()		// const void*					pInitialData;
5588 			};
5589 			memReservationInfo.pipelineCacheCreateInfoCount		= 1;
5590 			memReservationInfo.pPipelineCacheCreateInfos		= &pcCI;
5591 		}
5592 		poolSizes							= context.getResourceInterface()->getPipelinePoolSizes();
5593 		if (!poolSizes.empty())
5594 		{
5595 			memReservationInfo.pipelinePoolSizeCount		= deUint32(poolSizes.size());
5596 			memReservationInfo.pPipelinePoolSizes			= poolSizes.data();
5597 		}
5598 	}
5599 #endif // CTS_USES_VULKANSC
5600 
5601 	const VkDeviceCreateInfo	deviceCreateInfo =
5602 	{
5603 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,			// VkStructureType					sType;
5604 		pNext,											// const void*						pNext;
5605 		(VkDeviceCreateFlags)0u,						// VkDeviceCreateFlags				flags;
5606 		DE_LENGTH_OF_ARRAY(deviceQueueCreateInfos),		// uint32_t							queueCreateInfoCount;
5607 		deviceQueueCreateInfos,							// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
5608 		0u,												// uint32_t							enabledLayerCount;
5609 		DE_NULL,										// const char* const*				ppEnabledLayerNames;
5610 		static_cast<uint32_t>(extensionNames.size()),	// uint32_t							enabledExtensionCount;
5611 		extensionNames.data(),							// const char* const*				ppEnabledExtensionNames;
5612 		DE_NULL,										// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
5613 	};
5614 
5615 #ifndef CTS_USES_VULKANSC
5616 	return vkt::createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), instanceDriver, physicalDevice, &deviceCreateInfo);
5617 #else
5618 	return vkt::createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), customInstance, instanceDriver, physicalDevice, &deviceCreateInfo);
5619 #endif // CTS_USES_VULKANSC
5620 }
5621 
5622 class ResolveImageToImage : public CopiesAndBlittingTestInstance
5623 {
5624 public:
5625 												ResolveImageToImage				(Context&						context,
5626 																				 TestParams						params,
5627 																				 ResolveImageToImageOptions		options);
5628 	virtual tcu::TestStatus						iterate							(void);
shouldVerifyIntermediateResults(ResolveImageToImageOptions option)5629 	static inline bool							shouldVerifyIntermediateResults	(ResolveImageToImageOptions option)
5630 	{
5631 		return option == COPY_MS_IMAGE_TO_MS_IMAGE || option == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE || option == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || option == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || option == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER;
5632 	}
~ResolveImageToImage()5633 												~ResolveImageToImage()
5634 												{
5635 													// Destroy the command pool (and free the related command buffer).
5636 													// This must be done before the m_customDevice is destroyed.
5637 													m_cmdBuffer = Move<VkCommandBuffer>();
5638 													m_cmdPool = Move<VkCommandPool>();
5639 												}
5640 protected:
5641 	virtual tcu::TestStatus						checkTestResult					(tcu::ConstPixelBufferAccess result);
5642 	void										copyMSImageToMSImage			(deUint32 copyArraySize);
5643 	tcu::TestStatus								checkIntermediateCopy			(void);
5644 private:
5645 	const CustomInstance						m_customInstance;
5646 	Move<VkDevice>								m_customDevice;
5647 
5648 #ifndef CTS_USES_VULKANSC
5649 	de::MovePtr<vk::DeviceDriver>				m_deviceDriver;
5650 #else
5651 	de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>	m_deviceDriver;
5652 #endif // CTS_USES_VULKANSC
5653 
5654 	Move<VkCommandPool>							m_alternativeCmdPool;
5655 	Move<VkCommandBuffer>						m_alternativeCmdBuffer;
5656 	VkQueue										m_alternativeQueue;
5657 	uint32_t									m_alternativeQueueFamilyIndex;
5658 	de::MovePtr<vk::Allocator>					m_alternativeAllocator;
5659 	Move<VkImage>								m_multisampledImage;
5660 	de::MovePtr<Allocation>						m_multisampledImageAlloc;
5661 
5662 	Move<VkImage>								m_destination;
5663 	de::MovePtr<Allocation>						m_destinationImageAlloc;
5664 
5665 	Move<VkImage>								m_multisampledCopyImage;
5666 	de::MovePtr<Allocation>						m_multisampledCopyImageAlloc;
5667 	Move<VkImage>								m_multisampledCopyNoCabImage;
5668 	de::MovePtr<Allocation>						m_multisampledCopyImageNoCabAlloc;
5669 
5670 	const ResolveImageToImageOptions			m_options;
5671 
5672 	virtual void								copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess	src,
5673 																			 tcu::PixelBufferAccess			dst,
5674 																			 CopyRegion						region,
5675 																			 deUint32						mipLevel = 0u);
5676 };
5677 
ResolveImageToImage(Context & context,TestParams params,const ResolveImageToImageOptions options)5678 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
5679 	: CopiesAndBlittingTestInstance	(context, params)
5680 	, m_customInstance				(createCustomInstanceFromContext(context))
5681 	, m_options						(options)
5682 {
5683 
5684 
5685 #ifdef CTS_USES_VULKANSC
5686 	const InstanceInterface&	vki						= m_customInstance.getDriver();
5687 #else
5688 	const InstanceInterface&	vki						= m_context.getInstanceInterface();
5689 #endif // CTS_USES_VULKANSC
5690 
5691 		uint32_t queueFamilyIndex		= 0;
5692 	// Create custom device for compute and transfer only queue tests.
5693 	if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
5694 	{
5695 		// 'queueFamilyIndex' will be updated in 'createCustomDevice()' to match the requested queue type.
5696 #ifdef CTS_USES_VULKANSC
5697 		m_customDevice					= createCustomDevice(context, m_options, m_customInstance, queueFamilyIndex);
5698 #else
5699 		m_customDevice					= createCustomDevice(context, m_options, queueFamilyIndex);
5700 #endif // CTS_USES_VULKANSC
5701 		m_device						= m_customDevice.get();
5702 
5703 #ifndef CTS_USES_VULKANSC
5704 		m_deviceDriver = de::MovePtr<DeviceDriver>(new DeviceDriver(context.getPlatformInterface(), m_customInstance, m_device));
5705 #else
5706 		m_deviceDriver = de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>(new DeviceDriverSC(context.getPlatformInterface(), m_customInstance, m_device, context.getTestContext().getCommandLine(), context.getResourceInterface(), context.getDeviceVulkanSC10Properties(), context.getDeviceProperties()), vk::DeinitDeviceDeleter(context.getResourceInterface().get(), m_device));
5707 #endif // CTS_USES_VULKANSC
5708 
5709 		m_queue							= getDeviceQueue(m_context.getDeviceInterface(), m_device, context.getUniversalQueueFamilyIndex(), 0u);
5710 		m_alternativeQueue				= getDeviceQueue(m_context.getDeviceInterface(), m_device, queueFamilyIndex, 0u);
5711 	}
5712 
5713 	m_alternativeQueueFamilyIndex	= queueFamilyIndex;
5714 
5715 #ifndef CTS_USES_VULKANSC
5716 	const DeviceInterface&		vk						= m_context.getDeviceInterface();
5717 #else
5718 	const DeviceInterface&		vk						= (DE_NULL != m_deviceDriver) ? *m_deviceDriver : m_context.getDeviceInterface();
5719 #endif // CTS_USES_VULKANSC
5720 
5721 	m_alternativeAllocator			= de::MovePtr<Allocator>(new SimpleAllocator(vk, m_device, getPhysicalDeviceMemoryProperties(vki, context.getPhysicalDevice())));
5722 	m_allocator						= m_alternativeAllocator.get();
5723 
5724 	// Release the command buffer.
5725 	m_cmdBuffer = Move<VkCommandBuffer>();
5726 
5727 	// Create a new command pool and allocate a command buffer with universal queue family index and destroy the old one.
5728 	m_cmdPool						= createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex());
5729 	m_cmdBuffer						= allocateCommandBuffer(vk, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5730 
5731 	// Create a command pool and allocate a command buffer from the queue family supporting compute / transfer capabilities.
5732 	m_alternativeCmdPool			= createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
5733 	m_alternativeCmdBuffer			= allocateCommandBuffer(vk, m_device, *m_alternativeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5734 
5735 	Allocator&					memAlloc				= *m_allocator;
5736 	const VkPhysicalDevice		vkPhysDevice			= m_context.getPhysicalDevice();
5737 	const VkDevice				vkDevice				= m_device;
5738 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
5739 	Move<VkRenderPass>			renderPass;
5740 
5741 	Move<VkShaderModule>		vertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
5742 	Move<VkShaderModule>		fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
5743 	std::vector<tcu::Vec4>		vertices;
5744 
5745 	Move<VkBuffer>				vertexBuffer;
5746 	de::MovePtr<Allocation>		vertexBufferAlloc;
5747 
5748 	Move<VkPipelineLayout>		pipelineLayout;
5749 	Move<VkPipeline>			graphicsPipeline;
5750 
5751 	const VkSampleCountFlagBits	rasterizationSamples	= m_params.samples;
5752 
5753 	// Create color image.
5754 	{
5755 		VkImageCreateInfo		colorImageParams	=
5756 		{
5757 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
5758 			DE_NULL,																// const void*				pNext;
5759 			getCreateFlags(m_params.src.image),										// VkImageCreateFlags		flags;
5760 			m_params.src.image.imageType,											// VkImageType				imageType;
5761 			m_params.src.image.format,												// VkFormat					format;
5762 			getExtent3D(m_params.src.image),										// VkExtent3D				extent;
5763 			1u,																		// deUint32					mipLevels;
5764 			getArraySize(m_params.src.image),										// deUint32					arrayLayers;
5765 			rasterizationSamples,													// VkSampleCountFlagBits	samples;
5766 			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
5767 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT										// VkImageUsageFlags		usage;
5768 				| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
5769 				| VK_IMAGE_USAGE_TRANSFER_DST_BIT
5770 				| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
5771 			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
5772 			0u,																		// deUint32					queueFamilyIndexCount;
5773 			(const deUint32*)DE_NULL,												// const deUint32*			pQueueFamilyIndices;
5774 			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout			initialLayout;
5775 		};
5776 
5777 		m_multisampledImage						= createImage(vk, vkDevice, &colorImageParams);
5778 		VkMemoryRequirements	req				= getImageMemoryRequirements(vk, vkDevice, *m_multisampledImage);
5779 
5780 		// Allocate and bind color image memory.
5781 		deUint32				offset			= m_params.imageOffset ? static_cast<deUint32>(req.alignment) : 0u;
5782 		m_multisampledImageAlloc				= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any,
5783 																memAlloc, m_params.allocationKind, offset);
5784 
5785 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), offset));
5786 
5787 		switch (m_options)
5788 		{
5789 			case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
5790 			case COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE:
5791 			case COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER:
5792 			case COPY_MS_IMAGE_TO_MS_IMAGE:
5793 			{
5794 				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;
5795 				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
5796 				// Allocate and bind color image memory.
5797 				m_multisampledCopyImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5798 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5799 				break;
5800 			}
5801 			case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
5802 			case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
5803 			{
5804 				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;
5805 				colorImageParams.arrayLayers	= getArraySize(m_params.dst.image);
5806 				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
5807 				// Allocate and bind color image memory.
5808 				m_multisampledCopyImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5809 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5810 				break;
5811 			}
5812 			case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
5813 			{
5814 				colorImageParams.usage				= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5815 				colorImageParams.arrayLayers		= getArraySize(m_params.dst.image);
5816 				m_multisampledCopyImage				= createImage(vk, vkDevice, &colorImageParams);
5817 				m_multisampledCopyNoCabImage		= createImage(vk, vkDevice, &colorImageParams);
5818 				// Allocate and bind color image memory.
5819 				m_multisampledCopyImageAlloc			= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5820 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5821 				m_multisampledCopyImageNoCabAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyNoCabImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5822 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyNoCabImage, m_multisampledCopyImageNoCabAlloc->getMemory(), m_multisampledCopyImageNoCabAlloc->getOffset()));
5823 				break;
5824 			}
5825 
5826 			default :
5827 				break;
5828 		}
5829 	}
5830 
5831 	// Create destination image.
5832 	{
5833 		const VkImageCreateInfo	destinationImageParams	=
5834 		{
5835 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
5836 			DE_NULL,								// const void*			pNext;
5837 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
5838 			m_params.dst.image.imageType,			// VkImageType			imageType;
5839 			m_params.dst.image.format,				// VkFormat				format;
5840 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
5841 			1u,										// deUint32				mipLevels;
5842 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
5843 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
5844 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
5845 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
5846 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
5847 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
5848 			0u,										// deUint32				queueFamilyIndexCount;
5849 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
5850 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
5851 		};
5852 
5853 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
5854 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5855 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
5856 	}
5857 
5858 	// Barriers for image clearing.
5859 	std::vector<VkImageMemoryBarrier> srcImageBarriers;
5860 
5861 	const VkImageMemoryBarrier m_multisampledImageBarrier =
5862 	{
5863 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5864 		DE_NULL,									// const void*				pNext;
5865 		0u,											// VkAccessFlags			srcAccessMask;
5866 		VK_ACCESS_MEMORY_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
5867 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
5868 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
5869 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5870 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5871 		m_multisampledImage.get(),					// VkImage					image;
5872 		{											// VkImageSubresourceRange	subresourceRange;
5873 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
5874 			0u,										// deUint32				baseMipLevel;
5875 			1u,										// deUint32				mipLevels;
5876 			0u,										// deUint32				baseArraySlice;
5877 			getArraySize(m_params.src.image)		// deUint32				arraySize;
5878 		}
5879 	};
5880 	const VkImageMemoryBarrier m_multisampledCopyImageBarrier =
5881 	{
5882 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5883 		DE_NULL,									// const void*				pNext;
5884 		0u,											// VkAccessFlags			srcAccessMask;
5885 		VK_ACCESS_MEMORY_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
5886 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
5887 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
5888 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5889 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5890 		m_multisampledCopyImage.get(),				// VkImage					image;
5891 		{											// VkImageSubresourceRange	subresourceRange;
5892 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
5893 			0u,										// deUint32				baseMipLevel;
5894 			1u,										// deUint32				mipLevels;
5895 			0u,										// deUint32				baseArraySlice;
5896 			getArraySize(m_params.dst.image)		// deUint32				arraySize;
5897 		}
5898 	};
5899 	const VkImageMemoryBarrier m_multisampledCopyImageNoCabBarrier =
5900 	{
5901 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5902 		DE_NULL,									// const void*				pNext;
5903 		0u,											// VkAccessFlags			srcAccessMask;
5904 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
5905 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
5906 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
5907 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5908 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5909 		m_multisampledCopyNoCabImage.get(),			// VkImage					image;
5910 		{											// VkImageSubresourceRange	subresourceRange;
5911 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
5912 			0u,										// deUint32				baseMipLevel;
5913 			1u,										// deUint32				mipLevels;
5914 			0u,										// deUint32				baseArraySlice;
5915 			getArraySize(m_params.dst.image)		// deUint32				arraySize;
5916 		}
5917 	};
5918 
5919 	// Only use one barrier if no options have been given.
5920 	if (m_options != DE_NULL)
5921 	{
5922 		srcImageBarriers.push_back(m_multisampledImageBarrier);
5923 		srcImageBarriers.push_back(m_multisampledCopyImageBarrier);
5924 		// Add the third barrier if option is as below.
5925 		if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
5926 			srcImageBarriers.push_back(m_multisampledCopyImageNoCabBarrier);
5927 	}
5928 	else
5929 	{
5930 		srcImageBarriers.push_back(m_multisampledImageBarrier);
5931 	}
5932 
5933 	// Create render pass.
5934 	{
5935 		const VkAttachmentDescription	attachmentDescription		=
5936 		{
5937 			0u,											// VkAttachmentDescriptionFlags		flags;
5938 			m_params.src.image.format,					// VkFormat							format;
5939 			rasterizationSamples,						// VkSampleCountFlagBits			samples;
5940 			VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp				loadOp;
5941 			VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp;
5942 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp;
5943 			VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp;
5944 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout					initialLayout;
5945 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL		// VkImageLayout					finalLayout;
5946 		};
5947 
5948 		const VkAttachmentReference		colorAttachmentReference	=
5949 		{
5950 			0u,													// deUint32			attachment;
5951 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
5952 		};
5953 
5954 		const VkSubpassDescription		subpassDescription			=
5955 		{
5956 			0u,									// VkSubpassDescriptionFlags	flags;
5957 			VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint			pipelineBindPoint;
5958 			0u,									// deUint32						inputAttachmentCount;
5959 			DE_NULL,							// const VkAttachmentReference*	pInputAttachments;
5960 			1u,									// deUint32						colorAttachmentCount;
5961 			&colorAttachmentReference,			// const VkAttachmentReference*	pColorAttachments;
5962 			DE_NULL,							// const VkAttachmentReference*	pResolveAttachments;
5963 			DE_NULL,							// const VkAttachmentReference*	pDepthStencilAttachment;
5964 			0u,									// deUint32						preserveAttachmentCount;
5965 			DE_NULL								// const VkAttachmentReference*	pPreserveAttachments;
5966 		};
5967 
5968 		// Subpass dependency is used to synchronize the memory access of the image clear and color attachment write in some test cases.
5969 		const VkSubpassDependency		subpassDependency			=
5970 		{
5971 			VK_SUBPASS_EXTERNAL,							//uint32_t				srcSubpass;
5972 			0u,												//uint32_t				dstSubpass;
5973 			VK_PIPELINE_STAGE_TRANSFER_BIT,					//VkPipelineStageFlags	srcStageMask;
5974 			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,	//VkPipelineStageFlags	dstStageMask;
5975 			VK_ACCESS_TRANSFER_WRITE_BIT,					//VkAccessFlags			srcAccessMask;
5976 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			//VkAccessFlags			dstAccessMask;
5977 			0u												//VkDependencyFlags		dependencyFlags;
5978 		};
5979 
5980 		const deBool					useSubpassDependency		= m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION;
5981 		const VkRenderPassCreateInfo	renderPassParams			=
5982 		{
5983 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType					sType;
5984 			DE_NULL,									// const void*						pNext;
5985 			0u,											// VkRenderPassCreateFlags			flags;
5986 			1u,											// deUint32							attachmentCount;
5987 			&attachmentDescription,						// const VkAttachmentDescription*	pAttachments;
5988 			1u,											// deUint32							subpassCount;
5989 			&subpassDescription,						// const VkSubpassDescription*		pSubpasses;
5990 			useSubpassDependency ? 1u : 0u,				// deUint32							dependencyCount;
5991 			&subpassDependency							// const VkSubpassDependency*		pDependencies;
5992 		};
5993 
5994 		renderPass	= createRenderPass(vk, vkDevice, &renderPassParams);
5995 	}
5996 
5997 	// Create pipeline layout
5998 	{
5999 		const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
6000 		{
6001 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
6002 			DE_NULL,											// const void*						pNext;
6003 			0u,													// VkPipelineLayoutCreateFlags		flags;
6004 			0u,													// deUint32							setLayoutCount;
6005 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
6006 			0u,													// deUint32							pushConstantRangeCount;
6007 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
6008 		};
6009 
6010 		pipelineLayout	= createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
6011 	}
6012 
6013 	// Create upper half triangle.
6014 	{
6015 		const tcu::Vec4	a	(-1.0, -1.0, 0.0, 1.0);
6016 		const tcu::Vec4	b	(1.0, -1.0, 0.0, 1.0);
6017 		const tcu::Vec4	c	(1.0, 1.0, 0.0, 1.0);
6018 		// Add triangle.
6019 		vertices.push_back(a);
6020 		vertices.push_back(c);
6021 		vertices.push_back(b);
6022 	}
6023 
6024 	// Create vertex buffer.
6025 	{
6026 		const VkDeviceSize			vertexDataSize		= vertices.size() * sizeof(tcu::Vec4);
6027 		const VkBufferCreateInfo	vertexBufferParams	=
6028 		{
6029 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
6030 			DE_NULL,									// const void*			pNext;
6031 			0u,											// VkBufferCreateFlags	flags;
6032 			vertexDataSize,								// VkDeviceSize			size;
6033 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
6034 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
6035 			0u,											// deUint32				queueFamilyIndexCount;
6036 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
6037 		};
6038 
6039 		vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
6040 		vertexBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
6041 		VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
6042 
6043 		// Load vertices into vertex buffer.
6044 		deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
6045 		flushAlloc(vk, vkDevice, *vertexBufferAlloc);
6046 	}
6047 
6048 	{
6049 		Move<VkFramebuffer>		framebuffer;
6050 		Move<VkImageView>		sourceAttachmentView;
6051 
6052 		uint32_t baseArrayLayer = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : 0u;
6053 
6054 		// Create color attachment view.
6055 		{
6056 			const VkImageViewCreateInfo	colorAttachmentViewParams	=
6057 			{
6058 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,					// VkStructureType			sType;
6059 				DE_NULL,													// const void*				pNext;
6060 				0u,															// VkImageViewCreateFlags	flags;
6061 				*m_multisampledImage,										// VkImage					image;
6062 				VK_IMAGE_VIEW_TYPE_2D,										// VkImageViewType			viewType;
6063 				m_params.src.image.format,									// VkFormat					format;
6064 				componentMappingRGBA,										// VkComponentMapping		components;
6065 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, baseArrayLayer, 1u }	// VkImageSubresourceRange	subresourceRange;
6066 			};
6067 			sourceAttachmentView	= createImageView(vk, vkDevice, &colorAttachmentViewParams);
6068 		}
6069 
6070 		// Create framebuffer
6071 		{
6072 			const VkFramebufferCreateInfo	framebufferParams	=
6073 			{
6074 					VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
6075 					DE_NULL,											// const void*					pNext;
6076 					0u,													// VkFramebufferCreateFlags		flags;
6077 					*renderPass,										// VkRenderPass					renderPass;
6078 					1u,													// deUint32						attachmentCount;
6079 					&sourceAttachmentView.get(),						// const VkImageView*			pAttachments;
6080 					m_params.src.image.extent.width,					// deUint32						width;
6081 					m_params.src.image.extent.height,					// deUint32						height;
6082 					1u													// deUint32						layers;
6083 			};
6084 
6085 			framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
6086 		}
6087 
6088 		// Create pipeline
6089 		{
6090 			const std::vector<VkViewport>	viewports	(1, makeViewport(m_params.src.image.extent));
6091 			const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_params.src.image.extent));
6092 
6093 			const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
6094 			{
6095 				VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
6096 				DE_NULL,													// const void*								pNext;
6097 				0u,															// VkPipelineMultisampleStateCreateFlags	flags;
6098 				rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
6099 				VK_FALSE,													// VkBool32									sampleShadingEnable;
6100 				0.0f,														// float									minSampleShading;
6101 				DE_NULL,													// const VkSampleMask*						pSampleMask;
6102 				VK_FALSE,													// VkBool32									alphaToCoverageEnable;
6103 				VK_FALSE													// VkBool32									alphaToOneEnable;
6104 			};
6105 
6106 			graphicsPipeline = makeGraphicsPipeline(vk,										// const DeviceInterface&                        vk
6107 													vkDevice,								// const VkDevice                                device
6108 													*pipelineLayout,						// const VkPipelineLayout                        pipelineLayout
6109 													*vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
6110 													DE_NULL,								// const VkShaderModule                          tessellationControlModule
6111 													DE_NULL,								// const VkShaderModule                          tessellationEvalModule
6112 													DE_NULL,								// const VkShaderModule                          geometryShaderModule
6113 													*fragmentShaderModule,					// const VkShaderModule                          fragmentShaderModule
6114 													*renderPass,							// const VkRenderPass                            renderPass
6115 													viewports,								// const std::vector<VkViewport>&                viewports
6116 													scissors,								// const std::vector<VkRect2D>&                  scissors
6117 													VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
6118 													0u,										// const deUint32                                subpass
6119 													0u,										// const deUint32                                patchControlPoints
6120 													DE_NULL,								// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
6121 													DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6122 													&multisampleStateParams);				// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
6123 		}
6124 
6125 		// Create command buffer
6126 		{
6127 			beginCommandBuffer(vk, *m_cmdBuffer, 0u);
6128 
6129 			if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6130 			{
6131 				// Change the image layouts.
6132 				vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, (uint32_t)srcImageBarriers.size(), srcImageBarriers.data());
6133 
6134 				// Clear the 'm_multisampledImage'.
6135 				{
6136 					const VkClearColorValue clearValue = {{0.0f, 0.0f, 0.0f, 1.0f}};
6137 					const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
6138 					vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
6139 				}
6140 
6141 				// Clear the 'm_multisampledCopyImage' with different color.
6142 				{
6143 					const VkClearColorValue clearValue = {{1.0f, 1.0f, 1.0f, 1.0f}};
6144 					const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
6145 					vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
6146 				}
6147 			}
6148 			else
6149 			{
6150 				// Change the image layouts.
6151 				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());
6152 			}
6153 
6154 			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));
6155 
6156 			const VkDeviceSize vertexBufferOffset = 0u;
6157 
6158 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
6159 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
6160 			vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
6161 
6162 			endRenderPass(vk, *m_cmdBuffer);
6163 			endCommandBuffer(vk, *m_cmdBuffer);
6164 		}
6165 
6166 		// Queue submit.
6167 		{
6168 			submitCommandsAndWait (vk, vkDevice, m_queue, *m_cmdBuffer);
6169 			m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
6170 		}
6171 	}
6172 }
6173 
iterate(void)6174 tcu::TestStatus ResolveImageToImage::iterate (void)
6175 {
6176 	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
6177 	const tcu::TextureFormat		dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
6178 
6179 	// upload the destination image
6180 	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
6181 																			(int)m_params.dst.image.extent.width,
6182 																			(int)m_params.dst.image.extent.height,
6183 																			(int)m_params.dst.image.extent.depth));
6184 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
6185 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
6186 
6187 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
6188 																	(int)m_params.src.image.extent.width,
6189 																	(int)m_params.src.image.extent.height,
6190 																	(int)m_params.dst.image.extent.depth));
6191 
6192 	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);
6193 	generateExpectedResult();
6194 
6195 	VkImage		sourceImage		= m_multisampledImage.get();
6196 	deUint32	sourceArraySize	= getArraySize(m_params.src.image);
6197 
6198 	switch (m_options)
6199 	{
6200 		case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
6201 		case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
6202 			// Duplicate the multisampled image to a multisampled image array
6203 			sourceArraySize	= getArraySize(m_params.dst.image); // fall through
6204 		case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
6205 		case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
6206 		case COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE:
6207 		case COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER:
6208 		case COPY_MS_IMAGE_TO_MS_IMAGE:
6209 			copyMSImageToMSImage(sourceArraySize);
6210 			sourceImage	= m_multisampledCopyImage.get();
6211 			break;
6212 		default:
6213 			break;
6214 	}
6215 
6216 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
6217 	const VkDevice					vkDevice			= m_device;
6218 	const VkQueue					queue				= m_queue;
6219 
6220 	std::vector<VkImageResolve>		imageResolves;
6221 	std::vector<VkImageResolve2KHR>	imageResolves2KHR;
6222 	for (CopyRegion region : m_params.regions)
6223 	{
6224 		// If copying multiple regions, make sure that the same regions are
6225 		// used for resolving as the ones used for copying.
6226 		if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6227 		{
6228 			VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
6229 										getExtent3D(m_params.src.image).height / 2,
6230 										getExtent3D(m_params.src.image).depth};
6231 
6232 			const VkImageResolve imageResolve =
6233 			{
6234 				region.imageResolve.srcSubresource,		// VkImageSubresourceLayers	srcSubresource;
6235 				region.imageResolve.dstOffset,			// VkOffset3D				srcOffset;
6236 				region.imageResolve.dstSubresource,		// VkImageSubresourceLayers	dstSubresource;
6237 				region.imageResolve.dstOffset,			// VkOffset3D				dstOffset;
6238 				partialExtent,							// VkExtent3D				extent;
6239 			};
6240 
6241 			if (m_params.extensionUse == EXTENSION_USE_NONE)
6242 			{
6243 				imageResolves.push_back(imageResolve);
6244 			}
6245 			else
6246 			{
6247 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6248 				imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(imageResolve));
6249 			}
6250 		}
6251 		else
6252 		{
6253 			if (m_params.extensionUse == EXTENSION_USE_NONE)
6254 			{
6255 				imageResolves.push_back(region.imageResolve);
6256 			}
6257 			else
6258 			{
6259 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6260 				imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(region.imageResolve));
6261 			}
6262 		}
6263 	}
6264 
6265 	const VkImageMemoryBarrier	imageBarriers[]		=
6266 	{
6267 		// source image
6268 		{
6269 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6270 			DE_NULL,									// const void*				pNext;
6271 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
6272 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
6273 			m_options == NO_OPTIONAL_OPERATION ?
6274 			m_params.dst.image.operationLayout :
6275 			m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
6276 			m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
6277 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6278 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6279 			sourceImage,								// VkImage					image;
6280 			{											// VkImageSubresourceRange	subresourceRange;
6281 				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
6282 				0u,									// deUint32				baseMipLevel;
6283 				1u,									// deUint32				mipLevels;
6284 				0u,									// deUint32				baseArraySlice;
6285 				sourceArraySize						// deUint32				arraySize;
6286 			}
6287 		},
6288 		// destination image
6289 		{
6290 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6291 			DE_NULL,									// const void*				pNext;
6292 			0u,											// VkAccessFlags			srcAccessMask;
6293 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
6294 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
6295 			m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
6296 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6297 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6298 			m_destination.get(),						// VkImage					image;
6299 			{											// VkImageSubresourceRange	subresourceRange;
6300 				getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
6301 				0u,									// deUint32				baseMipLevel;
6302 				1u,									// deUint32				mipLevels;
6303 				0u,									// deUint32				baseArraySlice;
6304 				getArraySize(m_params.dst.image)	// deUint32				arraySize;
6305 			}
6306 		},
6307 	};
6308 
6309 	const VkImageMemoryBarrier postImageBarrier =
6310 	{
6311 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
6312 		DE_NULL,								// const void*				pNext;
6313 		VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			srcAccessMask;
6314 		VK_ACCESS_HOST_READ_BIT,				// VkAccessFlags			dstAccessMask;
6315 		m_params.dst.image.operationLayout,		// VkImageLayout			oldLayout;
6316 		m_params.dst.image.operationLayout,		// VkImageLayout			newLayout;
6317 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
6318 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
6319 		m_destination.get(),					// VkImage					image;
6320 		{										// VkImageSubresourceRange	subresourceRange;
6321 			getAspectFlags(dstTcuFormat),		// VkImageAspectFlags		aspectMask;
6322 			0u,									// deUint32					baseMipLevel;
6323 			1u,									// deUint32					mipLevels;
6324 			0u,									// deUint32					baseArraySlice;
6325 			getArraySize(m_params.dst.image)	// deUint32					arraySize;
6326 		}
6327 	};
6328 
6329 	beginCommandBuffer(vk, *m_cmdBuffer);
6330 	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);
6331 
6332 	if (m_params.extensionUse == EXTENSION_USE_NONE)
6333 	{
6334 		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());
6335 	}
6336 #ifndef CTS_USES_VULKANSC
6337 	else
6338 	{
6339 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6340 		const VkResolveImageInfo2KHR ResolveImageInfo2KHR =
6341 		{
6342 			VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
6343 			DE_NULL,									// const void*					pNext;
6344 			sourceImage,								// VkImage						srcImage;
6345 			m_params.src.image.operationLayout,			// VkImageLayout				srcImageLayout;
6346 			m_destination.get(),						// VkImage						dstImage;
6347 			m_params.dst.image.operationLayout,			// VkImageLayout				dstImageLayout;
6348 			(deUint32)m_params.regions.size(),			// uint32_t						regionCount;
6349 			imageResolves2KHR.data()					// const  VkImageResolve2KHR*	pRegions;
6350 		};
6351 		vk.cmdResolveImage2(*m_cmdBuffer, &ResolveImageInfo2KHR);
6352 	}
6353 #endif // CTS_USES_VULKANSC
6354 
6355 	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);
6356 	endCommandBuffer(vk, *m_cmdBuffer);
6357 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
6358 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
6359 
6360 	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);
6361 
6362 	if (shouldVerifyIntermediateResults(m_options))
6363 	{
6364 		// Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
6365 		// resolving the image and giving every sample the same value.
6366 		const auto intermediateResult = checkIntermediateCopy();
6367 		if (intermediateResult.getCode() != QP_TEST_RESULT_PASS)
6368 			return intermediateResult;
6369 	}
6370 
6371 	return checkTestResult(resultTextureLevel->getAccess());
6372 }
6373 
checkTestResult(tcu::ConstPixelBufferAccess result)6374 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
6375 {
6376 	const tcu::ConstPixelBufferAccess	expected		= m_expectedTextureLevel[0]->getAccess();
6377 	const float							fuzzyThreshold	= 0.01f;
6378 
6379 	if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6380 	{
6381 		// Check that all the layers that have not been written to are solid white.
6382 		tcu::Vec4 expectedColor (1.0f, 1.0f, 1.0f, 1.0f);
6383 		for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image) - 1; ++arrayLayerNdx)
6384 		{
6385 			const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
6386 			if(resultSub.getPixel(0, 0) != expectedColor)
6387 				return tcu::TestStatus::fail("CopiesAndBlitting test. Layers image differs from initialized value.");
6388 		}
6389 
6390 		// Check that the layer that has been copied to is the same as the layer that has been copied from.
6391 		const tcu::ConstPixelBufferAccess	expectedSub	= getSubregion (expected, 0u, 0u, 2u, expected.getWidth(), expected.getHeight(), 1u);
6392 		const tcu::ConstPixelBufferAccess	resultSub	= getSubregion (result, 0u, 0u, 4u, result.getWidth(), result.getHeight(), 1u);
6393 		if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
6394 			return tcu::TestStatus::fail("CopiesAndBlitting test");
6395 	}
6396 	else
6397 	{
6398 		for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
6399 		{
6400 			const tcu::ConstPixelBufferAccess	expectedSub	= getSubregion (expected, 0u, 0u, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
6401 			const tcu::ConstPixelBufferAccess	resultSub	= getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
6402 			if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
6403 				return tcu::TestStatus::fail("CopiesAndBlitting test");
6404 		}
6405 	}
6406 
6407 	return tcu::TestStatus::pass("CopiesAndBlitting test");
6408 }
6409 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)6410 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
6411 {
6412 	DE_UNREF(mipLevel);
6413 
6414 	VkOffset3D srcOffset	= region.imageResolve.srcOffset;
6415 			srcOffset.z		= region.imageResolve.srcSubresource.baseArrayLayer;
6416 	VkOffset3D dstOffset	= region.imageResolve.dstOffset;
6417 			dstOffset.z		= region.imageResolve.dstSubresource.baseArrayLayer;
6418 	VkExtent3D extent		= region.imageResolve.extent;
6419 			extent.depth		= region.imageResolve.srcSubresource.layerCount;
6420 
6421 	const tcu::ConstPixelBufferAccess	srcSubRegion		= getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
6422 	// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
6423 	const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
6424 	const tcu::PixelBufferAccess		dstSubRegion		= getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
6425 
6426 	tcu::copy(dstSubRegion, srcSubRegion);
6427 }
6428 
checkIntermediateCopy(void)6429 tcu::TestStatus ResolveImageToImage::checkIntermediateCopy (void)
6430 {
6431 	const		auto&	vkd					= m_context.getDeviceInterface();
6432 	const		auto	device				= m_device;
6433 	const		auto	queue				= m_queue;
6434 	const		auto	queueIndex			= m_context.getUniversalQueueFamilyIndex();
6435 				auto&	alloc				= *m_allocator;
6436 	const		auto	currentLayout		= m_params.src.image.operationLayout;
6437 	const		auto	numDstLayers		= getArraySize(m_params.dst.image);
6438 	const		auto	numInputAttachments	= m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : numDstLayers + 1u; // For the source image.
6439 	constexpr	auto	numSets				= 2u; // 1 for the output buffer, 1 for the input attachments.
6440 	const		auto	fbWidth				= m_params.src.image.extent.width;
6441 	const		auto	fbHeight			= m_params.src.image.extent.height;
6442 
6443 	// Push constants.
6444 	const std::array<int, 3> pushConstantData =
6445 	{{
6446 		static_cast<int>(fbWidth),
6447 		static_cast<int>(fbHeight),
6448 		static_cast<int>(m_params.samples),
6449 	}};
6450 	const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
6451 
6452 	// Shader modules.
6453 	const auto vertexModule			= createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
6454 	const auto verificationModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("verify"), 0u);
6455 
6456 	// Descriptor sets.
6457 	DescriptorPoolBuilder poolBuilder;
6458 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
6459 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
6460 	const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
6461 
6462 	DescriptorSetLayoutBuilder layoutBuilderBuffer;
6463 	layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
6464 	const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
6465 
6466 	DescriptorSetLayoutBuilder layoutBuilderAttachments;
6467 	for (deUint32 i = 0u; i < numInputAttachments; ++i)
6468 		layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
6469 	const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
6470 
6471 	const auto descriptorSetBuffer		= makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
6472 	const auto descriptorSetAttachments	= makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
6473 
6474 	// Array with raw descriptor sets.
6475 	const std::array<VkDescriptorSet, numSets> descriptorSets =
6476 	{{
6477 		descriptorSetBuffer.get(),
6478 		descriptorSetAttachments.get(),
6479 	}};
6480 
6481 	// Pipeline layout.
6482 	const std::array<VkDescriptorSetLayout, numSets> setLayouts =
6483 	{{
6484 		outputBufferSetLayout.get(),
6485 		inputAttachmentsSetLayout.get(),
6486 	}};
6487 
6488 	const VkPushConstantRange pushConstantRange =
6489 	{
6490 		VK_SHADER_STAGE_FRAGMENT_BIT,	//	VkShaderStageFlags	stageFlags;
6491 		0u,								//	deUint32			offset;
6492 		pushConstantSize,				//	deUint32			size;
6493 	};
6494 
6495 	const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
6496 	{
6497 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	//	VkStructureType					sType;
6498 		nullptr,										//	const void*						pNext;
6499 		0u,												//	VkPipelineLayoutCreateFlags		flags;
6500 		static_cast<deUint32>(setLayouts.size()),		//	deUint32						setLayoutCount;
6501 		setLayouts.data(),								//	const VkDescriptorSetLayout*	pSetLayouts;
6502 		1u,												//	deUint32						pushConstantRangeCount;
6503 		&pushConstantRange,								//	const VkPushConstantRange*		pPushConstantRanges;
6504 	};
6505 
6506 	const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
6507 
6508 	// Render pass.
6509 	const VkAttachmentDescription commonAttachmentDescription =
6510 	{
6511 		0u,									//	VkAttachmentDescriptionFlags	flags;
6512 		m_params.src.image.format,			//	VkFormat						format;
6513 		m_params.samples,					//	VkSampleCountFlagBits			samples;
6514 		VK_ATTACHMENT_LOAD_OP_LOAD,			//	VkAttachmentLoadOp				loadOp;
6515 		VK_ATTACHMENT_STORE_OP_STORE,		//	VkAttachmentStoreOp				storeOp;
6516 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,	//	VkAttachmentLoadOp				stencilLoadOp;
6517 		VK_ATTACHMENT_STORE_OP_DONT_CARE,	//	VkAttachmentStoreOp				stencilStoreOp;
6518 		currentLayout,						//	VkImageLayout					initialLayout;
6519 		currentLayout,						//	VkImageLayout					finalLayout;
6520 	};
6521 	const std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
6522 
6523 	std::vector<VkAttachmentReference> inputAttachmentReferences;
6524 	inputAttachmentReferences.reserve(numInputAttachments);
6525 	for (deUint32 i = 0u; i < numInputAttachments; ++i)
6526 	{
6527 		const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
6528 		inputAttachmentReferences.push_back(reference);
6529 	}
6530 
6531 	const VkSubpassDescription subpassDescription =
6532 	{
6533 		0u,															//	VkSubpassDescriptionFlags		flags;
6534 		VK_PIPELINE_BIND_POINT_GRAPHICS,							//	VkPipelineBindPoint				pipelineBindPoint;
6535 		static_cast<deUint32>(inputAttachmentReferences.size()),	//	deUint32						inputAttachmentCount;
6536 		inputAttachmentReferences.data(),							//	const VkAttachmentReference*	pInputAttachments;
6537 		0u,															//	deUint32						colorAttachmentCount;
6538 		nullptr,													//	const VkAttachmentReference*	pColorAttachments;
6539 		nullptr,													//	const VkAttachmentReference*	pResolveAttachments;
6540 		nullptr,													//	const VkAttachmentReference*	pDepthStencilAttachment;
6541 		0u,															//	deUint32						preserveAttachmentCount;
6542 		nullptr,													//	const deUint32*					pPreserveAttachments;
6543 	};
6544 
6545 	const VkRenderPassCreateInfo renderPassInfo =
6546 	{
6547 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				//	VkStructureType					sType;
6548 		nullptr,												//	const void*						pNext;
6549 		0u,														//	VkRenderPassCreateFlags			flags;
6550 		static_cast<deUint32>(attachmentDescriptions.size()),	//	deUint32						attachmentCount;
6551 		attachmentDescriptions.data(),							//	const VkAttachmentDescription*	pAttachments;
6552 		1u,														//	deUint32						subpassCount;
6553 		&subpassDescription,									//	const VkSubpassDescription*		pSubpasses;
6554 		0u,														//	deUint32						dependencyCount;
6555 		nullptr,												//	const VkSubpassDependency*		pDependencies;
6556 	};
6557 
6558 	const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
6559 
6560 	// Framebuffer.
6561 	std::vector<Move<VkImageView>>	imageViews;
6562 	std::vector<VkImageView>		imageViewsRaw;
6563 
6564 
6565 	if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6566 	{
6567 		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)));
6568 		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)));
6569 	}
6570 	else
6571 	{
6572 		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)));
6573 		for (deUint32 i = 0u; i < numDstLayers; ++i)
6574 		{
6575 			const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
6576 			imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
6577 		}
6578 	}
6579 
6580 
6581 	imageViewsRaw.reserve(imageViews.size());
6582 	std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
6583 
6584 	const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
6585 
6586 	// Storage buffer.
6587 	const auto			bufferCount	= static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
6588 	const auto			bufferSize	= static_cast<VkDeviceSize>(bufferCount * sizeof(deInt32));
6589 	BufferWithMemory	buffer		(vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
6590 	auto&				bufferAlloc	= buffer.getAllocation();
6591 	void*				bufferData	= bufferAlloc.getHostPtr();
6592 
6593 	// Update descriptor sets.
6594 	DescriptorSetUpdateBuilder updater;
6595 
6596 	const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
6597 	updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
6598 
6599 	std::vector<VkDescriptorImageInfo> imageInfos;
6600 	imageInfos.reserve(imageViewsRaw.size());
6601 	for (size_t i = 0; i < imageViewsRaw.size(); ++i)
6602 		imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
6603 
6604 	for (size_t i = 0; i < imageInfos.size(); ++i)
6605 		updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
6606 
6607 	updater.update(vkd, device);
6608 
6609 	// Vertex buffer.
6610 	std::vector<tcu::Vec4> fullScreenQuad;
6611 	{
6612 		// Full screen quad so every framebuffer pixel and sample location is verified by the shader.
6613 		const tcu::Vec4 topLeft		(-1.0f, -1.0f, 0.0f, 1.0f);
6614 		const tcu::Vec4 topRight	( 1.0f, -1.0f, 0.0f, 1.0f);
6615 		const tcu::Vec4 bottomLeft	(-1.0f,  1.0f, 0.0f, 1.0f);
6616 		const tcu::Vec4 bottomRight	( 1.0f,  1.0f, 0.0f, 1.0f);
6617 
6618 		fullScreenQuad.reserve(6u);
6619 		fullScreenQuad.push_back(topLeft);
6620 		fullScreenQuad.push_back(topRight);
6621 		fullScreenQuad.push_back(bottomRight);
6622 		fullScreenQuad.push_back(topLeft);
6623 		fullScreenQuad.push_back(bottomRight);
6624 		fullScreenQuad.push_back(bottomLeft);
6625 	}
6626 
6627 	const auto				vertexBufferSize	= static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
6628 	const auto				vertexBufferInfo	= makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
6629 	const BufferWithMemory	vertexBuffer		(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
6630 	const auto				vertexBufferHandler	= vertexBuffer.get();
6631 	auto&					vertexBufferAlloc	= vertexBuffer.getAllocation();
6632 	void*					vertexBufferData	= vertexBufferAlloc.getHostPtr();
6633 	const VkDeviceSize		vertexBufferOffset	= 0ull;
6634 
6635 	deMemcpy(vertexBufferData, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
6636 	flushAlloc(vkd, device, vertexBufferAlloc);
6637 
6638 	// Graphics pipeline.
6639 	const std::vector<VkViewport>	viewports	(1, makeViewport(m_params.src.image.extent));
6640 	const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_params.src.image.extent));
6641 
6642 	const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
6643 	{
6644 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
6645 		nullptr,													// const void*								pNext;
6646 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
6647 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
6648 		VK_FALSE,													// VkBool32									sampleShadingEnable;
6649 		0.0f,														// float									minSampleShading;
6650 		nullptr,													// const VkSampleMask*						pSampleMask;
6651 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
6652 		VK_FALSE													// VkBool32									alphaToOneEnable;
6653 	};
6654 
6655 	const auto graphicsPipeline = makeGraphicsPipeline(
6656 		vkd,									// const DeviceInterface&                        vk
6657 		device,									// const VkDevice                                device
6658 		pipelineLayout.get(),					// const VkPipelineLayout                        pipelineLayout
6659 		vertexModule.get(),						// const VkShaderModule                          vertexShaderModule
6660 		DE_NULL,								// const VkShaderModule                          tessellationControlModule
6661 		DE_NULL,								// const VkShaderModule                          tessellationEvalModule
6662 		DE_NULL,								// const VkShaderModule                          geometryShaderModule
6663 		verificationModule.get(),				// const VkShaderModule                          fragmentShaderModule
6664 		renderPass.get(),						// const VkRenderPass                            renderPass
6665 		viewports,								// const std::vector<VkViewport>&                viewports
6666 		scissors,								// const std::vector<VkRect2D>&                  scissors
6667 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
6668 		0u,										// const deUint32                                subpass
6669 		0u,										// const deUint32                                patchControlPoints
6670 		nullptr,								// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
6671 		nullptr,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6672 		&multisampleStateParams);				// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
6673 
6674 	// Command buffer.
6675 	const auto cmdPool		= makeCommandPool(vkd, device, queueIndex);
6676 	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6677 	const auto cmdBuffer	= cmdBufferPtr.get();
6678 
6679 	// Make sure multisample copy data is available to the fragment shader.
6680 	const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
6681 
6682 	// Make sure verification buffer data is available on the host.
6683 	const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6684 
6685 	// Record and submit command buffer.
6686 	beginCommandBuffer(vkd, cmdBuffer);
6687 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
6688 	beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_params.src.image.extent));
6689 	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
6690 	vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBufferHandler, &vertexBufferOffset);
6691 	vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
6692 	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
6693 	vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
6694 	endRenderPass(vkd, cmdBuffer);
6695 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
6696 	endCommandBuffer(vkd, cmdBuffer);
6697 	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6698 	m_context.resetCommandPoolForVKSC(device, *cmdPool);
6699 
6700 	// Verify intermediate results.
6701 	invalidateAlloc(vkd, device, bufferAlloc);
6702 	std::vector<deInt32> outputFlags (bufferCount, 0);
6703 	deMemcpy(outputFlags.data(), bufferData, static_cast<size_t>(bufferSize));
6704 
6705 	auto& log = m_context.getTestContext().getLog();
6706 	log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
6707 
6708 	const auto sampleCount = static_cast<deUint32>(m_params.samples);
6709 
6710 	for (deUint32 x = 0u; x < fbWidth; ++x)
6711 	for (deUint32 y = 0u; y < fbHeight; ++y)
6712 	for (deUint32 s = 0u; s < sampleCount; ++s)
6713 	{
6714 		const auto index = (y * fbWidth + x) * sampleCount + s;
6715 		if (!outputFlags[index])
6716 		{
6717 			std::ostringstream msg;
6718 			msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s;
6719 			return tcu::TestStatus::fail(msg.str());
6720 		}
6721 	}
6722 
6723 	log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
6724 	return tcu::TestStatus::pass("Pass");
6725 }
6726 
copyMSImageToMSImage(deUint32 copyArraySize)6727 void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
6728 {
6729 	const bool						useTwoQueues		= m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER;
6730 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
6731 	const VkDevice					vkDevice			= m_device;
6732 	const VkQueue					queue				= useTwoQueues ? m_alternativeQueue : m_queue;
6733 	const VkCommandBuffer			commandBuffer		= useTwoQueues ? m_alternativeCmdBuffer.get() : m_cmdBuffer.get();
6734 	const VkCommandPool				commandPool			= useTwoQueues ? m_alternativeCmdPool.get() : m_cmdPool.get();
6735 	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
6736 	std::vector<VkImageCopy>		imageCopies;
6737 	std::vector<VkImageCopy2KHR>	imageCopies2KHR;
6738 
6739 	if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6740 	{
6741 		const VkImageSubresourceLayers	sourceSubresourceLayers	=
6742 		{
6743 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
6744 			0u,								// deUint32				mipLevel;
6745 			2u,								// deUint32				baseArrayLayer;
6746 			1u								// deUint32				layerCount;
6747 		};
6748 
6749 		const VkImageSubresourceLayers	destinationSubresourceLayers	=
6750 		{
6751 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;//getAspectFlags(dstTcuFormat)
6752 			0u,								// deUint32				mipLevel;
6753 			4u,								// deUint32				baseArrayLayer;
6754 			1u								// deUint32				layerCount;
6755 		};
6756 
6757 		const VkImageCopy				imageCopy	=
6758 		{
6759 			sourceSubresourceLayers,			// VkImageSubresourceLayers	srcSubresource;
6760 			{0, 0, 0},							// VkOffset3D				srcOffset;
6761 			destinationSubresourceLayers,		// VkImageSubresourceLayers	dstSubresource;
6762 			{0, 0, 0},							// VkOffset3D				dstOffset;
6763 			getExtent3D(m_params.src.image),	// VkExtent3D				extent;
6764 		};
6765 
6766 		if (m_params.extensionUse == EXTENSION_USE_NONE)
6767 		{
6768 			imageCopies.push_back(imageCopy);
6769 		}
6770 		else
6771 		{
6772 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6773 			imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6774 		}
6775 	}
6776 	else if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6777 	{
6778 		VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
6779 									getExtent3D(m_params.src.image).height / 2,
6780 									getExtent3D(m_params.src.image).depth};
6781 
6782 		for (CopyRegion region : m_params.regions)
6783 		{
6784 			const VkImageCopy				imageCopy	=
6785 			{
6786 				region.imageResolve.srcSubresource,		// VkImageSubresourceLayers	srcSubresource;
6787 				region.imageResolve.srcOffset,			// VkOffset3D				srcOffset;
6788 				region.imageResolve.dstSubresource,		// VkImageSubresourceLayers	dstSubresource;
6789 				region.imageResolve.dstOffset,			// VkOffset3D				dstOffset;
6790 				partialExtent,							// VkExtent3D				extent;
6791 			};
6792 
6793 			if (m_params.extensionUse == EXTENSION_USE_NONE)
6794 			{
6795 				imageCopies.push_back(imageCopy);
6796 			}
6797 			else
6798 			{
6799 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6800 				imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6801 			}
6802 		}
6803 	}
6804 	else
6805 	{
6806 		for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
6807 		{
6808 			const VkImageSubresourceLayers	sourceSubresourceLayers	=
6809 			{
6810 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
6811 				0u,								// deUint32				mipLevel;
6812 				0u,								// deUint32				baseArrayLayer;
6813 				1u								// deUint32				layerCount;
6814 			};
6815 
6816 			const VkImageSubresourceLayers	destinationSubresourceLayers	=
6817 			{
6818 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;//getAspectFlags(dstTcuFormat)
6819 				0u,								// deUint32				mipLevel;
6820 				layerNdx,						// deUint32				baseArrayLayer;
6821 				1u								// deUint32				layerCount;
6822 			};
6823 
6824 			const VkImageCopy				imageCopy	=
6825 			{
6826 				sourceSubresourceLayers,			// VkImageSubresourceLayers	srcSubresource;
6827 				{0, 0, 0},							// VkOffset3D				srcOffset;
6828 				destinationSubresourceLayers,		// VkImageSubresourceLayers	dstSubresource;
6829 				{0, 0, 0},							// VkOffset3D				dstOffset;
6830 				getExtent3D(m_params.src.image),	// VkExtent3D				extent;
6831 			};
6832 
6833 			if (m_params.extensionUse == EXTENSION_USE_NONE)
6834 			{
6835 				imageCopies.push_back(imageCopy);
6836 			}
6837 			else
6838 			{
6839 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6840 				imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6841 			}
6842 		}
6843 	}
6844 
6845 	VkImageSubresourceRange subresourceRange = {
6846 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask
6847 			0u,								// deUint32				baseMipLevel
6848 			1u,								// deUint32				mipLevels
6849 			0u,								// deUint32				baseArraySlice
6850 			copyArraySize					// deUint32				arraySize
6851 	};
6852 
6853 	// m_multisampledImage
6854 	const VkImageMemoryBarrier m_multisampledImageBarrier =
6855 	{
6856 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6857 		DE_NULL,									// const void*				pNext;
6858 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
6859 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
6860 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
6861 		m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
6862 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6863 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6864 		m_multisampledImage.get(),					// VkImage					image;
6865 		{											// VkImageSubresourceRange	subresourceRange;
6866 			getAspectFlags(srcTcuFormat),			// VkImageAspectFlags	aspectMask;
6867 			0u,										// deUint32				baseMipLevel;
6868 			1u,										// deUint32				mipLevels;
6869 			0u,										// deUint32				baseArraySlice;
6870 			getArraySize(m_params.src.image)		// deUint32				arraySize;
6871 		}
6872 	};
6873 	// m_multisampledCopyImage
6874 	VkImageMemoryBarrier m_multisampledCopyImageBarrier =
6875 	{
6876 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6877 		DE_NULL,									// const void*				pNext;
6878 		0,											// VkAccessFlags			srcAccessMask;
6879 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
6880 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
6881 		m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
6882 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6883 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6884 		m_multisampledCopyImage.get(),				// VkImage					image;
6885 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
6886 	};
6887 
6888 	// m_multisampledCopyNoCabImage (no USAGE_COLOR_ATTACHMENT_BIT)
6889 	const VkImageMemoryBarrier		m_multisampledCopyNoCabImageBarrier	=
6890 	{
6891 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6892 		DE_NULL,									// const void*				pNext;
6893 		0,											// VkAccessFlags			srcAccessMask;
6894 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
6895 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
6896 		m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
6897 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6898 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6899 		m_multisampledCopyNoCabImage.get(),			// VkImage					image;
6900 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
6901 	};
6902 
6903 	// destination image
6904 	const VkImageMemoryBarrier		multisampledCopyImagePostBarrier	=
6905 	{
6906 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6907 		DE_NULL,									// const void*				pNext;
6908 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
6909 		VK_ACCESS_MEMORY_READ_BIT,					// VkAccessFlags			dstAccessMask;
6910 		m_params.dst.image.operationLayout,			// VkImageLayout			oldLayout;
6911 		m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
6912 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6913 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6914 		m_multisampledCopyImage.get(),				// VkImage					image;
6915 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
6916 	};
6917 
6918 	// destination image (no USAGE_COLOR_ATTACHMENT_BIT)
6919 	const VkImageMemoryBarrier		betweenCopyImageBarrier				=
6920 	{
6921 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6922 		DE_NULL,									// const void*				pNext;
6923 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
6924 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
6925 		m_params.dst.image.operationLayout,			// VkImageLayout			oldLayout;
6926 		m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
6927 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6928 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6929 		m_multisampledCopyNoCabImage.get(),			// VkImage					image;
6930 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
6931 	};
6932 
6933 	// Queue family ownership transfer. Move ownership of the m_multisampledImage and m_multisampledImageCopy to the compute/transfer queue.
6934 	if (useTwoQueues)
6935 	{
6936 		// Release ownership from graphics queue.
6937 		{
6938 			std::vector<VkImageMemoryBarrier> barriers;
6939 			barriers.reserve(2);
6940 
6941 			// Barrier for m_multisampledImage
6942 			VkImageMemoryBarrier releaseBarrier = m_multisampledImageBarrier;
6943 			releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
6944 			releaseBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6945 			releaseBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6946 			barriers.push_back(releaseBarrier);
6947 
6948 			// Barrier for m_multisampledCopyImage
6949 			releaseBarrier = m_multisampledCopyImageBarrier;
6950 			releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
6951 			releaseBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6952 			releaseBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6953 			barriers.push_back(releaseBarrier);
6954 
6955 			beginCommandBuffer(vk, m_cmdBuffer.get());
6956 			vk.cmdPipelineBarrier(m_cmdBuffer.get(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, (uint32_t)barriers.size(), barriers.data());
6957 			endCommandBuffer(vk, m_cmdBuffer.get());
6958 			submitCommandsAndWait(vk, vkDevice, m_queue, m_cmdBuffer.get());
6959 			m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
6960 		}
6961 
6962 		// Acquire ownership to compute / transfer queue.
6963 		{
6964 			std::vector<VkImageMemoryBarrier> barriers;
6965 			barriers.reserve(2);
6966 
6967 			// Barrier for m_multisampledImage
6968 			VkImageMemoryBarrier acquireBarrier = m_multisampledImageBarrier;
6969 			acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
6970 			acquireBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6971 			acquireBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6972 			barriers.push_back(acquireBarrier);
6973 
6974 			// Barrier for m_multisampledImage
6975 			acquireBarrier = m_multisampledCopyImageBarrier;
6976 			acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
6977 			acquireBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6978 			acquireBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6979 			barriers.push_back(acquireBarrier);
6980 
6981 			beginCommandBuffer(vk, commandBuffer);
6982 			vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, (uint32_t)barriers.size(), barriers.data());
6983 			endCommandBuffer(vk, commandBuffer);
6984 			submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
6985 			m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
6986 		}
6987 
6988 		beginCommandBuffer(vk, commandBuffer);
6989 	}
6990 	else
6991 	{
6992 		std::vector<VkImageMemoryBarrier> imageBarriers;
6993 
6994 		imageBarriers.push_back(m_multisampledImageBarrier);
6995 		// Only use one barrier if no options have been given.
6996 		if (m_options != NO_OPTIONAL_OPERATION)
6997 		{
6998 			imageBarriers.push_back(m_multisampledCopyImageBarrier);
6999 			// Add the third barrier if option is as below.
7000 			if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7001 				imageBarriers.push_back(m_multisampledCopyNoCabImageBarrier);
7002 		}
7003 
7004 		beginCommandBuffer(vk, commandBuffer);
7005 		vk.cmdPipelineBarrier(commandBuffer, 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());
7006 	}
7007 
7008 	if (m_params.extensionUse == EXTENSION_USE_NONE)
7009 	{
7010 		if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7011 		{
7012 			vk.cmdCopyImage(commandBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout, m_multisampledCopyNoCabImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
7013 			vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &betweenCopyImageBarrier);
7014 			vk.cmdCopyImage(commandBuffer, m_multisampledCopyNoCabImage.get(), m_params.src.image.operationLayout, m_multisampledCopyImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
7015 		}
7016 		else
7017 		{
7018 			vk.cmdCopyImage(commandBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout, m_multisampledCopyImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
7019 		}
7020 	}
7021 #ifndef CTS_USES_VULKANSC
7022 	else
7023 	{
7024 		if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7025 		{
7026 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7027 			const VkCopyImageInfo2KHR copyImageInfo2KHR =
7028 			{
7029 				VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
7030 				DE_NULL,									// const void*				pNext;
7031 				m_multisampledImage.get(),					// VkImage					srcImage;
7032 				m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
7033 				m_multisampledCopyNoCabImage.get(),			// VkImage					dstImage;
7034 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			dstImageLayout;
7035 				(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
7036 				imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
7037 			};
7038 			const VkCopyImageInfo2KHR copyImageInfo2KHRCopy =
7039 			{
7040 				VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
7041 				DE_NULL,									// const void*				pNext;
7042 				m_multisampledCopyNoCabImage.get(),			// VkImage					srcImage;
7043 				vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,	// VkImageLayout			srcImageLayout;
7044 				m_multisampledCopyImage.get(),				// VkImage					dstImage;
7045 				m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
7046 				(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
7047 				imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
7048 			};
7049 
7050 			vk.cmdCopyImage2(commandBuffer, &copyImageInfo2KHR);
7051 			vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &betweenCopyImageBarrier);
7052 			vk.cmdCopyImage2(commandBuffer, &copyImageInfo2KHRCopy);
7053 		}
7054 		else
7055 		{
7056 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7057 			const VkCopyImageInfo2KHR copyImageInfo2KHR =
7058 			{
7059 				VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
7060 				DE_NULL,									// const void*				pNext;
7061 				m_multisampledImage.get(),					// VkImage					srcImage;
7062 				m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
7063 				m_multisampledCopyImage.get(),				// VkImage					dstImage;
7064 				m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
7065 				(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
7066 				imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
7067 			};
7068 			vk.cmdCopyImage2(commandBuffer, &copyImageInfo2KHR);
7069 		}
7070 	}
7071 #endif // CTS_USES_VULKANSC
7072 
7073 	if (useTwoQueues)
7074 	{
7075 		endCommandBuffer(vk, commandBuffer);
7076 		submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7077 		m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7078 
7079 		VkImageMemoryBarrier srcImageBarrier = makeImageMemoryBarrier(
7080 				0u,
7081 				0u,
7082 				m_params.src.image.operationLayout,
7083 				m_params.src.image.operationLayout,
7084 				m_multisampledImage.get(),
7085 				m_multisampledImageBarrier.subresourceRange,
7086 				m_alternativeQueueFamilyIndex,
7087 				m_context.getUniversalQueueFamilyIndex());
7088 		// Release ownership from compute / transfer queue.
7089 		{
7090 			std::vector<VkImageMemoryBarrier> barriers;
7091 			barriers.reserve(2);
7092 
7093 			VkImageMemoryBarrier releaseBarrier = multisampledCopyImagePostBarrier;
7094 			releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7095 			releaseBarrier.srcQueueFamilyIndex = m_alternativeQueueFamilyIndex;
7096 			releaseBarrier.dstQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7097 			barriers.push_back(releaseBarrier);
7098 
7099 			releaseBarrier = srcImageBarrier;
7100 			releaseBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
7101 			releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7102 			barriers.push_back(releaseBarrier);
7103 
7104 			beginCommandBuffer(vk, commandBuffer);
7105 			vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, (uint32_t)barriers.size(), barriers.data());
7106 			endCommandBuffer(vk, commandBuffer);
7107 			submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7108 			m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7109 		}
7110 
7111 		// Acquire ownership to graphics queue.
7112 		{
7113 			std::vector<VkImageMemoryBarrier> barriers;
7114 			barriers.reserve(2);
7115 
7116 			VkImageMemoryBarrier acquireBarrier = multisampledCopyImagePostBarrier;
7117 			acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7118 			acquireBarrier.srcQueueFamilyIndex = m_alternativeQueueFamilyIndex;
7119 			acquireBarrier.dstQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7120 			barriers.push_back(acquireBarrier);
7121 
7122 			acquireBarrier = srcImageBarrier;
7123 			acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7124 			acquireBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
7125 			barriers.push_back(acquireBarrier);
7126 
7127 			beginCommandBuffer(vk, m_cmdBuffer.get());
7128 			vk.cmdPipelineBarrier(m_cmdBuffer.get(), VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,  0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, (uint32_t)barriers.size(), barriers.data());
7129 			endCommandBuffer(vk, m_cmdBuffer.get());
7130 			submitCommandsAndWait(vk, vkDevice, m_queue, m_cmdBuffer.get());
7131 			m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
7132 		}
7133 	}
7134 	else
7135 	{
7136 		vk.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &multisampledCopyImagePostBarrier);
7137 		endCommandBuffer(vk, commandBuffer);
7138 		submitCommandsAndWait (vk, vkDevice, queue, commandBuffer);
7139 		m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7140 	}
7141 }
7142 
7143 class ResolveImageToImageTestCase : public vkt::TestCase
7144 {
7145 public:
ResolveImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params,const ResolveImageToImageOptions options=NO_OPTIONAL_OPERATION)7146 							ResolveImageToImageTestCase	(tcu::TestContext&					testCtx,
7147 														 const std::string&					name,
7148 														 const std::string&					description,
7149 														 const TestParams					params,
7150 														 const ResolveImageToImageOptions	options = NO_OPTIONAL_OPERATION)
7151 								: vkt::TestCase	(testCtx, name, description)
7152 								, m_params		(params)
7153 								, m_options		(options)
7154 	{}
7155 
7156 							virtual	void			initPrograms				(SourceCollections&		programCollection) const;
7157 
createInstance(Context & context) const7158 	virtual TestInstance*	createInstance				(Context&				context) const
7159 	{
7160 		return new ResolveImageToImage(context, m_params, m_options);
7161 	}
7162 
checkSupport(Context & context) const7163 	virtual void			checkSupport				(Context&				context) const
7164 	{
7165 		const VkSampleCountFlagBits	rasterizationSamples = m_params.samples;
7166 
7167 		// Intermediate result check uses fragmentStoresAndAtomics.
7168 		if (ResolveImageToImage::shouldVerifyIntermediateResults(m_options) && !context.getDeviceFeatures().fragmentStoresAndAtomics)
7169 		{
7170 			TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
7171 		}
7172 
7173 		if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
7174 			throw tcu::NotSupportedError("Unsupported number of rasterization samples");
7175 
7176 		VkImageFormatProperties properties;
7177 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
7178 																					m_params.src.image.format,
7179 																					m_params.src.image.imageType,
7180 																					VK_IMAGE_TILING_OPTIMAL,
7181 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
7182 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
7183 			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
7184 																					m_params.dst.image.format,
7185 																					m_params.dst.image.imageType,
7186 																					VK_IMAGE_TILING_OPTIMAL,
7187 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
7188 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
7189 		{
7190 			TCU_THROW(NotSupportedError, "Format not supported");
7191 		}
7192 
7193 		if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)	&&
7194 			(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
7195 		{
7196 			TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
7197 		}
7198 
7199 		// Find at least one queue family that supports compute queue but does NOT support graphics queue.
7200 		if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE)
7201 		{
7202 			bool foundQueue = false;
7203 			const std::vector<VkQueueFamilyProperties> queueFamilies = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
7204 			for (const auto& queueFamily : queueFamilies)
7205 			{
7206 				if (queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
7207 				{
7208 					foundQueue = true;
7209 					break;
7210 				}
7211 			}
7212 			if (!foundQueue)
7213 				TCU_THROW(NotSupportedError, "No queue family found that only supports compute queue.");
7214 		}
7215 
7216 		// Find at least one queue family that supports transfer queue but does NOT support graphics and compute queue.
7217 		if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
7218 		{
7219 			bool foundQueue = false;
7220 			const std::vector<VkQueueFamilyProperties> queueFamilies = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
7221 			for (const auto& queueFamily : queueFamilies)
7222 			{
7223 				if (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT && !(queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT) && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
7224 				{
7225 					foundQueue = true;
7226 					break;
7227 				}
7228 			}
7229 			if (!foundQueue)
7230 				TCU_THROW(NotSupportedError, "No queue family found that only supports transfer queue.");
7231 		}
7232 	}
7233 
7234 private:
7235 	TestParams							m_params;
7236 	const ResolveImageToImageOptions	m_options;
7237 };
7238 
initPrograms(SourceCollections & programCollection) const7239 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
7240 {
7241 	programCollection.glslSources.add("vert") << glu::VertexSource(
7242 		"#version 310 es\n"
7243 		"layout (location = 0) in highp vec4 a_position;\n"
7244 		"void main()\n"
7245 		"{\n"
7246 		"	gl_Position = a_position;\n"
7247 		"}\n");
7248 
7249 
7250 	programCollection.glslSources.add("frag") << glu::FragmentSource(
7251 		"#version 310 es\n"
7252 		"layout (location = 0) out highp vec4 o_color;\n"
7253 		"void main()\n"
7254 		"{\n"
7255 		"	o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
7256 		"}\n");
7257 
7258 	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 || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
7259 	{
7260 		// The shader verifies all layers in the copied image are the same as the source image.
7261 		// This needs an image view per layer in the copied image.
7262 		// Set 0 contains the output buffer.
7263 		// Set 1 contains the input attachments.
7264 
7265 		std::ostringstream verificationShader;
7266 
7267 		verificationShader
7268 			<< "#version 450\n"
7269 			<< "\n"
7270 			<< "layout (push_constant, std430) uniform PushConstants {\n"
7271 			<< "    int width;\n"
7272 			<< "    int height;\n"
7273 			<< "    int samples;\n"
7274 			<< "};\n"
7275 			<< "layout (set=0, binding=0) buffer VerificationResults {\n"
7276 			<< "    int verificationFlags[];\n"
7277 			<< "};\n"
7278 			<< "layout (input_attachment_index=0, set=1, binding=0) uniform subpassInputMS attachment0;\n"
7279 			;
7280 
7281 		const auto dstLayers = getArraySize(m_params.dst.image);
7282 
7283 		if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7284 		{
7285 			verificationShader << "layout (input_attachment_index=1, set=1, binding=1) uniform subpassInputMS attachment1;\n";
7286 		}
7287 		else
7288 		{
7289 			for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7290 			{
7291 				const auto i = layerNdx + 1u;
7292 				verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
7293 			}
7294 		}
7295 
7296 		// Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
7297 		// created with a single sample.
7298 		verificationShader
7299 			<< "\n"
7300 			<< "void main() {\n"
7301 			<< "    for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
7302 			<< "        vec4 orig = subpassLoad(attachment0, sampleID);\n"
7303 			;
7304 
7305 		std::ostringstream testCondition;
7306 		if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7307 		{
7308 			verificationShader << "        vec4 copy = subpassLoad(attachment1, sampleID);\n";
7309 			testCondition << "orig == copy";
7310 		}
7311 		else
7312 		{
7313 			for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7314 			{
7315 				const auto i = layerNdx + 1u;
7316 				verificationShader << "        vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
7317 			}
7318 
7319 			for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7320 			{
7321 				const auto i = layerNdx + 1u;
7322 				testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
7323 			}
7324 		}
7325 
7326 		verificationShader
7327 			<< "\n"
7328 			<< "        ivec3 coords  = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
7329 			<< "        int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
7330 			<< "\n"
7331 			<< "        verificationFlags[bufferPos] = ((" << testCondition.str() << ") ? 1 : 0); \n"
7332 			<< "    }\n"
7333 			<< "}\n"
7334 			;
7335 
7336 		programCollection.glslSources.add("verify") << glu::FragmentSource(verificationShader.str());
7337 	}
7338 }
7339 
7340 class DepthStencilMSAA : public vkt::TestInstance
7341 {
7342 public:
7343 	enum CopyOptions				{COPY_WHOLE_IMAGE, COPY_ARRAY_TO_ARRAY, COPY_PARTIAL};
7344 
7345 	struct TestParameters
7346 	{
7347 		AllocationKind				allocationKind;
7348 		ExtensionUse				extensionUse;
7349 		CopyOptions					copyOptions;
7350 		VkSampleCountFlagBits		samples;
7351 		VkImageLayout				srcImageLayout;
7352 		VkImageLayout				dstImageLayout;
7353 		VkFormat					imageFormat;
7354 		VkImageAspectFlags			copyAspect;
7355 		deBool						imageOffset;
7356 	};
7357 
7358 									DepthStencilMSAA			(Context&			context,
7359 																 TestParameters		testParameters);
7360 	tcu::TestStatus					iterate						(void) override;
7361 protected:
7362 	tcu::TestStatus					checkCopyResults			(VkCommandBuffer				cmdBuffer,
7363 																 const VkImageAspectFlagBits&	aspectToVerify,
7364 																 VkImage						srcImage,
7365 																 VkImage						dstImage);
7366 
7367 private:
7368 	// Returns image aspects used in the copy regions.
getUsedImageAspects()7369 	VkImageAspectFlags				getUsedImageAspects ()
7370 	{
7371 		auto aspectFlags = (VkImageAspectFlags)0;
7372 		for (const auto &region : m_regions)
7373 		{
7374 			aspectFlags |= region.imageCopy.srcSubresource.aspectMask;
7375 		}
7376 		return aspectFlags;
7377 	}
7378 
7379 	ImageParms						m_srcImage;
7380 	ImageParms						m_dstImage;
7381 	std::vector<CopyRegion>			m_regions;
7382 	const TestParameters			m_params;
7383 	const float						m_clearValue = 0.0f;
7384 };
7385 
DepthStencilMSAA(Context & context,TestParameters testParameters)7386 DepthStencilMSAA::DepthStencilMSAA (Context& context, TestParameters testParameters)
7387 	: vkt::TestInstance(context)
7388 	, m_params(testParameters)
7389 {
7390 	// params.src.image is the parameters used to create the copy source image
7391 	m_srcImage.imageType			= VK_IMAGE_TYPE_2D;
7392 	m_srcImage.format				= testParameters.imageFormat;
7393 	m_srcImage.extent				= defaultExtent;
7394 	m_srcImage.tiling				= VK_IMAGE_TILING_OPTIMAL;
7395 	m_srcImage.operationLayout		= testParameters.srcImageLayout;
7396 	m_srcImage.createFlags			= 0u;
7397 
7398 	// params.src.image is the parameters used to create the copy destination image
7399 	m_dstImage.imageType			= VK_IMAGE_TYPE_2D;
7400 	m_dstImage.format				= testParameters.imageFormat;
7401 	m_dstImage.extent				= defaultExtent;
7402 	m_dstImage.tiling				= VK_IMAGE_TILING_OPTIMAL;
7403 	m_dstImage.operationLayout		= testParameters.dstImageLayout;
7404 	m_dstImage.createFlags			= 0u;
7405 
7406 	const VkImageSubresourceLayers depthSubresourceLayers =
7407 	{
7408 		VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
7409 		0u,							// uint32_t				mipLevel;
7410 		0u,							// uint32_t				baseArrayLayer;
7411 		1u							// uint32_t				layerCount;
7412 	};
7413 
7414 	const VkImageSubresourceLayers stencilSubresourceLayers =
7415 	{
7416 		VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
7417 		0u,								// uint32_t				mipLevel;
7418 		0u,								// uint32_t				baseArrayLayer;
7419 		1u								// uint32_t				layerCount;
7420 	};
7421 
7422 	VkImageCopy				depthCopy	=
7423 	{
7424 		depthSubresourceLayers,	// VkImageSubresourceLayers	srcSubresource;
7425 		{0, 0, 0},				// VkOffset3D				srcOffset;
7426 		depthSubresourceLayers,	// VkImageSubresourceLayers	dstSubresource;
7427 		{0, 0, 0},				// VkOffset3D				dstOffset;
7428 		defaultExtent,			// VkExtent3D				extent;
7429 	};
7430 
7431 	VkImageCopy				stencilCopy	=
7432 	{
7433 		stencilSubresourceLayers,	// VkImageSubresourceLayers	srcSubresource;
7434 		{0, 0, 0},					// VkOffset3D				srcOffset;
7435 		stencilSubresourceLayers,	// VkImageSubresourceLayers	dstSubresource;
7436 		{0, 0, 0},					// VkOffset3D				dstOffset;
7437 		defaultExtent,				// VkExtent3D				extent;
7438 	};
7439 
7440 	if (testParameters.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY)
7441 	{
7442 		m_srcImage.extent.depth						= 5u;
7443 		depthCopy.srcSubresource.baseArrayLayer		= 2u;
7444 		depthCopy.dstSubresource.baseArrayLayer		= 3u;
7445 		stencilCopy.srcSubresource.baseArrayLayer	= 2u;
7446 		stencilCopy.dstSubresource.baseArrayLayer	= 3u;
7447 	}
7448 
7449 	CopyRegion					depthCopyRegion;
7450 	CopyRegion					stencilCopyRegion;
7451 	depthCopyRegion.imageCopy	= depthCopy;
7452 	stencilCopyRegion.imageCopy	= stencilCopy;
7453 
7454 	std::vector<CopyRegion>		depthRegions;
7455 	std::vector<CopyRegion>		stencilRegions;
7456 
7457 	if (testParameters.copyOptions == DepthStencilMSAA::COPY_PARTIAL)
7458 	{
7459 		if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
7460 		{
7461 			depthCopyRegion.imageCopy.extent		= {defaultHalfSize, defaultHalfSize, 1};
7462 			// Copy region from bottom right to bottom left
7463 			depthCopyRegion.imageCopy.srcOffset		= {defaultHalfSize, defaultHalfSize, 0};
7464 			depthCopyRegion.imageCopy.dstOffset		= {0, defaultHalfSize, 0};
7465 			depthRegions.push_back(depthCopyRegion);
7466 			// Copy region from top right to bottom right
7467 			depthCopyRegion.imageCopy.srcOffset		= {defaultHalfSize, 0, 0};
7468 			depthCopyRegion.imageCopy.dstOffset		= {defaultHalfSize, defaultHalfSize, 0};
7469 			depthRegions.push_back(depthCopyRegion);
7470 		}
7471 		if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
7472 		{
7473 			stencilCopyRegion.imageCopy.extent		= {defaultHalfSize, defaultHalfSize, 1};
7474 			// Copy region from bottom right to bottom left
7475 			stencilCopyRegion.imageCopy.srcOffset	= {defaultHalfSize, defaultHalfSize, 0};
7476 			stencilCopyRegion.imageCopy.dstOffset	= {0, defaultHalfSize, 0};
7477 			stencilRegions.push_back(stencilCopyRegion);
7478 			// Copy region from top right to bottom right
7479 			stencilCopyRegion.imageCopy.srcOffset	= {defaultHalfSize, 0, 0};
7480 			stencilCopyRegion.imageCopy.dstOffset	= {defaultHalfSize, defaultHalfSize, 0};
7481 			stencilRegions.push_back(stencilCopyRegion);
7482 		}
7483 	}
7484 	else
7485 	{
7486 		// Copy the default region (full image)
7487 		if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
7488 		{
7489 			depthRegions.push_back(depthCopyRegion);
7490 		}
7491 		if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
7492 		{
7493 			stencilRegions.push_back(stencilCopyRegion);
7494 		}
7495 	}
7496 
7497 	if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
7498 	{
7499 		m_regions.insert(m_regions.end(), depthRegions.begin(), depthRegions.end());
7500 	}
7501 
7502 	if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
7503 	{
7504 		m_regions.insert(m_regions.end(), stencilRegions.begin(), stencilRegions.end());
7505 	}
7506 }
7507 
iterate(void)7508 tcu::TestStatus DepthStencilMSAA::iterate (void)
7509 {
7510 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
7511 	const InstanceInterface&		vki					= m_context.getInstanceInterface();
7512 	const VkDevice					vkDevice			= m_context.getDevice();
7513 	const VkPhysicalDevice			vkPhysDevice		= m_context.getPhysicalDevice();
7514 	const VkQueue					queue				= m_context.getUniversalQueue();
7515 	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
7516 	Allocator&						memAlloc			= m_context.getDefaultAllocator();
7517 	Move<VkCommandPool>				cmdPool				= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
7518 	Move<VkCommandBuffer>			cmdBuffer			= allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
7519 
7520 	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_srcImage.format);
7521 	const tcu::TextureFormat		dstTcuFormat		= mapVkFormat(m_dstImage.format);
7522 	VkImageAspectFlags				aspectFlags			= getUsedImageAspects();
7523 	deUint32						sourceArraySize		= getArraySize(m_srcImage);
7524 
7525 	Move<VkImage>					srcImage;
7526 	de::MovePtr<Allocation>			srcImageAlloc;
7527 	Move<VkImage>					dstImage;
7528 	de::MovePtr<Allocation>			dstImageAlloc;
7529 
7530 	// 1. Create the images and draw a triangle to the source image.
7531 	{
7532 		const VkComponentMapping		componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
7533 		Move<VkShaderModule>			vertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
7534 		Move<VkShaderModule>			fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
7535 		std::vector<tcu::Vec4>			vertices;
7536 		Move<VkBuffer>					vertexBuffer;
7537 		de::MovePtr<Allocation>			vertexBufferAlloc;
7538 		Move<VkPipelineLayout>			pipelineLayout;
7539 		Move<VkPipeline>				graphicsPipeline;
7540 		Move<VkRenderPass>				renderPass;
7541 
7542 		// Create multisampled depth/stencil image (srcImage) and the copy destination image (dstImage).
7543 		{
7544 			VkImageCreateInfo multiSampledImageParams =
7545 			{
7546 				VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
7547 				DE_NULL,										// const void*				pNext;
7548 				getCreateFlags(m_srcImage),						// VkImageCreateFlags		flags;
7549 				m_srcImage.imageType,							// VkImageType				imageType;
7550 				m_srcImage.format,								// VkFormat					format;
7551 				getExtent3D(m_srcImage),						// VkExtent3D				extent;
7552 				1u,												// deUint32					mipLevels;
7553 				getArraySize(m_srcImage),						// deUint32					arrayLayers;
7554 				m_params.samples,								// VkSampleCountFlagBits	samples;
7555 				VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
7556 				VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT		// VkImageUsageFlags		usage;
7557 					| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
7558 					| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
7559 					| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
7560 				VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
7561 				1u,												// deUint32					queueFamilyIndexCount;
7562 				&queueFamilyIndex,								// const deUint32*			pQueueFamilyIndices;
7563 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
7564 			};
7565 
7566 			srcImage		= createImage(vk, vkDevice, &multiSampledImageParams);
7567 
7568 			VkMemoryRequirements	req		= getImageMemoryRequirements(vk, vkDevice, *srcImage);
7569 			deUint32				offset	= m_params.imageOffset ? static_cast<deUint32>(req.alignment) : 0;
7570 
7571 			srcImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, srcImage.get(), MemoryRequirement::Any, memAlloc,
7572 											 m_params.allocationKind, offset);
7573 			VK_CHECK(vk.bindImageMemory(vkDevice, srcImage.get(), srcImageAlloc->getMemory(), srcImageAlloc->getOffset() + offset));
7574 
7575 			dstImage		= createImage(vk, vkDevice, &multiSampledImageParams);
7576 			dstImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, dstImage.get(), MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
7577 			VK_CHECK(vk.bindImageMemory(vkDevice, dstImage.get(), dstImageAlloc->getMemory(), dstImageAlloc->getOffset()));
7578 		}
7579 
7580 		// Create render pass.
7581 		{
7582 			const VkImageLayout				initialLayout			= m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
7583 			const VkAttachmentDescription	attachmentDescription	=
7584 			{
7585 				0u,													// VkAttachmentDescriptionFlags		flags
7586 				m_srcImage.format,									// VkFormat							format
7587 				m_params.samples,									// VkSampleCountFlagBits			samples
7588 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp
7589 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp
7590 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				stencilLoadOp
7591 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				stencilStoreOp
7592 				initialLayout,										// VkImageLayout					initialLayout
7593 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout
7594 			};
7595 
7596 			const VkAttachmentReference		attachmentReference		=
7597 			{
7598 				0u,													// deUint32			attachment
7599 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
7600 			};
7601 
7602 			const VkSubpassDescription		subpassDescription		=
7603 			{
7604 				0u,									// VkSubpassDescriptionFlags	flags
7605 				VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint			pipelineBindPoint
7606 				0u,									// deUint32						inputAttachmentCount
7607 				DE_NULL,							// const VkAttachmentReference*	pInputAttachments
7608 				0u,									// deUint32						colorAttachmentCount
7609 				DE_NULL,							// const VkAttachmentReference*	pColorAttachments
7610 				DE_NULL,							// const VkAttachmentReference*	pResolveAttachments
7611 				&attachmentReference,				// const VkAttachmentReference*	pDepthStencilAttachment
7612 				0u,									// deUint32						preserveAttachmentCount
7613 				DE_NULL								// const VkAttachmentReference*	pPreserveAttachments
7614 			};
7615 
7616 			const VkRenderPassCreateInfo	renderPassParams		=
7617 			{
7618 				VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType					sType;
7619 				DE_NULL,									// const void*						pNext;
7620 				0u,											// VkRenderPassCreateFlags			flags;
7621 				1u,											// deUint32							attachmentCount;
7622 				&attachmentDescription,						// const VkAttachmentDescription*	pAttachments;
7623 				1u,											// deUint32							subpassCount;
7624 				&subpassDescription,						// const VkSubpassDescription*		pSubpasses;
7625 				0u,											// deUint32							dependencyCount;
7626 				DE_NULL										// const VkSubpassDependency*		pDependencies;
7627 			};
7628 
7629 			renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
7630 		}
7631 
7632 		// Create pipeline layout
7633 		{
7634 			const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
7635 			{
7636 				VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType					sType;
7637 				DE_NULL,										// const void*						pNext;
7638 				0u,												// VkPipelineLayoutCreateFlags		flags;
7639 				0u,												// deUint32							setLayoutCount;
7640 				DE_NULL,										// const VkDescriptorSetLayout*		pSetLayouts;
7641 				0u,												// deUint32							pushConstantRangeCount;
7642 				DE_NULL											// const VkPushConstantRange*		pPushConstantRanges;
7643 			};
7644 
7645 			pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
7646 		}
7647 
7648 		// Create upper half triangle.
7649 		{
7650 			// Add triangle.
7651 			vertices.emplace_back(-1.0f, -1.0f, 0.0f, 1.0f);
7652 			vertices.emplace_back(1.0f,  -1.0f, 0.0f, 1.0f);
7653 			vertices.emplace_back(1.0f,  1.0f,  0.0f, 1.0f);
7654 		}
7655 
7656 		// Create vertex buffer.
7657 		{
7658 			const VkDeviceSize			vertexDataSize		= vertices.size() * sizeof(tcu::Vec4);
7659 			const VkBufferCreateInfo	vertexBufferParams	=
7660 			{
7661 				VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
7662 				DE_NULL,								// const void*			pNext;
7663 				0u,										// VkBufferCreateFlags	flags;
7664 				vertexDataSize,							// VkDeviceSize			size;
7665 				VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// VkBufferUsageFlags	usage;
7666 				VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
7667 				1u,										// deUint32				queueFamilyIndexCount;
7668 				&queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
7669 			};
7670 
7671 			vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
7672 			vertexBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
7673 			VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
7674 
7675 			// Load vertices into vertex buffer.
7676 			deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
7677 			flushAlloc(vk, vkDevice, *vertexBufferAlloc);
7678 		}
7679 
7680 		{
7681 			Move<VkFramebuffer>		framebuffer;
7682 			Move<VkImageView>		sourceAttachmentView;
7683 
7684 			// Create depth/stencil attachment view.
7685 			{
7686 				const uint32_t arrayLayer = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? 2u : 0u;
7687 				const VkImageViewCreateInfo		depthStencilAttachmentViewParams	=
7688 				{
7689 					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
7690 					DE_NULL,									// const void*				pNext;
7691 					0u,											// VkImageViewCreateFlags	flags;
7692 					*srcImage,									// VkImage					image;
7693 					VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType;
7694 					m_srcImage.format,							// VkFormat					format;
7695 					componentMappingRGBA,						// VkComponentMapping		components;
7696 					{ aspectFlags, 0u, 1u, arrayLayer, 1u }		// VkImageSubresourceRange	subresourceRange;
7697 				};
7698 				sourceAttachmentView	= createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
7699 			}
7700 
7701 			// Create framebuffer
7702 			{
7703 				const VkFramebufferCreateInfo	framebufferParams	=
7704 				{
7705 					VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType				sType;
7706 					DE_NULL,									// const void*					pNext;
7707 					0u,											// VkFramebufferCreateFlags		flags;
7708 					*renderPass,								// VkRenderPass					renderPass;
7709 					1u,											// deUint32						attachmentCount;
7710 					&sourceAttachmentView.get(),				// const VkImageView*			pAttachments;
7711 					m_srcImage.extent.width,					// deUint32						width;
7712 					m_srcImage.extent.height,					// deUint32						height;
7713 					1u											// deUint32						layers;
7714 				};
7715 
7716 				framebuffer	= createFramebuffer(vk, vkDevice, &framebufferParams);
7717 			}
7718 
7719 			// Create pipeline
7720 			{
7721 				const std::vector<VkViewport>	viewports	(1, makeViewport(m_srcImage.extent));
7722 				const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_srcImage.extent));
7723 
7724 				const VkPipelineMultisampleStateCreateInfo		multisampleStateParams				=
7725 				{
7726 					VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
7727 					DE_NULL,													// const void*								pNext;
7728 					0u,															// VkPipelineMultisampleStateCreateFlags	flags;
7729 					m_params.samples,											// VkSampleCountFlagBits					rasterizationSamples;
7730 					VK_FALSE,													// VkBool32									sampleShadingEnable;
7731 					0.0f,														// float									minSampleShading;
7732 					DE_NULL,													// const VkSampleMask*						pSampleMask;
7733 					VK_FALSE,													// VkBool32									alphaToCoverageEnable;
7734 					VK_FALSE													// VkBool32									alphaToOneEnable;
7735 				};
7736 
7737 				const VkStencilOpState							stencilOpState						=
7738 				{
7739 					VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp
7740 					VK_STENCIL_OP_REPLACE,	// VkStencilOp	passOp
7741 					VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp
7742 					VK_COMPARE_OP_ALWAYS,	// VkCompareOp	compareOp
7743 					0,						// deUint32		compareMask
7744 					0xFF,					// deUint32		writeMask
7745 					0xFF					// deUint32		reference
7746 				};
7747 
7748 				const VkPipelineDepthStencilStateCreateInfo		depthStencilStateCreateInfoDefault	=
7749 				{
7750 					VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType							sType
7751 					DE_NULL,														// const void*								pNext
7752 					0u,																// VkPipelineDepthStencilStateCreateFlags	flags
7753 					aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT ? VK_TRUE : VK_FALSE,	// VkBool32									depthTestEnable
7754 					aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT ? VK_TRUE : VK_FALSE,	// VkBool32									depthWriteEnable
7755 					VK_COMPARE_OP_ALWAYS,											// VkCompareOp								depthCompareOp
7756 					VK_FALSE,														// VkBool32									depthBoundsTestEnable
7757 					aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT ? VK_TRUE : VK_FALSE,	// VkBool32									stencilTestEnable
7758 					stencilOpState,													// VkStencilOpState							front
7759 					stencilOpState,													// VkStencilOpState							back
7760 					0.0f,															// float									minDepthBounds
7761 					1.0f,															// float									maxDepthBounds
7762 				};
7763 
7764 				graphicsPipeline = makeGraphicsPipeline(vk,										// const DeviceInterface&							vk
7765 														vkDevice,								// const VkDevice									device
7766 														*pipelineLayout,						// const VkPipelineLayout							pipelineLayout
7767 														*vertexShaderModule,					// const VkShaderModule								vertexShaderModule
7768 														DE_NULL,								// const VkShaderModule								tessellationControlModule
7769 														DE_NULL,								// const VkShaderModule								tessellationEvalModule
7770 														DE_NULL,								// const VkShaderModule								geometryShaderModule
7771 														*fragmentShaderModule,					// const VkShaderModule								fragmentShaderModule
7772 														*renderPass,							// const VkRenderPass								renderPass
7773 														viewports,								// const std::vector<VkViewport>&					viewports
7774 														scissors,								// const std::vector<VkRect2D>&						scissors
7775 														VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology						topology
7776 														0u,										// const deUint32									subpass
7777 														0u,										// const deUint32									patchControlPoints
7778 														DE_NULL,								// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
7779 														DE_NULL,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
7780 														&multisampleStateParams,				// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
7781 														&depthStencilStateCreateInfoDefault);	// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
7782 			}
7783 
7784 			// Create command buffer
7785 			{
7786 				beginCommandBuffer(vk, *cmdBuffer, 0u);
7787 
7788 				const VkClearValue srcImageClearValue = makeClearValueDepthStencil(0.1f, 0x10);
7789 
7790 				// Change the layout of each layer of the depth / stencil image to VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL and clear the images.
7791 				const VkClearValue copiedImageClearValue = makeClearValueDepthStencil(m_clearValue, (uint32_t)m_clearValue);
7792 				const auto subResourceRange = makeImageSubresourceRange(				// VkImageSubresourceRange	subresourceRange
7793 												(getAspectFlags(m_srcImage.format)),	// VkImageAspectFlags		aspectMask
7794 												0u,										// uint32_t					baseMipLevel
7795 												1u,										// uint32_t					levelCount
7796 												0u,										// uint32_t					baseArrayLayer
7797 												getArraySize(m_srcImage));
7798 
7799 				const VkImageMemoryBarrier preClearBarrier = makeImageMemoryBarrier(
7800 					0u,										// VkAccessFlags			srcAccessMask
7801 					VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask
7802 					VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			oldLayout
7803 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout
7804 					srcImage.get(),							// VkImage					image
7805 					subResourceRange);						// VkImageSubresourceRange	subresourceRange
7806 				std::vector<VkImageMemoryBarrier> preClearBarriers(2u, preClearBarrier);
7807 				preClearBarriers[1].image = dstImage.get();
7808 				vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7809 					(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2, preClearBarriers.data());
7810 
7811 				vk.cmdClearDepthStencilImage(
7812 						*cmdBuffer,								// VkCommandBuffer					commandBuffer
7813 						srcImage.get(),							// VkImage							image
7814 						VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout					imageLayout
7815 						&srcImageClearValue.depthStencil,		// const VkClearDepthStencilValue*	pDepthStencil
7816 						1u,										// uint32_t							rangeCount
7817 						&subResourceRange);						// const VkImageSubresourceRange*	pRanges
7818 
7819 				vk.cmdClearDepthStencilImage(
7820 						*cmdBuffer,								// VkCommandBuffer					commandBuffer
7821 						dstImage.get(),							// VkImage							image
7822 						VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout					imageLayout
7823 						&copiedImageClearValue.depthStencil,	// const VkClearDepthStencilValue*	pDepthStencil
7824 						1u,										// uint32_t							rangeCount
7825 						&subResourceRange);						// const VkImageSubresourceRange*	pRanges
7826 
7827 				// Post clear barrier
7828 				const VkImageMemoryBarrier postClearBarrier = makeImageMemoryBarrier(
7829 					VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags			srcAccessMask
7830 					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask
7831 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout			oldLayout
7832 					VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout
7833 					srcImage.get(),										// VkImage					image
7834 					subResourceRange);									// VkImageSubresourceRange	subresourceRange
7835 
7836 				vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
7837 					(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postClearBarrier);
7838 
7839 				beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_srcImage.extent.width, m_srcImage.extent.height), 1u, &srcImageClearValue);
7840 
7841 				const VkDeviceSize vertexBufferOffset = 0u;
7842 
7843 				vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
7844 				vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
7845 				vk.cmdDraw(*cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
7846 
7847 				endRenderPass(vk, *cmdBuffer);
7848 				endCommandBuffer(vk, *cmdBuffer);
7849 			}
7850 
7851 			submitCommandsAndWait (vk, vkDevice, queue, *cmdBuffer);
7852 			m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
7853 		}
7854 	}
7855 
7856 	// 2. Record a command buffer that contains the copy operation(s).
7857 	beginCommandBuffer(vk, *cmdBuffer);
7858 	{
7859 		// Change the image layouts and synchronize the memory access before copying
7860 		{
7861 			const VkImageMemoryBarrier imageBarriers[] =
7862 			{
7863 				// srcImage
7864 				makeImageMemoryBarrier(
7865 					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask
7866 					VK_ACCESS_TRANSFER_READ_BIT,						// VkAccessFlags			dstAccessMask
7867 					VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout
7868 					m_srcImage.operationLayout,							// VkImageLayout			newLayout
7869 					srcImage.get(),										// VkImage					image
7870 					makeImageSubresourceRange(							// VkImageSubresourceRange	subresourceRange
7871 						getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask
7872 						0u,								// deUint32				baseMipLevel
7873 						1u,								// deUint32				levelCount
7874 						0u,								// deUint32				baseArrayLayer
7875 						sourceArraySize					// deUint32				layerCount
7876 					)),
7877 				// dstImage
7878 				makeImageMemoryBarrier(
7879 					VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			srcAccessMask
7880 					VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask
7881 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			oldLayout
7882 					m_dstImage.operationLayout,				// VkImageLayout			newLayout
7883 					dstImage.get(),							// VkImage					image
7884 					makeImageSubresourceRange(				// VkImageSubresourceRange	subresourceRange
7885 						getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask
7886 						0u,								// deUint32				baseMipLevel
7887 						1u,								// deUint32				levelCount
7888 						0u,								// deUint32				baseArrayLayer
7889 						sourceArraySize					// deUint32				layerCount
7890 					)),
7891 			};
7892 			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7893 				(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2u, imageBarriers);
7894 		}
7895 
7896 		std::vector<VkImageCopy>		imageCopies;
7897 		std::vector<VkImageCopy2KHR>	imageCopies2KHR;
7898 		for (const auto & region : m_regions)
7899 		{
7900 			if (m_params.extensionUse == EXTENSION_USE_NONE)
7901 			{
7902 				imageCopies.push_back(region.imageCopy);
7903 			}
7904 			else
7905 			{
7906 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7907 				imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(region.imageCopy));
7908 			}
7909 		}
7910 
7911 		if (m_params.extensionUse == EXTENSION_USE_NONE)
7912 		{
7913 			vk.cmdCopyImage(*cmdBuffer, srcImage.get(), m_srcImage.operationLayout, dstImage.get(), m_dstImage.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
7914 		}
7915 #ifndef CTS_USES_VULKANSC
7916 		else
7917 		{
7918 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7919 			const VkCopyImageInfo2KHR copyImageInfo2KHR =
7920 			{
7921 				VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
7922 				DE_NULL,									// const void*				pNext;
7923 				srcImage.get(),								// VkImage					srcImage;
7924 				m_srcImage.operationLayout,					// VkImageLayout			srcImageLayout;
7925 				dstImage.get(),								// VkImage					dstImage;
7926 				m_dstImage.operationLayout,					// VkImageLayout			dstImageLayout;
7927 				(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
7928 				imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
7929 			};
7930 
7931 			vk.cmdCopyImage2(*cmdBuffer, &copyImageInfo2KHR);
7932 		}
7933 #endif // CTS_USES_VULKANSC
7934 	}
7935 	endCommandBuffer(vk, *cmdBuffer);
7936 	submitCommandsAndWait (vk, vkDevice, queue, *cmdBuffer);
7937 	m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
7938 
7939 	// Verify that all samples have been copied properly from all aspects.
7940 	const auto usedImageAspects = getUsedImageAspects();
7941 	if (usedImageAspects & VK_IMAGE_ASPECT_DEPTH_BIT)
7942 	{
7943 		auto copyResult = checkCopyResults(cmdBuffer.get(), VK_IMAGE_ASPECT_DEPTH_BIT, srcImage.get(), dstImage.get());
7944 		if (copyResult.getCode() != QP_TEST_RESULT_PASS)
7945 			return copyResult;
7946 	}
7947 	if (usedImageAspects & VK_IMAGE_ASPECT_STENCIL_BIT)
7948 	{
7949 		auto copyResult = checkCopyResults(cmdBuffer.get(), VK_IMAGE_ASPECT_STENCIL_BIT, srcImage.get(), dstImage.get());
7950 		if (copyResult.getCode() != QP_TEST_RESULT_PASS)
7951 			return copyResult;
7952 	}
7953 	return tcu::TestStatus::pass("pass");
7954 }
7955 
checkCopyResults(VkCommandBuffer cmdBuffer,const VkImageAspectFlagBits & aspectToVerify,VkImage srcImage,VkImage dstImage)7956 tcu::TestStatus DepthStencilMSAA::checkCopyResults (VkCommandBuffer cmdBuffer, const VkImageAspectFlagBits& aspectToVerify, VkImage srcImage, VkImage dstImage)
7957 {
7958 	DE_ASSERT((aspectToVerify & VK_IMAGE_ASPECT_DEPTH_BIT) || (aspectToVerify & VK_IMAGE_ASPECT_STENCIL_BIT));
7959 
7960 	const	auto&	vkd						= m_context.getDeviceInterface();
7961 	const	auto	device					= m_context.getDevice();
7962 	const	auto	queue					= m_context.getUniversalQueue();
7963 			auto&	alloc					= m_context.getDefaultAllocator();
7964 	const	auto	layerCount				= getArraySize(m_srcImage);
7965 	const	auto	numInputAttachments		= layerCount + 1u; // +1 for the source image.
7966 	const	auto	numOutputBuffers		= 2u; // 1 for the reference and 1 for the copied values.
7967 	const	auto	numSets					= 2u; // 1 for the output buffers, 1 for the input attachments.
7968 	const	auto	fbWidth					= m_srcImage.extent.width;
7969 	const	auto	fbHeight				= m_srcImage.extent.height;
7970 	const	auto	aspectFlags				= getUsedImageAspects();
7971 
7972 	// Shader modules.
7973 	const	auto	vertexModule			= createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
7974 	const	auto	verificationModule		= createShaderModule(vkd, device, m_context.getBinaryCollection().get(aspectToVerify & VK_IMAGE_ASPECT_DEPTH_BIT ? "verify_depth" : "verify_stencil"), 0u);
7975 
7976 	// Descriptor sets.
7977 	DescriptorPoolBuilder poolBuilder;
7978 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, numOutputBuffers);
7979 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
7980 	const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
7981 
7982 	DescriptorSetLayoutBuilder layoutBuilderBuffer;
7983 	layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
7984 	layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
7985 	const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
7986 
7987 	DescriptorSetLayoutBuilder layoutBuilderAttachments;
7988 	for (deUint32 i = 0u; i < numInputAttachments; ++i)
7989 		layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
7990 	const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
7991 
7992 	const auto descriptorSetBuffer		= makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
7993 	const auto descriptorSetAttachments	= makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
7994 
7995 	// Array with raw descriptor sets.
7996 	const std::array<VkDescriptorSet, numSets> descriptorSets =
7997 	{{
7998 		descriptorSetBuffer.get(),
7999 		descriptorSetAttachments.get(),
8000 	}};
8001 
8002 	// Pipeline layout.
8003 	const std::array<VkDescriptorSetLayout, numSets> setLayouts =
8004 	{{
8005 		outputBufferSetLayout.get(),
8006 		inputAttachmentsSetLayout.get(),
8007 	}};
8008 
8009 	// Push constants.
8010 	std::array<int, 3> pushConstantData =
8011 		{{
8012 			static_cast<int>(fbWidth),
8013 			static_cast<int>(fbHeight),
8014 			static_cast<int>(m_params.samples),
8015 		}};
8016 
8017 	const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
8018 
8019 	const VkPushConstantRange pushConstantRange =
8020 	{
8021 		VK_SHADER_STAGE_FRAGMENT_BIT,	// VkShaderStageFlags	stageFlags;
8022 		0u,								// deUint32				offset;
8023 		pushConstantSize,				// deUint32				size;
8024 	};
8025 
8026 	const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
8027 	{
8028 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType					sType;
8029 		nullptr,										// const void*						pNext;
8030 		0u,												// VkPipelineLayoutCreateFlags		flags;
8031 		static_cast<deUint32>(setLayouts.size()),		// deUint32							setLayoutCount;
8032 		setLayouts.data(),								// const VkDescriptorSetLayout*		pSetLayouts;
8033 		1u,												// deUint32							pushConstantRangeCount;
8034 		&pushConstantRange,								// const VkPushConstantRange*		pPushConstantRanges;
8035 	};
8036 
8037 	const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
8038 
8039 	// Render pass.
8040 	const VkAttachmentDescription commonAttachmentDescription =
8041 	{
8042 		0u,										// VkAttachmentDescriptionFlags		flags;
8043 		m_srcImage.format,						// VkFormat							format;
8044 		m_params.samples,						// VkSampleCountFlagBits			samples;
8045 		VK_ATTACHMENT_LOAD_OP_LOAD,				// VkAttachmentLoadOp				loadOp;
8046 		VK_ATTACHMENT_STORE_OP_STORE,			// VkAttachmentStoreOp				storeOp;
8047 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,		// VkAttachmentLoadOp				stencilLoadOp;
8048 		VK_ATTACHMENT_STORE_OP_DONT_CARE,		// VkAttachmentStoreOp				stencilStoreOp;
8049 		m_dstImage.operationLayout,				// VkImageLayout					initialLayout;
8050 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,	// VkImageLayout					finalLayout;
8051 	};
8052 
8053 	std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
8054 	// Set the first attachment's (m_srcImage) initial layout to match the layout it was left after copying.
8055 	attachmentDescriptions[0].initialLayout = m_srcImage.operationLayout;
8056 
8057 	std::vector<VkAttachmentReference> inputAttachmentReferences;
8058 	inputAttachmentReferences.reserve(numInputAttachments);
8059 	for (deUint32 i = 0u; i < numInputAttachments; ++i)
8060 	{
8061 		const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
8062 		inputAttachmentReferences.push_back(reference);
8063 	}
8064 
8065 	const VkSubpassDescription		subpassDescription	=
8066 	{
8067 		0u,															// VkSubpassDescriptionFlags		flags;
8068 		VK_PIPELINE_BIND_POINT_GRAPHICS,							// VkPipelineBindPoint				pipelineBindPoint;
8069 		static_cast<deUint32>(inputAttachmentReferences.size()),	// deUint32							inputAttachmentCount;
8070 		inputAttachmentReferences.data(),							// const VkAttachmentReference*		pInputAttachments;
8071 		0u,															// deUint32							colorAttachmentCount;
8072 		nullptr,													// const VkAttachmentReference*		pColorAttachments;
8073 		nullptr,													// const VkAttachmentReference*		pResolveAttachments;
8074 		nullptr,													// const VkAttachmentReference*		pDepthStencilAttachment;
8075 		0u,															// deUint32							preserveAttachmentCount;
8076 		nullptr,													// const deUint32*					pPreserveAttachments;
8077 	};
8078 
8079 	const VkRenderPassCreateInfo	renderPassInfo		=
8080 	{
8081 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				// VkStructureType					sType;
8082 		nullptr,												// const void*						pNext;
8083 		0u,														// VkRenderPassCreateFlags			flags;
8084 		static_cast<deUint32>(attachmentDescriptions.size()),	// deUint32							attachmentCount;
8085 		attachmentDescriptions.data(),							// const VkAttachmentDescription*	pAttachments;
8086 		1u,														// deUint32							subpassCount;
8087 		&subpassDescription,									// const VkSubpassDescription*		pSubpasses;
8088 		0u,														// deUint32							dependencyCount;
8089 		nullptr,												// const VkSubpassDependency*		pDependencies;
8090 	};
8091 
8092 	const auto						renderPass			= createRenderPass(vkd, device, &renderPassInfo);
8093 
8094 	// Framebuffer.
8095 	std::vector<Move<VkImageView>>	imageViews;
8096 	std::vector<VkImageView>		imageViewsRaw;
8097 
8098 	const uint32_t					srcArrayLayer		= m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? 2u : 0u;
8099 	imageViews.push_back(makeImageView(vkd, device, srcImage, VK_IMAGE_VIEW_TYPE_2D, m_srcImage.format, makeImageSubresourceRange(aspectFlags, 0u, 1u, srcArrayLayer, 1u)));
8100 	for (deUint32 i = 0u; i < layerCount; ++i)
8101 	{
8102 		const auto subresourceRange = makeImageSubresourceRange(aspectFlags, 0u, 1u, i, 1u);
8103 		imageViews.push_back(makeImageView(vkd, device, dstImage, VK_IMAGE_VIEW_TYPE_2D, m_srcImage.format, subresourceRange));
8104 	}
8105 
8106 	imageViewsRaw.reserve(imageViews.size());
8107 	std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
8108 
8109 	const auto				framebuffer			= makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
8110 
8111 	// Create storage buffers for both original and copied multisampled depth/stencil images.
8112 	const auto				bufferCount			= static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
8113 	const auto				bufferSize			= static_cast<VkDeviceSize>(bufferCount * sizeof(float));
8114 	BufferWithMemory		bufferOriginal		(vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
8115 	BufferWithMemory		bufferCopied		(vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
8116 	auto&					bufferOriginalAlloc	= bufferOriginal.getAllocation();
8117 	auto&					bufferCopiedAlloc	= bufferCopied.getAllocation();
8118 
8119 	// Update descriptor sets.
8120 	DescriptorSetUpdateBuilder updater;
8121 
8122 	const auto				bufferOriginalInfo	= makeDescriptorBufferInfo(bufferOriginal.get(), 0ull, bufferSize);
8123 	const auto				bufferCopiedInfo	= makeDescriptorBufferInfo(bufferCopied.get(), 0ull, bufferSize);
8124 	updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferOriginalInfo);
8125 	updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferCopiedInfo);
8126 
8127 	std::vector<VkDescriptorImageInfo> imageInfos;
8128 	imageInfos.reserve(imageViewsRaw.size());
8129 	for (size_t i = 0; i < imageViewsRaw.size(); ++i)
8130 	{
8131 		imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
8132 		updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
8133 	}
8134 
8135 	updater.update(vkd, device);
8136 
8137 	// Vertex buffer.
8138 	std::vector<tcu::Vec4> fullScreenQuad;
8139 	{
8140 		// Full screen quad so every framebuffer pixel and sample location is verified by the shader.
8141 		const tcu::Vec4 topLeft		(-1.0f, -1.0f, 0.0f, 1.0f);
8142 		const tcu::Vec4 topRight	( 1.0f, -1.0f, 0.0f, 1.0f);
8143 		const tcu::Vec4 bottomLeft	(-1.0f,  1.0f, 0.0f, 1.0f);
8144 		const tcu::Vec4 bottomRight	( 1.0f,  1.0f, 0.0f, 1.0f);
8145 
8146 		fullScreenQuad.reserve(6u);
8147 		fullScreenQuad.push_back(topLeft);
8148 		fullScreenQuad.push_back(topRight);
8149 		fullScreenQuad.push_back(bottomRight);
8150 		fullScreenQuad.push_back(topLeft);
8151 		fullScreenQuad.push_back(bottomRight);
8152 		fullScreenQuad.push_back(bottomLeft);
8153 	}
8154 
8155 	const auto				vertexBufferSize	= static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
8156 	const auto				vertexBufferInfo	= makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
8157 	const BufferWithMemory	vertexBuffer		(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
8158 	const VkDeviceSize		vertexBufferOffset	= 0ull;
8159 
8160 	deMemcpy(vertexBuffer.getAllocation().getHostPtr(), fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
8161 	flushAlloc(vkd, device, vertexBuffer.getAllocation());
8162 
8163 	// Graphics pipeline.
8164 	const std::vector<VkViewport>	viewports	(1, makeViewport(m_srcImage.extent));
8165 	const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_srcImage.extent));
8166 
8167 	const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
8168 	{
8169 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
8170 		nullptr,													// const void*								pNext;
8171 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
8172 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
8173 		VK_FALSE,													// VkBool32									sampleShadingEnable;
8174 		0.0f,														// float									minSampleShading;
8175 		nullptr,													// const VkSampleMask*						pSampleMask;
8176 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
8177 		VK_FALSE													// VkBool32									alphaToOneEnable;
8178 	};
8179 
8180 	const auto graphicsPipeline = makeGraphicsPipeline(
8181 		vkd,									// const DeviceInterface&							vk
8182 		device,									// const VkDevice									device
8183 		pipelineLayout.get(),					// const VkPipelineLayout							pipelineLayout
8184 		vertexModule.get(),						// const VkShaderModule								vertexShaderModule
8185 		DE_NULL,								// const VkShaderModule								tessellationControlModule
8186 		DE_NULL,								// const VkShaderModule								tessellationEvalModule
8187 		DE_NULL,								// const VkShaderModule								geometryShaderModule
8188 		verificationModule.get(),				// const VkShaderModule								fragmentShaderModule
8189 		renderPass.get(),						// const VkRenderPass								renderPass
8190 		viewports,								// const std::vector<VkViewport>&					viewports
8191 		scissors,								// const std::vector<VkRect2D>&						scissors
8192 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology						topology
8193 		0u,										// const deUint32									subpass
8194 		0u,										// const deUint32									patchControlPoints
8195 		nullptr,								// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
8196 		nullptr,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
8197 		&multisampleStateParams);				// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
8198 
8199 	// Make sure multisample copy data is available to the fragment shader.
8200 	const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
8201 
8202 	// Record and submit command buffer.
8203 	beginCommandBuffer(vkd, cmdBuffer);
8204 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
8205 	beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_srcImage.extent));
8206 	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
8207 	vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
8208 
8209 	vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
8210 	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
8211 	vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
8212 
8213 	endRenderPass(vkd, cmdBuffer);
8214 
8215 	// Make sure verification buffer data is available on the host.
8216 	const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
8217 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
8218 	endCommandBuffer(vkd, cmdBuffer);
8219 	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
8220 
8221 	// Verify intermediate results.
8222 	invalidateAlloc(vkd, device, bufferOriginalAlloc);
8223 	invalidateAlloc(vkd, device, bufferCopiedAlloc);
8224 	std::vector<float> outputOriginal (bufferCount, 0);
8225 	std::vector<float> outputCopied (bufferCount, 0);
8226 	deMemcpy(outputOriginal.data(), bufferOriginalAlloc.getHostPtr(), static_cast<size_t>(bufferSize));
8227 	deMemcpy(outputCopied.data(), bufferCopiedAlloc.getHostPtr(), static_cast<size_t>(bufferSize));
8228 
8229 	auto& log = m_context.getTestContext().getLog();
8230 	log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
8231 
8232 	const auto sampleCount = static_cast<deUint32>(m_params.samples);
8233 
8234 	// Verify copied region(s)
8235 	for (const auto &region : m_regions)
8236 	{
8237 		for (uint32_t x = 0u; x < region.imageCopy.extent.width; ++x)
8238 		for (uint32_t y = 0u; y < region.imageCopy.extent.height; ++y)
8239 		for (uint32_t s = 0u; s < sampleCount; ++s)
8240 		{
8241 			tcu::UVec2 srcCoord(x + region.imageCopy.srcOffset.x, y + region.imageCopy.srcOffset.y);
8242 			tcu::UVec2 dstCoord(x + region.imageCopy.dstOffset.x, y + region.imageCopy.dstOffset.y);
8243 			const auto srcIndex = (srcCoord.y() * fbWidth + srcCoord.x()) * sampleCount + s;
8244 			const auto dstIndex = (dstCoord.y() * fbWidth + dstCoord.x()) * sampleCount + s;
8245 			if (outputOriginal[srcIndex] != outputCopied[dstIndex])
8246 			{
8247 				std::ostringstream msg;
8248 				msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s << ". "
8249 					<< "result: " << outputCopied[dstIndex] << " expected: " << outputOriginal[srcIndex];
8250 				return tcu::TestStatus::fail(msg.str());
8251 			}
8252 		}
8253 	}
8254 
8255 	if (m_params.copyOptions == COPY_PARTIAL)
8256 	{
8257 		// In the partial copy tests the destination image contains copied data only in the bottom half of the image.
8258 		// Verify that the upper half of the image is left at it's clear value (0).
8259 		for (uint32_t x = 0u; x < m_srcImage.extent.width; x++)
8260 		for (uint32_t y = 0u; y < m_srcImage.extent.height / 2; y++)
8261 		for (uint32_t s = 0u; s < sampleCount; ++s)
8262 		{
8263 			const auto bufferIndex = (y * fbWidth + x) * sampleCount + s;
8264 			if (outputCopied[bufferIndex] != m_clearValue)
8265 			{
8266 				std::ostringstream msg;
8267 				msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s << ". "
8268 					<< "result: " << outputCopied[bufferIndex] << " expected: 0.0" ;
8269 				return tcu::TestStatus::fail(msg.str());
8270 			}
8271 		}
8272 	}
8273 
8274 	log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
8275 	return tcu::TestStatus::pass("Pass");
8276 }
8277 
8278 class DepthStencilMSAATestCase : public vkt::TestCase
8279 {
8280 public:
DepthStencilMSAATestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const DepthStencilMSAA::TestParameters testParams)8281 							DepthStencilMSAATestCase	(tcu::TestContext&						testCtx,
8282 														 const std::string&						name,
8283 														 const std::string&						description,
8284 														 const DepthStencilMSAA::TestParameters	testParams)
8285 								: vkt::TestCase	(testCtx, name, description)
8286 								, m_params		(testParams)
8287 	{}
8288 
8289 	virtual	void			initPrograms				(SourceCollections&		programCollection) const;
8290 
createInstance(Context & context) const8291 	virtual TestInstance*	createInstance				(Context&				context) const
8292 	{
8293 		return new DepthStencilMSAA(context, m_params);
8294 	}
8295 
checkSupport(Context & context) const8296 	virtual void			checkSupport				(Context&				context) const
8297 	{
8298 		const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
8299 
8300 		if (!context.getDeviceFeatures().fragmentStoresAndAtomics)
8301 			TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
8302 
8303 		if ((m_params.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT) && !(context.getDeviceProperties().limits.framebufferDepthSampleCounts & rasterizationSamples))
8304 			TCU_THROW(NotSupportedError, "Unsupported number of depth samples");
8305 
8306 		if ((m_params.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT) && !(context.getDeviceProperties().limits.framebufferDepthSampleCounts & rasterizationSamples))
8307 			TCU_THROW(NotSupportedError, "Unsupported number of stencil samples");
8308 
8309 		VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
8310 										| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
8311 										| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
8312 										| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
8313 
8314 		VkImageFormatProperties properties;
8315 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
8316 																					m_params.imageFormat,
8317 																					VK_IMAGE_TYPE_2D,
8318 																					VK_IMAGE_TILING_OPTIMAL,
8319 																					usageFlags, 0,
8320 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
8321 		{
8322 			TCU_THROW(NotSupportedError, "Format not supported");
8323 		}
8324 
8325 		if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)	&&
8326 			(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
8327 		{
8328 			TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
8329 		}
8330 	}
8331 
8332 private:
8333 
getArrayLayerCount() const8334 	uint32_t				getArrayLayerCount			() const
8335 	{
8336 		return (m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY) ? 5u : 1u;
8337 	}
8338 
createVerificationShader(std::ostringstream & shaderCode,const VkImageAspectFlagBits attachmentAspect) const8339 	void createVerificationShader						(std::ostringstream& shaderCode, const VkImageAspectFlagBits attachmentAspect) const
8340 	{
8341 		DE_ASSERT(attachmentAspect & (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT));
8342 		// The shader copies the sample values from the source and destination image to output buffers OriginalValue and
8343 		// CopiedValues, respectively. If the dst image contains multiple array layers, only one layer has the copied data
8344 		// and the rest should be filled with the clear value (0). This is also verified in this shader.
8345 		// Array layer cases need an image view per layer in the copied image.
8346 		// Set 0 contains the output buffers.
8347 		// Set 1 contains the input attachments.
8348 
8349 		std::string inputAttachmentPrefix = attachmentAspect == VK_IMAGE_ASPECT_STENCIL_BIT ? "u" : "";
8350 
8351 		shaderCode
8352 			<< "#version 450\n"
8353 			<< "\n"
8354 			<< "layout (push_constant, std430) uniform PushConstants {\n"
8355 			<< "    int width;\n"
8356 			<< "    int height;\n"
8357 			<< "    int samples;\n"
8358 			<< "};\n"
8359 			<< "layout (set=0, binding=0) buffer OriginalValues {\n"
8360 			<< "    float outputOriginal[];\n"
8361 			<< "};\n"
8362 			<< "layout (set=0, binding=1) buffer CopiedValues {\n"
8363 			<< "    float outputCopied[];\n"
8364 			<< "};\n"
8365 			<< "layout (input_attachment_index=0, set=1, binding=0) uniform " << inputAttachmentPrefix << "subpassInputMS attachment0;\n"
8366 			;
8367 
8368 		const auto layerCount = getArrayLayerCount();
8369 		for (deUint32 layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8370 		{
8371 			const auto i = layerNdx + 1u;
8372 			shaderCode << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform " << inputAttachmentPrefix << "subpassInputMS attachment" << i << ";\n";
8373 		}
8374 
8375 		// Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
8376 		// created with a single sample.
8377 		shaderCode
8378 			<< "\n"
8379 			<< "void main() {\n"
8380 			<< "    for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
8381 			<< "        ivec3 coords  = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
8382 			<< "        int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
8383 			<< "        " << inputAttachmentPrefix << "vec4 orig = subpassLoad(attachment0, sampleID);\n"
8384 			<< "        outputOriginal[bufferPos] = orig.r;\n"
8385 			;
8386 
8387 		for (deUint32 layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8388 		{
8389 			const auto i = layerNdx + 1u;
8390 			shaderCode << "        " << inputAttachmentPrefix << "vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
8391 		}
8392 
8393 		std::ostringstream testCondition;
8394 		std::string layerToVerify = m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY ? "copy4" : "copy1";
8395 		shaderCode
8396 			<< "\n"
8397 			<< "        outputCopied[bufferPos] = " << layerToVerify << ".r; \n";
8398 
8399 		if (m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY)
8400 		{
8401 			// In array layer copy tests the copied image should be in the layer 3 and other layers should be value of 0 or 0.0 depending on the format.
8402 			// This verifies that all the samples in the other layers have proper values.
8403 			shaderCode << "        bool equalEmptyLayers = ";
8404 			for (deUint32 layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8405 			{
8406 				if (layerNdx == 3)
8407 					continue;
8408 				const auto i = layerNdx + 1u;
8409 				shaderCode << "copy" << i << ".r == " << (attachmentAspect == VK_IMAGE_ASPECT_STENCIL_BIT ? "0" : "0.0") << (layerNdx < 4u ? " && " : ";\n");
8410 			}
8411 			shaderCode
8412 				<< "        if (!equalEmptyLayers)\n"
8413 				<< "            outputCopied[bufferPos]--; \n";
8414 		}
8415 
8416 		shaderCode
8417 			<< "    }\n"
8418 			<< "}\n";
8419 	}
8420 
8421 	DepthStencilMSAA::TestParameters	m_params;
8422 };
8423 
initPrograms(SourceCollections & programCollection) const8424 void DepthStencilMSAATestCase::initPrograms (SourceCollections& programCollection) const
8425 {
8426 	programCollection.glslSources.add("vert") << glu::VertexSource(
8427 		"#version 310 es\n"
8428 		"layout (location = 0) in highp vec4 a_position;\n"
8429 		"void main()\n"
8430 		"{\n"
8431 		"    gl_Position = vec4(a_position.xy, 1.0, 1.0);\n"
8432 		"}\n");
8433 
8434 	programCollection.glslSources.add("frag") << glu::FragmentSource(
8435 		"#version 310 es\n"
8436 		"void main()\n"
8437 		"{}\n");
8438 
8439 	// Create the verifying shader for the depth aspect if the depth is used.
8440 	if (m_params.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
8441 	{
8442 		std::ostringstream verificationShader;
8443 		// All the depth formats are float types, so the input attachment prefix is not used.
8444 		createVerificationShader(verificationShader, VK_IMAGE_ASPECT_DEPTH_BIT);
8445 		programCollection.glslSources.add("verify_depth") << glu::FragmentSource(verificationShader.str());
8446 	}
8447 
8448 	// Create the verifying shader for the stencil aspect if the stencil is used.
8449 	if (m_params.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
8450 	{
8451 		std::ostringstream verificationShader;
8452 		// All the stencil formats are uint types, so the input attachment prefix is "u".
8453 		createVerificationShader(verificationShader, VK_IMAGE_ASPECT_STENCIL_BIT);
8454 		programCollection.glslSources.add("verify_stencil") << glu::FragmentSource(verificationShader.str());
8455 	}
8456 }
8457 
8458 struct BufferOffsetParams
8459 {
8460 	static constexpr deUint32 kMaxOffset = 8u;
8461 
8462 	deUint32 srcOffset;
8463 	deUint32 dstOffset;
8464 };
8465 
checkZerosAt(const std::vector<deUint8> & bufferData,deUint32 from,deUint32 count)8466 void checkZerosAt(const std::vector<deUint8>& bufferData, deUint32 from, deUint32 count)
8467 {
8468 	constexpr deUint8 zero{0};
8469 	for (deUint32 i = 0; i < count; ++i)
8470 	{
8471 		const auto& val = bufferData[from + i];
8472 		if (val != zero)
8473 		{
8474 			std::ostringstream msg;
8475 			msg << "Unexpected non-zero byte found at position " << (from + i) << ": " << static_cast<int>(val);
8476 			TCU_FAIL(msg.str());
8477 		}
8478 	}
8479 }
8480 
bufferOffsetTest(Context & ctx,BufferOffsetParams params)8481 tcu::TestStatus bufferOffsetTest (Context& ctx, BufferOffsetParams params)
8482 {
8483 	// 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.
8484 	constexpr auto kMaxOffset	= BufferOffsetParams::kMaxOffset;
8485 	constexpr auto kBlockSize	= kMaxOffset * 2u;
8486 	constexpr auto kBufferSize	= kMaxOffset * kBlockSize;
8487 
8488 	DE_ASSERT(params.srcOffset < kMaxOffset);
8489 	DE_ASSERT(params.dstOffset < kMaxOffset);
8490 
8491 	const auto&	vkd		= ctx.getDeviceInterface();
8492 	const auto	device	= ctx.getDevice();
8493 	auto&		alloc	= ctx.getDefaultAllocator();
8494 	const auto	qIndex	= ctx.getUniversalQueueFamilyIndex();
8495 	const auto	queue	= ctx.getUniversalQueue();
8496 
8497 	const auto srcBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
8498 	const auto dstBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
8499 
8500 	BufferWithMemory	srcBuffer	(vkd, device, alloc, srcBufferInfo, MemoryRequirement::HostVisible);
8501 	BufferWithMemory	dstBuffer	(vkd, device, alloc, dstBufferInfo, MemoryRequirement::HostVisible);
8502 	auto&				srcAlloc	= srcBuffer.getAllocation();
8503 	auto&				dstAlloc	= dstBuffer.getAllocation();
8504 
8505 	// Zero-out destination buffer.
8506 	deMemset(dstAlloc.getHostPtr(), 0, kBufferSize);
8507 	flushAlloc(vkd, device, dstAlloc);
8508 
8509 	// Fill source buffer with nonzero bytes.
8510 	std::vector<deUint8> srcData;
8511 	srcData.reserve(kBufferSize);
8512 	for (deUint32 i = 0; i < kBufferSize; ++i)
8513 		srcData.push_back(static_cast<deUint8>(100u + i));
8514 	deMemcpy(srcAlloc.getHostPtr(), srcData.data(), de::dataSize(srcData));
8515 	flushAlloc(vkd, device, srcAlloc);
8516 
8517 	// Copy regions.
8518 	std::vector<VkBufferCopy> copies;
8519 	copies.reserve(kMaxOffset);
8520 	for (deUint32 i = 0; i < kMaxOffset; ++i)
8521 	{
8522 		const auto blockStart	= kBlockSize * i;
8523 		const auto copySize		= i + 1u;
8524 		const auto bufferCopy	= makeBufferCopy(params.srcOffset + blockStart, params.dstOffset + blockStart, copySize);
8525 		copies.push_back(bufferCopy);
8526 	}
8527 
8528 	const auto cmdPool		= makeCommandPool(vkd, device, qIndex);
8529 	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
8530 	const auto cmdBuffer	= cmdBufferPtr.get();
8531 
8532 	beginCommandBuffer(vkd, cmdBuffer);
8533 	vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), static_cast<deUint32>(copies.size()), copies.data());
8534 	const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
8535 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
8536 	endCommandBuffer(vkd, cmdBuffer);
8537 	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
8538 	invalidateAlloc(vkd, device, dstAlloc);
8539 
8540 	// Verify destination buffer data.
8541 	std::vector<deUint8> dstData(kBufferSize);
8542 	deMemcpy(dstData.data(), dstAlloc.getHostPtr(), de::dataSize(dstData));
8543 
8544 	for (deUint32 blockIdx = 0; blockIdx < kMaxOffset; ++blockIdx)
8545 	{
8546 		const auto blockStart	= kBlockSize * blockIdx;
8547 		const auto copySize		= blockIdx + 1u;
8548 
8549 		// Verify no data has been written before dstOffset.
8550 		checkZerosAt(dstData, blockStart, params.dstOffset);
8551 
8552 		// Verify copied block.
8553 		for (deUint32 i = 0; i < copySize; ++i)
8554 		{
8555 			const auto& dstVal = dstData[blockStart + params.dstOffset + i];
8556 			const auto& srcVal = srcData[blockStart + params.srcOffset + i];
8557 			if (dstVal != srcVal)
8558 			{
8559 				std::ostringstream msg;
8560 				msg << "Unexpected value found at position " << (blockStart + params.dstOffset + i) << ": expected " << static_cast<int>(srcVal) << " but found " << static_cast<int>(dstVal);
8561 				TCU_FAIL(msg.str());
8562 			}
8563 		}
8564 
8565 		// Verify no data has been written after copy block.
8566 		checkZerosAt(dstData, blockStart + params.dstOffset + copySize, kBlockSize - (params.dstOffset + copySize));
8567 	}
8568 
8569 	return tcu::TestStatus::pass("Pass");
8570 }
8571 
getSampleCountCaseName(VkSampleCountFlagBits sampleFlag)8572 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
8573 {
8574 	return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
8575 }
8576 
getFormatCaseName(VkFormat format)8577 std::string getFormatCaseName (VkFormat format)
8578 {
8579 	return de::toLower(de::toString(getFormatStr(format)).substr(10));
8580 }
8581 
getImageLayoutCaseName(VkImageLayout layout)8582 std::string getImageLayoutCaseName (VkImageLayout layout)
8583 {
8584 	switch (layout)
8585 	{
8586 		case VK_IMAGE_LAYOUT_GENERAL:
8587 			return "general";
8588 		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
8589 		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
8590 			return "optimal";
8591 		default:
8592 			DE_ASSERT(false);
8593 			return "";
8594 	}
8595 }
8596 
addImageToImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)8597 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8598 {
8599 	tcu::TestContext& testCtx	= group->getTestContext();
8600 
8601 	{
8602 		TestParams	params;
8603 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8604 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
8605 		params.src.image.extent				= defaultExtent;
8606 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8607 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8608 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8609 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
8610 		params.dst.image.extent				= defaultExtent;
8611 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8612 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8613 		params.allocationKind				= allocationKind;
8614 		params.extensionUse					= extensionUse;
8615 
8616 		{
8617 			const VkImageCopy				testCopy	=
8618 			{
8619 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
8620 				{0, 0, 0},			// VkOffset3D				srcOffset;
8621 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
8622 				{0, 0, 0},			// VkOffset3D				dstOffset;
8623 				defaultExtent,		// VkExtent3D				extent;
8624 			};
8625 
8626 			CopyRegion	imageCopy;
8627 			imageCopy.imageCopy	= testCopy;
8628 			params.regions.push_back(imageCopy);
8629 		}
8630 
8631 		group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
8632 	}
8633 
8634 	{
8635 		TestParams	params;
8636 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8637 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
8638 		params.src.image.extent				= defaultExtent;
8639 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8640 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8641 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8642 		params.dst.image.format				= VK_FORMAT_R32_UINT;
8643 		params.dst.image.extent				= defaultExtent;
8644 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8645 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8646 		params.allocationKind				= allocationKind;
8647 		params.extensionUse					= extensionUse;
8648 
8649 		{
8650 			const VkImageCopy				testCopy	=
8651 			{
8652 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
8653 				{0, 0, 0},			// VkOffset3D				srcOffset;
8654 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
8655 				{0, 0, 0},			// VkOffset3D				dstOffset;
8656 				defaultExtent,		// VkExtent3D				extent;
8657 			};
8658 
8659 			CopyRegion	imageCopy;
8660 			imageCopy.imageCopy = testCopy;
8661 			params.regions.push_back(imageCopy);
8662 		}
8663 
8664 		group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
8665 	}
8666 
8667 	{
8668 		TestParams	params;
8669 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8670 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
8671 		params.src.image.extent				= defaultExtent;
8672 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8673 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8674 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8675 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
8676 		params.dst.image.extent				= defaultExtent;
8677 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8678 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8679 		params.allocationKind				= allocationKind;
8680 		params.extensionUse					= extensionUse;
8681 
8682 		{
8683 			const VkImageCopy				testCopy	=
8684 			{
8685 				defaultSourceLayer,									// VkImageSubresourceLayers	srcSubresource;
8686 				{0, 0, 0},											// VkOffset3D				srcOffset;
8687 				defaultSourceLayer,									// VkImageSubresourceLayers	dstSubresource;
8688 				{defaultQuarterSize, defaultQuarterSize / 2, 0},		// VkOffset3D				dstOffset;
8689 				{defaultQuarterSize / 2, defaultQuarterSize / 2, 1},	// VkExtent3D				extent;
8690 			};
8691 
8692 			CopyRegion	imageCopy;
8693 			imageCopy.imageCopy = testCopy;
8694 			params.regions.push_back(imageCopy);
8695 		}
8696 
8697 		group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
8698 	}
8699 
8700 	static const struct
8701 	{
8702 		std::string		name;
8703 		vk::VkFormat	format1;
8704 		vk::VkFormat	format2;
8705 	} formats [] =
8706 	{
8707 		{ "diff_format",	vk::VK_FORMAT_R32_UINT,			vk::VK_FORMAT_R8G8B8A8_UNORM	},
8708 		{ "same_format",	vk::VK_FORMAT_R8G8B8A8_UNORM,	vk::VK_FORMAT_R8G8B8A8_UNORM	}
8709 	};
8710 	static const struct
8711 	{
8712 		std::string		name;
8713 		vk::VkBool32	clear;
8714 	} clears [] =
8715 	{
8716 		{ "clear",		VK_TRUE		},
8717 		{ "noclear",	VK_FALSE	}
8718 	};
8719 	static const struct
8720 	{
8721 		std::string		name;
8722 		VkExtent3D		extent;
8723 	} extents [] =
8724 	{
8725 		{ "npot",	{65u, 63u, 1u}	},
8726 		{ "pot",	{64u, 64u, 1u}	}
8727 	};
8728 
8729 	for (const auto& format : formats)
8730 	{
8731 		for (const auto& clear : clears)
8732 		{
8733 			for (const auto& extent : extents)
8734 			{
8735 				TestParams	params;
8736 				params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8737 				params.src.image.format				= format.format1;
8738 				params.src.image.extent				= extent.extent;
8739 				params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8740 				params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8741 				params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8742 				params.dst.image.format				= format.format2;
8743 				params.dst.image.extent				= extent.extent;
8744 				params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8745 				params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8746 				params.allocationKind				= allocationKind;
8747 				params.extensionUse					= extensionUse;
8748 				params.clearDestination				= clear.clear;
8749 
8750 				{
8751 					VkImageCopy	testCopy	=
8752 					{
8753 						defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
8754 						{34, 34, 0},		// VkOffset3D				srcOffset;
8755 						defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
8756 						{0, 0, 0},			// VkOffset3D				dstOffset;
8757 						{31, 29, 1}			// VkExtent3D				extent;
8758 					};
8759 
8760 					if (extent.name == "pot")
8761 					{
8762 						testCopy.srcOffset	= { 16, 16, 0 };
8763 						testCopy.extent		= { 32, 32, 1 };
8764 					}
8765 
8766 					CopyRegion	imageCopy;
8767 					imageCopy.imageCopy = testCopy;
8768 					params.regions.push_back(imageCopy);
8769 				}
8770 
8771 				// Example test case name: "partial_image_npot_diff_format_clear"
8772 				const std::string testCaseName = "partial_image_" + extent.name + "_" + format.name + "_" + clear.name;
8773 
8774 				group->addChild(new CopyImageToImageTestCase(testCtx, testCaseName, "", params));
8775 			}
8776 		}
8777 	}
8778 
8779 	{
8780 		TestParams	params;
8781 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8782 		params.src.image.format				= VK_FORMAT_D32_SFLOAT;
8783 		params.src.image.extent				= defaultExtent;
8784 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8785 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8786 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8787 		params.dst.image.format				= VK_FORMAT_D32_SFLOAT;
8788 		params.dst.image.extent				= defaultExtent;
8789 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8790 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8791 		params.allocationKind				= allocationKind;
8792 		params.extensionUse					= extensionUse;
8793 
8794 		{
8795 			const VkImageSubresourceLayers  sourceLayer =
8796 			{
8797 				VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
8798 				0u,							// deUint32				mipLevel;
8799 				0u,							// deUint32				baseArrayLayer;
8800 				1u							// deUint32				layerCount;
8801 			};
8802 			const VkImageCopy				testCopy	=
8803 			{
8804 				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
8805 				{0, 0, 0},											// VkOffset3D				srcOffset;
8806 				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
8807 				{defaultQuarterSize, defaultQuarterSize / 2, 0},		// VkOffset3D				dstOffset;
8808 				{defaultQuarterSize / 2, defaultQuarterSize / 2, 1},	// VkExtent3D				extent;
8809 			};
8810 
8811 			CopyRegion	imageCopy;
8812 			imageCopy.imageCopy = testCopy;
8813 			params.regions.push_back(imageCopy);
8814 		}
8815 
8816 		group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
8817 	}
8818 
8819 	{
8820 		TestParams	params;
8821 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8822 		params.src.image.format				= VK_FORMAT_S8_UINT;
8823 		params.src.image.extent				= defaultExtent;
8824 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8825 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8826 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8827 		params.dst.image.format				= VK_FORMAT_S8_UINT;
8828 		params.dst.image.extent				= defaultExtent;
8829 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8830 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8831 		params.allocationKind				= allocationKind;
8832 		params.extensionUse					= extensionUse;
8833 
8834 		{
8835 			const VkImageSubresourceLayers  sourceLayer =
8836 			{
8837 				VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
8838 				0u,								// deUint32				mipLevel;
8839 				0u,								// deUint32				baseArrayLayer;
8840 				1u								// deUint32				layerCount;
8841 			};
8842 			const VkImageCopy				testCopy	=
8843 			{
8844 				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
8845 				{0, 0, 0},											// VkOffset3D				srcOffset;
8846 				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
8847 				{defaultQuarterSize, defaultQuarterSize / 2, 0},		// VkOffset3D				dstOffset;
8848 				{defaultQuarterSize / 2, defaultQuarterSize / 2, 1},	// VkExtent3D				extent;
8849 			};
8850 
8851 			CopyRegion	imageCopy;
8852 			imageCopy.imageCopy = testCopy;
8853 			params.regions.push_back(imageCopy);
8854 		}
8855 
8856 		group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
8857 	}
8858 }
8859 
8860 struct CopyColorTestParams
8861 {
8862 	TestParams		params;
8863 	const VkFormat*	compatibleFormats;
8864 };
8865 
addImageToImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,TestParams params)8866 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
8867 {
8868 	const VkImageLayout copySrcLayouts[]		=
8869 	{
8870 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
8871 		VK_IMAGE_LAYOUT_GENERAL
8872 	};
8873 	const VkImageLayout copyDstLayouts[]		=
8874 	{
8875 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
8876 		VK_IMAGE_LAYOUT_GENERAL
8877 	};
8878 
8879 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
8880 	{
8881 		params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
8882 
8883 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
8884 		{
8885 			params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
8886 
8887 			const std::string testName	= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
8888 										  getImageLayoutCaseName(params.dst.image.operationLayout);
8889 			const std::string description	= "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
8890 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
8891 			group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
8892 		}
8893 	}
8894 }
8895 
isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams & testParams)8896 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams& testParams)
8897 {
8898 	bool result = true;
8899 
8900 	if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
8901 	{
8902 		DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
8903 
8904 		result =
8905 			de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
8906 			de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
8907 	}
8908 
8909 	return result;
8910 }
8911 
addImageToImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,CopyColorTestParams testParams)8912 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
8913 {
8914 	// If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
8915 	const VkFormat	srcFormatOnly[2]	= { testParams.params.src.image.format, VK_FORMAT_UNDEFINED };
8916 	const VkFormat*	formatList			= (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);
8917 
8918 	for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
8919 	{
8920 		testParams.params.dst.image.format = formatList[dstFormatIndex];
8921 
8922 		const VkFormat		srcFormat	= testParams.params.src.image.format;
8923 		const VkFormat		dstFormat	= testParams.params.dst.image.format;
8924 
8925 		if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
8926 			continue;
8927 
8928 		if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
8929 			continue;
8930 
8931 		if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
8932 			if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) || (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
8933 				continue;
8934 
8935 		const std::string	description	= "Copy to destination format " + getFormatCaseName(dstFormat);
8936 		addTestGroup(group, getFormatCaseName(dstFormat), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
8937 	}
8938 }
8939 
8940 const VkFormat	compatibleFormats8Bit[]		=
8941 {
8942 	VK_FORMAT_R4G4_UNORM_PACK8,
8943 	VK_FORMAT_R8_UNORM,
8944 	VK_FORMAT_R8_SNORM,
8945 	VK_FORMAT_R8_USCALED,
8946 	VK_FORMAT_R8_SSCALED,
8947 	VK_FORMAT_R8_UINT,
8948 	VK_FORMAT_R8_SINT,
8949 	VK_FORMAT_R8_SRGB,
8950 
8951 	VK_FORMAT_UNDEFINED
8952 };
8953 const VkFormat	compatibleFormats16Bit[]	=
8954 {
8955 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
8956 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
8957 	VK_FORMAT_R5G6B5_UNORM_PACK16,
8958 	VK_FORMAT_B5G6R5_UNORM_PACK16,
8959 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
8960 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
8961 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
8962 	VK_FORMAT_R8G8_UNORM,
8963 	VK_FORMAT_R8G8_SNORM,
8964 	VK_FORMAT_R8G8_USCALED,
8965 	VK_FORMAT_R8G8_SSCALED,
8966 	VK_FORMAT_R8G8_UINT,
8967 	VK_FORMAT_R8G8_SINT,
8968 	VK_FORMAT_R8G8_SRGB,
8969 	VK_FORMAT_R16_UNORM,
8970 	VK_FORMAT_R16_SNORM,
8971 	VK_FORMAT_R16_USCALED,
8972 	VK_FORMAT_R16_SSCALED,
8973 	VK_FORMAT_R16_UINT,
8974 	VK_FORMAT_R16_SINT,
8975 	VK_FORMAT_R16_SFLOAT,
8976 	VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
8977 	VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
8978 
8979 	VK_FORMAT_UNDEFINED
8980 };
8981 const VkFormat	compatibleFormats24Bit[]	=
8982 {
8983 	VK_FORMAT_R8G8B8_UNORM,
8984 	VK_FORMAT_R8G8B8_SNORM,
8985 	VK_FORMAT_R8G8B8_USCALED,
8986 	VK_FORMAT_R8G8B8_SSCALED,
8987 	VK_FORMAT_R8G8B8_UINT,
8988 	VK_FORMAT_R8G8B8_SINT,
8989 	VK_FORMAT_R8G8B8_SRGB,
8990 	VK_FORMAT_B8G8R8_UNORM,
8991 	VK_FORMAT_B8G8R8_SNORM,
8992 	VK_FORMAT_B8G8R8_USCALED,
8993 	VK_FORMAT_B8G8R8_SSCALED,
8994 	VK_FORMAT_B8G8R8_UINT,
8995 	VK_FORMAT_B8G8R8_SINT,
8996 	VK_FORMAT_B8G8R8_SRGB,
8997 
8998 	VK_FORMAT_UNDEFINED
8999 };
9000 const VkFormat	compatibleFormats32Bit[]	=
9001 {
9002 	VK_FORMAT_R8G8B8A8_UNORM,
9003 	VK_FORMAT_R8G8B8A8_SNORM,
9004 	VK_FORMAT_R8G8B8A8_USCALED,
9005 	VK_FORMAT_R8G8B8A8_SSCALED,
9006 	VK_FORMAT_R8G8B8A8_UINT,
9007 	VK_FORMAT_R8G8B8A8_SINT,
9008 	VK_FORMAT_R8G8B8A8_SRGB,
9009 	VK_FORMAT_B8G8R8A8_UNORM,
9010 	VK_FORMAT_B8G8R8A8_SNORM,
9011 	VK_FORMAT_B8G8R8A8_USCALED,
9012 	VK_FORMAT_B8G8R8A8_SSCALED,
9013 	VK_FORMAT_B8G8R8A8_UINT,
9014 	VK_FORMAT_B8G8R8A8_SINT,
9015 	VK_FORMAT_B8G8R8A8_SRGB,
9016 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
9017 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
9018 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
9019 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
9020 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
9021 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
9022 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
9023 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
9024 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
9025 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
9026 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
9027 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
9028 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
9029 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
9030 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
9031 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
9032 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
9033 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
9034 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
9035 	VK_FORMAT_R16G16_UNORM,
9036 	VK_FORMAT_R16G16_SNORM,
9037 	VK_FORMAT_R16G16_USCALED,
9038 	VK_FORMAT_R16G16_SSCALED,
9039 	VK_FORMAT_R16G16_UINT,
9040 	VK_FORMAT_R16G16_SINT,
9041 	VK_FORMAT_R16G16_SFLOAT,
9042 	VK_FORMAT_R32_UINT,
9043 	VK_FORMAT_R32_SINT,
9044 	VK_FORMAT_R32_SFLOAT,
9045 
9046 	VK_FORMAT_UNDEFINED
9047 };
9048 const VkFormat	compatibleFormats48Bit[]	=
9049 {
9050 	VK_FORMAT_R16G16B16_UNORM,
9051 	VK_FORMAT_R16G16B16_SNORM,
9052 	VK_FORMAT_R16G16B16_USCALED,
9053 	VK_FORMAT_R16G16B16_SSCALED,
9054 	VK_FORMAT_R16G16B16_UINT,
9055 	VK_FORMAT_R16G16B16_SINT,
9056 	VK_FORMAT_R16G16B16_SFLOAT,
9057 
9058 	VK_FORMAT_UNDEFINED
9059 };
9060 const VkFormat	compatibleFormats64Bit[]	=
9061 {
9062 	VK_FORMAT_R16G16B16A16_UNORM,
9063 	VK_FORMAT_R16G16B16A16_SNORM,
9064 	VK_FORMAT_R16G16B16A16_USCALED,
9065 	VK_FORMAT_R16G16B16A16_SSCALED,
9066 	VK_FORMAT_R16G16B16A16_UINT,
9067 	VK_FORMAT_R16G16B16A16_SINT,
9068 	VK_FORMAT_R16G16B16A16_SFLOAT,
9069 	VK_FORMAT_R32G32_UINT,
9070 	VK_FORMAT_R32G32_SINT,
9071 	VK_FORMAT_R32G32_SFLOAT,
9072 	VK_FORMAT_R64_UINT,
9073 	VK_FORMAT_R64_SINT,
9074 	VK_FORMAT_R64_SFLOAT,
9075 
9076 	VK_FORMAT_BC1_RGB_UNORM_BLOCK,
9077 	VK_FORMAT_BC1_RGB_SRGB_BLOCK,
9078 	VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
9079 	VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
9080 	VK_FORMAT_BC4_UNORM_BLOCK,
9081 	VK_FORMAT_BC4_SNORM_BLOCK,
9082 
9083 	VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
9084 	VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
9085 	VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
9086 	VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
9087 
9088 	VK_FORMAT_EAC_R11_UNORM_BLOCK,
9089 	VK_FORMAT_EAC_R11_SNORM_BLOCK,
9090 
9091 	VK_FORMAT_UNDEFINED
9092 };
9093 const VkFormat	compatibleFormats96Bit[]	=
9094 {
9095 	VK_FORMAT_R32G32B32_UINT,
9096 	VK_FORMAT_R32G32B32_SINT,
9097 	VK_FORMAT_R32G32B32_SFLOAT,
9098 
9099 	VK_FORMAT_UNDEFINED
9100 };
9101 const VkFormat	compatibleFormats128Bit[]	=
9102 {
9103 	VK_FORMAT_R32G32B32A32_UINT,
9104 	VK_FORMAT_R32G32B32A32_SINT,
9105 	VK_FORMAT_R32G32B32A32_SFLOAT,
9106 	VK_FORMAT_R64G64_UINT,
9107 	VK_FORMAT_R64G64_SINT,
9108 	VK_FORMAT_R64G64_SFLOAT,
9109 
9110 	VK_FORMAT_BC2_UNORM_BLOCK,
9111 	VK_FORMAT_BC2_SRGB_BLOCK,
9112 	VK_FORMAT_BC3_UNORM_BLOCK,
9113 	VK_FORMAT_BC3_SRGB_BLOCK,
9114 	VK_FORMAT_BC5_UNORM_BLOCK,
9115 	VK_FORMAT_BC5_SNORM_BLOCK,
9116 	VK_FORMAT_BC6H_UFLOAT_BLOCK,
9117 	VK_FORMAT_BC6H_SFLOAT_BLOCK,
9118 	VK_FORMAT_BC7_UNORM_BLOCK,
9119 	VK_FORMAT_BC7_SRGB_BLOCK,
9120 
9121 	VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
9122 	VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
9123 
9124 	VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
9125 	VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
9126 
9127 	VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
9128 	VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
9129 	VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
9130 	VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
9131 	VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
9132 	VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
9133 	VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
9134 	VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
9135 	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
9136 	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
9137 	VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
9138 	VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
9139 	VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
9140 	VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
9141 	VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
9142 	VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
9143 	VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
9144 	VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
9145 	VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
9146 	VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
9147 	VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
9148 	VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
9149 	VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
9150 	VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
9151 	VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
9152 	VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
9153 	VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
9154 	VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
9155 
9156 	VK_FORMAT_UNDEFINED
9157 };
9158 const VkFormat	compatibleFormats192Bit[]	=
9159 {
9160 	VK_FORMAT_R64G64B64_UINT,
9161 	VK_FORMAT_R64G64B64_SINT,
9162 	VK_FORMAT_R64G64B64_SFLOAT,
9163 
9164 	VK_FORMAT_UNDEFINED
9165 };
9166 const VkFormat	compatibleFormats256Bit[]	=
9167 {
9168 	VK_FORMAT_R64G64B64A64_UINT,
9169 	VK_FORMAT_R64G64B64A64_SINT,
9170 	VK_FORMAT_R64G64B64A64_SFLOAT,
9171 
9172 	VK_FORMAT_UNDEFINED
9173 };
9174 
9175 const VkFormat*	colorImageFormatsToTest[]	=
9176 {
9177 	compatibleFormats8Bit,
9178 	compatibleFormats16Bit,
9179 	compatibleFormats24Bit,
9180 	compatibleFormats32Bit,
9181 	compatibleFormats48Bit,
9182 	compatibleFormats64Bit,
9183 	compatibleFormats96Bit,
9184 	compatibleFormats128Bit,
9185 	compatibleFormats192Bit,
9186 	compatibleFormats256Bit
9187 };
9188 
9189 const VkFormat	dedicatedAllocationImageToImageFormatsToTest[]	=
9190 {
9191 	// From compatibleFormats8Bit
9192 	VK_FORMAT_R4G4_UNORM_PACK8,
9193 	VK_FORMAT_R8_SRGB,
9194 
9195 	// From compatibleFormats16Bit
9196 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9197 	VK_FORMAT_R16_SFLOAT,
9198 
9199 	// From compatibleFormats24Bit
9200 	VK_FORMAT_R8G8B8_UNORM,
9201 	VK_FORMAT_B8G8R8_SRGB,
9202 
9203 	// From compatibleFormats32Bit
9204 	VK_FORMAT_R8G8B8A8_UNORM,
9205 	VK_FORMAT_R32_SFLOAT,
9206 
9207 	// From compatibleFormats48Bit
9208 	VK_FORMAT_R16G16B16_UNORM,
9209 	VK_FORMAT_R16G16B16_SFLOAT,
9210 
9211 	// From compatibleFormats64Bit
9212 	VK_FORMAT_R16G16B16A16_UNORM,
9213 	VK_FORMAT_R64_SFLOAT,
9214 
9215 	// From compatibleFormats96Bit
9216 	VK_FORMAT_R32G32B32_UINT,
9217 	VK_FORMAT_R32G32B32_SFLOAT,
9218 
9219 	// From compatibleFormats128Bit
9220 	VK_FORMAT_R32G32B32A32_UINT,
9221 	VK_FORMAT_R64G64_SFLOAT,
9222 
9223 	// From compatibleFormats192Bit
9224 	VK_FORMAT_R64G64B64_UINT,
9225 	VK_FORMAT_R64G64B64_SFLOAT,
9226 
9227 	// From compatibleFormats256Bit
9228 	VK_FORMAT_R64G64B64A64_UINT,
9229 	VK_FORMAT_R64G64B64A64_SFLOAT,
9230 };
9231 
addImageToImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9232 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9233 {
9234 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
9235 	{
9236 		const int numOfDedicatedAllocationImageToImageFormatsToTest = DE_LENGTH_OF_ARRAY(dedicatedAllocationImageToImageFormatsToTest);
9237 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfDedicatedAllocationImageToImageFormatsToTest; ++compatibleFormatsIndex)
9238 			dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
9239 	}
9240 
9241 	// 2D tests.
9242 	{
9243 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
9244 
9245 		TestParams	params;
9246 		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
9247 		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
9248 		params.src.image.extent		= defaultExtent;
9249 		params.dst.image.extent		= defaultExtent;
9250 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9251 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9252 		params.allocationKind		= allocationKind;
9253 		params.extensionUse			= extensionUse;
9254 
9255 		for (deInt32 i = 0; i < defaultSize; i += defaultQuarterSize)
9256 		{
9257 			const VkImageCopy				testCopy =
9258 			{
9259 				defaultSourceLayer,								// VkImageSubresourceLayers	srcSubresource;
9260 				{0, 0, 0},										// VkOffset3D				srcOffset;
9261 				defaultSourceLayer,								// VkImageSubresourceLayers	dstSubresource;
9262 				{i, defaultSize - i - defaultQuarterSize, 0},	// VkOffset3D				dstOffset;
9263 				{defaultQuarterSize, defaultQuarterSize, 1},		// VkExtent3D				extent;
9264 			};
9265 
9266 			CopyRegion	imageCopy;
9267 			imageCopy.imageCopy = testCopy;
9268 
9269 			params.regions.push_back(imageCopy);
9270 		}
9271 
9272 		const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
9273 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9274 		{
9275 			const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
9276 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9277 			{
9278 				params.src.image.format = compatibleFormats[srcFormatIndex];
9279 				if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
9280 					continue;
9281 
9282 				CopyColorTestParams	testParams;
9283 				testParams.params				= params;
9284 				testParams.compatibleFormats	= compatibleFormats;
9285 
9286 				const std::string testName		= getFormatCaseName(params.src.image.format);
9287 				const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
9288 				addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
9289 			}
9290 		}
9291 
9292 		group->addChild(subGroup.release());
9293 	}
9294 
9295 	// 1D tests.
9296 	{
9297 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
9298 
9299 		TestParams	params;
9300 		params.src.image.imageType	= VK_IMAGE_TYPE_1D;
9301 		params.dst.image.imageType	= VK_IMAGE_TYPE_1D;
9302 		params.src.image.extent		= default1dExtent;
9303 		params.dst.image.extent		= default1dExtent;
9304 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9305 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9306 		params.allocationKind		= allocationKind;
9307 		params.extensionUse			= extensionUse;
9308 
9309 		for (deInt32 i = defaultQuarterSize; i < defaultSize; i += defaultSize / 2)
9310 		{
9311 			const VkImageCopy				testCopy =
9312 			{
9313 				defaultSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
9314 				{0, 0, 0},					// VkOffset3D				srcOffset;
9315 				defaultSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
9316 				{i, 0, 0},					// VkOffset3D				dstOffset;
9317 				{defaultQuarterSize, 1, 1},	// VkExtent3D				extent;
9318 			};
9319 
9320 			CopyRegion	imageCopy;
9321 			imageCopy.imageCopy = testCopy;
9322 
9323 			params.regions.push_back(imageCopy);
9324 		}
9325 
9326 		const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
9327 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9328 		{
9329 			const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
9330 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9331 			{
9332 				params.src.image.format = compatibleFormats[srcFormatIndex];
9333 				if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
9334 					continue;
9335 
9336 				CopyColorTestParams	testParams;
9337 				testParams.params				= params;
9338 				testParams.compatibleFormats	= nullptr;
9339 
9340 				const std::string testName		= getFormatCaseName(params.src.image.format);
9341 				const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
9342 				addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
9343 			}
9344 		}
9345 
9346 		group->addChild(subGroup.release());
9347 	}
9348 
9349 	// 3D tests. Note we use smaller dimensions here for performance reasons.
9350 	{
9351 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
9352 
9353 		TestParams	params;
9354 		params.src.image.imageType	= VK_IMAGE_TYPE_3D;
9355 		params.dst.image.imageType	= VK_IMAGE_TYPE_3D;
9356 		params.src.image.extent		= default3dExtent;
9357 		params.dst.image.extent		= default3dExtent;
9358 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9359 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9360 		params.allocationKind		= allocationKind;
9361 		params.extensionUse			= extensionUse;
9362 
9363 		for (deInt32 i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
9364 		{
9365 			const VkImageCopy				testCopy =
9366 			{
9367 				defaultSourceLayer,													// VkImageSubresourceLayers	srcSubresource;
9368 				{0, 0, 0},															// VkOffset3D				srcOffset;
9369 				defaultSourceLayer,													// VkImageSubresourceLayers	dstSubresource;
9370 				{i, defaultQuarterSize - i - defaultSixteenthSize, i},				// VkOffset3D				dstOffset;
9371 				{defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize},	// VkExtent3D				extent;
9372 			};
9373 
9374 			CopyRegion	imageCopy;
9375 			imageCopy.imageCopy = testCopy;
9376 
9377 			params.regions.push_back(imageCopy);
9378 		}
9379 
9380 		const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
9381 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9382 		{
9383 			const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
9384 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9385 			{
9386 				params.src.image.format = compatibleFormats[srcFormatIndex];
9387 				if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
9388 					continue;
9389 
9390 				CopyColorTestParams	testParams;
9391 				testParams.params				= params;
9392 				testParams.compatibleFormats	= nullptr;
9393 
9394 				const std::string testName		= getFormatCaseName(params.src.image.format);
9395 				const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
9396 				addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
9397 			}
9398 		}
9399 
9400 		group->addChild(subGroup.release());
9401 	}
9402 }
9403 
addImageToImageDimensionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9404 void addImageToImageDimensionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9405 {
9406 	tcu::TestContext&		testCtx				= group->getTestContext();
9407 
9408 	const VkFormat			testFormats[][2]	=
9409 	{
9410 		// From compatibleFormats8Bit
9411 		{
9412 			VK_FORMAT_R4G4_UNORM_PACK8,
9413 			VK_FORMAT_R8_SRGB
9414 		},
9415 		// From compatibleFormats16Bit
9416 		{
9417 			VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9418 			VK_FORMAT_R16_SFLOAT,
9419 		},
9420 		// From compatibleFormats24Bit
9421 		{
9422 			VK_FORMAT_R8G8B8_UNORM,
9423 			VK_FORMAT_B8G8R8_SRGB
9424 		},
9425 		// From compatibleFormats32Bit
9426 		{
9427 			VK_FORMAT_R8G8B8A8_UNORM,
9428 			VK_FORMAT_R32_SFLOAT
9429 		},
9430 		// From compatibleFormats48Bit
9431 		{
9432 			VK_FORMAT_R16G16B16_UNORM,
9433 			VK_FORMAT_R16G16B16_SFLOAT
9434 		},
9435 		// From compatibleFormats64Bit
9436 		{
9437 			VK_FORMAT_R16G16B16A16_UNORM,
9438 			VK_FORMAT_R64_SFLOAT
9439 		},
9440 		// From compatibleFormats96Bit
9441 		{
9442 			VK_FORMAT_R32G32B32_UINT,
9443 			VK_FORMAT_R32G32B32_SFLOAT
9444 		},
9445 		// From compatibleFormats128Bit
9446 		{
9447 			VK_FORMAT_R32G32B32A32_UINT,
9448 			VK_FORMAT_R64G64_SFLOAT
9449 		},
9450 		// From compatibleFormats192Bit
9451 		{
9452 			VK_FORMAT_R64G64B64_UINT,
9453 			VK_FORMAT_R64G64B64_SFLOAT,
9454 		},
9455 		// From compatibleFormats256Bit
9456 		{
9457 			VK_FORMAT_R64G64B64A64_UINT,
9458 			VK_FORMAT_R64G64B64A64_SFLOAT
9459 		}
9460 	};
9461 
9462 	const tcu::UVec2		imageDimensions[]	=
9463 	{
9464 		// large pot x small pot
9465 		tcu::UVec2(4096,	4u),
9466 		tcu::UVec2(8192,	4u),
9467 		tcu::UVec2(16384,	4u),
9468 		tcu::UVec2(32768,	4u),
9469 
9470 		// large pot x small npot
9471 		tcu::UVec2(4096,	6u),
9472 		tcu::UVec2(8192,	6u),
9473 		tcu::UVec2(16384,	6u),
9474 		tcu::UVec2(32768,	6u),
9475 
9476 		// small pot x large pot
9477 		tcu::UVec2(4u, 4096),
9478 		tcu::UVec2(4u, 8192),
9479 		tcu::UVec2(4u, 16384),
9480 		tcu::UVec2(4u, 32768),
9481 
9482 		// small npot x large pot
9483 		tcu::UVec2(6u, 4096),
9484 		tcu::UVec2(6u, 8192),
9485 		tcu::UVec2(6u, 16384),
9486 		tcu::UVec2(6u, 32768)
9487 	};
9488 
9489 	const VkImageLayout		copySrcLayouts[]	=
9490 	{
9491 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
9492 		VK_IMAGE_LAYOUT_GENERAL
9493 	};
9494 
9495 	const VkImageLayout		copyDstLayouts[]	=
9496 	{
9497 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
9498 		VK_IMAGE_LAYOUT_GENERAL
9499 	};
9500 
9501 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
9502 	{
9503 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(dedicatedAllocationImageToImageFormatsToTest); compatibleFormatsIndex++)
9504 			dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
9505 	}
9506 
9507 	// Image dimensions
9508 	for (size_t dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); dimensionNdx++)
9509 	{
9510 		CopyRegion				copyRegion;
9511 		CopyColorTestParams		testParams;
9512 
9513 		const VkExtent3D		extent			= { imageDimensions[dimensionNdx].x(), imageDimensions[dimensionNdx].y(), 1 };
9514 
9515 		const VkImageCopy		testCopy		=
9516 		{
9517 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9518 			{0, 0, 0},			// VkOffset3D				srcOffset;
9519 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9520 			{0, 0, 0},			// VkOffset3D				dstOffset;
9521 			extent,				// VkExtent3D				extent;
9522 		};
9523 
9524 		testParams.params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9525 		testParams.params.src.image.imageType	= VK_IMAGE_TYPE_2D;
9526 		testParams.params.src.image.extent		= extent;
9527 
9528 		testParams.params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9529 		testParams.params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
9530 		testParams.params.dst.image.extent		= extent;
9531 
9532 		copyRegion.imageCopy					= testCopy;
9533 		testParams.params.allocationKind		= allocationKind;
9534 		testParams.params.extensionUse			= extensionUse;
9535 
9536 		testParams.params.regions.push_back(copyRegion);
9537 
9538 		const std::string	dimensionStr		= "src" + de::toString(testParams.params.src.image.extent.width) + "x" + de::toString(testParams.params.src.image.extent.height)
9539 												  + "_dst" + de::toString(testParams.params.dst.image.extent.width) + "x" + de::toString(testParams.params.dst.image.extent.height);
9540 		tcu::TestCaseGroup*	imageSizeGroup		= new tcu::TestCaseGroup(testCtx, dimensionStr.c_str(), ("Image sizes " + dimensionStr).c_str());
9541 
9542 		// Compatible formats for copying
9543 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
9544 		{
9545 			const VkFormat* compatibleFormats = testFormats[compatibleFormatsIndex];
9546 
9547 			testParams.compatibleFormats = compatibleFormats;
9548 
9549 			// Source image format
9550 			for (int srcFormatIndex = 0; srcFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); srcFormatIndex++)
9551 			{
9552 				testParams.params.src.image.format = testParams.compatibleFormats[srcFormatIndex];
9553 
9554 				if (!isSupportedByFramework(testParams.params.src.image.format) && !isCompressedFormat(testParams.params.src.image.format))
9555 					continue;
9556 
9557 				const std::string	srcDescription	= "Copy from source format " + getFormatCaseName(testParams.params.src.image.format);
9558 				tcu::TestCaseGroup*	srcFormatGroup	= new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.src.image.format).c_str(), srcDescription.c_str());
9559 
9560 				// Destination image format
9561 				for (int dstFormatIndex = 0; dstFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); dstFormatIndex++)
9562 				{
9563 					testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
9564 
9565 					if (!isSupportedByFramework(testParams.params.dst.image.format) && !isCompressedFormat(testParams.params.dst.image.format))
9566 						continue;
9567 
9568 					if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
9569 						continue;
9570 
9571 					if (isCompressedFormat(testParams.params.src.image.format) && isCompressedFormat(testParams.params.dst.image.format))
9572 					{
9573 						if ((getBlockWidth(testParams.params.src.image.format) != getBlockWidth(testParams.params.dst.image.format))
9574 							|| (getBlockHeight(testParams.params.src.image.format) != getBlockHeight(testParams.params.dst.image.format)))
9575 							continue;
9576 					}
9577 
9578 					const std::string	dstDescription	= "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
9579 					tcu::TestCaseGroup*	dstFormatGroup	= new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.dst.image.format).c_str(), dstDescription.c_str());
9580 
9581 					// Source/destionation image layouts
9582 					for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); srcLayoutNdx++)
9583 					{
9584 						testParams.params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
9585 
9586 						for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); dstLayoutNdx++)
9587 						{
9588 							testParams.params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
9589 
9590 							const std::string	testName	= getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
9591 							const std::string	description	= "From layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
9592 							const TestParams	params		= testParams.params;
9593 
9594 							dstFormatGroup->addChild(new CopyImageToImageTestCase(testCtx, testName, description, params));
9595 						}
9596 					}
9597 
9598 					srcFormatGroup->addChild(dstFormatGroup);
9599 				}
9600 
9601 				imageSizeGroup->addChild(srcFormatGroup);
9602 			}
9603 		}
9604 
9605 		group->addChild(imageSizeGroup);
9606 	}
9607 }
9608 
addImageToImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)9609 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
9610 {
9611 	const VkImageLayout copySrcLayouts[]		=
9612 	{
9613 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
9614 		VK_IMAGE_LAYOUT_GENERAL
9615 	};
9616 	const VkImageLayout copyDstLayouts[]		=
9617 	{
9618 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
9619 		VK_IMAGE_LAYOUT_GENERAL
9620 	};
9621 
9622 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
9623 	{
9624 		params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
9625 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
9626 		{
9627 			params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
9628 
9629 			const std::string testName		= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
9630 											  getImageLayoutCaseName(params.dst.image.operationLayout);
9631 			const std::string description	= "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
9632 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
9633 			group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
9634 		}
9635 	}
9636 }
9637 
addImageToImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9638 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9639 {
9640 	const VkFormat	depthAndStencilFormats[]	=
9641 	{
9642 		VK_FORMAT_D16_UNORM,
9643 		VK_FORMAT_X8_D24_UNORM_PACK32,
9644 		VK_FORMAT_D32_SFLOAT,
9645 		VK_FORMAT_S8_UINT,
9646 		VK_FORMAT_D16_UNORM_S8_UINT,
9647 		VK_FORMAT_D24_UNORM_S8_UINT,
9648 		VK_FORMAT_D32_SFLOAT_S8_UINT,
9649 	};
9650 
9651 	// 2D tests.
9652 	{
9653 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
9654 
9655 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9656 		{
9657 			TestParams	params;
9658 			params.src.image.imageType			= VK_IMAGE_TYPE_2D;
9659 			params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
9660 			params.src.image.extent				= defaultExtent;
9661 			params.dst.image.extent				= defaultExtent;
9662 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
9663 			params.dst.image.format				= params.src.image.format;
9664 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9665 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9666 			params.allocationKind				= allocationKind;
9667 			params.extensionUse					= extensionUse;
9668 			params.separateDepthStencilLayouts	= DE_FALSE;
9669 
9670 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9671 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9672 
9673 			const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9674 			const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9675 			const VkImageSubresourceLayers		defaultDSSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9676 
9677 			for (deInt32 i = 0; i < defaultSize; i += defaultQuarterSize)
9678 			{
9679 				CopyRegion			copyRegion;
9680 				const VkOffset3D	srcOffset	= {0, 0, 0};
9681 				const VkOffset3D	dstOffset	= {i, defaultSize - i - defaultQuarterSize, 0};
9682 				const VkExtent3D	extent		= {defaultQuarterSize, defaultQuarterSize, 1};
9683 
9684 				if (hasDepth)
9685 				{
9686 					const VkImageCopy				testCopy	=
9687 					{
9688 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9689 						srcOffset,					// VkOffset3D				srcOffset;
9690 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9691 						dstOffset,					// VkOffset3D				dstOffset;
9692 						extent,						// VkExtent3D				extent;
9693 					};
9694 
9695 					copyRegion.imageCopy	= testCopy;
9696 					params.regions.push_back(copyRegion);
9697 				}
9698 				if (hasStencil)
9699 				{
9700 					const VkImageCopy				testCopy	=
9701 					{
9702 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9703 						srcOffset,					// VkOffset3D				srcOffset;
9704 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9705 						dstOffset,					// VkOffset3D				dstOffset;
9706 						extent,						// VkExtent3D				extent;
9707 					};
9708 
9709 					copyRegion.imageCopy	= testCopy;
9710 					params.regions.push_back(copyRegion);
9711 				}
9712 			}
9713 
9714 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9715 			const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9716 			addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9717 
9718 			if (hasDepth && hasStencil)
9719 			{
9720 				params.separateDepthStencilLayouts	= DE_TRUE;
9721 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9722 				const std::string description2	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9723 				addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9724 
9725 				// DS Image copy
9726 				{
9727 					params.separateDepthStencilLayouts	= DE_FALSE;
9728 					// Clear previous vkImageCopy elements
9729 					params.regions.clear();
9730 
9731 					for (deInt32 i = 0; i < defaultSize; i += defaultQuarterSize)
9732 					{
9733 						CopyRegion			copyRegion;
9734 						const VkOffset3D	srcOffset	= {0, 0, 0};
9735 						const VkOffset3D	dstOffset	= {i, defaultSize - i - defaultQuarterSize, 0};
9736 						const VkExtent3D	extent		= {defaultQuarterSize, defaultQuarterSize, 1};
9737 
9738 						const VkImageCopy				testCopy	=
9739 						{
9740 							defaultDSSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
9741 							srcOffset,					// VkOffset3D				srcOffset;
9742 							defaultDSSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
9743 							dstOffset,					// VkOffset3D				dstOffset;
9744 							extent,						// VkExtent3D				extent;
9745 						};
9746 
9747 						copyRegion.imageCopy	= testCopy;
9748 						params.regions.push_back(copyRegion);
9749 					}
9750 
9751 					const std::string testName3		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
9752 					const std::string description3	= "Copy both depth and stencil aspects from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9753 					addTestGroup(subGroup.get(), testName3, description3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9754 				}
9755 			}
9756 		}
9757 
9758 		group->addChild(subGroup.release());
9759 	}
9760 
9761 	// 1D tests.
9762 	{
9763 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
9764 
9765 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9766 		{
9767 			TestParams	params;
9768 			params.src.image.imageType			= VK_IMAGE_TYPE_1D;
9769 			params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
9770 			params.src.image.extent				= default1dExtent;
9771 			params.dst.image.extent				= default1dExtent;
9772 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
9773 			params.dst.image.format				= params.src.image.format;
9774 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9775 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9776 			params.allocationKind				= allocationKind;
9777 			params.extensionUse					= extensionUse;
9778 
9779 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9780 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9781 
9782 			const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9783 			const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9784 
9785 			for (deInt32 i = defaultQuarterSize; i < defaultSize; i += defaultSize / 2)
9786 			{
9787 				CopyRegion			copyRegion;
9788 				const VkOffset3D	srcOffset	= {0, 0, 0};
9789 				const VkOffset3D	dstOffset	= {i, 0, 0};
9790 				const VkExtent3D	extent		= {defaultQuarterSize, 1, 1};
9791 
9792 				if (hasDepth)
9793 				{
9794 					const VkImageCopy				testCopy	=
9795 					{
9796 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9797 						srcOffset,					// VkOffset3D				srcOffset;
9798 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9799 						dstOffset,					// VkOffset3D				dstOffset;
9800 						extent,						// VkExtent3D				extent;
9801 					};
9802 
9803 					copyRegion.imageCopy	= testCopy;
9804 					params.regions.push_back(copyRegion);
9805 				}
9806 				if (hasStencil)
9807 				{
9808 					const VkImageCopy				testCopy	=
9809 					{
9810 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9811 						srcOffset,					// VkOffset3D				srcOffset;
9812 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9813 						dstOffset,					// VkOffset3D				dstOffset;
9814 						extent,						// VkExtent3D				extent;
9815 					};
9816 
9817 					copyRegion.imageCopy	= testCopy;
9818 					params.regions.push_back(copyRegion);
9819 				}
9820 			}
9821 
9822 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9823 			const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9824 			addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9825 
9826 			if (hasDepth && hasStencil)
9827 			{
9828 				params.separateDepthStencilLayouts	= DE_TRUE;
9829 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9830 				const std::string description2	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9831 				addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9832 			}
9833 		}
9834 
9835 		group->addChild(subGroup.release());
9836 	}
9837 
9838 	// 3D tests. Note we use smaller dimensions here for performance reasons.
9839 	{
9840 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
9841 
9842 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9843 		{
9844 			TestParams	params;
9845 			params.src.image.imageType			= VK_IMAGE_TYPE_3D;
9846 			params.dst.image.imageType			= VK_IMAGE_TYPE_3D;
9847 			params.src.image.extent				= default3dExtent;
9848 			params.dst.image.extent				= default3dExtent;
9849 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
9850 			params.dst.image.format				= params.src.image.format;
9851 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9852 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9853 			params.allocationKind				= allocationKind;
9854 			params.extensionUse					= extensionUse;
9855 
9856 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9857 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9858 
9859 			const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9860 			const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9861 
9862 			for (deInt32 i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
9863 			{
9864 				CopyRegion			copyRegion;
9865 				const VkOffset3D	srcOffset	= {0, 0, 0};
9866 				const VkOffset3D	dstOffset	= {i, defaultQuarterSize - i - defaultSixteenthSize, i};
9867 				const VkExtent3D	extent		= {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
9868 
9869 				if (hasDepth)
9870 				{
9871 					const VkImageCopy				testCopy	=
9872 					{
9873 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9874 						srcOffset,					// VkOffset3D				srcOffset;
9875 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9876 						dstOffset,					// VkOffset3D				dstOffset;
9877 						extent,						// VkExtent3D				extent;
9878 					};
9879 
9880 					copyRegion.imageCopy	= testCopy;
9881 					params.regions.push_back(copyRegion);
9882 				}
9883 				if (hasStencil)
9884 				{
9885 					const VkImageCopy				testCopy	=
9886 					{
9887 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9888 						srcOffset,					// VkOffset3D				srcOffset;
9889 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9890 						dstOffset,					// VkOffset3D				dstOffset;
9891 						extent,						// VkExtent3D				extent;
9892 					};
9893 
9894 					copyRegion.imageCopy	= testCopy;
9895 					params.regions.push_back(copyRegion);
9896 				}
9897 			}
9898 
9899 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9900 			const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9901 			addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9902 
9903 			if (hasDepth && hasStencil)
9904 			{
9905 				params.separateDepthStencilLayouts	= DE_TRUE;
9906 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9907 				const std::string description2	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9908 				addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9909 			}
9910 		}
9911 
9912 		group->addChild(subGroup.release());
9913 	}
9914 }
9915 
addImageToImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9916 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9917 {
9918 	addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind, extensionUse);
9919 	addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
9920 }
9921 
addImageToImage3dImagesTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9922 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9923 {
9924 	tcu::TestContext& testCtx	= group->getTestContext();
9925 
9926 	{
9927 		TestParams	params3DTo2D;
9928 		const deUint32	slicesLayers			= 16u;
9929 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
9930 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
9931 		params3DTo2D.src.image.extent			= defaultHalfExtent;
9932 		params3DTo2D.src.image.extent.depth		= slicesLayers;
9933 		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
9934 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9935 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
9936 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
9937 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
9938 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
9939 		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
9940 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9941 		params3DTo2D.allocationKind				= allocationKind;
9942 		params3DTo2D.extensionUse				= extensionUse;
9943 
9944 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
9945 		{
9946 			const VkImageSubresourceLayers	sourceLayer	=
9947 			{
9948 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
9949 				0u,							// deUint32				mipLevel;
9950 				0u,							// deUint32				baseArrayLayer;
9951 				1u							// deUint32				layerCount;
9952 			};
9953 
9954 			const VkImageSubresourceLayers	destinationLayer	=
9955 			{
9956 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
9957 				0u,							// deUint32				mipLevel;
9958 				slicesLayersNdx,			// deUint32				baseArrayLayer;
9959 				1u							// deUint32				layerCount;
9960 			};
9961 
9962 			const VkImageCopy				testCopy	=
9963 			{
9964 				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
9965 				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D				srcOffset;
9966 				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
9967 				{0, 0, 0},							// VkOffset3D				dstOffset;
9968 				defaultHalfExtent,					// VkExtent3D				extent;
9969 			};
9970 
9971 			CopyRegion	imageCopy;
9972 			imageCopy.imageCopy	= testCopy;
9973 
9974 			params3DTo2D.regions.push_back(imageCopy);
9975 		}
9976 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
9977 	}
9978 
9979 	{
9980 		TestParams	params2DTo3D;
9981 		const deUint32	slicesLayers			= 16u;
9982 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
9983 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
9984 		params2DTo3D.src.image.extent			= defaultHalfExtent;
9985 		params2DTo3D.src.image.extent.depth		= slicesLayers;
9986 		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
9987 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9988 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
9989 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
9990 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
9991 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
9992 		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
9993 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9994 		params2DTo3D.allocationKind				= allocationKind;
9995 		params2DTo3D.extensionUse				= extensionUse;
9996 
9997 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
9998 		{
9999 			const VkImageSubresourceLayers	sourceLayer	=
10000 			{
10001 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10002 				0u,							// deUint32				mipLevel;
10003 				slicesLayersNdx,			// deUint32				baseArrayLayer;
10004 				1u							// deUint32				layerCount;
10005 			};
10006 
10007 			const VkImageSubresourceLayers	destinationLayer	=
10008 			{
10009 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10010 				0u,							// deUint32				mipLevel;
10011 				0u,							// deUint32				baseArrayLayer;
10012 				1u							// deUint32				layerCount;
10013 			};
10014 
10015 			const VkImageCopy				testCopy	=
10016 			{
10017 				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
10018 				{0, 0, 0},							// VkOffset3D				srcOffset;
10019 				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
10020 				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D				dstOffset;
10021 				defaultHalfExtent,					// VkExtent3D				extent;
10022 			};
10023 
10024 			CopyRegion	imageCopy;
10025 			imageCopy.imageCopy	= testCopy;
10026 
10027 			params2DTo3D.regions.push_back(imageCopy);
10028 		}
10029 
10030 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
10031 	}
10032 
10033 	{
10034 		TestParams	params3DTo2D;
10035 		const deUint32	slicesLayers			= 16u;
10036 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
10037 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10038 		params3DTo2D.src.image.extent			= defaultHalfExtent;
10039 		params3DTo2D.src.image.extent.depth		= slicesLayers;
10040 		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10041 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10042 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10043 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10044 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
10045 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
10046 		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10047 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10048 		params3DTo2D.allocationKind				= allocationKind;
10049 		params3DTo2D.extensionUse				= extensionUse;
10050 
10051 		{
10052 			const VkImageSubresourceLayers	sourceLayer	=
10053 			{
10054 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10055 				0u,							// deUint32				mipLevel;
10056 				0u,							// deUint32				baseArrayLayer;
10057 				1u							// deUint32				layerCount;
10058 			};
10059 
10060 			const VkImageSubresourceLayers	destinationLayer	=
10061 			{
10062 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10063 				0u,							// deUint32				mipLevel;
10064 				0,							// deUint32				baseArrayLayer;
10065 				slicesLayers				// deUint32				layerCount;
10066 			};
10067 
10068 			const VkImageCopy				testCopy	=
10069 			{
10070 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
10071 				{0, 0, 0},						// VkOffset3D				srcOffset;
10072 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
10073 				{0, 0, 0},						// VkOffset3D				dstOffset;
10074 				params3DTo2D.src.image.extent	// VkExtent3D				extent;
10075 			};
10076 
10077 			CopyRegion	imageCopy;
10078 			imageCopy.imageCopy	= testCopy;
10079 
10080 			params3DTo2D.regions.push_back(imageCopy);
10081 		}
10082 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
10083 	}
10084 
10085 	{
10086 		TestParams	params2DTo3D;
10087 		const deUint32	slicesLayers			= 16u;
10088 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
10089 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10090 		params2DTo3D.src.image.extent			= defaultHalfExtent;
10091 		params2DTo3D.src.image.extent.depth		= slicesLayers;
10092 		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10093 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10094 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
10095 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10096 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
10097 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
10098 		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10099 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10100 		params2DTo3D.allocationKind				= allocationKind;
10101 		params2DTo3D.extensionUse				= extensionUse;
10102 
10103 		{
10104 			const VkImageSubresourceLayers	sourceLayer	=
10105 			{
10106 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10107 				0u,							// deUint32				mipLevel;
10108 				0u,							// deUint32				baseArrayLayer;
10109 				slicesLayers				// deUint32				layerCount;
10110 			};
10111 
10112 			const VkImageSubresourceLayers	destinationLayer	=
10113 			{
10114 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10115 				0u,							// deUint32				mipLevel;
10116 				0u,							// deUint32				baseArrayLayer;
10117 				1u							// deUint32				layerCount;
10118 			};
10119 
10120 			const VkImageCopy				testCopy	=
10121 			{
10122 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
10123 				{0, 0, 0},						// VkOffset3D				srcOffset;
10124 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
10125 				{0, 0, 0},						// VkOffset3D				dstOffset;
10126 				params2DTo3D.src.image.extent,	// VkExtent3D				extent;
10127 			};
10128 
10129 			CopyRegion	imageCopy;
10130 			imageCopy.imageCopy	= testCopy;
10131 
10132 			params2DTo3D.regions.push_back(imageCopy);
10133 		}
10134 
10135 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
10136 	}
10137 
10138 	{
10139 		TestParams	params3DTo2D;
10140 		const deUint32	slicesLayers			= 16u;
10141 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
10142 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10143 		params3DTo2D.src.image.extent			= defaultHalfExtent;
10144 		params3DTo2D.src.image.extent.depth		= slicesLayers;
10145 		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10146 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10147 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10148 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10149 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
10150 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
10151 		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10152 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10153 		params3DTo2D.allocationKind				= allocationKind;
10154 		params3DTo2D.extensionUse				= extensionUse;
10155 
10156 		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
10157 		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;
10158 
10159 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
10160 		{
10161 			const VkImageSubresourceLayers	sourceLayer	=
10162 			{
10163 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10164 				0u,							// deUint32				mipLevel;
10165 				0u,							// deUint32				baseArrayLayer;
10166 				1u							// deUint32				layerCount;
10167 			};
10168 
10169 			const VkImageSubresourceLayers	destinationLayer	=
10170 			{
10171 					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10172 					0u,								// deUint32				mipLevel;
10173 					slicesLayersNdx,				// deUint32				baseArrayLayer;
10174 					1u								// deUint32				layerCount;
10175 			};
10176 
10177 
10178 			const VkImageCopy				testCopy	=
10179 			{
10180 				sourceLayer,															// VkImageSubresourceLayers	srcSubresource;
10181 				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx},	// VkOffset3D				srcOffset;
10182 					destinationLayer,													// VkImageSubresourceLayers	dstSubresource;
10183 					{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},						// VkOffset3D				dstOffset;
10184 					{
10185 						(defaultHalfExtent.width - regionWidth*slicesLayersNdx),
10186 						(defaultHalfExtent.height - regionHeight*slicesLayersNdx),
10187 						1
10188 					}																	// VkExtent3D				extent;
10189 			};
10190 
10191 			CopyRegion	imageCopy;
10192 			imageCopy.imageCopy = testCopy;
10193 			params3DTo2D.regions.push_back(imageCopy);
10194 		}
10195 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
10196 	}
10197 
10198 	{
10199 		TestParams	params2DTo3D;
10200 		const deUint32	slicesLayers			= 16u;
10201 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
10202 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10203 		params2DTo3D.src.image.extent			= defaultHalfExtent;
10204 		params2DTo3D.src.image.extent.depth		= slicesLayers;
10205 		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10206 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10207 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
10208 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10209 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
10210 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
10211 		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10212 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10213 		params2DTo3D.allocationKind				= allocationKind;
10214 		params2DTo3D.extensionUse				= extensionUse;
10215 
10216 		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
10217 		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;
10218 
10219 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
10220 		{
10221 			const VkImageSubresourceLayers	sourceLayer	=
10222 			{
10223 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10224 				0u,							// deUint32				mipLevel;
10225 				slicesLayersNdx,			// deUint32				baseArrayLayer;
10226 				1u							// deUint32				layerCount;
10227 			};
10228 
10229 			const VkImageSubresourceLayers	destinationLayer	=
10230 			{
10231 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10232 				0u,							// deUint32				mipLevel;
10233 				0u,							// deUint32				baseArrayLayer;
10234 				1u							// deUint32				layerCount;
10235 			};
10236 
10237 			const VkImageCopy				testCopy	=
10238 			{
10239 				sourceLayer,																// VkImageSubresourceLayers	srcSubresource;
10240 				{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},								// VkOffset3D				srcOffset;
10241 				destinationLayer,															// VkImageSubresourceLayers	dstSubresource;
10242 				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)},	// VkOffset3D				dstOffset;
10243 				{
10244 					defaultHalfExtent.width - regionWidth*slicesLayersNdx,
10245 					defaultHalfExtent.height - regionHeight*slicesLayersNdx,
10246 					1
10247 				}																			// VkExtent3D				extent;
10248 			};
10249 
10250 			CopyRegion	imageCopy;
10251 			imageCopy.imageCopy	= testCopy;
10252 
10253 			params2DTo3D.regions.push_back(imageCopy);
10254 		}
10255 
10256 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
10257 	}
10258 }
10259 
addImageToImageCubeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10260 void addImageToImageCubeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10261 {
10262 	tcu::TestContext& testCtx	= group->getTestContext();
10263 
10264 	{
10265 		TestParams	paramsCubeToArray;
10266 		const deUint32	arrayLayers					= 6u;
10267 		paramsCubeToArray.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10268 		paramsCubeToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
10269 		paramsCubeToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10270 		paramsCubeToArray.src.image.extent			= defaultHalfExtent;
10271 		paramsCubeToArray.src.image.extent.depth	= arrayLayers;
10272 		paramsCubeToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10273 		paramsCubeToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10274 		paramsCubeToArray.dst.image.createFlags		= 0;
10275 		paramsCubeToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10276 		paramsCubeToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10277 		paramsCubeToArray.dst.image.extent			= defaultHalfExtent;
10278 		paramsCubeToArray.dst.image.extent.depth	= arrayLayers;
10279 		paramsCubeToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10280 		paramsCubeToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10281 		paramsCubeToArray.allocationKind			= allocationKind;
10282 		paramsCubeToArray.extensionUse				= extensionUse;
10283 
10284 		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10285 		{
10286 			const VkImageSubresourceLayers	sourceLayer	=
10287 				{
10288 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10289 					0u,							// deUint32				mipLevel;
10290 					arrayLayersNdx,				// deUint32				baseArrayLayer;
10291 					1u							// deUint32				layerCount;
10292 				};
10293 
10294 			const VkImageSubresourceLayers	destinationLayer	=
10295 				{
10296 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10297 					0u,							// deUint32				mipLevel;
10298 					arrayLayersNdx,				// deUint32				baseArrayLayer;
10299 					1u							// deUint32				layerCount;
10300 				};
10301 
10302 			const VkImageCopy				testCopy	=
10303 				{
10304 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
10305 					{0, 0, 0},					// VkOffset3D				srcOffset;
10306 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
10307 					{0, 0, 0},					// VkOffset3D				dstOffset;
10308 					defaultHalfExtent				// VkExtent3D				extent;
10309 				};
10310 
10311 			CopyRegion	imageCopy;
10312 			imageCopy.imageCopy	= testCopy;
10313 
10314 			paramsCubeToArray.regions.push_back(imageCopy);
10315 		}
10316 
10317 		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_layers", "copy cube compatible image to 2d layers layer by layer", paramsCubeToArray));
10318 	}
10319 
10320 	{
10321 		TestParams	paramsCubeToArray;
10322 		const deUint32	arrayLayers					= 6u;
10323 		paramsCubeToArray.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10324 		paramsCubeToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
10325 		paramsCubeToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10326 		paramsCubeToArray.src.image.extent			= defaultHalfExtent;
10327 		paramsCubeToArray.src.image.extent.depth	= arrayLayers;
10328 		paramsCubeToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10329 		paramsCubeToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10330 		paramsCubeToArray.dst.image.createFlags		= 0;
10331 		paramsCubeToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10332 		paramsCubeToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10333 		paramsCubeToArray.dst.image.extent			= defaultHalfExtent;
10334 		paramsCubeToArray.dst.image.extent.depth	= arrayLayers;
10335 		paramsCubeToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10336 		paramsCubeToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10337 		paramsCubeToArray.allocationKind			= allocationKind;
10338 		paramsCubeToArray.extensionUse				= extensionUse;
10339 
10340 		{
10341 			const VkImageSubresourceLayers	sourceLayer	=
10342 				{
10343 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10344 					0u,							// deUint32				mipLevel;
10345 					0u,							// deUint32				baseArrayLayer;
10346 					arrayLayers					// deUint32				layerCount;
10347 				};
10348 
10349 			const VkImageSubresourceLayers	destinationLayer	=
10350 				{
10351 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10352 					0u,							// deUint32				mipLevel;
10353 					0u,							// deUint32				baseArrayLayer;
10354 					arrayLayers					// deUint32				layerCount;
10355 				};
10356 
10357 			const VkImageCopy				testCopy	=
10358 				{
10359 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
10360 					{0, 0, 0},					// VkOffset3D				srcOffset;
10361 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
10362 					{0, 0, 0},					// VkOffset3D				dstOffset;
10363 					defaultHalfExtent			// VkExtent3D				extent;
10364 				};
10365 
10366 			CopyRegion	imageCopy;
10367 			imageCopy.imageCopy	= testCopy;
10368 
10369 			paramsCubeToArray.regions.push_back(imageCopy);
10370 		}
10371 
10372 		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_whole", "copy cube compatible image to 2d layers all at once", paramsCubeToArray));
10373 	}
10374 
10375 	{
10376 		TestParams	paramsArrayToCube;
10377 		const deUint32	arrayLayers					= 6u;
10378 		paramsArrayToCube.src.image.createFlags		= 0;
10379 		paramsArrayToCube.src.image.imageType		= VK_IMAGE_TYPE_2D;
10380 		paramsArrayToCube.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10381 		paramsArrayToCube.src.image.extent			= defaultHalfExtent;
10382 		paramsArrayToCube.src.image.extent.depth	= arrayLayers;
10383 		paramsArrayToCube.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10384 		paramsArrayToCube.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10385 		paramsArrayToCube.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10386 		paramsArrayToCube.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10387 		paramsArrayToCube.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10388 		paramsArrayToCube.dst.image.extent			= defaultHalfExtent;
10389 		paramsArrayToCube.dst.image.extent.depth	= arrayLayers;
10390 		paramsArrayToCube.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10391 		paramsArrayToCube.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10392 		paramsArrayToCube.allocationKind			= allocationKind;
10393 		paramsArrayToCube.extensionUse				= extensionUse;
10394 
10395 		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10396 		{
10397 			const VkImageSubresourceLayers	sourceLayer	=
10398 				{
10399 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10400 					0u,							// deUint32				mipLevel;
10401 					arrayLayersNdx,				// deUint32				baseArrayLayer;
10402 					1u							// deUint32				layerCount;
10403 				};
10404 
10405 			const VkImageSubresourceLayers	destinationLayer =
10406 				{
10407 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10408 					0u,							// deUint32				mipLevel;
10409 					arrayLayersNdx,				// deUint32				baseArrayLayer;
10410 					1u							// deUint32				layerCount;
10411 				};
10412 
10413 			const VkImageCopy				testCopy =
10414 				{
10415 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
10416 					{0, 0, 0},					// VkOffset3D				srcOffset;
10417 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
10418 					{0, 0, 0},					// VkOffset3D				dstOffset;
10419 					defaultHalfExtent			// VkExtent3D				extent;
10420 				};
10421 
10422 			CopyRegion	imageCopy;
10423 			imageCopy.imageCopy	= testCopy;
10424 
10425 			paramsArrayToCube.regions.push_back(imageCopy);
10426 		}
10427 
10428 		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_layers", "copy 2d layers to cube compatible image layer by layer", paramsArrayToCube));
10429 	}
10430 
10431 	{
10432 		TestParams	paramsArrayToCube;
10433 		const deUint32	arrayLayers					= 6u;
10434 		paramsArrayToCube.src.image.createFlags		= 0;
10435 		paramsArrayToCube.src.image.imageType		= VK_IMAGE_TYPE_2D;
10436 		paramsArrayToCube.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10437 		paramsArrayToCube.src.image.extent			= defaultHalfExtent;
10438 		paramsArrayToCube.src.image.extent.depth	= arrayLayers;
10439 		paramsArrayToCube.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10440 		paramsArrayToCube.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10441 		paramsArrayToCube.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10442 		paramsArrayToCube.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10443 		paramsArrayToCube.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10444 		paramsArrayToCube.dst.image.extent			= defaultHalfExtent;
10445 		paramsArrayToCube.dst.image.extent.depth	= arrayLayers;
10446 		paramsArrayToCube.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10447 		paramsArrayToCube.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10448 		paramsArrayToCube.allocationKind			= allocationKind;
10449 		paramsArrayToCube.extensionUse				= extensionUse;
10450 
10451 		{
10452 			const VkImageSubresourceLayers sourceLayer =
10453 				{
10454 					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10455 					0u,								// deUint32				mipLevel;
10456 					0u,								// deUint32				baseArrayLayer;
10457 					arrayLayers						// deUint32				layerCount;
10458 				};
10459 
10460 			const VkImageSubresourceLayers destinationLayer =
10461 				{
10462 					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10463 					0u,								// deUint32				mipLevel;
10464 					0u,								// deUint32				baseArrayLayer;
10465 					arrayLayers						// deUint32				layerCount;
10466 				};
10467 
10468 			const VkImageCopy				testCopy =
10469 				{
10470 					sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
10471 					{0, 0, 0},						// VkOffset3D				srcOffset;
10472 					destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
10473 					{0, 0, 0},						// VkOffset3D				dstOffset;
10474 					defaultHalfExtent				// VkExtent3D				extent;
10475 				};
10476 
10477 			CopyRegion imageCopy;
10478 			imageCopy.imageCopy = testCopy;
10479 
10480 			paramsArrayToCube.regions.push_back(imageCopy);
10481 		}
10482 
10483 		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_whole", "copy 2d layers to cube compatible image all at once", paramsArrayToCube));
10484 	}
10485 
10486 	{
10487 		TestParams	paramsCubeToArray;
10488 		const deUint32	arrayLayers					= 6u;
10489 		paramsCubeToArray.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10490 		paramsCubeToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
10491 		paramsCubeToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10492 		paramsCubeToArray.src.image.extent			= defaultHalfExtent;
10493 		paramsCubeToArray.src.image.extent.depth	= arrayLayers;
10494 		paramsCubeToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10495 		paramsCubeToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10496 		paramsCubeToArray.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10497 		paramsCubeToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10498 		paramsCubeToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10499 		paramsCubeToArray.dst.image.extent			= defaultHalfExtent;
10500 		paramsCubeToArray.dst.image.extent.depth	= arrayLayers;
10501 		paramsCubeToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10502 		paramsCubeToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10503 		paramsCubeToArray.allocationKind			= allocationKind;
10504 		paramsCubeToArray.extensionUse				= extensionUse;
10505 
10506 		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10507 		{
10508 			const VkImageSubresourceLayers	sourceLayer	=
10509 				{
10510 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10511 					0u,							// deUint32				mipLevel;
10512 					arrayLayersNdx,				// deUint32				baseArrayLayer;
10513 					1u							// deUint32				layerCount;
10514 				};
10515 
10516 			const VkImageSubresourceLayers	destinationLayer	=
10517 				{
10518 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10519 					0u,							// deUint32				mipLevel;
10520 					arrayLayersNdx,				// deUint32				baseArrayLayer;
10521 					1u							// deUint32				layerCount;
10522 				};
10523 
10524 			const VkImageCopy				testCopy	=
10525 				{
10526 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
10527 					{0, 0, 0},					// VkOffset3D				srcOffset;
10528 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
10529 					{0, 0, 0},					// VkOffset3D				dstOffset;
10530 					defaultHalfExtent				// VkExtent3D				extent;
10531 				};
10532 
10533 			CopyRegion	imageCopy;
10534 			imageCopy.imageCopy	= testCopy;
10535 
10536 			paramsCubeToArray.regions.push_back(imageCopy);
10537 		}
10538 
10539 		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_layers", "copy cube compatible image to cube compatible image layer by layer", paramsCubeToArray));
10540 	}
10541 
10542 	{
10543 		TestParams	paramsCubeToCube;
10544 		const deUint32	arrayLayers					= 6u;
10545 		paramsCubeToCube.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10546 		paramsCubeToCube.src.image.imageType		= VK_IMAGE_TYPE_2D;
10547 		paramsCubeToCube.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10548 		paramsCubeToCube.src.image.extent			= defaultHalfExtent;
10549 		paramsCubeToCube.src.image.extent.depth		= arrayLayers;
10550 		paramsCubeToCube.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10551 		paramsCubeToCube.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10552 		paramsCubeToCube.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10553 		paramsCubeToCube.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10554 		paramsCubeToCube.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10555 		paramsCubeToCube.dst.image.extent			= defaultHalfExtent;
10556 		paramsCubeToCube.dst.image.extent.depth		= arrayLayers;
10557 		paramsCubeToCube.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10558 		paramsCubeToCube.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10559 		paramsCubeToCube.allocationKind				= allocationKind;
10560 		paramsCubeToCube.extensionUse				= extensionUse;
10561 
10562 		{
10563 			const VkImageSubresourceLayers	sourceLayer	=
10564 				{
10565 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10566 					0u,							// deUint32				mipLevel;
10567 					0u,							// deUint32				baseArrayLayer;
10568 					arrayLayers					// deUint32				layerCount;
10569 				};
10570 
10571 			const VkImageSubresourceLayers	destinationLayer	=
10572 				{
10573 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10574 					0u,							// deUint32				mipLevel;
10575 					0u,							// deUint32				baseArrayLayer;
10576 					arrayLayers					// deUint32				layerCount;
10577 				};
10578 
10579 			const VkImageCopy				testCopy	=
10580 				{
10581 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
10582 					{0, 0, 0},					// VkOffset3D				srcOffset;
10583 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
10584 					{0, 0, 0},					// VkOffset3D				dstOffset;
10585 					defaultHalfExtent			// VkExtent3D				extent;
10586 				};
10587 
10588 			CopyRegion	imageCopy;
10589 			imageCopy.imageCopy	= testCopy;
10590 
10591 			paramsCubeToCube.regions.push_back(imageCopy);
10592 		}
10593 
10594 		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_whole", "copy cube compatible image to cube compatible image all at once", paramsCubeToCube));
10595 	}
10596 }
10597 
addImageToImageArrayTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10598 void addImageToImageArrayTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10599 {
10600 	tcu::TestContext& testCtx	= group->getTestContext();
10601 
10602 	{
10603 		TestParams	paramsArrayToArray;
10604 		const deUint32	arrayLayers					= 16u;
10605 		paramsArrayToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
10606 		paramsArrayToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10607 		paramsArrayToArray.src.image.extent			= defaultHalfExtent;
10608 		paramsArrayToArray.src.image.extent.depth	= arrayLayers;
10609 		paramsArrayToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10610 		paramsArrayToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10611 		paramsArrayToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10612 		paramsArrayToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10613 		paramsArrayToArray.dst.image.extent			= defaultHalfExtent;
10614 		paramsArrayToArray.dst.image.extent.depth	= arrayLayers;
10615 		paramsArrayToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10616 		paramsArrayToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10617 		paramsArrayToArray.allocationKind			= allocationKind;
10618 		paramsArrayToArray.extensionUse				= extensionUse;
10619 
10620 		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10621 		{
10622 			const VkImageSubresourceLayers	sourceLayer	=
10623 					{
10624 							VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10625 							0u,							// deUint32				mipLevel;
10626 							arrayLayersNdx,				// deUint32				baseArrayLayer;
10627 							1u							// deUint32				layerCount;
10628 					};
10629 
10630 			const VkImageSubresourceLayers	destinationLayer =
10631 					{
10632 							VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10633 							0u,							// deUint32				mipLevel;
10634 							arrayLayersNdx,				// deUint32				baseArrayLayer;
10635 							1u							// deUint32				layerCount;
10636 					};
10637 
10638 			const VkImageCopy				testCopy =
10639 					{
10640 							sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
10641 							{0, 0, 0},					// VkOffset3D				srcOffset;
10642 							destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
10643 							{0, 0, 0},					// VkOffset3D				dstOffset;
10644 							defaultHalfExtent			// VkExtent3D				extent;
10645 					};
10646 
10647 			CopyRegion	imageCopy;
10648 			imageCopy.imageCopy	= testCopy;
10649 
10650 			paramsArrayToArray.regions.push_back(imageCopy);
10651 		}
10652 
10653 		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_layers", "copy 2d array image to 2d array image layer by layer", paramsArrayToArray));
10654 	}
10655 
10656 	{
10657 		TestParams	paramsArrayToArray;
10658 		const deUint32	arrayLayers						= 16u;
10659 		paramsArrayToArray.src.image.imageType			= VK_IMAGE_TYPE_2D;
10660 		paramsArrayToArray.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
10661 		paramsArrayToArray.src.image.extent				= defaultHalfExtent;
10662 		paramsArrayToArray.src.image.extent.depth		= arrayLayers;
10663 		paramsArrayToArray.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10664 		paramsArrayToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10665 		paramsArrayToArray.dst.image.imageType			= VK_IMAGE_TYPE_2D;
10666 		paramsArrayToArray.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
10667 		paramsArrayToArray.dst.image.extent				= defaultHalfExtent;
10668 		paramsArrayToArray.dst.image.extent.depth		= arrayLayers;
10669 		paramsArrayToArray.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10670 		paramsArrayToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10671 		paramsArrayToArray.allocationKind				= allocationKind;
10672 		paramsArrayToArray.extensionUse					= extensionUse;
10673 
10674 		{
10675 			const VkImageSubresourceLayers sourceLayer =
10676 					{
10677 							VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10678 							0u,								// deUint32				mipLevel;
10679 							0u,								// deUint32				baseArrayLayer;
10680 							arrayLayers						// deUint32				layerCount;
10681 					};
10682 
10683 			const VkImageSubresourceLayers destinationLayer =
10684 					{
10685 							VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10686 							0u,								// deUint32				mipLevel;
10687 							0u,								// deUint32				baseArrayLayer;
10688 							arrayLayers						// deUint32				layerCount;
10689 					};
10690 
10691 			const VkImageCopy				testCopy =
10692 					{
10693 							sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
10694 							{0, 0, 0},						// VkOffset3D				srcOffset;
10695 							destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
10696 							{0, 0, 0},						// VkOffset3D				dstOffset;
10697 							defaultHalfExtent				// VkExtent3D				extent;
10698 					};
10699 
10700 			CopyRegion imageCopy;
10701 			imageCopy.imageCopy = testCopy;
10702 
10703 			paramsArrayToArray.regions.push_back(imageCopy);
10704 		}
10705 
10706 		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_whole", "copy 2d array image to 2d array image all at once", paramsArrayToArray));
10707 	}
10708 
10709 	{
10710 		TestParams	paramsArrayToArray;
10711 		const deUint32	arrayLayers						= 16u;
10712 		paramsArrayToArray.src.image.imageType			= VK_IMAGE_TYPE_2D;
10713 		paramsArrayToArray.src.image.extent				= defaultHalfExtent;
10714 		paramsArrayToArray.src.image.extent.depth		= arrayLayers;
10715 		paramsArrayToArray.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10716 		paramsArrayToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10717 		paramsArrayToArray.dst.image.imageType			= VK_IMAGE_TYPE_2D;
10718 		paramsArrayToArray.dst.image.extent				= defaultHalfExtent;
10719 		paramsArrayToArray.dst.image.extent.depth		= arrayLayers;
10720 		paramsArrayToArray.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10721 		paramsArrayToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10722 		paramsArrayToArray.allocationKind				= allocationKind;
10723 		paramsArrayToArray.extensionUse					= extensionUse;
10724 		paramsArrayToArray.mipLevels					= deLog2Floor32(deMaxu32(defaultHalfExtent.width, defaultHalfExtent.height)) + 1u;
10725 
10726 		for (deUint32 mipLevelNdx = 0u; mipLevelNdx < paramsArrayToArray.mipLevels; mipLevelNdx++)
10727 		{
10728 			const VkImageSubresourceLayers sourceLayer =
10729 			{
10730 				VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10731 				mipLevelNdx,					// deUint32				mipLevel;
10732 				0u,								// deUint32				baseArrayLayer;
10733 				arrayLayers						// deUint32				layerCount;
10734 			};
10735 
10736 			const VkImageSubresourceLayers destinationLayer =
10737 			{
10738 				VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10739 				mipLevelNdx,					// deUint32				mipLevel;
10740 				0u,								// deUint32				baseArrayLayer;
10741 				arrayLayers						// deUint32				layerCount;
10742 			};
10743 
10744 			const VkExtent3D extent =
10745 			{
10746 				(deUint32)deMax(defaultHalfExtent.width >> mipLevelNdx, 1),		// deUint32    width;
10747 				(deUint32)deMax(defaultHalfExtent.height >> mipLevelNdx, 1),	// deUint32    height;
10748 				1u,																// deUint32    depth;
10749 			};
10750 
10751 			const VkImageCopy				testCopy =
10752 			{
10753 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
10754 				{0, 0, 0},						// VkOffset3D				srcOffset;
10755 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
10756 				{0, 0, 0},						// VkOffset3D				dstOffset;
10757 				extent							// VkExtent3D				extent;
10758 			};
10759 
10760 			CopyRegion imageCopy;
10761 			imageCopy.imageCopy = testCopy;
10762 
10763 			paramsArrayToArray.regions.push_back(imageCopy);
10764 		}
10765 
10766 		VkFormat imageFormats [] = { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_S8_UINT};
10767 
10768 		for (deUint32 imageFormatsNdx = 0; imageFormatsNdx < DE_LENGTH_OF_ARRAY(imageFormats); imageFormatsNdx++)
10769 		{
10770 			paramsArrayToArray.src.image.format = imageFormats[imageFormatsNdx];
10771 			paramsArrayToArray.dst.image.format = imageFormats[imageFormatsNdx];
10772 			for (deUint32 regionNdx = 0u; regionNdx < paramsArrayToArray.regions.size(); regionNdx++)
10773 			{
10774 				paramsArrayToArray.regions[regionNdx].imageCopy.srcSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
10775 				paramsArrayToArray.regions[regionNdx].imageCopy.dstSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
10776 			}
10777 			std::ostringstream testName;
10778 			const std::string formatName = getFormatName(imageFormats[imageFormatsNdx]);
10779 			testName << "array_to_array_whole_mipmap_" << de::toLower(formatName.substr(10));
10780 			group->addChild(new CopyImageToImageMipmapTestCase(testCtx, testName.str(), "copy 2d array mipmap image to 2d array mipmap image all at once", paramsArrayToArray));
10781 		}
10782 	}
10783 }
10784 
addImageToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10785 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10786 {
10787 	addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind, extensionUse);
10788 	addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind, extensionUse);
10789 	addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind, extensionUse);
10790 	addTestGroup(group, "dimensions", "Copying operations on different image dimensions", addImageToImageDimensionsTests, allocationKind, extensionUse);
10791 	addTestGroup(group, "cube", "Coping operations on cube compatible images", addImageToImageCubeTests, allocationKind, extensionUse);
10792 	addTestGroup(group, "array", "Copying operations on array of images", addImageToImageArrayTests, allocationKind, extensionUse);
10793 }
10794 
add1dImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10795 void add1dImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10796 {
10797 	tcu::TestContext& testCtx	= group->getTestContext();
10798 
10799 	{
10800 		TestParams	params;
10801 		params.src.image.imageType			= VK_IMAGE_TYPE_1D;
10802 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
10803 		params.src.image.extent				= default1dExtent;
10804 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10805 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10806 		params.dst.buffer.size				= defaultSize;
10807 		params.allocationKind				= allocationKind;
10808 		params.extensionUse					= extensionUse;
10809 
10810 		const VkBufferImageCopy	bufferImageCopy =
10811 		{
10812 			0u,											// VkDeviceSize				bufferOffset;
10813 			0u,											// deUint32					bufferRowLength;
10814 			0u,											// deUint32					bufferImageHeight;
10815 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
10816 			{0, 0, 0},									// VkOffset3D				imageOffset;
10817 			default1dExtent								// VkExtent3D				imageExtent;
10818 		};
10819 		CopyRegion	copyRegion;
10820 		copyRegion.bufferImageCopy = bufferImageCopy;
10821 
10822 		params.regions.push_back(copyRegion);
10823 
10824 		group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
10825 	}
10826 
10827 	{
10828 		TestParams				params;
10829 		deUint32				bufferImageHeight = defaultSize + 1u;
10830 		params.src.image.imageType			= VK_IMAGE_TYPE_1D;
10831 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
10832 		params.src.image.extent				= default1dExtent;
10833 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10834 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10835 		params.dst.buffer.size				= bufferImageHeight;
10836 		params.allocationKind				= allocationKind;
10837 		params.extensionUse					= extensionUse;
10838 
10839 		const VkBufferImageCopy	bufferImageCopy =
10840 		{
10841 			0u,											// VkDeviceSize				bufferOffset;
10842 			0u,											// deUint32					bufferRowLength;
10843 			bufferImageHeight,							// deUint32					bufferImageHeight;
10844 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
10845 			{0, 0, 0},									// VkOffset3D				imageOffset;
10846 			default1dExtent								// VkExtent3D				imageExtent;
10847 		};
10848 		CopyRegion	copyRegion;
10849 		copyRegion.bufferImageCopy = bufferImageCopy;
10850 
10851 		params.regions.push_back(copyRegion);
10852 
10853 		group->addChild(new CopyImageToBufferTestCase(testCtx, "larger_buffer", "Copy from image to a buffer that is larger than necessary", params));
10854 	}
10855 
10856 	{
10857 		TestParams				params;
10858 		deUint32				arrayLayers = 16u;
10859 		params.src.image.imageType = VK_IMAGE_TYPE_1D;
10860 		params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10861 		params.src.image.extent = default1dExtent;
10862 		params.src.image.extent.depth = arrayLayers;
10863 		params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10864 		params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10865 		params.dst.buffer.size = defaultSize * arrayLayers;
10866 		params.allocationKind = allocationKind;
10867 		params.extensionUse = extensionUse;
10868 
10869 		const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
10870 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
10871 		{
10872 			const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
10873 			const VkBufferImageCopy bufferImageCopy =
10874 			{
10875 				offset,													// VkDeviceSize				bufferOffset;
10876 				0u,														// deUint32					bufferRowLength;
10877 				defaultSize,											// deUint32					bufferImageHeight;
10878 				{
10879 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
10880 					0u,												// deUint32				mipLevel;
10881 					arrayLayerNdx,									// deUint32				baseArrayLayer;
10882 					1u,												// deUint32				layerCount;
10883 				},														// VkImageSubresourceLayers	imageSubresource;
10884 				{0, 0, 0},												// VkOffset3D				imageOffset;
10885 				default1dExtent										// VkExtent3D				imageExtent;
10886 			};
10887 			CopyRegion copyRegion;
10888 			copyRegion.bufferImageCopy = bufferImageCopy;
10889 
10890 			params.regions.push_back(copyRegion);
10891 		}
10892 
10893 		group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
10894 	}
10895 
10896 	{
10897 		TestParams				params;
10898 		deUint32				arrayLayers			= 16u;
10899 		deUint32				bufferImageHeight	= defaultSize + 1u;
10900 		params.src.image.imageType			= VK_IMAGE_TYPE_1D;
10901 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
10902 		params.src.image.extent				= default1dExtent;
10903 		params.src.image.extent.depth		= arrayLayers;
10904 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10905 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10906 		params.dst.buffer.size				= bufferImageHeight * arrayLayers;
10907 		params.allocationKind				= allocationKind;
10908 		params.extensionUse					= extensionUse;
10909 
10910 		const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
10911 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
10912 		{
10913 			const VkDeviceSize offset = bufferImageHeight * pixelSize * arrayLayerNdx;
10914 			const VkBufferImageCopy bufferImageCopy =
10915 			{
10916 				offset,													// VkDeviceSize				bufferOffset;
10917 				0u,														// deUint32					bufferRowLength;
10918 				bufferImageHeight,										// deUint32					bufferImageHeight;
10919 				{
10920 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
10921 					0u,												// deUint32				mipLevel;
10922 					arrayLayerNdx,									// deUint32				baseArrayLayer;
10923 					1u,												// deUint32				layerCount;
10924 				},														// VkImageSubresourceLayers	imageSubresource;
10925 				{0, 0, 0},												// VkOffset3D				imageOffset;
10926 				default1dExtent										// VkExtent3D				imageExtent;
10927 			};
10928 			CopyRegion copyRegion;
10929 			copyRegion.bufferImageCopy = bufferImageCopy;
10930 
10931 			params.regions.push_back(copyRegion);
10932 		}
10933 
10934 		group->addChild(new CopyImageToBufferTestCase(testCtx, "array_larger_buffer", "Copy each layer from array to a buffer that is larger than necessary", params));
10935 	}
10936 }
10937 
add2dImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10938 void add2dImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10939 {
10940 	tcu::TestContext& testCtx = group->getTestContext();
10941 
10942 	{
10943 		TestParams	params;
10944 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
10945 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
10946 		params.src.image.extent				= defaultExtent;
10947 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10948 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10949 		params.dst.buffer.size				= defaultSize * defaultSize;
10950 		params.allocationKind				= allocationKind;
10951 		params.extensionUse					= extensionUse;
10952 
10953 		const VkBufferImageCopy	bufferImageCopy	=
10954 		{
10955 			0u,											// VkDeviceSize				bufferOffset;
10956 			0u,											// deUint32					bufferRowLength;
10957 			0u,											// deUint32					bufferImageHeight;
10958 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
10959 			{0, 0, 0},									// VkOffset3D				imageOffset;
10960 			defaultExtent								// VkExtent3D				imageExtent;
10961 		};
10962 		CopyRegion	copyRegion;
10963 		copyRegion.bufferImageCopy	= bufferImageCopy;
10964 
10965 		params.regions.push_back(copyRegion);
10966 
10967 		group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
10968 	}
10969 
10970 	{
10971 		TestParams	params;
10972 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
10973 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
10974 		params.src.image.extent				= defaultExtent;
10975 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10976 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10977 		params.dst.buffer.size				= defaultSize * defaultSize;
10978 		params.allocationKind				= allocationKind;
10979 		params.extensionUse					= extensionUse;
10980 
10981 		const VkBufferImageCopy	bufferImageCopy	=
10982 		{
10983 			defaultSize * defaultHalfSize,				// VkDeviceSize				bufferOffset;
10984 			0u,											// deUint32					bufferRowLength;
10985 			0u,											// deUint32					bufferImageHeight;
10986 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
10987 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
10988 			defaultHalfExtent							// VkExtent3D				imageExtent;
10989 		};
10990 		CopyRegion	copyRegion;
10991 		copyRegion.bufferImageCopy	= bufferImageCopy;
10992 
10993 		params.regions.push_back(copyRegion);
10994 
10995 		group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
10996 	}
10997 
10998 	{
10999 		TestParams	params;
11000 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11001 		params.src.image.format				= VK_FORMAT_R8_UNORM;
11002 		params.src.image.extent				= defaultExtent;
11003 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11004 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11005 		params.dst.buffer.size				= defaultSize * defaultSize;
11006 		params.allocationKind				= allocationKind;
11007 		params.extensionUse					= extensionUse;
11008 
11009 		const VkBufferImageCopy	bufferImageCopy	=
11010 		{
11011 			defaultSize * defaultHalfSize + 1u,		// VkDeviceSize				bufferOffset;
11012 			0u,											// deUint32					bufferRowLength;
11013 			0u,											// deUint32					bufferImageHeight;
11014 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11015 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11016 			defaultHalfExtent							// VkExtent3D				imageExtent;
11017 		};
11018 		CopyRegion	copyRegion;
11019 		copyRegion.bufferImageCopy	= bufferImageCopy;
11020 
11021 		params.regions.push_back(copyRegion);
11022 
11023 		group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset_relaxed", "Copy from image to buffer with buffer offset not a multiple of 4", params));
11024 	}
11025 
11026 	{
11027 		TestParams	params;
11028 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11029 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11030 		params.src.image.extent				= defaultExtent;
11031 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11032 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11033 		params.dst.buffer.size				= defaultSize * defaultSize;
11034 		params.allocationKind				= allocationKind;
11035 		params.extensionUse					= extensionUse;
11036 
11037 		const int			pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
11038 		const VkDeviceSize	bufferSize	= pixelSize * params.dst.buffer.size;
11039 		const VkDeviceSize	offsetSize	= pixelSize * defaultQuarterSize * defaultQuarterSize;
11040 		deUint32			divisor		= 1;
11041 		for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
11042 		{
11043 			const deUint32			bufferRowLength		= defaultQuarterSize;
11044 			const deUint32			bufferImageHeight	= defaultQuarterSize;
11045 			const VkExtent3D		imageExtent			= {defaultQuarterSize / divisor, defaultQuarterSize, 1};
11046 			DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
11047 			DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
11048 			DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
11049 
11050 			CopyRegion				region;
11051 			const VkBufferImageCopy	bufferImageCopy		=
11052 			{
11053 				offset,						// VkDeviceSize				bufferOffset;
11054 				bufferRowLength,			// deUint32					bufferRowLength;
11055 				bufferImageHeight,			// deUint32					bufferImageHeight;
11056 				defaultSourceLayer,			// VkImageSubresourceLayers	imageSubresource;
11057 				{0, 0, 0},					// VkOffset3D				imageOffset;
11058 				imageExtent					// VkExtent3D				imageExtent;
11059 			};
11060 			region.bufferImageCopy	= bufferImageCopy;
11061 			params.regions.push_back(region);
11062 		}
11063 
11064 		group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
11065 	}
11066 
11067 	{
11068 		TestParams				params;
11069 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11070 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11071 		params.src.image.extent				= defaultExtent;
11072 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11073 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11074 		params.dst.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
11075 		params.allocationKind				= allocationKind;
11076 		params.extensionUse					= extensionUse;
11077 
11078 		const VkBufferImageCopy	bufferImageCopy	=
11079 		{
11080 			0u,											// VkDeviceSize				bufferOffset;
11081 			defaultSize,								// deUint32					bufferRowLength;
11082 			defaultSize,								// deUint32					bufferImageHeight;
11083 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11084 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11085 			defaultHalfExtent							// VkExtent3D				imageExtent;
11086 		};
11087 		CopyRegion				copyRegion;
11088 		copyRegion.bufferImageCopy	= bufferImageCopy;
11089 
11090 		params.regions.push_back(copyRegion);
11091 
11092 		group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
11093 	}
11094 
11095 	{
11096 		TestParams				params;
11097 		deUint32				bufferImageHeight = defaultSize + 1u;
11098 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11099 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11100 		params.src.image.extent				= defaultExtent;
11101 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11102 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11103 		params.dst.buffer.size				= bufferImageHeight * defaultSize;
11104 		params.allocationKind				= allocationKind;
11105 		params.extensionUse					= extensionUse;
11106 
11107 		const VkBufferImageCopy	bufferImageCopy =
11108 		{
11109 			0u,											// VkDeviceSize				bufferOffset;
11110 			defaultSize,								// deUint32					bufferRowLength;
11111 			bufferImageHeight,							// deUint32					bufferImageHeight;
11112 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11113 			{0, 0, 0},										// VkOffset3D				imageOffset;
11114 			defaultExtent								// VkExtent3D				imageExtent;
11115 		};
11116 		CopyRegion				copyRegion;
11117 		copyRegion.bufferImageCopy = bufferImageCopy;
11118 
11119 		params.regions.push_back(copyRegion);
11120 
11121 		group->addChild(new CopyImageToBufferTestCase(testCtx, "larger_buffer", "Copy from image to a buffer that is larger than necessary", params));
11122 	}
11123 
11124 	{
11125 		TestParams				params;
11126 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11127 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11128 		params.src.image.extent				= defaultExtent;
11129 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11130 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11131 		params.dst.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
11132 		params.allocationKind				= allocationKind;
11133 		params.extensionUse					= extensionUse;
11134 
11135 		const VkBufferImageCopy	bufferImageCopy	=
11136 		{
11137 			defaultQuarterSize,							// VkDeviceSize				bufferOffset;
11138 			defaultSize,								// deUint32					bufferRowLength;
11139 			defaultSize,								// deUint32					bufferImageHeight;
11140 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11141 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11142 			defaultHalfExtent							// VkExtent3D				imageExtent;
11143 		};
11144 		CopyRegion				copyRegion;
11145 		copyRegion.bufferImageCopy	= bufferImageCopy;
11146 
11147 		params.regions.push_back(copyRegion);
11148 
11149 		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));
11150 	}
11151 
11152 	{
11153 		TestParams				params;
11154 		deUint32				arrayLayers = 16u;
11155 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11156 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11157 		params.src.image.extent				= defaultHalfExtent;
11158 		params.src.image.extent.depth		= arrayLayers;
11159 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11160 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11161 		params.dst.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
11162 		params.allocationKind				= allocationKind;
11163 		params.extensionUse					= extensionUse;
11164 
11165 		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
11166 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11167 		{
11168 			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11169 			const VkBufferImageCopy bufferImageCopy =
11170 				{
11171 					offset,													// VkDeviceSize				bufferOffset;
11172 					0u,														// deUint32					bufferRowLength;
11173 					0u,														// deUint32					bufferImageHeight;
11174 					{
11175 						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11176 						0u,												// deUint32				mipLevel;
11177 						arrayLayerNdx,									// deUint32				baseArrayLayer;
11178 						1u,												// deUint32				layerCount;
11179 					},														// VkImageSubresourceLayers	imageSubresource;
11180 					{0, 0, 0},												// VkOffset3D				imageOffset;
11181 					defaultHalfExtent										// VkExtent3D				imageExtent;
11182 				};
11183 			CopyRegion copyRegion;
11184 			copyRegion.bufferImageCopy = bufferImageCopy;
11185 
11186 			params.regions.push_back(copyRegion);
11187 		}
11188 		group->addChild(new CopyImageToBufferTestCase(testCtx, "array", "Copy each layer from array to buffer", params));
11189 	}
11190 
11191 	{
11192 		TestParams				params;
11193 		deUint32				arrayLayers			= 16u;
11194 		deUint32				imageBufferHeight	= defaultHalfSize + 1u;
11195 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11196 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11197 		params.src.image.extent				= defaultHalfExtent;
11198 		params.src.image.extent.depth		= arrayLayers;
11199 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11200 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11201 		params.dst.buffer.size				= defaultHalfSize * imageBufferHeight * arrayLayers;
11202 		params.allocationKind				= allocationKind;
11203 		params.extensionUse					= extensionUse;
11204 
11205 		const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
11206 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11207 		{
11208 			const VkDeviceSize offset = defaultHalfSize * imageBufferHeight * pixelSize * arrayLayerNdx;
11209 			const VkBufferImageCopy bufferImageCopy =
11210 			{
11211 				offset,													// VkDeviceSize				bufferOffset;
11212 				0u,														// deUint32					bufferRowLength;
11213 				imageBufferHeight,										// deUint32					bufferImageHeight;
11214 				{
11215 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11216 					0u,												// deUint32				mipLevel;
11217 					arrayLayerNdx,									// deUint32				baseArrayLayer;
11218 					1u,												// deUint32				layerCount;
11219 				},														// VkImageSubresourceLayers	imageSubresource;
11220 				{0, 0, 0},												// VkOffset3D				imageOffset;
11221 				defaultHalfExtent										// VkExtent3D				imageExtent;
11222 			};
11223 			CopyRegion copyRegion;
11224 			copyRegion.bufferImageCopy = bufferImageCopy;
11225 
11226 			params.regions.push_back(copyRegion);
11227 		}
11228 		group->addChild(new CopyImageToBufferTestCase(testCtx, "array_larger_buffer", "Copy each layer from array to a buffer that is larger than necessary", params));
11229 	}
11230 
11231 	{
11232 		TestParams				params;
11233 		deUint32				arrayLayers = 16u;
11234 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11235 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11236 		params.src.image.extent				= defaultHalfExtent;
11237 		params.src.image.extent.depth		= arrayLayers;
11238 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11239 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11240 		params.dst.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
11241 		params.allocationKind				= allocationKind;
11242 		params.extensionUse					= extensionUse;
11243 
11244 		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
11245 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11246 		{
11247 			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11248 			const VkBufferImageCopy bufferImageCopy =
11249 				{
11250 					offset,													// VkDeviceSize				bufferOffset;
11251 					defaultHalfSize,										// deUint32					bufferRowLength;
11252 					defaultHalfSize,										// deUint32					bufferImageHeight;
11253 					{
11254 						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11255 						0u,												// deUint32				mipLevel;
11256 						arrayLayerNdx,									// deUint32				baseArrayLayer;
11257 						1u,												// deUint32				layerCount;
11258 					},														// VkImageSubresourceLayers	imageSubresource;
11259 					{0, 0, 0},												// VkOffset3D				imageOffset;
11260 					defaultHalfExtent										// VkExtent3D				imageExtent;
11261 				};
11262 			CopyRegion copyRegion;
11263 			copyRegion.bufferImageCopy = bufferImageCopy;
11264 
11265 			params.regions.push_back(copyRegion);
11266 		}
11267 		group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
11268 	}
11269 }
11270 
addImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11271 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11272 {
11273 	addTestGroup(group, "1d_images", "Copying operations on 1d images", add1dImageToBufferTests, allocationKind, extensionUse);
11274 	addTestGroup(group, "2d_images", "Copying operations on 2d images", add2dImageToBufferTests, allocationKind, extensionUse);
11275 }
11276 
addBufferToDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11277 void addBufferToDepthStencilTests(tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11278 {
11279 	tcu::TestContext& testCtx = group->getTestContext();
11280 
11281 	const struct
11282 	{
11283 		const char*		name;
11284 		const VkFormat	format;
11285 	} depthAndStencilFormats[] =
11286 	{
11287 		{ "d16_unorm",				VK_FORMAT_D16_UNORM				},
11288 		{ "x8_d24_unorm_pack32",	VK_FORMAT_X8_D24_UNORM_PACK32	},
11289 		{ "d32_sfloat",				VK_FORMAT_D32_SFLOAT			},
11290 		{ "d16_unorm_s8_uint",		VK_FORMAT_D16_UNORM_S8_UINT		},
11291 		{ "d24_unorm_s8_uint",		VK_FORMAT_D24_UNORM_S8_UINT		},
11292 		{ "d32_sfloat_s8_uint",		VK_FORMAT_D32_SFLOAT_S8_UINT	}
11293 	};
11294 
11295 	const VkImageSubresourceLayers	depthSourceLayer		=
11296 	{
11297 		VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
11298 		0u,							// deUint32				mipLevel;
11299 		0u,							// deUint32				baseArrayLayer;
11300 		1u,							// deUint32				layerCount;
11301 	};
11302 
11303 	const VkBufferImageCopy			bufferDepthCopy			=
11304 	{
11305 		0u,											// VkDeviceSize				bufferOffset;
11306 		0u,											// deUint32					bufferRowLength;
11307 		0u,											// deUint32					bufferImageHeight;
11308 		depthSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11309 		{0, 0, 0},									// VkOffset3D				imageOffset;
11310 		defaultExtent								// VkExtent3D				imageExtent;
11311 	};
11312 
11313 	const VkBufferImageCopy			bufferDepthCopyOffset	=
11314 	{
11315 		32,											// VkDeviceSize				bufferOffset;
11316 		defaultHalfSize + defaultQuarterSize,		// deUint32					bufferRowLength;
11317 		defaultHalfSize + defaultQuarterSize,		// deUint32					bufferImageHeight;
11318 		depthSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11319 		{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11320 		defaultHalfExtent							// VkExtent3D				imageExtent;
11321 	};
11322 
11323 	const VkImageSubresourceLayers	stencilSourceLayer		=
11324 	{
11325 		VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
11326 		0u,								// deUint32				mipLevel;
11327 		0u,								// deUint32				baseArrayLayer;
11328 		1u,								// deUint32				layerCount;
11329 	};
11330 
11331 	const VkBufferImageCopy			bufferStencilCopy		=
11332 	{
11333 		0u,					// VkDeviceSize				bufferOffset;
11334 		0u,					// deUint32					bufferRowLength;
11335 		0u,					// deUint32					bufferImageHeight;
11336 		stencilSourceLayer,	// VkImageSubresourceLayers	imageSubresource;
11337 		{0, 0, 0},			// VkOffset3D				imageOffset;
11338 		defaultExtent		// VkExtent3D				imageExtent;
11339 	};
11340 
11341     const VkBufferImageCopy			bufferStencilCopyOffset	=
11342 	{
11343 		32,											// VkDeviceSize				bufferOffset;
11344 		defaultHalfSize + defaultQuarterSize,		// deUint32					bufferRowLength;
11345 		defaultHalfSize + defaultQuarterSize,		// deUint32					bufferImageHeight;
11346 		stencilSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11347 		{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11348 		defaultHalfExtent							// VkExtent3D				imageExtent;
11349 	};
11350 
11351     const bool						useOffset[]				= {false, true};
11352 
11353 	// Note: Depth stencil tests I want to do
11354 	// Formats: D16, D24S8, D32FS8
11355 	// Test writing each component with separate CopyBufferToImage commands
11356 	// Test writing both components in one CopyBufferToImage command
11357 	// Swap order of writes of Depth & Stencil
11358 	// whole surface, subimages?
11359 	// Similar tests as BufferToImage?
11360 	for (const auto config : depthAndStencilFormats)
11361 		for (const auto offset : useOffset)
11362 		{
11363 			// TODO: Check that this format is supported before creating tests?
11364 			//if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
11365 
11366 			CopyRegion					copyDepthRegion;
11367 			CopyRegion					copyStencilRegion;
11368 			TestParams					params;
11369 			const tcu::TextureFormat	format		= mapVkFormat(config.format);
11370 			const bool					hasDepth	= tcu::hasDepthComponent(format.order);
11371 			const bool					hasStencil	= tcu::hasStencilComponent(format.order);
11372 			std::string					description	= config.name;
11373 
11374 			if (offset)
11375 			{
11376 				copyDepthRegion.bufferImageCopy = bufferDepthCopyOffset;
11377 				copyStencilRegion.bufferImageCopy = bufferStencilCopyOffset;
11378 				description = "buffer_offset_" + description;
11379 				params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
11380 			}
11381 			else
11382 			{
11383 				copyDepthRegion.bufferImageCopy = bufferDepthCopy;
11384 				copyStencilRegion.bufferImageCopy = bufferStencilCopy;
11385 				params.src.buffer.size = defaultSize * defaultSize;
11386 			}
11387 
11388 			params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11389 			params.dst.image.format = config.format;
11390 			params.dst.image.extent = defaultExtent;
11391 			params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11392 			params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11393 			params.allocationKind = allocationKind;
11394 			params.extensionUse = extensionUse;
11395 
11396 			if (hasDepth && hasStencil)
11397 			{
11398 				params.singleCommand = DE_TRUE;
11399 
11400 				params.regions.push_back(copyDepthRegion);
11401 				params.regions.push_back(copyStencilRegion);
11402 
11403 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_DS", "Copy from depth&stencil to image", params));
11404 
11405 				params.singleCommand = DE_FALSE;
11406 
11407 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D_S", "Copy from depth then stencil to image", params));
11408 
11409 				params.regions.clear();
11410 				params.regions.push_back(copyStencilRegion);
11411 				params.regions.push_back(copyDepthRegion);
11412 
11413 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S_D", "Copy from depth then stencil to image", params));
11414 
11415 				params.singleCommand = DE_TRUE;
11416 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_SD", "Copy from depth&stencil to image", params));
11417 			}
11418 
11419 			if (hasStencil)
11420 			{
11421 				params.regions.clear();
11422 				params.regions.push_back(copyStencilRegion);
11423 
11424 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S", "Copy from stencil to image", params));
11425 			}
11426 
11427 			if (hasDepth)
11428 			{
11429 				params.regions.clear();
11430 				params.regions.push_back(copyDepthRegion);
11431 
11432 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D", "Copy from depth to image", params));
11433 			}
11434 		}
11435 }
11436 
add1dBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11437 void add1dBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11438 {
11439 	tcu::TestContext& testCtx	= group->getTestContext();
11440 
11441 	{
11442 		TestParams	params;
11443 		params.src.buffer.size				= defaultSize;
11444 		params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
11445 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
11446 		params.dst.image.extent				= default1dExtent;
11447 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11448 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11449 		params.allocationKind				= allocationKind;
11450 		params.extensionUse					= extensionUse;
11451 
11452 		const VkBufferImageCopy	bufferImageCopy =
11453 		{
11454 			0u,											// VkDeviceSize				bufferOffset;
11455 			0u,											// deUint32					bufferRowLength;
11456 			0u,											// deUint32					bufferImageHeight;
11457 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11458 			{0, 0, 0},									// VkOffset3D				imageOffset;
11459 			default1dExtent								// VkExtent3D				imageExtent;
11460 		};
11461 		CopyRegion	copyRegion;
11462 		copyRegion.bufferImageCopy = bufferImageCopy;
11463 
11464 		params.regions.push_back(copyRegion);
11465 
11466 		group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from tightly packed buffer to image", params));
11467 	}
11468 
11469 	{
11470 		TestParams				params;
11471 		deUint32				bufferImageHeight = defaultSize + 1u;
11472 		params.src.buffer.size				= bufferImageHeight;
11473 		params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
11474 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
11475 		params.dst.image.extent				= default1dExtent;
11476 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11477 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11478 		params.allocationKind				= allocationKind;
11479 		params.extensionUse					= extensionUse;
11480 
11481 		const VkBufferImageCopy	bufferImageCopy =
11482 		{
11483 			0u,											// VkDeviceSize				bufferOffset;
11484 			0u,											// deUint32					bufferRowLength;
11485 			bufferImageHeight,							// deUint32					bufferImageHeight;
11486 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11487 			{0, 0, 0},									// VkOffset3D				imageOffset;
11488 			default1dExtent								// VkExtent3D				imageExtent;
11489 		};
11490 		CopyRegion	copyRegion;
11491 		copyRegion.bufferImageCopy = bufferImageCopy;
11492 
11493 		params.regions.push_back(copyRegion);
11494 
11495 		group->addChild(new CopyBufferToImageTestCase(testCtx, "larger_buffer", "Copy from a buffer to image", params));
11496 	}
11497 
11498 	{
11499 		TestParams				params;
11500 		deUint32				arrayLayers = 16u;
11501 		params.src.buffer.size				= defaultSize * arrayLayers;
11502 		params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
11503 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11504 		params.dst.image.extent				= default1dExtent;
11505 		params.dst.image.extent.depth		= arrayLayers;
11506 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11507 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11508 		params.allocationKind				= allocationKind;
11509 		params.extensionUse					= extensionUse;
11510 
11511 		const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11512 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11513 		{
11514 			const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
11515 			const VkBufferImageCopy bufferImageCopy =
11516 			{
11517 				offset,													// VkDeviceSize				bufferOffset;
11518 				0u,														// deUint32					bufferRowLength;
11519 				0u,														// deUint32					bufferImageHeight;
11520 				{
11521 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11522 					0u,												// deUint32				mipLevel;
11523 					arrayLayerNdx,									// deUint32				baseArrayLayer;
11524 					1u,												// deUint32				layerCount;
11525 				},														// VkImageSubresourceLayers	imageSubresource;
11526 				{0, 0, 0},												// VkOffset3D				imageOffset;
11527 				default1dExtent											// VkExtent3D				imageExtent;
11528 			};
11529 			CopyRegion copyRegion;
11530 			copyRegion.bufferImageCopy = bufferImageCopy;
11531 
11532 			params.regions.push_back(copyRegion);
11533 		}
11534 
11535 		group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from a different part of the tightly packed buffer to each layer", params));
11536 	}
11537 
11538 	{
11539 		TestParams				params;
11540 		deUint32				arrayLayers = 16u;
11541 		deUint32				bufferImageHeight = defaultSize + 1u;
11542 		params.src.buffer.size				= defaultSize * arrayLayers;
11543 		params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
11544 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11545 		params.dst.image.extent				= default1dExtent;
11546 		params.dst.image.extent.depth		= arrayLayers;
11547 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11548 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11549 		params.allocationKind				= allocationKind;
11550 		params.extensionUse					= extensionUse;
11551 
11552 		const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11553 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11554 		{
11555 			const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
11556 			const VkBufferImageCopy bufferImageCopy =
11557 			{
11558 				offset,													// VkDeviceSize				bufferOffset;
11559 				0u,														// deUint32					bufferRowLength;
11560 				bufferImageHeight,										// deUint32					bufferImageHeight;
11561 				{
11562 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11563 					0u,												// deUint32				mipLevel;
11564 					arrayLayerNdx,									// deUint32				baseArrayLayer;
11565 					1u,												// deUint32				layerCount;
11566 				},														// VkImageSubresourceLayers	imageSubresource;
11567 				{0, 0, 0},												// VkOffset3D				imageOffset;
11568 				default1dExtent											// VkExtent3D				imageExtent;
11569 			};
11570 			CopyRegion copyRegion;
11571 			copyRegion.bufferImageCopy = bufferImageCopy;
11572 
11573 			params.regions.push_back(copyRegion);
11574 		}
11575 
11576 		group->addChild(new CopyBufferToImageTestCase(testCtx, "array_larger_buffer", "Copy from a different part of the buffer to each layer", params));
11577 	}
11578 }
11579 
add2dBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11580 void add2dBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11581 {
11582 	tcu::TestContext& testCtx = group->getTestContext();
11583 
11584 	{
11585 		TestParams	params;
11586 		params.src.buffer.size				= defaultSize * defaultSize;
11587 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11588 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
11589 		params.dst.image.extent				= defaultExtent;
11590 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11591 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11592 		params.allocationKind				= allocationKind;
11593 		params.extensionUse					= extensionUse;
11594 
11595 		const VkBufferImageCopy	bufferImageCopy	=
11596 		{
11597 			0u,											// VkDeviceSize				bufferOffset;
11598 			0u,											// deUint32					bufferRowLength;
11599 			0u,											// deUint32					bufferImageHeight;
11600 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11601 			{0, 0, 0},									// VkOffset3D				imageOffset;
11602 			defaultExtent								// VkExtent3D				imageExtent;
11603 		};
11604 		CopyRegion	copyRegion;
11605 		copyRegion.bufferImageCopy	= bufferImageCopy;
11606 
11607 		params.regions.push_back(copyRegion);
11608 
11609 		group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
11610 	}
11611 
11612 	{
11613 		TestParams	params;
11614 		params.src.buffer.size				= defaultSize * defaultSize;
11615 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11616 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11617 		params.dst.image.extent				= defaultExtent;
11618 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11619 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11620 		params.allocationKind				= allocationKind;
11621 		params.extensionUse					= extensionUse;
11622 
11623 		CopyRegion	region;
11624 		deUint32	divisor	= 1;
11625 		for (int offset = 0; (offset + defaultQuarterSize / divisor < defaultSize) && (defaultQuarterSize > divisor); offset += defaultQuarterSize / divisor++)
11626 		{
11627 			const VkBufferImageCopy	bufferImageCopy	=
11628 			{
11629 				0u,																// VkDeviceSize				bufferOffset;
11630 				0u,																// deUint32					bufferRowLength;
11631 				0u,																// deUint32					bufferImageHeight;
11632 				defaultSourceLayer,												// VkImageSubresourceLayers	imageSubresource;
11633 				{offset, defaultHalfSize, 0},									// VkOffset3D				imageOffset;
11634 				{defaultQuarterSize / divisor, defaultQuarterSize / divisor, 1}	// VkExtent3D				imageExtent;
11635 			};
11636 			region.bufferImageCopy	= bufferImageCopy;
11637 			params.regions.push_back(region);
11638 		}
11639 
11640 		group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
11641 	}
11642 
11643 	{
11644 		TestParams	params;
11645 		params.src.buffer.size				= defaultSize * defaultSize;
11646 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11647 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11648 		params.dst.image.extent				= defaultExtent;
11649 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11650 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11651 		params.allocationKind				= allocationKind;
11652 		params.extensionUse					= extensionUse;
11653 
11654 		const VkBufferImageCopy	bufferImageCopy	=
11655 		{
11656 			defaultQuarterSize,							// VkDeviceSize				bufferOffset;
11657 			defaultHalfSize + defaultQuarterSize,		// deUint32					bufferRowLength;
11658 			defaultHalfSize + defaultQuarterSize,		// deUint32					bufferImageHeight;
11659 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11660 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11661 			defaultHalfExtent							// VkExtent3D				imageExtent;
11662 		};
11663 		CopyRegion	copyRegion;
11664 		copyRegion.bufferImageCopy	= bufferImageCopy;
11665 
11666 		params.regions.push_back(copyRegion);
11667 
11668 		group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
11669 	}
11670 
11671 	{
11672 		TestParams	params;
11673 		params.src.buffer.size				= defaultSize * defaultSize;
11674 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11675 		params.dst.image.format				= VK_FORMAT_R8_UNORM;
11676 		params.dst.image.extent				= defaultExtent;
11677 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11678 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11679 		params.allocationKind				= allocationKind;
11680 		params.extensionUse					= extensionUse;
11681 
11682 		const VkBufferImageCopy	bufferImageCopy	=
11683 		{
11684 			defaultQuarterSize + 1u,						// VkDeviceSize				bufferOffset;
11685 			defaultHalfSize + defaultQuarterSize,		// deUint32					bufferRowLength;
11686 			defaultHalfSize + defaultQuarterSize,		// deUint32					bufferImageHeight;
11687 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11688 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11689 			defaultHalfExtent							// VkExtent3D				imageExtent;
11690 		};
11691 		CopyRegion	copyRegion;
11692 		copyRegion.bufferImageCopy	= bufferImageCopy;
11693 
11694 		params.regions.push_back(copyRegion);
11695 
11696 		group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset_relaxed", "Copy from buffer to image with buffer offset not a multiple of 4", params));
11697 	}
11698 
11699 	{
11700 		TestParams				params;
11701 		params.src.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
11702 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11703 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11704 		params.dst.image.extent				= defaultExtent;
11705 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11706 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11707 		params.allocationKind				= allocationKind;
11708 		params.extensionUse					= extensionUse;
11709 
11710 		const VkBufferImageCopy	bufferImageCopy	=
11711 		{
11712 			0u,											// VkDeviceSize				bufferOffset;
11713 			defaultSize,								// deUint32					bufferRowLength;
11714 			defaultSize,								// deUint32					bufferImageHeight;
11715 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11716 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11717 			defaultHalfExtent							// VkExtent3D				imageExtent;
11718 		};
11719 		CopyRegion				copyRegion;
11720 		copyRegion.bufferImageCopy	= bufferImageCopy;
11721 
11722 		params.regions.push_back(copyRegion);
11723 
11724 		group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from buffer that is just large enough to contain the accessed elements", params));
11725 	}
11726 
11727 	{
11728 		TestParams				params;
11729 		deUint32				bufferImageHeight = defaultSize + 1u;
11730 		params.src.buffer.size				= defaultSize * bufferImageHeight;
11731 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11732 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11733 		params.dst.image.extent				= defaultExtent;
11734 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11735 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11736 		params.allocationKind				= allocationKind;
11737 		params.extensionUse					= extensionUse;
11738 
11739 		const VkBufferImageCopy	bufferImageCopy	=
11740 		{
11741 			0u,											// VkDeviceSize				bufferOffset;
11742 			defaultSize,								// deUint32					bufferRowLength;
11743 			bufferImageHeight,							// deUint32					bufferImageHeight;
11744 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11745 			{0, 0, 0},										// VkOffset3D				imageOffset;
11746 			defaultHalfExtent							// VkExtent3D				imageExtent;
11747 		};
11748 		CopyRegion				copyRegion;
11749 		copyRegion.bufferImageCopy	= bufferImageCopy;
11750 
11751 		params.regions.push_back(copyRegion);
11752 
11753 		group->addChild(new CopyBufferToImageTestCase(testCtx, "larger_buffer", "Copy from buffer that is larger than necessary to image", params));
11754 	}
11755 
11756 	{
11757 		TestParams				params;
11758 		params.src.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
11759 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11760 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11761 		params.dst.image.extent				= defaultExtent;
11762 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11763 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11764 		params.allocationKind				= allocationKind;
11765 		params.extensionUse					= extensionUse;
11766 
11767 		const VkBufferImageCopy	bufferImageCopy	=
11768 		{
11769 			defaultQuarterSize,							// VkDeviceSize				bufferOffset;
11770 			defaultSize,								// deUint32					bufferRowLength;
11771 			defaultSize,								// deUint32					bufferImageHeight;
11772 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11773 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11774 			defaultHalfExtent							// VkExtent3D				imageExtent;
11775 		};
11776 		CopyRegion				copyRegion;
11777 		copyRegion.bufferImageCopy	= bufferImageCopy;
11778 
11779 		params.regions.push_back(copyRegion);
11780 
11781 		group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from buffer that is just large enough to contain the accessed elements", params));
11782 	}
11783 
11784 	{
11785 		TestParams				params;
11786 		deUint32				arrayLayers = 16u;
11787 		params.src.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
11788 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11789 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11790 		params.dst.image.extent				= defaultHalfExtent;
11791 		params.dst.image.extent.depth		= arrayLayers;
11792 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11793 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11794 		params.allocationKind				= allocationKind;
11795 		params.extensionUse					= extensionUse;
11796 
11797 		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11798 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11799 		{
11800 			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11801 			const VkBufferImageCopy bufferImageCopy =
11802 				{
11803 					offset,													// VkDeviceSize				bufferOffset;
11804 					0u,														// deUint32					bufferRowLength;
11805 					0u,														// deUint32					bufferImageHeight;
11806 					{
11807 						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11808 						0u,												// deUint32				mipLevel;
11809 						arrayLayerNdx,									// deUint32				baseArrayLayer;
11810 						1u,												// deUint32				layerCount;
11811 					},														// VkImageSubresourceLayers	imageSubresource;
11812 					{0, 0, 0},												// VkOffset3D				imageOffset;
11813 					defaultHalfExtent										// VkExtent3D				imageExtent;
11814 				};
11815 			CopyRegion copyRegion;
11816 			copyRegion.bufferImageCopy = bufferImageCopy;
11817 
11818 			params.regions.push_back(copyRegion);
11819 		}
11820 		group->addChild(new CopyBufferToImageTestCase(testCtx, "array", "Copy from a different part of the buffer to each layer", params));
11821 	}
11822 
11823 	{
11824 		TestParams				params;
11825 		deUint32				arrayLayers			= 16u;
11826 		deUint32				bufferImageHeight	= defaultHalfSize + 1u;
11827 		params.src.buffer.size				= defaultHalfSize * bufferImageHeight * arrayLayers;
11828 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11829 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11830 		params.dst.image.extent				= defaultHalfExtent;
11831 		params.dst.image.extent.depth		= arrayLayers;
11832 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11833 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11834 		params.allocationKind				= allocationKind;
11835 		params.extensionUse					= extensionUse;
11836 
11837 		const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11838 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11839 		{
11840 			const VkDeviceSize offset = defaultHalfSize * bufferImageHeight * pixelSize * arrayLayerNdx;
11841 			const VkBufferImageCopy bufferImageCopy =
11842 			{
11843 				offset,													// VkDeviceSize				bufferOffset;
11844 				defaultHalfSize,										// deUint32					bufferRowLength;
11845 				bufferImageHeight,										// deUint32					bufferImageHeight;
11846 				{
11847 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11848 					0u,												// deUint32				mipLevel;
11849 					arrayLayerNdx,									// deUint32				baseArrayLayer;
11850 					1u,												// deUint32				layerCount;
11851 				},														// VkImageSubresourceLayers	imageSubresource;
11852 				{0, 0, 0},												// VkOffset3D				imageOffset;
11853 				defaultHalfExtent										// VkExtent3D				imageExtent;
11854 			};
11855 			CopyRegion copyRegion;
11856 			copyRegion.bufferImageCopy = bufferImageCopy;
11857 
11858 			params.regions.push_back(copyRegion);
11859 		}
11860 		group->addChild(new CopyBufferToImageTestCase(testCtx, "array_larger_buffer", "Copy from different part of buffer to each layer", params));
11861 	}
11862 
11863 	{
11864 		TestParams				params;
11865 		deUint32				arrayLayers = 16u;
11866 		params.src.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
11867 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11868 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11869 		params.dst.image.extent				= defaultHalfExtent;
11870 		params.dst.image.extent.depth		= arrayLayers;
11871 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11872 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11873 		params.allocationKind				= allocationKind;
11874 		params.extensionUse					= extensionUse;
11875 
11876 		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11877 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11878 		{
11879 			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11880 			const VkBufferImageCopy bufferImageCopy =
11881 				{
11882 					offset,													// VkDeviceSize				bufferOffset;
11883 					defaultHalfSize,										// deUint32					bufferRowLength;
11884 					defaultHalfSize,										// deUint32					bufferImageHeight;
11885 					{
11886 						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11887 						0u,												// deUint32				mipLevel;
11888 						arrayLayerNdx,									// deUint32				baseArrayLayer;
11889 						1u,												// deUint32				layerCount;
11890 					},														// VkImageSubresourceLayers	imageSubresource;
11891 					{0, 0, 0},												// VkOffset3D				imageOffset;
11892 					defaultHalfExtent										// VkExtent3D				imageExtent;
11893 				};
11894 			CopyRegion copyRegion;
11895 			copyRegion.bufferImageCopy = bufferImageCopy;
11896 
11897 			params.regions.push_back(copyRegion);
11898 		}
11899 		group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from different part of tightly sized buffer to each layer", params));
11900 	}
11901 }
11902 
addBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11903 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11904 {
11905 	addTestGroup(group, "1d_images", "Copying operations on 1d images", add1dBufferToImageTests, allocationKind, extensionUse);
11906 	addTestGroup(group, "2d_images", "Copying operations on 2d images", add2dBufferToImageTests, allocationKind, extensionUse);
11907 }
11908 
addBufferToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11909 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11910 {
11911 	tcu::TestContext&				testCtx					= group->getTestContext();
11912 
11913 	{
11914 		TestParams			params;
11915 		params.src.buffer.size	= defaultSize;
11916 		params.dst.buffer.size	= defaultSize;
11917 		params.allocationKind	= allocationKind;
11918 		params.extensionUse		= extensionUse;
11919 
11920 		const VkBufferCopy	bufferCopy	=
11921 		{
11922 			0u,				// VkDeviceSize	srcOffset;
11923 			0u,				// VkDeviceSize	dstOffset;
11924 			defaultSize,	// VkDeviceSize	size;
11925 		};
11926 
11927 		CopyRegion	copyRegion;
11928 		copyRegion.bufferCopy	= bufferCopy;
11929 		params.regions.push_back(copyRegion);
11930 
11931 		group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
11932 	}
11933 
11934 	// Filter is VK_FILTER_NEAREST.
11935 	{
11936 		TestParams			params;
11937 		params.src.buffer.size	= defaultQuarterSize;
11938 		params.dst.buffer.size	= defaultQuarterSize;
11939 		params.allocationKind	= allocationKind;
11940 		params.extensionUse		= extensionUse;
11941 
11942 		const VkBufferCopy	bufferCopy	=
11943 		{
11944 			12u,	// VkDeviceSize	srcOffset;
11945 			4u,		// VkDeviceSize	dstOffset;
11946 			1u,		// VkDeviceSize	size;
11947 		};
11948 
11949 		CopyRegion	copyRegion;
11950 		copyRegion.bufferCopy = bufferCopy;
11951 		params.regions.push_back(copyRegion);
11952 
11953 		group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
11954 	}
11955 
11956 	{
11957 		const deUint32		size		= 16;
11958 		TestParams			params;
11959 		params.src.buffer.size	= size;
11960 		params.dst.buffer.size	= size * (size + 1);
11961 		params.allocationKind	= allocationKind;
11962 		params.extensionUse		= extensionUse;
11963 
11964 		// Copy region with size 1..size
11965 		for (unsigned int i = 1; i <= size; i++)
11966 		{
11967 			const VkBufferCopy	bufferCopy	=
11968 			{
11969 				0,			// VkDeviceSize	srcOffset;
11970 				i * size,	// VkDeviceSize	dstOffset;
11971 				i,			// VkDeviceSize	size;
11972 			};
11973 
11974 			CopyRegion	copyRegion;
11975 			copyRegion.bufferCopy = bufferCopy;
11976 			params.regions.push_back(copyRegion);
11977 		}
11978 
11979 		group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
11980 	}
11981 
11982 	{
11983 		TestParams params;
11984 		params.src.buffer.size	= 32;
11985 		params.dst.buffer.size	= 32;
11986 		params.allocationKind	= allocationKind;
11987 		params.extensionUse		= extensionUse;
11988 
11989 		// Copy four unaligned regions
11990 		for (unsigned int i = 0; i < 4; i++)
11991 		{
11992 			const VkBufferCopy bufferCopy
11993 			{
11994 				3 + i * 3,	// VkDeviceSize	srcOffset;	3  6   9  12
11995 				1 + i * 5,	// VkDeviceSize	dstOffset;	1  6  11  16
11996 				2 + i,		// VkDeviceSize	size;		2  3   4   5
11997 			};
11998 
11999 			CopyRegion copyRegion;
12000 			copyRegion.bufferCopy = bufferCopy;
12001 			params.regions.push_back(copyRegion);
12002 		}
12003 
12004 		group->addChild(new BufferToBufferTestCase(testCtx, "unaligned_regions", "Multiple unaligned regions", params));
12005 	}
12006 }
12007 
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,TestParams & params)12008 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, TestParams& params)
12009 {
12010 	tcu::TestContext& testCtx = group->getTestContext();
12011 
12012 	// Filter is VK_FILTER_NEAREST.
12013 	{
12014 		params.filter					= VK_FILTER_NEAREST;
12015 		const std::string description	= "Nearest filter";
12016 
12017 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
12018 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
12019 
12020 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
12021 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
12022 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
12023 
12024 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
12025 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
12026 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
12027 	}
12028 
12029 	// Filter is VK_FILTER_LINEAR.
12030 	{
12031 		params.filter					= VK_FILTER_LINEAR;
12032 		const std::string description	= "Linear filter";
12033 
12034 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
12035 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
12036 
12037 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
12038 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
12039 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
12040 
12041 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
12042 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
12043 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
12044 	}
12045 
12046 	// Filter is VK_FILTER_CUBIC_EXT.
12047 	// Cubic filtering can only be used with 2D images.
12048 	if (params.dst.image.imageType == VK_IMAGE_TYPE_2D)
12049 	{
12050 		params.filter					= VK_FILTER_CUBIC_EXT;
12051 		const std::string description	= "Cubic filter";
12052 
12053 		params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12054 		group->addChild(new BlitImageTestCase(testCtx, "cubic", description, params));
12055 
12056 		params.dst.image.format = VK_FORMAT_R32_SFLOAT;
12057 		const std::string	descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
12058 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToR32, params));
12059 
12060 		params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
12061 		const std::string	descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
12062 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToBGRA, params));
12063 	}
12064 }
12065 
addBlittingImageSimpleWholeTests(tcu::TestCaseGroup * group,TestParams params)12066 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, TestParams params)
12067 {
12068 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12069 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12070 	params.src.image.extent			= defaultExtent;
12071 	params.dst.image.extent			= defaultExtent;
12072 	params.src.image.extent.depth	= imageDepth;
12073 	params.dst.image.extent.depth	= imageDepth;
12074 
12075 	{
12076 		const VkImageBlit imageBlit =
12077 		{
12078 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12079 			{
12080 				{ 0, 0, 0 },
12081 				{ defaultSize, defaultSize, imageDepth }
12082 			},					// VkOffset3D				srcOffsets[2];
12083 
12084 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12085 			{
12086 				{ 0, 0, 0 },
12087 				{ defaultSize, defaultSize, imageDepth }
12088 			}					// VkOffset3D				dstOffset[2];
12089 		};
12090 
12091 		CopyRegion region;
12092 		region.imageBlit = imageBlit;
12093 		params.regions.push_back(region);
12094 	}
12095 
12096 	addBlittingImageSimpleTests(group, params);
12097 }
12098 
addBlittingImageSimpleMirrorXYTests(tcu::TestCaseGroup * group,TestParams params)12099 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, TestParams params)
12100 {
12101 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12102 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12103 	params.src.image.extent			= defaultExtent;
12104 	params.dst.image.extent			= defaultExtent;
12105 	params.src.image.extent.depth	= imageDepth;
12106 	params.dst.image.extent.depth	= imageDepth;
12107 
12108 	{
12109 		const VkImageBlit imageBlit =
12110 		{
12111 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12112 			{
12113 				{0, 0, 0},
12114 				{defaultSize, defaultSize, imageDepth}
12115 			},					// VkOffset3D				srcOffsets[2];
12116 
12117 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12118 			{
12119 				{defaultSize, defaultSize, 0},
12120 				{0, 0, imageDepth}
12121 			}					// VkOffset3D				dstOffset[2];
12122 		};
12123 
12124 		CopyRegion region;
12125 		region.imageBlit = imageBlit;
12126 		params.regions.push_back(region);
12127 	}
12128 
12129 	addBlittingImageSimpleTests(group, params);
12130 }
12131 
addBlittingImageSimpleMirrorXTests(tcu::TestCaseGroup * group,TestParams params)12132 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, TestParams params)
12133 {
12134 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12135 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12136 	params.src.image.extent			= defaultExtent;
12137 	params.dst.image.extent			= defaultExtent;
12138 	params.src.image.extent.depth	= imageDepth;
12139 	params.dst.image.extent.depth	= imageDepth;
12140 
12141 	{
12142 		const VkImageBlit imageBlit =
12143 		{
12144 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12145 			{
12146 				{0, 0, 0},
12147 				{defaultSize, defaultSize, imageDepth}
12148 			},					// VkOffset3D				srcOffsets[2];
12149 
12150 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12151 			{
12152 				{defaultSize, 0, 0},
12153 				{0, defaultSize, imageDepth}
12154 			}					// VkOffset3D				dstOffset[2];
12155 		};
12156 
12157 		CopyRegion region;
12158 		region.imageBlit = imageBlit;
12159 		params.regions.push_back(region);
12160 	}
12161 
12162 	addBlittingImageSimpleTests(group, params);
12163 }
12164 
addBlittingImageSimpleMirrorYTests(tcu::TestCaseGroup * group,TestParams params)12165 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, TestParams params)
12166 {
12167 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12168 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12169 	params.src.image.extent			= defaultExtent;
12170 	params.dst.image.extent			= defaultExtent;
12171 	params.src.image.extent.depth	= imageDepth;
12172 	params.dst.image.extent.depth	= imageDepth;
12173 
12174 	{
12175 		const VkImageBlit imageBlit =
12176 		{
12177 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12178 			{
12179 				{0, 0, 0},
12180 				{defaultSize, defaultSize, imageDepth}
12181 			},					// VkOffset3D				srcOffsets[2];
12182 
12183 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12184 			{
12185 				{0, defaultSize, 0},
12186 				{defaultSize, 0, imageDepth}
12187 			}					// VkOffset3D				dstOffset[2];
12188 		};
12189 
12190 		CopyRegion region;
12191 		region.imageBlit = imageBlit;
12192 		params.regions.push_back(region);
12193 	}
12194 
12195 	addBlittingImageSimpleTests(group, params);
12196 }
12197 
addBlittingImageSimpleMirrorZTests(tcu::TestCaseGroup * group,TestParams params)12198 void addBlittingImageSimpleMirrorZTests (tcu::TestCaseGroup* group, TestParams params)
12199 {
12200 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12201 	DE_ASSERT(params.src.image.imageType == VK_IMAGE_TYPE_3D);
12202 	params.src.image.extent			= defaultExtent;
12203 	params.dst.image.extent			= defaultExtent;
12204 	params.src.image.extent.depth	= defaultSize;
12205 	params.dst.image.extent.depth	= defaultSize;
12206 
12207 	{
12208 		const VkImageBlit imageBlit =
12209 		{
12210 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12211 			{
12212 				{0, 0, 0},
12213 				{defaultSize, defaultSize, defaultSize}
12214 			},					// VkOffset3D				srcOffsets[2];
12215 
12216 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12217 			{
12218 				{0, 0, defaultSize},
12219 				{defaultSize, defaultSize, 0}
12220 			}					// VkOffset3D				dstOffset[2];
12221 		};
12222 
12223 		CopyRegion region;
12224 		region.imageBlit = imageBlit;
12225 		params.regions.push_back(region);
12226 	}
12227 
12228 	addBlittingImageSimpleTests(group, params);
12229 }
12230 
addBlittingImageSimpleMirrorSubregionsTests(tcu::TestCaseGroup * group,TestParams params)12231 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, TestParams params)
12232 {
12233 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12234 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12235 	params.src.image.extent			= defaultExtent;
12236 	params.dst.image.extent			= defaultExtent;
12237 	params.src.image.extent.depth	= imageDepth;
12238 	params.dst.image.extent.depth	= imageDepth;
12239 
12240 	// No mirroring.
12241 	{
12242 		const VkImageBlit imageBlit =
12243 		{
12244 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12245 			{
12246 				{0, 0, 0},
12247 				{defaultHalfSize, defaultHalfSize, imageDepth}
12248 			},					// VkOffset3D				srcOffsets[2];
12249 
12250 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12251 			{
12252 				{0, 0, 0},
12253 				{defaultHalfSize, defaultHalfSize, imageDepth}
12254 			}					// VkOffset3D				dstOffset[2];
12255 		};
12256 
12257 		CopyRegion region;
12258 		region.imageBlit = imageBlit;
12259 		params.regions.push_back(region);
12260 	}
12261 
12262 	// Flipping y coordinates.
12263 	{
12264 		const VkImageBlit imageBlit =
12265 		{
12266 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12267 			{
12268 				{defaultHalfSize, 0, 0},
12269 				{defaultSize, defaultHalfSize, imageDepth}
12270 			},					// VkOffset3D				srcOffsets[2];
12271 
12272 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12273 			{
12274 				{defaultHalfSize, defaultHalfSize, 0},
12275 				{defaultSize, 0, imageDepth}
12276 			}					// VkOffset3D				dstOffset[2];
12277 		};
12278 		CopyRegion region;
12279 		region.imageBlit = imageBlit;
12280 		params.regions.push_back(region);
12281 	}
12282 
12283 	// Flipping x coordinates.
12284 	{
12285 		const VkImageBlit imageBlit =
12286 		{
12287 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12288 			{
12289 				{0, defaultHalfSize, 0},
12290 				{defaultHalfSize, defaultSize, imageDepth}
12291 			},					// VkOffset3D				srcOffsets[2];
12292 
12293 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12294 			{
12295 				{defaultHalfSize, defaultHalfSize, 0},
12296 				{0, defaultSize, imageDepth}
12297 			}					// VkOffset3D				dstOffset[2];
12298 		};
12299 
12300 		CopyRegion region;
12301 		region.imageBlit = imageBlit;
12302 		params.regions.push_back(region);
12303 	}
12304 
12305 	// Flipping x and y coordinates.
12306 	{
12307 		const VkImageBlit imageBlit =
12308 		{
12309 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12310 			{
12311 				{defaultHalfSize, defaultHalfSize, 0},
12312 				{defaultSize, defaultSize, imageDepth}
12313 			},					// VkOffset3D				srcOffsets[2];
12314 
12315 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12316 			{
12317 				{defaultSize, defaultSize, 0},
12318 				{defaultHalfSize, defaultHalfSize, imageDepth}
12319 			}					// VkOffset3D				dstOffset[2];
12320 		};
12321 
12322 		CopyRegion region;
12323 		region.imageBlit = imageBlit;
12324 		params.regions.push_back(region);
12325 	}
12326 
12327 	addBlittingImageSimpleTests(group, params);
12328 }
12329 
addBlittingImageSimpleScalingWhole1Tests(tcu::TestCaseGroup * group,TestParams params)12330 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, TestParams params)
12331 {
12332 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12333 	const deInt32	imageDepth		= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12334 	const deInt32	halfImageDepth	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
12335 	params.src.image.extent			= defaultExtent;
12336 	params.dst.image.extent			= defaultHalfExtent;
12337 	params.src.image.extent.depth	= imageDepth;
12338 	params.dst.image.extent.depth	= halfImageDepth;
12339 
12340 	{
12341 		const VkImageBlit imageBlit =
12342 		{
12343 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12344 			{
12345 				{0, 0, 0},
12346 				{defaultSize, defaultSize, imageDepth}
12347 			},					// VkOffset3D					srcOffsets[2];
12348 
12349 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12350 			{
12351 				{0, 0, 0},
12352 				{defaultHalfSize, defaultHalfSize, halfImageDepth}
12353 			}					// VkOffset3D					dstOffset[2];
12354 		};
12355 
12356 		CopyRegion region;
12357 		region.imageBlit = imageBlit;
12358 		params.regions.push_back(region);
12359 	}
12360 
12361 	addBlittingImageSimpleTests(group, params);
12362 }
12363 
addBlittingImageSimpleScalingWhole2Tests(tcu::TestCaseGroup * group,TestParams params)12364 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, TestParams params)
12365 {
12366 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12367 	const deInt32	imageDepth		= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12368 	const deInt32	halfImageDepth	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
12369 	params.src.image.extent			= defaultHalfExtent;
12370 	params.dst.image.extent			= defaultExtent;
12371 	params.src.image.extent.depth	= halfImageDepth;
12372 	params.dst.image.extent.depth	= imageDepth;
12373 
12374 	{
12375 		const VkImageBlit imageBlit =
12376 		{
12377 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12378 			{
12379 				{0, 0, 0},
12380 				{defaultHalfSize, defaultHalfSize, halfImageDepth}
12381 			},					// VkOffset3D					srcOffsets[2];
12382 
12383 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12384 			{
12385 				{0, 0, 0},
12386 				{defaultSize, defaultSize, imageDepth}
12387 			}					// VkOffset3D					dstOffset[2];
12388 		};
12389 
12390 		CopyRegion region;
12391 		region.imageBlit = imageBlit;
12392 		params.regions.push_back(region);
12393 	}
12394 
12395 	addBlittingImageSimpleTests(group, params);
12396 }
12397 
addBlittingImageSimpleScalingAndOffsetTests(tcu::TestCaseGroup * group,TestParams params)12398 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, TestParams params)
12399 {
12400 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12401 	const deInt32	imageDepth		= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12402 	const deInt32	srcDepthOffset	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultQuarterSize : 0;
12403 	const deInt32	srcDepthSize	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultQuarterSize * 3 : 1;
12404 	params.src.image.extent			= defaultExtent;
12405 	params.dst.image.extent			= defaultExtent;
12406 	params.src.image.extent.depth	= imageDepth;
12407 	params.dst.image.extent.depth	= imageDepth;
12408 
12409 	{
12410 		const VkImageBlit imageBlit =
12411 		{
12412 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12413 			{
12414 				{defaultQuarterSize, defaultQuarterSize, srcDepthOffset},
12415 				{defaultQuarterSize*3, defaultQuarterSize*3, srcDepthSize}
12416 			},					// VkOffset3D					srcOffsets[2];
12417 
12418 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12419 			{
12420 				{0, 0, 0},
12421 				{defaultSize, defaultSize, imageDepth}
12422 			}					// VkOffset3D					dstOffset[2];
12423 		};
12424 
12425 		CopyRegion region;
12426 		region.imageBlit = imageBlit;
12427 		params.regions.push_back(region);
12428 	}
12429 
12430 	addBlittingImageSimpleTests(group, params);
12431 }
12432 
addBlittingImageSimpleWithoutScalingPartialTests(tcu::TestCaseGroup * group,TestParams params)12433 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, TestParams params)
12434 {
12435 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12436 	const bool is3dBlit = params.src.image.imageType == VK_IMAGE_TYPE_3D;
12437 	params.src.image.extent	= defaultExtent;
12438 	params.dst.image.extent	= defaultExtent;
12439 
12440 	if (is3dBlit)
12441 	{
12442 		params.src.image.extent.depth = defaultSize;
12443 		params.dst.image.extent.depth = defaultSize;
12444 	}
12445 
12446 	{
12447 		CopyRegion region;
12448 		for (int i = 0; i < defaultSize; i += defaultQuarterSize)
12449 		{
12450 			const VkImageBlit imageBlit =
12451 			{
12452 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12453 				{
12454 					{defaultSize - defaultQuarterSize - i, defaultSize - defaultQuarterSize - i, is3dBlit ? defaultSize - defaultQuarterSize - i : 0},
12455 					{defaultSize - i, defaultSize - i, is3dBlit ? defaultSize - i : 1}
12456 				},					// VkOffset3D					srcOffsets[2];
12457 
12458 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12459 				{
12460 					{i, i, is3dBlit ? i : 0},
12461 					{i + defaultQuarterSize, i + defaultQuarterSize, is3dBlit ? i + defaultQuarterSize : 1}
12462 				}					// VkOffset3D					dstOffset[2];
12463 			};
12464 			region.imageBlit = imageBlit;
12465 			params.regions.push_back(region);
12466 		}
12467 	}
12468 
12469 	addBlittingImageSimpleTests(group, params);
12470 }
12471 
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12472 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12473 {
12474 	TestParams params;
12475 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12476 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12477 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12478 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12479 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12480 	params.allocationKind				= allocationKind;
12481 	params.extensionUse					= extensionUse;
12482 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12483 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12484 	addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
12485 	addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, params);
12486 	addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, params);
12487 	addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, params);
12488 	addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
12489 	addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
12490 	addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
12491 	addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
12492 	addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
12493 
12494 	params.src.image.imageType			= VK_IMAGE_TYPE_3D;
12495 	params.dst.image.imageType			= VK_IMAGE_TYPE_3D;
12496 	addTestGroup(group, "whole_3d", "3D blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
12497 	addTestGroup(group, "mirror_xy_3d", "Flipping x and y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXYTests, params);
12498 	addTestGroup(group, "mirror_x_3d", "Flipping x coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXTests, params);
12499 	addTestGroup(group, "mirror_y_3d", "Flipping y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorYTests, params);
12500 	addTestGroup(group, "mirror_z_3d", "Flipping z coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorZTests, params);
12501 	addTestGroup(group, "mirror_subregions_3d", "Mirroring subregions in a 3D image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
12502 	addTestGroup(group, "scaling_whole1_3d", "3D blit a with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
12503 	addTestGroup(group, "scaling_whole2_3d", "3D blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
12504 	addTestGroup(group, "scaling_and_offset_3d", "3D blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
12505 	addTestGroup(group, "without_scaling_partial_3d", "3D blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
12506 }
12507 
12508 enum FilterMaskBits
12509 {
12510 	FILTER_MASK_NEAREST	= 0,			// Always tested.
12511 	FILTER_MASK_LINEAR	= (1u << 0),
12512 	FILTER_MASK_CUBIC	= (1u << 1),
12513 };
12514 
12515 using FilterMask = deUint32;
12516 
makeFilterMask(bool onlyNearest,bool discardCubicFilter)12517 FilterMask makeFilterMask (bool onlyNearest, bool discardCubicFilter)
12518 {
12519 	FilterMask mask = FILTER_MASK_NEAREST;
12520 
12521 	if (!onlyNearest)
12522 	{
12523 		mask |= FILTER_MASK_LINEAR;
12524 		if (!discardCubicFilter)
12525 			mask |= FILTER_MASK_CUBIC;
12526 	}
12527 
12528 	return mask;
12529 }
12530 
12531 struct BlitColorTestParams
12532 {
12533 	TestParams		params;
12534 	const VkFormat*	compatibleFormats;
12535 	FilterMask		testFilters;
12536 };
12537 
isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams & testParams)12538 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
12539 {
12540 	bool result = true;
12541 
12542 	if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
12543 	{
12544 		DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
12545 
12546 		result =
12547 			de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
12548 			de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
12549 	}
12550 
12551 	return result;
12552 }
12553 
12554 const VkFormat	linearOtherImageFormatsToTest[]	=
12555 {
12556 	// From compatibleFormats8Bit
12557 	VK_FORMAT_R4G4_UNORM_PACK8,
12558 	VK_FORMAT_R8_SRGB,
12559 
12560 	// From compatibleFormats16Bit
12561 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
12562 	VK_FORMAT_R16_SFLOAT,
12563 
12564 	// From compatibleFormats24Bit
12565 	VK_FORMAT_R8G8B8_UNORM,
12566 	VK_FORMAT_B8G8R8_SRGB,
12567 
12568 	// From compatibleFormats32Bit
12569 	VK_FORMAT_R8G8B8A8_UNORM,
12570 	VK_FORMAT_R32_SFLOAT,
12571 
12572 	// From compatibleFormats48Bit
12573 	VK_FORMAT_R16G16B16_UNORM,
12574 	VK_FORMAT_R16G16B16_SFLOAT,
12575 
12576 	// From compatibleFormats64Bit
12577 	VK_FORMAT_R16G16B16A16_UNORM,
12578 	VK_FORMAT_R64_SFLOAT,
12579 
12580 	// From compatibleFormats96Bit
12581 	VK_FORMAT_R32G32B32_UINT,
12582 	VK_FORMAT_R32G32B32_SFLOAT,
12583 
12584 	// From compatibleFormats128Bit
12585 	VK_FORMAT_R32G32B32A32_UINT,
12586 	VK_FORMAT_R64G64_SFLOAT,
12587 
12588 	// From compatibleFormats192Bit
12589 	VK_FORMAT_R64G64B64_UINT,
12590 	VK_FORMAT_R64G64B64_SFLOAT,
12591 
12592 	// From compatibleFormats256Bit
12593 	VK_FORMAT_R64G64B64A64_UINT,
12594 	VK_FORMAT_R64G64B64A64_SFLOAT,
12595 };
12596 
getBlitImageTilingLayoutCaseName(VkImageTiling tiling,VkImageLayout layout)12597 std::string getBlitImageTilingLayoutCaseName (VkImageTiling tiling, VkImageLayout layout)
12598 {
12599 	switch (tiling)
12600 	{
12601 		case VK_IMAGE_TILING_OPTIMAL:
12602 			return getImageLayoutCaseName(layout);
12603 		case VK_IMAGE_TILING_LINEAR:
12604 			return "linear";
12605 		default:
12606 			DE_ASSERT(false);
12607 			return "";
12608 	}
12609 }
12610 
addBlittingImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)12611 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
12612 {
12613 	tcu::TestContext& testCtx				= group->getTestContext();
12614 
12615 	FormatSet linearOtherImageFormatsToTestSet;
12616 	const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
12617 	for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter; ++otherImageFormatsIndex)
12618 		linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);
12619 
12620 	const VkImageTiling blitSrcTilings[]	=
12621 	{
12622 		VK_IMAGE_TILING_OPTIMAL,
12623 		VK_IMAGE_TILING_LINEAR,
12624 	};
12625 	const VkImageLayout blitSrcLayouts[]	=
12626 	{
12627 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
12628 		VK_IMAGE_LAYOUT_GENERAL
12629 	};
12630 	const VkImageTiling blitDstTilings[]	=
12631 	{
12632 		VK_IMAGE_TILING_OPTIMAL,
12633 		VK_IMAGE_TILING_LINEAR,
12634 	};
12635 	const VkImageLayout blitDstLayouts[]	=
12636 	{
12637 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
12638 		VK_IMAGE_LAYOUT_GENERAL
12639 	};
12640 
12641 	for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
12642 	{
12643 		testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];
12644 
12645 		for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
12646 		{
12647 			testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
12648 
12649 			// 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
12650 			if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
12651 				continue;
12652 
12653 			for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
12654 			{
12655 				testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];
12656 
12657 				for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
12658 				{
12659 					testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
12660 
12661 					// 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
12662 					if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
12663 						continue;
12664 
12665 					if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
12666 					    (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
12667 						continue;
12668 
12669 					testParams.params.filter			= VK_FILTER_NEAREST;
12670 					const std::string testName			= getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) + "_" +
12671 														  getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
12672 					const std::string description		= "Blit from layout " + getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) +
12673 														  " to " + getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
12674 					group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params));
12675 
12676 					if (testParams.testFilters & FILTER_MASK_LINEAR)
12677 					{
12678 						testParams.params.filter = VK_FILTER_LINEAR;
12679 						group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params));
12680 					}
12681 
12682 					if (testParams.testFilters & FILTER_MASK_CUBIC)
12683 					{
12684 						testParams.params.filter = VK_FILTER_CUBIC_EXT;
12685 						group->addChild(new BlitImageTestCase(testCtx, testName + "_cubic", description, testParams.params));
12686 					}
12687 
12688 					if ((testParams.params.src.image.imageType == VK_IMAGE_TYPE_3D) && !isCompressedFormat(testParams.params.src.image.format))
12689 					{
12690 						const struct
12691 						{
12692 							FillMode	mode;
12693 							const char*	name;
12694 						} modeList[] =
12695 						{
12696 							{ FILL_MODE_BLUE_RED_X, "x" },
12697 							{ FILL_MODE_BLUE_RED_Y, "y" },
12698 							{ FILL_MODE_BLUE_RED_Z, "z" },
12699 						};
12700 
12701 						auto otherParams = testParams;
12702 						otherParams.params.dst.image.fillMode = FILL_MODE_WHITE;
12703 
12704 						for (int i = 0; i < DE_LENGTH_OF_ARRAY(modeList); ++i)
12705 						{
12706 							otherParams.params.src.image.fillMode = modeList[i].mode;
12707 
12708 							otherParams.params.filter = VK_FILTER_LINEAR;
12709 							group->addChild(new BlitImageTestCase(testCtx, testName + "_linear_stripes_" + modeList[i].name, description, otherParams.params));
12710 
12711 							otherParams.params.filter = VK_FILTER_NEAREST;
12712 							group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest_stripes_" + modeList[i].name, description, otherParams.params));
12713 						}
12714 					}
12715 				}
12716 			}
12717 		}
12718 	}
12719 }
12720 
addBlittingImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)12721 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
12722 {
12723 	VkFormat srcFormat = testParams.params.src.image.format;
12724 
12725 	if (testParams.compatibleFormats)
12726 	{
12727 		for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
12728 		{
12729 			testParams.params.dst.image.format	= testParams.compatibleFormats[dstFormatIndex];
12730 			if (!isSupportedByFramework(testParams.params.dst.image.format))
12731 				continue;
12732 
12733 			if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
12734 				continue;
12735 
12736 			const std::string description	= "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
12737 			addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
12738 		}
12739 	}
12740 
12741 	// If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format
12742 	// When testParams.compatibleFormats is not nullptr but format is compressed we also need to add that format
12743 	// as it is not on compatibleFormats list
12744 	if (!testParams.compatibleFormats || isCompressedFormat(srcFormat))
12745 	{
12746 		testParams.params.dst.image.format = srcFormat;
12747 
12748 		const std::string description = "Blit destination format " + getFormatCaseName(srcFormat);
12749 		addTestGroup(group, getFormatCaseName(srcFormat), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
12750 	}
12751 }
12752 
12753 const VkFormat	compatibleFormatsUInts[]	=
12754 {
12755 	VK_FORMAT_R8_UINT,
12756 	VK_FORMAT_R8G8_UINT,
12757 	VK_FORMAT_R8G8B8_UINT,
12758 	VK_FORMAT_B8G8R8_UINT,
12759 	VK_FORMAT_R8G8B8A8_UINT,
12760 	VK_FORMAT_B8G8R8A8_UINT,
12761 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
12762 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
12763 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
12764 	VK_FORMAT_R16_UINT,
12765 	VK_FORMAT_R16G16_UINT,
12766 	VK_FORMAT_R16G16B16_UINT,
12767 	VK_FORMAT_R16G16B16A16_UINT,
12768 	VK_FORMAT_R32_UINT,
12769 	VK_FORMAT_R32G32_UINT,
12770 	VK_FORMAT_R32G32B32_UINT,
12771 	VK_FORMAT_R32G32B32A32_UINT,
12772 	VK_FORMAT_R64_UINT,
12773 	VK_FORMAT_R64G64_UINT,
12774 	VK_FORMAT_R64G64B64_UINT,
12775 	VK_FORMAT_R64G64B64A64_UINT,
12776 
12777 	VK_FORMAT_UNDEFINED
12778 };
12779 const VkFormat	compatibleFormatsSInts[]	=
12780 {
12781 	VK_FORMAT_R8_SINT,
12782 	VK_FORMAT_R8G8_SINT,
12783 	VK_FORMAT_R8G8B8_SINT,
12784 	VK_FORMAT_B8G8R8_SINT,
12785 	VK_FORMAT_R8G8B8A8_SINT,
12786 	VK_FORMAT_B8G8R8A8_SINT,
12787 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
12788 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
12789 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
12790 	VK_FORMAT_R16_SINT,
12791 	VK_FORMAT_R16G16_SINT,
12792 	VK_FORMAT_R16G16B16_SINT,
12793 	VK_FORMAT_R16G16B16A16_SINT,
12794 	VK_FORMAT_R32_SINT,
12795 	VK_FORMAT_R32G32_SINT,
12796 	VK_FORMAT_R32G32B32_SINT,
12797 	VK_FORMAT_R32G32B32A32_SINT,
12798 	VK_FORMAT_R64_SINT,
12799 	VK_FORMAT_R64G64_SINT,
12800 	VK_FORMAT_R64G64B64_SINT,
12801 	VK_FORMAT_R64G64B64A64_SINT,
12802 
12803 	VK_FORMAT_UNDEFINED
12804 };
12805 const VkFormat	compatibleFormatsFloats[]	=
12806 {
12807 	VK_FORMAT_R4G4_UNORM_PACK8,
12808 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
12809 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
12810 	VK_FORMAT_R5G6B5_UNORM_PACK16,
12811 	VK_FORMAT_B5G6R5_UNORM_PACK16,
12812 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
12813 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
12814 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
12815 	VK_FORMAT_R8_UNORM,
12816 	VK_FORMAT_R8_SNORM,
12817 	VK_FORMAT_R8_USCALED,
12818 	VK_FORMAT_R8_SSCALED,
12819 	VK_FORMAT_R8G8_UNORM,
12820 	VK_FORMAT_R8G8_SNORM,
12821 	VK_FORMAT_R8G8_USCALED,
12822 	VK_FORMAT_R8G8_SSCALED,
12823 	VK_FORMAT_R8G8B8_UNORM,
12824 	VK_FORMAT_R8G8B8_SNORM,
12825 	VK_FORMAT_R8G8B8_USCALED,
12826 	VK_FORMAT_R8G8B8_SSCALED,
12827 	VK_FORMAT_B8G8R8_UNORM,
12828 	VK_FORMAT_B8G8R8_SNORM,
12829 	VK_FORMAT_B8G8R8_USCALED,
12830 	VK_FORMAT_B8G8R8_SSCALED,
12831 	VK_FORMAT_R8G8B8A8_UNORM,
12832 	VK_FORMAT_R8G8B8A8_SNORM,
12833 	VK_FORMAT_R8G8B8A8_USCALED,
12834 	VK_FORMAT_R8G8B8A8_SSCALED,
12835 	VK_FORMAT_B8G8R8A8_UNORM,
12836 	VK_FORMAT_B8G8R8A8_SNORM,
12837 	VK_FORMAT_B8G8R8A8_USCALED,
12838 	VK_FORMAT_B8G8R8A8_SSCALED,
12839 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
12840 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
12841 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
12842 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
12843 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
12844 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
12845 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
12846 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
12847 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
12848 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
12849 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
12850 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
12851 	VK_FORMAT_R16_UNORM,
12852 	VK_FORMAT_R16_SNORM,
12853 	VK_FORMAT_R16_USCALED,
12854 	VK_FORMAT_R16_SSCALED,
12855 	VK_FORMAT_R16_SFLOAT,
12856 	VK_FORMAT_R16G16_UNORM,
12857 	VK_FORMAT_R16G16_SNORM,
12858 	VK_FORMAT_R16G16_USCALED,
12859 	VK_FORMAT_R16G16_SSCALED,
12860 	VK_FORMAT_R16G16_SFLOAT,
12861 	VK_FORMAT_R16G16B16_UNORM,
12862 	VK_FORMAT_R16G16B16_SNORM,
12863 	VK_FORMAT_R16G16B16_USCALED,
12864 	VK_FORMAT_R16G16B16_SSCALED,
12865 	VK_FORMAT_R16G16B16_SFLOAT,
12866 	VK_FORMAT_R16G16B16A16_UNORM,
12867 	VK_FORMAT_R16G16B16A16_SNORM,
12868 	VK_FORMAT_R16G16B16A16_USCALED,
12869 	VK_FORMAT_R16G16B16A16_SSCALED,
12870 	VK_FORMAT_R16G16B16A16_SFLOAT,
12871 	VK_FORMAT_R32_SFLOAT,
12872 	VK_FORMAT_R32G32_SFLOAT,
12873 	VK_FORMAT_R32G32B32_SFLOAT,
12874 	VK_FORMAT_R32G32B32A32_SFLOAT,
12875 	VK_FORMAT_R64_SFLOAT,
12876 	VK_FORMAT_R64G64_SFLOAT,
12877 	VK_FORMAT_R64G64B64_SFLOAT,
12878 	VK_FORMAT_R64G64B64A64_SFLOAT,
12879 	VK_FORMAT_B10G11R11_UFLOAT_PACK32,
12880 	VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
12881 
12882 	VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
12883 	VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
12884 
12885 	VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
12886 
12887 	VK_FORMAT_UNDEFINED
12888 };
12889 
12890 const VkFormat	compressedFormatsFloats[] =
12891 {
12892 	VK_FORMAT_BC1_RGB_UNORM_BLOCK,
12893 	VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
12894 	VK_FORMAT_BC2_UNORM_BLOCK,
12895 	VK_FORMAT_BC3_UNORM_BLOCK,
12896 	VK_FORMAT_BC4_UNORM_BLOCK,
12897 	VK_FORMAT_BC4_SNORM_BLOCK,
12898 	VK_FORMAT_BC5_UNORM_BLOCK,
12899 	VK_FORMAT_BC5_SNORM_BLOCK,
12900 	VK_FORMAT_BC6H_UFLOAT_BLOCK,
12901 	VK_FORMAT_BC6H_SFLOAT_BLOCK,
12902 	VK_FORMAT_BC7_UNORM_BLOCK,
12903 	VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
12904 	VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
12905 	VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
12906 	VK_FORMAT_EAC_R11_UNORM_BLOCK,
12907 	VK_FORMAT_EAC_R11_SNORM_BLOCK,
12908 	VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
12909 	VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
12910 	VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
12911 	VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
12912 	VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
12913 	VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
12914 	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
12915 	VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
12916 	VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
12917 	VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
12918 	VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
12919 	VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
12920 	VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
12921 	VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
12922 	VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
12923 	VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
12924 
12925 	VK_FORMAT_UNDEFINED
12926 };
12927 
12928 const VkFormat	compatibleFormatsSrgb[]		=
12929 {
12930 	VK_FORMAT_R8_SRGB,
12931 	VK_FORMAT_R8G8_SRGB,
12932 	VK_FORMAT_R8G8B8_SRGB,
12933 	VK_FORMAT_B8G8R8_SRGB,
12934 	VK_FORMAT_R8G8B8A8_SRGB,
12935 	VK_FORMAT_B8G8R8A8_SRGB,
12936 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
12937 
12938 	VK_FORMAT_UNDEFINED
12939 };
12940 
12941 const VkFormat	compressedFormatsSrgb[] =
12942 {
12943 	VK_FORMAT_BC1_RGB_SRGB_BLOCK,
12944 	VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
12945 	VK_FORMAT_BC2_SRGB_BLOCK,
12946 	VK_FORMAT_BC3_SRGB_BLOCK,
12947 	VK_FORMAT_BC7_SRGB_BLOCK,
12948 	VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
12949 	VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
12950 	VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
12951 	VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
12952 	VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
12953 	VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
12954 	VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
12955 	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
12956 	VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
12957 	VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
12958 	VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
12959 	VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
12960 	VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
12961 	VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
12962 	VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
12963 	VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
12964 	VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
12965 
12966 	VK_FORMAT_UNDEFINED
12967 };
12968 
12969 const VkFormat	dedicatedAllocationBlittingFormatsToTest[]	=
12970 {
12971 	// compatibleFormatsUInts
12972 	VK_FORMAT_R8_UINT,
12973 	VK_FORMAT_R64G64B64A64_UINT,
12974 
12975 	// compatibleFormatsSInts
12976 	VK_FORMAT_R8_SINT,
12977 	VK_FORMAT_R64G64B64A64_SINT,
12978 
12979 	// compatibleFormatsFloats
12980 	VK_FORMAT_R4G4_UNORM_PACK8,
12981 	VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
12982 
12983 	// compatibleFormatsSrgb
12984 	VK_FORMAT_R8_SRGB,
12985 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
12986 };
12987 
12988 // skip cubic filtering test for the following data formats
12989 const FormatSet	onlyNearestAndLinearFormatsToTest =
12990 {
12991 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
12992 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
12993 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
12994 	VK_FORMAT_A8B8G8R8_SINT_PACK32
12995 };
12996 
12997 // astc formats have diferent block sizes and thus require diferent resolutions for images
12998 enum class AstcImageSizeType
12999 {
13000 	SIZE_64_64 = 0,
13001 	SIZE_60_64,
13002 	SIZE_64_60,
13003 	SIZE_60_60,
13004 };
13005 
13006 const std::map<VkFormat, AstcImageSizeType> astcSizes
13007 {
13008 	{ VK_FORMAT_ASTC_4x4_SRGB_BLOCK,	AstcImageSizeType::SIZE_64_64 },
13009 	{ VK_FORMAT_ASTC_4x4_UNORM_BLOCK,	AstcImageSizeType::SIZE_64_64 },
13010 	{ VK_FORMAT_ASTC_5x4_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_64 },
13011 	{ VK_FORMAT_ASTC_5x4_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_64 },
13012 	{ VK_FORMAT_ASTC_5x5_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13013 	{ VK_FORMAT_ASTC_5x5_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13014 	{ VK_FORMAT_ASTC_6x5_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13015 	{ VK_FORMAT_ASTC_6x5_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13016 	{ VK_FORMAT_ASTC_6x6_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13017 	{ VK_FORMAT_ASTC_6x6_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13018 	{ VK_FORMAT_ASTC_8x5_SRGB_BLOCK,	AstcImageSizeType::SIZE_64_60 },
13019 	{ VK_FORMAT_ASTC_8x5_UNORM_BLOCK,	AstcImageSizeType::SIZE_64_60 },
13020 	{ VK_FORMAT_ASTC_8x6_SRGB_BLOCK,	AstcImageSizeType::SIZE_64_60 },
13021 	{ VK_FORMAT_ASTC_8x6_UNORM_BLOCK,	AstcImageSizeType::SIZE_64_60 },
13022 	{ VK_FORMAT_ASTC_8x8_SRGB_BLOCK,	AstcImageSizeType::SIZE_64_64 },
13023 	{ VK_FORMAT_ASTC_8x8_UNORM_BLOCK,	AstcImageSizeType::SIZE_64_64 },
13024 	{ VK_FORMAT_ASTC_10x5_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13025 	{ VK_FORMAT_ASTC_10x5_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13026 	{ VK_FORMAT_ASTC_10x6_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13027 	{ VK_FORMAT_ASTC_10x6_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13028 	{ VK_FORMAT_ASTC_10x8_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_64 },
13029 	{ VK_FORMAT_ASTC_10x8_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_64 },
13030 	{ VK_FORMAT_ASTC_10x10_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13031 	{ VK_FORMAT_ASTC_10x10_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13032 	{ VK_FORMAT_ASTC_12x10_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13033 	{ VK_FORMAT_ASTC_12x10_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13034 	{ VK_FORMAT_ASTC_12x12_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13035 	{ VK_FORMAT_ASTC_12x12_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 }
13036 };
13037 
create2DCopyRegions(deInt32 srcWidth,deInt32 srcHeight,deInt32 dstWidth,deInt32 dstHeight)13038 std::vector<CopyRegion> create2DCopyRegions(deInt32 srcWidth, deInt32 srcHeight, deInt32 dstWidth, deInt32 dstHeight)
13039 {
13040 	CopyRegion				region;
13041 	std::vector<CopyRegion>	regionsVector;
13042 
13043 	deInt32					fourthOfSrcWidth	= srcWidth / 4;
13044 	deInt32					fourthOfSrcHeight	= srcHeight / 4;
13045 	deInt32					fourthOfDstWidth	= dstWidth / 4;
13046 	deInt32					fourthOfDstHeight	= dstHeight / 4;
13047 
13048 	// to the top of resulting image copy whole source image but with increasingly smaller sizes
13049 	for (int i = 0, j = 1; (i + fourthOfDstWidth / j < dstWidth) && (fourthOfDstWidth > j); i += fourthOfDstWidth / j++)
13050 	{
13051 		region.imageBlit =
13052 		{
13053 			defaultSourceLayer,						// VkImageSubresourceLayers		srcSubresource;
13054 			{
13055 				{0, 0, 0},
13056 				{srcWidth, srcHeight, 1}
13057 			},										// VkOffset3D					srcOffsets[2];
13058 
13059 			defaultSourceLayer,						// VkImageSubresourceLayers		dstSubresource;
13060 			{
13061 				{i, 0, 0},
13062 				{i + fourthOfDstWidth / j, fourthOfDstHeight / j, 1}
13063 			}										// VkOffset3D					dstOffset[2];
13064 		};
13065 		regionsVector.push_back(region);
13066 	}
13067 
13068 	// to the bottom of resulting image copy parts of source image;
13069 	for (int i = 0; i < 4; ++i)
13070 	{
13071 		int srcX = i * fourthOfSrcWidth;
13072 		int srcY = i * fourthOfSrcHeight;
13073 		int dstX = i * fourthOfDstWidth;
13074 
13075 		region.imageBlit =
13076 		{
13077 			defaultSourceLayer,						// VkImageSubresourceLayers		srcSubresource;
13078 			{
13079 				{srcX, srcY, 0},
13080 				{srcX + fourthOfSrcWidth, srcY + fourthOfSrcHeight, 1}
13081 			},										// VkOffset3D					srcOffsets[2];
13082 
13083 			defaultSourceLayer,						// VkImageSubresourceLayers		dstSubresource;
13084 			{
13085 				{dstX, 2 * fourthOfDstHeight, 0},
13086 				{dstX + fourthOfDstWidth, 3 * fourthOfDstHeight, 1}
13087 			}										// VkOffset3D					dstOffset[2];
13088 		};
13089 
13090 		regionsVector.push_back(region);
13091 	}
13092 
13093 	return regionsVector;
13094 }
13095 
addBlittingImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13096 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13097 {
13098 	const struct {
13099 		const VkFormat*	sourceFormats;
13100 		const VkFormat*	destinationFormats;
13101 		const bool		onlyNearest;
13102 	}	colorImageFormatsToTestBlit[] =
13103 	{
13104 		{ compatibleFormatsUInts,	compatibleFormatsUInts,		true	},
13105 		{ compatibleFormatsSInts,	compatibleFormatsSInts,		true	},
13106 		{ compatibleFormatsFloats,	compatibleFormatsFloats,	false	},
13107 		{ compressedFormatsFloats,	compatibleFormatsFloats,	false	},
13108 		{ compatibleFormatsSrgb,	compatibleFormatsSrgb,		false	},
13109 		{ compressedFormatsSrgb,	compatibleFormatsSrgb,		false	},
13110 	};
13111 
13112 	const int	numOfColorImageFormatsToTest		= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
13113 
13114 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
13115 	{
13116 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
13117 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
13118 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
13119 	}
13120 
13121 	// 2D tests.
13122 	{
13123 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
13124 
13125 		TestParams	params;
13126 		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
13127 		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
13128 		params.src.image.extent		= defaultExtent;
13129 		params.dst.image.extent		= defaultExtent;
13130 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13131 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13132 		params.allocationKind		= allocationKind;
13133 		params.extensionUse			= extensionUse;
13134 
13135 		// create all required copy regions
13136 		const std::map<AstcImageSizeType, std::vector<CopyRegion> > imageRegions
13137 		{
13138 			{ AstcImageSizeType::SIZE_64_64, create2DCopyRegions(64, 64,	64, 64) },
13139 			{ AstcImageSizeType::SIZE_60_64, create2DCopyRegions(60, 64,	60, 64) },
13140 			{ AstcImageSizeType::SIZE_64_60, create2DCopyRegions(64, 60,	64, 60) },
13141 			{ AstcImageSizeType::SIZE_60_60, create2DCopyRegions(60, 60,	60, 60) },
13142 		};
13143 
13144 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13145 		{
13146 			const VkFormat*	sourceFormats		= colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
13147 			const VkFormat*	destinationFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].destinationFormats;
13148 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13149 			for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13150 			{
13151 				VkFormat srcFormat		= sourceFormats[srcFormatIndex];
13152 				params.src.image.format = srcFormat;
13153 
13154 				const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
13155 
13156 				// most of tests are using regions caluculated for 64x64 size but astc formats require custom regions
13157 				params.regions = imageRegions.at(AstcImageSizeType::SIZE_64_64);
13158 				if (isCompressedFormat(srcFormat) && isAstcFormat(mapVkCompressedFormat(srcFormat)))
13159 					params.regions = imageRegions.at(astcSizes.at(srcFormat));
13160 
13161 				// use the fact that first region contains the size of full source image
13162 				// and make source and destination the same size - this is needed for astc formats
13163 				const VkOffset3D&	srcImageSize	= params.regions[0].imageBlit.srcOffsets[1];
13164 				VkExtent3D&			srcImageExtent	= params.src.image.extent;
13165 				VkExtent3D&			dstImageExtent	= params.dst.image.extent;
13166 				srcImageExtent.width	= srcImageSize.x;
13167 				srcImageExtent.height	= srcImageSize.y;
13168 				dstImageExtent.width	= srcImageSize.x;
13169 				dstImageExtent.height	= srcImageSize.y;
13170 
13171 				BlitColorTestParams testParams
13172 				{
13173 					params,
13174 					destinationFormats,
13175 					makeFilterMask(onlyNearest, onlyNearestAndLinear)
13176 				};
13177 
13178 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
13179 				addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
13180 			}
13181 		}
13182 
13183 		group->addChild(subGroup.release());
13184 	}
13185 
13186 	// 1D tests.
13187 	{
13188 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
13189 
13190 		TestParams	params;
13191 		params.src.image.imageType	= VK_IMAGE_TYPE_1D;
13192 		params.dst.image.imageType	= VK_IMAGE_TYPE_1D;
13193 		params.src.image.extent		= default1dExtent;
13194 		params.dst.image.extent		= default1dExtent;
13195 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13196 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13197 		params.allocationKind		= allocationKind;
13198 		params.extensionUse			= extensionUse;
13199 
13200 		CopyRegion	region;
13201 		for (int i = 0; i < defaultSize; i += defaultSize / 2)
13202 		{
13203 			const VkImageBlit			imageBlit	=
13204 			{
13205 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
13206 				{
13207 					{0, 0, 0},
13208 					{defaultSize, 1, 1}
13209 				},					// VkOffset3D					srcOffsets[2];
13210 
13211 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
13212 				{
13213 					{i, 0, 0},
13214 					{i + defaultQuarterSize, 1, 1}
13215 				}					// VkOffset3D					dstOffset[2];
13216 			};
13217 			region.imageBlit	= imageBlit;
13218 			params.regions.push_back(region);
13219 		}
13220 
13221 		{
13222 			const VkImageBlit			imageBlit	=
13223 			{
13224 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
13225 				{
13226 					{0, 0, 0},
13227 					{defaultQuarterSize, 1, 1}
13228 				},					// VkOffset3D					srcOffsets[2];
13229 
13230 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
13231 				{
13232 					{defaultQuarterSize, 0, 0},
13233 					{2 * defaultQuarterSize, 1, 1}
13234 				}					// VkOffset3D					dstOffset[2];
13235 			};
13236 			region.imageBlit	= imageBlit;
13237 			params.regions.push_back(region);
13238 		}
13239 
13240 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13241 		{
13242 			const VkFormat*	sourceFormats		= colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
13243 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13244 			for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13245 			{
13246 				params.src.image.format	= sourceFormats[srcFormatIndex];
13247 				if (!isSupportedByFramework(params.src.image.format))
13248 					continue;
13249 
13250 				// Cubic filtering can only be used with 2D images.
13251 				const bool onlyNearestAndLinear	= true;
13252 
13253 				BlitColorTestParams testParams
13254 				{
13255 					params,
13256 					nullptr,
13257 					makeFilterMask(onlyNearest, onlyNearestAndLinear)
13258 				};
13259 
13260 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
13261 				addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
13262 			}
13263 		}
13264 
13265 		group->addChild(subGroup.release());
13266 	}
13267 
13268 	// 3D tests. Note we use smaller dimensions here for performance reasons.
13269 	{
13270 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
13271 
13272 		TestParams	params;
13273 		params.src.image.imageType	= VK_IMAGE_TYPE_3D;
13274 		params.dst.image.imageType	= VK_IMAGE_TYPE_3D;
13275 		params.src.image.extent		= default3dExtent;
13276 		params.dst.image.extent		= default3dExtent;
13277 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13278 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13279 		params.allocationKind		= allocationKind;
13280 		params.extensionUse			= extensionUse;
13281 
13282 		CopyRegion	region;
13283 		for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultQuarterSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
13284 		{
13285 			const VkImageBlit			imageBlit	=
13286 			{
13287 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
13288 				{
13289 					{0, 0, 0},
13290 					{defaultQuarterSize, defaultQuarterSize, defaultQuarterSize}
13291 				},					// VkOffset3D					srcOffsets[2];
13292 
13293 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
13294 				{
13295 					{i, 0, i},
13296 					{i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j}
13297 				}					// VkOffset3D					dstOffset[2];
13298 			};
13299 			region.imageBlit	= imageBlit;
13300 			params.regions.push_back(region);
13301 		}
13302 		for (int i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
13303 		{
13304 			const VkImageBlit			imageBlit	=
13305 			{
13306 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
13307 				{
13308 					{i, i, i},
13309 					{i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize}
13310 				},					// VkOffset3D					srcOffsets[2];
13311 
13312 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
13313 				{
13314 					{i, defaultQuarterSize / 2, i},
13315 					{i + defaultSixteenthSize, defaultQuarterSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize}
13316 				}					// VkOffset3D					dstOffset[2];
13317 			};
13318 			region.imageBlit	= imageBlit;
13319 			params.regions.push_back(region);
13320 		}
13321 
13322 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13323 		{
13324 			const VkFormat*	sourceFormats		= colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
13325 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13326 			for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13327 			{
13328 				params.src.image.format	= sourceFormats[srcFormatIndex];
13329 				if (!isSupportedByFramework(params.src.image.format))
13330 					continue;
13331 
13332 				// Cubic filtering can only be used with 2D images.
13333 				const bool onlyNearestAndLinear	= true;
13334 
13335 				BlitColorTestParams testParams
13336 				{
13337 					params,
13338 					nullptr,
13339 					makeFilterMask(onlyNearest, onlyNearestAndLinear)
13340 				};
13341 
13342 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
13343 				addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
13344 			}
13345 		}
13346 
13347 		group->addChild(subGroup.release());
13348 	}
13349 }
13350 
addBlittingImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)13351 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
13352 {
13353 	const VkImageLayout blitSrcLayouts[]	=
13354 	{
13355 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
13356 		VK_IMAGE_LAYOUT_GENERAL
13357 	};
13358 	const VkImageLayout blitDstLayouts[]	=
13359 	{
13360 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
13361 		VK_IMAGE_LAYOUT_GENERAL
13362 	};
13363 
13364 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
13365 	{
13366 		params.src.image.operationLayout	= blitSrcLayouts[srcLayoutNdx];
13367 
13368 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
13369 		{
13370 			params.dst.image.operationLayout	= blitDstLayouts[dstLayoutNdx];
13371 			params.filter						= VK_FILTER_NEAREST;
13372 
13373 			const std::string testName		= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
13374 											  getImageLayoutCaseName(params.dst.image.operationLayout);
13375 			const std::string description	= "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
13376 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
13377 
13378 			group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params));
13379 		}
13380 	}
13381 }
13382 
addBlittingImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13383 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13384 {
13385 	const VkFormat	depthAndStencilFormats[]	=
13386 	{
13387 		VK_FORMAT_D16_UNORM,
13388 		VK_FORMAT_X8_D24_UNORM_PACK32,
13389 		VK_FORMAT_D32_SFLOAT,
13390 		VK_FORMAT_S8_UINT,
13391 		VK_FORMAT_D16_UNORM_S8_UINT,
13392 		VK_FORMAT_D24_UNORM_S8_UINT,
13393 		VK_FORMAT_D32_SFLOAT_S8_UINT,
13394 	};
13395 
13396 	const VkImageSubresourceLayers	defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
13397 	const VkImageSubresourceLayers	defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
13398 	const VkImageSubresourceLayers	defaultDSSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
13399 
13400 	// 2D tests
13401 	{
13402 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
13403 
13404 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
13405 		{
13406 			TestParams	params;
13407 			params.src.image.imageType			= VK_IMAGE_TYPE_2D;
13408 			params.src.image.extent				= defaultExtent;
13409 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
13410 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
13411 			params.dst.image.extent				= defaultExtent;
13412 			params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
13413 			params.dst.image.format				= params.src.image.format;
13414 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
13415 			params.allocationKind				= allocationKind;
13416 			params.extensionUse					= extensionUse;
13417 			params.separateDepthStencilLayouts	= DE_FALSE;
13418 
13419 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
13420 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
13421 
13422 			CopyRegion	region;
13423 			for (int i = 0, j = 1; (i + defaultQuarterSize / j < defaultSize) && (defaultQuarterSize > j); i += defaultQuarterSize / j++)
13424 			{
13425 				const VkOffset3D	srcOffset0	= {0, 0, 0};
13426 				const VkOffset3D	srcOffset1	= {defaultSize, defaultSize, 1};
13427 				const VkOffset3D	dstOffset0	= {i, 0, 0};
13428 				const VkOffset3D	dstOffset1	= {i + defaultQuarterSize / j, defaultQuarterSize / j, 1};
13429 
13430 				if (hasDepth)
13431 				{
13432 					const VkImageBlit			imageBlit	=
13433 					{
13434 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13435 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
13436 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13437 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
13438 					};
13439 					region.imageBlit	= imageBlit;
13440 					params.regions.push_back(region);
13441 				}
13442 				if (hasStencil)
13443 				{
13444 					const VkImageBlit			imageBlit	=
13445 					{
13446 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13447 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
13448 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13449 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
13450 					};
13451 					region.imageBlit	= imageBlit;
13452 					params.regions.push_back(region);
13453 				}
13454 			}
13455 			for (int i = 0; i < defaultSize; i += defaultQuarterSize)
13456 			{
13457 				const VkOffset3D	srcOffset0	= {i, i, 0};
13458 				const VkOffset3D	srcOffset1	= {i + defaultQuarterSize, i + defaultQuarterSize, 1};
13459 				const VkOffset3D	dstOffset0	= {i, defaultSize / 2, 0};
13460 				const VkOffset3D	dstOffset1	= {i + defaultQuarterSize, defaultSize / 2 + defaultQuarterSize, 1};
13461 
13462 				if (hasDepth)
13463 				{
13464 					const VkImageBlit			imageBlit	=
13465 					{
13466 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13467 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13468 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13469 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
13470 					};
13471 					region.imageBlit	= imageBlit;
13472 					params.regions.push_back(region);
13473 				}
13474 				if (hasStencil)
13475 				{
13476 					const VkImageBlit			imageBlit	=
13477 					{
13478 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13479 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13480 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13481 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
13482 					};
13483 					region.imageBlit	= imageBlit;
13484 					params.regions.push_back(region);
13485 				}
13486 				if (hasDepth && hasStencil)
13487 				{
13488 					const VkOffset3D			dstDSOffset0	= {i, 3 * defaultQuarterSize, 0};
13489 					const VkOffset3D			dstDSOffset1	= {i + defaultQuarterSize, defaultSize, 1};
13490 					const VkImageBlit			imageBlit	=
13491 					{
13492 						defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
13493 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13494 						defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
13495 						{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
13496 					};
13497 					region.imageBlit	= imageBlit;
13498 					params.regions.push_back(region);
13499 				}
13500 			}
13501 
13502 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
13503 			const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
13504 											" to " + getFormatCaseName(params.dst.image.format);
13505 			addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13506 
13507 			if (hasDepth && hasStencil)
13508 			{
13509 				params.separateDepthStencilLayouts	= DE_TRUE;
13510 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" +
13511 												getFormatCaseName(params.dst.image.format) + "_separate_layouts";
13512 				const std::string description2	= "Blit from " + getFormatCaseName(params.src.image.format) +
13513 												" to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
13514 				addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13515 			}
13516 		}
13517 
13518 		group->addChild(subGroup.release());
13519 	}
13520 
13521 	// 1D tests
13522 	{
13523 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
13524 
13525 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
13526 		{
13527 			TestParams	params;
13528 			params.src.image.imageType			= VK_IMAGE_TYPE_1D;
13529 			params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
13530 			params.src.image.extent				= default1dExtent;
13531 			params.dst.image.extent				= default1dExtent;
13532 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
13533 			params.dst.image.format				= params.src.image.format;
13534 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
13535 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
13536 			params.allocationKind				= allocationKind;
13537 			params.extensionUse					= extensionUse;
13538 
13539 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
13540 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
13541 
13542 			CopyRegion	region;
13543 			for (int i = 0; i < defaultSize; i += defaultSize / 2)
13544 			{
13545 				const VkOffset3D	srcOffset0	= {0, 0, 0};
13546 				const VkOffset3D	srcOffset1	= {defaultSize, 1, 1};
13547 				const VkOffset3D	dstOffset0	= {i, 0, 0};
13548 				const VkOffset3D	dstOffset1	= {i + defaultQuarterSize, 1, 1};
13549 
13550 				if (hasDepth)
13551 				{
13552 					const VkImageBlit			imageBlit	=
13553 					{
13554 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13555 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
13556 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13557 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
13558 					};
13559 					region.imageBlit	= imageBlit;
13560 					params.regions.push_back(region);
13561 				}
13562 				if (hasStencil)
13563 				{
13564 					const VkImageBlit			imageBlit	=
13565 					{
13566 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13567 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
13568 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13569 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
13570 					};
13571 					region.imageBlit	= imageBlit;
13572 					params.regions.push_back(region);
13573 				}
13574 			}
13575 
13576 			{
13577 				const VkOffset3D	srcOffset0	= {0, 0, 0};
13578 				const VkOffset3D	srcOffset1	= {defaultQuarterSize, 1, 1};
13579 				const VkOffset3D	dstOffset0	= {defaultQuarterSize, 0, 0};
13580 				const VkOffset3D	dstOffset1	= {2 * defaultQuarterSize, 1, 1};
13581 
13582 				if (hasDepth)
13583 				{
13584 					const VkImageBlit			imageBlit	=
13585 					{
13586 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13587 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13588 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13589 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
13590 					};
13591 					region.imageBlit	= imageBlit;
13592 					params.regions.push_back(region);
13593 				}
13594 				if (hasStencil)
13595 				{
13596 					const VkImageBlit			imageBlit	=
13597 					{
13598 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13599 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13600 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13601 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
13602 					};
13603 					region.imageBlit	= imageBlit;
13604 					params.regions.push_back(region);
13605 				}
13606 				if (hasDepth && hasStencil)
13607 				{
13608 					const VkOffset3D			dstDSOffset0	= {3 * defaultQuarterSize, 0, 0};
13609 					const VkOffset3D			dstDSOffset1	= {3 * defaultQuarterSize + defaultQuarterSize / 2, 1, 1};
13610 					const VkImageBlit			imageBlit	=
13611 					{
13612 						defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
13613 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13614 						defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
13615 						{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
13616 					};
13617 					region.imageBlit	= imageBlit;
13618 					params.regions.push_back(region);
13619 				}
13620 			}
13621 
13622 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
13623 			const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
13624 											" to " + getFormatCaseName(params.dst.image.format);
13625 			addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13626 
13627 			if (hasDepth && hasStencil)
13628 			{
13629 				params.separateDepthStencilLayouts	= DE_TRUE;
13630 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" +
13631 												getFormatCaseName(params.dst.image.format) + "_separate_layouts";
13632 				const std::string description2	= "Blit from " + getFormatCaseName(params.src.image.format) +
13633 												" to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
13634 				addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13635 			}
13636 		}
13637 
13638 		group->addChild(subGroup.release());
13639 	}
13640 
13641 	// 3D tests. Note we use smaller dimensions here for performance reasons.
13642 	{
13643 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
13644 
13645 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
13646 		{
13647 			TestParams	params;
13648 			params.src.image.imageType			= VK_IMAGE_TYPE_3D;
13649 			params.dst.image.imageType			= VK_IMAGE_TYPE_3D;
13650 			params.src.image.extent				= default3dExtent;
13651 			params.dst.image.extent				= default3dExtent;
13652 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
13653 			params.dst.image.format				= params.src.image.format;
13654 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
13655 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
13656 			params.allocationKind				= allocationKind;
13657 			params.extensionUse					= extensionUse;
13658 
13659 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
13660 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
13661 
13662 			CopyRegion	region;
13663 			for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultQuarterSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
13664 			{
13665 				const VkOffset3D	srcOffset0	= {0, 0, 0};
13666 				const VkOffset3D	srcOffset1	= {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize};
13667 				const VkOffset3D	dstOffset0	= {i, 0, i};
13668 				const VkOffset3D	dstOffset1	= {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j};
13669 
13670 				if (hasDepth)
13671 				{
13672 					const VkImageBlit			imageBlit	=
13673 					{
13674 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13675 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
13676 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13677 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
13678 					};
13679 					region.imageBlit	= imageBlit;
13680 					params.regions.push_back(region);
13681 				}
13682 				if (hasStencil)
13683 				{
13684 					const VkImageBlit			imageBlit	=
13685 					{
13686 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13687 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
13688 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13689 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
13690 					};
13691 					region.imageBlit	= imageBlit;
13692 					params.regions.push_back(region);
13693 				}
13694 			}
13695 			for (int i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
13696 			{
13697 				const VkOffset3D	srcOffset0	= {i, i, i};
13698 				const VkOffset3D	srcOffset1	= {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize};
13699 				const VkOffset3D	dstOffset0	= {i, defaultQuarterSize / 2, i};
13700 				const VkOffset3D	dstOffset1	= {i + defaultSixteenthSize, defaultQuarterSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize};
13701 
13702 				if (hasDepth)
13703 				{
13704 					const VkImageBlit			imageBlit	=
13705 					{
13706 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13707 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13708 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13709 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
13710 					};
13711 					region.imageBlit	= imageBlit;
13712 					params.regions.push_back(region);
13713 				}
13714 				if (hasStencil)
13715 				{
13716 					const VkImageBlit			imageBlit	=
13717 					{
13718 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13719 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13720 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13721 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
13722 					};
13723 					region.imageBlit	= imageBlit;
13724 					params.regions.push_back(region);
13725 				}
13726 				if (hasDepth && hasStencil)
13727 				{
13728 					const VkOffset3D			dstDSOffset0	= {i, 3 * defaultSixteenthSize, i};
13729 					const VkOffset3D			dstDSOffset1	= {i + defaultSixteenthSize, defaultQuarterSize, i + defaultSixteenthSize};
13730 					const VkImageBlit			imageBlit	=
13731 					{
13732 						defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
13733 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13734 						defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
13735 						{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
13736 					};
13737 					region.imageBlit	= imageBlit;
13738 					params.regions.push_back(region);
13739 				}
13740 			}
13741 
13742 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
13743 			const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
13744 											" to " + getFormatCaseName(params.dst.image.format);
13745 			addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13746 
13747 			if (hasDepth && hasStencil)
13748 			{
13749 				params.separateDepthStencilLayouts	= DE_TRUE;
13750 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" +
13751 												getFormatCaseName(params.dst.image.format) + "_separate_layouts";
13752 				const std::string description2	= "Blit from " + getFormatCaseName(params.src.image.format) +
13753 												" to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
13754 				addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13755 			}
13756 		}
13757 
13758 		group->addChild(subGroup.release());
13759 	}
13760 }
13761 
addBlittingImageAllFormatsMipmapFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)13762 void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
13763 {
13764 	tcu::TestContext& testCtx				= group->getTestContext();
13765 
13766 	const VkImageLayout blitSrcLayouts[]	=
13767 	{
13768 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
13769 		VK_IMAGE_LAYOUT_GENERAL
13770 	};
13771 	const VkImageLayout blitDstLayouts[]	=
13772 	{
13773 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
13774 		VK_IMAGE_LAYOUT_GENERAL
13775 	};
13776 
13777 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
13778 	{
13779 		testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
13780 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
13781 		{
13782 			testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
13783 
13784 			testParams.params.filter			= VK_FILTER_NEAREST;
13785 			const std::string testName			= getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
13786 												  getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
13787 			const std::string description		= "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
13788 												  " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
13789 			group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params));
13790 
13791 			if (testParams.testFilters & FILTER_MASK_LINEAR)
13792 			{
13793 				testParams.params.filter = VK_FILTER_LINEAR;
13794 				group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params));
13795 			}
13796 
13797 			if (testParams.testFilters & FILTER_MASK_CUBIC)
13798 			{
13799 				testParams.params.filter = VK_FILTER_CUBIC_EXT;
13800 				group->addChild(new BlitMipmapTestCase(testCtx, testName + "_cubic", description, testParams.params));
13801 			}
13802 		}
13803 	}
13804 }
13805 
addBlittingImageAllFormatsBaseLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13806 void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13807 {
13808 	const struct
13809 	{
13810 		const VkFormat* const	compatibleFormats;
13811 		const bool				onlyNearest;
13812 	}	colorImageFormatsToTestBlit[]			=
13813 	{
13814 		{ compatibleFormatsUInts,	true	},
13815 		{ compatibleFormatsSInts,	true	},
13816 		{ compatibleFormatsFloats,	false	},
13817 		{ compatibleFormatsSrgb,	false	},
13818 	};
13819 
13820 	const int	numOfColorImageFormatsToTest	= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
13821 
13822 	const int	layerCountsToTest[]				=
13823 	{
13824 		1,
13825 		6
13826 	};
13827 
13828 	TestParams	params;
13829 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
13830 	params.src.image.extent		= defaultExtent;
13831 	params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13832 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
13833 	params.dst.image.extent		= defaultExtent;
13834 	params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13835 	params.allocationKind		= allocationKind;
13836 	params.extensionUse			= extensionUse;
13837 	params.mipLevels			= deLog2Floor32(deMaxu32(defaultExtent.width, defaultExtent.height)) + 1u;
13838 	params.singleCommand		= DE_TRUE;
13839 
13840 	CopyRegion	region;
13841 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
13842 	{
13843 		VkImageSubresourceLayers	destLayer	= defaultSourceLayer;
13844 		destLayer.mipLevel = mipLevelNdx;
13845 
13846 		const VkImageBlit			imageBlit	=
13847 		{
13848 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
13849 			{
13850 				{0, 0, 0},
13851 				{defaultSize, defaultSize, 1}
13852 			},					// VkOffset3D					srcOffsets[2];
13853 
13854 			destLayer,			// VkImageSubresourceLayers	dstSubresource;
13855 			{
13856 				{0, 0, 0},
13857 				{defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
13858 			}					// VkOffset3D					dstOffset[2];
13859 		};
13860 		region.imageBlit	= imageBlit;
13861 		params.regions.push_back(region);
13862 	}
13863 
13864 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
13865 	{
13866 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
13867 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
13868 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
13869 	}
13870 
13871 	for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
13872 	{
13873 		const int						layerCount		= layerCountsToTest[layerCountIndex];
13874 		const std::string				layerGroupName	= "layercount_" + de::toString(layerCount);
13875 		const std::string				layerGroupDesc	= "Blit mipmaps with layerCount = " + de::toString(layerCount);
13876 
13877 		de::MovePtr<tcu::TestCaseGroup>	layerCountGroup	(new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
13878 
13879 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13880 		{
13881 			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
13882 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13883 
13884 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13885 			{
13886 				params.src.image.format	= compatibleFormats[srcFormatIndex];
13887 				params.dst.image.format	= compatibleFormats[srcFormatIndex];
13888 
13889 				if (!isSupportedByFramework(params.src.image.format))
13890 					continue;
13891 
13892 				const bool onlyNearestAndLinear	= de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
13893 
13894 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
13895 
13896 				BlitColorTestParams testParams;
13897 				testParams.params				= params;
13898 				testParams.compatibleFormats	= compatibleFormats;
13899 				testParams.testFilters			= makeFilterMask(onlyNearest, onlyNearestAndLinear);
13900 
13901 				testParams.params.src.image.extent.depth = layerCount;
13902 				testParams.params.dst.image.extent.depth = layerCount;
13903 
13904 				for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
13905 				{
13906 					testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
13907 					testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
13908 				}
13909 
13910 				addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
13911 			}
13912 		}
13913 		group->addChild(layerCountGroup.release());
13914 	}
13915 }
13916 
addBlittingImageAllFormatsPreviousLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13917 void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13918 {
13919 	const struct
13920 	{
13921 		const VkFormat* const	compatibleFormats;
13922 		const bool				onlyNearest;
13923 	}	colorImageFormatsToTestBlit[]			=
13924 	{
13925 		{ compatibleFormatsUInts,	true	},
13926 		{ compatibleFormatsSInts,	true	},
13927 		{ compatibleFormatsFloats,	false	},
13928 		{ compatibleFormatsSrgb,	false	},
13929 	};
13930 
13931 	const int	numOfColorImageFormatsToTest	= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
13932 
13933 	const int	layerCountsToTest[]				=
13934 	{
13935 		1,
13936 		6
13937 	};
13938 
13939 	TestParams	params;
13940 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
13941 	params.src.image.extent		= defaultExtent;
13942 	params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13943 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
13944 	params.dst.image.extent		= defaultExtent;
13945 	params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13946 	params.allocationKind		= allocationKind;
13947 	params.extensionUse			= extensionUse;
13948 	params.mipLevels			= deLog2Floor32(deMaxu32(defaultExtent.width, defaultExtent.height)) + 1u;
13949 	params.singleCommand		= DE_FALSE;
13950 
13951 	CopyRegion	region;
13952 	for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
13953 	{
13954 		VkImageSubresourceLayers	srcLayer	= defaultSourceLayer;
13955 		VkImageSubresourceLayers	destLayer	= defaultSourceLayer;
13956 
13957 		srcLayer.mipLevel	= mipLevelNdx - 1u;
13958 		destLayer.mipLevel	= mipLevelNdx;
13959 
13960 		const VkImageBlit			imageBlit	=
13961 		{
13962 			srcLayer,			// VkImageSubresourceLayers	srcSubresource;
13963 			{
13964 				{0, 0, 0},
13965 				{defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}
13966 			},					// VkOffset3D					srcOffsets[2];
13967 
13968 			destLayer,			// VkImageSubresourceLayers	dstSubresource;
13969 			{
13970 				{0, 0, 0},
13971 				{defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
13972 			}					// VkOffset3D					dstOffset[2];
13973 		};
13974 		region.imageBlit	= imageBlit;
13975 		params.regions.push_back(region);
13976 	}
13977 
13978 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
13979 	{
13980 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
13981 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
13982 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
13983 	}
13984 
13985 	for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
13986 	{
13987 		const int						layerCount		= layerCountsToTest[layerCountIndex];
13988 		const std::string				layerGroupName	= "layercount_" + de::toString(layerCount);
13989 		const std::string				layerGroupDesc	= "Blit mipmaps with layerCount = " + de::toString(layerCount);
13990 
13991 		de::MovePtr<tcu::TestCaseGroup>	layerCountGroup	(new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
13992 
13993 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13994 		{
13995 			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
13996 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13997 
13998 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13999 			{
14000 				params.src.image.format						= compatibleFormats[srcFormatIndex];
14001 				params.dst.image.format						= compatibleFormats[srcFormatIndex];
14002 
14003 				if (!isSupportedByFramework(params.src.image.format))
14004 					continue;
14005 
14006 				const bool			onlyNearestAndLinear	= de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
14007 
14008 				const std::string	description				= "Blit source format " + getFormatCaseName(params.src.image.format);
14009 
14010 				BlitColorTestParams	testParams;
14011 				testParams.params							= params;
14012 				testParams.compatibleFormats				= compatibleFormats;
14013 				testParams.testFilters						= makeFilterMask(onlyNearest, onlyNearestAndLinear);
14014 
14015 				testParams.params.src.image.extent.depth	= layerCount;
14016 				testParams.params.dst.image.extent.depth	= layerCount;
14017 
14018 				for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
14019 				{
14020 					testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
14021 					testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
14022 				}
14023 
14024 				addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
14025 			}
14026 		}
14027 		group->addChild(layerCountGroup.release());
14028 	}
14029 
14030 	for (int multiLayer = 0; multiLayer < 2; multiLayer++)
14031 	{
14032 		const int layerCount = multiLayer ? 6 : 1;
14033 
14034 		for (int barrierCount = 1; barrierCount < 4; barrierCount++)
14035 		{
14036 			if (layerCount != 1 || barrierCount != 1)
14037 			{
14038 				const std::string				barrierGroupName = (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
14039 				const std::string				barrierGroupDesc = "Use " + de::toString(barrierCount) + " image barriers";
14040 
14041 				de::MovePtr<tcu::TestCaseGroup>	barrierCountGroup(new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str(), barrierGroupDesc.c_str()));
14042 
14043 				params.barrierCount = barrierCount;
14044 
14045 				// Only go through a few common formats
14046 				for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
14047 				{
14048 					params.src.image.format						= compatibleFormatsUInts[srcFormatIndex];
14049 					params.dst.image.format						= compatibleFormatsUInts[srcFormatIndex];
14050 
14051 					if (!isSupportedByFramework(params.src.image.format))
14052 						continue;
14053 
14054 					const std::string description				= "Blit source format " + getFormatCaseName(params.src.image.format);
14055 
14056 					BlitColorTestParams testParams;
14057 					testParams.params							= params;
14058 					testParams.compatibleFormats				= compatibleFormatsUInts;
14059 					testParams.testFilters						= FILTER_MASK_NEAREST;
14060 
14061 					testParams.params.src.image.extent.depth	= layerCount;
14062 					testParams.params.dst.image.extent.depth	= layerCount;
14063 
14064 					for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
14065 					{
14066 						testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
14067 						testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
14068 					}
14069 
14070 					addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
14071 				}
14072 				group->addChild(barrierCountGroup.release());
14073 			}
14074 		}
14075 	}
14076 }
14077 
addBlittingImageAllFormatsMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14078 void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14079 {
14080 	addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind, extensionUse);
14081 	addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind, extensionUse);
14082 }
14083 
addBlittingImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14084 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14085 {
14086 	addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind, extensionUse);
14087 	addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
14088 	addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind, extensionUse);
14089 }
14090 
addBlittingImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14091 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14092 {
14093 	addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind, extensionUse);
14094 	addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind, extensionUse);
14095 }
14096 
14097 const VkSampleCountFlagBits	samples[]		=
14098 {
14099 	VK_SAMPLE_COUNT_2_BIT,
14100 	VK_SAMPLE_COUNT_4_BIT,
14101 	VK_SAMPLE_COUNT_8_BIT,
14102 	VK_SAMPLE_COUNT_16_BIT,
14103 	VK_SAMPLE_COUNT_32_BIT,
14104 	VK_SAMPLE_COUNT_64_BIT
14105 };
14106 const VkExtent3D			resolveExtent	= {256u, 256u, 1};
14107 
addResolveImageWholeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14108 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14109 {
14110 	TestParams	params;
14111 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14112 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14113 	params.src.image.extent				= resolveExtent;
14114 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14115 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14116 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14117 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14118 	params.dst.image.extent				= resolveExtent;
14119 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14120 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14121 	params.allocationKind				= allocationKind;
14122 	params.extensionUse					= extensionUse;
14123 
14124 	{
14125 		const VkImageSubresourceLayers	sourceLayer	=
14126 		{
14127 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14128 			0u,							// deUint32				mipLevel;
14129 			0u,							// deUint32				baseArrayLayer;
14130 			1u							// deUint32				layerCount;
14131 		};
14132 		const VkImageResolve			testResolve	=
14133 		{
14134 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
14135 			{0, 0, 0},		// VkOffset3D				srcOffset;
14136 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
14137 			{0, 0, 0},		// VkOffset3D				dstOffset;
14138 			resolveExtent,	// VkExtent3D				extent;
14139 		};
14140 
14141 		CopyRegion	imageResolve;
14142 		imageResolve.imageResolve	= testResolve;
14143 		params.regions.push_back(imageResolve);
14144 	}
14145 
14146 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14147 	{
14148 		params.imageOffset = false;
14149 		params.samples					= samples[samplesIndex];
14150 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14151 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
14152 		params.imageOffset = true;
14153 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14154 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params));
14155 		}
14156 	}
14157 }
14158 
addResolveImagePartialTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14159 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14160 {
14161 	TestParams	params;
14162 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14163 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14164 	params.src.image.extent				= resolveExtent;
14165 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14166 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14167 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14168 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14169 	params.dst.image.extent				= resolveExtent;
14170 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14171 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14172 	params.allocationKind				= allocationKind;
14173 	params.extensionUse					= extensionUse;
14174 
14175 	{
14176 		const VkImageSubresourceLayers	sourceLayer	=
14177 		{
14178 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14179 			0u,							// deUint32				mipLevel;
14180 			0u,							// deUint32				baseArrayLayer;
14181 			1u							// deUint32				layerCount;
14182 		};
14183 		const VkImageResolve			testResolve	=
14184 		{
14185 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
14186 			{0, 0, 0},		// VkOffset3D				srcOffset;
14187 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
14188 			{64u, 64u, 0},		// VkOffset3D				dstOffset;
14189 			{128u, 128u, 1u},	// VkExtent3D				extent;
14190 		};
14191 
14192 		CopyRegion	imageResolve;
14193 		imageResolve.imageResolve = testResolve;
14194 		params.regions.push_back(imageResolve);
14195 	}
14196 
14197 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14198 	{
14199 		params.samples					= samples[samplesIndex];
14200 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14201 		params.imageOffset = false;
14202 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
14203 		params.imageOffset = true;
14204 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14205 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params));
14206 		}
14207 	}
14208 }
14209 
addResolveImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14210 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14211 {
14212 	TestParams	params;
14213 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14214 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14215 	params.src.image.extent				= resolveExtent;
14216 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14217 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14218 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14219 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14220 	params.dst.image.extent				= resolveExtent;
14221 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14222 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14223 	params.allocationKind				= allocationKind;
14224 	params.extensionUse					= extensionUse;
14225 	params.imageOffset					= allocationKind != ALLOCATION_KIND_DEDICATED;
14226 
14227 	{
14228 		const VkImageSubresourceLayers	sourceLayer	=
14229 		{
14230 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14231 			0u,							// deUint32				mipLevel;
14232 			0u,							// deUint32				baseArrayLayer;
14233 			1u							// deUint32				layerCount;
14234 		};
14235 
14236 		for (int i = 0; i < 256; i += 64)
14237 		{
14238 			const VkImageResolve			testResolve	=
14239 			{
14240 				sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
14241 				{i, i, 0},		// VkOffset3D				srcOffset;
14242 				sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
14243 				{i, 0, 0},		// VkOffset3D				dstOffset;
14244 				{64u, 64u, 1u},	// VkExtent3D				extent;
14245 			};
14246 
14247 			CopyRegion	imageResolve;
14248 			imageResolve.imageResolve = testResolve;
14249 			params.regions.push_back(imageResolve);
14250 		}
14251 	}
14252 
14253 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14254 	{
14255 		params.samples					= samples[samplesIndex];
14256 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14257 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
14258 	}
14259 }
14260 
addResolveImageWholeCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14261 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14262 {
14263 	TestParams	params;
14264 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14265 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14266 	params.src.image.extent				= defaultExtent;
14267 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14268 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14269 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14270 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14271 	params.dst.image.extent				= defaultExtent;
14272 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14273 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14274 	params.allocationKind				= allocationKind;
14275 	params.extensionUse					= extensionUse;
14276 
14277 	{
14278 		const VkImageSubresourceLayers	sourceLayer	=
14279 		{
14280 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14281 			0u,							// deUint32				mipLevel;
14282 			0u,							// deUint32				baseArrayLayer;
14283 			1u							// deUint32				layerCount;
14284 		};
14285 
14286 		const VkImageResolve			testResolve	=
14287 		{
14288 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14289 			{0, 0, 0},			// VkOffset3D				srcOffset;
14290 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14291 			{0, 0, 0},			// VkOffset3D				dstOffset;
14292 			defaultExtent,		// VkExtent3D				extent;
14293 		};
14294 
14295 		CopyRegion	imageResolve;
14296 		imageResolve.imageResolve	= testResolve;
14297 		params.regions.push_back(imageResolve);
14298 	}
14299 
14300 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14301 	{
14302 		params.samples					= samples[samplesIndex];
14303 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14304 		params.imageOffset = false;
14305 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14306 		params.imageOffset = true;
14307 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14308 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14309 		}
14310 	}
14311 }
14312 
addComputeAndTransferQueueTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14313 void addComputeAndTransferQueueTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14314 {
14315 	de::MovePtr<tcu::TestCaseGroup>		computeGroup	(new tcu::TestCaseGroup(group->getTestContext(), "whole_copy_before_resolving_compute", "Resolve from image to image using compute queue (whole copy before resolving)"));
14316 	de::MovePtr<tcu::TestCaseGroup>		transferGroup	(new tcu::TestCaseGroup(group->getTestContext(), "whole_copy_before_resolving_transfer", "Resolve from image to image using compute queue (whole copy before resolving)"));
14317 
14318 	TestParams	params;
14319 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14320 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14321 	params.src.image.extent				= defaultExtent;
14322 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14323 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14324 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14325 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14326 	params.dst.image.extent				= defaultExtent;
14327 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14328 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14329 	params.allocationKind				= allocationKind;
14330 	params.extensionUse					= extensionUse;
14331 
14332 	{
14333 		const VkImageSubresourceLayers	sourceLayer	=
14334 		{
14335 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14336 			0u,							// deUint32				mipLevel;
14337 			0u,							// deUint32				baseArrayLayer;
14338 			1u							// deUint32				layerCount;
14339 		};
14340 
14341 		const VkImageResolve			testResolve	=
14342 		{
14343 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14344 			{0, 0, 0},			// VkOffset3D				srcOffset;
14345 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14346 			{0, 0, 0},			// VkOffset3D				dstOffset;
14347 			defaultExtent,		// VkExtent3D				extent;
14348 		};
14349 
14350 		CopyRegion	imageResolve;
14351 		imageResolve.imageResolve	= testResolve;
14352 		params.regions.push_back(imageResolve);
14353 	}
14354 
14355 	for (const auto& sample : samples)
14356 	{
14357 		params.samples					= sample;
14358 		const std::string description	= "With " + getSampleCountCaseName(sample);
14359 		computeGroup->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(sample), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE));
14360 		transferGroup->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(sample), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER));
14361 	}
14362 
14363 	group->addChild(computeGroup.release());
14364 	group->addChild(transferGroup.release());
14365 }
14366 
addResolveImageWholeCopyWithoutCabBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14367 void addResolveImageWholeCopyWithoutCabBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14368 {
14369 	TestParams	params;
14370 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14371 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14372 	params.src.image.extent				= defaultExtent;
14373 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14374 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14375 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14376 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14377 	params.dst.image.extent				= defaultExtent;
14378 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14379 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14380 	params.allocationKind				= allocationKind;
14381 	params.extensionUse					= extensionUse;
14382 
14383 	{
14384 		const VkImageSubresourceLayers	sourceLayer	=
14385 		{
14386 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14387 			0u,							// deUint32				mipLevel;
14388 			0u,							// deUint32				baseArrayLayer;
14389 			1u							// deUint32				layerCount;
14390 		};
14391 
14392 		const VkImageResolve			testResolve	=
14393 		{
14394 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14395 			{0, 0, 0},			// VkOffset3D				srcOffset;
14396 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14397 			{0, 0, 0},			// VkOffset3D				dstOffset;
14398 			defaultExtent,		// VkExtent3D				extent;
14399 		};
14400 
14401 		CopyRegion	imageResolve;
14402 		imageResolve.imageResolve	= testResolve;
14403 		params.regions.push_back(imageResolve);
14404 	}
14405 
14406 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14407 	{
14408 		params.samples					= samples[samplesIndex];
14409 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14410 		params.imageOffset = false;
14411 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
14412 		params.imageOffset = true;
14413 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14414 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
14415 		}
14416 	}
14417 }
14418 
addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14419 void addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14420 {
14421 	TestParams	params;
14422 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14423 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14424 	params.src.image.extent				= defaultExtent;
14425 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14426 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14427 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14428 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14429 	params.dst.image.extent				= defaultExtent;
14430 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14431 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14432 	params.allocationKind				= allocationKind;
14433 	params.extensionUse					= extensionUse;
14434 
14435 	{
14436 		const VkImageSubresourceLayers	sourceLayer	=
14437 		{
14438 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14439 			0u,							// deUint32				mipLevel;
14440 			0u,							// deUint32				baseArrayLayer;
14441 			1u							// deUint32				layerCount;
14442 		};
14443 
14444 		const VkImageResolve			testResolve	=
14445 		{
14446 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14447 			{0, 0, 0},			// VkOffset3D				srcOffset;
14448 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14449 			{0, 0, 0},			// VkOffset3D				dstOffset;
14450 			defaultExtent,		// VkExtent3D				extent;
14451 		};
14452 
14453 		CopyRegion	imageResolve;
14454 		imageResolve.imageResolve	= testResolve;
14455 		params.regions.push_back(imageResolve);
14456 	}
14457 
14458 	const struct
14459 	{
14460 		VkImageLayout	layout;
14461 		std::string		name;
14462 	}	imageLayouts[]			=
14463 	{
14464 		{ VK_IMAGE_LAYOUT_GENERAL,					"general"							},
14465 		{ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		"transfer_src_optimal"				},
14466 		{ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		"transfer_dst_optimal"				}
14467 	};
14468 
14469 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14470 	for (int srcLayoutIndex = 0; srcLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++srcLayoutIndex)
14471 	for (int dstLayoutIndex = 0; dstLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++dstLayoutIndex)
14472 	{
14473 		params.src.image.operationLayout	= imageLayouts[srcLayoutIndex].layout;
14474 		params.dst.image.operationLayout	= imageLayouts[dstLayoutIndex].layout;
14475 		if (params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
14476 			params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
14477 			continue;
14478 		params.samples						= samples[samplesIndex];
14479 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14480 		std::string testName = getSampleCountCaseName(samples[samplesIndex]) + "_" + imageLayouts[srcLayoutIndex].name + "_" + imageLayouts[dstLayoutIndex].name;
14481 		params.imageOffset = false;
14482 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName, description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14483 		params.imageOffset = true;
14484 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14485 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14486 		}
14487 	}
14488 }
14489 
addResolveImageLayerCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14490 void addResolveImageLayerCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14491 {
14492 	TestParams	params;
14493 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14494 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14495 	params.src.image.extent				= defaultExtent;
14496 	params.src.image.extent.depth		= 5u;
14497 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14498 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14499 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14500 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14501 	params.dst.image.extent				= defaultExtent;
14502 	params.dst.image.extent.depth		= 5u;
14503 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14504 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14505 	params.allocationKind				= allocationKind;
14506 	params.extensionUse					= extensionUse;
14507 
14508 	for (deUint32 layerNdx=0; layerNdx < params.src.image.extent.depth; ++layerNdx)
14509 	{
14510 		const VkImageSubresourceLayers	sourceLayer	=
14511 		{
14512 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
14513 			0u,								// deUint32				mipLevel;
14514 			layerNdx,						// deUint32				baseArrayLayer;
14515 			1u								// deUint32				layerCount;
14516 		};
14517 
14518 		const VkImageResolve			testResolve	=
14519 		{
14520 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14521 			{0, 0, 0},			// VkOffset3D				srcOffset;
14522 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14523 			{0, 0, 0},			// VkOffset3D				dstOffset;
14524 			defaultExtent,		// VkExtent3D				extent;
14525 		};
14526 
14527 		CopyRegion	imageResolve;
14528 		imageResolve.imageResolve	= testResolve;
14529 		params.regions.push_back(imageResolve);
14530 	}
14531 
14532 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14533 	{
14534 		params.samples					= samples[samplesIndex];
14535 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14536 		params.imageOffset = false;
14537 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
14538 		params.imageOffset = true;
14539 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14540 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
14541 		}
14542 	}
14543 }
14544 
addResolveCopyImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14545 void addResolveCopyImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14546 {
14547 	TestParams	params;
14548 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14549 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14550 	params.src.image.extent				= resolveExtent;
14551 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14552 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14553 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14554 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14555 	params.dst.image.extent				= resolveExtent;
14556 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14557 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14558 	params.allocationKind				= allocationKind;
14559 	params.extensionUse					= extensionUse;
14560 
14561 	int32_t		imageHalfWidth	= getExtent3D(params.src.image).width / 2;
14562 	int32_t		imageHalfHeight	= getExtent3D(params.src.image).height / 2;
14563 	VkExtent3D	halfImageExtent	= {resolveExtent.width / 2, resolveExtent.height / 2, 1u};
14564 
14565 	// Lower right corner to lower left corner.
14566 	{
14567 		const VkImageSubresourceLayers	sourceLayer	=
14568 		{
14569 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
14570 			0u,								// deUint32				mipLevel;
14571 			0u,								// deUint32				baseArrayLayer;
14572 			1u								// deUint32				layerCount;
14573 		};
14574 
14575 		const VkImageResolve			testResolve	=
14576 		{
14577 			sourceLayer,							// VkImageSubresourceLayers	srcSubresource;
14578 			{imageHalfWidth, imageHalfHeight, 0},	// VkOffset3D				srcOffset;
14579 			sourceLayer,							// VkImageSubresourceLayers	dstSubresource;
14580 			{0, imageHalfHeight, 0},				// VkOffset3D				dstOffset;
14581 			halfImageExtent,									// VkExtent3D				extent;
14582 		};
14583 
14584 		CopyRegion	imageResolve;
14585 		imageResolve.imageResolve	= testResolve;
14586 		params.regions.push_back(imageResolve);
14587 	}
14588 
14589 	// Upper right corner to lower right corner.
14590 	{
14591 		const VkImageSubresourceLayers	sourceLayer	=
14592 		{
14593 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
14594 			0u,								// deUint32				mipLevel;
14595 			0u,								// deUint32				baseArrayLayer;
14596 			1u								// deUint32				layerCount;
14597 		};
14598 
14599 		const VkImageResolve			testResolve	=
14600 		{
14601 			sourceLayer,							// VkImageSubresourceLayers	srcSubresource;
14602 			{imageHalfWidth, 0, 0},					// VkOffset3D				srcOffset;
14603 			sourceLayer,							// VkImageSubresourceLayers	dstSubresource;
14604 			{imageHalfWidth, imageHalfHeight, 0},	// VkOffset3D				dstOffset;
14605 			halfImageExtent,									// VkExtent3D				extent;
14606 		};
14607 
14608 		CopyRegion	imageResolve;
14609 		imageResolve.imageResolve	= testResolve;
14610 		params.regions.push_back(imageResolve);
14611 	}
14612 
14613 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14614 	{
14615 		params.samples					= samples[samplesIndex];
14616 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14617 		params.imageOffset = false;
14618 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
14619 		params.imageOffset = true;
14620 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14621 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
14622 		}
14623 	}
14624 }
14625 
addResolveImageWholeArrayImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14626 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14627 {
14628 	TestParams	params;
14629 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14630 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14631 	params.src.image.extent				= defaultExtent;
14632 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14633 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14634 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14635 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14636 	params.dst.image.extent				= defaultExtent;
14637 	params.dst.image.extent.depth		= 5u;
14638 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14639 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14640 	params.allocationKind				= allocationKind;
14641 	params.extensionUse					= extensionUse;
14642 
14643 	for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
14644 	{
14645 		const VkImageSubresourceLayers	sourceLayer	=
14646 		{
14647 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
14648 			0u,								// deUint32				mipLevel;
14649 			layerNdx,						// deUint32				baseArrayLayer;
14650 			1u								// deUint32				layerCount;
14651 		};
14652 
14653 		const VkImageResolve			testResolve	=
14654 		{
14655 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14656 			{0, 0, 0},			// VkOffset3D				srcOffset;
14657 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14658 			{0, 0, 0},			// VkOffset3D				dstOffset;
14659 			defaultExtent,		// VkExtent3D				extent;
14660 		};
14661 
14662 		CopyRegion	imageResolve;
14663 		imageResolve.imageResolve	= testResolve;
14664 		params.regions.push_back(imageResolve);
14665 	}
14666 
14667 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14668 	{
14669 		params.samples					= samples[samplesIndex];
14670 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14671 		params.imageOffset = false;
14672 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14673 		params.imageOffset = true;
14674 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14675 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14676 		}
14677 	}
14678 }
14679 
addResolveImageWholeArrayImageSingleRegionTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14680 void addResolveImageWholeArrayImageSingleRegionTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14681 {
14682 	TestParams	params;
14683 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14684 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14685 	params.src.image.extent				= defaultExtent;
14686 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14687 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14688 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14689 	params.dst.image.extent				= defaultExtent;
14690 	params.dst.image.extent.depth		= 5u;
14691 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14692 	params.allocationKind				= allocationKind;
14693 	params.extensionUse					= extensionUse;
14694 
14695 	const VkImageSubresourceLayers	sourceLayer	=
14696 	{
14697 		VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
14698 		0u,								// uint32_t				mipLevel;
14699 		0,						// uint32_t				baseArrayLayer;
14700 		params.dst.image.extent.depth			// uint32_t				layerCount;
14701 	};
14702 
14703 	const VkImageResolve			testResolve	=
14704 	{
14705 		sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14706 		{0, 0, 0},			// VkOffset3D				srcOffset;
14707 		sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14708 		{0, 0, 0},			// VkOffset3D				dstOffset;
14709 		defaultExtent,		// VkExtent3D				extent;
14710 	};
14711 
14712 	CopyRegion	imageResolve;
14713 	imageResolve.imageResolve	= testResolve;
14714 	params.regions.push_back(imageResolve);
14715 
14716 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14717 	{
14718 		params.samples					= samples[samplesIndex];
14719 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14720 		params.imageOffset = false;
14721 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14722 		params.imageOffset = true;
14723 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14724 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14725 		}
14726 	}
14727 }
14728 
addResolveImageDiffImageSizeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14729 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14730 {
14731 	tcu::TestContext&	testCtx			= group->getTestContext();
14732 	TestParams			params;
14733 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14734 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14735 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14736 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14737 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14738 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14739 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14740 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14741 	params.allocationKind				= allocationKind;
14742 	params.extensionUse					= extensionUse;
14743 
14744 	{
14745 		const VkImageSubresourceLayers	sourceLayer	=
14746 		{
14747 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14748 			0u,							// deUint32				mipLevel;
14749 			0u,							// deUint32				baseArrayLayer;
14750 			1u							// deUint32				layerCount;
14751 		};
14752 		const VkImageResolve			testResolve	=
14753 		{
14754 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
14755 			{0, 0, 0},		// VkOffset3D				srcOffset;
14756 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
14757 			{0, 0, 0},		// VkOffset3D				dstOffset;
14758 			resolveExtent,	// VkExtent3D				extent;
14759 		};
14760 		CopyRegion	imageResolve;
14761 		imageResolve.imageResolve	= testResolve;
14762 		params.regions.push_back(imageResolve);
14763 	}
14764 
14765 	const VkExtent3D imageExtents[]		=
14766 	{
14767 		{ resolveExtent.width + 10,	resolveExtent.height,		resolveExtent.depth },
14768 		{ resolveExtent.width,		resolveExtent.height * 2,	resolveExtent.depth },
14769 		{ resolveExtent.width,		resolveExtent.height,		resolveExtent.depth + 10 }
14770 	};
14771 
14772 	for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
14773 	{
14774 		const VkExtent3D&	srcImageSize	= imageExtents[srcImageExtentIndex];
14775 		params.src.image.extent				= srcImageSize;
14776 		params.dst.image.extent				= resolveExtent;
14777 		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14778 		{
14779 			params.samples	= samples[samplesIndex];
14780 			std::ostringstream testName;
14781 			testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
14782 			std::ostringstream description;
14783 			description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
14784 						<< srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
14785 			group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
14786 		}
14787 	}
14788 	for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
14789 	{
14790 		const VkExtent3D&	dstImageSize	= imageExtents[dstImageExtentIndex];
14791 		params.src.image.extent				= resolveExtent;
14792 		params.dst.image.extent				= dstImageSize;
14793 		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14794 		{
14795 			params.samples	= samples[samplesIndex];
14796 			std::ostringstream testName;
14797 			testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
14798 			std::ostringstream description;
14799 			description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
14800 						<< dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
14801 			params.imageOffset = false;
14802 			group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
14803 			params.imageOffset = true;
14804 			if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14805 				group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str() + "_bind_offset", description.str(), params));
14806 			}
14807 		}
14808 	}
14809 }
14810 
addDepthStencilCopyMSAATest(tcu::TestCaseGroup * group,DepthStencilMSAA::TestParameters testCreateParams)14811 void addDepthStencilCopyMSAATest (tcu::TestCaseGroup* group, DepthStencilMSAA::TestParameters testCreateParams)
14812 {
14813 	// Run all the tests with one of the bare depth format and one bare stencil format + mandatory combined formats.
14814 	const struct
14815 	{
14816 		const std::string	name;
14817 		const VkFormat		vkFormat;
14818 	} depthAndStencilFormats[] =
14819 	{
14820 		{ "d32_sfloat",				VK_FORMAT_D32_SFLOAT		},
14821 		{ "s8_uint",				VK_FORMAT_S8_UINT			},
14822 		{ "d16_unorm_s8_uint",		VK_FORMAT_D16_UNORM_S8_UINT	},
14823 		{ "d24_unorm_s8_uint",		VK_FORMAT_D24_UNORM_S8_UINT	},
14824 	};
14825 
14826 	// Both image layouts will be tested only with full image copy tests to limit the number of tests.
14827 	const VkImageLayout srcImageLayouts[] =
14828 	{
14829 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
14830 		VK_IMAGE_LAYOUT_GENERAL
14831 	};
14832 	const VkImageLayout dstImageLayouts[] =
14833 	{
14834 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
14835 		VK_IMAGE_LAYOUT_GENERAL
14836 	};
14837 
14838 	for (const auto &srcLayout : srcImageLayouts)
14839 	{
14840 		for (const auto &dstLayout : dstImageLayouts)
14841 		{
14842 			testCreateParams.srcImageLayout = srcLayout;
14843 			testCreateParams.dstImageLayout = dstLayout;
14844 			for (const auto &format : depthAndStencilFormats)
14845 			{
14846 				testCreateParams.imageFormat	= format.vkFormat;
14847 				const auto textureFormat		= mapVkFormat(format.vkFormat);
14848 				bool hasDepth					= tcu::hasDepthComponent(textureFormat.order);
14849 				bool hasStencil					= tcu::hasStencilComponent(textureFormat.order);
14850 				std::string testNameBase		= format.name + "_" + (testCreateParams.copyOptions == DepthStencilMSAA::COPY_WHOLE_IMAGE ? getImageLayoutCaseName(srcLayout) + "_" + getImageLayoutCaseName(dstLayout) + "_": "");
14851 
14852 				if (hasDepth)
14853 				{
14854 					testCreateParams.copyAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
14855 					for (auto sample : samples)
14856 					{
14857 						testCreateParams.samples = sample;
14858 						std::string description = "Copy depth component with sample count: " + getSampleCountCaseName(sample);
14859 						testCreateParams.imageOffset = false;
14860 						group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "D_" + getSampleCountCaseName(sample), description, testCreateParams));
14861 						testCreateParams.imageOffset = true;
14862 						if (testCreateParams.allocationKind != ALLOCATION_KIND_DEDICATED) {
14863 							group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "D_" + getSampleCountCaseName(sample) + "_bind_offset", description, testCreateParams));
14864 						}
14865 					}
14866 				}
14867 
14868 				if (hasStencil)
14869 				{
14870 					testCreateParams.copyAspect = VK_IMAGE_ASPECT_STENCIL_BIT;
14871 					for (auto sample : samples)
14872 					{
14873 						testCreateParams.samples = sample;
14874 						std::string description = "Copy stencil component with sample count: " + getSampleCountCaseName(sample);
14875 						testCreateParams.imageOffset = false;
14876 						group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "S_" + getSampleCountCaseName(sample), description, testCreateParams));
14877 						testCreateParams.imageOffset = true;
14878 						if (testCreateParams.allocationKind != ALLOCATION_KIND_DEDICATED) {
14879 							group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "S_" + getSampleCountCaseName(sample) + "_bind_offset", description, testCreateParams));
14880 						}
14881 					}
14882 				}
14883 			}
14884 			if (testCreateParams.copyOptions != DepthStencilMSAA::COPY_WHOLE_IMAGE)
14885 				break;
14886 		}
14887 		if (testCreateParams.copyOptions != DepthStencilMSAA::COPY_WHOLE_IMAGE)
14888 			break;
14889 	}
14890 }
14891 
addDepthStencilCopyMSAATestGroup(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14892 void addDepthStencilCopyMSAATestGroup (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14893 {
14894 	// Allocation kind, extension use copy option parameters are defined here. Rest of the parameters are defined in `addDepthStencilCopyMSAATest` function.
14895 	DepthStencilMSAA::TestParameters testParams = {};
14896 	testParams.allocationKind	= allocationKind;
14897 	testParams.extensionUse		= extensionUse;
14898 
14899 	testParams.copyOptions = DepthStencilMSAA::COPY_WHOLE_IMAGE;
14900 	addTestGroup(group, "whole", "Copy from depth stencil to depth stencil with multi sample tests", addDepthStencilCopyMSAATest, testParams);
14901 
14902 	testParams.copyOptions = DepthStencilMSAA::COPY_PARTIAL;
14903 	addTestGroup(group, "partial", "Copy from depth stencil to depth stencil with multi sample tests", addDepthStencilCopyMSAATest, testParams);
14904 
14905 	testParams.copyOptions = DepthStencilMSAA::COPY_ARRAY_TO_ARRAY;
14906 	addTestGroup(group, "array_to_array", "Copy from array layer to array layer", addDepthStencilCopyMSAATest, testParams);
14907 }
14908 
addBufferCopyOffsetTests(tcu::TestCaseGroup * group)14909 void addBufferCopyOffsetTests (tcu::TestCaseGroup* group)
14910 {
14911 	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"));
14912 
14913 	for (deUint32 srcOffset = 0u; srcOffset < BufferOffsetParams::kMaxOffset; ++srcOffset)
14914 	for (deUint32 dstOffset = 0u; dstOffset < BufferOffsetParams::kMaxOffset; ++dstOffset)
14915 	{
14916 		BufferOffsetParams params{srcOffset, dstOffset};
14917 		addFunctionCase(subGroup.get(), de::toString(srcOffset) + "_" + de::toString(dstOffset), "", bufferOffsetTest, params);
14918 	}
14919 
14920 	group->addChild(subGroup.release());
14921 }
14922 
addResolveImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14923 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14924 {
14925 	addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind, extensionUse);
14926 	addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind, extensionUse);
14927 	addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind, extensionUse);
14928 	addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind, extensionUse);
14929 	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);
14930 	addComputeAndTransferQueueTests(group, allocationKind, extensionUse);
14931 	addTestGroup(group, "diff_layout_copy_before_resolving", "Resolve from image to image (whole copy before resolving with different layouts)", addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests, allocationKind, extensionUse);
14932 	addTestGroup(group, "layer_copy_before_resolving", "Resolve from image to image (layer copy before resolving)", addResolveImageLayerCopyBeforeResolvingTests, allocationKind, extensionUse);
14933 	addTestGroup(group, "copy_with_regions_before_resolving", "Resolve from image to image (region copy before resolving)", addResolveCopyImageWithRegionsTests, allocationKind, extensionUse);
14934 	addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind, extensionUse);
14935 	addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind, extensionUse);
14936 	addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind, extensionUse);
14937 }
14938 
addCopiesAndBlittingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14939 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14940 {
14941 	addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind, extensionUse);
14942 	addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind, extensionUse);
14943 	addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind, extensionUse);
14944 	addTestGroup(group, "buffer_to_depthstencil", "Copy from buffer to depth/Stencil", addBufferToDepthStencilTests, allocationKind, extensionUse);
14945 	addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind, extensionUse);
14946 	addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind, extensionUse);
14947 	addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind, extensionUse);
14948 	addTestGroup(group, "depth_stencil_msaa_copy", "Copy depth/stencil with MSAA", addDepthStencilCopyMSAATestGroup, allocationKind, extensionUse);
14949 }
14950 
addCoreCopiesAndBlittingTests(tcu::TestCaseGroup * group)14951 void addCoreCopiesAndBlittingTests(tcu::TestCaseGroup* group)
14952 {
14953 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED, EXTENSION_USE_NONE);
14954 	addBufferCopyOffsetTests(group);
14955 }
14956 
14957 
addDedicatedAllocationCopiesAndBlittingTests(tcu::TestCaseGroup * group)14958 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
14959 {
14960 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_NONE);
14961 }
14962 
14963 #ifndef CTS_USES_VULKANSC
addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup * group)14964 void addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup* group)
14965 {
14966 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_COPY_COMMANDS2);
14967 }
14968 #endif // CTS_USES_VULKANSC
14969 
14970 } // anonymous
14971 
createCopiesAndBlittingTests(tcu::TestContext & testCtx)14972 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
14973 {
14974 	de::MovePtr<tcu::TestCaseGroup>	copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
14975 
14976 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", "Core Copies And Blitting Tests", addCoreCopiesAndBlittingTests));
14977 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation",	"Copies And Blitting Tests For Dedicated Memory Allocation",	addDedicatedAllocationCopiesAndBlittingTests));
14978 #ifndef CTS_USES_VULKANSC
14979 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "copy_commands2", "Copies And Blitting Tests using KHR_copy_commands2", addExtensionCopiesAndBlittingTests));
14980 #endif // CTS_USES_VULKANSC
14981 
14982 	return copiesAndBlittingTests.release();
14983 }
14984 
14985 } // api
14986 } // vkt
14987