• 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 <sstream>
66 
67 namespace vkt
68 {
69 
70 namespace api
71 {
72 
73 namespace
74 {
75 
76 enum FillMode
77 {
78 	FILL_MODE_GRADIENT = 0,
79 	FILL_MODE_WHITE,
80 	FILL_MODE_BLACK,
81 	FILL_MODE_RED,
82 	FILL_MODE_MULTISAMPLE,
83 	FILL_MODE_BLUE_RED_X,
84 	FILL_MODE_BLUE_RED_Y,
85 	FILL_MODE_BLUE_RED_Z,
86 
87 	FILL_MODE_LAST
88 };
89 
90 enum MirrorModeBits
91 {
92 	MIRROR_MODE_X		= (1<<0),
93 	MIRROR_MODE_Y		= (1<<1),
94 	MIRROR_MODE_Z		= (1<<2),
95 	MIRROR_MODE_LAST	= (1<<3),
96 };
97 
98 using MirrorMode = deUint32;
99 
100 enum AllocationKind
101 {
102 	ALLOCATION_KIND_SUBALLOCATED,
103 	ALLOCATION_KIND_DEDICATED,
104 };
105 
106 enum ExtensionUse
107 {
108 	EXTENSION_USE_NONE,
109 	EXTENSION_USE_COPY_COMMANDS2,
110 };
111 
112 template <typename Type>
113 class BinaryCompare
114 {
115 public:
operator ()(const Type & a,const Type & b) const116 	bool operator() (const Type& a, const Type& b) const
117 	{
118 		return deMemCmp(&a, &b, sizeof(Type)) < 0;
119 	}
120 };
121 
122 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> >	FormatSet;
123 
124 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
125 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
126 
127 using namespace vk;
128 
129 const deInt32					defaultSize				= 64;
130 const deInt32					defaultHalfSize			= defaultSize / 2;
131 const deInt32					defaultQuarterSize		= defaultSize / 4;
132 const deInt32					defaultSixteenthSize	= defaultSize / 16;
133 const VkExtent3D				defaultExtent			= {defaultSize, defaultSize, 1};
134 const VkExtent3D				defaultHalfExtent		= {defaultHalfSize, defaultHalfSize, 1};
135 const VkExtent3D				default1dExtent			= {defaultSize, 1, 1};
136 const VkExtent3D				default3dExtent			= {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize};
137 
138 const VkImageSubresourceLayers	defaultSourceLayer		=
139 {
140 	VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
141 	0u,							// deUint32				mipLevel;
142 	0u,							// deUint32				baseArrayLayer;
143 	1u,							// deUint32				layerCount;
144 };
145 
convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)146 VkImageCopy2KHR convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)
147 {
148 	const VkImageCopy2KHR	imageCopy2 =
149 	{
150 		VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR,		// VkStructureType				sType;
151 		DE_NULL,								// const void*					pNext;
152 		imageCopy.srcSubresource,				// VkImageSubresourceLayers		srcSubresource;
153 		imageCopy.srcOffset,					// VkOffset3D					srcOffset;
154 		imageCopy.dstSubresource,				// VkImageSubresourceLayers		dstSubresource;
155 		imageCopy.dstOffset,					// VkOffset3D					dstOffset;
156 		imageCopy.extent						// VkExtent3D					extent;
157 	};
158 	return imageCopy2;
159 }
convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)160 VkBufferCopy2KHR convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)
161 {
162 	const VkBufferCopy2KHR	bufferCopy2 =
163 	{
164 		VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR,	// VkStructureType				sType;
165 		DE_NULL,								// const void*					pNext;
166 		bufferCopy.srcOffset,					// VkDeviceSize					srcOffset;
167 		bufferCopy.dstOffset,					// VkDeviceSize					dstOffset;
168 		bufferCopy.size,						// VkDeviceSize					size;
169 	};
170 	return bufferCopy2;
171 }
172 
convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)173 VkBufferImageCopy2KHR convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)
174 {
175 	const VkBufferImageCopy2KHR	bufferImageCopy2 =
176 	{
177 		VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR,	// VkStructureType				sType;
178 		DE_NULL,									// const void*					pNext;
179 		bufferImageCopy.bufferOffset,				// VkDeviceSize					bufferOffset;
180 		bufferImageCopy.bufferRowLength,			// uint32_t						bufferRowLength;
181 		bufferImageCopy.bufferImageHeight,			// uint32_t						bufferImageHeight;
182 		bufferImageCopy.imageSubresource,			// VkImageSubresourceLayers		imageSubresource;
183 		bufferImageCopy.imageOffset,				// VkOffset3D					imageOffset;
184 		bufferImageCopy.imageExtent					// VkExtent3D					imageExtent;
185 	};
186 	return bufferImageCopy2;
187 }
188 
convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)189 VkImageBlit2KHR convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)
190 {
191 	const VkImageBlit2KHR	imageBlit2 =
192 	{
193 		VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR,			// VkStructureType				sType;
194 		DE_NULL,									// const void*					pNext;
195 		imageBlit.srcSubresource,					// VkImageSubresourceLayers		srcSubresource;
196 		{											// VkOffset3D					srcOffsets[2];
197 			{
198 				imageBlit.srcOffsets[0].x,				// VkOffset3D			srcOffsets[0].x;
199 				imageBlit.srcOffsets[0].y,				// VkOffset3D			srcOffsets[0].y;
200 				imageBlit.srcOffsets[0].z				// VkOffset3D			srcOffsets[0].z;
201 			},
202 			{
203 				imageBlit.srcOffsets[1].x,				// VkOffset3D			srcOffsets[1].x;
204 				imageBlit.srcOffsets[1].y,				// VkOffset3D			srcOffsets[1].y;
205 				imageBlit.srcOffsets[1].z				// VkOffset3D			srcOffsets[1].z;
206 			}
207 		},
208 		imageBlit.dstSubresource,					// VkImageSubresourceLayers		dstSubresource;
209 		{											// VkOffset3D					srcOffsets[2];
210 			{
211 				imageBlit.dstOffsets[0].x,				// VkOffset3D			dstOffsets[0].x;
212 				imageBlit.dstOffsets[0].y,				// VkOffset3D			dstOffsets[0].y;
213 				imageBlit.dstOffsets[0].z				// VkOffset3D			dstOffsets[0].z;
214 			},
215 			{
216 				imageBlit.dstOffsets[1].x,				// VkOffset3D			dstOffsets[1].x;
217 				imageBlit.dstOffsets[1].y,				// VkOffset3D			dstOffsets[1].y;
218 				imageBlit.dstOffsets[1].z				// VkOffset3D			dstOffsets[1].z;
219 			}
220 		}
221 	};
222 	return imageBlit2;
223 }
224 
convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)225 VkImageResolve2KHR convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)
226 {
227 	const VkImageResolve2KHR	imageResolve2 =
228 	{
229 		VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR,		// VkStructureType				sType;
230 		DE_NULL,									// const void*					pNext;
231 		imageResolve.srcSubresource,				// VkImageSubresourceLayers		srcSubresource;
232 		imageResolve.srcOffset,						// VkOffset3D					srcOffset;
233 		imageResolve.dstSubresource,				// VkImageSubresourceLayers		dstSubresource;
234 		imageResolve.dstOffset,						// VkOffset3D					dstOffset;
235 		imageResolve.extent							// VkExtent3D					extent;
236 	};
237 	return imageResolve2;
238 }
239 
getAspectFlags(tcu::TextureFormat format)240 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
241 {
242 	VkImageAspectFlags	aspectFlag	= 0;
243 	aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
244 	aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
245 
246 	if (!aspectFlag)
247 		aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
248 
249 	return aspectFlag;
250 }
251 
getAspectFlags(VkFormat format)252 VkImageAspectFlags getAspectFlags (VkFormat format)
253 {
254 	if (isCompressedFormat(format))
255 		return VK_IMAGE_ASPECT_COLOR_BIT;
256 	else
257 		return getAspectFlags(mapVkFormat(format));
258 }
259 
getSizeCompatibleTcuTextureFormat(VkFormat format)260 tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
261 {
262 	if (isCompressedFormat(format))
263 		return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
264 	else
265 		return mapVkFormat(format);
266 }
267 
268 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
269 // except that it supports some formats that are not mappable to VkFormat.
270 // When we are checking combined depth and stencil formats, each aspect is
271 // checked separately, and in some cases we construct PBA with a format that
272 // is not mappable to VkFormat.
isFloatFormat(tcu::TextureFormat format)273 bool isFloatFormat (tcu::TextureFormat format)
274 {
275 	return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
276 }
277 
278 union CopyRegion
279 {
280 	VkBufferCopy			bufferCopy;
281 	VkImageCopy				imageCopy;
282 	VkBufferImageCopy		bufferImageCopy;
283 	VkImageBlit				imageBlit;
284 	VkImageResolve			imageResolve;
285 };
286 
287 struct ImageParms
288 {
289 	VkImageType			imageType;
290 	VkFormat			format;
291 	VkExtent3D			extent;
292 	VkImageTiling		tiling;
293 	VkImageLayout		operationLayout;
294 	VkImageCreateFlags	createFlags;
295 	FillMode			fillMode;
296 };
297 
298 struct TestParams
299 {
300 	union Data
301 	{
302 		struct Buffer
303 		{
304 			VkDeviceSize	size;
305 		} buffer;
306 
307 		ImageParms	image;
308 	} src, dst;
309 
310 	std::vector<CopyRegion>	regions;
311 
312 	union
313 	{
314 		VkFilter				filter;
315 		VkSampleCountFlagBits	samples;
316 	};
317 
318 	AllocationKind	allocationKind;
319 	ExtensionUse	extensionUse;
320 	deUint32		mipLevels;
321 	deBool			singleCommand;
322 	deUint32		barrierCount;
323 	deBool			separateDepthStencilLayouts;
324 	deBool			clearDestination;
325 	deBool			imageOffset;
326 
TestParamsvkt::api::__anon1525b85c0111::TestParams327 	TestParams (void)
328 	{
329 		allocationKind				= ALLOCATION_KIND_DEDICATED;
330 		extensionUse				= EXTENSION_USE_NONE;
331 		mipLevels					= 1u;
332 		singleCommand				= DE_TRUE;
333 		barrierCount				= 1u;
334 		separateDepthStencilLayouts	= DE_FALSE;
335 		src.image.createFlags		= VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
336 		dst.image.createFlags		= VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
337 		src.image.fillMode			= FILL_MODE_GRADIENT;
338 		dst.image.fillMode			= FILL_MODE_WHITE;
339 		clearDestination			= DE_FALSE;
340 		samples						= VK_SAMPLE_COUNT_1_BIT;
341 		imageOffset					= false;
342 	}
343 };
344 
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)345 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface&	vki,
346 										const DeviceInterface&		vkd,
347 										const VkPhysicalDevice&		physDevice,
348 										const VkDevice				device,
349 										const VkBuffer&				buffer,
350 										const MemoryRequirement		requirement,
351 										Allocator&					allocator,
352 										AllocationKind				allocationKind)
353 {
354 	switch (allocationKind)
355 	{
356 		case ALLOCATION_KIND_SUBALLOCATED:
357 		{
358 			const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
359 
360 			return allocator.allocate(memoryRequirements, requirement);
361 		}
362 
363 		case ALLOCATION_KIND_DEDICATED:
364 		{
365 			return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
366 		}
367 
368 		default:
369 		{
370 			TCU_THROW(InternalError, "Invalid allocation kind");
371 		}
372 	}
373 }
374 
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)375 de::MovePtr<Allocation> allocateImage (const InstanceInterface&		vki,
376 									   const DeviceInterface&		vkd,
377 									   const VkPhysicalDevice&		physDevice,
378 									   const VkDevice				device,
379 									   const VkImage&				image,
380 									   const MemoryRequirement		requirement,
381 									   Allocator&					allocator,
382 									   AllocationKind				allocationKind,
383 									   const deUint32				offset)
384 {
385 	switch (allocationKind)
386 	{
387 		case ALLOCATION_KIND_SUBALLOCATED:
388 		{
389 			VkMemoryRequirements memoryRequirements	= getImageMemoryRequirements(vkd, device, image);
390 			memoryRequirements.size += offset;
391 
392 			return allocator.allocate(memoryRequirements, requirement);
393 		}
394 
395 		case ALLOCATION_KIND_DEDICATED:
396 		{
397 			VkMemoryRequirements					memoryRequirements		= getImageMemoryRequirements(vkd, device, image);
398 			memoryRequirements.size += offset;
399 
400 			const VkMemoryDedicatedAllocateInfo		dedicatedAllocationInfo	=
401 			{
402 				VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,				// VkStructureType		sType
403 				DE_NULL,														// const void*			pNext
404 				image,															// VkImage				image
405 				DE_NULL															// VkBuffer				buffer
406 			};
407 
408 			return allocateExtended(vki, vkd, physDevice, device, memoryRequirements, requirement, &dedicatedAllocationInfo);
409 		}
410 
411 		default:
412 		{
413 			TCU_THROW(InternalError, "Invalid allocation kind");
414 		}
415 	}
416 }
417 
418 
getArraySize(const ImageParms & parms)419 inline deUint32 getArraySize(const ImageParms& parms)
420 {
421 	return (parms.imageType != VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u;
422 }
423 
getCreateFlags(const ImageParms & parms)424 inline VkImageCreateFlags  getCreateFlags(const ImageParms& parms)
425 {
426 	if (parms.createFlags == VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM)
427 		return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
428 	else
429 		return parms.createFlags;
430 }
431 
getExtent3D(const ImageParms & parms,deUint32 mipLevel=0u)432 inline VkExtent3D getExtent3D(const ImageParms& parms, deUint32 mipLevel = 0u)
433 {
434 	const bool			isCompressed	= isCompressedFormat(parms.format);
435 	const deUint32		blockWidth		= (isCompressed) ? getBlockWidth(parms.format) : 1u;
436 	const deUint32		blockHeight		= (isCompressed) ? getBlockHeight(parms.format) : 1u;
437 
438 	if (isCompressed && mipLevel != 0u)
439 		DE_FATAL("Not implemented");
440 
441 	const VkExtent3D	extent			=
442 	{
443 		(parms.extent.width >> mipLevel) * blockWidth,
444 		(parms.imageType != VK_IMAGE_TYPE_1D) ? ((parms.extent.height >> mipLevel) * blockHeight) : 1u,
445 		(parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
446 	};
447 	return extent;
448 }
449 
mapCombinedToDepthTransferFormat(const tcu::TextureFormat & combinedFormat)450 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
451 {
452 	tcu::TextureFormat format;
453 	switch (combinedFormat.type)
454 	{
455 		case tcu::TextureFormat::UNORM_INT16:
456 		case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
457 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
458 			break;
459 		case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
460 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
461 			break;
462 		case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
463 		case tcu::TextureFormat::FLOAT:
464 			format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
465 			break;
466 		default:
467 			DE_ASSERT(false);
468 			break;
469 	}
470 	return format;
471 }
472 
473 class CopiesAndBlittingTestInstance : public vkt::TestInstance
474 {
475 public:
476 										CopiesAndBlittingTestInstance		(Context&	context,
477 																			 TestParams	testParams);
478 	virtual tcu::TestStatus				iterate								(void) = 0;
479 
480 protected:
481 	const TestParams					m_params;
482 
483 	VkDevice							m_device;
484 	VkQueue								m_queue;
485 	Allocator*							m_allocator;
486 	Move<VkCommandPool>					m_cmdPool;
487 	Move<VkCommandBuffer>				m_cmdBuffer;
488 	de::MovePtr<tcu::TextureLevel>		m_sourceTextureLevel;
489 	de::MovePtr<tcu::TextureLevel>		m_destinationTextureLevel;
490 	de::MovePtr<tcu::TextureLevel>		m_expectedTextureLevel[16];
491 
492 	void								generateBuffer						(tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
493 	virtual void						generateExpectedResult				(void);
494 	void								uploadBuffer						(const tcu::ConstPixelBufferAccess& bufferAccess, const Allocation& bufferAlloc);
495 	void								uploadImage							(const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u);
496 	virtual tcu::TestStatus				checkTestResult						(tcu::ConstPixelBufferAccess result);
497 	virtual void						copyRegionToTextureLevel			(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u) = 0;
calculateSize(tcu::ConstPixelBufferAccess src) const498 	deUint32							calculateSize						(tcu::ConstPixelBufferAccess src) const
499 										{
500 											return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
501 										}
502 
503 	de::MovePtr<tcu::TextureLevel>		readImage							(vk::VkImage				image,
504 																			 const ImageParms&			imageParms,
505 																			 const deUint32				mipLevel = 0u);
506 
507 private:
508 	void								uploadImageAspect					(const tcu::ConstPixelBufferAccess&	src,
509 																			 const VkImage&						dst,
510 																			 const ImageParms&					parms,
511 																			 const deUint32						mipLevels = 1u);
512 	void								readImageAspect						(vk::VkImage						src,
513 																			 const tcu::PixelBufferAccess&		dst,
514 																			 const ImageParms&					parms,
515 																			 const deUint32						mipLevel = 0u);
516 };
517 
CopiesAndBlittingTestInstance(Context & context,TestParams testParams)518 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
519 	: vkt::TestInstance	(context)
520 	, m_params			(testParams)
521 {
522 	// Store default device, queue and allocator. Some tests override these with custom device and queue.
523 	m_device		= context.getDevice();
524 	m_queue			= context.getUniversalQueue();
525 	m_allocator		= &context.getDefaultAllocator();
526 	const DeviceInterface&		vk					= context.getDeviceInterface();
527 	const deUint32				queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
528 
529 	// Create command pool
530 	m_cmdPool = createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
531 
532 	// Create command buffer
533 	m_cmdBuffer = allocateCommandBuffer(vk, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
534 }
535 
generateBuffer(tcu::PixelBufferAccess buffer,int width,int height,int depth,FillMode mode)536 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
537 {
538 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(buffer.getFormat().type);
539 	tcu::Vec4						maxValue		(1.0f);
540 
541 	if (buffer.getFormat().order == tcu::TextureFormat::S)
542 	{
543 		// Stencil-only is stored in the first component. Stencil is always 8 bits.
544 		maxValue.x() = 1 << 8;
545 	}
546 	else if (buffer.getFormat().order == tcu::TextureFormat::DS)
547 	{
548 		// In a combined format, fillWithComponentGradients expects stencil in the fourth component.
549 		maxValue.w() = 1 << 8;
550 	}
551 	else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
552 	{
553 		// The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
554 		const tcu::IVec4	bits	= tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
555 		const int			signBit	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
556 
557 		for (int i = 0; i < 4; ++i)
558 		{
559 			if (bits[i] != 0)
560 				maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1);
561 		}
562 	}
563 
564 	if (mode == FILL_MODE_GRADIENT)
565 	{
566 		tcu::fillWithComponentGradients2(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
567 		return;
568 	}
569 
570 	const tcu::Vec4		redColor	(maxValue.x(),	0.0,			0.0,			maxValue.w());
571 	const tcu::Vec4		greenColor	(0.0,			maxValue.y(),	0.0,			maxValue.w());
572 	const tcu::Vec4		blueColor	(0.0,			0.0,			maxValue.z(),	maxValue.w());
573 	const tcu::Vec4		whiteColor	(maxValue.x(),	maxValue.y(),	maxValue.z(),	maxValue.w());
574 	const tcu::Vec4		blackColor	(0.0f,			0.0f,			0.0f,			0.0f);
575 
576 	for (int z = 0; z < depth;  ++z)
577 	for (int y = 0; y < height; ++y)
578 	for (int x = 0; x < width;  ++x)
579 	{
580 		switch (mode)
581 		{
582 			case FILL_MODE_WHITE:
583 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
584 				{
585 					buffer.setPixDepth(1.0f, x, y, z);
586 					if (tcu::hasStencilComponent(buffer.getFormat().order))
587 						buffer.setPixStencil(255, x, y, z);
588 				}
589 				else
590 					buffer.setPixel(whiteColor, x, y, z);
591 				break;
592 
593 			case FILL_MODE_BLACK:
594 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
595 				{
596 					buffer.setPixDepth(0.0f, x, y, z);
597 					if (tcu::hasStencilComponent(buffer.getFormat().order))
598 						buffer.setPixStencil(0, x, y, z);
599 				}
600 				else
601 					buffer.setPixel(blackColor, x, y, z);
602 				break;
603 
604 			case FILL_MODE_RED:
605 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
606 				{
607 					buffer.setPixDepth(redColor[0], x, y, z);
608 					if (tcu::hasStencilComponent(buffer.getFormat().order))
609 						buffer.setPixStencil((int)redColor[3], x, y, z);
610 				}
611 				else
612 					buffer.setPixel(redColor, x, y, z);
613 				break;
614 
615 			case FILL_MODE_BLUE_RED_X:
616 			case FILL_MODE_BLUE_RED_Y:
617 			case FILL_MODE_BLUE_RED_Z:
618 				bool useBlue;
619 				switch (mode)
620 				{
621 					case FILL_MODE_BLUE_RED_X: useBlue = (x & 1); break;
622 					case FILL_MODE_BLUE_RED_Y: useBlue = (y & 1); break;
623 					case FILL_MODE_BLUE_RED_Z: useBlue = (z & 1); break;
624 					default: DE_ASSERT(false); break;
625 				}
626 				if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
627 				{
628 					buffer.setPixDepth((useBlue ? blueColor[0] : redColor[0]), x, y, z);
629 					if (tcu::hasStencilComponent(buffer.getFormat().order))
630 						buffer.setPixStencil((useBlue ? (int) blueColor[3] : (int)redColor[3]), x, y, z);
631 				}
632 				else
633 					buffer.setPixel((useBlue ? blueColor : redColor), x, y, z);
634 				break;
635 
636 			case FILL_MODE_MULTISAMPLE:
637 			{
638 				float xScaled = static_cast<float>(x) / static_cast<float>(width);
639 				float yScaled = static_cast<float>(y) / static_cast<float>(height);
640 				buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
641 				break;
642 			}
643 
644 			default:
645 				break;
646 		}
647 	}
648 }
649 
uploadBuffer(const tcu::ConstPixelBufferAccess & bufferAccess,const Allocation & bufferAlloc)650 void CopiesAndBlittingTestInstance::uploadBuffer (const tcu::ConstPixelBufferAccess& bufferAccess, const Allocation& bufferAlloc)
651 {
652 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
653 	const deUint32				bufferSize	= calculateSize(bufferAccess);
654 
655 	// Write buffer data
656 	deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
657 	flushAlloc(vk, m_device, bufferAlloc);
658 }
659 
uploadImageAspect(const tcu::ConstPixelBufferAccess & imageAccess,const VkImage & image,const ImageParms & parms,const deUint32 mipLevels)660 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels)
661 {
662 	const InstanceInterface&		vki					= m_context.getInstanceInterface();
663 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
664 	const VkPhysicalDevice			vkPhysDevice		= m_context.getPhysicalDevice();
665 	const VkDevice					vkDevice			= m_device;
666 	const VkQueue					queue				= m_queue;
667 	Allocator&						memAlloc			= *m_allocator;
668 	Move<VkBuffer>					buffer;
669 	const deUint32					bufferSize			= calculateSize(imageAccess);
670 	de::MovePtr<Allocation>			bufferAlloc;
671 	const deUint32					arraySize			= getArraySize(parms);
672 	const VkExtent3D				imageExtent			= getExtent3D(parms);
673 	std::vector <VkBufferImageCopy>	copyRegions;
674 
675 	// Create source buffer
676 	{
677 		const VkBufferCreateInfo	bufferParams		=
678 		{
679 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
680 			DE_NULL,									// const void*			pNext;
681 			0u,											// VkBufferCreateFlags	flags;
682 			bufferSize,									// VkDeviceSize			size;
683 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
684 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
685 			0u,											// deUint32				queueFamilyIndexCount;
686 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
687 		};
688 
689 		buffer		= createBuffer(vk, vkDevice, &bufferParams);
690 		bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
691 		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
692 	}
693 
694 	// Barriers for copying buffer to image
695 	const VkBufferMemoryBarrier		preBufferBarrier	=
696 	{
697 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
698 		DE_NULL,										// const void*		pNext;
699 		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
700 		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
701 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
702 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
703 		*buffer,										// VkBuffer			buffer;
704 		0u,												// VkDeviceSize		offset;
705 		bufferSize										// VkDeviceSize		size;
706 	};
707 
708 	const VkImageAspectFlags		formatAspect		= (m_params.separateDepthStencilLayouts) ? getAspectFlags(imageAccess.getFormat()) : getAspectFlags(parms.format);
709 	const bool						skipPreImageBarrier	= (m_params.separateDepthStencilLayouts) ? false : ((formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
710 														  getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT));
711 
712 	const VkImageMemoryBarrier		preImageBarrier		=
713 	{
714 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
715 		DE_NULL,										// const void*				pNext;
716 		0u,												// VkAccessFlags			srcAccessMask;
717 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
718 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
719 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
720 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
721 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
722 		image,											// VkImage					image;
723 		{												// VkImageSubresourceRange	subresourceRange;
724 			formatAspect,	// VkImageAspectFlags	aspect;
725 			0u,				// deUint32				baseMipLevel;
726 			mipLevels,		// deUint32				mipLevels;
727 			0u,				// deUint32				baseArraySlice;
728 			arraySize,		// deUint32				arraySize;
729 		}
730 	};
731 
732 	const VkImageMemoryBarrier		postImageBarrier	=
733 	{
734 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
735 		DE_NULL,										// const void*				pNext;
736 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
737 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
738 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
739 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
740 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
741 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
742 		image,											// VkImage					image;
743 		{												// VkImageSubresourceRange	subresourceRange;
744 			formatAspect,				// VkImageAspectFlags	aspect;
745 			0u,							// deUint32				baseMipLevel;
746 			mipLevels,					// deUint32				mipLevels;
747 			0u,							// deUint32				baseArraySlice;
748 			arraySize,					// deUint32				arraySize;
749 		}
750 	};
751 
752 	for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
753 	{
754 		const VkExtent3D		copyExtent	=
755 		{
756 			imageExtent.width	>> mipLevelNdx,
757 			imageExtent.height	>> mipLevelNdx,
758 			imageExtent.depth
759 		};
760 
761 		const bool		isCompressed	= isCompressedFormat(parms.format);
762 		const deUint32	blockWidth		= (isCompressed) ? getBlockWidth(parms.format) : 1u;
763 		const deUint32	blockHeight		= (isCompressed) ? getBlockHeight(parms.format) : 1u;
764 		deUint32 rowLength		= ((copyExtent.width + blockWidth-1) / blockWidth) * blockWidth;
765 		deUint32 imageHeight	= ((copyExtent.height + blockHeight-1) / blockHeight) * blockHeight;
766 
767 		const VkBufferImageCopy	copyRegion	=
768 		{
769 			0u,												// VkDeviceSize				bufferOffset;
770 			rowLength,										// deUint32					bufferRowLength;
771 			imageHeight,									// deUint32					bufferImageHeight;
772 			{
773 				getAspectFlags(imageAccess.getFormat()),		// VkImageAspectFlags	aspect;
774 				mipLevelNdx,									// deUint32				mipLevel;
775 				0u,												// deUint32				baseArrayLayer;
776 				arraySize,										// deUint32				layerCount;
777 			},												// VkImageSubresourceLayers	imageSubresource;
778 			{ 0, 0, 0 },									// VkOffset3D				imageOffset;
779 			copyExtent										// VkExtent3D				imageExtent;
780 		};
781 
782 		copyRegions.push_back(copyRegion);
783 	}
784 
785 	// Write buffer data
786 	deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
787 	flushAlloc(vk, vkDevice, *bufferAlloc);
788 
789 	// Copy buffer to image
790 	beginCommandBuffer(vk, *m_cmdBuffer);
791 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
792 						  1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
793 	vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), &copyRegions[0]);
794 	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);
795 	endCommandBuffer(vk, *m_cmdBuffer);
796 
797 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
798 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
799 }
800 
uploadImage(const tcu::ConstPixelBufferAccess & src,VkImage dst,const ImageParms & parms,const deUint32 mipLevels)801 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels)
802 {
803 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
804 	{
805 		if (tcu::hasDepthComponent(src.getFormat().order))
806 		{
807 			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
808 			tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
809 			uploadImageAspect(depthTexture.getAccess(), dst, parms, mipLevels);
810 		}
811 
812 		if (tcu::hasStencilComponent(src.getFormat().order))
813 		{
814 			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
815 			tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
816 			uploadImageAspect(stencilTexture.getAccess(), dst, parms, mipLevels);
817 		}
818 	}
819 	else
820 		uploadImageAspect(src, dst, parms, mipLevels);
821 }
822 
checkTestResult(tcu::ConstPixelBufferAccess result)823 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
824 {
825 	const tcu::ConstPixelBufferAccess	expected	= m_expectedTextureLevel[0]->getAccess();
826 
827 	if (isFloatFormat(result.getFormat()))
828 	{
829 		const tcu::Vec4	threshold (0.0f);
830 		if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
831 			return tcu::TestStatus::fail("CopiesAndBlitting test");
832 	}
833 	else
834 	{
835 		const tcu::UVec4 threshold (0u);
836 		if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
837 		{
838 			if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, 0.1f, tcu::COMPARE_LOG_RESULT))
839 				return tcu::TestStatus::fail("CopiesAndBlitting test");
840 		}
841 		else
842 		{
843 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
844 				return tcu::TestStatus::fail("CopiesAndBlitting test");
845 		}
846 	}
847 
848 	return tcu::TestStatus::pass("CopiesAndBlitting test");
849 }
850 
generateExpectedResult(void)851 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
852 {
853 	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
854 	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
855 
856 	m_expectedTextureLevel[0]	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
857 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
858 
859 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
860 		copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
861 }
862 
readImageAspect(vk::VkImage image,const tcu::PixelBufferAccess & dst,const ImageParms & imageParms,const deUint32 mipLevel)863 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage					image,
864 													 const tcu::PixelBufferAccess&	dst,
865 													 const ImageParms&				imageParms,
866 													 const deUint32					mipLevel)
867 {
868 	const InstanceInterface&	vki					= m_context.getInstanceInterface();
869 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
870 	const VkPhysicalDevice		physDevice			= m_context.getPhysicalDevice();
871 	const VkDevice				device				= m_device;
872 	const VkQueue				queue				= m_queue;
873 	Allocator&					allocator			= *m_allocator;
874 
875 	Move<VkBuffer>				buffer;
876 	de::MovePtr<Allocation>		bufferAlloc;
877 	const VkDeviceSize			pixelDataSize		= calculateSize(dst);
878 	const VkExtent3D			imageExtent			= getExtent3D(imageParms, mipLevel);
879 
880 	// Create destination buffer
881 	{
882 		const VkBufferCreateInfo			bufferParams			=
883 		{
884 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
885 			DE_NULL,									// const void*			pNext;
886 			0u,											// VkBufferCreateFlags	flags;
887 			pixelDataSize,								// VkDeviceSize			size;
888 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
889 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
890 			0u,											// deUint32				queueFamilyIndexCount;
891 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
892 		};
893 
894 		buffer		= createBuffer(vk, device, &bufferParams);
895 		bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
896 		VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
897 
898 		deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
899 		flushAlloc(vk, device, *bufferAlloc);
900 	}
901 
902 	// Barriers for copying image to buffer
903 	const VkImageAspectFlags				formatAspect			= getAspectFlags(imageParms.format);
904 	const VkImageMemoryBarrier				imageBarrier			=
905 	{
906 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
907 		DE_NULL,									// const void*				pNext;
908 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
909 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
910 		imageParms.operationLayout,					// VkImageLayout			oldLayout;
911 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
912 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
913 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
914 		image,										// VkImage					image;
915 		{											// VkImageSubresourceRange	subresourceRange;
916 			formatAspect,			// VkImageAspectFlags	aspectMask;
917 			mipLevel,				// deUint32				baseMipLevel;
918 			1u,						// deUint32				mipLevels;
919 			0u,						// deUint32				baseArraySlice;
920 			getArraySize(imageParms)// deUint32				arraySize;
921 		}
922 	};
923 
924 	const VkBufferMemoryBarrier				bufferBarrier			=
925 	{
926 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
927 		DE_NULL,									// const void*		pNext;
928 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
929 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
930 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
931 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
932 		*buffer,									// VkBuffer			buffer;
933 		0u,											// VkDeviceSize		offset;
934 		pixelDataSize								// VkDeviceSize		size;
935 	};
936 
937 	const VkImageMemoryBarrier				postImageBarrier		=
938 	{
939 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
940 		DE_NULL,									// const void*				pNext;
941 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
942 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
943 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			oldLayout;
944 		imageParms.operationLayout,					// VkImageLayout			newLayout;
945 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
946 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
947 		image,										// VkImage					image;
948 		{
949 			formatAspect,								// VkImageAspectFlags	aspectMask;
950 			mipLevel,									// deUint32				baseMipLevel;
951 			1u,											// deUint32				mipLevels;
952 			0u,											// deUint32				baseArraySlice;
953 			getArraySize(imageParms)					// deUint32				arraySize;
954 		}											// VkImageSubresourceRange	subresourceRange;
955 	};
956 
957 	// Copy image to buffer
958 	const bool		isCompressed	= isCompressedFormat(imageParms.format);
959 	const deUint32	blockWidth		= (isCompressed) ? getBlockWidth(imageParms.format) : 1u;
960 	const deUint32	blockHeight		= (isCompressed) ? getBlockHeight(imageParms.format) : 1u;
961 	deUint32 rowLength		= ((imageExtent.width + blockWidth-1) / blockWidth) * blockWidth;
962 	deUint32 imageHeight	= ((imageExtent.height + blockHeight-1) / blockHeight) * blockHeight;
963 
964 	// Copy image to buffer - note that there are cases where m_params.dst.image.format is not the same as dst.getFormat()
965 	const VkImageAspectFlags	aspect			= isCompressedFormat(m_params.dst.image.format) ?
966 													static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) : getAspectFlags(dst.getFormat());
967 	const VkBufferImageCopy		copyRegion		=
968 	{
969 		0u,								// VkDeviceSize				bufferOffset;
970 		rowLength,						// deUint32					bufferRowLength;
971 		imageHeight,					// deUint32					bufferImageHeight;
972 		{
973 			aspect,							// VkImageAspectFlags		aspect;
974 			mipLevel,						// deUint32					mipLevel;
975 			0u,								// deUint32					baseArrayLayer;
976 			getArraySize(imageParms),		// deUint32					layerCount;
977 		},								// VkImageSubresourceLayers	imageSubresource;
978 		{ 0, 0, 0 },					// VkOffset3D				imageOffset;
979 		imageExtent						// VkExtent3D				imageExtent;
980 	};
981 
982 	beginCommandBuffer(vk, *m_cmdBuffer);
983 	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);
984 	vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
985 	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);
986 	endCommandBuffer(vk, *m_cmdBuffer);
987 
988 	submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
989 	m_context.resetCommandPoolForVKSC(device, *m_cmdPool);
990 
991 	// Read buffer data
992 	invalidateAlloc(vk, device, *bufferAlloc);
993 	tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
994 }
995 
readImage(vk::VkImage image,const ImageParms & parms,const deUint32 mipLevel)996 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage	(vk::VkImage		image,
997 																		 const ImageParms&	parms,
998 																		 const deUint32		mipLevel)
999 {
1000 	const tcu::TextureFormat		imageFormat	= getSizeCompatibleTcuTextureFormat(parms.format);
1001 	de::MovePtr<tcu::TextureLevel>	resultLevel	(new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
1002 
1003 	if (tcu::isCombinedDepthStencilType(imageFormat.type))
1004 	{
1005 		if (tcu::hasDepthComponent(imageFormat.order))
1006 		{
1007 			tcu::TextureLevel	depthTexture	(mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
1008 			readImageAspect(image, depthTexture.getAccess(), parms, mipLevel);
1009 			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
1010 		}
1011 
1012 		if (tcu::hasStencilComponent(imageFormat.order))
1013 		{
1014 			tcu::TextureLevel	stencilTexture	(tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
1015 			readImageAspect(image, stencilTexture.getAccess(), parms, mipLevel);
1016 			tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
1017 		}
1018 	}
1019 	else
1020 		readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
1021 
1022 	return resultLevel;
1023 }
1024 
1025 // Copy from image to image.
1026 
1027 class CopyImageToImage : public CopiesAndBlittingTestInstance
1028 {
1029 public:
1030 										CopyImageToImage			(Context&	context,
1031 																	 TestParams params);
1032 	virtual tcu::TestStatus				iterate						(void);
1033 
1034 protected:
1035 	virtual tcu::TestStatus				checkTestResult				(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
1036 
1037 private:
1038 	Move<VkImage>						m_source;
1039 	de::MovePtr<Allocation>				m_sourceImageAlloc;
1040 	Move<VkImage>						m_destination;
1041 	de::MovePtr<Allocation>				m_destinationImageAlloc;
1042 
1043 	virtual void						copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1044 };
1045 
CopyImageToImage(Context & context,TestParams params)1046 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
1047 	: CopiesAndBlittingTestInstance(context, params)
1048 {
1049 	const InstanceInterface&	vki					= context.getInstanceInterface();
1050 	const DeviceInterface&		vk					= context.getDeviceInterface();
1051 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
1052 	const VkDevice				vkDevice			= m_device;
1053 	Allocator&					memAlloc			= context.getDefaultAllocator();
1054 
1055 	// Create source image
1056 	{
1057 		const VkImageCreateInfo	sourceImageParams		=
1058 		{
1059 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1060 			DE_NULL,								// const void*			pNext;
1061 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
1062 			m_params.src.image.imageType,			// VkImageType			imageType;
1063 			m_params.src.image.format,				// VkFormat				format;
1064 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
1065 			1u,										// deUint32				mipLevels;
1066 			getArraySize(m_params.src.image),		// deUint32				arraySize;
1067 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1068 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1069 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1070 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1071 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1072 			0u,										// deUint32				queueFamilyIndexCount;
1073 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
1074 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1075 		};
1076 
1077 		m_source				= createImage(vk, vkDevice, &sourceImageParams);
1078 		m_sourceImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1079 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1080 	}
1081 
1082 	// Create destination image
1083 	{
1084 		const VkImageCreateInfo	destinationImageParams	=
1085 		{
1086 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1087 			DE_NULL,								// const void*			pNext;
1088 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
1089 			m_params.dst.image.imageType,			// VkImageType			imageType;
1090 			m_params.dst.image.format,				// VkFormat				format;
1091 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
1092 			1u,										// deUint32				mipLevels;
1093 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
1094 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1095 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1096 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1097 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1098 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1099 			0u,										// deUint32				queueFamilyIndexCount;
1100 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
1101 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1102 		};
1103 
1104 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
1105 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1106 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1107 	}
1108 }
1109 
iterate(void)1110 tcu::TestStatus CopyImageToImage::iterate (void)
1111 {
1112 	const bool					srcCompressed		= isCompressedFormat(m_params.src.image.format);
1113 	const bool					dstCompressed		= isCompressedFormat(m_params.dst.image.format);
1114 
1115 	const tcu::TextureFormat	srcTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1116 	const tcu::TextureFormat	dstTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1117 
1118 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1119 																				(int)m_params.src.image.extent.width,
1120 																				(int)m_params.src.image.extent.height,
1121 																				(int)m_params.src.image.extent.depth));
1122 	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);
1123 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1124 																				(int)m_params.dst.image.extent.width,
1125 																				(int)m_params.dst.image.extent.height,
1126 																				(int)m_params.dst.image.extent.depth));
1127 	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);
1128 	generateExpectedResult();
1129 
1130 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1131 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1132 
1133 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
1134 	const VkDevice				vkDevice			= m_device;
1135 	const VkQueue				queue				= m_queue;
1136 
1137 	std::vector<VkImageCopy>		imageCopies;
1138 	std::vector<VkImageCopy2KHR>	imageCopies2KHR;
1139 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1140 	{
1141 		VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1142 
1143 		// When copying between compressed and uncompressed formats the extent
1144 		// members represent the texel dimensions of the source image.
1145 		if (srcCompressed)
1146 		{
1147 			const deUint32	blockWidth	= getBlockWidth(m_params.src.image.format);
1148 			const deUint32	blockHeight	= getBlockHeight(m_params.src.image.format);
1149 
1150 			imageCopy.srcOffset.x *= blockWidth;
1151 			imageCopy.srcOffset.y *= blockHeight;
1152 			imageCopy.extent.width *= blockWidth;
1153 			imageCopy.extent.height *= blockHeight;
1154 		}
1155 
1156 		if (dstCompressed)
1157 		{
1158 			const deUint32	blockWidth	= getBlockWidth(m_params.dst.image.format);
1159 			const deUint32	blockHeight	= getBlockHeight(m_params.dst.image.format);
1160 
1161 			imageCopy.dstOffset.x *= blockWidth;
1162 			imageCopy.dstOffset.y *= blockHeight;
1163 		}
1164 
1165 		if (m_params.extensionUse == EXTENSION_USE_NONE)
1166 		{
1167 			imageCopies.push_back(imageCopy);
1168 		}
1169 		else
1170 		{
1171 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1172 			imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1173 		}
1174 	}
1175 
1176 	VkImageMemoryBarrier	imageBarriers[]		=
1177 	{
1178 		// source image
1179 		{
1180 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1181 			DE_NULL,									// const void*				pNext;
1182 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1183 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
1184 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1185 			m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
1186 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1187 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1188 			m_source.get(),								// VkImage					image;
1189 			{											// VkImageSubresourceRange	subresourceRange;
1190 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
1191 				0u,								// deUint32				baseMipLevel;
1192 				1u,								// deUint32				mipLevels;
1193 				0u,								// deUint32				baseArraySlice;
1194 				getArraySize(m_params.src.image)// deUint32				arraySize;
1195 			}
1196 		},
1197 		// destination image
1198 		{
1199 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1200 			DE_NULL,									// const void*				pNext;
1201 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1202 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
1203 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1204 			m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
1205 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1206 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1207 			m_destination.get(),						// VkImage					image;
1208 			{											// VkImageSubresourceRange	subresourceRange;
1209 				getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
1210 				0u,								// deUint32				baseMipLevel;
1211 				1u,								// deUint32				mipLevels;
1212 				0u,								// deUint32				baseArraySlice;
1213 				getArraySize(m_params.dst.image)// deUint32				arraySize;
1214 			}
1215 		},
1216 	};
1217 
1218 	beginCommandBuffer(vk, *m_cmdBuffer);
1219 	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);
1220 
1221 	if (m_params.clearDestination)
1222 	{
1223 		VkImageSubresourceRange	range		= { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
1224 		VkClearColorValue		clearColor;
1225 
1226 		clearColor.float32[0] = 1.0f;
1227 		clearColor.float32[1] = 1.0f;
1228 		clearColor.float32[2] = 1.0f;
1229 		clearColor.float32[3] = 1.0f;
1230 		vk.cmdClearColorImage(*m_cmdBuffer, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u, &range);
1231 		imageBarriers[0].oldLayout = imageBarriers[0].newLayout;
1232 		imageBarriers[1].oldLayout = imageBarriers[1].newLayout;
1233 		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);
1234 	}
1235 
1236 	if (m_params.extensionUse == EXTENSION_USE_NONE)
1237 	{
1238 		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());
1239 	}
1240 #ifndef CTS_USES_VULKANSC
1241 	else
1242 	{
1243 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1244 		const VkCopyImageInfo2KHR copyImageInfo2KHR =
1245 		{
1246 			VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
1247 			DE_NULL,									// const void*				pNext;
1248 			m_source.get(),								// VkImage					srcImage;
1249 			m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
1250 			m_destination.get(),						// VkImage					dstImage;
1251 			m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
1252 			(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
1253 			imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
1254 		};
1255 
1256 		vk.cmdCopyImage2(*m_cmdBuffer, &copyImageInfo2KHR);
1257 	}
1258 #endif // CTS_USES_VULKANSC
1259 
1260 	endCommandBuffer(vk, *m_cmdBuffer);
1261 
1262 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1263 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
1264 
1265 	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);
1266 
1267 	return checkTestResult(resultTextureLevel->getAccess());
1268 }
1269 
checkTestResult(tcu::ConstPixelBufferAccess result)1270 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
1271 {
1272 	const tcu::Vec4	fThreshold (0.0f);
1273 	const tcu::UVec4 uThreshold (0u);
1274 
1275 	if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1276 	{
1277 		if (tcu::hasDepthComponent(result.getFormat().order))
1278 		{
1279 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
1280 			const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
1281 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1282 
1283 			if (isFloatFormat(result.getFormat()))
1284 			{
1285 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1286 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1287 			}
1288 			else
1289 			{
1290 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1291 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1292 			}
1293 		}
1294 
1295 		if (tcu::hasStencilComponent(result.getFormat().order))
1296 		{
1297 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
1298 			const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
1299 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1300 
1301 			if (isFloatFormat(result.getFormat()))
1302 			{
1303 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1304 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1305 			}
1306 			else
1307 			{
1308 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1309 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1310 			}
1311 		}
1312 	}
1313 	else
1314 	{
1315 		if (isFloatFormat(result.getFormat()))
1316 		{
1317 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1318 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1319 		}
1320 		else
1321 		{
1322 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1323 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1324 		}
1325 	}
1326 
1327 	return tcu::TestStatus::pass("CopiesAndBlitting test");
1328 }
1329 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1330 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1331 {
1332 	DE_UNREF(mipLevel);
1333 
1334 	VkOffset3D	srcOffset	= region.imageCopy.srcOffset;
1335 	VkOffset3D	dstOffset	= region.imageCopy.dstOffset;
1336 	VkExtent3D	extent		= region.imageCopy.extent;
1337 
1338 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1339 	{
1340 		dstOffset.z = srcOffset.z;
1341 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1342 	}
1343 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1344 	{
1345 		srcOffset.z = dstOffset.z;
1346 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1347 	}
1348 
1349 
1350 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1351 	{
1352 		DE_ASSERT(src.getFormat() == dst.getFormat());
1353 
1354 		// Copy depth.
1355 		if (tcu::hasDepthComponent(src.getFormat().order))
1356 		{
1357 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1358 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1359 			tcu::copy(dstSubRegion, srcSubRegion);
1360 		}
1361 
1362 		// Copy stencil.
1363 		if (tcu::hasStencilComponent(src.getFormat().order))
1364 		{
1365 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1366 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1367 			tcu::copy(dstSubRegion, srcSubRegion);
1368 		}
1369 	}
1370 	else
1371 	{
1372 		const tcu::ConstPixelBufferAccess	srcSubRegion		= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1373 		// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1374 		const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1375 		const tcu::PixelBufferAccess		dstSubRegion		= tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1376 
1377 		tcu::copy(dstSubRegion, srcSubRegion);
1378 	}
1379 }
1380 
1381 class CopyImageToImageTestCase : public vkt::TestCase
1382 {
1383 public:
CopyImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1384 							CopyImageToImageTestCase	(tcu::TestContext&				testCtx,
1385 														 const std::string&				name,
1386 														 const std::string&				description,
1387 														 const TestParams				params)
1388 								: vkt::TestCase	(testCtx, name, description)
1389 								, m_params		(params)
1390 	{}
1391 
createInstance(Context & context) const1392 	virtual TestInstance*	createInstance				(Context&						context) const
1393 	{
1394 		return new CopyImageToImage(context, m_params);
1395 	}
1396 
checkSupport(Context & context) const1397 	virtual void			checkSupport				(Context&						context) const
1398 	{
1399 		if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1400 		{
1401 			if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1402 				TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1403 		}
1404 
1405 		if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1406 		{
1407 			if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1408 				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1409 		}
1410 
1411 		if (m_params.separateDepthStencilLayouts)
1412 			if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1413 				TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1414 
1415 		if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1416 			(m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1417 		{
1418 			if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1419 				TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1420 		}
1421 
1422 		const VkPhysicalDeviceLimits	limits		= context.getDeviceProperties().limits;
1423 		VkImageFormatProperties			properties;
1424 
1425 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1426 																					m_params.src.image.format,
1427 																					m_params.src.image.imageType,
1428 																					VK_IMAGE_TILING_OPTIMAL,
1429 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1430 																					0,
1431 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1432 			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1433 																					m_params.dst.image.format,
1434 																					m_params.dst.image.imageType,
1435 																					VK_IMAGE_TILING_OPTIMAL,
1436 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1437 																					0,
1438 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1439 		{
1440 			TCU_THROW(NotSupportedError, "Format not supported");
1441 		}
1442 
1443 		// Check maxImageDimension1D
1444 		{
1445 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1446 				TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1447 
1448 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1449 				TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1450 		}
1451 
1452 		// Check maxImageDimension2D
1453 		{
1454 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1455 				|| m_params.src.image.extent.height > limits.maxImageDimension2D))
1456 			{
1457 				TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1458 			}
1459 
1460 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1461 				|| m_params.dst.image.extent.height > limits.maxImageDimension2D))
1462 			{
1463 				TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1464 			}
1465 		}
1466 
1467 		// Check maxImageDimension3D
1468 		{
1469 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1470 				|| m_params.src.image.extent.height > limits.maxImageDimension3D
1471 				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
1472 			{
1473 				TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1474 			}
1475 
1476 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1477 				|| m_params.dst.image.extent.height > limits.maxImageDimension3D
1478 				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
1479 			{
1480 				TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1481 			}
1482 		}
1483 	}
1484 
1485 private:
1486 	TestParams				m_params;
1487 };
1488 
1489 class CopyImageToImageMipmap : public CopiesAndBlittingTestInstance
1490 {
1491 public:
1492 										CopyImageToImageMipmap		(Context&	context,
1493 																	 TestParams params);
1494 	virtual tcu::TestStatus				iterate						(void);
1495 
1496 protected:
1497 	tcu::TestStatus						checkResult					(tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected);
1498 
1499 private:
1500 	Move<VkImage>						m_source;
1501 	de::MovePtr<Allocation>				m_sourceImageAlloc;
1502 	Move<VkImage>						m_destination;
1503 	de::MovePtr<Allocation>				m_destinationImageAlloc;
1504 
1505 	virtual void						copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1506 
1507 };
1508 
CopyImageToImageMipmap(Context & context,TestParams params)1509 CopyImageToImageMipmap::CopyImageToImageMipmap (Context& context, TestParams params)
1510 	: CopiesAndBlittingTestInstance(context, params)
1511 {
1512 	const InstanceInterface&	vki					= context.getInstanceInterface();
1513 	const DeviceInterface&		vk					= context.getDeviceInterface();
1514 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
1515 	const VkDevice				vkDevice			= m_device;
1516 	Allocator&					memAlloc			= context.getDefaultAllocator();
1517 
1518 	// Create source image
1519 	{
1520 		const VkImageCreateInfo	sourceImageParams		=
1521 		{
1522 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1523 			DE_NULL,								// const void*			pNext;
1524 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
1525 			m_params.src.image.imageType,			// VkImageType			imageType;
1526 			m_params.src.image.format,				// VkFormat				format;
1527 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
1528 			params.mipLevels,						// deUint32				mipLevels;
1529 			getArraySize(m_params.src.image),		// deUint32				arraySize;
1530 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1531 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1532 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1533 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1534 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1535 			0u,										// deUint32				queueFamilyIndexCount;
1536 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
1537 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1538 		};
1539 
1540 		m_source				= createImage(vk, vkDevice, &sourceImageParams);
1541 		m_sourceImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1542 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1543 	}
1544 
1545 	// Create destination image
1546 	{
1547 		const VkImageCreateInfo	destinationImageParams	=
1548 		{
1549 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
1550 			DE_NULL,								// const void*			pNext;
1551 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
1552 			m_params.dst.image.imageType,			// VkImageType			imageType;
1553 			m_params.dst.image.format,				// VkFormat				format;
1554 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
1555 			params.mipLevels,						// deUint32				mipLevels;
1556 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
1557 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
1558 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
1559 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1560 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
1561 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1562 			0u,										// deUint32				queueFamilyIndexCount;
1563 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
1564 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
1565 		};
1566 
1567 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
1568 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
1569 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1570 	}
1571 }
1572 
iterate(void)1573 tcu::TestStatus CopyImageToImageMipmap::iterate (void)
1574 {
1575 	const bool					srcCompressed		= isCompressedFormat(m_params.src.image.format);
1576 	const bool					dstCompressed		= isCompressedFormat(m_params.dst.image.format);
1577 
1578 	const tcu::TextureFormat	srcTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1579 	const tcu::TextureFormat	dstTcuFormat		= getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1580 
1581 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1582 																				(int)m_params.src.image.extent.width,
1583 																				(int)m_params.src.image.extent.height,
1584 																				(int)m_params.src.image.extent.depth));
1585 	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);
1586 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image, m_params.mipLevels);
1587 
1588 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1589 																					 (int)m_params.dst.image.extent.width,
1590 																					 (int)m_params.dst.image.extent.height,
1591 																					 (int)m_params.dst.image.extent.depth));
1592 	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);
1593 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
1594 
1595 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
1596 	const VkDevice				vkDevice			= m_device;
1597 	const VkQueue				queue				= m_queue;
1598 
1599 	std::vector<VkImageCopy>		imageCopies;
1600 	std::vector<VkImageCopy2KHR>	imageCopies2KHR;
1601 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
1602 	{
1603 		VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1604 
1605 		// When copying between compressed and uncompressed formats the extent
1606 		// members represent the texel dimensions of the source image.
1607 		if (srcCompressed)
1608 		{
1609 			const deUint32	blockWidth	= getBlockWidth(m_params.src.image.format);
1610 			const deUint32	blockHeight	= getBlockHeight(m_params.src.image.format);
1611 
1612 			imageCopy.srcOffset.x *= blockWidth;
1613 			imageCopy.srcOffset.y *= blockHeight;
1614 			imageCopy.extent.width *= blockWidth;
1615 			imageCopy.extent.height *= blockHeight;
1616 		}
1617 
1618 		if (dstCompressed)
1619 		{
1620 			const deUint32	blockWidth	= getBlockWidth(m_params.dst.image.format);
1621 			const deUint32	blockHeight	= getBlockHeight(m_params.dst.image.format);
1622 
1623 			imageCopy.dstOffset.x *= blockWidth;
1624 			imageCopy.dstOffset.y *= blockHeight;
1625 		}
1626 
1627 		if (m_params.extensionUse == EXTENSION_USE_NONE)
1628 		{
1629 			imageCopies.push_back(imageCopy);
1630 		}
1631 		else
1632 		{
1633 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1634 			imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1635 		}
1636 	}
1637 
1638 	VkImageMemoryBarrier	imageBarriers[]		=
1639 	{
1640 		// source image
1641 		{
1642 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1643 			DE_NULL,									// const void*				pNext;
1644 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1645 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
1646 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1647 			m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
1648 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1649 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1650 			m_source.get(),								// VkImage					image;
1651 			{											// VkImageSubresourceRange	subresourceRange;
1652 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
1653 				0u,								// deUint32				baseMipLevel;
1654 				m_params.mipLevels,				// deUint32				mipLevels;
1655 				0u,								// deUint32				baseArraySlice;
1656 				getArraySize(m_params.src.image)// deUint32				arraySize;
1657 			}
1658 		},
1659 		// destination image
1660 		{
1661 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1662 			DE_NULL,									// const void*				pNext;
1663 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
1664 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
1665 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
1666 			m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
1667 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
1668 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
1669 			m_destination.get(),						// VkImage					image;
1670 			{											// VkImageSubresourceRange	subresourceRange;
1671 				getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask;
1672 				0u,								// deUint32				baseMipLevel;
1673 				m_params.mipLevels,				// deUint32				mipLevels;
1674 				0u,								// deUint32				baseArraySlice;
1675 				getArraySize(m_params.dst.image)// deUint32				arraySize;
1676 			}
1677 		},
1678 	};
1679 
1680 	beginCommandBuffer(vk, *m_cmdBuffer);
1681 	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);
1682 
1683 	if (m_params.extensionUse == EXTENSION_USE_NONE)
1684 	{
1685 		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());
1686 	}
1687 #ifndef CTS_USES_VULKANSC
1688 	else
1689 	{
1690 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1691 		const VkCopyImageInfo2KHR copyImageInfo2KHR =
1692 		{
1693 			VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
1694 			DE_NULL,									// const void*				pNext;
1695 			m_source.get(),								// VkImage					srcImage;
1696 			m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
1697 			m_destination.get(),						// VkImage					dstImage;
1698 			m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
1699 			(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
1700 			imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
1701 		};
1702 
1703 		vk.cmdCopyImage2(*m_cmdBuffer, &copyImageInfo2KHR);
1704 	}
1705 #endif // CTS_USES_VULKANSC
1706 
1707 	endCommandBuffer(vk, *m_cmdBuffer);
1708 
1709 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1710 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
1711 
1712 	for (deUint32 miplevel = 0; miplevel < m_params.mipLevels; miplevel++)
1713 	{
1714 		de::MovePtr<tcu::TextureLevel>	resultTextureLevel		= readImage(*m_destination, m_params.dst.image, miplevel);
1715 		de::MovePtr<tcu::TextureLevel>	expectedTextureLevel	= readImage(*m_source, m_params.src.image, miplevel);
1716 
1717 		tcu::TestStatus result = checkResult(resultTextureLevel->getAccess(), expectedTextureLevel->getAccess());
1718 		if (result.getCode() != QP_TEST_RESULT_PASS)
1719 			return result;
1720 	}
1721 	return tcu::TestStatus::pass("Pass");
1722 }
1723 
checkResult(tcu::ConstPixelBufferAccess result,tcu::ConstPixelBufferAccess expected)1724 tcu::TestStatus CopyImageToImageMipmap::checkResult (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected)
1725 {
1726 	const tcu::Vec4	fThreshold (0.0f);
1727 	const tcu::UVec4 uThreshold (0u);
1728 
1729 	if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1730 	{
1731 		if (tcu::hasDepthComponent(result.getFormat().order))
1732 		{
1733 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
1734 			const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
1735 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(expected, mode);
1736 
1737 			if (isFloatFormat(result.getFormat()))
1738 			{
1739 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1740 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1741 			}
1742 			else
1743 			{
1744 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1745 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1746 			}
1747 		}
1748 
1749 		if (tcu::hasStencilComponent(result.getFormat().order))
1750 		{
1751 			const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
1752 			const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
1753 			const tcu::ConstPixelBufferAccess		expectedResult		= tcu::getEffectiveDepthStencilAccess(expected, mode);
1754 
1755 			if (isFloatFormat(result.getFormat()))
1756 			{
1757 				if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1758 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1759 			}
1760 			else
1761 			{
1762 				if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1763 					return tcu::TestStatus::fail("CopiesAndBlitting test");
1764 			}
1765 		}
1766 	}
1767 	else
1768 	{
1769 		if (isFloatFormat(result.getFormat()))
1770 		{
1771 			if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, fThreshold, tcu::COMPARE_LOG_RESULT))
1772 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1773 		}
1774 		else if (isSnormFormat(mapTextureFormat(result.getFormat())))
1775 		{
1776 			// There may be an ambiguity between two possible binary representations of 1.0.
1777 			// Get rid of that by expanding the data to floats and re-normalizing again.
1778 
1779 			tcu::TextureLevel resultSnorm	(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
1780 			{
1781 				tcu::TextureLevel resultFloat	(tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
1782 
1783 				tcu::copy(resultFloat.getAccess(), result);
1784 				tcu::copy(resultSnorm, resultFloat.getAccess());
1785 			}
1786 
1787 			tcu::TextureLevel expectedSnorm	(expected.getFormat(), expected.getWidth(), expected.getHeight(), expected.getDepth());
1788 
1789 			{
1790 				tcu::TextureLevel expectedFloat	(tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
1791 
1792 				tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess());
1793 				tcu::copy(expectedSnorm, expectedFloat.getAccess());
1794 			}
1795 
1796 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT))
1797 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1798 		}
1799 		else
1800 		{
1801 			if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, uThreshold, tcu::COMPARE_LOG_RESULT))
1802 				return tcu::TestStatus::fail("CopiesAndBlitting test");
1803 		}
1804 	}
1805 
1806 	return tcu::TestStatus::pass("CopiesAndBlitting test");
1807 }
1808 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1809 void CopyImageToImageMipmap::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1810 {
1811 	DE_UNREF(mipLevel);
1812 
1813 	VkOffset3D	srcOffset	= region.imageCopy.srcOffset;
1814 	VkOffset3D	dstOffset	= region.imageCopy.dstOffset;
1815 	VkExtent3D	extent		= region.imageCopy.extent;
1816 
1817 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1818 	{
1819 		dstOffset.z = srcOffset.z;
1820 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1821 	}
1822 	if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1823 	{
1824 		srcOffset.z = dstOffset.z;
1825 		extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1826 	}
1827 
1828 
1829 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1830 	{
1831 		DE_ASSERT(src.getFormat() == dst.getFormat());
1832 
1833 		// Copy depth.
1834 		if (tcu::hasDepthComponent(src.getFormat().order))
1835 		{
1836 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1837 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1838 			tcu::copy(dstSubRegion, srcSubRegion);
1839 		}
1840 
1841 		// Copy stencil.
1842 		if (tcu::hasStencilComponent(src.getFormat().order))
1843 		{
1844 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1845 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1846 			tcu::copy(dstSubRegion, srcSubRegion);
1847 		}
1848 	}
1849 	else
1850 	{
1851 		const tcu::ConstPixelBufferAccess	srcSubRegion		= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1852 		// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1853 		const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1854 		const tcu::PixelBufferAccess		dstSubRegion		= tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1855 
1856 		tcu::copy(dstSubRegion, srcSubRegion);
1857 	}
1858 }
1859 
1860 class CopyImageToImageMipmapTestCase : public vkt::TestCase
1861 {
1862 public:
CopyImageToImageMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1863 							CopyImageToImageMipmapTestCase	(tcu::TestContext&				testCtx,
1864 															 const std::string&				name,
1865 															 const std::string&				description,
1866 															 const TestParams				params)
1867 								: vkt::TestCase	(testCtx, name, description)
1868 								, m_params		(params)
1869 	{}
1870 
createInstance(Context & context) const1871 	virtual TestInstance*	createInstance				(Context&						context) const
1872 	{
1873 		return new CopyImageToImageMipmap(context, m_params);
1874 	}
1875 
checkSupport(Context & context) const1876 	virtual void			checkSupport				(Context&						context) const
1877 	{
1878 		if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1879 		{
1880 			if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1881 				TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1882 		}
1883 
1884 		if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1885 		{
1886 			if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1887 				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1888 		}
1889 
1890 		if (m_params.separateDepthStencilLayouts)
1891 			if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1892 				TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1893 
1894 		if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1895 			(m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1896 		{
1897 			if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1898 				TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1899 		}
1900 
1901 		const VkPhysicalDeviceLimits	limits		= context.getDeviceProperties().limits;
1902 		VkImageFormatProperties			properties;
1903 
1904 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1905 																					m_params.src.image.format,
1906 																					m_params.src.image.imageType,
1907 																					VK_IMAGE_TILING_OPTIMAL,
1908 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1909 																					0,
1910 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1911 			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1912 																					m_params.dst.image.format,
1913 																					m_params.dst.image.imageType,
1914 																					VK_IMAGE_TILING_OPTIMAL,
1915 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1916 																					0,
1917 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1918 		{
1919 			TCU_THROW(NotSupportedError, "Format not supported");
1920 		}
1921 
1922 		// Check maxImageDimension1D
1923 		{
1924 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1925 				TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1926 
1927 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1928 				TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1929 		}
1930 
1931 		// Check maxImageDimension2D
1932 		{
1933 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1934 				|| m_params.src.image.extent.height > limits.maxImageDimension2D))
1935 			{
1936 				TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1937 			}
1938 
1939 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1940 				|| m_params.dst.image.extent.height > limits.maxImageDimension2D))
1941 			{
1942 				TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1943 			}
1944 		}
1945 
1946 		// Check maxImageDimension3D
1947 		{
1948 			if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1949 				|| m_params.src.image.extent.height > limits.maxImageDimension3D
1950 				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
1951 			{
1952 				TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1953 			}
1954 
1955 			if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1956 				|| m_params.dst.image.extent.height > limits.maxImageDimension3D
1957 				|| m_params.src.image.extent.depth > limits.maxImageDimension3D))
1958 			{
1959 				TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1960 			}
1961 		}
1962 	}
1963 
1964 private:
1965 	TestParams				m_params;
1966 };
1967 
1968 // Copy from buffer to buffer.
1969 
1970 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
1971 {
1972 public:
1973 								CopyBufferToBuffer			(Context& context, TestParams params);
1974 	virtual tcu::TestStatus		iterate						(void);
1975 private:
1976 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion, deUint32 mipLevel = 0u);
1977 	Move<VkBuffer>				m_source;
1978 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
1979 	Move<VkBuffer>				m_destination;
1980 	de::MovePtr<Allocation>		m_destinationBufferAlloc;
1981 };
1982 
CopyBufferToBuffer(Context & context,TestParams params)1983 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
1984 	: CopiesAndBlittingTestInstance	(context, params)
1985 {
1986 	const InstanceInterface&	vki					= context.getInstanceInterface();
1987 	const DeviceInterface&		vk					= context.getDeviceInterface();
1988 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
1989 	const VkDevice				vkDevice			= m_device;
1990 	Allocator&					memAlloc			= context.getDefaultAllocator();
1991 
1992 	// Create source buffer
1993 	{
1994 		const VkBufferCreateInfo	sourceBufferParams		=
1995 		{
1996 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1997 			DE_NULL,									// const void*			pNext;
1998 			0u,											// VkBufferCreateFlags	flags;
1999 			m_params.src.buffer.size,					// VkDeviceSize			size;
2000 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
2001 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2002 			0u,											// deUint32				queueFamilyIndexCount;
2003 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
2004 		};
2005 
2006 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
2007 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2008 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2009 	}
2010 
2011 	// Create destination buffer
2012 	{
2013 		const VkBufferCreateInfo	destinationBufferParams	=
2014 		{
2015 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2016 			DE_NULL,									// const void*			pNext;
2017 			0u,											// VkBufferCreateFlags	flags;
2018 			m_params.dst.buffer.size,					// VkDeviceSize			size;
2019 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
2020 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2021 			0u,											// deUint32				queueFamilyIndexCount;
2022 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
2023 		};
2024 
2025 		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
2026 		m_destinationBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2027 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2028 	}
2029 }
2030 
iterate(void)2031 tcu::TestStatus CopyBufferToBuffer::iterate (void)
2032 {
2033 	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
2034 	m_sourceTextureLevel		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
2035 	generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
2036 
2037 	const int dstLevelWidth		= (int)(m_params.dst.buffer.size/4);
2038 	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2039 	generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_BLACK);
2040 
2041 	generateExpectedResult();
2042 
2043 	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2044 	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2045 
2046 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
2047 	const VkDevice				vkDevice	= m_device;
2048 	const VkQueue				queue		= m_queue;
2049 
2050 	const VkBufferMemoryBarrier		srcBufferBarrier	=
2051 	{
2052 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2053 		DE_NULL,									// const void*		pNext;
2054 		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
2055 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
2056 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
2057 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
2058 		*m_source,									// VkBuffer			buffer;
2059 		0u,											// VkDeviceSize		offset;
2060 		m_params.src.buffer.size					// VkDeviceSize		size;
2061 	};
2062 
2063 	const VkBufferMemoryBarrier		dstBufferBarrier	=
2064 	{
2065 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2066 		DE_NULL,									// const void*		pNext;
2067 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
2068 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
2069 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
2070 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
2071 		*m_destination,								// VkBuffer			buffer;
2072 		0u,											// VkDeviceSize		offset;
2073 		m_params.dst.buffer.size					// VkDeviceSize		size;
2074 	};
2075 
2076 	std::vector<VkBufferCopy>		bufferCopies;
2077 	std::vector<VkBufferCopy2KHR>	bufferCopies2KHR;
2078 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2079 	{
2080 		if (m_params.extensionUse == EXTENSION_USE_NONE)
2081 		{
2082 			bufferCopies.push_back(m_params.regions[i].bufferCopy);
2083 		}
2084 		else
2085 		{
2086 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2087 			bufferCopies2KHR.push_back(convertvkBufferCopyTovkBufferCopy2KHR(m_params.regions[i].bufferCopy));
2088 		}
2089 	}
2090 
2091 	beginCommandBuffer(vk, *m_cmdBuffer);
2092 	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);
2093 
2094 	if (m_params.extensionUse == EXTENSION_USE_NONE)
2095 	{
2096 		vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
2097 	}
2098 #ifndef CTS_USES_VULKANSC
2099 	else
2100 	{
2101 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2102 		const VkCopyBufferInfo2KHR copyBufferInfo2KHR =
2103 		{
2104 			VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR,	// VkStructureType			sType;
2105 			DE_NULL,									// const void*				pNext;
2106 			m_source.get(),								// VkBuffer					srcBuffer;
2107 			m_destination.get(),						// VkBuffer					dstBuffer;
2108 			(deUint32)m_params.regions.size(),			// uint32_t					regionCount;
2109 			&bufferCopies2KHR[0]						// const VkBufferCopy2KHR*	pRegions;
2110 		};
2111 
2112 		vk.cmdCopyBuffer2(*m_cmdBuffer, &copyBufferInfo2KHR);
2113 	}
2114 #endif // CTS_USES_VULKANSC
2115 
2116 	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);
2117 	endCommandBuffer(vk, *m_cmdBuffer);
2118 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2119 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2120 
2121 	// Read buffer data
2122 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2123 	invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2124 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2125 
2126 	return checkTestResult(resultLevel->getAccess());
2127 }
2128 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2129 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2130 {
2131 	DE_UNREF(mipLevel);
2132 
2133 	deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
2134 			 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
2135 			 (size_t)region.bufferCopy.size);
2136 }
2137 
2138 class BufferToBufferTestCase : public vkt::TestCase
2139 {
2140 public:
BufferToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2141 							BufferToBufferTestCase	(tcu::TestContext&	testCtx,
2142 													 const std::string&	name,
2143 													 const std::string&	description,
2144 													 const TestParams	params)
2145 								: vkt::TestCase	(testCtx, name, description)
2146 								, m_params		(params)
2147 							{}
2148 
createInstance(Context & context) const2149 	virtual TestInstance*	createInstance			(Context& context) const
2150 							{
2151 								return new CopyBufferToBuffer(context, m_params);
2152 							}
2153 
checkSupport(Context & context) const2154 	virtual void			checkSupport(Context&	context) const
2155 	{
2156 							if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
2157 							{
2158 								if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
2159 								{
2160 									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2161 								}
2162 							}
2163 	}
2164 
2165 	private:
2166 	TestParams				m_params;
2167 };
2168 
2169 // Copy from image to buffer.
2170 
2171 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
2172 {
2173 public:
2174 								CopyImageToBuffer			(Context&	context,
2175 															 TestParams	testParams);
2176 	virtual tcu::TestStatus		iterate						(void);
2177 private:
2178 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2179 
2180 	tcu::TextureFormat			m_textureFormat;
2181 	VkDeviceSize				m_bufferSize;
2182 
2183 	Move<VkImage>				m_source;
2184 	de::MovePtr<Allocation>		m_sourceImageAlloc;
2185 	Move<VkBuffer>				m_destination;
2186 	de::MovePtr<Allocation>		m_destinationBufferAlloc;
2187 };
2188 
CopyImageToBuffer(Context & context,TestParams testParams)2189 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
2190 	: CopiesAndBlittingTestInstance(context, testParams)
2191 	, m_textureFormat(mapVkFormat(testParams.src.image.format))
2192 	, m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
2193 {
2194 	const InstanceInterface&	vki					= context.getInstanceInterface();
2195 	const DeviceInterface&		vk					= context.getDeviceInterface();
2196 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
2197 	const VkDevice				vkDevice			= m_device;
2198 	Allocator&					memAlloc			= context.getDefaultAllocator();
2199 
2200 	// Create source image
2201 	{
2202 		const VkImageCreateInfo		sourceImageParams		=
2203 		{
2204 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
2205 			DE_NULL,								// const void*			pNext;
2206 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
2207 			m_params.src.image.imageType,			// VkImageType			imageType;
2208 			m_params.src.image.format,				// VkFormat				format;
2209 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
2210 			1u,										// deUint32				mipLevels;
2211 			getArraySize(m_params.src.image),		// deUint32				arraySize;
2212 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
2213 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
2214 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2215 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
2216 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2217 			0u,										// deUint32				queueFamilyIndexCount;
2218 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
2219 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
2220 		};
2221 
2222 		m_source			= createImage(vk, vkDevice, &sourceImageParams);
2223 		m_sourceImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
2224 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
2225 	}
2226 
2227 	// Create destination buffer
2228 	{
2229 		const VkBufferCreateInfo	destinationBufferParams	=
2230 		{
2231 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2232 			DE_NULL,									// const void*			pNext;
2233 			0u,											// VkBufferCreateFlags	flags;
2234 			m_bufferSize,								// VkDeviceSize			size;
2235 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// VkBufferUsageFlags	usage;
2236 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2237 			0u,											// deUint32				queueFamilyIndexCount;
2238 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
2239 		};
2240 
2241 		m_destination				= createBuffer(vk, vkDevice, &destinationBufferParams);
2242 		m_destinationBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2243 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2244 	}
2245 }
2246 
iterate(void)2247 tcu::TestStatus CopyImageToBuffer::iterate (void)
2248 {
2249 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2250 																				m_params.src.image.extent.width,
2251 																				m_params.src.image.extent.height,
2252 																				m_params.src.image.extent.depth));
2253 	generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
2254 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2255 	generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
2256 
2257 	generateExpectedResult();
2258 
2259 	uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
2260 	uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2261 
2262 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
2263 	const VkDevice				vkDevice	= m_device;
2264 	const VkQueue				queue		= m_queue;
2265 
2266 	// Barriers for copying image to buffer
2267 	const VkImageMemoryBarrier		imageBarrier		=
2268 	{
2269 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2270 		DE_NULL,									// const void*				pNext;
2271 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2272 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
2273 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
2274 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		// VkImageLayout			newLayout;
2275 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2276 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2277 		*m_source,									// VkImage					image;
2278 		{											// VkImageSubresourceRange	subresourceRange;
2279 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
2280 			0u,									// deUint32				baseMipLevel;
2281 			1u,									// deUint32				mipLevels;
2282 			0u,									// deUint32				baseArraySlice;
2283 			getArraySize(m_params.src.image)	// deUint32				arraySize;
2284 		}
2285 	};
2286 
2287 	const VkBufferMemoryBarrier		bufferBarrier		=
2288 	{
2289 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
2290 		DE_NULL,									// const void*		pNext;
2291 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
2292 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
2293 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
2294 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
2295 		*m_destination,								// VkBuffer			buffer;
2296 		0u,											// VkDeviceSize		offset;
2297 		m_bufferSize								// VkDeviceSize		size;
2298 	};
2299 
2300 	// Copy from image to buffer
2301 	std::vector<VkBufferImageCopy>		bufferImageCopies;
2302 	std::vector<VkBufferImageCopy2KHR>	bufferImageCopies2KHR;
2303 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2304 	{
2305 		if (m_params.extensionUse == EXTENSION_USE_NONE)
2306 		{
2307 			bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2308 		}
2309 		else
2310 		{
2311 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2312 			bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2313 		}
2314 	}
2315 
2316 	beginCommandBuffer(vk, *m_cmdBuffer);
2317 	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);
2318 
2319 	if (m_params.extensionUse == EXTENSION_USE_NONE)
2320 	{
2321 		vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
2322 	}
2323 #ifndef CTS_USES_VULKANSC
2324 	else
2325 	{
2326 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2327 		const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR =
2328 		{
2329 			VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR,	// VkStructureType				sType;
2330 			DE_NULL,											// const void*					pNext;
2331 			m_source.get(),										// VkImage						srcImage;
2332 			VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,				// VkImageLayout				srcImageLayout;
2333 			m_destination.get(),								// VkBuffer						dstBuffer;
2334 			(deUint32)m_params.regions.size(),					// uint32_t						regionCount;
2335 			&bufferImageCopies2KHR[0]							// const VkBufferImageCopy2KHR*	pRegions;
2336 		};
2337 
2338 		vk.cmdCopyImageToBuffer2(*m_cmdBuffer, &copyImageToBufferInfo2KHR);
2339 	}
2340 #endif // CTS_USES_VULKANSC
2341 
2342 	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);
2343 	endCommandBuffer(vk, *m_cmdBuffer);
2344 
2345 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2346 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2347 
2348 	// Read buffer data
2349 	de::MovePtr<tcu::TextureLevel>	resultLevel		(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2350 	invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2351 	tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2352 
2353 	return checkTestResult(resultLevel->getAccess());
2354 }
2355 
2356 class CopyImageToBufferTestCase : public vkt::TestCase
2357 {
2358 public:
CopyImageToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2359 							CopyImageToBufferTestCase	(tcu::TestContext&		testCtx,
2360 														 const std::string&		name,
2361 														 const std::string&		description,
2362 														 const TestParams		params)
2363 								: vkt::TestCase	(testCtx, name, description)
2364 								, m_params		(params)
2365 							{}
2366 
createInstance(Context & context) const2367 	virtual TestInstance*	createInstance				(Context&				context) const
2368 							{
2369 								return new CopyImageToBuffer(context, m_params);
2370 							}
2371 
checkSupport(Context & context) const2372 	virtual void			checkSupport				(Context&				context) const
2373 							{
2374 								if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2375 									(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2376 								{
2377 									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2378 								}
2379 							}
2380 
2381 private:
2382 	TestParams				m_params;
2383 };
2384 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2385 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2386 {
2387 	DE_UNREF(mipLevel);
2388 
2389 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
2390 	if (!rowLength)
2391 		rowLength = region.bufferImageCopy.imageExtent.width;
2392 
2393 	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
2394 	if (!imageHeight)
2395 		imageHeight = region.bufferImageCopy.imageExtent.height;
2396 
2397 	const int			texelSize		= src.getFormat().getPixelSize();
2398 	const VkExtent3D	extent			= region.bufferImageCopy.imageExtent;
2399 	const VkOffset3D	srcOffset		= region.bufferImageCopy.imageOffset;
2400 	const int			texelOffset		= (int) region.bufferImageCopy.bufferOffset / texelSize;
2401 	const deUint32		baseArrayLayer	= region.bufferImageCopy.imageSubresource.baseArrayLayer;
2402 
2403 	for (deUint32 z = 0; z < extent.depth; z++)
2404 	{
2405 		for (deUint32 y = 0; y < extent.height; y++)
2406 		{
2407 			int									texelIndex		= texelOffset + (z * imageHeight + y) *	rowLength;
2408 			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z + baseArrayLayer,
2409 																					region.bufferImageCopy.imageExtent.width, 1, 1);
2410 			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2411 			tcu::copy(dstSubRegion, srcSubRegion);
2412 		}
2413 	}
2414 }
2415 
2416 // Copy from buffer to image.
2417 
2418 class CopyBufferToImage : public CopiesAndBlittingTestInstance
2419 {
2420 public:
2421 								CopyBufferToImage			(Context&	context,
2422 															 TestParams	testParams);
2423 	virtual tcu::TestStatus		iterate						(void);
2424 
2425 private:
2426 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2427 
2428 	tcu::TextureFormat			m_textureFormat;
2429 	VkDeviceSize				m_bufferSize;
2430 
2431 	Move<VkBuffer>				m_source;
2432 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
2433 	Move<VkImage>				m_destination;
2434 	de::MovePtr<Allocation>		m_destinationImageAlloc;
2435 };
2436 
CopyBufferToImage(Context & context,TestParams testParams)2437 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
2438 	: CopiesAndBlittingTestInstance(context, testParams)
2439 	, m_textureFormat(mapVkFormat(testParams.dst.image.format))
2440 	, m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
2441 {
2442 	const InstanceInterface&	vki					= context.getInstanceInterface();
2443 	const DeviceInterface&		vk					= context.getDeviceInterface();
2444 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
2445 	const VkDevice				vkDevice			= m_device;
2446 	Allocator&					memAlloc			= context.getDefaultAllocator();
2447 
2448 	// Create source buffer
2449 	{
2450 		const VkBufferCreateInfo	sourceBufferParams		=
2451 		{
2452 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2453 			DE_NULL,									// const void*			pNext;
2454 			0u,											// VkBufferCreateFlags	flags;
2455 			m_bufferSize,								// VkDeviceSize			size;
2456 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
2457 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2458 			0u,											// deUint32				queueFamilyIndexCount;
2459 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
2460 		};
2461 
2462 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
2463 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2464 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2465 	}
2466 
2467 	// Create destination image
2468 	{
2469 		const VkImageCreateInfo		destinationImageParams	=
2470 		{
2471 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
2472 			DE_NULL,								// const void*			pNext;
2473 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
2474 			m_params.dst.image.imageType,			// VkImageType			imageType;
2475 			m_params.dst.image.format,				// VkFormat				format;
2476 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
2477 			1u,										// deUint32				mipLevels;
2478 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
2479 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
2480 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
2481 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2482 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
2483 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2484 			0u,										// deUint32				queueFamilyIndexCount;
2485 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
2486 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
2487 		};
2488 
2489 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
2490 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
2491 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2492 	}
2493 }
2494 
iterate(void)2495 tcu::TestStatus CopyBufferToImage::iterate (void)
2496 {
2497 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2498 	generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2499 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2500 																					m_params.dst.image.extent.width,
2501 																					m_params.dst.image.extent.height,
2502 																					m_params.dst.image.extent.depth));
2503 
2504 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2505 
2506 	generateExpectedResult();
2507 
2508 	uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2509 	uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2510 
2511 	const DeviceInterface&		vk			= m_context.getDeviceInterface();
2512 	const VkDevice				vkDevice	= m_device;
2513 	const VkQueue				queue		= m_queue;
2514 
2515 	const VkImageMemoryBarrier	imageBarrier	=
2516 	{
2517 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2518 		DE_NULL,									// const void*				pNext;
2519 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2520 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
2521 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
2522 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
2523 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2524 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2525 		*m_destination,								// VkImage					image;
2526 		{											// VkImageSubresourceRange	subresourceRange;
2527 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
2528 			0u,								// deUint32				baseMipLevel;
2529 			1u,								// deUint32				mipLevels;
2530 			0u,								// deUint32				baseArraySlice;
2531 			getArraySize(m_params.dst.image)								// deUint32				arraySize;
2532 		}
2533 	};
2534 
2535 	// Copy from buffer to image
2536 	std::vector<VkBufferImageCopy>		bufferImageCopies;
2537 	std::vector<VkBufferImageCopy2KHR>	bufferImageCopies2KHR;
2538 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2539 	{
2540 		if (m_params.extensionUse == EXTENSION_USE_NONE)
2541 		{
2542 			bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2543 		}
2544 		else
2545 		{
2546 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2547 			bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2548 		}
2549 	}
2550 
2551 	beginCommandBuffer(vk, *m_cmdBuffer);
2552 	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);
2553 
2554 	if (m_params.extensionUse == EXTENSION_USE_NONE)
2555 	{
2556 		vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2557 	}
2558 #ifndef CTS_USES_VULKANSC
2559 	else
2560 	{
2561 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2562 		const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2563 		{
2564 			VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
2565 			DE_NULL,											// const void*					pNext;
2566 			m_source.get(),										// VkBuffer						srcBuffer;
2567 			m_destination.get(),								// VkImage						dstImage;
2568 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout				dstImageLayout;
2569 			(deUint32)m_params.regions.size(),					// uint32_t						regionCount;
2570 			bufferImageCopies2KHR.data()						// const VkBufferImageCopy2KHR*	pRegions;
2571 		};
2572 
2573 		vk.cmdCopyBufferToImage2(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2574 	}
2575 #endif // CTS_USES_VULKANSC
2576 
2577 	endCommandBuffer(vk, *m_cmdBuffer);
2578 
2579 	submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2580 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2581 
2582 	de::MovePtr<tcu::TextureLevel>	resultLevel	= readImage(*m_destination, m_params.dst.image);
2583 
2584 	return checkTestResult(resultLevel->getAccess());
2585 }
2586 
2587 class CopyBufferToImageTestCase : public vkt::TestCase
2588 {
2589 public:
CopyBufferToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2590 							CopyBufferToImageTestCase	(tcu::TestContext&		testCtx,
2591 														 const std::string&		name,
2592 														 const std::string&		description,
2593 														 const TestParams		params)
2594 								: vkt::TestCase	(testCtx, name, description)
2595 								, m_params		(params)
2596 							{}
2597 
~CopyBufferToImageTestCase(void)2598 	virtual					~CopyBufferToImageTestCase	(void) {}
2599 
createInstance(Context & context) const2600 	virtual TestInstance*	createInstance				(Context&				context) const
2601 							{
2602 								return new CopyBufferToImage(context, m_params);
2603 							}
2604 
checkSupport(Context & context) const2605 	virtual void			checkSupport				(Context&				context) const
2606 							{
2607 								if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2608 									(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2609 								{
2610 									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2611 								}
2612 							}
2613 
2614 
2615 private:
2616 	TestParams				m_params;
2617 };
2618 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2619 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2620 {
2621 	DE_UNREF(mipLevel);
2622 
2623 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
2624 	if (!rowLength)
2625 		rowLength = region.bufferImageCopy.imageExtent.width;
2626 
2627 	deUint32			imageHeight	= region.bufferImageCopy.bufferImageHeight;
2628 	if (!imageHeight)
2629 		imageHeight = region.bufferImageCopy.imageExtent.height;
2630 
2631 	const int			texelSize		= dst.getFormat().getPixelSize();
2632 	const VkExtent3D	extent			= region.bufferImageCopy.imageExtent;
2633 	const VkOffset3D	dstOffset		= region.bufferImageCopy.imageOffset;
2634 	const int			texelOffset		= (int) region.bufferImageCopy.bufferOffset / texelSize;
2635 	const deUint32		baseArrayLayer	= region.bufferImageCopy.imageSubresource.baseArrayLayer;
2636 
2637 	for (deUint32 z = 0; z < extent.depth; z++)
2638 	{
2639 		for (deUint32 y = 0; y < extent.height; y++)
2640 		{
2641 			int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2642 			const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2643 			const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z + baseArrayLayer,
2644 																		  region.bufferImageCopy.imageExtent.width, 1, 1);
2645 			tcu::copy(dstSubRegion, srcSubRegion);
2646 		}
2647 	}
2648 }
2649 
2650 class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
2651 {
2652 public:
2653 								CopyBufferToDepthStencil	(Context& context,
2654 															 TestParams	testParams);
2655 	virtual tcu::TestStatus		iterate						(void);
2656 private:
2657 	virtual void				copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2658 
2659 	tcu::TextureFormat			m_textureFormat;
2660 	VkDeviceSize				m_bufferSize;
2661 
2662 	Move<VkBuffer>				m_source;
2663 	de::MovePtr<Allocation>		m_sourceBufferAlloc;
2664 	Move<VkImage>				m_destination;
2665 	de::MovePtr<Allocation>		m_destinationImageAlloc;
2666 };
2667 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2668 void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2669 {
2670 	DE_UNREF(mipLevel);
2671 
2672 	deUint32			rowLength	= region.bufferImageCopy.bufferRowLength;
2673 	if (!rowLength)
2674 		rowLength = region.bufferImageCopy.imageExtent.width;
2675 
2676 	deUint32			imageHeight = region.bufferImageCopy.bufferImageHeight;
2677 	if (!imageHeight)
2678 		imageHeight = region.bufferImageCopy.imageExtent.height;
2679 
2680 	const int			texelSize	= dst.getFormat().getPixelSize();
2681 	const VkExtent3D	extent		= region.bufferImageCopy.imageExtent;
2682 	const VkOffset3D	dstOffset	= region.bufferImageCopy.imageOffset;
2683 	const int			texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
2684 
2685 	for (deUint32 z = 0; z < extent.depth; z++)
2686 	{
2687 		for (deUint32 y = 0; y < extent.height; y++)
2688 		{
2689 			int									texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2690 			const tcu::ConstPixelBufferAccess	srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2691 			const tcu::PixelBufferAccess		dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
2692 				region.bufferImageCopy.imageExtent.width, 1, 1);
2693 
2694 			if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
2695 			{
2696 				tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH), DE_FALSE);
2697 			}
2698 			else
2699 			{
2700 				tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL), DE_FALSE);
2701 			}
2702 		}
2703 	}
2704 }
2705 
isSupportedDepthStencilFormat(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat format)2706 bool isSupportedDepthStencilFormat(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
2707 {
2708 	VkFormatProperties formatProps;
2709 	vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
2710 	return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
2711 }
2712 
CopyBufferToDepthStencil(Context & context,TestParams testParams)2713 CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context& context, TestParams testParams)
2714 	: CopiesAndBlittingTestInstance(context, testParams)
2715 	, m_textureFormat(mapVkFormat(testParams.dst.image.format))
2716 	, m_bufferSize(0)
2717 {
2718 	const InstanceInterface&	vki					= context.getInstanceInterface();
2719 	const DeviceInterface&		vk					= context.getDeviceInterface();
2720 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
2721 	const VkDevice				vkDevice			= m_device;
2722 	Allocator&					memAlloc			= context.getDefaultAllocator();
2723 	const bool					hasDepth			= tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
2724 	const bool					hasStencil			= tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
2725 
2726 	if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
2727 	{
2728 		TCU_THROW(NotSupportedError, "Image format not supported.");
2729 	}
2730 
2731 	if (hasDepth)
2732 	{
2733 		glw::GLuint texelSize = m_textureFormat.getPixelSize();
2734 		if (texelSize > sizeof(float))
2735 		{
2736 			// We must have D32F_S8 format, depth must be packed so we only need
2737 			// to allocate space for the D32F part. Stencil will be separate
2738 			texelSize = sizeof(float);
2739 		}
2740 		m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height) * static_cast<VkDeviceSize>(texelSize);
2741 	}
2742 	if (hasStencil)
2743 	{
2744 		// Stencil is always 8bits and packed.
2745 		m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
2746 	}
2747 
2748 	// Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
2749 	{
2750 		const VkBufferCreateInfo	sourceBufferParams		=
2751 		{
2752 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
2753 			DE_NULL,									// const void*			pNext;
2754 			0u,											// VkBufferCreateFlags	flags;
2755 			m_bufferSize,								// VkDeviceSize			size;
2756 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
2757 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
2758 			0u,											// deUint32				queueFamilyIndexCount;
2759 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
2760 		};
2761 
2762 		m_source				= createBuffer(vk, vkDevice, &sourceBufferParams);
2763 		m_sourceBufferAlloc		= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2764 		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2765 	}
2766 
2767 	// Create destination image
2768 	{
2769 		const VkImageCreateInfo		destinationImageParams	=
2770 		{
2771 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
2772 			DE_NULL,								// const void*			pNext;
2773 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
2774 			m_params.dst.image.imageType,			// VkImageType			imageType;
2775 			m_params.dst.image.format,				// VkFormat				format;
2776 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
2777 			1u,										// deUint32				mipLevels;
2778 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
2779 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
2780 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
2781 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2782 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
2783 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
2784 			0u,										// deUint32				queueFamilyIndexCount;
2785 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
2786 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
2787 		};
2788 
2789 		m_destination				= createImage(vk, vkDevice, &destinationImageParams);
2790 		m_destinationImageAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
2791 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2792 	}
2793 }
2794 
iterate(void)2795 tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
2796 {
2797 	// Create source depth/stencil content. Treat as 1D texture to get different pattern
2798 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2799 	// Fill buffer with linear gradiant
2800 	generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2801 
2802 	// Create image layer for depth/stencil
2803 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2804 		m_params.dst.image.extent.width,
2805 		m_params.dst.image.extent.height,
2806 		m_params.dst.image.extent.depth));
2807 
2808 	// Fill image layer with 2D gradiant
2809 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2810 
2811 	// Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
2812 	// Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
2813 	// This emulates what the HW will be doing.
2814 	generateExpectedResult();
2815 
2816 	// Upload our source depth/stencil content to the source buffer
2817 	// This is the buffer that will be used by region commands
2818 	std::vector<VkBufferImageCopy>		bufferImageCopies;
2819 	std::vector<VkBufferImageCopy2KHR>	bufferImageCopies2KHR;
2820 	VkDeviceSize					bufferOffset	= 0;
2821 	const VkDevice					vkDevice		= m_device;
2822 	const DeviceInterface&			vk				= m_context.getDeviceInterface();
2823 	const VkQueue					queue			= m_queue;
2824 	char*							dstPtr			= reinterpret_cast<char*>(m_sourceBufferAlloc->getHostPtr());
2825 	bool							depthLoaded		= DE_FALSE;
2826 	bool							stencilLoaded	= DE_FALSE;
2827 	VkDeviceSize					depthOffset		= 0;
2828 	VkDeviceSize					stencilOffset	= 0;
2829 
2830 	// To be able to test ordering depth & stencil differently
2831 	// we take the given copy regions and use that as the desired order
2832 	// and copy the appropriate data into place and compute the appropriate
2833 	// data offsets to be used in the copy command.
2834 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
2835 	{
2836 		tcu::ConstPixelBufferAccess bufferAccess	= m_sourceTextureLevel->getAccess();
2837 		deUint32					bufferSize		= bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
2838 		VkBufferImageCopy			copyData		= m_params.regions[i].bufferImageCopy;
2839 		char*						srcPtr;
2840 
2841 		if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
2842 		{
2843 			// Create level that is same component as depth buffer (e.g. D16, D24, D32F)
2844 			tcu::TextureLevel	depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2845 			bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
2846 			// Copy depth component only from source data. This gives us packed depth-only data.
2847 			tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
2848 			srcPtr = (char*)depthTexture.getAccess().getDataPtr();
2849 			// Copy packed depth-only data to output buffer
2850 			deMemcpy(dstPtr, srcPtr, bufferSize);
2851 			depthLoaded = DE_TRUE;
2852 			depthOffset = bufferOffset;
2853 			dstPtr += bufferSize;
2854 			bufferOffset += bufferSize;
2855 			copyData.bufferOffset += depthOffset;
2856 		}
2857 		else if (!stencilLoaded)
2858 		{
2859 			// Create level that is same component as stencil buffer (always 8-bits)
2860 			tcu::TextureLevel	stencilTexture(tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2861 			// Copy stencil component only from source data. This gives us packed stencil-only data.
2862 			tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
2863 			srcPtr = (char*)stencilTexture.getAccess().getDataPtr();
2864 			// Copy packed stencil-only data to output buffer
2865 			deMemcpy(dstPtr, srcPtr, bufferSize);
2866 			stencilLoaded = DE_TRUE;
2867 			stencilOffset = bufferOffset;
2868 			dstPtr += bufferSize;
2869 			bufferOffset += bufferSize;
2870 
2871 			// Reference image generation uses pixel offsets based on buffer offset.
2872 			// We need to adjust the offset now that the stencil data is not interleaved.
2873 			copyData.bufferOffset /= tcu::getPixelSize(m_textureFormat);
2874 
2875 			copyData.bufferOffset += stencilOffset;
2876 		}
2877 
2878 		if (m_params.extensionUse == EXTENSION_USE_NONE)
2879 		{
2880 			bufferImageCopies.push_back(copyData);
2881 		}
2882 		else
2883 		{
2884 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2885 			bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyData));
2886 		}
2887 	}
2888 
2889 	flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
2890 
2891 	// Upload the depth/stencil data from m_destinationTextureLevel to initialize
2892 	// depth and stencil to known values.
2893 	// Uses uploadImageAspect so makes its own buffers for depth and stencil
2894 	// aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
2895 	uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2896 
2897 	const VkImageMemoryBarrier	imageBarrier	=
2898 	{
2899 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
2900 		DE_NULL,									// const void*				pNext;
2901 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
2902 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
2903 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
2904 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
2905 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
2906 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
2907 		*m_destination,								// VkImage					image;
2908 		{											// VkImageSubresourceRange	subresourceRange;
2909 			getAspectFlags(m_textureFormat),	// VkImageAspectFlags	aspectMask;
2910 			0u,								// deUint32				baseMipLevel;
2911 			1u,								// deUint32				mipLevels;
2912 			0u,								// deUint32				baseArraySlice;
2913 			1u								// deUint32				arraySize;
2914 		}
2915 	};
2916 
2917 	// Copy from buffer to depth/stencil image
2918 
2919 	beginCommandBuffer(vk, *m_cmdBuffer);
2920 	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);
2921 
2922 	if (m_params.extensionUse == EXTENSION_USE_NONE)
2923 	{
2924 		if (m_params.singleCommand)
2925 		{
2926 			// Issue a single copy command with regions defined by the test.
2927 			vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2928 		}
2929 		else
2930 		{
2931 			// Issue a a copy command per region defined by the test.
2932 			for (deUint32 i = 0; i < bufferImageCopies.size(); i++)
2933 			{
2934 				vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
2935 			}
2936 		}
2937 	}
2938 #ifndef CTS_USES_VULKANSC
2939 	else
2940 	{
2941 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2942 
2943 		if (m_params.singleCommand)
2944 		{
2945 			// Issue a single copy command with regions defined by the test.
2946 			const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2947 			{
2948 				VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
2949 				DE_NULL,											// const void*					pNext;
2950 				m_source.get(),										// VkBuffer						srcBuffer;
2951 				m_destination.get(),								// VkImage						dstImage;
2952 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout				dstImageLayout;
2953 				(deUint32)m_params.regions.size(),					// uint32_t						regionCount;
2954 				bufferImageCopies2KHR.data()						// const VkBufferImageCopy2KHR*	pRegions;
2955 			};
2956 			vk.cmdCopyBufferToImage2(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2957 		}
2958 		else
2959 		{
2960 			// Issue a a copy command per region defined by the test.
2961 			for (deUint32 i = 0; i < bufferImageCopies2KHR.size(); i++)
2962 			{
2963 				const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2964 				{
2965 					VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
2966 					DE_NULL,											// const void*					pNext;
2967 					m_source.get(),										// VkBuffer						srcBuffer;
2968 					m_destination.get(),								// VkImage						dstImage;
2969 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout				dstImageLayout;
2970 					1,													// uint32_t						regionCount;
2971 					&bufferImageCopies2KHR[i]							// const VkBufferImageCopy2KHR*	pRegions;
2972 				};
2973 				// Issue a single copy command with regions defined by the test.
2974 				vk.cmdCopyBufferToImage2(*m_cmdBuffer, &copyBufferToImageInfo2KHR);
2975 			}
2976 		}
2977 	}
2978 #endif // CTS_USES_VULKANSC
2979 
2980 	endCommandBuffer(vk, *m_cmdBuffer);
2981 
2982 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2983 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
2984 
2985 	de::MovePtr<tcu::TextureLevel>	resultLevel = readImage(*m_destination, m_params.dst.image);
2986 
2987 	// For combined depth/stencil formats both aspects are checked even when the test only
2988 	// copies one. Clear such aspects here for both the result and the reference.
2989 	if (tcu::hasDepthComponent(m_textureFormat.order) && !depthLoaded)
2990 	{
2991 		tcu::clearDepth(m_expectedTextureLevel[0]->getAccess(), 0.0f);
2992 		tcu::clearDepth(resultLevel->getAccess(), 0.0f);
2993 	}
2994 	if (tcu::hasStencilComponent(m_textureFormat.order) && !stencilLoaded)
2995 	{
2996 		tcu::clearStencil(m_expectedTextureLevel[0]->getAccess(), 0);
2997 		tcu::clearStencil(resultLevel->getAccess(), 0);
2998 	}
2999 
3000 	return checkTestResult(resultLevel->getAccess());
3001 }
3002 
3003 class CopyBufferToDepthStencilTestCase : public vkt::TestCase
3004 {
3005 public:
CopyBufferToDepthStencilTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)3006 							CopyBufferToDepthStencilTestCase	(tcu::TestContext&		testCtx,
3007 																 const std::string&		name,
3008 																 const std::string&		description,
3009 																 const TestParams		params)
3010 								: vkt::TestCase(testCtx, name, description)
3011 								, m_params(params)
3012 							{}
3013 
~CopyBufferToDepthStencilTestCase(void)3014 	virtual					~CopyBufferToDepthStencilTestCase	(void) {}
3015 
createInstance(Context & context) const3016 	virtual TestInstance*	createInstance						(Context&				context) const
3017 							{
3018 								return new CopyBufferToDepthStencil(context, m_params);
3019 							}
3020 
checkSupport(Context & context) const3021 	virtual void			checkSupport						(Context&				context) const
3022 							{
3023 								if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
3024 									(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
3025 								{
3026 									TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
3027 								}
3028 							}
3029 
3030 private:
3031 	TestParams				m_params;
3032 };
3033 
3034 // CompressedTextureForBlit is a helper class that stores compressed texture data.
3035 // Implementation is based on pipeline::TestTexture2D but it allocates only one level
3036 // and has special cases needed for blits to some formats.
3037 
3038 class CompressedTextureForBlit
3039 {
3040 public:
3041 	CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth);
3042 
3043 	tcu::PixelBufferAccess			getDecompressedAccess() const;
3044 	const tcu::CompressedTexture&	getCompressedTexture() const;
3045 
3046 protected:
3047 
3048 	tcu::CompressedTexture		m_compressedTexture;
3049 	de::ArrayBuffer<deUint8>	m_decompressedData;
3050 	tcu::PixelBufferAccess		m_decompressedAccess;
3051 };
3052 
CompressedTextureForBlit(const tcu::CompressedTexFormat & srcFormat,int width,int height,int depth)3053 CompressedTextureForBlit::CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth)
3054 	: m_compressedTexture(srcFormat, width, height, depth)
3055 {
3056 	de::Random			random					(123);
3057 
3058 	const int			compressedDataSize		(m_compressedTexture.getDataSize());
3059 	deUint8*			compressedData			((deUint8*)m_compressedTexture.getData());
3060 
3061 	tcu::TextureFormat	decompressedSrcFormat	(tcu::getUncompressedFormat(srcFormat));
3062 	const int			decompressedDataSize	(tcu::getPixelSize(decompressedSrcFormat) * width * height * depth);
3063 
3064 	// generate random data for compresed textre
3065 	if (tcu::isAstcFormat(srcFormat))
3066 	{
3067 		// comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
3068 		tcu::astc::generateRandomValidBlocks(compressedData, compressedDataSize / tcu::astc::BLOCK_SIZE_BYTES,
3069 											 srcFormat, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
3070 	}
3071 	else if ((srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK) ||
3072 			 (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
3073 	{
3074 		// special case - when we are blitting compressed floating-point image we can't have both big and small values
3075 		// in compressed image; to resolve this we are constructing source texture out of set of predefined compressed
3076 		// blocks that after decompression will have components in proper range
3077 
3078 		struct BC6HBlock
3079 		{
3080 			deUint32 data[4];
3081 		};
3082 		std::vector<BC6HBlock> validBlocks;
3083 
3084 		if (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)
3085 		{
3086 			// define set of few valid blocks that contain values from <0; 1> range
3087 			validBlocks =
3088 			{
3089 				{ { 1686671500, 3957317723, 3010132342, 2420137890 } },
3090 				{ { 3538027716, 298848033, 1925786021, 2022072301 } },
3091 				{ { 2614043466, 1636155440, 1023731774, 1894349986 } },
3092 				{ { 3433039318, 1294346072, 1587319645, 1738449906 } },
3093 				{ { 1386298160, 1639492154, 1273285776, 361562050 } },
3094 				{ { 1310110688, 526460754, 3630858047, 537617591 } },
3095 				{ { 3270356556, 2432993217, 2415924417, 1792488857 } },
3096 				{ { 1204947583, 353249154, 3739153467, 2068076443 } },
3097 			};
3098 		}
3099 		else
3100 		{
3101 			// define set of few valid blocks that contain values from <-1; 1> range
3102 			validBlocks =
3103 			{
3104 				{ { 2120678840, 3264271120, 4065378848, 3479743703 } },
3105 				{ { 1479697556, 3480872527, 3369382558, 568252340 } },
3106 				{ { 1301480032, 1607738094, 3055221704, 3663953681 } },
3107 				{ { 3531657186, 2285472028, 1429601507, 1969308187 } },
3108 				{ { 73229044, 650504649, 1120954865, 2626631975 } },
3109 				{ { 3872486086, 15326178, 2565171269, 2857722432 } },
3110 				{ { 1301480032, 1607738094, 3055221704, 3663953681 } },
3111 				{ { 73229044, 650504649, 1120954865, 2626631975 } },
3112 			};
3113 		}
3114 
3115 		deUint32*	compressedDataUint32	= reinterpret_cast<deUint32*>(compressedData);
3116 		const int	blocksCount				= compressedDataSize / static_cast<int>(sizeof(BC6HBlock));
3117 
3118 		// fill data using randomly selected valid blocks
3119 		for (int blockNdx = 0; blockNdx < blocksCount; blockNdx++)
3120 		{
3121 			deUint32 selectedBlock = random.getUint32() % static_cast<deUint32>(validBlocks.size());
3122 			deMemcpy(compressedDataUint32, validBlocks[selectedBlock].data, sizeof(BC6HBlock));
3123 			compressedDataUint32 += 4;
3124 		}
3125 	}
3126 	else if (srcFormat != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
3127 	{
3128 		// random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
3129 		for (int byteNdx = 0; byteNdx < compressedDataSize; byteNdx++)
3130 			compressedData[byteNdx] = 0xFF & random.getUint32();
3131 	}
3132 
3133 	// alocate space for decompressed texture
3134 	m_decompressedData.setStorage(decompressedDataSize);
3135 	m_decompressedAccess = tcu::PixelBufferAccess(decompressedSrcFormat, width, height, depth, m_decompressedData.getPtr());
3136 
3137 	// store decompressed data
3138 	m_compressedTexture.decompress(m_decompressedAccess, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
3139 }
3140 
getDecompressedAccess() const3141 tcu::PixelBufferAccess CompressedTextureForBlit::getDecompressedAccess() const
3142 {
3143 	return m_decompressedAccess;
3144 }
3145 
getCompressedTexture() const3146 const tcu::CompressedTexture& CompressedTextureForBlit::getCompressedTexture() const
3147 {
3148 	return m_compressedTexture;
3149 }
3150 
3151 // Copy from image to image with scaling.
3152 
3153 class BlittingImages : public CopiesAndBlittingTestInstance
3154 {
3155 public:
3156 											BlittingImages					(Context&	context,
3157 																			 TestParams params);
3158 	virtual tcu::TestStatus					iterate							(void);
3159 protected:
3160 	virtual tcu::TestStatus					checkTestResult							(tcu::ConstPixelBufferAccess	result);
3161 	virtual void							copyRegionToTextureLevel				(tcu::ConstPixelBufferAccess	src,
3162 																					 tcu::PixelBufferAccess			dst,
3163 																					 CopyRegion						region,
3164 																					 deUint32						mipLevel = 0u);
3165 	virtual void							generateExpectedResult					(void);
3166 	void									uploadCompressedImage					(const VkImage& image, const ImageParms& parms);
3167 private:
3168 	bool									checkNonNearestFilteredResult			(const tcu::ConstPixelBufferAccess&	result,
3169 																					 const tcu::ConstPixelBufferAccess&	clampedReference,
3170 																					 const tcu::ConstPixelBufferAccess&	unclampedReference,
3171 																					 const tcu::TextureFormat&			sourceFormat);
3172 	bool									checkNearestFilteredResult				(const tcu::ConstPixelBufferAccess&	result,
3173 																					 const tcu::ConstPixelBufferAccess&	source);
3174 
3175 	bool									checkCompressedNonNearestFilteredResult	(const tcu::ConstPixelBufferAccess&	result,
3176 																					 const tcu::ConstPixelBufferAccess&	clampedReference,
3177 																					 const tcu::ConstPixelBufferAccess&	unclampedReference,
3178 																					 const tcu::CompressedTexFormat		format);
3179 	bool									checkCompressedNearestFilteredResult	(const tcu::ConstPixelBufferAccess&	result,
3180 																					 const tcu::ConstPixelBufferAccess&	source,
3181 																					 const tcu::CompressedTexFormat		format);
3182 
3183 
3184 	Move<VkImage>						m_source;
3185 	de::MovePtr<Allocation>				m_sourceImageAlloc;
3186 	Move<VkImage>						m_destination;
3187 	de::MovePtr<Allocation>				m_destinationImageAlloc;
3188 
3189 	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel;
3190 
3191 	// helper used only when bliting from compressed formats
3192 	typedef de::SharedPtr<CompressedTextureForBlit> CompressedTextureForBlitSp;
3193 	CompressedTextureForBlitSp			m_sourceCompressedTexture;
3194 	CompressedTextureForBlitSp			m_destinationCompressedTexture;
3195 };
3196 
BlittingImages(Context & context,TestParams params)3197 BlittingImages::BlittingImages (Context& context, TestParams params)
3198 	: CopiesAndBlittingTestInstance(context, params)
3199 {
3200 	const InstanceInterface&	vki					= context.getInstanceInterface();
3201 	const DeviceInterface&		vk					= context.getDeviceInterface();
3202 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
3203 	const VkDevice				vkDevice			= m_device;
3204 	Allocator&					memAlloc			= context.getDefaultAllocator();
3205 
3206 	// Create source image
3207 	{
3208 		const VkImageCreateInfo		sourceImageParams		=
3209 		{
3210 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
3211 			DE_NULL,								// const void*			pNext;
3212 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
3213 			m_params.src.image.imageType,			// VkImageType			imageType;
3214 			m_params.src.image.format,				// VkFormat				format;
3215 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
3216 			1u,										// deUint32				mipLevels;
3217 			getArraySize(m_params.src.image),		// deUint32				arraySize;
3218 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
3219 			m_params.src.image.tiling,				// VkImageTiling		tiling;
3220 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3221 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
3222 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
3223 			0u,										// deUint32				queueFamilyIndexCount;
3224 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
3225 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
3226 		};
3227 
3228 		m_source = createImage(vk, vkDevice, &sourceImageParams);
3229 		m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
3230 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
3231 	}
3232 
3233 	// Create destination image
3234 	{
3235 		const VkImageCreateInfo		destinationImageParams	=
3236 		{
3237 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
3238 			DE_NULL,								// const void*			pNext;
3239 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
3240 			m_params.dst.image.imageType,			// VkImageType			imageType;
3241 			m_params.dst.image.format,				// VkFormat				format;
3242 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
3243 			1u,										// deUint32				mipLevels;
3244 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
3245 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
3246 			m_params.dst.image.tiling,				// VkImageTiling		tiling;
3247 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3248 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
3249 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
3250 			0u,										// deUint32				queueFamilyIndexCount;
3251 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
3252 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
3253 		};
3254 
3255 		m_destination = createImage(vk, vkDevice, &destinationImageParams);
3256 		m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
3257 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
3258 	}
3259 }
3260 
iterate(void)3261 tcu::TestStatus BlittingImages::iterate (void)
3262 {
3263 	const DeviceInterface&		vk				= m_context.getDeviceInterface();
3264 	const VkDevice				vkDevice		= m_device;
3265 	const VkQueue				queue			= m_queue;
3266 
3267 	const ImageParms&			srcImageParams	= m_params.src.image;
3268 	const int					srcWidth		= static_cast<int>(srcImageParams.extent.width);
3269 	const int					srcHeight		= static_cast<int>(srcImageParams.extent.height);
3270 	const int					srcDepth		= static_cast<int>(srcImageParams.extent.depth);
3271 	const ImageParms&			dstImageParams	= m_params.dst.image;
3272 	const int					dstWidth		= static_cast<int>(dstImageParams.extent.width);
3273 	const int					dstHeight		= static_cast<int>(dstImageParams.extent.height);
3274 	const int					dstDepth		= static_cast<int>(dstImageParams.extent.depth);
3275 
3276 	std::vector<VkImageBlit>		regions;
3277 	std::vector<VkImageBlit2KHR>	regions2KHR;
3278 
3279 	// setup blit regions - they are also needed for reference generation
3280 	if (m_params.extensionUse == EXTENSION_USE_NONE)
3281 	{
3282 		regions.reserve(m_params.regions.size());
3283 		for (const auto& r : m_params.regions)
3284 			regions.push_back(r.imageBlit);
3285 	}
3286 	else
3287 	{
3288 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3289 		regions2KHR.reserve(m_params.regions.size());
3290 		for (const auto& r : m_params.regions)
3291 			regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(r.imageBlit));
3292 	}
3293 
3294 	// generate source image
3295 	if (isCompressedFormat(srcImageParams.format))
3296 	{
3297 		// for compressed images srcImageParams.fillMode is not used - we are using random data
3298 		tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(srcImageParams.format);
3299 		m_sourceCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth));
3300 		uploadCompressedImage(m_source.get(), srcImageParams);
3301 	}
3302 	else
3303 	{
3304 		// non-compressed image is filled with selected fillMode
3305 		const tcu::TextureFormat srcTcuFormat = mapVkFormat(srcImageParams.format);
3306 		m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, srcWidth, srcHeight, srcDepth));
3307 		generateBuffer(m_sourceTextureLevel->getAccess(), srcWidth, srcHeight, srcDepth, srcImageParams.fillMode);
3308 		uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), srcImageParams);
3309 	}
3310 
3311 	// generate destination image
3312 	if (isCompressedFormat(dstImageParams.format))
3313 	{
3314 		// compressed images are filled with random data
3315 		tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(dstImageParams.format);
3316 		m_destinationCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth));
3317 		uploadCompressedImage(m_destination.get(), dstImageParams);
3318 	}
3319 	else
3320 	{
3321 		// non-compressed image is filled with white background
3322 		const tcu::TextureFormat dstTcuFormat = mapVkFormat(dstImageParams.format);
3323 		m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, dstWidth, dstHeight, dstDepth));
3324 		generateBuffer(m_destinationTextureLevel->getAccess(), dstWidth, dstHeight, dstDepth, dstImageParams.fillMode);
3325 		uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), dstImageParams);
3326 	}
3327 
3328 	generateExpectedResult();
3329 
3330 	// Barriers for copying images to buffer
3331 	const VkImageMemoryBarrier imageBarriers[]
3332 	{
3333 		{
3334 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3335 			DE_NULL,									// const void*				pNext;
3336 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
3337 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
3338 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
3339 			srcImageParams.operationLayout,				// VkImageLayout			newLayout;
3340 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3341 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3342 			m_source.get(),								// VkImage					image;
3343 			{											// VkImageSubresourceRange	subresourceRange;
3344 				getAspectFlags(srcImageParams.format),	//   VkImageAspectFlags		aspectMask;
3345 				0u,										//   deUint32				baseMipLevel;
3346 				1u,										//   deUint32				mipLevels;
3347 				0u,										//   deUint32				baseArraySlice;
3348 				1u										//   deUint32				arraySize;
3349 			}
3350 		},
3351 		{
3352 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
3353 			DE_NULL,									// const void*				pNext;
3354 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
3355 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
3356 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
3357 			dstImageParams.operationLayout,				// VkImageLayout			newLayout;
3358 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
3359 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
3360 			m_destination.get(),						// VkImage					image;
3361 			{											// VkImageSubresourceRange	subresourceRange;
3362 				getAspectFlags(dstImageParams.format),	//   VkImageAspectFlags		aspectMask;
3363 				0u,										//   deUint32				baseMipLevel;
3364 				1u,										//   deUint32				mipLevels;
3365 				0u,										//   deUint32				baseArraySlice;
3366 				1u										//   deUint32				arraySize;
3367 			}
3368 		}
3369 	};
3370 
3371 	beginCommandBuffer(vk, *m_cmdBuffer);
3372 	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);
3373 
3374 	if (m_params.extensionUse == EXTENSION_USE_NONE)
3375 	{
3376 		vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), srcImageParams.operationLayout, m_destination.get(), dstImageParams.operationLayout, (deUint32)m_params.regions.size(), &regions[0], m_params.filter);
3377 	}
3378 #ifndef CTS_USES_VULKANSC
3379 	else
3380 	{
3381 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3382 		const VkBlitImageInfo2KHR blitImageInfo2KHR
3383 		{
3384 			VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
3385 			DE_NULL,									// const void*					pNext;
3386 			m_source.get(),								// VkImage						srcImage;
3387 			srcImageParams.operationLayout,				// VkImageLayout				srcImageLayout;
3388 			m_destination.get(),						// VkImage						dstImage;
3389 			dstImageParams.operationLayout,				// VkImageLayout				dstImageLayout;
3390 			(deUint32)m_params.regions.size(),			// uint32_t						regionCount;
3391 			&regions2KHR[0],							// const VkImageBlit2KHR*		pRegions;
3392 			m_params.filter,							// VkFilter						filter;
3393 		};
3394 		vk.cmdBlitImage2(*m_cmdBuffer, &blitImageInfo2KHR);
3395 	}
3396 #endif // CTS_USES_VULKANSC
3397 
3398 	endCommandBuffer(vk, *m_cmdBuffer);
3399 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
3400 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
3401 
3402 	de::MovePtr<tcu::TextureLevel>	resultLevel		= readImage(*m_destination, dstImageParams);
3403 	tcu::PixelBufferAccess			resultAccess	= resultLevel->getAccess();
3404 
3405 	// if blit was done to a compressed format we need to decompress it to be able to verify it
3406 	if (m_destinationCompressedTexture)
3407 	{
3408 		deUint8* const					compressedDataSrc	(static_cast<deUint8*>(resultAccess.getDataPtr()));
3409 		const tcu::CompressedTexFormat	dstCompressedFormat (mapVkCompressedFormat(dstImageParams.format));
3410 		tcu::TextureLevel				decompressedLevel	(getUncompressedFormat(dstCompressedFormat), dstWidth, dstHeight, dstDepth);
3411 		tcu::PixelBufferAccess			decompressedAccess	(decompressedLevel.getAccess());
3412 
3413 		tcu::decompress(decompressedAccess, dstCompressedFormat, compressedDataSrc);
3414 
3415 		return checkTestResult(decompressedAccess);
3416 	}
3417 
3418 	return checkTestResult(resultAccess);
3419 }
3420 
calculateFloatConversionError(int srcBits)3421 static float calculateFloatConversionError (int srcBits)
3422 {
3423 	if (srcBits > 0)
3424 	{
3425 		const int	clampedBits	= de::clamp<int>(srcBits, 0, 32);
3426 		const float	srcMaxValue	= de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
3427 		const float	error		= 1.0f / srcMaxValue;
3428 
3429 		return de::clamp<float>(error, 0.0f, 1.0f);
3430 	}
3431 	else
3432 		return 1.0f;
3433 }
3434 
getFormatThreshold(const tcu::TextureFormat & format)3435 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
3436 {
3437 	tcu::Vec4 threshold(0.01f);
3438 
3439 	switch (format.type)
3440 	{
3441 	case tcu::TextureFormat::HALF_FLOAT:
3442 		threshold = tcu::Vec4(0.005f);
3443 		break;
3444 
3445 	case tcu::TextureFormat::FLOAT:
3446 	case tcu::TextureFormat::FLOAT64:
3447 		threshold = tcu::Vec4(0.001f);
3448 		break;
3449 
3450 	case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
3451 		threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
3452 		break;
3453 
3454 	case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
3455 		threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
3456 		break;
3457 
3458 	case tcu::TextureFormat::UNORM_INT_1010102_REV:
3459 		threshold = tcu::Vec4(0.002f, 0.002f, 0.002f, 0.3f);
3460 		break;
3461 
3462 	case tcu:: TextureFormat::UNORM_INT8:
3463 		threshold = tcu::Vec4(0.008f, 0.008f, 0.008f, 0.008f);
3464 		break;
3465 
3466 	default:
3467 		const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
3468 		threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
3469 				      calculateFloatConversionError(bits.y()),
3470 				      calculateFloatConversionError(bits.z()),
3471 				      calculateFloatConversionError(bits.w()));
3472 	}
3473 
3474 	// Return value matching the channel order specified by the format
3475 	if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
3476 		return threshold.swizzle(2, 1, 0, 3);
3477 	else
3478 		return threshold;
3479 }
3480 
getCompressedFormatThreshold(const tcu::CompressedTexFormat & format)3481 tcu::Vec4 getCompressedFormatThreshold(const tcu::CompressedTexFormat& format)
3482 {
3483 	bool		isSigned(false);
3484 	tcu::IVec4	bitDepth(0);
3485 
3486 	switch (format)
3487 	{
3488 	case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
3489 		bitDepth = { 7, 0, 0, 0 };
3490 		isSigned = true;
3491 		break;
3492 
3493 	case tcu::COMPRESSEDTEXFORMAT_EAC_R11:
3494 		bitDepth = { 8, 0, 0, 0 };
3495 		break;
3496 
3497 	case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
3498 		bitDepth = { 7, 7, 0, 0 };
3499 		isSigned = true;
3500 		break;
3501 
3502 	case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:
3503 		bitDepth = { 8, 8, 0, 0 };
3504 		break;
3505 
3506 	case tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8:
3507 	case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:
3508 	case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:
3509 		bitDepth = { 8, 8, 8, 0 };
3510 		break;
3511 
3512 	case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
3513 	case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
3514 		bitDepth = { 8, 8, 8, 1 };
3515 		break;
3516 
3517 	case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
3518 	case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
3519 	case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
3520 	case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
3521 	case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
3522 	case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
3523 	case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
3524 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
3525 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
3526 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
3527 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
3528 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
3529 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
3530 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
3531 	case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
3532 	case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
3533 	case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
3534 	case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
3535 	case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
3536 	case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
3537 	case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
3538 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
3539 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
3540 	case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
3541 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
3542 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
3543 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
3544 	case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
3545 	case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
3546 	case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
3547 		bitDepth = { 8, 8, 8, 8 };
3548 		break;
3549 
3550 	case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
3551 	case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
3552 	case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
3553 	case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
3554 	case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
3555 	case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
3556 		bitDepth = { 5, 6, 5, 0 };
3557 		break;
3558 
3559 	case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
3560 	case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
3561 	case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
3562 	case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
3563 		bitDepth = { 5, 5, 5, 1 };
3564 		break;
3565 
3566 	case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
3567 		bitDepth = { 7, 0, 0, 0 };
3568 		isSigned = true;
3569 		break;
3570 
3571 	case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
3572 		bitDepth = { 8, 0, 0, 0 };
3573 		break;
3574 
3575 	case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
3576 		bitDepth = { 7, 7, 0, 0 };
3577 		isSigned = true;
3578 		break;
3579 
3580 	case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
3581 		bitDepth = { 8, 8, 0, 0 };
3582 		break;
3583 
3584 	case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
3585 		return tcu::Vec4(0.01f);
3586 	case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
3587 		return tcu::Vec4(0.005f);
3588 
3589 	default:
3590 		DE_ASSERT(DE_FALSE);
3591 	}
3592 
3593 	const float	range = isSigned ? 1.0f - (-1.0f)
3594 								 : 1.0f - 0.0f;
3595 	tcu::Vec4 v;
3596 	for (int i = 0; i < 4; ++i)
3597 	{
3598 		if (bitDepth[i] == 0)
3599 			v[i] = 1.0f;
3600 		else
3601 			v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3602 	}
3603 	return v;
3604 }
3605 
checkNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedExpected,const tcu::ConstPixelBufferAccess & unclampedExpected,const tcu::TextureFormat & srcFormat)3606 bool BlittingImages::checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
3607 													const tcu::ConstPixelBufferAccess&	clampedExpected,
3608 													const tcu::ConstPixelBufferAccess&	unclampedExpected,
3609 													const tcu::TextureFormat&			srcFormat)
3610 {
3611 	tcu::TestLog&					log				(m_context.getTestContext().getLog());
3612 	const tcu::TextureFormat		dstFormat		= result.getFormat();
3613 	const tcu::TextureChannelClass	dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3614 	const tcu::TextureChannelClass	srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3615 	bool							isOk			= false;
3616 
3617 	log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3618 
3619 	// if either of srcImage or dstImage stores values as a signed/unsigned integer,
3620 	// the other must also store values a signed/unsigned integer
3621 	// e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3622 	// despite the fact that both formats are sampled as floats
3623 	bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3624 							  dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3625 	bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3626 							  srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3627 	if (dstImageIsIntClass != srcImageIsIntClass)
3628 	{
3629 		log << tcu::TestLog::EndSection;
3630 		return false;
3631 	}
3632 
3633 	if (isFloatFormat(dstFormat))
3634 	{
3635 		const bool		srcIsSRGB	= tcu::isSRGB(srcFormat);
3636 		const tcu::Vec4	srcMaxDiff	= getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
3637 		const tcu::Vec4	dstMaxDiff	= getFormatThreshold(dstFormat);
3638 		const tcu::Vec4	threshold	= ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
3639 
3640 		isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3641 		log << tcu::TestLog::EndSection;
3642 
3643 		if (!isOk)
3644 		{
3645 			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3646 			isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3647 			log << tcu::TestLog::EndSection;
3648 		}
3649 	}
3650 	else
3651 	{
3652 		tcu::UVec4	threshold;
3653 		// Calculate threshold depending on channel width of destination format.
3654 		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
3655 		const tcu::IVec4	srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
3656 		for (deUint32 i = 0; i < 4; ++i)
3657 			threshold[i] = 1 + de::max( ( ( 1 << dstBitDepth[i] ) - 1 ) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
3658 
3659 		isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3660 		log << tcu::TestLog::EndSection;
3661 
3662 		if (!isOk)
3663 		{
3664 			log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3665 			isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3666 			log << tcu::TestLog::EndSection;
3667 		}
3668 	}
3669 
3670 	return isOk;
3671 }
3672 
checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedReference,const tcu::ConstPixelBufferAccess & unclampedReference,const tcu::CompressedTexFormat format)3673 bool BlittingImages::checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess&	result,
3674 															 const tcu::ConstPixelBufferAccess&	clampedReference,
3675 															 const tcu::ConstPixelBufferAccess&	unclampedReference,
3676 															 const tcu::CompressedTexFormat		format)
3677 {
3678 	tcu::TestLog&				log				= m_context.getTestContext().getLog();
3679 	const tcu::TextureFormat	dstFormat		= result.getFormat();
3680 
3681 	// there are rare cases wher one or few pixels have slightly bigger error
3682 	// in one of channels this accepted error allows those casses to pass
3683 	const tcu::Vec4				acceptedError	(0.06f);
3684 
3685 	const tcu::Vec4				srcMaxDiff		= getCompressedFormatThreshold(format);
3686 	const tcu::Vec4				dstMaxDiff		= m_destinationCompressedTexture ?
3687 													getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
3688 													getFormatThreshold(dstFormat);
3689 	const tcu::Vec4				threshold		= (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f) + acceptedError;
3690 
3691 	bool						filteredResultVerification(false);
3692 	tcu::Vec4					filteredResultMinValue(-6e6);
3693 	tcu::Vec4					filteredResultMaxValue(6e6);
3694 	tcu::TextureLevel			filteredResult;
3695 	tcu::TextureLevel			filteredClampedReference;
3696 	tcu::TextureLevel			filteredUnclampedReference;
3697 
3698 	if (((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
3699 		(format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)))
3700 	{
3701 		if ((dstFormat.type == tcu::TextureFormat::FLOAT) ||
3702 			(dstFormat.type == tcu::TextureFormat::HALF_FLOAT))
3703 		{
3704 			// for compressed formats we are using random data and for bc6h formats
3705 			// this will give us also large color values; when we are bliting to
3706 			// a format that accepts large values we can end up with large diferences
3707 			// betwean filtered result and reference; to avoid that we need to remove
3708 			// values that are to big from verification
3709 			filteredResultVerification	= true;
3710 			filteredResultMinValue		= tcu::Vec4(-10.0f);
3711 			filteredResultMaxValue		= tcu::Vec4( 10.0f);
3712 		}
3713 		else if (dstFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
3714 		{
3715 			// we need to clamp some formats to <0;1> range as it has
3716 			// small precision for big numbers compared to reference
3717 			filteredResultVerification	= true;
3718 			filteredResultMinValue		= tcu::Vec4(0.0f);
3719 			filteredResultMaxValue		= tcu::Vec4(1.0f);
3720 		}
3721 		// else don't use filtered verification
3722 	}
3723 
3724 	if (filteredResultVerification)
3725 	{
3726 		filteredResult.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3727 		tcu::PixelBufferAccess filteredResultAcccess(filteredResult.getAccess());
3728 
3729 		filteredClampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3730 		tcu::PixelBufferAccess filteredClampedAcccess(filteredClampedReference.getAccess());
3731 
3732 		filteredUnclampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3733 		tcu::PixelBufferAccess filteredUnclampedResultAcccess(filteredUnclampedReference.getAccess());
3734 
3735 		for (deInt32 z = 0; z < result.getDepth(); z++)
3736 		for (deInt32 y = 0; y < result.getHeight(); y++)
3737 		for (deInt32 x = 0; x < result.getWidth(); x++)
3738 		{
3739 			tcu::Vec4 resultTexel				= result.getPixel(x, y, z);
3740 			tcu::Vec4 clampedReferenceTexel		= clampedReference.getPixel(x, y, z);
3741 			tcu::Vec4 unclampedReferenceTexel	= unclampedReference.getPixel(x, y, z);
3742 
3743 			resultTexel				= tcu::clamp(resultTexel, filteredResultMinValue, filteredResultMaxValue);
3744 			clampedReferenceTexel	= tcu::clamp(clampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3745 			unclampedReferenceTexel	= tcu::clamp(unclampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3746 
3747 			filteredResultAcccess.setPixel(resultTexel, x, y, z);
3748 			filteredClampedAcccess.setPixel(clampedReferenceTexel, x, y, z);
3749 			filteredUnclampedResultAcccess.setPixel(unclampedReferenceTexel, x, y, z);
3750 		}
3751 	}
3752 
3753 	const tcu::ConstPixelBufferAccess clampedRef	= filteredResultVerification ? filteredClampedReference.getAccess() : clampedReference;
3754 	const tcu::ConstPixelBufferAccess res			= filteredResultVerification ? filteredResult.getAccess() : result;
3755 
3756 	log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3757 	bool isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3758 	log << tcu::TestLog::EndSection;
3759 
3760 	if (!isOk)
3761 	{
3762 		const tcu::ConstPixelBufferAccess unclampedRef = filteredResultVerification ? filteredUnclampedReference.getAccess() : unclampedReference;
3763 
3764 		log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3765 		isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3766 		log << tcu::TestLog::EndSection;
3767 	}
3768 
3769 	return isOk;
3770 }
3771 
3772 //! Utility to encapsulate coordinate computation and loops.
3773 struct CompareEachPixelInEachRegion
3774 {
~CompareEachPixelInEachRegionvkt::api::__anon1525b85c0111::CompareEachPixelInEachRegion3775 	virtual		 ~CompareEachPixelInEachRegion  (void) {}
3776 	virtual bool compare								(const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const = 0;
3777 
forEachvkt::api::__anon1525b85c0111::CompareEachPixelInEachRegion3778 	bool forEach (const void*							pUserData,
3779 				  const std::vector<CopyRegion>&		regions,
3780 				  const int								sourceWidth,
3781 				  const int								sourceHeight,
3782 				  const int								sourceDepth,
3783 				  const tcu::PixelBufferAccess&			errorMask) const
3784 	{
3785 		bool compareOk = true;
3786 
3787 		for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
3788 		{
3789 			const VkImageBlit& blit = regionIter->imageBlit;
3790 
3791 			const int	xStart	= deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3792 			const int	yStart	= deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3793 			const int	zStart	= deMin32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3794 			const int	xEnd	= deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3795 			const int	yEnd	= deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3796 			const int	zEnd	= deMax32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3797 			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);
3798 			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);
3799 			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);
3800 			const float srcInvW	= 1.0f / static_cast<float>(sourceWidth);
3801 			const float srcInvH	= 1.0f / static_cast<float>(sourceHeight);
3802 			const float srcInvD	= 1.0f / static_cast<float>(sourceDepth);
3803 
3804 			for (int z = zStart; z < zEnd; z++)
3805 			for (int y = yStart; y < yEnd; y++)
3806 			for (int x = xStart; x < xEnd; x++)
3807 			{
3808 				const tcu::Vec3 srcNormCoord
3809 				(
3810 					(xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
3811 					(yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH,
3812 					(zScale * (static_cast<float>(z - blit.dstOffsets[0].z) + 0.5f) + static_cast<float>(blit.srcOffsets[0].z)) * srcInvD
3813 				);
3814 
3815 				if (!compare(pUserData, x, y, z, srcNormCoord))
3816 				{
3817 					errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
3818 					compareOk = false;
3819 				}
3820 			}
3821 		}
3822 		return compareOk;
3823 	}
3824 };
3825 
getFloatOrFixedPointFormatThreshold(const tcu::TextureFormat & format)3826 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
3827 {
3828 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
3829 	const tcu::IVec4				bitDepth		= tcu::getTextureFormatBitDepth(format);
3830 
3831 	if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
3832 	{
3833 		return getFormatThreshold(format);
3834 	}
3835 	else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
3836 			 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
3837 	{
3838 		const bool	isSigned	= (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
3839 		const float	range		= isSigned ? 1.0f - (-1.0f)
3840 										   : 1.0f -   0.0f;
3841 
3842 		tcu::Vec4 v;
3843 		for (int i = 0; i < 4; ++i)
3844 		{
3845 			if (bitDepth[i] == 0)
3846 				v[i] = 1.0f;
3847 			else
3848 				v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3849 		}
3850 		return v;
3851 	}
3852 	else
3853 	{
3854 		DE_ASSERT(0);
3855 		return tcu::Vec4();
3856 	}
3857 }
3858 
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)3859 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess&	source,
3860 							  const tcu::ConstPixelBufferAccess&	result,
3861 							  const tcu::Vec4&						sourceThreshold,
3862 							  const tcu::Vec4&						resultThreshold,
3863 							  const tcu::PixelBufferAccess&			errorMask,
3864 							  const std::vector<CopyRegion>&		regions)
3865 {
3866 	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,
3867 										 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
3868 	const tcu::IVec4		dstBitDepth (tcu::getTextureFormatBitDepth(result.getFormat()));
3869 	tcu::LookupPrecision	precision;
3870 
3871 	precision.colorMask		 = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
3872 	precision.colorThreshold = tcu::max(sourceThreshold, resultThreshold);
3873 
3874 	const struct Capture
3875 	{
3876 		const tcu::ConstPixelBufferAccess&	source;
3877 		const tcu::ConstPixelBufferAccess&	result;
3878 		const tcu::Sampler&					sampler;
3879 		const tcu::LookupPrecision&			precision;
3880 		const bool							isSRGB;
3881 	} capture =
3882 	{
3883 		source, result, sampler, precision, tcu::isSRGB(result.getFormat())
3884 	};
3885 
3886 	const struct Loop : CompareEachPixelInEachRegion
3887 	{
3888 		Loop (void) {}
3889 
3890 		bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3891 		{
3892 			const Capture&					c					= *static_cast<const Capture*>(pUserData);
3893 			const tcu::TexLookupScaleMode	lookupScaleDontCare	= tcu::TEX_LOOKUP_SCALE_MINIFY;
3894 			tcu::Vec4						dstColor			= c.result.getPixel(x, y, z);
3895 
3896 			// TexLookupVerifier performs a conversion to linear space, so we have to as well
3897 			if (c.isSRGB)
3898 				dstColor = tcu::sRGBToLinear(dstColor);
3899 
3900 			return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3901 		}
3902 	} loop;
3903 
3904 	return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3905 }
3906 
intNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask,const std::vector<CopyRegion> & regions)3907 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess&	source,
3908 							const tcu::ConstPixelBufferAccess&	result,
3909 							const tcu::PixelBufferAccess&		errorMask,
3910 							const std::vector<CopyRegion>&		regions)
3911 {
3912 	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,
3913 										 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
3914 	tcu::IntLookupPrecision	precision;
3915 
3916 	{
3917 		const tcu::IVec4	srcBitDepth	= tcu::getTextureFormatBitDepth(source.getFormat());
3918 		const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(result.getFormat());
3919 
3920 		for (deUint32 i = 0; i < 4; ++i) {
3921 			precision.colorThreshold[i]	= de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
3922 			precision.colorMask[i]		= dstBitDepth[i] != 0;
3923 		}
3924 	}
3925 
3926 	// Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
3927 	// does the conversion on the fly without wasting memory, but this approach is more straightforward.
3928 	tcu::TextureLevel				convertedSourceTexture	(result.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
3929 	const tcu::PixelBufferAccess	convertedSource			= convertedSourceTexture.getAccess();
3930 
3931 	for (int z = 0; z < source.getDepth();	++z)
3932 	for (int y = 0; y < source.getHeight(); ++y)
3933 	for (int x = 0; x < source.getWidth();  ++x)
3934 		convertedSource.setPixel(source.getPixelInt(x, y, z), x, y, z);	// will be clamped to max. representable value
3935 
3936 	const struct Capture
3937 	{
3938 		const tcu::ConstPixelBufferAccess&	source;
3939 		const tcu::ConstPixelBufferAccess&	result;
3940 		const tcu::Sampler&					sampler;
3941 		const tcu::IntLookupPrecision&		precision;
3942 	} capture =
3943 	{
3944 		convertedSource, result, sampler, precision
3945 	};
3946 
3947 	const struct Loop : CompareEachPixelInEachRegion
3948 	{
3949 		Loop (void) {}
3950 
3951 		bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3952 		{
3953 			const Capture&					c					= *static_cast<const Capture*>(pUserData);
3954 			const tcu::TexLookupScaleMode	lookupScaleDontCare	= tcu::TEX_LOOKUP_SCALE_MINIFY;
3955 			const tcu::IVec4				dstColor			= c.result.getPixelInt(x, y, z);
3956 
3957 			return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3958 		}
3959 	} loop;
3960 
3961 	return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3962 }
3963 
checkNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source)3964 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
3965 												 const tcu::ConstPixelBufferAccess& source)
3966 {
3967 	tcu::TestLog&					log				(m_context.getTestContext().getLog());
3968 	const tcu::TextureFormat		dstFormat		= result.getFormat();
3969 	const tcu::TextureFormat		srcFormat		= source.getFormat();
3970 	const tcu::TextureChannelClass	dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3971 	const tcu::TextureChannelClass	srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3972 
3973 	tcu::TextureLevel		errorMaskStorage	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
3974 	tcu::PixelBufferAccess	errorMask			= errorMaskStorage.getAccess();
3975 	tcu::Vec4				pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
3976 	tcu::Vec4				pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
3977 	bool					ok					= false;
3978 
3979 	tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3980 
3981 	// if either of srcImage or dstImage stores values as a signed/unsigned integer,
3982 	// the other must also store values a signed/unsigned integer
3983 	// e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3984 	// despite the fact that both formats are sampled as floats
3985 	bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3986 							  dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3987 	bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3988 							  srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3989 	if (dstImageIsIntClass != srcImageIsIntClass)
3990 		return false;
3991 
3992 	if (dstImageIsIntClass)
3993 	{
3994 		ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
3995 	}
3996 	else
3997 	{
3998 		const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
3999 		const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
4000 		ok = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions);
4001 	}
4002 
4003 	if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4004 		tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4005 
4006 	if (!ok)
4007 	{
4008 		log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4009 			<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
4010 			<< tcu::TestLog::Image("ErrorMask",	"Error mask", errorMask)
4011 			<< tcu::TestLog::EndImageSet;
4012 	}
4013 	else
4014 	{
4015 		log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4016 			<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
4017 			<< tcu::TestLog::EndImageSet;
4018 	}
4019 
4020 	return ok;
4021 }
4022 
checkCompressedNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source,const tcu::CompressedTexFormat format)4023 bool BlittingImages::checkCompressedNearestFilteredResult (const tcu::ConstPixelBufferAccess&	result,
4024 														   const tcu::ConstPixelBufferAccess&	source,
4025 														   const tcu::CompressedTexFormat		format)
4026 {
4027 	tcu::TestLog&				log					(m_context.getTestContext().getLog());
4028 	tcu::TextureFormat			errorMaskFormat		(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8);
4029 	tcu::TextureLevel			errorMaskStorage	(errorMaskFormat, result.getWidth(), result.getHeight(), result.getDepth());
4030 	tcu::PixelBufferAccess		errorMask			(errorMaskStorage.getAccess());
4031 	tcu::Vec4					pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
4032 	tcu::Vec4					pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
4033 	const tcu::TextureFormat&	resultFormat		(result.getFormat());
4034 	VkFormat					nativeResultFormat	(mapTextureFormat(resultFormat));
4035 
4036 	// there are rare cases wher one or few pixels have slightly bigger error
4037 	// in one of channels this accepted error allows those casses to pass
4038 	const tcu::Vec4				acceptedError		(0.04f);
4039 	const tcu::Vec4				srcMaxDiff			(acceptedError + getCompressedFormatThreshold(format));
4040 	const tcu::Vec4				dstMaxDiff			(acceptedError + (m_destinationCompressedTexture ?
4041 														getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
4042 														getFloatOrFixedPointFormatThreshold(resultFormat)));
4043 
4044 	tcu::TextureLevel			clampedSourceLevel;
4045 	bool						clampSource			(false);
4046 	tcu::Vec4					clampSourceMinValue	(-1.0f);
4047 	tcu::Vec4					clampSourceMaxValue	(1.0f);
4048 	tcu::TextureLevel			clampedResultLevel;
4049 	bool						clampResult			(false);
4050 
4051 	tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
4052 
4053 	if (resultFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4054 		tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4055 
4056 	log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4057 		<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias);
4058 
4059 	// for compressed formats source buffer access is not actual compressed format
4060 	// but equivalent uncompressed format that is some cases needs additional
4061 	// modifications so that sampling it will produce valid reference
4062 	if ((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
4063 		(format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK))
4064 	{
4065 		if (resultFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
4066 		{
4067 			// for compressed formats we are using random data and for some formats it
4068 			// can be outside of <-1;1> range - for cases where result is not a float
4069 			// format we need to clamp source to <-1;1> range as this will be done on
4070 			// the device but not in software sampler in framework
4071 			clampSource = true;
4072 			// for this format we also need to clamp the result as precision of
4073 			// this format is smaller then precision of calculations in framework;
4074 			// the biger color valus are the bigger errors can be
4075 			clampResult = true;
4076 
4077 			if (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)
4078 				clampSourceMinValue = tcu::Vec4(0.0f);
4079 		}
4080 		else if ((resultFormat.type != tcu::TextureFormat::FLOAT) &&
4081 				 (resultFormat.type != tcu::TextureFormat::HALF_FLOAT))
4082 		{
4083 			// clamp source for all non float formats
4084 			clampSource = true;
4085 		}
4086 	}
4087 
4088 	if (isUnormFormat(nativeResultFormat) || isUfloatFormat(nativeResultFormat))
4089 	{
4090 		// when tested compressed format is signed but the result format
4091 		// is unsigned we need to clamp source to <0; x> so that proper
4092 		// reference is calculated
4093 		if ((format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11) ||
4094 			(format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11) ||
4095 			(format == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK) ||
4096 			(format == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK) ||
4097 			(format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
4098 		{
4099 			clampSource			= true;
4100 			clampSourceMinValue	= tcu::Vec4(0.0f);
4101 		}
4102 	}
4103 
4104 	if (clampSource || clampResult)
4105 	{
4106 		if (clampSource)
4107 		{
4108 			clampedSourceLevel.setStorage(source.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
4109 			tcu::PixelBufferAccess clampedSourceAcccess(clampedSourceLevel.getAccess());
4110 
4111 			for (deInt32 z = 0; z < source.getDepth() ; z++)
4112 			for (deInt32 y = 0; y < source.getHeight() ; y++)
4113 			for (deInt32 x = 0; x < source.getWidth() ; x++)
4114 			{
4115 				tcu::Vec4 texel = source.getPixel(x, y, z);
4116 				texel = tcu::clamp(texel, tcu::Vec4(clampSourceMinValue), tcu::Vec4(clampSourceMaxValue));
4117 				clampedSourceAcccess.setPixel(texel, x, y, z);
4118 			}
4119 		}
4120 
4121 		if (clampResult)
4122 		{
4123 			clampedResultLevel.setStorage(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
4124 			tcu::PixelBufferAccess clampedResultAcccess(clampedResultLevel.getAccess());
4125 
4126 			for (deInt32 z = 0; z < result.getDepth() ; z++)
4127 			for (deInt32 y = 0; y < result.getHeight() ; y++)
4128 			for (deInt32 x = 0; x < result.getWidth() ; x++)
4129 			{
4130 				tcu::Vec4 texel = result.getPixel(x, y, z);
4131 				texel = tcu::clamp(texel, tcu::Vec4(-1.0f), tcu::Vec4(1.0f));
4132 				clampedResultAcccess.setPixel(texel, x, y, z);
4133 			}
4134 		}
4135 	}
4136 
4137 	const tcu::ConstPixelBufferAccess src = clampSource ? clampedSourceLevel.getAccess() : source;
4138 	const tcu::ConstPixelBufferAccess res = clampResult ? clampedResultLevel.getAccess() : result;
4139 
4140 	if (floatNearestBlitCompare(src, res, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions))
4141 	{
4142 		log << tcu::TestLog::EndImageSet;
4143 		return true;
4144 	}
4145 
4146 	log << tcu::TestLog::Image("ErrorMask",	"Error mask", errorMask)
4147 		<< tcu::TestLog::EndImageSet;
4148 	return false;
4149 }
4150 
checkTestResult(tcu::ConstPixelBufferAccess result)4151 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
4152 {
4153 	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
4154 	const std::string failMessage("Result image is incorrect");
4155 
4156 	if (m_params.filter != VK_FILTER_NEAREST)
4157 	{
4158 		if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4159 		{
4160 			if (tcu::hasDepthComponent(result.getFormat().order))
4161 			{
4162 				const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_DEPTH;
4163 				const tcu::ConstPixelBufferAccess		depthResult			= tcu::getEffectiveDepthStencilAccess(result, mode);
4164 				const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4165 				const tcu::ConstPixelBufferAccess		unclampedExpected	= tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4166 				const tcu::TextureFormat				sourceFormat		= tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4167 
4168 				if (!checkNonNearestFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
4169 					return tcu::TestStatus::fail(failMessage);
4170 			}
4171 
4172 			if (tcu::hasStencilComponent(result.getFormat().order))
4173 			{
4174 				const tcu::Sampler::DepthStencilMode	mode				= tcu::Sampler::MODE_STENCIL;
4175 				const tcu::ConstPixelBufferAccess		stencilResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
4176 				const tcu::ConstPixelBufferAccess		clampedExpected		= tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4177 				const tcu::ConstPixelBufferAccess		unclampedExpected	= tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4178 				const tcu::TextureFormat				sourceFormat		= tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4179 
4180 				if (!checkNonNearestFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
4181 					return tcu::TestStatus::fail(failMessage);
4182 			}
4183 		}
4184 		else if (m_sourceCompressedTexture)
4185 		{
4186 			const tcu::CompressedTexture& compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4187 			if (!checkCompressedNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), compressedLevel.getFormat()))
4188 				return tcu::TestStatus::fail(failMessage);
4189 		}
4190 		else
4191 		{
4192 			const tcu::TextureFormat sourceFormat = mapVkFormat(m_params.src.image.format);
4193 			if (!checkNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
4194 				return tcu::TestStatus::fail(failMessage);
4195 		}
4196 	}
4197 	else // NEAREST filtering
4198 	{
4199 		if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4200 		{
4201 			if (tcu::hasDepthComponent(result.getFormat().order))
4202 			{
4203 				const tcu::Sampler::DepthStencilMode	mode			= tcu::Sampler::MODE_DEPTH;
4204 				const tcu::ConstPixelBufferAccess		depthResult		= tcu::getEffectiveDepthStencilAccess(result, mode);
4205 				const tcu::ConstPixelBufferAccess		depthSource		= tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4206 
4207 				if (!checkNearestFilteredResult(depthResult, depthSource))
4208 					return tcu::TestStatus::fail(failMessage);
4209 			}
4210 
4211 			if (tcu::hasStencilComponent(result.getFormat().order))
4212 			{
4213 				const tcu::Sampler::DepthStencilMode	mode			= tcu::Sampler::MODE_STENCIL;
4214 				const tcu::ConstPixelBufferAccess		stencilResult	= tcu::getEffectiveDepthStencilAccess(result, mode);
4215 				const tcu::ConstPixelBufferAccess		stencilSource	= tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4216 
4217 				if (!checkNearestFilteredResult(stencilResult, stencilSource))
4218 					return tcu::TestStatus::fail(failMessage);
4219 			}
4220 		}
4221 		else if (m_sourceCompressedTexture)
4222 		{
4223 			const tcu::CompressedTexture& compressedLevel	= m_sourceCompressedTexture->getCompressedTexture();
4224 			const tcu::PixelBufferAccess& decompressedLevel	= m_sourceCompressedTexture->getDecompressedAccess();
4225 
4226 			if (!checkCompressedNearestFilteredResult(result, decompressedLevel, compressedLevel.getFormat()))
4227 				return tcu::TestStatus::fail(failMessage);
4228 		}
4229 		else if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
4230 			return tcu::TestStatus::fail(failMessage);
4231 	}
4232 
4233 	return tcu::TestStatus::pass("Pass");
4234 }
4235 
linearToSRGBIfNeeded(const tcu::TextureFormat & format,const tcu::Vec4 & color)4236 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
4237 {
4238 	return isSRGB(format) ? linearToSRGB(color) : color;
4239 }
4240 
scaleFromWholeSrcBuffer(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const VkOffset3D regionOffset,const VkOffset3D regionExtent,tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode=0u)4241 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = 0u)
4242 {
4243 	DE_ASSERT(filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4244 
4245 	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4246 					filter, filter, 0.0f, false, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
4247 
4248 	float sX = (float)regionExtent.x / (float)dst.getWidth();
4249 	float sY = (float)regionExtent.y / (float)dst.getHeight();
4250 	float sZ = (float)regionExtent.z / (float)dst.getDepth();
4251 
4252 	for (int z = 0; z < dst.getDepth(); z++)
4253 	for (int y = 0; y < dst.getHeight(); y++)
4254 	for (int x = 0; x < dst.getWidth(); x++)
4255 	{
4256 		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;
4257 		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;
4258 		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;
4259 		if (dst.getDepth() > 1)
4260 			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, srcX, srcY, srcZ)), x, y, z);
4261 		else
4262 			dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x, y);
4263 	}
4264 }
4265 
blit(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode)4266 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
4267 {
4268 	DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4269 
4270 	tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4271 			filter, filter, 0.0f, false, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
4272 
4273 	const float sX = (float)src.getWidth() / (float)dst.getWidth();
4274 	const float sY = (float)src.getHeight() / (float)dst.getHeight();
4275 	const float sZ = (float)src.getDepth() / (float)dst.getDepth();
4276 
4277 	const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
4278 	const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
4279 	const int zOffset = (mirrorMode & MIRROR_MODE_Z) ? dst.getDepth() - 1 : 0;
4280 
4281 	const int xScale = (mirrorMode & MIRROR_MODE_X) ? -1 : 1;
4282 	const int yScale = (mirrorMode & MIRROR_MODE_Y) ? -1 : 1;
4283 	const int zScale = (mirrorMode & MIRROR_MODE_Z) ? -1 : 1;
4284 
4285 	for (int z = 0; z < dst.getDepth(); ++z)
4286 	for (int y = 0; y < dst.getHeight(); ++y)
4287 	for (int x = 0; x < dst.getWidth(); ++x)
4288 	{
4289 		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);
4290 	}
4291 }
4292 
flipCoordinates(CopyRegion & region,const MirrorMode mirrorMode)4293 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
4294 {
4295 	const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
4296 	const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
4297 	const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
4298 	const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
4299 
4300 	if (mirrorMode != 0u)
4301 	{
4302 		//sourceRegion
4303 		region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
4304 		region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
4305 		region.imageBlit.srcOffsets[0].z = std::min(srcOffset0.z, srcOffset1.z);
4306 
4307 		region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
4308 		region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
4309 		region.imageBlit.srcOffsets[1].z = std::max(srcOffset0.z, srcOffset1.z);
4310 
4311 		//destinationRegion
4312 		region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
4313 		region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
4314 		region.imageBlit.dstOffsets[0].z = std::min(dstOffset0.z, dstOffset1.z);
4315 
4316 		region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
4317 		region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
4318 		region.imageBlit.dstOffsets[1].z = std::max(dstOffset0.z, dstOffset1.z);
4319 	}
4320 }
4321 
4322 // Mirror X, Y and Z as required by the offset values in the 3 axes.
getMirrorMode(const VkOffset3D from,const VkOffset3D to)4323 MirrorMode getMirrorMode(const VkOffset3D from, const VkOffset3D to)
4324 {
4325 	MirrorMode mode = 0u;
4326 
4327 	if (from.x > to.x)
4328 		mode |= MIRROR_MODE_X;
4329 
4330 	if (from.y > to.y)
4331 		mode |= MIRROR_MODE_Y;
4332 
4333 	if (from.z > to.z)
4334 		mode |= MIRROR_MODE_Z;
4335 
4336 	return mode;
4337 }
4338 
4339 // 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)4340 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
4341 {
4342 	static const MirrorModeBits kBits[] = { MIRROR_MODE_X, MIRROR_MODE_Y, MIRROR_MODE_Z };
4343 
4344 	const MirrorMode source		 = getMirrorMode(s1, s2);
4345 	const MirrorMode destination = getMirrorMode(d1, d2);
4346 
4347 	MirrorMode mode = 0u;
4348 
4349 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(kBits); ++i)
4350 	{
4351 		const MirrorModeBits bit = kBits[i];
4352 		if ((source & bit) != (destination & bit))
4353 			mode |= bit;
4354 	}
4355 
4356 	return mode;
4357 }
4358 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)4359 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
4360 {
4361 	DE_UNREF(mipLevel);
4362 
4363 	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
4364 												region.imageBlit.srcOffsets[1],
4365 												region.imageBlit.dstOffsets[0],
4366 												region.imageBlit.dstOffsets[1]);
4367 
4368 	flipCoordinates(region, mirrorMode);
4369 
4370 	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
4371 	const VkOffset3D					srcExtent		=
4372 	{
4373 		region.imageBlit.srcOffsets[1].x - srcOffset.x,
4374 		region.imageBlit.srcOffsets[1].y - srcOffset.y,
4375 		region.imageBlit.srcOffsets[1].z - srcOffset.z,
4376 	};
4377 	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
4378 	const VkOffset3D					dstExtent		=
4379 	{
4380 		region.imageBlit.dstOffsets[1].x - dstOffset.x,
4381 		region.imageBlit.dstOffsets[1].y - dstOffset.y,
4382 		region.imageBlit.dstOffsets[1].z - dstOffset.z,
4383 	};
4384 
4385 	tcu::Sampler::FilterMode		filter;
4386 	switch (m_params.filter)
4387 	{
4388 		case VK_FILTER_LINEAR:		filter = tcu::Sampler::LINEAR; break;
4389 		case VK_FILTER_CUBIC_EXT:	filter = tcu::Sampler::CUBIC;  break;
4390 		case VK_FILTER_NEAREST:
4391 		default:					filter = tcu::Sampler::NEAREST;  break;
4392 	}
4393 
4394 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
4395 	{
4396 		DE_ASSERT(src.getFormat() == dst.getFormat());
4397 
4398 		// Scale depth.
4399 		if (tcu::hasDepthComponent(src.getFormat().order))
4400 		{
4401 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_DEPTH);
4402 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
4403 			tcu::scale(dstSubRegion, srcSubRegion, filter);
4404 
4405 			if (filter != tcu::Sampler::NEAREST)
4406 			{
4407 				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
4408 				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);
4409 				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
4410 			}
4411 		}
4412 
4413 		// Scale stencil.
4414 		if (tcu::hasStencilComponent(src.getFormat().order))
4415 		{
4416 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_STENCIL);
4417 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
4418 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4419 
4420 			if (filter != tcu::Sampler::NEAREST)
4421 			{
4422 				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
4423 				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);
4424 				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
4425 			}
4426 		}
4427 	}
4428 	else
4429 	{
4430 		const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z);
4431 		const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4432 		blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4433 
4434 		if (filter != tcu::Sampler::NEAREST)
4435 		{
4436 			const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4437 			scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
4438 		}
4439 	}
4440 }
4441 
generateExpectedResult(void)4442 void BlittingImages::generateExpectedResult (void)
4443 {
4444 	const tcu::ConstPixelBufferAccess src = m_sourceCompressedTexture ? m_sourceCompressedTexture->getDecompressedAccess() : m_sourceTextureLevel->getAccess();
4445 	const tcu::ConstPixelBufferAccess dst = m_destinationCompressedTexture ? m_destinationCompressedTexture->getDecompressedAccess() : m_destinationTextureLevel->getAccess();
4446 
4447 	m_expectedTextureLevel[0]		= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4448 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
4449 
4450 	if (m_params.filter != VK_FILTER_NEAREST)
4451 	{
4452 		m_unclampedExpectedTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4453 		tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
4454 	}
4455 
4456 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
4457 	{
4458 		CopyRegion region = m_params.regions[i];
4459 		copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
4460 	}
4461 }
4462 
uploadCompressedImage(const VkImage & image,const ImageParms & parms)4463 void BlittingImages::uploadCompressedImage (const VkImage& image, const ImageParms& parms)
4464 {
4465 	DE_ASSERT(m_sourceCompressedTexture);
4466 
4467 	const InstanceInterface&		vki					= m_context.getInstanceInterface();
4468 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
4469 	const VkPhysicalDevice			vkPhysDevice		= m_context.getPhysicalDevice();
4470 	const VkDevice					vkDevice			= m_device;
4471 	const VkQueue					queue				= m_queue;
4472 	Allocator&						memAlloc			= *m_allocator;
4473 	Move<VkBuffer>					buffer;
4474 	const deUint32					bufferSize			= m_sourceCompressedTexture->getCompressedTexture().getDataSize();
4475 	de::MovePtr<Allocation>			bufferAlloc;
4476 	const deUint32					arraySize			= getArraySize(parms);
4477 	const VkExtent3D				imageExtent
4478 	{
4479 		parms.extent.width,
4480 		(parms.imageType != VK_IMAGE_TYPE_1D) ? parms.extent.height : 1u,
4481 		(parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
4482 	};
4483 
4484 	// Create source buffer
4485 	{
4486 		const VkBufferCreateInfo bufferParams
4487 		{
4488 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
4489 			DE_NULL,									// const void*			pNext;
4490 			0u,											// VkBufferCreateFlags	flags;
4491 			bufferSize,									// VkDeviceSize			size;
4492 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
4493 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
4494 			0u,											// deUint32				queueFamilyIndexCount;
4495 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
4496 		};
4497 
4498 		buffer		= createBuffer(vk, vkDevice, &bufferParams);
4499 		bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
4500 		VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
4501 	}
4502 
4503 	// Barriers for copying buffer to image
4504 	const VkBufferMemoryBarrier preBufferBarrier
4505 	{
4506 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
4507 		DE_NULL,										// const void*		pNext;
4508 		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
4509 		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
4510 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
4511 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
4512 		*buffer,										// VkBuffer			buffer;
4513 		0u,												// VkDeviceSize		offset;
4514 		bufferSize										// VkDeviceSize		size;
4515 	};
4516 
4517 	const VkImageMemoryBarrier preImageBarrier
4518 	{
4519 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
4520 		DE_NULL,										// const void*				pNext;
4521 		0u,												// VkAccessFlags			srcAccessMask;
4522 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
4523 		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout;
4524 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
4525 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
4526 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
4527 		image,											// VkImage					image;
4528 		{												// VkImageSubresourceRange	subresourceRange;
4529 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspect;
4530 			0u,							// deUint32				baseMipLevel;
4531 			1u,							// deUint32				mipLevels;
4532 			0u,							// deUint32				baseArraySlice;
4533 			arraySize,					// deUint32				arraySize;
4534 		}
4535 	};
4536 
4537 	const VkImageMemoryBarrier postImageBarrier
4538 	{
4539 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
4540 		DE_NULL,										// const void*				pNext;
4541 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask;
4542 		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
4543 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout;
4544 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout;
4545 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
4546 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex;
4547 		image,											// VkImage					image;
4548 		{												// VkImageSubresourceRange	subresourceRange;
4549 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspect;
4550 			0u,								// deUint32				baseMipLevel;
4551 			1u,								// deUint32				mipLevels;
4552 			0u,								// deUint32				baseArraySlice;
4553 			arraySize,						// deUint32				arraySize;
4554 		}
4555 	};
4556 
4557 	const VkExtent3D copyExtent
4558 	{
4559 		imageExtent.width,
4560 		imageExtent.height,
4561 		imageExtent.depth
4562 	};
4563 
4564 	VkBufferImageCopy copyRegion
4565 	{
4566 		0u,												// VkDeviceSize				bufferOffset;
4567 		copyExtent.width,								// deUint32					bufferRowLength;
4568 		copyExtent.height,								// deUint32					bufferImageHeight;
4569 		{
4570 			VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspect;
4571 			0u,												// deUint32				mipLevel;
4572 			0u,												// deUint32				baseArrayLayer;
4573 			arraySize,										// deUint32				layerCount;
4574 		},												// VkImageSubresourceLayers	imageSubresource;
4575 		{ 0, 0, 0 },									// VkOffset3D				imageOffset;
4576 		copyExtent										// VkExtent3D				imageExtent;
4577 	};
4578 
4579 	// Write buffer data
4580 	deMemcpy(bufferAlloc->getHostPtr(), m_sourceCompressedTexture->getCompressedTexture().getData(), bufferSize);
4581 	flushAlloc(vk, vkDevice, *bufferAlloc);
4582 
4583 	// Copy buffer to image
4584 	beginCommandBuffer(vk, *m_cmdBuffer);
4585 	vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
4586 						  1, &preBufferBarrier, 1, &preImageBarrier);
4587 	vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
4588 	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);
4589 	endCommandBuffer(vk, *m_cmdBuffer);
4590 
4591 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4592 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
4593 }
4594 
4595 
4596 class BlitImageTestCase : public vkt::TestCase
4597 {
4598 public:
BlitImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)4599 							BlitImageTestCase		(tcu::TestContext&				testCtx,
4600 													 const std::string&				name,
4601 													 const std::string&				description,
4602 													 const TestParams				params)
4603 								: vkt::TestCase	(testCtx, name, description)
4604 								, m_params		(params)
4605 	{}
4606 
createInstance(Context & context) const4607 	virtual TestInstance*	createInstance			(Context&						context) const
4608 	{
4609 		return new BlittingImages(context, m_params);
4610 	}
4611 
checkSupport(Context & context) const4612 	virtual void			checkSupport			(Context&						context) const
4613 	{
4614 		VkImageFormatProperties properties;
4615 		if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4616 																					m_params.src.image.format,
4617 																					m_params.src.image.imageType,
4618 																					m_params.src.image.tiling,
4619 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
4620 																					0,
4621 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4622 		{
4623 			TCU_THROW(NotSupportedError, "Source format not supported");
4624 		}
4625 		if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4626 																					m_params.dst.image.format,
4627 																					m_params.dst.image.imageType,
4628 																					m_params.dst.image.tiling,
4629 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4630 																					0,
4631 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4632 		{
4633 			TCU_THROW(NotSupportedError, "Destination format not supported");
4634 		}
4635 
4636 		VkFormatProperties srcFormatProperties;
4637 		context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
4638 		VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ? srcFormatProperties.linearTilingFeatures : srcFormatProperties.optimalTilingFeatures;
4639 		if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
4640 		{
4641 			TCU_THROW(NotSupportedError, "Format feature blit source not supported");
4642 		}
4643 
4644 		VkFormatProperties dstFormatProperties;
4645 		context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
4646 		VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ? dstFormatProperties.linearTilingFeatures : dstFormatProperties.optimalTilingFeatures;
4647 		if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
4648 		{
4649 			TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
4650 		}
4651 
4652 		if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
4653 		{
4654 			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
4655 		}
4656 
4657 		if (m_params.filter == VK_FILTER_CUBIC_EXT)
4658 		{
4659 			context.requireDeviceFunctionality("VK_EXT_filter_cubic");
4660 
4661 			if (!(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
4662 			{
4663 				TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
4664 			}
4665 		}
4666 
4667 		if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
4668 		{
4669 			if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
4670 			{
4671 				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
4672 			}
4673 		}
4674 	}
4675 
4676 private:
4677 	TestParams				m_params;
4678 };
4679 
4680 class BlittingMipmaps : public CopiesAndBlittingTestInstance
4681 {
4682 public:
4683 										BlittingMipmaps					(Context&   context,
4684 																		 TestParams params);
4685 	virtual tcu::TestStatus				iterate							(void);
4686 protected:
4687 	virtual tcu::TestStatus				checkTestResult					(tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
4688 	virtual void						copyRegionToTextureLevel		(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
4689 	virtual void						generateExpectedResult			(void);
4690 private:
4691 	bool								checkNonNearestFilteredResult	(void);
4692 	bool								checkNearestFilteredResult		(void);
4693 
4694 	Move<VkImage>						m_source;
4695 	de::MovePtr<Allocation>				m_sourceImageAlloc;
4696 	Move<VkImage>						m_destination;
4697 	de::MovePtr<Allocation>				m_destinationImageAlloc;
4698 
4699 	de::MovePtr<tcu::TextureLevel>		m_unclampedExpectedTextureLevel[16];
4700 };
4701 
BlittingMipmaps(Context & context,TestParams params)4702 BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params)
4703 	: CopiesAndBlittingTestInstance (context, params)
4704 {
4705 	const InstanceInterface&	vki					= context.getInstanceInterface();
4706 	const DeviceInterface&		vk					= context.getDeviceInterface();
4707 	const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
4708 	const VkDevice				vkDevice			= m_device;
4709 	Allocator&					memAlloc			= context.getDefaultAllocator();
4710 
4711 	// Create source image
4712 	{
4713 		const VkImageCreateInfo		sourceImageParams		=
4714 		{
4715 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
4716 			DE_NULL,								// const void*			pNext;
4717 			getCreateFlags(m_params.src.image),		// VkImageCreateFlags	flags;
4718 			m_params.src.image.imageType,			// VkImageType			imageType;
4719 			m_params.src.image.format,				// VkFormat				format;
4720 			getExtent3D(m_params.src.image),		// VkExtent3D			extent;
4721 			1u,										// deUint32				mipLevels;
4722 			getArraySize(m_params.src.image),		// deUint32				arraySize;
4723 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
4724 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
4725 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4726 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
4727 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
4728 			0u,										// deUint32				queueFamilyIndexCount;
4729 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
4730 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
4731 		};
4732 
4733 		m_source = createImage(vk, vkDevice, &sourceImageParams);
4734 		m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
4735 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
4736 	}
4737 
4738 	// Create destination image
4739 	{
4740 		const VkImageCreateInfo		destinationImageParams  =
4741 		{
4742 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
4743 			DE_NULL,								// const void*			pNext;
4744 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
4745 			m_params.dst.image.imageType,			// VkImageType			imageType;
4746 			m_params.dst.image.format,				// VkFormat				format;
4747 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
4748 			m_params.mipLevels,						// deUint32				mipLevels;
4749 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
4750 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
4751 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
4752 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4753 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
4754 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
4755 			0u,										// deUint32				queueFamilyIndexCount;
4756 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
4757 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
4758 		};
4759 
4760 		m_destination = createImage(vk, vkDevice, &destinationImageParams);
4761 		m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
4762 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
4763 	}
4764 }
4765 
iterate(void)4766 tcu::TestStatus BlittingMipmaps::iterate (void)
4767 {
4768 	const tcu::TextureFormat	srcTcuFormat		= mapVkFormat(m_params.src.image.format);
4769 	const tcu::TextureFormat	dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
4770 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
4771 																				m_params.src.image.extent.width,
4772 																				m_params.src.image.extent.height,
4773 																				m_params.src.image.extent.depth));
4774 	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);
4775 	m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
4776 																						(int)m_params.dst.image.extent.width,
4777 																						(int)m_params.dst.image.extent.height,
4778 																						(int)m_params.dst.image.extent.depth));
4779 	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);
4780 	generateExpectedResult();
4781 
4782 	uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
4783 
4784 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
4785 
4786 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
4787 	const VkDevice				vkDevice			= m_device;
4788 	const VkQueue				queue				= m_queue;
4789 
4790 	std::vector<VkImageBlit>		regions;
4791 	std::vector<VkImageBlit2KHR>	regions2KHR;
4792 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
4793 	{
4794 		if (m_params.extensionUse == EXTENSION_USE_NONE)
4795 		{
4796 			regions.push_back(m_params.regions[i].imageBlit);
4797 		}
4798 		else
4799 		{
4800 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4801 			regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
4802 		}
4803 	}
4804 
4805 	// Copy source image to mip level 0 when generating mipmaps with multiple blit commands
4806 	if (!m_params.singleCommand)
4807 		uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
4808 
4809 	beginCommandBuffer(vk, *m_cmdBuffer);
4810 
4811 	// Blit all mip levels with a single blit command
4812 	if (m_params.singleCommand)
4813 	{
4814 		{
4815 			// Source image layout
4816 			const VkImageMemoryBarrier		srcImageBarrier		=
4817 			{
4818 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4819 				DE_NULL,									// const void*				pNext;
4820 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4821 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
4822 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
4823 				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
4824 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4825 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4826 				m_source.get(),								// VkImage					image;
4827 				{											// VkImageSubresourceRange	subresourceRange;
4828 					getAspectFlags(srcTcuFormat),		// VkImageAspectFlags   aspectMask;
4829 					0u,									// deUint32				baseMipLevel;
4830 					1u,									// deUint32				mipLevels;
4831 					0u,									// deUint32				baseArraySlice;
4832 					getArraySize(m_params.src.image)	// deUint32				arraySize;
4833 				}
4834 			};
4835 
4836 			// Destination image layout
4837 			const VkImageMemoryBarrier		dstImageBarrier		=
4838 			{
4839 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4840 				DE_NULL,									// const void*				pNext;
4841 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4842 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
4843 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
4844 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
4845 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4846 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4847 				m_destination.get(),						// VkImage					image;
4848 				{											// VkImageSubresourceRange	subresourceRange;
4849 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags   aspectMask;
4850 					0u,									// deUint32				baseMipLevel;
4851 					m_params.mipLevels,					// deUint32				mipLevels;
4852 					0u,									// deUint32				baseArraySlice;
4853 					getArraySize(m_params.dst.image)	// deUint32				arraySize;
4854 				}
4855 			};
4856 
4857 			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);
4858 			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);
4859 
4860 			if (m_params.extensionUse == EXTENSION_USE_NONE)
4861 			{
4862 				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);
4863 			}
4864 #ifndef CTS_USES_VULKANSC
4865 			else
4866 			{
4867 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4868 				const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4869 				{
4870 					VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
4871 					DE_NULL,									// const void*					pNext;
4872 					m_source.get(),								// VkImage						srcImage;
4873 					m_params.src.image.operationLayout,			// VkImageLayout				srcImageLayout;
4874 					m_destination.get(),						// VkImage						dstImage;
4875 					m_params.dst.image.operationLayout,			// VkImageLayout				dstImageLayout;
4876 					(deUint32)m_params.regions.size(),			// uint32_t						regionCount;
4877 					&regions2KHR[0],							// const VkImageBlit2KHR*		pRegions;
4878 					m_params.filter								// VkFilter						filter;
4879 				};
4880 				vk.cmdBlitImage2(*m_cmdBuffer, &BlitImageInfo2KHR);
4881 			}
4882 #endif // CTS_USES_VULKANSC
4883 		}
4884 	}
4885 	// Blit mip levels with multiple blit commands
4886 	else
4887 	{
4888 		// Prepare all mip levels for reading
4889 		{
4890 			for (deUint32 barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
4891 			{
4892 				VkImageMemoryBarrier preImageBarrier =
4893 				{
4894 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,									// VkStructureType	sType;
4895 					DE_NULL,																// const void*		pNext;
4896 					VK_ACCESS_TRANSFER_WRITE_BIT,											// VkAccessFlags	srcAccessMask;
4897 					VK_ACCESS_TRANSFER_READ_BIT,											// VkAccessFlags	dstAccessMask;
4898 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,									// VkImageLayout	oldLayout;
4899 					m_params.src.image.operationLayout,										// VkImageLayout	newLayout;
4900 					VK_QUEUE_FAMILY_IGNORED,												// deUint32			srcQueueFamilyIndex;
4901 					VK_QUEUE_FAMILY_IGNORED,												// deUint32			dstQueueFamilyIndex;
4902 					m_destination.get(),													// VkImage			image;
4903 					{																		// VkImageSubresourceRange	subresourceRange;
4904 						getAspectFlags(dstTcuFormat),										// VkImageAspectFlags	aspectMask;
4905 							0u,																// deUint32				baseMipLevel;
4906 							VK_REMAINING_MIP_LEVELS,										// deUint32				mipLevels;
4907 							0u,																// deUint32				baseArraySlice;
4908 							getArraySize(m_params.src.image)								// deUint32				arraySize;
4909 					}
4910 				};
4911 
4912 				if (getArraySize(m_params.src.image) == 1)
4913 				{
4914 					DE_ASSERT(barrierno < m_params.mipLevels);
4915 					preImageBarrier.subresourceRange.baseMipLevel	= barrierno;
4916 					preImageBarrier.subresourceRange.levelCount		= (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
4917 				}
4918 				else
4919 				{
4920 					preImageBarrier.subresourceRange.baseArrayLayer	= barrierno;
4921 					preImageBarrier.subresourceRange.layerCount		= (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
4922 				}
4923 				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);
4924 			}
4925 		}
4926 
4927 		for (deUint32 regionNdx = 0u; regionNdx < (deUint32)m_params.regions.size(); regionNdx++)
4928 		{
4929 			const deUint32	mipLevel	= m_params.regions[regionNdx].imageBlit.dstSubresource.mipLevel;
4930 
4931 			// Prepare single mip level for writing
4932 			const VkImageMemoryBarrier		preImageBarrier		=
4933 			{
4934 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4935 				DE_NULL,									// const void*					pNext;
4936 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
4937 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
4938 				m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
4939 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
4940 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4941 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4942 				m_destination.get(),						// VkImage					image;
4943 				{											// VkImageSubresourceRange	subresourceRange;
4944 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
4945 					mipLevel,							// deUint32				baseMipLevel;
4946 					1u,									// deUint32				mipLevels;
4947 					0u,									// deUint32				baseArraySlice;
4948 					getArraySize(m_params.dst.image)	// deUint32				arraySize;
4949 				}
4950 			};
4951 
4952 			// Prepare single mip level for reading
4953 			const VkImageMemoryBarrier		postImageBarrier	=
4954 			{
4955 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
4956 				DE_NULL,									// const void*				pNext;
4957 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
4958 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
4959 				m_params.dst.image.operationLayout,			// VkImageLayout			oldLayout;
4960 				m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
4961 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
4962 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
4963 				m_destination.get(),						// VkImage					image;
4964 				{											// VkImageSubresourceRange	subresourceRange;
4965 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
4966 					mipLevel,							// deUint32				baseMipLevel;
4967 					1u,									// deUint32				mipLevels;
4968 					0u,									// deUint32				baseArraySlice;
4969 					getArraySize(m_params.src.image)	// deUint32				arraySize;
4970 				}
4971 			};
4972 
4973 			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);
4974 
4975 			if (m_params.extensionUse == EXTENSION_USE_NONE)
4976 			{
4977 				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);
4978 			}
4979 #ifndef CTS_USES_VULKANSC
4980 			else
4981 			{
4982 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4983 				const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4984 				{
4985 					VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
4986 					DE_NULL,									// const void*					pNext;
4987 					m_destination.get(),						// VkImage						srcImage;
4988 					m_params.src.image.operationLayout,			// VkImageLayout				srcImageLayout;
4989 					m_destination.get(),						// VkImage						dstImage;
4990 					m_params.dst.image.operationLayout,			// VkImageLayout				dstImageLayout;
4991 					1u,											// uint32_t						regionCount;
4992 					&regions2KHR[regionNdx],					// const VkImageBlit2KHR*		pRegions;
4993 					m_params.filter								// VkFilter						filter;
4994 				};
4995 				vk.cmdBlitImage2(*m_cmdBuffer, &BlitImageInfo2KHR);
4996 			}
4997 #endif // CTS_USES_VULKANSC
4998 
4999 			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);
5000 		}
5001 
5002 		// Prepare all mip levels for writing
5003 		{
5004 			const VkImageMemoryBarrier		postImageBarrier		=
5005 			{
5006 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5007 				DE_NULL,									// const void*				pNext;
5008 				VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			srcAccessMask;
5009 				VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
5010 				m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
5011 				m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
5012 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5013 				VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5014 				m_destination.get(),						// VkImage					image;
5015 				{											// VkImageSubresourceRange	subresourceRange;
5016 					getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
5017 					0u,									// deUint32				baseMipLevel;
5018 					VK_REMAINING_MIP_LEVELS,			// deUint32				mipLevels;
5019 					0u,									// deUint32				baseArraySlice;
5020 					getArraySize(m_params.dst.image)	// deUint32				arraySize;
5021 				}
5022 			};
5023 
5024 			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);
5025 		}
5026 	}
5027 
5028 	endCommandBuffer(vk, *m_cmdBuffer);
5029 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
5030 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
5031 
5032 	return checkTestResult();
5033 }
5034 
checkNonNearestFilteredResult(void)5035 bool BlittingMipmaps::checkNonNearestFilteredResult (void)
5036 {
5037 	tcu::TestLog&				log				(m_context.getTestContext().getLog());
5038 	bool						allLevelsOk		= true;
5039 
5040 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5041 	{
5042 		// Update reference results with previous results that have been verified.
5043 		// This needs to be done such that accumulated errors don't exceed the fixed threshold.
5044 		for (deUint32 i = 0; i < m_params.regions.size(); i++)
5045 		{
5046 			const CopyRegion region = m_params.regions[i];
5047 			const deUint32 srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
5048 			const deUint32 dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
5049 			de::MovePtr<tcu::TextureLevel>	prevResultLevel;
5050 			tcu::ConstPixelBufferAccess src;
5051 			if (srcMipLevel < mipLevelNdx)
5052 			{
5053 				// Generate expected result from rendered result that was previously verified
5054 				prevResultLevel	= readImage(*m_destination, m_params.dst.image, srcMipLevel);
5055 				src = prevResultLevel->getAccess();
5056 			}
5057 			else
5058 			{
5059 				// Previous reference mipmaps might have changed, so recompute expected result
5060 				src = m_expectedTextureLevel[srcMipLevel]->getAccess();
5061 			}
5062 			copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
5063 		}
5064 
5065 		de::MovePtr<tcu::TextureLevel>			resultLevel			= readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5066 		const tcu::ConstPixelBufferAccess&		resultAccess		= resultLevel->getAccess();
5067 
5068 		const tcu::Sampler::DepthStencilMode	mode				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::Sampler::MODE_DEPTH :
5069 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
5070 																																	tcu::Sampler::MODE_LAST;
5071 		const tcu::ConstPixelBufferAccess		result				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5072 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5073 																																	resultAccess;
5074 		const tcu::ConstPixelBufferAccess		clampedLevel		= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5075 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5076 																																	m_expectedTextureLevel[mipLevelNdx]->getAccess();
5077 		const tcu::ConstPixelBufferAccess		unclampedLevel		= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5078 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5079 																																	m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
5080 		const tcu::TextureFormat				srcFormat			= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5081 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5082 																																	mapVkFormat(m_params.src.image.format);
5083 
5084 		const tcu::TextureFormat				dstFormat			= result.getFormat();
5085 		bool									singleLevelOk		= false;
5086 		std::vector <CopyRegion>				mipLevelRegions;
5087 
5088 		for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5089 			if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5090 				mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5091 
5092 		log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
5093 
5094 		if (isFloatFormat(dstFormat))
5095 		{
5096 			const bool		srcIsSRGB   = tcu::isSRGB(srcFormat);
5097 			const tcu::Vec4 srcMaxDiff  = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
5098 			const tcu::Vec4 dstMaxDiff  = getFormatThreshold(dstFormat);
5099 			const tcu::Vec4 threshold   = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT)? 1.5f : 1.0f);
5100 
5101 			singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5102 			log << tcu::TestLog::EndSection;
5103 
5104 			if (!singleLevelOk)
5105 			{
5106 				log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5107 				singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5108 				log << tcu::TestLog::EndSection;
5109 			}
5110 		}
5111 		else
5112 		{
5113 			tcu::UVec4  threshold;
5114 			// Calculate threshold depending on channel width of destination format.
5115 			const tcu::IVec4	dstBitDepth	= tcu::getTextureFormatBitDepth(dstFormat);
5116 			const tcu::IVec4	srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
5117 			for (deUint32 i = 0; i < 4; ++i)
5118 				threshold[i] = 1 + de::max(((1 << dstBitDepth[i]) - 1) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
5119 
5120 			singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5121 			log << tcu::TestLog::EndSection;
5122 
5123 			if (!singleLevelOk)
5124 			{
5125 				log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5126 				singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5127 				log << tcu::TestLog::EndSection;
5128 			}
5129 		}
5130 		allLevelsOk &= singleLevelOk;
5131 	}
5132 
5133 	return allLevelsOk;
5134 }
5135 
checkNearestFilteredResult(void)5136 bool BlittingMipmaps::checkNearestFilteredResult (void)
5137 {
5138 	bool						allLevelsOk		= true;
5139 	tcu::TestLog&				log				(m_context.getTestContext().getLog());
5140 
5141 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5142 	{
5143 		de::MovePtr<tcu::TextureLevel>			resultLevel			= readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5144 		const tcu::ConstPixelBufferAccess&		resultAccess		= resultLevel->getAccess();
5145 
5146 		const tcu::Sampler::DepthStencilMode	mode				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::Sampler::MODE_DEPTH :
5147 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::Sampler::MODE_STENCIL :
5148 																																	tcu::Sampler::MODE_LAST;
5149 		const tcu::ConstPixelBufferAccess		result				= tcu::hasDepthComponent(resultAccess.getFormat().order)	?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5150 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   getEffectiveDepthStencilAccess(resultAccess, mode) :
5151 																																	resultAccess;
5152 		const tcu::ConstPixelBufferAccess		source				= (m_params.singleCommand || mipLevelNdx == 0) ?			//  Read from source image
5153 																	  tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5154 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5155 																																	m_sourceTextureLevel->getAccess()
5156 																																//  Read from destination image
5157 																	: tcu::hasDepthComponent(resultAccess.getFormat().order)	?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5158 																	  tcu::hasStencilComponent(resultAccess.getFormat().order)  ?   tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5159 																																	m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
5160 		const tcu::TextureFormat				dstFormat			= result.getFormat();
5161 		const tcu::TextureChannelClass			dstChannelClass		= tcu::getTextureChannelClass(dstFormat.type);
5162 		bool									singleLevelOk		= false;
5163 		std::vector <CopyRegion>				mipLevelRegions;
5164 
5165 		for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5166 			if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5167 				mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5168 
5169 		tcu::TextureLevel				errorMaskStorage	(tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
5170 		tcu::PixelBufferAccess			errorMask			= errorMaskStorage.getAccess();
5171 		tcu::Vec4						pixelBias			(0.0f, 0.0f, 0.0f, 0.0f);
5172 		tcu::Vec4						pixelScale			(1.0f, 1.0f, 1.0f, 1.0f);
5173 
5174 		tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
5175 
5176 		if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
5177 			dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
5178 		{
5179 			singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions);
5180 		}
5181 		else
5182 		{
5183 			const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
5184 			const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
5185 
5186 			singleLevelOk = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, mipLevelRegions);
5187 		}
5188 
5189 		if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
5190 			tcu::computePixelScaleBias(result, pixelScale, pixelBias);
5191 
5192 		if (!singleLevelOk)
5193 		{
5194 			log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5195 				<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5196 				<< tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
5197 				<< tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
5198 				<< tcu::TestLog::EndImageSet;
5199 		}
5200 		else
5201 		{
5202 			log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5203 				<< tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5204 				<< tcu::TestLog::EndImageSet;
5205 		}
5206 
5207 		allLevelsOk &= singleLevelOk;
5208 	}
5209 
5210 	return allLevelsOk;
5211 }
5212 
checkTestResult(tcu::ConstPixelBufferAccess result)5213 tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result)
5214 {
5215 	DE_UNREF(result);
5216 	DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
5217 	const std::string failMessage("Result image is incorrect");
5218 
5219 	if (m_params.filter != VK_FILTER_NEAREST)
5220 	{
5221 		if (!checkNonNearestFilteredResult())
5222 			return tcu::TestStatus::fail(failMessage);
5223 	}
5224 	else // NEAREST filtering
5225 	{
5226 		if (!checkNearestFilteredResult())
5227 			return tcu::TestStatus::fail(failMessage);
5228 	}
5229 
5230 	return tcu::TestStatus::pass("Pass");
5231 }
5232 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)5233 void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
5234 {
5235 	DE_ASSERT(src.getDepth() == dst.getDepth());
5236 
5237 	const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
5238 												region.imageBlit.srcOffsets[1],
5239 												region.imageBlit.dstOffsets[0],
5240 												region.imageBlit.dstOffsets[1]);
5241 
5242 	flipCoordinates(region, mirrorMode);
5243 
5244 	const VkOffset3D					srcOffset		= region.imageBlit.srcOffsets[0];
5245 	const VkOffset3D					srcExtent		=
5246 	{
5247 		region.imageBlit.srcOffsets[1].x - srcOffset.x,
5248 		region.imageBlit.srcOffsets[1].y - srcOffset.y,
5249 		region.imageBlit.srcOffsets[1].z - srcOffset.z
5250 	};
5251 	const VkOffset3D					dstOffset		= region.imageBlit.dstOffsets[0];
5252 	const VkOffset3D					dstExtent		=
5253 	{
5254 		region.imageBlit.dstOffsets[1].x - dstOffset.x,
5255 		region.imageBlit.dstOffsets[1].y - dstOffset.y,
5256 		region.imageBlit.dstOffsets[1].z - dstOffset.z
5257 	};
5258 
5259 	tcu::Sampler::FilterMode		filter;
5260 	switch (m_params.filter)
5261 	{
5262 	case VK_FILTER_LINEAR:		filter = tcu::Sampler::LINEAR; break;
5263 	case VK_FILTER_CUBIC_EXT:	filter = tcu::Sampler::CUBIC;  break;
5264 	case VK_FILTER_NEAREST:
5265 	default:					filter = tcu::Sampler::NEAREST;  break;
5266 	}
5267 
5268 	if (tcu::isCombinedDepthStencilType(src.getFormat().type))
5269 	{
5270 		DE_ASSERT(src.getFormat() == dst.getFormat());
5271 		// Scale depth.
5272 		if (tcu::hasDepthComponent(src.getFormat().order))
5273 		{
5274 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
5275 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5276 			tcu::scale(dstSubRegion, srcSubRegion, filter);
5277 
5278 			if (filter != tcu::Sampler::NEAREST)
5279 			{
5280 				const tcu::ConstPixelBufferAccess	depthSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
5281 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5282 				scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
5283 			}
5284 		}
5285 
5286 		// Scale stencil.
5287 		if (tcu::hasStencilComponent(src.getFormat().order))
5288 		{
5289 			const tcu::ConstPixelBufferAccess	srcSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
5290 			const tcu::PixelBufferAccess		dstSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5291 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5292 
5293 			if (filter != tcu::Sampler::NEAREST)
5294 			{
5295 				const tcu::ConstPixelBufferAccess	stencilSrc			= getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
5296 				const tcu::PixelBufferAccess		unclampedSubRegion	= getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5297 				scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
5298 			}
5299 		}
5300 	}
5301 	else
5302 	{
5303 		for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
5304 		{
5305 			const tcu::ConstPixelBufferAccess	srcSubRegion	= tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
5306 			const tcu::PixelBufferAccess		dstSubRegion	= tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5307 			blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5308 
5309 			if (filter != tcu::Sampler::NEAREST)
5310 			{
5311 				const tcu::PixelBufferAccess	unclampedSubRegion	= tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5312 				scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
5313 			}
5314 		}
5315 	}
5316 }
5317 
generateExpectedResult(void)5318 void BlittingMipmaps::generateExpectedResult (void)
5319 {
5320 	const tcu::ConstPixelBufferAccess	src	= m_sourceTextureLevel->getAccess();
5321 	const tcu::ConstPixelBufferAccess	dst	= m_destinationTextureLevel->getAccess();
5322 
5323 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5324 		m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5325 
5326 	tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
5327 
5328 	if (m_params.filter != VK_FILTER_NEAREST)
5329 	{
5330 		for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5331 			m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5332 
5333 		tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
5334 	}
5335 
5336 	for (deUint32 i = 0; i < m_params.regions.size(); i++)
5337 	{
5338 		CopyRegion region = m_params.regions[i];
5339 		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);
5340 	}
5341 }
5342 
5343 class BlitMipmapTestCase : public vkt::TestCase
5344 {
5345 public:
BlitMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)5346 							BlitMipmapTestCase		(tcu::TestContext&				testCtx,
5347 													 const std::string&				name,
5348 													 const std::string&				description,
5349 													 const TestParams				params)
5350 								: vkt::TestCase	(testCtx, name, description)
5351 								, m_params		(params)
5352 	{}
5353 
createInstance(Context & context) const5354 	virtual TestInstance*	createInstance			(Context&						context) const
5355 	{
5356 		return new BlittingMipmaps(context, m_params);
5357 	}
5358 
checkSupport(Context & context) const5359 	virtual void			checkSupport			(Context&						context) const
5360 	{
5361 		const InstanceInterface&	vki					= context.getInstanceInterface();
5362 		const VkPhysicalDevice		vkPhysDevice		= context.getPhysicalDevice();
5363 		{
5364 			VkImageFormatProperties	properties;
5365 			if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5366 																						m_params.src.image.format,
5367 																						VK_IMAGE_TYPE_2D,
5368 																						VK_IMAGE_TILING_OPTIMAL,
5369 																						VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
5370 																						0,
5371 																						&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5372 			{
5373 				TCU_THROW(NotSupportedError, "Format not supported");
5374 			}
5375 			else if ((m_params.src.image.extent.width	> properties.maxExtent.width)	||
5376 						(m_params.src.image.extent.height	> properties.maxExtent.height)	||
5377 						(m_params.src.image.extent.depth	> properties.maxArrayLayers))
5378 			{
5379 				TCU_THROW(NotSupportedError, "Image size not supported");
5380 			}
5381 		}
5382 
5383 		{
5384 			VkImageFormatProperties	properties;
5385 			if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5386 																						m_params.dst.image.format,
5387 																						VK_IMAGE_TYPE_2D,
5388 																						VK_IMAGE_TILING_OPTIMAL,
5389 																						VK_IMAGE_USAGE_TRANSFER_DST_BIT,
5390 																						0,
5391 																						&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5392 			{
5393 				TCU_THROW(NotSupportedError, "Format not supported");
5394 			}
5395 			else if ((m_params.dst.image.extent.width	> properties.maxExtent.width)	||
5396 						(m_params.dst.image.extent.height	> properties.maxExtent.height)	||
5397 						(m_params.dst.image.extent.depth	> properties.maxArrayLayers))
5398 			{
5399 				TCU_THROW(NotSupportedError, "Image size not supported");
5400 			}
5401 			else if (m_params.mipLevels > properties.maxMipLevels)
5402 			{
5403 				TCU_THROW(NotSupportedError, "Number of mip levels not supported");
5404 			}
5405 			else if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)	&&
5406 					 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
5407 			{
5408 				TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
5409 			}
5410 		}
5411 
5412 		const VkFormatProperties	srcFormatProperties	= getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format);
5413 		if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
5414 		{
5415 			TCU_THROW(NotSupportedError, "Format feature blit source not supported");
5416 		}
5417 
5418 		const VkFormatProperties	dstFormatProperties	= getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format);
5419 		if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
5420 		{
5421 			TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
5422 		}
5423 
5424 		if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
5425 			TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
5426 
5427 		if (m_params.filter == VK_FILTER_CUBIC_EXT)
5428 		{
5429 			context.requireDeviceFunctionality("VK_EXT_filter_cubic");
5430 
5431 			if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
5432 			{
5433 				TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
5434 			}
5435 		}
5436 	}
5437 
5438 private:
5439 	TestParams				m_params;
5440 };
5441 
5442 // Resolve image to image.
5443 
5444 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION = 0,
5445 								COPY_MS_IMAGE_TO_MS_IMAGE,
5446 								COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE,
5447 								COPY_MS_IMAGE_LAYER_TO_MS_IMAGE,
5448 								COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION,
5449 								COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB,
5450 								COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE,
5451 								COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER};
5452 
removeExtensions(const std::vector<std::string> & a,const std::vector<const char * > & b)5453 std::vector<std::string> removeExtensions (const std::vector<std::string>& a, const std::vector<const char*>& b)
5454 {
5455 	std::vector<std::string>	res;
5456 	std::set<std::string>		removeExts	(b.begin(), b.end());
5457 
5458 	for (const auto & aIter : a)
5459 	{
5460 		if (!de::contains(removeExts, aIter))
5461 			res.push_back(aIter);
5462 	}
5463 
5464 	return res;
5465 }
5466 
5467 
5468 // 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)5469 Move<VkDevice> createCustomDevice (Context&								context,
5470 								   const ResolveImageToImageOptions		imageCreateOptions,
5471 #ifdef CTS_USES_VULKANSC
5472 								   const CustomInstance&				customInstance,
5473 #endif // CTS_USES_VULKANSC
5474 								   uint32_t&							queueFamilyIndex)
5475 {
5476 #ifdef CTS_USES_VULKANSC
5477 	const InstanceInterface&	instanceDriver		= customInstance.getDriver();
5478 	const VkPhysicalDevice		physicalDevice		= chooseDevice(instanceDriver, customInstance, context.getTestContext().getCommandLine());
5479 #else
5480 	const InstanceInterface&	instanceDriver		= context.getInstanceInterface();
5481 	const VkPhysicalDevice		physicalDevice		= context.getPhysicalDevice();
5482 #endif // CTS_USES_VULKANSC
5483 
5484 	// This function can only be used to create a device with compute only or transfer only queue.
5485 	DE_ASSERT(imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER);
5486 
5487 	// When testing with compute or transfer queue, find a queue family that supports compute or transfer queue, but does NOT support graphics queue.
5488 	const std::vector<VkQueueFamilyProperties>	queueFamilies = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
5489 
5490 	queueFamilyIndex = 0;
5491 	for (const auto &queueFamily: queueFamilies)
5492 	{
5493 		if (imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE)
5494 		{
5495 			if (queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
5496 				break;
5497 			else
5498 				queueFamilyIndex++;
5499 		}
5500 		else if (imageCreateOptions == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
5501 		{
5502 			if (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT && !(queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT) && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
5503 				break;
5504 			else
5505 				queueFamilyIndex++;
5506 		}
5507 	}
5508 
5509 	// One should be found, because this is checked in "checkSupport" function.
5510 	DE_ASSERT(queueFamilyIndex < queueFamilies.size());
5511 
5512 	const float queuePriority = 1.0f;
5513 	const VkDeviceQueueCreateInfo deviceQueueCreateInfos[] = {
5514 		{
5515 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,		// VkStructureType				sType;
5516 			DE_NULL,										// const void*					pNext;
5517 			(VkDeviceQueueCreateFlags)0u,					// VkDeviceQueueCreateFlags		flags;
5518 			context.getUniversalQueueFamilyIndex(),			// uint32_t						queueFamilyIndex;
5519 			1u,												// uint32_t						queueCount;
5520 			&queuePriority,									// const float*					pQueuePriorities;
5521 		},
5522 		{
5523 			VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,		// VkStructureType				sType;
5524 			DE_NULL,										// const void*					pNext;
5525 			(VkDeviceQueueCreateFlags)0u,					// VkDeviceQueueCreateFlags		flags;
5526 			queueFamilyIndex,								// uint32_t						queueFamilyIndex;
5527 			1u,												// uint32_t						queueCount;
5528 			&queuePriority,									// const float*					pQueuePriorities;
5529 		}
5530 	};
5531 
5532 	// context.getDeviceExtensions() returns supported device extension including extensions that have been promoted to
5533 	// Vulkan core. The core extensions must be removed from the list.
5534 	std::vector<const char*>	coreExtensions;
5535 	getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
5536 	std::vector<std::string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));
5537 
5538 	std::vector<const char*>	extensionNames;
5539 	extensionNames.reserve(nonCoreExtensions.size());
5540 	for (const std::string& extension : nonCoreExtensions)
5541 		extensionNames.push_back(extension.c_str());
5542 
5543 	const auto& deviceFeatures2 = context.getDeviceFeatures2();
5544 
5545 	const void *pNext = &deviceFeatures2;
5546 #ifdef CTS_USES_VULKANSC
5547 	VkDeviceObjectReservationCreateInfo memReservationInfo = context.getTestContext().getCommandLine().isSubProcess() ? context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
5548 	memReservationInfo.pNext = pNext;
5549 	pNext = &memReservationInfo;
5550 
5551 	VkPipelineCacheCreateInfo			pcCI;
5552 	std::vector<VkPipelinePoolSize>		poolSizes;
5553 	if (context.getTestContext().getCommandLine().isSubProcess())
5554 	{
5555 		if (context.getResourceInterface()->getCacheDataSize() > 0)
5556 		{
5557 			pcCI =
5558 			{
5559 				VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,			// VkStructureType				sType;
5560 				DE_NULL,												// const void*					pNext;
5561 				VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
5562 					VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
5563 				context.getResourceInterface()->getCacheDataSize(),	// deUintptr					initialDataSize;
5564 				context.getResourceInterface()->getCacheData()		// const void*					pInitialData;
5565 			};
5566 			memReservationInfo.pipelineCacheCreateInfoCount		= 1;
5567 			memReservationInfo.pPipelineCacheCreateInfos		= &pcCI;
5568 		}
5569 		poolSizes							= context.getResourceInterface()->getPipelinePoolSizes();
5570 		if (!poolSizes.empty())
5571 		{
5572 			memReservationInfo.pipelinePoolSizeCount		= deUint32(poolSizes.size());
5573 			memReservationInfo.pPipelinePoolSizes			= poolSizes.data();
5574 		}
5575 	}
5576 #endif // CTS_USES_VULKANSC
5577 
5578 	const VkDeviceCreateInfo	deviceCreateInfo =
5579 	{
5580 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,			// VkStructureType					sType;
5581 		pNext,											// const void*						pNext;
5582 		(VkDeviceCreateFlags)0u,						// VkDeviceCreateFlags				flags;
5583 		DE_LENGTH_OF_ARRAY(deviceQueueCreateInfos),		// uint32_t							queueCreateInfoCount;
5584 		deviceQueueCreateInfos,							// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
5585 		0u,												// uint32_t							enabledLayerCount;
5586 		DE_NULL,										// const char* const*				ppEnabledLayerNames;
5587 		static_cast<uint32_t>(extensionNames.size()),	// uint32_t							enabledExtensionCount;
5588 		extensionNames.data(),							// const char* const*				ppEnabledExtensionNames;
5589 		DE_NULL,										// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
5590 	};
5591 
5592 #ifndef CTS_USES_VULKANSC
5593 	return vkt::createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), instanceDriver, physicalDevice, &deviceCreateInfo);
5594 #else
5595 	return vkt::createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), customInstance, instanceDriver, physicalDevice, &deviceCreateInfo);
5596 #endif // CTS_USES_VULKANSC
5597 }
5598 
5599 class ResolveImageToImage : public CopiesAndBlittingTestInstance
5600 {
5601 public:
5602 												ResolveImageToImage				(Context&						context,
5603 																				 TestParams						params,
5604 																				 ResolveImageToImageOptions		options);
5605 	virtual tcu::TestStatus						iterate							(void);
shouldVerifyIntermediateResults(ResolveImageToImageOptions option)5606 	static inline bool							shouldVerifyIntermediateResults	(ResolveImageToImageOptions option)
5607 	{
5608 		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;
5609 	}
~ResolveImageToImage()5610 												~ResolveImageToImage()
5611 												{
5612 													// Destroy the command pool (and free the related command buffer).
5613 													// This must be done before the m_customDevice is destroyed.
5614 													m_cmdBuffer = Move<VkCommandBuffer>();
5615 													m_cmdPool = Move<VkCommandPool>();
5616 												}
5617 protected:
5618 	virtual tcu::TestStatus						checkTestResult					(tcu::ConstPixelBufferAccess result);
5619 	void										copyMSImageToMSImage			(deUint32 copyArraySize);
5620 	tcu::TestStatus								checkIntermediateCopy			(void);
5621 private:
5622 	const CustomInstance						m_customInstance;
5623 	Move<VkDevice>								m_customDevice;
5624 
5625 #ifndef CTS_USES_VULKANSC
5626 	de::MovePtr<vk::DeviceDriver>				m_deviceDriver;
5627 #else
5628 	de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>	m_deviceDriver;
5629 #endif // CTS_USES_VULKANSC
5630 
5631 	Move<VkCommandPool>							m_alternativeCmdPool;
5632 	Move<VkCommandBuffer>						m_alternativeCmdBuffer;
5633 	VkQueue										m_alternativeQueue;
5634 	uint32_t									m_alternativeQueueFamilyIndex;
5635 	de::MovePtr<vk::Allocator>					m_alternativeAllocator;
5636 	Move<VkImage>								m_multisampledImage;
5637 	de::MovePtr<Allocation>						m_multisampledImageAlloc;
5638 
5639 	Move<VkImage>								m_destination;
5640 	de::MovePtr<Allocation>						m_destinationImageAlloc;
5641 
5642 	Move<VkImage>								m_multisampledCopyImage;
5643 	de::MovePtr<Allocation>						m_multisampledCopyImageAlloc;
5644 	Move<VkImage>								m_multisampledCopyNoCabImage;
5645 	de::MovePtr<Allocation>						m_multisampledCopyImageNoCabAlloc;
5646 
5647 	const ResolveImageToImageOptions			m_options;
5648 
5649 	virtual void								copyRegionToTextureLevel	(tcu::ConstPixelBufferAccess	src,
5650 																			 tcu::PixelBufferAccess			dst,
5651 																			 CopyRegion						region,
5652 																			 deUint32						mipLevel = 0u);
5653 };
5654 
ResolveImageToImage(Context & context,TestParams params,const ResolveImageToImageOptions options)5655 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
5656 	: CopiesAndBlittingTestInstance	(context, params)
5657 	, m_customInstance				(createCustomInstanceFromContext(context))
5658 	, m_options						(options)
5659 {
5660 
5661 
5662 #ifdef CTS_USES_VULKANSC
5663 	const InstanceInterface&	vki						= m_customInstance.getDriver();
5664 #else
5665 	const InstanceInterface&	vki						= m_context.getInstanceInterface();
5666 #endif // CTS_USES_VULKANSC
5667 
5668 		uint32_t queueFamilyIndex		= 0;
5669 	// Create custom device for compute and transfer only queue tests.
5670 	if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
5671 	{
5672 		// 'queueFamilyIndex' will be updated in 'createCustomDevice()' to match the requested queue type.
5673 #ifdef CTS_USES_VULKANSC
5674 		m_customDevice					= createCustomDevice(context, m_options, m_customInstance, queueFamilyIndex);
5675 #else
5676 		m_customDevice					= createCustomDevice(context, m_options, queueFamilyIndex);
5677 #endif // CTS_USES_VULKANSC
5678 		m_device						= m_customDevice.get();
5679 
5680 #ifndef CTS_USES_VULKANSC
5681 		m_deviceDriver = de::MovePtr<DeviceDriver>(new DeviceDriver(context.getPlatformInterface(), m_customInstance, m_device));
5682 #else
5683 		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));
5684 #endif // CTS_USES_VULKANSC
5685 
5686 		m_queue							= getDeviceQueue(m_context.getDeviceInterface(), m_device, context.getUniversalQueueFamilyIndex(), 0u);
5687 		m_alternativeQueue				= getDeviceQueue(m_context.getDeviceInterface(), m_device, queueFamilyIndex, 0u);
5688 	}
5689 
5690 	m_alternativeQueueFamilyIndex	= queueFamilyIndex;
5691 
5692 #ifndef CTS_USES_VULKANSC
5693 	const DeviceInterface&		vk						= m_context.getDeviceInterface();
5694 #else
5695 	const DeviceInterface&		vk						= (DE_NULL != m_deviceDriver) ? *m_deviceDriver : m_context.getDeviceInterface();
5696 #endif // CTS_USES_VULKANSC
5697 
5698 	m_alternativeAllocator			= de::MovePtr<Allocator>(new SimpleAllocator(vk, m_device, getPhysicalDeviceMemoryProperties(vki, context.getPhysicalDevice())));
5699 	m_allocator						= m_alternativeAllocator.get();
5700 
5701 	// Release the command buffer.
5702 	m_cmdBuffer = Move<VkCommandBuffer>();
5703 
5704 	// Create a new command pool and allocate a command buffer with universal queue family index and destroy the old one.
5705 	m_cmdPool						= createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, context.getUniversalQueueFamilyIndex());
5706 	m_cmdBuffer						= allocateCommandBuffer(vk, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5707 
5708 	// Create a command pool and allocate a command buffer from the queue family supporting compute / transfer capabilities.
5709 	m_alternativeCmdPool			= createCommandPool(vk, m_device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
5710 	m_alternativeCmdBuffer			= allocateCommandBuffer(vk, m_device, *m_alternativeCmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5711 
5712 	Allocator&					memAlloc				= *m_allocator;
5713 	const VkPhysicalDevice		vkPhysDevice			= m_context.getPhysicalDevice();
5714 	const VkDevice				vkDevice				= m_device;
5715 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
5716 	Move<VkRenderPass>			renderPass;
5717 
5718 	Move<VkShaderModule>		vertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
5719 	Move<VkShaderModule>		fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
5720 	std::vector<tcu::Vec4>		vertices;
5721 
5722 	Move<VkBuffer>				vertexBuffer;
5723 	de::MovePtr<Allocation>		vertexBufferAlloc;
5724 
5725 	Move<VkPipelineLayout>		pipelineLayout;
5726 	Move<VkPipeline>			graphicsPipeline;
5727 
5728 	const VkSampleCountFlagBits	rasterizationSamples	= m_params.samples;
5729 
5730 	// Create color image.
5731 	{
5732 		VkImageCreateInfo		colorImageParams	=
5733 		{
5734 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
5735 			DE_NULL,																// const void*				pNext;
5736 			getCreateFlags(m_params.src.image),										// VkImageCreateFlags		flags;
5737 			m_params.src.image.imageType,											// VkImageType				imageType;
5738 			m_params.src.image.format,												// VkFormat					format;
5739 			getExtent3D(m_params.src.image),										// VkExtent3D				extent;
5740 			1u,																		// deUint32					mipLevels;
5741 			getArraySize(m_params.src.image),										// deUint32					arrayLayers;
5742 			rasterizationSamples,													// VkSampleCountFlagBits	samples;
5743 			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
5744 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT										// VkImageUsageFlags		usage;
5745 				| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
5746 				| VK_IMAGE_USAGE_TRANSFER_DST_BIT
5747 				| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
5748 			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
5749 			0u,																		// deUint32					queueFamilyIndexCount;
5750 			(const deUint32*)DE_NULL,												// const deUint32*			pQueueFamilyIndices;
5751 			VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout			initialLayout;
5752 		};
5753 
5754 		m_multisampledImage						= createImage(vk, vkDevice, &colorImageParams);
5755 		VkMemoryRequirements	req				= getImageMemoryRequirements(vk, vkDevice, *m_multisampledImage);
5756 
5757 		// Allocate and bind color image memory.
5758 		deUint32				offset			= m_params.imageOffset ? static_cast<deUint32>(req.alignment) : 0u;
5759 		m_multisampledImageAlloc				= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any,
5760 																memAlloc, m_params.allocationKind, offset);
5761 
5762 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), offset));
5763 
5764 		switch (m_options)
5765 		{
5766 			case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
5767 			case COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE:
5768 			case COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER:
5769 			case COPY_MS_IMAGE_TO_MS_IMAGE:
5770 			{
5771 				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;
5772 				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
5773 				// Allocate and bind color image memory.
5774 				m_multisampledCopyImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5775 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5776 				break;
5777 			}
5778 			case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
5779 			case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
5780 			{
5781 				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;
5782 				colorImageParams.arrayLayers	= getArraySize(m_params.dst.image);
5783 				m_multisampledCopyImage			= createImage(vk, vkDevice, &colorImageParams);
5784 				// Allocate and bind color image memory.
5785 				m_multisampledCopyImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5786 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5787 				break;
5788 			}
5789 			case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
5790 			{
5791 				colorImageParams.usage				= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5792 				colorImageParams.arrayLayers		= getArraySize(m_params.dst.image);
5793 				m_multisampledCopyImage				= createImage(vk, vkDevice, &colorImageParams);
5794 				m_multisampledCopyNoCabImage		= createImage(vk, vkDevice, &colorImageParams);
5795 				// Allocate and bind color image memory.
5796 				m_multisampledCopyImageAlloc			= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5797 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5798 				m_multisampledCopyImageNoCabAlloc		= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyNoCabImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5799 				VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyNoCabImage, m_multisampledCopyImageNoCabAlloc->getMemory(), m_multisampledCopyImageNoCabAlloc->getOffset()));
5800 				break;
5801 			}
5802 
5803 			default :
5804 				break;
5805 		}
5806 	}
5807 
5808 	// Create destination image.
5809 	{
5810 		const VkImageCreateInfo	destinationImageParams	=
5811 		{
5812 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType		sType;
5813 			DE_NULL,								// const void*			pNext;
5814 			getCreateFlags(m_params.dst.image),		// VkImageCreateFlags	flags;
5815 			m_params.dst.image.imageType,			// VkImageType			imageType;
5816 			m_params.dst.image.format,				// VkFormat				format;
5817 			getExtent3D(m_params.dst.image),		// VkExtent3D			extent;
5818 			1u,										// deUint32				mipLevels;
5819 			getArraySize(m_params.dst.image),		// deUint32				arraySize;
5820 			VK_SAMPLE_COUNT_1_BIT,					// deUint32				samples;
5821 			VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling		tiling;
5822 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
5823 				VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
5824 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
5825 			0u,										// deUint32				queueFamilyIndexCount;
5826 			(const deUint32*)DE_NULL,				// const deUint32*		pQueueFamilyIndices;
5827 			VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout		initialLayout;
5828 		};
5829 
5830 		m_destination			= createImage(vk, vkDevice, &destinationImageParams);
5831 		m_destinationImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
5832 		VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
5833 	}
5834 
5835 	// Barriers for image clearing.
5836 	std::vector<VkImageMemoryBarrier> srcImageBarriers;
5837 
5838 	const VkImageMemoryBarrier m_multisampledImageBarrier =
5839 	{
5840 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5841 		DE_NULL,									// const void*				pNext;
5842 		0u,											// VkAccessFlags			srcAccessMask;
5843 		VK_ACCESS_MEMORY_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
5844 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
5845 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
5846 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5847 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5848 		m_multisampledImage.get(),					// VkImage					image;
5849 		{											// VkImageSubresourceRange	subresourceRange;
5850 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
5851 			0u,										// deUint32				baseMipLevel;
5852 			1u,										// deUint32				mipLevels;
5853 			0u,										// deUint32				baseArraySlice;
5854 			getArraySize(m_params.src.image)		// deUint32				arraySize;
5855 		}
5856 	};
5857 	const VkImageMemoryBarrier m_multisampledCopyImageBarrier =
5858 	{
5859 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5860 		DE_NULL,									// const void*				pNext;
5861 		0u,											// VkAccessFlags			srcAccessMask;
5862 		VK_ACCESS_MEMORY_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
5863 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
5864 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
5865 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5866 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5867 		m_multisampledCopyImage.get(),				// VkImage					image;
5868 		{											// VkImageSubresourceRange	subresourceRange;
5869 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
5870 			0u,										// deUint32				baseMipLevel;
5871 			1u,										// deUint32				mipLevels;
5872 			0u,										// deUint32				baseArraySlice;
5873 			getArraySize(m_params.dst.image)		// deUint32				arraySize;
5874 		}
5875 	};
5876 	const VkImageMemoryBarrier m_multisampledCopyImageNoCabBarrier =
5877 	{
5878 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
5879 		DE_NULL,									// const void*				pNext;
5880 		0u,											// VkAccessFlags			srcAccessMask;
5881 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask;
5882 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
5883 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
5884 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
5885 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
5886 		m_multisampledCopyNoCabImage.get(),			// VkImage					image;
5887 		{											// VkImageSubresourceRange	subresourceRange;
5888 			VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask;
5889 			0u,										// deUint32				baseMipLevel;
5890 			1u,										// deUint32				mipLevels;
5891 			0u,										// deUint32				baseArraySlice;
5892 			getArraySize(m_params.dst.image)		// deUint32				arraySize;
5893 		}
5894 	};
5895 
5896 	// Only use one barrier if no options have been given.
5897 	if (m_options != DE_NULL)
5898 	{
5899 		srcImageBarriers.push_back(m_multisampledImageBarrier);
5900 		srcImageBarriers.push_back(m_multisampledCopyImageBarrier);
5901 		// Add the third barrier if option is as below.
5902 		if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
5903 			srcImageBarriers.push_back(m_multisampledCopyImageNoCabBarrier);
5904 	}
5905 	else
5906 	{
5907 		srcImageBarriers.push_back(m_multisampledImageBarrier);
5908 	}
5909 
5910 	// Create render pass.
5911 	{
5912 		const VkAttachmentDescription	attachmentDescription		=
5913 		{
5914 			0u,											// VkAttachmentDescriptionFlags		flags;
5915 			m_params.src.image.format,					// VkFormat							format;
5916 			rasterizationSamples,						// VkSampleCountFlagBits			samples;
5917 			VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp				loadOp;
5918 			VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp;
5919 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp;
5920 			VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp;
5921 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout					initialLayout;
5922 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL		// VkImageLayout					finalLayout;
5923 		};
5924 
5925 		const VkAttachmentReference		colorAttachmentReference	=
5926 		{
5927 			0u,													// deUint32			attachment;
5928 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
5929 		};
5930 
5931 		const VkSubpassDescription		subpassDescription			=
5932 		{
5933 			0u,									// VkSubpassDescriptionFlags	flags;
5934 			VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint			pipelineBindPoint;
5935 			0u,									// deUint32						inputAttachmentCount;
5936 			DE_NULL,							// const VkAttachmentReference*	pInputAttachments;
5937 			1u,									// deUint32						colorAttachmentCount;
5938 			&colorAttachmentReference,			// const VkAttachmentReference*	pColorAttachments;
5939 			DE_NULL,							// const VkAttachmentReference*	pResolveAttachments;
5940 			DE_NULL,							// const VkAttachmentReference*	pDepthStencilAttachment;
5941 			0u,									// deUint32						preserveAttachmentCount;
5942 			DE_NULL								// const VkAttachmentReference*	pPreserveAttachments;
5943 		};
5944 
5945 		// Subpass dependency is used to synchronize the memory access of the image clear and color attachment write in some test cases.
5946 		const VkSubpassDependency		subpassDependency			=
5947 		{
5948 			VK_SUBPASS_EXTERNAL,							//uint32_t				srcSubpass;
5949 			0u,												//uint32_t				dstSubpass;
5950 			VK_PIPELINE_STAGE_TRANSFER_BIT,					//VkPipelineStageFlags	srcStageMask;
5951 			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,	//VkPipelineStageFlags	dstStageMask;
5952 			VK_ACCESS_TRANSFER_WRITE_BIT,					//VkAccessFlags			srcAccessMask;
5953 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			//VkAccessFlags			dstAccessMask;
5954 			0u												//VkDependencyFlags		dependencyFlags;
5955 		};
5956 
5957 		const deBool					useSubpassDependency		= m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION;
5958 		const VkRenderPassCreateInfo	renderPassParams			=
5959 		{
5960 			VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType					sType;
5961 			DE_NULL,									// const void*						pNext;
5962 			0u,											// VkRenderPassCreateFlags			flags;
5963 			1u,											// deUint32							attachmentCount;
5964 			&attachmentDescription,						// const VkAttachmentDescription*	pAttachments;
5965 			1u,											// deUint32							subpassCount;
5966 			&subpassDescription,						// const VkSubpassDescription*		pSubpasses;
5967 			useSubpassDependency ? 1u : 0u,				// deUint32							dependencyCount;
5968 			&subpassDependency							// const VkSubpassDependency*		pDependencies;
5969 		};
5970 
5971 		renderPass	= createRenderPass(vk, vkDevice, &renderPassParams);
5972 	}
5973 
5974 	// Create pipeline layout
5975 	{
5976 		const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
5977 		{
5978 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
5979 			DE_NULL,											// const void*						pNext;
5980 			0u,													// VkPipelineLayoutCreateFlags		flags;
5981 			0u,													// deUint32							setLayoutCount;
5982 			DE_NULL,											// const VkDescriptorSetLayout*		pSetLayouts;
5983 			0u,													// deUint32							pushConstantRangeCount;
5984 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
5985 		};
5986 
5987 		pipelineLayout	= createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
5988 	}
5989 
5990 	// Create upper half triangle.
5991 	{
5992 		const tcu::Vec4	a	(-1.0, -1.0, 0.0, 1.0);
5993 		const tcu::Vec4	b	(1.0, -1.0, 0.0, 1.0);
5994 		const tcu::Vec4	c	(1.0, 1.0, 0.0, 1.0);
5995 		// Add triangle.
5996 		vertices.push_back(a);
5997 		vertices.push_back(c);
5998 		vertices.push_back(b);
5999 	}
6000 
6001 	// Create vertex buffer.
6002 	{
6003 		const VkDeviceSize			vertexDataSize		= vertices.size() * sizeof(tcu::Vec4);
6004 		const VkBufferCreateInfo	vertexBufferParams	=
6005 		{
6006 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
6007 			DE_NULL,									// const void*			pNext;
6008 			0u,											// VkBufferCreateFlags	flags;
6009 			vertexDataSize,								// VkDeviceSize			size;
6010 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,			// VkBufferUsageFlags	usage;
6011 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
6012 			0u,											// deUint32				queueFamilyIndexCount;
6013 			(const deUint32*)DE_NULL,					// const deUint32*		pQueueFamilyIndices;
6014 		};
6015 
6016 		vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
6017 		vertexBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
6018 		VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
6019 
6020 		// Load vertices into vertex buffer.
6021 		deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
6022 		flushAlloc(vk, vkDevice, *vertexBufferAlloc);
6023 	}
6024 
6025 	{
6026 		Move<VkFramebuffer>		framebuffer;
6027 		Move<VkImageView>		sourceAttachmentView;
6028 
6029 		uint32_t baseArrayLayer = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : 0u;
6030 
6031 		// Create color attachment view.
6032 		{
6033 			const VkImageViewCreateInfo	colorAttachmentViewParams	=
6034 			{
6035 				VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,					// VkStructureType			sType;
6036 				DE_NULL,													// const void*				pNext;
6037 				0u,															// VkImageViewCreateFlags	flags;
6038 				*m_multisampledImage,										// VkImage					image;
6039 				VK_IMAGE_VIEW_TYPE_2D,										// VkImageViewType			viewType;
6040 				m_params.src.image.format,									// VkFormat					format;
6041 				componentMappingRGBA,										// VkComponentMapping		components;
6042 				{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, baseArrayLayer, 1u }	// VkImageSubresourceRange	subresourceRange;
6043 			};
6044 			sourceAttachmentView	= createImageView(vk, vkDevice, &colorAttachmentViewParams);
6045 		}
6046 
6047 		// Create framebuffer
6048 		{
6049 			const VkFramebufferCreateInfo	framebufferParams	=
6050 			{
6051 					VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType;
6052 					DE_NULL,											// const void*					pNext;
6053 					0u,													// VkFramebufferCreateFlags		flags;
6054 					*renderPass,										// VkRenderPass					renderPass;
6055 					1u,													// deUint32						attachmentCount;
6056 					&sourceAttachmentView.get(),						// const VkImageView*			pAttachments;
6057 					m_params.src.image.extent.width,					// deUint32						width;
6058 					m_params.src.image.extent.height,					// deUint32						height;
6059 					1u													// deUint32						layers;
6060 			};
6061 
6062 			framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
6063 		}
6064 
6065 		// Create pipeline
6066 		{
6067 			const std::vector<VkViewport>	viewports	(1, makeViewport(m_params.src.image.extent));
6068 			const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_params.src.image.extent));
6069 
6070 			const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
6071 			{
6072 				VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
6073 				DE_NULL,													// const void*								pNext;
6074 				0u,															// VkPipelineMultisampleStateCreateFlags	flags;
6075 				rasterizationSamples,										// VkSampleCountFlagBits					rasterizationSamples;
6076 				VK_FALSE,													// VkBool32									sampleShadingEnable;
6077 				0.0f,														// float									minSampleShading;
6078 				DE_NULL,													// const VkSampleMask*						pSampleMask;
6079 				VK_FALSE,													// VkBool32									alphaToCoverageEnable;
6080 				VK_FALSE													// VkBool32									alphaToOneEnable;
6081 			};
6082 
6083 			graphicsPipeline = makeGraphicsPipeline(vk,										// const DeviceInterface&                        vk
6084 													vkDevice,								// const VkDevice                                device
6085 													*pipelineLayout,						// const VkPipelineLayout                        pipelineLayout
6086 													*vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
6087 													DE_NULL,								// const VkShaderModule                          tessellationControlModule
6088 													DE_NULL,								// const VkShaderModule                          tessellationEvalModule
6089 													DE_NULL,								// const VkShaderModule                          geometryShaderModule
6090 													*fragmentShaderModule,					// const VkShaderModule                          fragmentShaderModule
6091 													*renderPass,							// const VkRenderPass                            renderPass
6092 													viewports,								// const std::vector<VkViewport>&                viewports
6093 													scissors,								// const std::vector<VkRect2D>&                  scissors
6094 													VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
6095 													0u,										// const deUint32                                subpass
6096 													0u,										// const deUint32                                patchControlPoints
6097 													DE_NULL,								// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
6098 													DE_NULL,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6099 													&multisampleStateParams);				// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
6100 		}
6101 
6102 		// Create command buffer
6103 		{
6104 			beginCommandBuffer(vk, *m_cmdBuffer, 0u);
6105 
6106 			if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6107 			{
6108 				// Change the image layouts.
6109 				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());
6110 
6111 				// Clear the 'm_multisampledImage'.
6112 				{
6113 					const VkClearColorValue clearValue = {{0.0f, 0.0f, 0.0f, 1.0f}};
6114 					const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
6115 					vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
6116 				}
6117 
6118 				// Clear the 'm_multisampledCopyImage' with different color.
6119 				{
6120 					const VkClearColorValue clearValue = {{1.0f, 1.0f, 1.0f, 1.0f}};
6121 					const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
6122 					vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
6123 				}
6124 			}
6125 			else
6126 			{
6127 				// Change the image layouts.
6128 				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());
6129 			}
6130 
6131 			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));
6132 
6133 			const VkDeviceSize vertexBufferOffset = 0u;
6134 
6135 			vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
6136 			vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
6137 			vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
6138 
6139 			endRenderPass(vk, *m_cmdBuffer);
6140 			endCommandBuffer(vk, *m_cmdBuffer);
6141 		}
6142 
6143 		// Queue submit.
6144 		{
6145 			submitCommandsAndWait (vk, vkDevice, m_queue, *m_cmdBuffer);
6146 			m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
6147 		}
6148 	}
6149 }
6150 
iterate(void)6151 tcu::TestStatus ResolveImageToImage::iterate (void)
6152 {
6153 	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
6154 	const tcu::TextureFormat		dstTcuFormat		= mapVkFormat(m_params.dst.image.format);
6155 
6156 	// upload the destination image
6157 	m_destinationTextureLevel	= de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
6158 																			(int)m_params.dst.image.extent.width,
6159 																			(int)m_params.dst.image.extent.height,
6160 																			(int)m_params.dst.image.extent.depth));
6161 	generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
6162 	uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
6163 
6164 	m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
6165 																	(int)m_params.src.image.extent.width,
6166 																	(int)m_params.src.image.extent.height,
6167 																	(int)m_params.dst.image.extent.depth));
6168 
6169 	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);
6170 	generateExpectedResult();
6171 
6172 	VkImage		sourceImage		= m_multisampledImage.get();
6173 	deUint32	sourceArraySize	= getArraySize(m_params.src.image);
6174 
6175 	switch (m_options)
6176 	{
6177 		case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
6178 		case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
6179 			// Duplicate the multisampled image to a multisampled image array
6180 			sourceArraySize	= getArraySize(m_params.dst.image); // fall through
6181 		case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
6182 		case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
6183 		case COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE:
6184 		case COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER:
6185 		case COPY_MS_IMAGE_TO_MS_IMAGE:
6186 			copyMSImageToMSImage(sourceArraySize);
6187 			sourceImage	= m_multisampledCopyImage.get();
6188 			break;
6189 		default:
6190 			break;
6191 	}
6192 
6193 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
6194 	const VkDevice					vkDevice			= m_device;
6195 	const VkQueue					queue				= m_queue;
6196 
6197 	std::vector<VkImageResolve>		imageResolves;
6198 	std::vector<VkImageResolve2KHR>	imageResolves2KHR;
6199 	for (CopyRegion region : m_params.regions)
6200 	{
6201 		// If copying multiple regions, make sure that the same regions are
6202 		// used for resolving as the ones used for copying.
6203 		if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6204 		{
6205 			VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
6206 										getExtent3D(m_params.src.image).height / 2,
6207 										getExtent3D(m_params.src.image).depth};
6208 
6209 			const VkImageResolve imageResolve =
6210 			{
6211 				region.imageResolve.srcSubresource,		// VkImageSubresourceLayers	srcSubresource;
6212 				region.imageResolve.dstOffset,			// VkOffset3D				srcOffset;
6213 				region.imageResolve.dstSubresource,		// VkImageSubresourceLayers	dstSubresource;
6214 				region.imageResolve.dstOffset,			// VkOffset3D				dstOffset;
6215 				partialExtent,							// VkExtent3D				extent;
6216 			};
6217 
6218 			if (m_params.extensionUse == EXTENSION_USE_NONE)
6219 			{
6220 				imageResolves.push_back(imageResolve);
6221 			}
6222 			else
6223 			{
6224 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6225 				imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(imageResolve));
6226 			}
6227 		}
6228 		else
6229 		{
6230 			if (m_params.extensionUse == EXTENSION_USE_NONE)
6231 			{
6232 				imageResolves.push_back(region.imageResolve);
6233 			}
6234 			else
6235 			{
6236 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6237 				imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(region.imageResolve));
6238 			}
6239 		}
6240 	}
6241 
6242 	const VkImageMemoryBarrier	imageBarriers[]		=
6243 	{
6244 		// source image
6245 		{
6246 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6247 			DE_NULL,									// const void*				pNext;
6248 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
6249 			VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
6250 			m_options == NO_OPTIONAL_OPERATION ?
6251 			m_params.dst.image.operationLayout :
6252 			m_params.src.image.operationLayout,			// VkImageLayout			oldLayout;
6253 			m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
6254 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6255 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6256 			sourceImage,								// VkImage					image;
6257 			{											// VkImageSubresourceRange	subresourceRange;
6258 				getAspectFlags(srcTcuFormat),		// VkImageAspectFlags	aspectMask;
6259 				0u,									// deUint32				baseMipLevel;
6260 				1u,									// deUint32				mipLevels;
6261 				0u,									// deUint32				baseArraySlice;
6262 				sourceArraySize						// deUint32				arraySize;
6263 			}
6264 		},
6265 		// destination image
6266 		{
6267 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6268 			DE_NULL,									// const void*				pNext;
6269 			0u,											// VkAccessFlags			srcAccessMask;
6270 			VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
6271 			VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
6272 			m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
6273 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6274 			VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6275 			m_destination.get(),						// VkImage					image;
6276 			{											// VkImageSubresourceRange	subresourceRange;
6277 				getAspectFlags(dstTcuFormat),		// VkImageAspectFlags	aspectMask;
6278 				0u,									// deUint32				baseMipLevel;
6279 				1u,									// deUint32				mipLevels;
6280 				0u,									// deUint32				baseArraySlice;
6281 				getArraySize(m_params.dst.image)	// deUint32				arraySize;
6282 			}
6283 		},
6284 	};
6285 
6286 	const VkImageMemoryBarrier postImageBarrier =
6287 	{
6288 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
6289 		DE_NULL,								// const void*				pNext;
6290 		VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			srcAccessMask;
6291 		VK_ACCESS_HOST_READ_BIT,				// VkAccessFlags			dstAccessMask;
6292 		m_params.dst.image.operationLayout,		// VkImageLayout			oldLayout;
6293 		m_params.dst.image.operationLayout,		// VkImageLayout			newLayout;
6294 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
6295 		VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
6296 		m_destination.get(),					// VkImage					image;
6297 		{										// VkImageSubresourceRange	subresourceRange;
6298 			getAspectFlags(dstTcuFormat),		// VkImageAspectFlags		aspectMask;
6299 			0u,									// deUint32					baseMipLevel;
6300 			1u,									// deUint32					mipLevels;
6301 			0u,									// deUint32					baseArraySlice;
6302 			getArraySize(m_params.dst.image)	// deUint32					arraySize;
6303 		}
6304 	};
6305 
6306 	beginCommandBuffer(vk, *m_cmdBuffer);
6307 	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);
6308 
6309 	if (m_params.extensionUse == EXTENSION_USE_NONE)
6310 	{
6311 		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());
6312 	}
6313 #ifndef CTS_USES_VULKANSC
6314 	else
6315 	{
6316 		DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6317 		const VkResolveImageInfo2KHR ResolveImageInfo2KHR =
6318 		{
6319 			VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR,	// VkStructureType				sType;
6320 			DE_NULL,									// const void*					pNext;
6321 			sourceImage,								// VkImage						srcImage;
6322 			m_params.src.image.operationLayout,			// VkImageLayout				srcImageLayout;
6323 			m_destination.get(),						// VkImage						dstImage;
6324 			m_params.dst.image.operationLayout,			// VkImageLayout				dstImageLayout;
6325 			(deUint32)m_params.regions.size(),			// uint32_t						regionCount;
6326 			imageResolves2KHR.data()					// const  VkImageResolve2KHR*	pRegions;
6327 		};
6328 		vk.cmdResolveImage2(*m_cmdBuffer, &ResolveImageInfo2KHR);
6329 	}
6330 #endif // CTS_USES_VULKANSC
6331 
6332 	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);
6333 	endCommandBuffer(vk, *m_cmdBuffer);
6334 	submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
6335 	m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
6336 
6337 	de::MovePtr<tcu::TextureLevel>	resultTextureLevel	= readImage(*m_destination, m_params.dst.image);
6338 
6339 	if (shouldVerifyIntermediateResults(m_options))
6340 	{
6341 		// Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
6342 		// resolving the image and giving every sample the same value.
6343 		const auto intermediateResult = checkIntermediateCopy();
6344 		if (intermediateResult.getCode() != QP_TEST_RESULT_PASS)
6345 			return intermediateResult;
6346 	}
6347 
6348 	return checkTestResult(resultTextureLevel->getAccess());
6349 }
6350 
checkTestResult(tcu::ConstPixelBufferAccess result)6351 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
6352 {
6353 	const tcu::ConstPixelBufferAccess	expected		= m_expectedTextureLevel[0]->getAccess();
6354 	const float							fuzzyThreshold	= 0.01f;
6355 
6356 	if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6357 	{
6358 		// Check that all the layers that have not been written to are solid white.
6359 		tcu::Vec4 expectedColor (1.0f, 1.0f, 1.0f, 1.0f);
6360 		for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image) - 1; ++arrayLayerNdx)
6361 		{
6362 			const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
6363 			if(resultSub.getPixel(0, 0) != expectedColor)
6364 				return tcu::TestStatus::fail("CopiesAndBlitting test. Layers image differs from initialized value.");
6365 		}
6366 
6367 		// Check that the layer that has been copied to is the same as the layer that has been copied from.
6368 		const tcu::ConstPixelBufferAccess	expectedSub	= getSubregion (expected, 0u, 0u, 2u, expected.getWidth(), expected.getHeight(), 1u);
6369 		const tcu::ConstPixelBufferAccess	resultSub	= getSubregion (result, 0u, 0u, 4u, result.getWidth(), result.getHeight(), 1u);
6370 		if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
6371 			return tcu::TestStatus::fail("CopiesAndBlitting test");
6372 	}
6373 	else
6374 	{
6375 		for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
6376 		{
6377 			const tcu::ConstPixelBufferAccess	expectedSub	= getSubregion (expected, 0u, 0u, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
6378 			const tcu::ConstPixelBufferAccess	resultSub	= getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
6379 			if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
6380 				return tcu::TestStatus::fail("CopiesAndBlitting test");
6381 		}
6382 	}
6383 
6384 	return tcu::TestStatus::pass("CopiesAndBlitting test");
6385 }
6386 
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)6387 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
6388 {
6389 	DE_UNREF(mipLevel);
6390 
6391 	VkOffset3D srcOffset	= region.imageResolve.srcOffset;
6392 			srcOffset.z		= region.imageResolve.srcSubresource.baseArrayLayer;
6393 	VkOffset3D dstOffset	= region.imageResolve.dstOffset;
6394 			dstOffset.z		= region.imageResolve.dstSubresource.baseArrayLayer;
6395 	VkExtent3D extent		= region.imageResolve.extent;
6396 			extent.depth		= region.imageResolve.srcSubresource.layerCount;
6397 
6398 	const tcu::ConstPixelBufferAccess	srcSubRegion		= getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
6399 	// CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
6400 	const tcu::PixelBufferAccess		dstWithSrcFormat	(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
6401 	const tcu::PixelBufferAccess		dstSubRegion		= getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
6402 
6403 	tcu::copy(dstSubRegion, srcSubRegion);
6404 }
6405 
checkIntermediateCopy(void)6406 tcu::TestStatus ResolveImageToImage::checkIntermediateCopy (void)
6407 {
6408 	const		auto&	vkd					= m_context.getDeviceInterface();
6409 	const		auto	device				= m_device;
6410 	const		auto	queue				= m_queue;
6411 	const		auto	queueIndex			= m_context.getUniversalQueueFamilyIndex();
6412 				auto&	alloc				= *m_allocator;
6413 	const		auto	currentLayout		= m_params.src.image.operationLayout;
6414 	const		auto	numDstLayers		= getArraySize(m_params.dst.image);
6415 	const		auto	numInputAttachments	= m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : numDstLayers + 1u; // For the source image.
6416 	constexpr	auto	numSets				= 2u; // 1 for the output buffer, 1 for the input attachments.
6417 	const		auto	fbWidth				= m_params.src.image.extent.width;
6418 	const		auto	fbHeight			= m_params.src.image.extent.height;
6419 
6420 	// Push constants.
6421 	const std::array<int, 3> pushConstantData =
6422 	{{
6423 		static_cast<int>(fbWidth),
6424 		static_cast<int>(fbHeight),
6425 		static_cast<int>(m_params.samples),
6426 	}};
6427 	const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
6428 
6429 	// Shader modules.
6430 	const auto vertexModule			= createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
6431 	const auto verificationModule	= createShaderModule(vkd, device, m_context.getBinaryCollection().get("verify"), 0u);
6432 
6433 	// Descriptor sets.
6434 	DescriptorPoolBuilder poolBuilder;
6435 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
6436 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
6437 	const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
6438 
6439 	DescriptorSetLayoutBuilder layoutBuilderBuffer;
6440 	layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
6441 	const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
6442 
6443 	DescriptorSetLayoutBuilder layoutBuilderAttachments;
6444 	for (deUint32 i = 0u; i < numInputAttachments; ++i)
6445 		layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
6446 	const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
6447 
6448 	const auto descriptorSetBuffer		= makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
6449 	const auto descriptorSetAttachments	= makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
6450 
6451 	// Array with raw descriptor sets.
6452 	const std::array<VkDescriptorSet, numSets> descriptorSets =
6453 	{{
6454 		descriptorSetBuffer.get(),
6455 		descriptorSetAttachments.get(),
6456 	}};
6457 
6458 	// Pipeline layout.
6459 	const std::array<VkDescriptorSetLayout, numSets> setLayouts =
6460 	{{
6461 		outputBufferSetLayout.get(),
6462 		inputAttachmentsSetLayout.get(),
6463 	}};
6464 
6465 	const VkPushConstantRange pushConstantRange =
6466 	{
6467 		VK_SHADER_STAGE_FRAGMENT_BIT,	//	VkShaderStageFlags	stageFlags;
6468 		0u,								//	deUint32			offset;
6469 		pushConstantSize,				//	deUint32			size;
6470 	};
6471 
6472 	const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
6473 	{
6474 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	//	VkStructureType					sType;
6475 		nullptr,										//	const void*						pNext;
6476 		0u,												//	VkPipelineLayoutCreateFlags		flags;
6477 		static_cast<deUint32>(setLayouts.size()),		//	deUint32						setLayoutCount;
6478 		setLayouts.data(),								//	const VkDescriptorSetLayout*	pSetLayouts;
6479 		1u,												//	deUint32						pushConstantRangeCount;
6480 		&pushConstantRange,								//	const VkPushConstantRange*		pPushConstantRanges;
6481 	};
6482 
6483 	const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
6484 
6485 	// Render pass.
6486 	const VkAttachmentDescription commonAttachmentDescription =
6487 	{
6488 		0u,									//	VkAttachmentDescriptionFlags	flags;
6489 		m_params.src.image.format,			//	VkFormat						format;
6490 		m_params.samples,					//	VkSampleCountFlagBits			samples;
6491 		VK_ATTACHMENT_LOAD_OP_LOAD,			//	VkAttachmentLoadOp				loadOp;
6492 		VK_ATTACHMENT_STORE_OP_STORE,		//	VkAttachmentStoreOp				storeOp;
6493 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,	//	VkAttachmentLoadOp				stencilLoadOp;
6494 		VK_ATTACHMENT_STORE_OP_DONT_CARE,	//	VkAttachmentStoreOp				stencilStoreOp;
6495 		currentLayout,						//	VkImageLayout					initialLayout;
6496 		currentLayout,						//	VkImageLayout					finalLayout;
6497 	};
6498 	const std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
6499 
6500 	std::vector<VkAttachmentReference> inputAttachmentReferences;
6501 	inputAttachmentReferences.reserve(numInputAttachments);
6502 	for (deUint32 i = 0u; i < numInputAttachments; ++i)
6503 	{
6504 		const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
6505 		inputAttachmentReferences.push_back(reference);
6506 	}
6507 
6508 	const VkSubpassDescription subpassDescription =
6509 	{
6510 		0u,															//	VkSubpassDescriptionFlags		flags;
6511 		VK_PIPELINE_BIND_POINT_GRAPHICS,							//	VkPipelineBindPoint				pipelineBindPoint;
6512 		static_cast<deUint32>(inputAttachmentReferences.size()),	//	deUint32						inputAttachmentCount;
6513 		inputAttachmentReferences.data(),							//	const VkAttachmentReference*	pInputAttachments;
6514 		0u,															//	deUint32						colorAttachmentCount;
6515 		nullptr,													//	const VkAttachmentReference*	pColorAttachments;
6516 		nullptr,													//	const VkAttachmentReference*	pResolveAttachments;
6517 		nullptr,													//	const VkAttachmentReference*	pDepthStencilAttachment;
6518 		0u,															//	deUint32						preserveAttachmentCount;
6519 		nullptr,													//	const deUint32*					pPreserveAttachments;
6520 	};
6521 
6522 	const VkRenderPassCreateInfo renderPassInfo =
6523 	{
6524 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				//	VkStructureType					sType;
6525 		nullptr,												//	const void*						pNext;
6526 		0u,														//	VkRenderPassCreateFlags			flags;
6527 		static_cast<deUint32>(attachmentDescriptions.size()),	//	deUint32						attachmentCount;
6528 		attachmentDescriptions.data(),							//	const VkAttachmentDescription*	pAttachments;
6529 		1u,														//	deUint32						subpassCount;
6530 		&subpassDescription,									//	const VkSubpassDescription*		pSubpasses;
6531 		0u,														//	deUint32						dependencyCount;
6532 		nullptr,												//	const VkSubpassDependency*		pDependencies;
6533 	};
6534 
6535 	const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
6536 
6537 	// Framebuffer.
6538 	std::vector<Move<VkImageView>>	imageViews;
6539 	std::vector<VkImageView>		imageViewsRaw;
6540 
6541 
6542 	if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6543 	{
6544 		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)));
6545 		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)));
6546 	}
6547 	else
6548 	{
6549 		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)));
6550 		for (deUint32 i = 0u; i < numDstLayers; ++i)
6551 		{
6552 			const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
6553 			imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
6554 		}
6555 	}
6556 
6557 
6558 	imageViewsRaw.reserve(imageViews.size());
6559 	std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
6560 
6561 	const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
6562 
6563 	// Storage buffer.
6564 	const auto			bufferCount	= static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
6565 	const auto			bufferSize	= static_cast<VkDeviceSize>(bufferCount * sizeof(deInt32));
6566 	BufferWithMemory	buffer		(vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
6567 	auto&				bufferAlloc	= buffer.getAllocation();
6568 	void*				bufferData	= bufferAlloc.getHostPtr();
6569 
6570 	// Update descriptor sets.
6571 	DescriptorSetUpdateBuilder updater;
6572 
6573 	const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
6574 	updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
6575 
6576 	std::vector<VkDescriptorImageInfo> imageInfos;
6577 	imageInfos.reserve(imageViewsRaw.size());
6578 	for (size_t i = 0; i < imageViewsRaw.size(); ++i)
6579 		imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
6580 
6581 	for (size_t i = 0; i < imageInfos.size(); ++i)
6582 		updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
6583 
6584 	updater.update(vkd, device);
6585 
6586 	// Vertex buffer.
6587 	std::vector<tcu::Vec4> fullScreenQuad;
6588 	{
6589 		// Full screen quad so every framebuffer pixel and sample location is verified by the shader.
6590 		const tcu::Vec4 topLeft		(-1.0f, -1.0f, 0.0f, 1.0f);
6591 		const tcu::Vec4 topRight	( 1.0f, -1.0f, 0.0f, 1.0f);
6592 		const tcu::Vec4 bottomLeft	(-1.0f,  1.0f, 0.0f, 1.0f);
6593 		const tcu::Vec4 bottomRight	( 1.0f,  1.0f, 0.0f, 1.0f);
6594 
6595 		fullScreenQuad.reserve(6u);
6596 		fullScreenQuad.push_back(topLeft);
6597 		fullScreenQuad.push_back(topRight);
6598 		fullScreenQuad.push_back(bottomRight);
6599 		fullScreenQuad.push_back(topLeft);
6600 		fullScreenQuad.push_back(bottomRight);
6601 		fullScreenQuad.push_back(bottomLeft);
6602 	}
6603 
6604 	const auto				vertexBufferSize	= static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
6605 	const auto				vertexBufferInfo	= makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
6606 	const BufferWithMemory	vertexBuffer		(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
6607 	const auto				vertexBufferHandler	= vertexBuffer.get();
6608 	auto&					vertexBufferAlloc	= vertexBuffer.getAllocation();
6609 	void*					vertexBufferData	= vertexBufferAlloc.getHostPtr();
6610 	const VkDeviceSize		vertexBufferOffset	= 0ull;
6611 
6612 	deMemcpy(vertexBufferData, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
6613 	flushAlloc(vkd, device, vertexBufferAlloc);
6614 
6615 	// Graphics pipeline.
6616 	const std::vector<VkViewport>	viewports	(1, makeViewport(m_params.src.image.extent));
6617 	const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_params.src.image.extent));
6618 
6619 	const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
6620 	{
6621 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
6622 		nullptr,													// const void*								pNext;
6623 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
6624 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
6625 		VK_FALSE,													// VkBool32									sampleShadingEnable;
6626 		0.0f,														// float									minSampleShading;
6627 		nullptr,													// const VkSampleMask*						pSampleMask;
6628 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
6629 		VK_FALSE													// VkBool32									alphaToOneEnable;
6630 	};
6631 
6632 	const auto graphicsPipeline = makeGraphicsPipeline(
6633 		vkd,									// const DeviceInterface&                        vk
6634 		device,									// const VkDevice                                device
6635 		pipelineLayout.get(),					// const VkPipelineLayout                        pipelineLayout
6636 		vertexModule.get(),						// const VkShaderModule                          vertexShaderModule
6637 		DE_NULL,								// const VkShaderModule                          tessellationControlModule
6638 		DE_NULL,								// const VkShaderModule                          tessellationEvalModule
6639 		DE_NULL,								// const VkShaderModule                          geometryShaderModule
6640 		verificationModule.get(),				// const VkShaderModule                          fragmentShaderModule
6641 		renderPass.get(),						// const VkRenderPass                            renderPass
6642 		viewports,								// const std::vector<VkViewport>&                viewports
6643 		scissors,								// const std::vector<VkRect2D>&                  scissors
6644 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology                     topology
6645 		0u,										// const deUint32                                subpass
6646 		0u,										// const deUint32                                patchControlPoints
6647 		nullptr,								// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
6648 		nullptr,								// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6649 		&multisampleStateParams);				// const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
6650 
6651 	// Command buffer.
6652 	const auto cmdPool		= makeCommandPool(vkd, device, queueIndex);
6653 	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6654 	const auto cmdBuffer	= cmdBufferPtr.get();
6655 
6656 	// Make sure multisample copy data is available to the fragment shader.
6657 	const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
6658 
6659 	// Make sure verification buffer data is available on the host.
6660 	const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6661 
6662 	// Record and submit command buffer.
6663 	beginCommandBuffer(vkd, cmdBuffer);
6664 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
6665 	beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_params.src.image.extent));
6666 	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
6667 	vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBufferHandler, &vertexBufferOffset);
6668 	vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
6669 	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
6670 	vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
6671 	endRenderPass(vkd, cmdBuffer);
6672 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
6673 	endCommandBuffer(vkd, cmdBuffer);
6674 	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6675 	m_context.resetCommandPoolForVKSC(device, *cmdPool);
6676 
6677 	// Verify intermediate results.
6678 	invalidateAlloc(vkd, device, bufferAlloc);
6679 	std::vector<deInt32> outputFlags (bufferCount, 0);
6680 	deMemcpy(outputFlags.data(), bufferData, static_cast<size_t>(bufferSize));
6681 
6682 	auto& log = m_context.getTestContext().getLog();
6683 	log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
6684 
6685 	const auto sampleCount = static_cast<deUint32>(m_params.samples);
6686 
6687 	for (deUint32 x = 0u; x < fbWidth; ++x)
6688 	for (deUint32 y = 0u; y < fbHeight; ++y)
6689 	for (deUint32 s = 0u; s < sampleCount; ++s)
6690 	{
6691 		const auto index = (y * fbWidth + x) * sampleCount + s;
6692 		if (!outputFlags[index])
6693 		{
6694 			std::ostringstream msg;
6695 			msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s;
6696 			return tcu::TestStatus::fail(msg.str());
6697 		}
6698 	}
6699 
6700 	log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
6701 	return tcu::TestStatus::pass("Pass");
6702 }
6703 
copyMSImageToMSImage(deUint32 copyArraySize)6704 void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
6705 {
6706 	const bool						useTwoQueues		= m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER;
6707 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
6708 	const VkDevice					vkDevice			= m_device;
6709 	const VkQueue					queue				= useTwoQueues ? m_alternativeQueue : m_queue;
6710 	const VkCommandBuffer			commandBuffer		= useTwoQueues ? m_alternativeCmdBuffer.get() : m_cmdBuffer.get();
6711 	const VkCommandPool				commandPool			= useTwoQueues ? m_alternativeCmdPool.get() : m_cmdPool.get();
6712 	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_params.src.image.format);
6713 	std::vector<VkImageCopy>		imageCopies;
6714 	std::vector<VkImageCopy2KHR>	imageCopies2KHR;
6715 
6716 	if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6717 	{
6718 		const VkImageSubresourceLayers	sourceSubresourceLayers	=
6719 		{
6720 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
6721 			0u,								// deUint32				mipLevel;
6722 			2u,								// deUint32				baseArrayLayer;
6723 			1u								// deUint32				layerCount;
6724 		};
6725 
6726 		const VkImageSubresourceLayers	destinationSubresourceLayers	=
6727 		{
6728 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;//getAspectFlags(dstTcuFormat)
6729 			0u,								// deUint32				mipLevel;
6730 			4u,								// deUint32				baseArrayLayer;
6731 			1u								// deUint32				layerCount;
6732 		};
6733 
6734 		const VkImageCopy				imageCopy	=
6735 		{
6736 			sourceSubresourceLayers,			// VkImageSubresourceLayers	srcSubresource;
6737 			{0, 0, 0},							// VkOffset3D				srcOffset;
6738 			destinationSubresourceLayers,		// VkImageSubresourceLayers	dstSubresource;
6739 			{0, 0, 0},							// VkOffset3D				dstOffset;
6740 			getExtent3D(m_params.src.image),	// VkExtent3D				extent;
6741 		};
6742 
6743 		if (m_params.extensionUse == EXTENSION_USE_NONE)
6744 		{
6745 			imageCopies.push_back(imageCopy);
6746 		}
6747 		else
6748 		{
6749 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6750 			imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6751 		}
6752 	}
6753 	else if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6754 	{
6755 		VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
6756 									getExtent3D(m_params.src.image).height / 2,
6757 									getExtent3D(m_params.src.image).depth};
6758 
6759 		for (CopyRegion region : m_params.regions)
6760 		{
6761 			const VkImageCopy				imageCopy	=
6762 			{
6763 				region.imageResolve.srcSubresource,		// VkImageSubresourceLayers	srcSubresource;
6764 				region.imageResolve.srcOffset,			// VkOffset3D				srcOffset;
6765 				region.imageResolve.dstSubresource,		// VkImageSubresourceLayers	dstSubresource;
6766 				region.imageResolve.dstOffset,			// VkOffset3D				dstOffset;
6767 				partialExtent,							// VkExtent3D				extent;
6768 			};
6769 
6770 			if (m_params.extensionUse == EXTENSION_USE_NONE)
6771 			{
6772 				imageCopies.push_back(imageCopy);
6773 			}
6774 			else
6775 			{
6776 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6777 				imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6778 			}
6779 		}
6780 	}
6781 	else
6782 	{
6783 		for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
6784 		{
6785 			const VkImageSubresourceLayers	sourceSubresourceLayers	=
6786 			{
6787 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;
6788 				0u,								// deUint32				mipLevel;
6789 				0u,								// deUint32				baseArrayLayer;
6790 				1u								// deUint32				layerCount;
6791 			};
6792 
6793 			const VkImageSubresourceLayers	destinationSubresourceLayers	=
6794 			{
6795 				getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask;//getAspectFlags(dstTcuFormat)
6796 				0u,								// deUint32				mipLevel;
6797 				layerNdx,						// deUint32				baseArrayLayer;
6798 				1u								// deUint32				layerCount;
6799 			};
6800 
6801 			const VkImageCopy				imageCopy	=
6802 			{
6803 				sourceSubresourceLayers,			// VkImageSubresourceLayers	srcSubresource;
6804 				{0, 0, 0},							// VkOffset3D				srcOffset;
6805 				destinationSubresourceLayers,		// VkImageSubresourceLayers	dstSubresource;
6806 				{0, 0, 0},							// VkOffset3D				dstOffset;
6807 				getExtent3D(m_params.src.image),	// VkExtent3D				extent;
6808 			};
6809 
6810 			if (m_params.extensionUse == EXTENSION_USE_NONE)
6811 			{
6812 				imageCopies.push_back(imageCopy);
6813 			}
6814 			else
6815 			{
6816 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6817 				imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6818 			}
6819 		}
6820 	}
6821 
6822 	VkImageSubresourceRange subresourceRange = {
6823 			getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask
6824 			0u,								// deUint32				baseMipLevel
6825 			1u,								// deUint32				mipLevels
6826 			0u,								// deUint32				baseArraySlice
6827 			copyArraySize					// deUint32				arraySize
6828 	};
6829 
6830 	// m_multisampledImage
6831 	const VkImageMemoryBarrier m_multisampledImageBarrier =
6832 	{
6833 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6834 		DE_NULL,									// const void*				pNext;
6835 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask;
6836 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
6837 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
6838 		m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
6839 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6840 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6841 		m_multisampledImage.get(),					// VkImage					image;
6842 		{											// VkImageSubresourceRange	subresourceRange;
6843 			getAspectFlags(srcTcuFormat),			// VkImageAspectFlags	aspectMask;
6844 			0u,										// deUint32				baseMipLevel;
6845 			1u,										// deUint32				mipLevels;
6846 			0u,										// deUint32				baseArraySlice;
6847 			getArraySize(m_params.src.image)		// deUint32				arraySize;
6848 		}
6849 	};
6850 	// m_multisampledCopyImage
6851 	VkImageMemoryBarrier m_multisampledCopyImageBarrier =
6852 	{
6853 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6854 		DE_NULL,									// const void*				pNext;
6855 		0,											// VkAccessFlags			srcAccessMask;
6856 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
6857 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
6858 		m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
6859 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6860 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6861 		m_multisampledCopyImage.get(),				// VkImage					image;
6862 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
6863 	};
6864 
6865 	// m_multisampledCopyNoCabImage (no USAGE_COLOR_ATTACHMENT_BIT)
6866 	const VkImageMemoryBarrier		m_multisampledCopyNoCabImageBarrier	=
6867 	{
6868 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6869 		DE_NULL,									// const void*				pNext;
6870 		0,											// VkAccessFlags			srcAccessMask;
6871 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
6872 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
6873 		m_params.dst.image.operationLayout,			// VkImageLayout			newLayout;
6874 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6875 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6876 		m_multisampledCopyNoCabImage.get(),			// VkImage					image;
6877 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
6878 	};
6879 
6880 	// destination image
6881 	const VkImageMemoryBarrier		multisampledCopyImagePostBarrier	=
6882 	{
6883 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6884 		DE_NULL,									// const void*				pNext;
6885 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
6886 		VK_ACCESS_MEMORY_READ_BIT,					// VkAccessFlags			dstAccessMask;
6887 		m_params.dst.image.operationLayout,			// VkImageLayout			oldLayout;
6888 		m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
6889 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6890 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6891 		m_multisampledCopyImage.get(),				// VkImage					image;
6892 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
6893 	};
6894 
6895 	// destination image (no USAGE_COLOR_ATTACHMENT_BIT)
6896 	const VkImageMemoryBarrier		betweenCopyImageBarrier				=
6897 	{
6898 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
6899 		DE_NULL,									// const void*				pNext;
6900 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
6901 		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
6902 		m_params.dst.image.operationLayout,			// VkImageLayout			oldLayout;
6903 		m_params.src.image.operationLayout,			// VkImageLayout			newLayout;
6904 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
6905 		VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
6906 		m_multisampledCopyNoCabImage.get(),			// VkImage					image;
6907 		subresourceRange							// VkImageSubresourceRange	subresourceRange;
6908 	};
6909 
6910 	// Queue family ownership transfer. Move ownership of the m_multisampledImage and m_multisampledImageCopy to the compute/transfer queue.
6911 	if (useTwoQueues)
6912 	{
6913 		// Release ownership from graphics queue.
6914 		{
6915 			std::vector<VkImageMemoryBarrier> barriers;
6916 			barriers.reserve(2);
6917 
6918 			// Barrier for m_multisampledImage
6919 			VkImageMemoryBarrier releaseBarrier = m_multisampledImageBarrier;
6920 			releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
6921 			releaseBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6922 			releaseBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6923 			barriers.push_back(releaseBarrier);
6924 
6925 			// Barrier for m_multisampledCopyImage
6926 			releaseBarrier = m_multisampledCopyImageBarrier;
6927 			releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
6928 			releaseBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6929 			releaseBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6930 			barriers.push_back(releaseBarrier);
6931 
6932 			beginCommandBuffer(vk, m_cmdBuffer.get());
6933 			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());
6934 			endCommandBuffer(vk, m_cmdBuffer.get());
6935 			submitCommandsAndWait(vk, vkDevice, m_queue, m_cmdBuffer.get());
6936 			m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
6937 		}
6938 
6939 		// Acquire ownership to compute / transfer queue.
6940 		{
6941 			std::vector<VkImageMemoryBarrier> barriers;
6942 			barriers.reserve(2);
6943 
6944 			// Barrier for m_multisampledImage
6945 			VkImageMemoryBarrier acquireBarrier = m_multisampledImageBarrier;
6946 			acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
6947 			acquireBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6948 			acquireBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6949 			barriers.push_back(acquireBarrier);
6950 
6951 			// Barrier for m_multisampledImage
6952 			acquireBarrier = m_multisampledCopyImageBarrier;
6953 			acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
6954 			acquireBarrier.srcQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
6955 			acquireBarrier.dstQueueFamilyIndex = m_alternativeQueueFamilyIndex;
6956 			barriers.push_back(acquireBarrier);
6957 
6958 			beginCommandBuffer(vk, commandBuffer);
6959 			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());
6960 			endCommandBuffer(vk, commandBuffer);
6961 			submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
6962 			m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
6963 		}
6964 
6965 		beginCommandBuffer(vk, commandBuffer);
6966 	}
6967 	else
6968 	{
6969 		std::vector<VkImageMemoryBarrier> imageBarriers;
6970 
6971 		imageBarriers.push_back(m_multisampledImageBarrier);
6972 		// Only use one barrier if no options have been given.
6973 		if (m_options != NO_OPTIONAL_OPERATION)
6974 		{
6975 			imageBarriers.push_back(m_multisampledCopyImageBarrier);
6976 			// Add the third barrier if option is as below.
6977 			if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
6978 				imageBarriers.push_back(m_multisampledCopyNoCabImageBarrier);
6979 		}
6980 
6981 		beginCommandBuffer(vk, commandBuffer);
6982 		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());
6983 	}
6984 
6985 	if (m_params.extensionUse == EXTENSION_USE_NONE)
6986 	{
6987 		if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
6988 		{
6989 			vk.cmdCopyImage(commandBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout, m_multisampledCopyNoCabImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
6990 			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);
6991 			vk.cmdCopyImage(commandBuffer, m_multisampledCopyNoCabImage.get(), m_params.src.image.operationLayout, m_multisampledCopyImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
6992 		}
6993 		else
6994 		{
6995 			vk.cmdCopyImage(commandBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout, m_multisampledCopyImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
6996 		}
6997 	}
6998 #ifndef CTS_USES_VULKANSC
6999 	else
7000 	{
7001 		if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
7002 		{
7003 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7004 			const VkCopyImageInfo2KHR copyImageInfo2KHR =
7005 			{
7006 				VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
7007 				DE_NULL,									// const void*				pNext;
7008 				m_multisampledImage.get(),					// VkImage					srcImage;
7009 				m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
7010 				m_multisampledCopyNoCabImage.get(),			// VkImage					dstImage;
7011 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			dstImageLayout;
7012 				(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
7013 				imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
7014 			};
7015 			const VkCopyImageInfo2KHR copyImageInfo2KHRCopy =
7016 			{
7017 				VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
7018 				DE_NULL,									// const void*				pNext;
7019 				m_multisampledCopyNoCabImage.get(),			// VkImage					srcImage;
7020 				vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,	// VkImageLayout			srcImageLayout;
7021 				m_multisampledCopyImage.get(),				// VkImage					dstImage;
7022 				m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
7023 				(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
7024 				imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
7025 			};
7026 
7027 			vk.cmdCopyImage2(commandBuffer, &copyImageInfo2KHR);
7028 			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);
7029 			vk.cmdCopyImage2(commandBuffer, &copyImageInfo2KHRCopy);
7030 		}
7031 		else
7032 		{
7033 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7034 			const VkCopyImageInfo2KHR copyImageInfo2KHR =
7035 			{
7036 				VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
7037 				DE_NULL,									// const void*				pNext;
7038 				m_multisampledImage.get(),					// VkImage					srcImage;
7039 				m_params.src.image.operationLayout,			// VkImageLayout			srcImageLayout;
7040 				m_multisampledCopyImage.get(),				// VkImage					dstImage;
7041 				m_params.dst.image.operationLayout,			// VkImageLayout			dstImageLayout;
7042 				(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
7043 				imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
7044 			};
7045 			vk.cmdCopyImage2(commandBuffer, &copyImageInfo2KHR);
7046 		}
7047 	}
7048 #endif // CTS_USES_VULKANSC
7049 
7050 	if (useTwoQueues)
7051 	{
7052 		endCommandBuffer(vk, commandBuffer);
7053 		submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7054 		m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7055 
7056 		VkImageMemoryBarrier srcImageBarrier = makeImageMemoryBarrier(
7057 				0u,
7058 				0u,
7059 				m_params.src.image.operationLayout,
7060 				m_params.src.image.operationLayout,
7061 				m_multisampledImage.get(),
7062 				m_multisampledImageBarrier.subresourceRange,
7063 				m_alternativeQueueFamilyIndex,
7064 				m_context.getUniversalQueueFamilyIndex());
7065 		// Release ownership from compute / transfer queue.
7066 		{
7067 			std::vector<VkImageMemoryBarrier> barriers;
7068 			barriers.reserve(2);
7069 
7070 			VkImageMemoryBarrier releaseBarrier = multisampledCopyImagePostBarrier;
7071 			releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7072 			releaseBarrier.srcQueueFamilyIndex = m_alternativeQueueFamilyIndex;
7073 			releaseBarrier.dstQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7074 			barriers.push_back(releaseBarrier);
7075 
7076 			releaseBarrier = srcImageBarrier;
7077 			releaseBarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
7078 			releaseBarrier.dstAccessMask = 0u; // dstAccessMask is ignored in ownership release operation.
7079 			barriers.push_back(releaseBarrier);
7080 
7081 			beginCommandBuffer(vk, commandBuffer);
7082 			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());
7083 			endCommandBuffer(vk, commandBuffer);
7084 			submitCommandsAndWait(vk, vkDevice, queue, commandBuffer);
7085 			m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7086 		}
7087 
7088 		// Acquire ownership to graphics queue.
7089 		{
7090 			std::vector<VkImageMemoryBarrier> barriers;
7091 			barriers.reserve(2);
7092 
7093 			VkImageMemoryBarrier acquireBarrier = multisampledCopyImagePostBarrier;
7094 			acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7095 			acquireBarrier.srcQueueFamilyIndex = m_alternativeQueueFamilyIndex;
7096 			acquireBarrier.dstQueueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
7097 			barriers.push_back(acquireBarrier);
7098 
7099 			acquireBarrier = srcImageBarrier;
7100 			acquireBarrier.srcAccessMask = 0u; // srcAccessMask is ignored in ownership acquire operation.
7101 			acquireBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
7102 			barriers.push_back(acquireBarrier);
7103 
7104 			beginCommandBuffer(vk, m_cmdBuffer.get());
7105 			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());
7106 			endCommandBuffer(vk, m_cmdBuffer.get());
7107 			submitCommandsAndWait(vk, vkDevice, m_queue, m_cmdBuffer.get());
7108 			m_context.resetCommandPoolForVKSC(vkDevice, *m_cmdPool);
7109 		}
7110 	}
7111 	else
7112 	{
7113 		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);
7114 		endCommandBuffer(vk, commandBuffer);
7115 		submitCommandsAndWait (vk, vkDevice, queue, commandBuffer);
7116 		m_context.resetCommandPoolForVKSC(vkDevice, commandPool);
7117 	}
7118 }
7119 
7120 class ResolveImageToImageTestCase : public vkt::TestCase
7121 {
7122 public:
ResolveImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params,const ResolveImageToImageOptions options=NO_OPTIONAL_OPERATION)7123 							ResolveImageToImageTestCase	(tcu::TestContext&					testCtx,
7124 														 const std::string&					name,
7125 														 const std::string&					description,
7126 														 const TestParams					params,
7127 														 const ResolveImageToImageOptions	options = NO_OPTIONAL_OPERATION)
7128 								: vkt::TestCase	(testCtx, name, description)
7129 								, m_params		(params)
7130 								, m_options		(options)
7131 	{}
7132 
7133 							virtual	void			initPrograms				(SourceCollections&		programCollection) const;
7134 
createInstance(Context & context) const7135 	virtual TestInstance*	createInstance				(Context&				context) const
7136 	{
7137 		return new ResolveImageToImage(context, m_params, m_options);
7138 	}
7139 
checkSupport(Context & context) const7140 	virtual void			checkSupport				(Context&				context) const
7141 	{
7142 		const VkSampleCountFlagBits	rasterizationSamples = m_params.samples;
7143 
7144 		// Intermediate result check uses fragmentStoresAndAtomics.
7145 		if (ResolveImageToImage::shouldVerifyIntermediateResults(m_options) && !context.getDeviceFeatures().fragmentStoresAndAtomics)
7146 		{
7147 			TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
7148 		}
7149 
7150 		if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
7151 			throw tcu::NotSupportedError("Unsupported number of rasterization samples");
7152 
7153 		VkImageFormatProperties properties;
7154 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
7155 																					m_params.src.image.format,
7156 																					m_params.src.image.imageType,
7157 																					VK_IMAGE_TILING_OPTIMAL,
7158 																					VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
7159 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
7160 			(context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
7161 																					m_params.dst.image.format,
7162 																					m_params.dst.image.imageType,
7163 																					VK_IMAGE_TILING_OPTIMAL,
7164 																					VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
7165 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
7166 		{
7167 			TCU_THROW(NotSupportedError, "Format not supported");
7168 		}
7169 
7170 		if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)	&&
7171 			(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
7172 		{
7173 			TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
7174 		}
7175 
7176 		// Find at least one queue family that supports compute queue but does NOT support graphics queue.
7177 		if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE)
7178 		{
7179 			bool foundQueue = false;
7180 			const std::vector<VkQueueFamilyProperties> queueFamilies = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
7181 			for (const auto& queueFamily : queueFamilies)
7182 			{
7183 				if (queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
7184 				{
7185 					foundQueue = true;
7186 					break;
7187 				}
7188 			}
7189 			if (!foundQueue)
7190 				TCU_THROW(NotSupportedError, "No queue family found that only supports compute queue.");
7191 		}
7192 
7193 		// Find at least one queue family that supports transfer queue but does NOT support graphics and compute queue.
7194 		if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER)
7195 		{
7196 			bool foundQueue = false;
7197 			const std::vector<VkQueueFamilyProperties> queueFamilies = getPhysicalDeviceQueueFamilyProperties(context.getInstanceInterface(), context.getPhysicalDevice());
7198 			for (const auto& queueFamily : queueFamilies)
7199 			{
7200 				if (queueFamily.queueFlags & VK_QUEUE_TRANSFER_BIT && !(queueFamily.queueFlags & VK_QUEUE_COMPUTE_BIT) && !(queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT))
7201 				{
7202 					foundQueue = true;
7203 					break;
7204 				}
7205 			}
7206 			if (!foundQueue)
7207 				TCU_THROW(NotSupportedError, "No queue family found that only supports transfer queue.");
7208 		}
7209 	}
7210 
7211 private:
7212 	TestParams							m_params;
7213 	const ResolveImageToImageOptions	m_options;
7214 };
7215 
initPrograms(SourceCollections & programCollection) const7216 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
7217 {
7218 	programCollection.glslSources.add("vert") << glu::VertexSource(
7219 		"#version 310 es\n"
7220 		"layout (location = 0) in highp vec4 a_position;\n"
7221 		"void main()\n"
7222 		"{\n"
7223 		"	gl_Position = a_position;\n"
7224 		"}\n");
7225 
7226 
7227 	programCollection.glslSources.add("frag") << glu::FragmentSource(
7228 		"#version 310 es\n"
7229 		"layout (location = 0) out highp vec4 o_color;\n"
7230 		"void main()\n"
7231 		"{\n"
7232 		"	o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
7233 		"}\n");
7234 
7235 	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)
7236 	{
7237 		// The shader verifies all layers in the copied image are the same as the source image.
7238 		// This needs an image view per layer in the copied image.
7239 		// Set 0 contains the output buffer.
7240 		// Set 1 contains the input attachments.
7241 
7242 		std::ostringstream verificationShader;
7243 
7244 		verificationShader
7245 			<< "#version 450\n"
7246 			<< "\n"
7247 			<< "layout (push_constant, std430) uniform PushConstants {\n"
7248 			<< "    int width;\n"
7249 			<< "    int height;\n"
7250 			<< "    int samples;\n"
7251 			<< "};\n"
7252 			<< "layout (set=0, binding=0) buffer VerificationResults {\n"
7253 			<< "    int verificationFlags[];\n"
7254 			<< "};\n"
7255 			<< "layout (input_attachment_index=0, set=1, binding=0) uniform subpassInputMS attachment0;\n"
7256 			;
7257 
7258 		const auto dstLayers = getArraySize(m_params.dst.image);
7259 
7260 		if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7261 		{
7262 			verificationShader << "layout (input_attachment_index=1, set=1, binding=1) uniform subpassInputMS attachment1;\n";
7263 		}
7264 		else
7265 		{
7266 			for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7267 			{
7268 				const auto i = layerNdx + 1u;
7269 				verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
7270 			}
7271 		}
7272 
7273 		// Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
7274 		// created with a single sample.
7275 		verificationShader
7276 			<< "\n"
7277 			<< "void main() {\n"
7278 			<< "    for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
7279 			<< "        vec4 orig = subpassLoad(attachment0, sampleID);\n"
7280 			;
7281 
7282 		std::ostringstream testCondition;
7283 		if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
7284 		{
7285 			verificationShader << "        vec4 copy = subpassLoad(attachment1, sampleID);\n";
7286 			testCondition << "orig == copy";
7287 		}
7288 		else
7289 		{
7290 			for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7291 			{
7292 				const auto i = layerNdx + 1u;
7293 				verificationShader << "        vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
7294 			}
7295 
7296 			for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
7297 			{
7298 				const auto i = layerNdx + 1u;
7299 				testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
7300 			}
7301 		}
7302 
7303 		verificationShader
7304 			<< "\n"
7305 			<< "        ivec3 coords  = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
7306 			<< "        int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
7307 			<< "\n"
7308 			<< "        verificationFlags[bufferPos] = ((" << testCondition.str() << ") ? 1 : 0); \n"
7309 			<< "    }\n"
7310 			<< "}\n"
7311 			;
7312 
7313 		programCollection.glslSources.add("verify") << glu::FragmentSource(verificationShader.str());
7314 	}
7315 }
7316 
7317 class DepthStencilMSAA : public vkt::TestInstance
7318 {
7319 public:
7320 	enum CopyOptions				{COPY_WHOLE_IMAGE, COPY_ARRAY_TO_ARRAY, COPY_PARTIAL};
7321 
7322 	struct TestParameters
7323 	{
7324 		AllocationKind				allocationKind;
7325 		ExtensionUse				extensionUse;
7326 		CopyOptions					copyOptions;
7327 		VkSampleCountFlagBits		samples;
7328 		VkImageLayout				srcImageLayout;
7329 		VkImageLayout				dstImageLayout;
7330 		VkFormat					imageFormat;
7331 		VkImageAspectFlags			copyAspect;
7332 		deBool						imageOffset;
7333 	};
7334 
7335 									DepthStencilMSAA			(Context&			context,
7336 																 TestParameters		testParameters);
7337 	tcu::TestStatus					iterate						(void) override;
7338 protected:
7339 	tcu::TestStatus					checkCopyResults			(VkCommandBuffer				cmdBuffer,
7340 																 const VkImageAspectFlagBits&	aspectToVerify,
7341 																 VkImage						srcImage,
7342 																 VkImage						dstImage);
7343 
7344 private:
7345 	// Returns image aspects used in the copy regions.
getUsedImageAspects()7346 	VkImageAspectFlags				getUsedImageAspects ()
7347 	{
7348 		auto aspectFlags = (VkImageAspectFlags)0;
7349 		for (const auto &region : m_regions)
7350 		{
7351 			aspectFlags |= region.imageCopy.srcSubresource.aspectMask;
7352 		}
7353 		return aspectFlags;
7354 	}
7355 
7356 	ImageParms						m_srcImage;
7357 	ImageParms						m_dstImage;
7358 	std::vector<CopyRegion>			m_regions;
7359 	const TestParameters			m_params;
7360 	const float						m_clearValue = 0.0f;
7361 };
7362 
DepthStencilMSAA(Context & context,TestParameters testParameters)7363 DepthStencilMSAA::DepthStencilMSAA (Context& context, TestParameters testParameters)
7364 	: vkt::TestInstance(context)
7365 	, m_params(testParameters)
7366 {
7367 	// params.src.image is the parameters used to create the copy source image
7368 	m_srcImage.imageType			= VK_IMAGE_TYPE_2D;
7369 	m_srcImage.format				= testParameters.imageFormat;
7370 	m_srcImage.extent				= defaultExtent;
7371 	m_srcImage.tiling				= VK_IMAGE_TILING_OPTIMAL;
7372 	m_srcImage.operationLayout		= testParameters.srcImageLayout;
7373 	m_srcImage.createFlags			= 0u;
7374 
7375 	// params.src.image is the parameters used to create the copy destination image
7376 	m_dstImage.imageType			= VK_IMAGE_TYPE_2D;
7377 	m_dstImage.format				= testParameters.imageFormat;
7378 	m_dstImage.extent				= defaultExtent;
7379 	m_dstImage.tiling				= VK_IMAGE_TILING_OPTIMAL;
7380 	m_dstImage.operationLayout		= testParameters.dstImageLayout;
7381 	m_dstImage.createFlags			= 0u;
7382 
7383 	const VkImageSubresourceLayers depthSubresourceLayers =
7384 	{
7385 		VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
7386 		0u,							// uint32_t				mipLevel;
7387 		0u,							// uint32_t				baseArrayLayer;
7388 		1u							// uint32_t				layerCount;
7389 	};
7390 
7391 	const VkImageSubresourceLayers stencilSubresourceLayers =
7392 	{
7393 		VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
7394 		0u,								// uint32_t				mipLevel;
7395 		0u,								// uint32_t				baseArrayLayer;
7396 		1u								// uint32_t				layerCount;
7397 	};
7398 
7399 	VkImageCopy				depthCopy	=
7400 	{
7401 		depthSubresourceLayers,	// VkImageSubresourceLayers	srcSubresource;
7402 		{0, 0, 0},				// VkOffset3D				srcOffset;
7403 		depthSubresourceLayers,	// VkImageSubresourceLayers	dstSubresource;
7404 		{0, 0, 0},				// VkOffset3D				dstOffset;
7405 		defaultExtent,			// VkExtent3D				extent;
7406 	};
7407 
7408 	VkImageCopy				stencilCopy	=
7409 	{
7410 		stencilSubresourceLayers,	// VkImageSubresourceLayers	srcSubresource;
7411 		{0, 0, 0},					// VkOffset3D				srcOffset;
7412 		stencilSubresourceLayers,	// VkImageSubresourceLayers	dstSubresource;
7413 		{0, 0, 0},					// VkOffset3D				dstOffset;
7414 		defaultExtent,				// VkExtent3D				extent;
7415 	};
7416 
7417 	if (testParameters.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY)
7418 	{
7419 		m_srcImage.extent.depth						= 5u;
7420 		depthCopy.srcSubresource.baseArrayLayer		= 2u;
7421 		depthCopy.dstSubresource.baseArrayLayer		= 3u;
7422 		stencilCopy.srcSubresource.baseArrayLayer	= 2u;
7423 		stencilCopy.dstSubresource.baseArrayLayer	= 3u;
7424 	}
7425 
7426 	CopyRegion					depthCopyRegion;
7427 	CopyRegion					stencilCopyRegion;
7428 	depthCopyRegion.imageCopy	= depthCopy;
7429 	stencilCopyRegion.imageCopy	= stencilCopy;
7430 
7431 	std::vector<CopyRegion>		depthRegions;
7432 	std::vector<CopyRegion>		stencilRegions;
7433 
7434 	if (testParameters.copyOptions == DepthStencilMSAA::COPY_PARTIAL)
7435 	{
7436 		if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
7437 		{
7438 			depthCopyRegion.imageCopy.extent		= {defaultHalfSize, defaultHalfSize, 1};
7439 			// Copy region from bottom right to bottom left
7440 			depthCopyRegion.imageCopy.srcOffset		= {defaultHalfSize, defaultHalfSize, 0};
7441 			depthCopyRegion.imageCopy.dstOffset		= {0, defaultHalfSize, 0};
7442 			depthRegions.push_back(depthCopyRegion);
7443 			// Copy region from top right to bottom right
7444 			depthCopyRegion.imageCopy.srcOffset		= {defaultHalfSize, 0, 0};
7445 			depthCopyRegion.imageCopy.dstOffset		= {defaultHalfSize, defaultHalfSize, 0};
7446 			depthRegions.push_back(depthCopyRegion);
7447 		}
7448 		if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
7449 		{
7450 			stencilCopyRegion.imageCopy.extent		= {defaultHalfSize, defaultHalfSize, 1};
7451 			// Copy region from bottom right to bottom left
7452 			stencilCopyRegion.imageCopy.srcOffset	= {defaultHalfSize, defaultHalfSize, 0};
7453 			stencilCopyRegion.imageCopy.dstOffset	= {0, defaultHalfSize, 0};
7454 			stencilRegions.push_back(stencilCopyRegion);
7455 			// Copy region from top right to bottom right
7456 			stencilCopyRegion.imageCopy.srcOffset	= {defaultHalfSize, 0, 0};
7457 			stencilCopyRegion.imageCopy.dstOffset	= {defaultHalfSize, defaultHalfSize, 0};
7458 			stencilRegions.push_back(stencilCopyRegion);
7459 		}
7460 	}
7461 	else
7462 	{
7463 		// Copy the default region (full image)
7464 		if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
7465 		{
7466 			depthRegions.push_back(depthCopyRegion);
7467 		}
7468 		if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
7469 		{
7470 			stencilRegions.push_back(stencilCopyRegion);
7471 		}
7472 	}
7473 
7474 	if (testParameters.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
7475 	{
7476 		m_regions.insert(m_regions.end(), depthRegions.begin(), depthRegions.end());
7477 	}
7478 
7479 	if (testParameters.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
7480 	{
7481 		m_regions.insert(m_regions.end(), stencilRegions.begin(), stencilRegions.end());
7482 	}
7483 }
7484 
iterate(void)7485 tcu::TestStatus DepthStencilMSAA::iterate (void)
7486 {
7487 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
7488 	const InstanceInterface&		vki					= m_context.getInstanceInterface();
7489 	const VkDevice					vkDevice			= m_context.getDevice();
7490 	const VkPhysicalDevice			vkPhysDevice		= m_context.getPhysicalDevice();
7491 	const VkQueue					queue				= m_context.getUniversalQueue();
7492 	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
7493 	Allocator&						memAlloc			= m_context.getDefaultAllocator();
7494 	Move<VkCommandPool>				cmdPool				= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
7495 	Move<VkCommandBuffer>			cmdBuffer			= allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
7496 
7497 	const tcu::TextureFormat		srcTcuFormat		= mapVkFormat(m_srcImage.format);
7498 	const tcu::TextureFormat		dstTcuFormat		= mapVkFormat(m_dstImage.format);
7499 	VkImageAspectFlags				aspectFlags			= getUsedImageAspects();
7500 	deUint32						sourceArraySize		= getArraySize(m_srcImage);
7501 
7502 	Move<VkImage>					srcImage;
7503 	de::MovePtr<Allocation>			srcImageAlloc;
7504 	Move<VkImage>					dstImage;
7505 	de::MovePtr<Allocation>			dstImageAlloc;
7506 
7507 	// 1. Create the images and draw a triangle to the source image.
7508 	{
7509 		const VkComponentMapping		componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
7510 		Move<VkShaderModule>			vertexShaderModule		= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
7511 		Move<VkShaderModule>			fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
7512 		std::vector<tcu::Vec4>			vertices;
7513 		Move<VkBuffer>					vertexBuffer;
7514 		de::MovePtr<Allocation>			vertexBufferAlloc;
7515 		Move<VkPipelineLayout>			pipelineLayout;
7516 		Move<VkPipeline>				graphicsPipeline;
7517 		Move<VkRenderPass>				renderPass;
7518 
7519 		// Create multisampled depth/stencil image (srcImage) and the copy destination image (dstImage).
7520 		{
7521 			VkImageCreateInfo multiSampledImageParams =
7522 			{
7523 				VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
7524 				DE_NULL,										// const void*				pNext;
7525 				getCreateFlags(m_srcImage),						// VkImageCreateFlags		flags;
7526 				m_srcImage.imageType,							// VkImageType				imageType;
7527 				m_srcImage.format,								// VkFormat					format;
7528 				getExtent3D(m_srcImage),						// VkExtent3D				extent;
7529 				1u,												// deUint32					mipLevels;
7530 				getArraySize(m_srcImage),						// deUint32					arrayLayers;
7531 				m_params.samples,								// VkSampleCountFlagBits	samples;
7532 				VK_IMAGE_TILING_OPTIMAL,						// VkImageTiling			tiling;
7533 				VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT		// VkImageUsageFlags		usage;
7534 					| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
7535 					| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
7536 					| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
7537 				VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
7538 				1u,												// deUint32					queueFamilyIndexCount;
7539 				&queueFamilyIndex,								// const deUint32*			pQueueFamilyIndices;
7540 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			initialLayout;
7541 			};
7542 
7543 			srcImage		= createImage(vk, vkDevice, &multiSampledImageParams);
7544 
7545 			VkMemoryRequirements	req		= getImageMemoryRequirements(vk, vkDevice, *srcImage);
7546 			deUint32				offset	= m_params.imageOffset ? static_cast<deUint32>(req.alignment) : 0;
7547 
7548 			srcImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, srcImage.get(), MemoryRequirement::Any, memAlloc,
7549 											 m_params.allocationKind, offset);
7550 			VK_CHECK(vk.bindImageMemory(vkDevice, srcImage.get(), srcImageAlloc->getMemory(), srcImageAlloc->getOffset() + offset));
7551 
7552 			dstImage		= createImage(vk, vkDevice, &multiSampledImageParams);
7553 			dstImageAlloc	= allocateImage(vki, vk, vkPhysDevice, vkDevice, dstImage.get(), MemoryRequirement::Any, memAlloc, m_params.allocationKind, 0u);
7554 			VK_CHECK(vk.bindImageMemory(vkDevice, dstImage.get(), dstImageAlloc->getMemory(), dstImageAlloc->getOffset()));
7555 		}
7556 
7557 		// Create render pass.
7558 		{
7559 			const VkImageLayout				initialLayout			= m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED;
7560 			const VkAttachmentDescription	attachmentDescription	=
7561 			{
7562 				0u,													// VkAttachmentDescriptionFlags		flags
7563 				m_srcImage.format,									// VkFormat							format
7564 				m_params.samples,									// VkSampleCountFlagBits			samples
7565 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp
7566 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp
7567 				VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				stencilLoadOp
7568 				VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				stencilStoreOp
7569 				initialLayout,										// VkImageLayout					initialLayout
7570 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout
7571 			};
7572 
7573 			const VkAttachmentReference		attachmentReference		=
7574 			{
7575 				0u,													// deUint32			attachment
7576 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout	layout
7577 			};
7578 
7579 			const VkSubpassDescription		subpassDescription		=
7580 			{
7581 				0u,									// VkSubpassDescriptionFlags	flags
7582 				VK_PIPELINE_BIND_POINT_GRAPHICS,	// VkPipelineBindPoint			pipelineBindPoint
7583 				0u,									// deUint32						inputAttachmentCount
7584 				DE_NULL,							// const VkAttachmentReference*	pInputAttachments
7585 				0u,									// deUint32						colorAttachmentCount
7586 				DE_NULL,							// const VkAttachmentReference*	pColorAttachments
7587 				DE_NULL,							// const VkAttachmentReference*	pResolveAttachments
7588 				&attachmentReference,				// const VkAttachmentReference*	pDepthStencilAttachment
7589 				0u,									// deUint32						preserveAttachmentCount
7590 				DE_NULL								// const VkAttachmentReference*	pPreserveAttachments
7591 			};
7592 
7593 			const VkRenderPassCreateInfo	renderPassParams		=
7594 			{
7595 				VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType					sType;
7596 				DE_NULL,									// const void*						pNext;
7597 				0u,											// VkRenderPassCreateFlags			flags;
7598 				1u,											// deUint32							attachmentCount;
7599 				&attachmentDescription,						// const VkAttachmentDescription*	pAttachments;
7600 				1u,											// deUint32							subpassCount;
7601 				&subpassDescription,						// const VkSubpassDescription*		pSubpasses;
7602 				0u,											// deUint32							dependencyCount;
7603 				DE_NULL										// const VkSubpassDependency*		pDependencies;
7604 			};
7605 
7606 			renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
7607 		}
7608 
7609 		// Create pipeline layout
7610 		{
7611 			const VkPipelineLayoutCreateInfo	pipelineLayoutParams	=
7612 			{
7613 				VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType					sType;
7614 				DE_NULL,										// const void*						pNext;
7615 				0u,												// VkPipelineLayoutCreateFlags		flags;
7616 				0u,												// deUint32							setLayoutCount;
7617 				DE_NULL,										// const VkDescriptorSetLayout*		pSetLayouts;
7618 				0u,												// deUint32							pushConstantRangeCount;
7619 				DE_NULL											// const VkPushConstantRange*		pPushConstantRanges;
7620 			};
7621 
7622 			pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
7623 		}
7624 
7625 		// Create upper half triangle.
7626 		{
7627 			// Add triangle.
7628 			vertices.emplace_back(-1.0f, -1.0f, 0.0f, 1.0f);
7629 			vertices.emplace_back(1.0f,  -1.0f, 0.0f, 1.0f);
7630 			vertices.emplace_back(1.0f,  1.0f,  0.0f, 1.0f);
7631 		}
7632 
7633 		// Create vertex buffer.
7634 		{
7635 			const VkDeviceSize			vertexDataSize		= vertices.size() * sizeof(tcu::Vec4);
7636 			const VkBufferCreateInfo	vertexBufferParams	=
7637 			{
7638 				VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
7639 				DE_NULL,								// const void*			pNext;
7640 				0u,										// VkBufferCreateFlags	flags;
7641 				vertexDataSize,							// VkDeviceSize			size;
7642 				VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// VkBufferUsageFlags	usage;
7643 				VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
7644 				1u,										// deUint32				queueFamilyIndexCount;
7645 				&queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
7646 			};
7647 
7648 			vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
7649 			vertexBufferAlloc	= allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
7650 			VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
7651 
7652 			// Load vertices into vertex buffer.
7653 			deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
7654 			flushAlloc(vk, vkDevice, *vertexBufferAlloc);
7655 		}
7656 
7657 		{
7658 			Move<VkFramebuffer>		framebuffer;
7659 			Move<VkImageView>		sourceAttachmentView;
7660 
7661 			// Create depth/stencil attachment view.
7662 			{
7663 				const uint32_t arrayLayer = m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? 2u : 0u;
7664 				const VkImageViewCreateInfo		depthStencilAttachmentViewParams	=
7665 				{
7666 					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
7667 					DE_NULL,									// const void*				pNext;
7668 					0u,											// VkImageViewCreateFlags	flags;
7669 					*srcImage,									// VkImage					image;
7670 					VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType;
7671 					m_srcImage.format,							// VkFormat					format;
7672 					componentMappingRGBA,						// VkComponentMapping		components;
7673 					{ aspectFlags, 0u, 1u, arrayLayer, 1u }		// VkImageSubresourceRange	subresourceRange;
7674 				};
7675 				sourceAttachmentView	= createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
7676 			}
7677 
7678 			// Create framebuffer
7679 			{
7680 				const VkFramebufferCreateInfo	framebufferParams	=
7681 				{
7682 					VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType				sType;
7683 					DE_NULL,									// const void*					pNext;
7684 					0u,											// VkFramebufferCreateFlags		flags;
7685 					*renderPass,								// VkRenderPass					renderPass;
7686 					1u,											// deUint32						attachmentCount;
7687 					&sourceAttachmentView.get(),				// const VkImageView*			pAttachments;
7688 					m_srcImage.extent.width,					// deUint32						width;
7689 					m_srcImage.extent.height,					// deUint32						height;
7690 					1u											// deUint32						layers;
7691 				};
7692 
7693 				framebuffer	= createFramebuffer(vk, vkDevice, &framebufferParams);
7694 			}
7695 
7696 			// Create pipeline
7697 			{
7698 				const std::vector<VkViewport>	viewports	(1, makeViewport(m_srcImage.extent));
7699 				const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_srcImage.extent));
7700 
7701 				const VkPipelineMultisampleStateCreateInfo		multisampleStateParams				=
7702 				{
7703 					VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
7704 					DE_NULL,													// const void*								pNext;
7705 					0u,															// VkPipelineMultisampleStateCreateFlags	flags;
7706 					m_params.samples,											// VkSampleCountFlagBits					rasterizationSamples;
7707 					VK_FALSE,													// VkBool32									sampleShadingEnable;
7708 					0.0f,														// float									minSampleShading;
7709 					DE_NULL,													// const VkSampleMask*						pSampleMask;
7710 					VK_FALSE,													// VkBool32									alphaToCoverageEnable;
7711 					VK_FALSE													// VkBool32									alphaToOneEnable;
7712 				};
7713 
7714 				const VkStencilOpState							stencilOpState						=
7715 				{
7716 					VK_STENCIL_OP_KEEP,		// VkStencilOp	failOp
7717 					VK_STENCIL_OP_REPLACE,	// VkStencilOp	passOp
7718 					VK_STENCIL_OP_KEEP,		// VkStencilOp	depthFailOp
7719 					VK_COMPARE_OP_ALWAYS,	// VkCompareOp	compareOp
7720 					0,						// deUint32		compareMask
7721 					0xFF,					// deUint32		writeMask
7722 					0xFF					// deUint32		reference
7723 				};
7724 
7725 				const VkPipelineDepthStencilStateCreateInfo		depthStencilStateCreateInfoDefault	=
7726 				{
7727 					VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType							sType
7728 					DE_NULL,														// const void*								pNext
7729 					0u,																// VkPipelineDepthStencilStateCreateFlags	flags
7730 					aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT ? VK_TRUE : VK_FALSE,	// VkBool32									depthTestEnable
7731 					aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT ? VK_TRUE : VK_FALSE,	// VkBool32									depthWriteEnable
7732 					VK_COMPARE_OP_ALWAYS,											// VkCompareOp								depthCompareOp
7733 					VK_FALSE,														// VkBool32									depthBoundsTestEnable
7734 					aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT ? VK_TRUE : VK_FALSE,	// VkBool32									stencilTestEnable
7735 					stencilOpState,													// VkStencilOpState							front
7736 					stencilOpState,													// VkStencilOpState							back
7737 					0.0f,															// float									minDepthBounds
7738 					1.0f,															// float									maxDepthBounds
7739 				};
7740 
7741 				graphicsPipeline = makeGraphicsPipeline(vk,										// const DeviceInterface&							vk
7742 														vkDevice,								// const VkDevice									device
7743 														*pipelineLayout,						// const VkPipelineLayout							pipelineLayout
7744 														*vertexShaderModule,					// const VkShaderModule								vertexShaderModule
7745 														DE_NULL,								// const VkShaderModule								tessellationControlModule
7746 														DE_NULL,								// const VkShaderModule								tessellationEvalModule
7747 														DE_NULL,								// const VkShaderModule								geometryShaderModule
7748 														*fragmentShaderModule,					// const VkShaderModule								fragmentShaderModule
7749 														*renderPass,							// const VkRenderPass								renderPass
7750 														viewports,								// const std::vector<VkViewport>&					viewports
7751 														scissors,								// const std::vector<VkRect2D>&						scissors
7752 														VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology						topology
7753 														0u,										// const deUint32									subpass
7754 														0u,										// const deUint32									patchControlPoints
7755 														DE_NULL,								// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
7756 														DE_NULL,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
7757 														&multisampleStateParams,				// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
7758 														&depthStencilStateCreateInfoDefault);	// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
7759 			}
7760 
7761 			// Create command buffer
7762 			{
7763 				beginCommandBuffer(vk, *cmdBuffer, 0u);
7764 
7765 				const VkClearValue srcImageClearValue = makeClearValueDepthStencil(0.1f, 0x10);
7766 
7767 				// Change the layout of each layer of the depth / stencil image to VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL and clear the images.
7768 				const VkClearValue copiedImageClearValue = makeClearValueDepthStencil(m_clearValue, (uint32_t)m_clearValue);
7769 				const auto subResourceRange = makeImageSubresourceRange(				// VkImageSubresourceRange	subresourceRange
7770 												(getAspectFlags(m_srcImage.format)),	// VkImageAspectFlags		aspectMask
7771 												0u,										// uint32_t					baseMipLevel
7772 												1u,										// uint32_t					levelCount
7773 												0u,										// uint32_t					baseArrayLayer
7774 												getArraySize(m_srcImage));
7775 
7776 				const VkImageMemoryBarrier preClearBarrier = makeImageMemoryBarrier(
7777 					0u,										// VkAccessFlags			srcAccessMask
7778 					VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask
7779 					VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			oldLayout
7780 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout
7781 					srcImage.get(),							// VkImage					image
7782 					subResourceRange);						// VkImageSubresourceRange	subresourceRange
7783 				std::vector<VkImageMemoryBarrier> preClearBarriers(2u, preClearBarrier);
7784 				preClearBarriers[1].image = dstImage.get();
7785 				vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7786 					(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2, preClearBarriers.data());
7787 
7788 				vk.cmdClearDepthStencilImage(
7789 						*cmdBuffer,								// VkCommandBuffer					commandBuffer
7790 						srcImage.get(),							// VkImage							image
7791 						VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout					imageLayout
7792 						&srcImageClearValue.depthStencil,		// const VkClearDepthStencilValue*	pDepthStencil
7793 						1u,										// uint32_t							rangeCount
7794 						&subResourceRange);						// const VkImageSubresourceRange*	pRanges
7795 
7796 				vk.cmdClearDepthStencilImage(
7797 						*cmdBuffer,								// VkCommandBuffer					commandBuffer
7798 						dstImage.get(),							// VkImage							image
7799 						VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout					imageLayout
7800 						&copiedImageClearValue.depthStencil,	// const VkClearDepthStencilValue*	pDepthStencil
7801 						1u,										// uint32_t							rangeCount
7802 						&subResourceRange);						// const VkImageSubresourceRange*	pRanges
7803 
7804 				// Post clear barrier
7805 				const VkImageMemoryBarrier postClearBarrier = makeImageMemoryBarrier(
7806 					VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags			srcAccessMask
7807 					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			dstAccessMask
7808 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout			oldLayout
7809 					VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout
7810 					srcImage.get(),										// VkImage					image
7811 					subResourceRange);									// VkImageSubresourceRange	subresourceRange
7812 
7813 				vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
7814 					(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postClearBarrier);
7815 
7816 				beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_srcImage.extent.width, m_srcImage.extent.height), 1u, &srcImageClearValue);
7817 
7818 				const VkDeviceSize vertexBufferOffset = 0u;
7819 
7820 				vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
7821 				vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
7822 				vk.cmdDraw(*cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
7823 
7824 				endRenderPass(vk, *cmdBuffer);
7825 				endCommandBuffer(vk, *cmdBuffer);
7826 			}
7827 
7828 			submitCommandsAndWait (vk, vkDevice, queue, *cmdBuffer);
7829 			m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
7830 		}
7831 	}
7832 
7833 	// 2. Record a command buffer that contains the copy operation(s).
7834 	beginCommandBuffer(vk, *cmdBuffer);
7835 	{
7836 		// Change the image layouts and synchronize the memory access before copying
7837 		{
7838 			const VkImageMemoryBarrier imageBarriers[] =
7839 			{
7840 				// srcImage
7841 				makeImageMemoryBarrier(
7842 					VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,		// VkAccessFlags			srcAccessMask
7843 					VK_ACCESS_TRANSFER_READ_BIT,						// VkAccessFlags			dstAccessMask
7844 					VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			oldLayout
7845 					m_srcImage.operationLayout,							// VkImageLayout			newLayout
7846 					srcImage.get(),										// VkImage					image
7847 					makeImageSubresourceRange(							// VkImageSubresourceRange	subresourceRange
7848 						getAspectFlags(srcTcuFormat),	// VkImageAspectFlags	aspectMask
7849 						0u,								// deUint32				baseMipLevel
7850 						1u,								// deUint32				levelCount
7851 						0u,								// deUint32				baseArrayLayer
7852 						sourceArraySize					// deUint32				layerCount
7853 					)),
7854 				// dstImage
7855 				makeImageMemoryBarrier(
7856 					VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			srcAccessMask
7857 					VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask
7858 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			oldLayout
7859 					m_dstImage.operationLayout,				// VkImageLayout			newLayout
7860 					dstImage.get(),							// VkImage					image
7861 					makeImageSubresourceRange(				// VkImageSubresourceRange	subresourceRange
7862 						getAspectFlags(dstTcuFormat),	// VkImageAspectFlags	aspectMask
7863 						0u,								// deUint32				baseMipLevel
7864 						1u,								// deUint32				levelCount
7865 						0u,								// deUint32				baseArrayLayer
7866 						sourceArraySize					// deUint32				layerCount
7867 					)),
7868 			};
7869 			vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
7870 				(VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2u, imageBarriers);
7871 		}
7872 
7873 		std::vector<VkImageCopy>		imageCopies;
7874 		std::vector<VkImageCopy2KHR>	imageCopies2KHR;
7875 		for (const auto & region : m_regions)
7876 		{
7877 			if (m_params.extensionUse == EXTENSION_USE_NONE)
7878 			{
7879 				imageCopies.push_back(region.imageCopy);
7880 			}
7881 			else
7882 			{
7883 				DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7884 				imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(region.imageCopy));
7885 			}
7886 		}
7887 
7888 		if (m_params.extensionUse == EXTENSION_USE_NONE)
7889 		{
7890 			vk.cmdCopyImage(*cmdBuffer, srcImage.get(), m_srcImage.operationLayout, dstImage.get(), m_dstImage.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
7891 		}
7892 #ifndef CTS_USES_VULKANSC
7893 		else
7894 		{
7895 			DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
7896 			const VkCopyImageInfo2KHR copyImageInfo2KHR =
7897 			{
7898 				VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR,	// VkStructureType			sType;
7899 				DE_NULL,									// const void*				pNext;
7900 				srcImage.get(),								// VkImage					srcImage;
7901 				m_srcImage.operationLayout,					// VkImageLayout			srcImageLayout;
7902 				dstImage.get(),								// VkImage					dstImage;
7903 				m_dstImage.operationLayout,					// VkImageLayout			dstImageLayout;
7904 				(deUint32)imageCopies2KHR.size(),			// uint32_t					regionCount;
7905 				imageCopies2KHR.data()						// const VkImageCopy2KHR*	pRegions;
7906 			};
7907 
7908 			vk.cmdCopyImage2(*cmdBuffer, &copyImageInfo2KHR);
7909 		}
7910 #endif // CTS_USES_VULKANSC
7911 	}
7912 	endCommandBuffer(vk, *cmdBuffer);
7913 	submitCommandsAndWait (vk, vkDevice, queue, *cmdBuffer);
7914 	m_context.resetCommandPoolForVKSC(vkDevice, *cmdPool);
7915 
7916 	// Verify that all samples have been copied properly from all aspects.
7917 	const auto usedImageAspects = getUsedImageAspects();
7918 	if (usedImageAspects & VK_IMAGE_ASPECT_DEPTH_BIT)
7919 	{
7920 		auto copyResult = checkCopyResults(cmdBuffer.get(), VK_IMAGE_ASPECT_DEPTH_BIT, srcImage.get(), dstImage.get());
7921 		if (copyResult.getCode() != QP_TEST_RESULT_PASS)
7922 			return copyResult;
7923 	}
7924 	if (usedImageAspects & VK_IMAGE_ASPECT_STENCIL_BIT)
7925 	{
7926 		auto copyResult = checkCopyResults(cmdBuffer.get(), VK_IMAGE_ASPECT_STENCIL_BIT, srcImage.get(), dstImage.get());
7927 		if (copyResult.getCode() != QP_TEST_RESULT_PASS)
7928 			return copyResult;
7929 	}
7930 	return tcu::TestStatus::pass("pass");
7931 }
7932 
checkCopyResults(VkCommandBuffer cmdBuffer,const VkImageAspectFlagBits & aspectToVerify,VkImage srcImage,VkImage dstImage)7933 tcu::TestStatus DepthStencilMSAA::checkCopyResults (VkCommandBuffer cmdBuffer, const VkImageAspectFlagBits& aspectToVerify, VkImage srcImage, VkImage dstImage)
7934 {
7935 	DE_ASSERT((aspectToVerify & VK_IMAGE_ASPECT_DEPTH_BIT) || (aspectToVerify & VK_IMAGE_ASPECT_STENCIL_BIT));
7936 
7937 	const	auto&	vkd						= m_context.getDeviceInterface();
7938 	const	auto	device					= m_context.getDevice();
7939 	const	auto	queue					= m_context.getUniversalQueue();
7940 			auto&	alloc					= m_context.getDefaultAllocator();
7941 	const	auto	layerCount				= getArraySize(m_srcImage);
7942 	const	auto	numInputAttachments		= layerCount + 1u; // +1 for the source image.
7943 	const	auto	numOutputBuffers		= 2u; // 1 for the reference and 1 for the copied values.
7944 	const	auto	numSets					= 2u; // 1 for the output buffers, 1 for the input attachments.
7945 	const	auto	fbWidth					= m_srcImage.extent.width;
7946 	const	auto	fbHeight				= m_srcImage.extent.height;
7947 	const	auto	aspectFlags				= getUsedImageAspects();
7948 
7949 	// Shader modules.
7950 	const	auto	vertexModule			= createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
7951 	const	auto	verificationModule		= createShaderModule(vkd, device, m_context.getBinaryCollection().get(aspectToVerify & VK_IMAGE_ASPECT_DEPTH_BIT ? "verify_depth" : "verify_stencil"), 0u);
7952 
7953 	// Descriptor sets.
7954 	DescriptorPoolBuilder poolBuilder;
7955 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, numOutputBuffers);
7956 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
7957 	const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
7958 
7959 	DescriptorSetLayoutBuilder layoutBuilderBuffer;
7960 	layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
7961 	layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
7962 	const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
7963 
7964 	DescriptorSetLayoutBuilder layoutBuilderAttachments;
7965 	for (deUint32 i = 0u; i < numInputAttachments; ++i)
7966 		layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
7967 	const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
7968 
7969 	const auto descriptorSetBuffer		= makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
7970 	const auto descriptorSetAttachments	= makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
7971 
7972 	// Array with raw descriptor sets.
7973 	const std::array<VkDescriptorSet, numSets> descriptorSets =
7974 	{{
7975 		descriptorSetBuffer.get(),
7976 		descriptorSetAttachments.get(),
7977 	}};
7978 
7979 	// Pipeline layout.
7980 	const std::array<VkDescriptorSetLayout, numSets> setLayouts =
7981 	{{
7982 		outputBufferSetLayout.get(),
7983 		inputAttachmentsSetLayout.get(),
7984 	}};
7985 
7986 	// Push constants.
7987 	std::array<int, 3> pushConstantData =
7988 		{{
7989 			static_cast<int>(fbWidth),
7990 			static_cast<int>(fbHeight),
7991 			static_cast<int>(m_params.samples),
7992 		}};
7993 
7994 	const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
7995 
7996 	const VkPushConstantRange pushConstantRange =
7997 	{
7998 		VK_SHADER_STAGE_FRAGMENT_BIT,	// VkShaderStageFlags	stageFlags;
7999 		0u,								// deUint32				offset;
8000 		pushConstantSize,				// deUint32				size;
8001 	};
8002 
8003 	const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
8004 	{
8005 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType					sType;
8006 		nullptr,										// const void*						pNext;
8007 		0u,												// VkPipelineLayoutCreateFlags		flags;
8008 		static_cast<deUint32>(setLayouts.size()),		// deUint32							setLayoutCount;
8009 		setLayouts.data(),								// const VkDescriptorSetLayout*		pSetLayouts;
8010 		1u,												// deUint32							pushConstantRangeCount;
8011 		&pushConstantRange,								// const VkPushConstantRange*		pPushConstantRanges;
8012 	};
8013 
8014 	const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
8015 
8016 	// Render pass.
8017 	const VkAttachmentDescription commonAttachmentDescription =
8018 	{
8019 		0u,										// VkAttachmentDescriptionFlags		flags;
8020 		m_srcImage.format,						// VkFormat							format;
8021 		m_params.samples,						// VkSampleCountFlagBits			samples;
8022 		VK_ATTACHMENT_LOAD_OP_LOAD,				// VkAttachmentLoadOp				loadOp;
8023 		VK_ATTACHMENT_STORE_OP_STORE,			// VkAttachmentStoreOp				storeOp;
8024 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,		// VkAttachmentLoadOp				stencilLoadOp;
8025 		VK_ATTACHMENT_STORE_OP_DONT_CARE,		// VkAttachmentStoreOp				stencilStoreOp;
8026 		m_dstImage.operationLayout,				// VkImageLayout					initialLayout;
8027 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,	// VkImageLayout					finalLayout;
8028 	};
8029 
8030 	std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
8031 	// Set the first attachment's (m_srcImage) initial layout to match the layout it was left after copying.
8032 	attachmentDescriptions[0].initialLayout = m_srcImage.operationLayout;
8033 
8034 	std::vector<VkAttachmentReference> inputAttachmentReferences;
8035 	inputAttachmentReferences.reserve(numInputAttachments);
8036 	for (deUint32 i = 0u; i < numInputAttachments; ++i)
8037 	{
8038 		const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
8039 		inputAttachmentReferences.push_back(reference);
8040 	}
8041 
8042 	const VkSubpassDescription		subpassDescription	=
8043 	{
8044 		0u,															// VkSubpassDescriptionFlags		flags;
8045 		VK_PIPELINE_BIND_POINT_GRAPHICS,							// VkPipelineBindPoint				pipelineBindPoint;
8046 		static_cast<deUint32>(inputAttachmentReferences.size()),	// deUint32							inputAttachmentCount;
8047 		inputAttachmentReferences.data(),							// const VkAttachmentReference*		pInputAttachments;
8048 		0u,															// deUint32							colorAttachmentCount;
8049 		nullptr,													// const VkAttachmentReference*		pColorAttachments;
8050 		nullptr,													// const VkAttachmentReference*		pResolveAttachments;
8051 		nullptr,													// const VkAttachmentReference*		pDepthStencilAttachment;
8052 		0u,															// deUint32							preserveAttachmentCount;
8053 		nullptr,													// const deUint32*					pPreserveAttachments;
8054 	};
8055 
8056 	const VkRenderPassCreateInfo	renderPassInfo		=
8057 	{
8058 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,				// VkStructureType					sType;
8059 		nullptr,												// const void*						pNext;
8060 		0u,														// VkRenderPassCreateFlags			flags;
8061 		static_cast<deUint32>(attachmentDescriptions.size()),	// deUint32							attachmentCount;
8062 		attachmentDescriptions.data(),							// const VkAttachmentDescription*	pAttachments;
8063 		1u,														// deUint32							subpassCount;
8064 		&subpassDescription,									// const VkSubpassDescription*		pSubpasses;
8065 		0u,														// deUint32							dependencyCount;
8066 		nullptr,												// const VkSubpassDependency*		pDependencies;
8067 	};
8068 
8069 	const auto						renderPass			= createRenderPass(vkd, device, &renderPassInfo);
8070 
8071 	// Framebuffer.
8072 	std::vector<Move<VkImageView>>	imageViews;
8073 	std::vector<VkImageView>		imageViewsRaw;
8074 
8075 	const uint32_t					srcArrayLayer		= m_params.copyOptions == COPY_ARRAY_TO_ARRAY ? 2u : 0u;
8076 	imageViews.push_back(makeImageView(vkd, device, srcImage, VK_IMAGE_VIEW_TYPE_2D, m_srcImage.format, makeImageSubresourceRange(aspectFlags, 0u, 1u, srcArrayLayer, 1u)));
8077 	for (deUint32 i = 0u; i < layerCount; ++i)
8078 	{
8079 		const auto subresourceRange = makeImageSubresourceRange(aspectFlags, 0u, 1u, i, 1u);
8080 		imageViews.push_back(makeImageView(vkd, device, dstImage, VK_IMAGE_VIEW_TYPE_2D, m_srcImage.format, subresourceRange));
8081 	}
8082 
8083 	imageViewsRaw.reserve(imageViews.size());
8084 	std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
8085 
8086 	const auto				framebuffer			= makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
8087 
8088 	// Create storage buffers for both original and copied multisampled depth/stencil images.
8089 	const auto				bufferCount			= static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
8090 	const auto				bufferSize			= static_cast<VkDeviceSize>(bufferCount * sizeof(float));
8091 	BufferWithMemory		bufferOriginal		(vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
8092 	BufferWithMemory		bufferCopied		(vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
8093 	auto&					bufferOriginalAlloc	= bufferOriginal.getAllocation();
8094 	auto&					bufferCopiedAlloc	= bufferCopied.getAllocation();
8095 
8096 	// Update descriptor sets.
8097 	DescriptorSetUpdateBuilder updater;
8098 
8099 	const auto				bufferOriginalInfo	= makeDescriptorBufferInfo(bufferOriginal.get(), 0ull, bufferSize);
8100 	const auto				bufferCopiedInfo	= makeDescriptorBufferInfo(bufferCopied.get(), 0ull, bufferSize);
8101 	updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferOriginalInfo);
8102 	updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferCopiedInfo);
8103 
8104 	std::vector<VkDescriptorImageInfo> imageInfos;
8105 	imageInfos.reserve(imageViewsRaw.size());
8106 	for (size_t i = 0; i < imageViewsRaw.size(); ++i)
8107 	{
8108 		imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
8109 		updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
8110 	}
8111 
8112 	updater.update(vkd, device);
8113 
8114 	// Vertex buffer.
8115 	std::vector<tcu::Vec4> fullScreenQuad;
8116 	{
8117 		// Full screen quad so every framebuffer pixel and sample location is verified by the shader.
8118 		const tcu::Vec4 topLeft		(-1.0f, -1.0f, 0.0f, 1.0f);
8119 		const tcu::Vec4 topRight	( 1.0f, -1.0f, 0.0f, 1.0f);
8120 		const tcu::Vec4 bottomLeft	(-1.0f,  1.0f, 0.0f, 1.0f);
8121 		const tcu::Vec4 bottomRight	( 1.0f,  1.0f, 0.0f, 1.0f);
8122 
8123 		fullScreenQuad.reserve(6u);
8124 		fullScreenQuad.push_back(topLeft);
8125 		fullScreenQuad.push_back(topRight);
8126 		fullScreenQuad.push_back(bottomRight);
8127 		fullScreenQuad.push_back(topLeft);
8128 		fullScreenQuad.push_back(bottomRight);
8129 		fullScreenQuad.push_back(bottomLeft);
8130 	}
8131 
8132 	const auto				vertexBufferSize	= static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
8133 	const auto				vertexBufferInfo	= makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
8134 	const BufferWithMemory	vertexBuffer		(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
8135 	const VkDeviceSize		vertexBufferOffset	= 0ull;
8136 
8137 	deMemcpy(vertexBuffer.getAllocation().getHostPtr(), fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
8138 	flushAlloc(vkd, device, vertexBuffer.getAllocation());
8139 
8140 	// Graphics pipeline.
8141 	const std::vector<VkViewport>	viewports	(1, makeViewport(m_srcImage.extent));
8142 	const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_srcImage.extent));
8143 
8144 	const VkPipelineMultisampleStateCreateInfo	multisampleStateParams		=
8145 	{
8146 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
8147 		nullptr,													// const void*								pNext;
8148 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
8149 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
8150 		VK_FALSE,													// VkBool32									sampleShadingEnable;
8151 		0.0f,														// float									minSampleShading;
8152 		nullptr,													// const VkSampleMask*						pSampleMask;
8153 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
8154 		VK_FALSE													// VkBool32									alphaToOneEnable;
8155 	};
8156 
8157 	const auto graphicsPipeline = makeGraphicsPipeline(
8158 		vkd,									// const DeviceInterface&							vk
8159 		device,									// const VkDevice									device
8160 		pipelineLayout.get(),					// const VkPipelineLayout							pipelineLayout
8161 		vertexModule.get(),						// const VkShaderModule								vertexShaderModule
8162 		DE_NULL,								// const VkShaderModule								tessellationControlModule
8163 		DE_NULL,								// const VkShaderModule								tessellationEvalModule
8164 		DE_NULL,								// const VkShaderModule								geometryShaderModule
8165 		verificationModule.get(),				// const VkShaderModule								fragmentShaderModule
8166 		renderPass.get(),						// const VkRenderPass								renderPass
8167 		viewports,								// const std::vector<VkViewport>&					viewports
8168 		scissors,								// const std::vector<VkRect2D>&						scissors
8169 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology						topology
8170 		0u,										// const deUint32									subpass
8171 		0u,										// const deUint32									patchControlPoints
8172 		nullptr,								// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
8173 		nullptr,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
8174 		&multisampleStateParams);				// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
8175 
8176 	// Make sure multisample copy data is available to the fragment shader.
8177 	const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
8178 
8179 	// Record and submit command buffer.
8180 	beginCommandBuffer(vkd, cmdBuffer);
8181 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
8182 	beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_srcImage.extent));
8183 	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
8184 	vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
8185 
8186 	vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
8187 	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
8188 	vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
8189 
8190 	endRenderPass(vkd, cmdBuffer);
8191 
8192 	// Make sure verification buffer data is available on the host.
8193 	const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
8194 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
8195 	endCommandBuffer(vkd, cmdBuffer);
8196 	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
8197 
8198 	// Verify intermediate results.
8199 	invalidateAlloc(vkd, device, bufferOriginalAlloc);
8200 	invalidateAlloc(vkd, device, bufferCopiedAlloc);
8201 	std::vector<float> outputOriginal (bufferCount, 0);
8202 	std::vector<float> outputCopied (bufferCount, 0);
8203 	deMemcpy(outputOriginal.data(), bufferOriginalAlloc.getHostPtr(), static_cast<size_t>(bufferSize));
8204 	deMemcpy(outputCopied.data(), bufferCopiedAlloc.getHostPtr(), static_cast<size_t>(bufferSize));
8205 
8206 	auto& log = m_context.getTestContext().getLog();
8207 	log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
8208 
8209 	const auto sampleCount = static_cast<deUint32>(m_params.samples);
8210 
8211 	// Verify copied region(s)
8212 	for (const auto &region : m_regions)
8213 	{
8214 		for (uint32_t x = 0u; x < region.imageCopy.extent.width; ++x)
8215 		for (uint32_t y = 0u; y < region.imageCopy.extent.height; ++y)
8216 		for (uint32_t s = 0u; s < sampleCount; ++s)
8217 		{
8218 			tcu::UVec2 srcCoord(x + region.imageCopy.srcOffset.x, y + region.imageCopy.srcOffset.y);
8219 			tcu::UVec2 dstCoord(x + region.imageCopy.dstOffset.x, y + region.imageCopy.dstOffset.y);
8220 			const auto srcIndex = (srcCoord.y() * fbWidth + srcCoord.x()) * sampleCount + s;
8221 			const auto dstIndex = (dstCoord.y() * fbWidth + dstCoord.x()) * sampleCount + s;
8222 			if (outputOriginal[srcIndex] != outputCopied[dstIndex])
8223 			{
8224 				std::ostringstream msg;
8225 				msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s << ". "
8226 					<< "result: " << outputCopied[dstIndex] << " expected: " << outputOriginal[srcIndex];
8227 				return tcu::TestStatus::fail(msg.str());
8228 			}
8229 		}
8230 	}
8231 
8232 	if (m_params.copyOptions == COPY_PARTIAL)
8233 	{
8234 		// In the partial copy tests the destination image contains copied data only in the bottom half of the image.
8235 		// Verify that the upper half of the image is left at it's clear value (0).
8236 		for (uint32_t x = 0u; x < m_srcImage.extent.width; x++)
8237 		for (uint32_t y = 0u; y < m_srcImage.extent.height / 2; y++)
8238 		for (uint32_t s = 0u; s < sampleCount; ++s)
8239 		{
8240 			const auto bufferIndex = (y * fbWidth + x) * sampleCount + s;
8241 			if (outputCopied[bufferIndex] != m_clearValue)
8242 			{
8243 				std::ostringstream msg;
8244 				msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s << ". "
8245 					<< "result: " << outputCopied[bufferIndex] << " expected: 0.0" ;
8246 				return tcu::TestStatus::fail(msg.str());
8247 			}
8248 		}
8249 	}
8250 
8251 	log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
8252 	return tcu::TestStatus::pass("Pass");
8253 }
8254 
8255 class DepthStencilMSAATestCase : public vkt::TestCase
8256 {
8257 public:
DepthStencilMSAATestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const DepthStencilMSAA::TestParameters testParams)8258 							DepthStencilMSAATestCase	(tcu::TestContext&						testCtx,
8259 														 const std::string&						name,
8260 														 const std::string&						description,
8261 														 const DepthStencilMSAA::TestParameters	testParams)
8262 								: vkt::TestCase	(testCtx, name, description)
8263 								, m_params		(testParams)
8264 	{}
8265 
8266 	virtual	void			initPrograms				(SourceCollections&		programCollection) const;
8267 
createInstance(Context & context) const8268 	virtual TestInstance*	createInstance				(Context&				context) const
8269 	{
8270 		return new DepthStencilMSAA(context, m_params);
8271 	}
8272 
checkSupport(Context & context) const8273 	virtual void			checkSupport				(Context&				context) const
8274 	{
8275 		const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
8276 
8277 		if (!context.getDeviceFeatures().fragmentStoresAndAtomics)
8278 			TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
8279 
8280 		if ((m_params.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT) && !(context.getDeviceProperties().limits.framebufferDepthSampleCounts & rasterizationSamples))
8281 			TCU_THROW(NotSupportedError, "Unsupported number of depth samples");
8282 
8283 		if ((m_params.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT) && !(context.getDeviceProperties().limits.framebufferDepthSampleCounts & rasterizationSamples))
8284 			TCU_THROW(NotSupportedError, "Unsupported number of stencil samples");
8285 
8286 		VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
8287 										| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
8288 										| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
8289 										| VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
8290 
8291 		VkImageFormatProperties properties;
8292 		if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
8293 																					m_params.imageFormat,
8294 																					VK_IMAGE_TYPE_2D,
8295 																					VK_IMAGE_TILING_OPTIMAL,
8296 																					usageFlags, 0,
8297 																					&properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
8298 		{
8299 			TCU_THROW(NotSupportedError, "Format not supported");
8300 		}
8301 
8302 		if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)	&&
8303 			(!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
8304 		{
8305 			TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
8306 		}
8307 	}
8308 
8309 private:
8310 
getArrayLayerCount() const8311 	uint32_t				getArrayLayerCount			() const
8312 	{
8313 		return (m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY) ? 5u : 1u;
8314 	}
8315 
createVerificationShader(std::ostringstream & shaderCode,const VkImageAspectFlagBits attachmentAspect) const8316 	void createVerificationShader						(std::ostringstream& shaderCode, const VkImageAspectFlagBits attachmentAspect) const
8317 	{
8318 		DE_ASSERT(attachmentAspect & (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT));
8319 		// The shader copies the sample values from the source and destination image to output buffers OriginalValue and
8320 		// CopiedValues, respectively. If the dst image contains multiple array layers, only one layer has the copied data
8321 		// and the rest should be filled with the clear value (0). This is also verified in this shader.
8322 		// Array layer cases need an image view per layer in the copied image.
8323 		// Set 0 contains the output buffers.
8324 		// Set 1 contains the input attachments.
8325 
8326 		std::string inputAttachmentPrefix = attachmentAspect == VK_IMAGE_ASPECT_STENCIL_BIT ? "u" : "";
8327 
8328 		shaderCode
8329 			<< "#version 450\n"
8330 			<< "\n"
8331 			<< "layout (push_constant, std430) uniform PushConstants {\n"
8332 			<< "    int width;\n"
8333 			<< "    int height;\n"
8334 			<< "    int samples;\n"
8335 			<< "};\n"
8336 			<< "layout (set=0, binding=0) buffer OriginalValues {\n"
8337 			<< "    float outputOriginal[];\n"
8338 			<< "};\n"
8339 			<< "layout (set=0, binding=1) buffer CopiedValues {\n"
8340 			<< "    float outputCopied[];\n"
8341 			<< "};\n"
8342 			<< "layout (input_attachment_index=0, set=1, binding=0) uniform " << inputAttachmentPrefix << "subpassInputMS attachment0;\n"
8343 			;
8344 
8345 		const auto layerCount = getArrayLayerCount();
8346 		for (deUint32 layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8347 		{
8348 			const auto i = layerNdx + 1u;
8349 			shaderCode << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform " << inputAttachmentPrefix << "subpassInputMS attachment" << i << ";\n";
8350 		}
8351 
8352 		// Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
8353 		// created with a single sample.
8354 		shaderCode
8355 			<< "\n"
8356 			<< "void main() {\n"
8357 			<< "    for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
8358 			<< "        ivec3 coords  = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
8359 			<< "        int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
8360 			<< "        " << inputAttachmentPrefix << "vec4 orig = subpassLoad(attachment0, sampleID);\n"
8361 			<< "        outputOriginal[bufferPos] = orig.r;\n"
8362 			;
8363 
8364 		for (deUint32 layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8365 		{
8366 			const auto i = layerNdx + 1u;
8367 			shaderCode << "        " << inputAttachmentPrefix << "vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
8368 		}
8369 
8370 		std::ostringstream testCondition;
8371 		std::string layerToVerify = m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY ? "copy4" : "copy1";
8372 		shaderCode
8373 			<< "\n"
8374 			<< "        outputCopied[bufferPos] = " << layerToVerify << ".r; \n";
8375 
8376 		if (m_params.copyOptions == DepthStencilMSAA::COPY_ARRAY_TO_ARRAY)
8377 		{
8378 			// 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.
8379 			// This verifies that all the samples in the other layers have proper values.
8380 			shaderCode << "        bool equalEmptyLayers = ";
8381 			for (deUint32 layerNdx = 0u; layerNdx < layerCount; ++layerNdx)
8382 			{
8383 				if (layerNdx == 3)
8384 					continue;
8385 				const auto i = layerNdx + 1u;
8386 				shaderCode << "copy" << i << ".r == " << (attachmentAspect == VK_IMAGE_ASPECT_STENCIL_BIT ? "0" : "0.0") << (layerNdx < 4u ? " && " : ";\n");
8387 			}
8388 			shaderCode
8389 				<< "        if (!equalEmptyLayers)\n"
8390 				<< "            outputCopied[bufferPos]--; \n";
8391 		}
8392 
8393 		shaderCode
8394 			<< "    }\n"
8395 			<< "}\n";
8396 	}
8397 
8398 	DepthStencilMSAA::TestParameters	m_params;
8399 };
8400 
initPrograms(SourceCollections & programCollection) const8401 void DepthStencilMSAATestCase::initPrograms (SourceCollections& programCollection) const
8402 {
8403 	programCollection.glslSources.add("vert") << glu::VertexSource(
8404 		"#version 310 es\n"
8405 		"layout (location = 0) in highp vec4 a_position;\n"
8406 		"void main()\n"
8407 		"{\n"
8408 		"    gl_Position = vec4(a_position.xy, 1.0, 1.0);\n"
8409 		"}\n");
8410 
8411 	programCollection.glslSources.add("frag") << glu::FragmentSource(
8412 		"#version 310 es\n"
8413 		"void main()\n"
8414 		"{}\n");
8415 
8416 	// Create the verifying shader for the depth aspect if the depth is used.
8417 	if (m_params.copyAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
8418 	{
8419 		std::ostringstream verificationShader;
8420 		// All the depth formats are float types, so the input attachment prefix is not used.
8421 		createVerificationShader(verificationShader, VK_IMAGE_ASPECT_DEPTH_BIT);
8422 		programCollection.glslSources.add("verify_depth") << glu::FragmentSource(verificationShader.str());
8423 	}
8424 
8425 	// Create the verifying shader for the stencil aspect if the stencil is used.
8426 	if (m_params.copyAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
8427 	{
8428 		std::ostringstream verificationShader;
8429 		// All the stencil formats are uint types, so the input attachment prefix is "u".
8430 		createVerificationShader(verificationShader, VK_IMAGE_ASPECT_STENCIL_BIT);
8431 		programCollection.glslSources.add("verify_stencil") << glu::FragmentSource(verificationShader.str());
8432 	}
8433 }
8434 
8435 struct BufferOffsetParams
8436 {
8437 	static constexpr deUint32 kMaxOffset = 8u;
8438 
8439 	deUint32 srcOffset;
8440 	deUint32 dstOffset;
8441 };
8442 
checkZerosAt(const std::vector<deUint8> & bufferData,deUint32 from,deUint32 count)8443 void checkZerosAt(const std::vector<deUint8>& bufferData, deUint32 from, deUint32 count)
8444 {
8445 	constexpr deUint8 zero{0};
8446 	for (deUint32 i = 0; i < count; ++i)
8447 	{
8448 		const auto& val = bufferData[from + i];
8449 		if (val != zero)
8450 		{
8451 			std::ostringstream msg;
8452 			msg << "Unexpected non-zero byte found at position " << (from + i) << ": " << static_cast<int>(val);
8453 			TCU_FAIL(msg.str());
8454 		}
8455 	}
8456 }
8457 
bufferOffsetTest(Context & ctx,BufferOffsetParams params)8458 tcu::TestStatus bufferOffsetTest (Context& ctx, BufferOffsetParams params)
8459 {
8460 	// 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.
8461 	constexpr auto kMaxOffset	= BufferOffsetParams::kMaxOffset;
8462 	constexpr auto kBlockSize	= kMaxOffset * 2u;
8463 	constexpr auto kBufferSize	= kMaxOffset * kBlockSize;
8464 
8465 	DE_ASSERT(params.srcOffset < kMaxOffset);
8466 	DE_ASSERT(params.dstOffset < kMaxOffset);
8467 
8468 	const auto&	vkd		= ctx.getDeviceInterface();
8469 	const auto	device	= ctx.getDevice();
8470 	auto&		alloc	= ctx.getDefaultAllocator();
8471 	const auto	qIndex	= ctx.getUniversalQueueFamilyIndex();
8472 	const auto	queue	= ctx.getUniversalQueue();
8473 
8474 	const auto srcBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
8475 	const auto dstBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
8476 
8477 	BufferWithMemory	srcBuffer	(vkd, device, alloc, srcBufferInfo, MemoryRequirement::HostVisible);
8478 	BufferWithMemory	dstBuffer	(vkd, device, alloc, dstBufferInfo, MemoryRequirement::HostVisible);
8479 	auto&				srcAlloc	= srcBuffer.getAllocation();
8480 	auto&				dstAlloc	= dstBuffer.getAllocation();
8481 
8482 	// Zero-out destination buffer.
8483 	deMemset(dstAlloc.getHostPtr(), 0, kBufferSize);
8484 	flushAlloc(vkd, device, dstAlloc);
8485 
8486 	// Fill source buffer with nonzero bytes.
8487 	std::vector<deUint8> srcData;
8488 	srcData.reserve(kBufferSize);
8489 	for (deUint32 i = 0; i < kBufferSize; ++i)
8490 		srcData.push_back(static_cast<deUint8>(100u + i));
8491 	deMemcpy(srcAlloc.getHostPtr(), srcData.data(), de::dataSize(srcData));
8492 	flushAlloc(vkd, device, srcAlloc);
8493 
8494 	// Copy regions.
8495 	std::vector<VkBufferCopy> copies;
8496 	copies.reserve(kMaxOffset);
8497 	for (deUint32 i = 0; i < kMaxOffset; ++i)
8498 	{
8499 		const auto blockStart	= kBlockSize * i;
8500 		const auto copySize		= i + 1u;
8501 		const auto bufferCopy	= makeBufferCopy(params.srcOffset + blockStart, params.dstOffset + blockStart, copySize);
8502 		copies.push_back(bufferCopy);
8503 	}
8504 
8505 	const auto cmdPool		= makeCommandPool(vkd, device, qIndex);
8506 	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
8507 	const auto cmdBuffer	= cmdBufferPtr.get();
8508 
8509 	beginCommandBuffer(vkd, cmdBuffer);
8510 	vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), static_cast<deUint32>(copies.size()), copies.data());
8511 	const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
8512 	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
8513 	endCommandBuffer(vkd, cmdBuffer);
8514 	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
8515 	invalidateAlloc(vkd, device, dstAlloc);
8516 
8517 	// Verify destination buffer data.
8518 	std::vector<deUint8> dstData(kBufferSize);
8519 	deMemcpy(dstData.data(), dstAlloc.getHostPtr(), de::dataSize(dstData));
8520 
8521 	for (deUint32 blockIdx = 0; blockIdx < kMaxOffset; ++blockIdx)
8522 	{
8523 		const auto blockStart	= kBlockSize * blockIdx;
8524 		const auto copySize		= blockIdx + 1u;
8525 
8526 		// Verify no data has been written before dstOffset.
8527 		checkZerosAt(dstData, blockStart, params.dstOffset);
8528 
8529 		// Verify copied block.
8530 		for (deUint32 i = 0; i < copySize; ++i)
8531 		{
8532 			const auto& dstVal = dstData[blockStart + params.dstOffset + i];
8533 			const auto& srcVal = srcData[blockStart + params.srcOffset + i];
8534 			if (dstVal != srcVal)
8535 			{
8536 				std::ostringstream msg;
8537 				msg << "Unexpected value found at position " << (blockStart + params.dstOffset + i) << ": expected " << static_cast<int>(srcVal) << " but found " << static_cast<int>(dstVal);
8538 				TCU_FAIL(msg.str());
8539 			}
8540 		}
8541 
8542 		// Verify no data has been written after copy block.
8543 		checkZerosAt(dstData, blockStart + params.dstOffset + copySize, kBlockSize - (params.dstOffset + copySize));
8544 	}
8545 
8546 	return tcu::TestStatus::pass("Pass");
8547 }
8548 
getSampleCountCaseName(VkSampleCountFlagBits sampleFlag)8549 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
8550 {
8551 	return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
8552 }
8553 
getFormatCaseName(VkFormat format)8554 std::string getFormatCaseName (VkFormat format)
8555 {
8556 	return de::toLower(de::toString(getFormatStr(format)).substr(10));
8557 }
8558 
getImageLayoutCaseName(VkImageLayout layout)8559 std::string getImageLayoutCaseName (VkImageLayout layout)
8560 {
8561 	switch (layout)
8562 	{
8563 		case VK_IMAGE_LAYOUT_GENERAL:
8564 			return "general";
8565 		case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
8566 		case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
8567 			return "optimal";
8568 		default:
8569 			DE_ASSERT(false);
8570 			return "";
8571 	}
8572 }
8573 
addImageToImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)8574 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8575 {
8576 	tcu::TestContext& testCtx	= group->getTestContext();
8577 
8578 	{
8579 		TestParams	params;
8580 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8581 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
8582 		params.src.image.extent				= defaultExtent;
8583 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8584 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8585 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8586 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
8587 		params.dst.image.extent				= defaultExtent;
8588 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8589 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8590 		params.allocationKind				= allocationKind;
8591 		params.extensionUse					= extensionUse;
8592 
8593 		{
8594 			const VkImageCopy				testCopy	=
8595 			{
8596 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
8597 				{0, 0, 0},			// VkOffset3D				srcOffset;
8598 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
8599 				{0, 0, 0},			// VkOffset3D				dstOffset;
8600 				defaultExtent,		// VkExtent3D				extent;
8601 			};
8602 
8603 			CopyRegion	imageCopy;
8604 			imageCopy.imageCopy	= testCopy;
8605 			params.regions.push_back(imageCopy);
8606 		}
8607 
8608 		group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
8609 	}
8610 
8611 	{
8612 		TestParams	params;
8613 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8614 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
8615 		params.src.image.extent				= defaultExtent;
8616 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8617 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8618 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8619 		params.dst.image.format				= VK_FORMAT_R32_UINT;
8620 		params.dst.image.extent				= defaultExtent;
8621 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8622 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8623 		params.allocationKind				= allocationKind;
8624 		params.extensionUse					= extensionUse;
8625 
8626 		{
8627 			const VkImageCopy				testCopy	=
8628 			{
8629 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
8630 				{0, 0, 0},			// VkOffset3D				srcOffset;
8631 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
8632 				{0, 0, 0},			// VkOffset3D				dstOffset;
8633 				defaultExtent,		// VkExtent3D				extent;
8634 			};
8635 
8636 			CopyRegion	imageCopy;
8637 			imageCopy.imageCopy = testCopy;
8638 			params.regions.push_back(imageCopy);
8639 		}
8640 
8641 		group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
8642 	}
8643 
8644 	{
8645 		TestParams	params;
8646 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8647 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
8648 		params.src.image.extent				= defaultExtent;
8649 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8650 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8651 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8652 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
8653 		params.dst.image.extent				= defaultExtent;
8654 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8655 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8656 		params.allocationKind				= allocationKind;
8657 		params.extensionUse					= extensionUse;
8658 
8659 		{
8660 			const VkImageCopy				testCopy	=
8661 			{
8662 				defaultSourceLayer,									// VkImageSubresourceLayers	srcSubresource;
8663 				{0, 0, 0},											// VkOffset3D				srcOffset;
8664 				defaultSourceLayer,									// VkImageSubresourceLayers	dstSubresource;
8665 				{defaultQuarterSize, defaultQuarterSize / 2, 0},		// VkOffset3D				dstOffset;
8666 				{defaultQuarterSize / 2, defaultQuarterSize / 2, 1},	// VkExtent3D				extent;
8667 			};
8668 
8669 			CopyRegion	imageCopy;
8670 			imageCopy.imageCopy = testCopy;
8671 			params.regions.push_back(imageCopy);
8672 		}
8673 
8674 		group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
8675 	}
8676 
8677 	static const struct
8678 	{
8679 		std::string		name;
8680 		vk::VkFormat	format1;
8681 		vk::VkFormat	format2;
8682 	} formats [] =
8683 	{
8684 		{ "diff_format",	vk::VK_FORMAT_R32_UINT,			vk::VK_FORMAT_R8G8B8A8_UNORM	},
8685 		{ "same_format",	vk::VK_FORMAT_R8G8B8A8_UNORM,	vk::VK_FORMAT_R8G8B8A8_UNORM	}
8686 	};
8687 	static const struct
8688 	{
8689 		std::string		name;
8690 		vk::VkBool32	clear;
8691 	} clears [] =
8692 	{
8693 		{ "clear",		VK_TRUE		},
8694 		{ "noclear",	VK_FALSE	}
8695 	};
8696 	static const struct
8697 	{
8698 		std::string		name;
8699 		VkExtent3D		extent;
8700 	} extents [] =
8701 	{
8702 		{ "npot",	{65u, 63u, 1u}	},
8703 		{ "pot",	{64u, 64u, 1u}	}
8704 	};
8705 
8706 	for (const auto& format : formats)
8707 	{
8708 		for (const auto& clear : clears)
8709 		{
8710 			for (const auto& extent : extents)
8711 			{
8712 				TestParams	params;
8713 				params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8714 				params.src.image.format				= format.format1;
8715 				params.src.image.extent				= extent.extent;
8716 				params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8717 				params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8718 				params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8719 				params.dst.image.format				= format.format2;
8720 				params.dst.image.extent				= extent.extent;
8721 				params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8722 				params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8723 				params.allocationKind				= allocationKind;
8724 				params.extensionUse					= extensionUse;
8725 				params.clearDestination				= clear.clear;
8726 
8727 				{
8728 					VkImageCopy	testCopy	=
8729 					{
8730 						defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
8731 						{34, 34, 0},		// VkOffset3D				srcOffset;
8732 						defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
8733 						{0, 0, 0},			// VkOffset3D				dstOffset;
8734 						{31, 29, 1}			// VkExtent3D				extent;
8735 					};
8736 
8737 					if (extent.name == "pot")
8738 					{
8739 						testCopy.srcOffset	= { 16, 16, 0 };
8740 						testCopy.extent		= { 32, 32, 1 };
8741 					}
8742 
8743 					CopyRegion	imageCopy;
8744 					imageCopy.imageCopy = testCopy;
8745 					params.regions.push_back(imageCopy);
8746 				}
8747 
8748 				// Example test case name: "partial_image_npot_diff_format_clear"
8749 				const std::string testCaseName = "partial_image_" + extent.name + "_" + format.name + "_" + clear.name;
8750 
8751 				group->addChild(new CopyImageToImageTestCase(testCtx, testCaseName, "", params));
8752 			}
8753 		}
8754 	}
8755 
8756 	{
8757 		TestParams	params;
8758 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8759 		params.src.image.format				= VK_FORMAT_D32_SFLOAT;
8760 		params.src.image.extent				= defaultExtent;
8761 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8762 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8763 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8764 		params.dst.image.format				= VK_FORMAT_D32_SFLOAT;
8765 		params.dst.image.extent				= defaultExtent;
8766 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8767 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8768 		params.allocationKind				= allocationKind;
8769 		params.extensionUse					= extensionUse;
8770 
8771 		{
8772 			const VkImageSubresourceLayers  sourceLayer =
8773 			{
8774 				VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
8775 				0u,							// deUint32				mipLevel;
8776 				0u,							// deUint32				baseArrayLayer;
8777 				1u							// deUint32				layerCount;
8778 			};
8779 			const VkImageCopy				testCopy	=
8780 			{
8781 				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
8782 				{0, 0, 0},											// VkOffset3D				srcOffset;
8783 				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
8784 				{defaultQuarterSize, defaultQuarterSize / 2, 0},		// VkOffset3D				dstOffset;
8785 				{defaultQuarterSize / 2, defaultQuarterSize / 2, 1},	// VkExtent3D				extent;
8786 			};
8787 
8788 			CopyRegion	imageCopy;
8789 			imageCopy.imageCopy = testCopy;
8790 			params.regions.push_back(imageCopy);
8791 		}
8792 
8793 		group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
8794 	}
8795 
8796 	{
8797 		TestParams	params;
8798 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
8799 		params.src.image.format				= VK_FORMAT_S8_UINT;
8800 		params.src.image.extent				= defaultExtent;
8801 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8802 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8803 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
8804 		params.dst.image.format				= VK_FORMAT_S8_UINT;
8805 		params.dst.image.extent				= defaultExtent;
8806 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
8807 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8808 		params.allocationKind				= allocationKind;
8809 		params.extensionUse					= extensionUse;
8810 
8811 		{
8812 			const VkImageSubresourceLayers  sourceLayer =
8813 			{
8814 				VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
8815 				0u,								// deUint32				mipLevel;
8816 				0u,								// deUint32				baseArrayLayer;
8817 				1u								// deUint32				layerCount;
8818 			};
8819 			const VkImageCopy				testCopy	=
8820 			{
8821 				sourceLayer,										// VkImageSubresourceLayers	srcSubresource;
8822 				{0, 0, 0},											// VkOffset3D				srcOffset;
8823 				sourceLayer,										// VkImageSubresourceLayers	dstSubresource;
8824 				{defaultQuarterSize, defaultQuarterSize / 2, 0},		// VkOffset3D				dstOffset;
8825 				{defaultQuarterSize / 2, defaultQuarterSize / 2, 1},	// VkExtent3D				extent;
8826 			};
8827 
8828 			CopyRegion	imageCopy;
8829 			imageCopy.imageCopy = testCopy;
8830 			params.regions.push_back(imageCopy);
8831 		}
8832 
8833 		group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
8834 	}
8835 }
8836 
8837 struct CopyColorTestParams
8838 {
8839 	TestParams		params;
8840 	const VkFormat*	compatibleFormats;
8841 };
8842 
addImageToImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,TestParams params)8843 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
8844 {
8845 	const VkImageLayout copySrcLayouts[]		=
8846 	{
8847 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
8848 		VK_IMAGE_LAYOUT_GENERAL
8849 	};
8850 	const VkImageLayout copyDstLayouts[]		=
8851 	{
8852 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
8853 		VK_IMAGE_LAYOUT_GENERAL
8854 	};
8855 
8856 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
8857 	{
8858 		params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
8859 
8860 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
8861 		{
8862 			params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
8863 
8864 			const std::string testName	= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
8865 										  getImageLayoutCaseName(params.dst.image.operationLayout);
8866 			const std::string description	= "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
8867 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
8868 			group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
8869 		}
8870 	}
8871 }
8872 
isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams & testParams)8873 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams& testParams)
8874 {
8875 	bool result = true;
8876 
8877 	if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
8878 	{
8879 		DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
8880 
8881 		result =
8882 			de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
8883 			de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
8884 	}
8885 
8886 	return result;
8887 }
8888 
addImageToImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,CopyColorTestParams testParams)8889 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
8890 {
8891 	// If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
8892 	const VkFormat	srcFormatOnly[2]	= { testParams.params.src.image.format, VK_FORMAT_UNDEFINED };
8893 	const VkFormat*	formatList			= (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);
8894 
8895 	for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
8896 	{
8897 		testParams.params.dst.image.format = formatList[dstFormatIndex];
8898 
8899 		const VkFormat		srcFormat	= testParams.params.src.image.format;
8900 		const VkFormat		dstFormat	= testParams.params.dst.image.format;
8901 
8902 		if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
8903 			continue;
8904 
8905 		if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
8906 			continue;
8907 
8908 		if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
8909 			if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) || (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
8910 				continue;
8911 
8912 		const std::string	description	= "Copy to destination format " + getFormatCaseName(dstFormat);
8913 		addTestGroup(group, getFormatCaseName(dstFormat), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
8914 	}
8915 }
8916 
8917 const VkFormat	compatibleFormats8Bit[]		=
8918 {
8919 	VK_FORMAT_R4G4_UNORM_PACK8,
8920 	VK_FORMAT_R8_UNORM,
8921 	VK_FORMAT_R8_SNORM,
8922 	VK_FORMAT_R8_USCALED,
8923 	VK_FORMAT_R8_SSCALED,
8924 	VK_FORMAT_R8_UINT,
8925 	VK_FORMAT_R8_SINT,
8926 	VK_FORMAT_R8_SRGB,
8927 
8928 	VK_FORMAT_UNDEFINED
8929 };
8930 const VkFormat	compatibleFormats16Bit[]	=
8931 {
8932 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
8933 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
8934 	VK_FORMAT_R5G6B5_UNORM_PACK16,
8935 	VK_FORMAT_B5G6R5_UNORM_PACK16,
8936 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
8937 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
8938 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
8939 	VK_FORMAT_R8G8_UNORM,
8940 	VK_FORMAT_R8G8_SNORM,
8941 	VK_FORMAT_R8G8_USCALED,
8942 	VK_FORMAT_R8G8_SSCALED,
8943 	VK_FORMAT_R8G8_UINT,
8944 	VK_FORMAT_R8G8_SINT,
8945 	VK_FORMAT_R8G8_SRGB,
8946 	VK_FORMAT_R16_UNORM,
8947 	VK_FORMAT_R16_SNORM,
8948 	VK_FORMAT_R16_USCALED,
8949 	VK_FORMAT_R16_SSCALED,
8950 	VK_FORMAT_R16_UINT,
8951 	VK_FORMAT_R16_SINT,
8952 	VK_FORMAT_R16_SFLOAT,
8953 	VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
8954 	VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
8955 
8956 	VK_FORMAT_UNDEFINED
8957 };
8958 const VkFormat	compatibleFormats24Bit[]	=
8959 {
8960 	VK_FORMAT_R8G8B8_UNORM,
8961 	VK_FORMAT_R8G8B8_SNORM,
8962 	VK_FORMAT_R8G8B8_USCALED,
8963 	VK_FORMAT_R8G8B8_SSCALED,
8964 	VK_FORMAT_R8G8B8_UINT,
8965 	VK_FORMAT_R8G8B8_SINT,
8966 	VK_FORMAT_R8G8B8_SRGB,
8967 	VK_FORMAT_B8G8R8_UNORM,
8968 	VK_FORMAT_B8G8R8_SNORM,
8969 	VK_FORMAT_B8G8R8_USCALED,
8970 	VK_FORMAT_B8G8R8_SSCALED,
8971 	VK_FORMAT_B8G8R8_UINT,
8972 	VK_FORMAT_B8G8R8_SINT,
8973 	VK_FORMAT_B8G8R8_SRGB,
8974 
8975 	VK_FORMAT_UNDEFINED
8976 };
8977 const VkFormat	compatibleFormats32Bit[]	=
8978 {
8979 	VK_FORMAT_R8G8B8A8_UNORM,
8980 	VK_FORMAT_R8G8B8A8_SNORM,
8981 	VK_FORMAT_R8G8B8A8_USCALED,
8982 	VK_FORMAT_R8G8B8A8_SSCALED,
8983 	VK_FORMAT_R8G8B8A8_UINT,
8984 	VK_FORMAT_R8G8B8A8_SINT,
8985 	VK_FORMAT_R8G8B8A8_SRGB,
8986 	VK_FORMAT_B8G8R8A8_UNORM,
8987 	VK_FORMAT_B8G8R8A8_SNORM,
8988 	VK_FORMAT_B8G8R8A8_USCALED,
8989 	VK_FORMAT_B8G8R8A8_SSCALED,
8990 	VK_FORMAT_B8G8R8A8_UINT,
8991 	VK_FORMAT_B8G8R8A8_SINT,
8992 	VK_FORMAT_B8G8R8A8_SRGB,
8993 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
8994 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
8995 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
8996 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
8997 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
8998 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
8999 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
9000 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
9001 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
9002 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
9003 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
9004 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
9005 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
9006 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
9007 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
9008 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
9009 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
9010 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
9011 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
9012 	VK_FORMAT_R16G16_UNORM,
9013 	VK_FORMAT_R16G16_SNORM,
9014 	VK_FORMAT_R16G16_USCALED,
9015 	VK_FORMAT_R16G16_SSCALED,
9016 	VK_FORMAT_R16G16_UINT,
9017 	VK_FORMAT_R16G16_SINT,
9018 	VK_FORMAT_R16G16_SFLOAT,
9019 	VK_FORMAT_R32_UINT,
9020 	VK_FORMAT_R32_SINT,
9021 	VK_FORMAT_R32_SFLOAT,
9022 
9023 	VK_FORMAT_UNDEFINED
9024 };
9025 const VkFormat	compatibleFormats48Bit[]	=
9026 {
9027 	VK_FORMAT_R16G16B16_UNORM,
9028 	VK_FORMAT_R16G16B16_SNORM,
9029 	VK_FORMAT_R16G16B16_USCALED,
9030 	VK_FORMAT_R16G16B16_SSCALED,
9031 	VK_FORMAT_R16G16B16_UINT,
9032 	VK_FORMAT_R16G16B16_SINT,
9033 	VK_FORMAT_R16G16B16_SFLOAT,
9034 
9035 	VK_FORMAT_UNDEFINED
9036 };
9037 const VkFormat	compatibleFormats64Bit[]	=
9038 {
9039 	VK_FORMAT_R16G16B16A16_UNORM,
9040 	VK_FORMAT_R16G16B16A16_SNORM,
9041 	VK_FORMAT_R16G16B16A16_USCALED,
9042 	VK_FORMAT_R16G16B16A16_SSCALED,
9043 	VK_FORMAT_R16G16B16A16_UINT,
9044 	VK_FORMAT_R16G16B16A16_SINT,
9045 	VK_FORMAT_R16G16B16A16_SFLOAT,
9046 	VK_FORMAT_R32G32_UINT,
9047 	VK_FORMAT_R32G32_SINT,
9048 	VK_FORMAT_R32G32_SFLOAT,
9049 	VK_FORMAT_R64_UINT,
9050 	VK_FORMAT_R64_SINT,
9051 	VK_FORMAT_R64_SFLOAT,
9052 
9053 	VK_FORMAT_BC1_RGB_UNORM_BLOCK,
9054 	VK_FORMAT_BC1_RGB_SRGB_BLOCK,
9055 	VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
9056 	VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
9057 	VK_FORMAT_BC4_UNORM_BLOCK,
9058 	VK_FORMAT_BC4_SNORM_BLOCK,
9059 
9060 	VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
9061 	VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
9062 	VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
9063 	VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
9064 
9065 	VK_FORMAT_EAC_R11_UNORM_BLOCK,
9066 	VK_FORMAT_EAC_R11_SNORM_BLOCK,
9067 
9068 	VK_FORMAT_UNDEFINED
9069 };
9070 const VkFormat	compatibleFormats96Bit[]	=
9071 {
9072 	VK_FORMAT_R32G32B32_UINT,
9073 	VK_FORMAT_R32G32B32_SINT,
9074 	VK_FORMAT_R32G32B32_SFLOAT,
9075 
9076 	VK_FORMAT_UNDEFINED
9077 };
9078 const VkFormat	compatibleFormats128Bit[]	=
9079 {
9080 	VK_FORMAT_R32G32B32A32_UINT,
9081 	VK_FORMAT_R32G32B32A32_SINT,
9082 	VK_FORMAT_R32G32B32A32_SFLOAT,
9083 	VK_FORMAT_R64G64_UINT,
9084 	VK_FORMAT_R64G64_SINT,
9085 	VK_FORMAT_R64G64_SFLOAT,
9086 
9087 	VK_FORMAT_BC2_UNORM_BLOCK,
9088 	VK_FORMAT_BC2_SRGB_BLOCK,
9089 	VK_FORMAT_BC3_UNORM_BLOCK,
9090 	VK_FORMAT_BC3_SRGB_BLOCK,
9091 	VK_FORMAT_BC5_UNORM_BLOCK,
9092 	VK_FORMAT_BC5_SNORM_BLOCK,
9093 	VK_FORMAT_BC6H_UFLOAT_BLOCK,
9094 	VK_FORMAT_BC6H_SFLOAT_BLOCK,
9095 	VK_FORMAT_BC7_UNORM_BLOCK,
9096 	VK_FORMAT_BC7_SRGB_BLOCK,
9097 
9098 	VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
9099 	VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
9100 
9101 	VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
9102 	VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
9103 
9104 	VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
9105 	VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
9106 	VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
9107 	VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
9108 	VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
9109 	VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
9110 	VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
9111 	VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
9112 	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
9113 	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
9114 	VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
9115 	VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
9116 	VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
9117 	VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
9118 	VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
9119 	VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
9120 	VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
9121 	VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
9122 	VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
9123 	VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
9124 	VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
9125 	VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
9126 	VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
9127 	VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
9128 	VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
9129 	VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
9130 	VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
9131 	VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
9132 
9133 	VK_FORMAT_UNDEFINED
9134 };
9135 const VkFormat	compatibleFormats192Bit[]	=
9136 {
9137 	VK_FORMAT_R64G64B64_UINT,
9138 	VK_FORMAT_R64G64B64_SINT,
9139 	VK_FORMAT_R64G64B64_SFLOAT,
9140 
9141 	VK_FORMAT_UNDEFINED
9142 };
9143 const VkFormat	compatibleFormats256Bit[]	=
9144 {
9145 	VK_FORMAT_R64G64B64A64_UINT,
9146 	VK_FORMAT_R64G64B64A64_SINT,
9147 	VK_FORMAT_R64G64B64A64_SFLOAT,
9148 
9149 	VK_FORMAT_UNDEFINED
9150 };
9151 
9152 const VkFormat*	colorImageFormatsToTest[]	=
9153 {
9154 	compatibleFormats8Bit,
9155 	compatibleFormats16Bit,
9156 	compatibleFormats24Bit,
9157 	compatibleFormats32Bit,
9158 	compatibleFormats48Bit,
9159 	compatibleFormats64Bit,
9160 	compatibleFormats96Bit,
9161 	compatibleFormats128Bit,
9162 	compatibleFormats192Bit,
9163 	compatibleFormats256Bit
9164 };
9165 
9166 const VkFormat	dedicatedAllocationImageToImageFormatsToTest[]	=
9167 {
9168 	// From compatibleFormats8Bit
9169 	VK_FORMAT_R4G4_UNORM_PACK8,
9170 	VK_FORMAT_R8_SRGB,
9171 
9172 	// From compatibleFormats16Bit
9173 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9174 	VK_FORMAT_R16_SFLOAT,
9175 
9176 	// From compatibleFormats24Bit
9177 	VK_FORMAT_R8G8B8_UNORM,
9178 	VK_FORMAT_B8G8R8_SRGB,
9179 
9180 	// From compatibleFormats32Bit
9181 	VK_FORMAT_R8G8B8A8_UNORM,
9182 	VK_FORMAT_R32_SFLOAT,
9183 
9184 	// From compatibleFormats48Bit
9185 	VK_FORMAT_R16G16B16_UNORM,
9186 	VK_FORMAT_R16G16B16_SFLOAT,
9187 
9188 	// From compatibleFormats64Bit
9189 	VK_FORMAT_R16G16B16A16_UNORM,
9190 	VK_FORMAT_R64_SFLOAT,
9191 
9192 	// From compatibleFormats96Bit
9193 	VK_FORMAT_R32G32B32_UINT,
9194 	VK_FORMAT_R32G32B32_SFLOAT,
9195 
9196 	// From compatibleFormats128Bit
9197 	VK_FORMAT_R32G32B32A32_UINT,
9198 	VK_FORMAT_R64G64_SFLOAT,
9199 
9200 	// From compatibleFormats192Bit
9201 	VK_FORMAT_R64G64B64_UINT,
9202 	VK_FORMAT_R64G64B64_SFLOAT,
9203 
9204 	// From compatibleFormats256Bit
9205 	VK_FORMAT_R64G64B64A64_UINT,
9206 	VK_FORMAT_R64G64B64A64_SFLOAT,
9207 };
9208 
addImageToImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9209 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9210 {
9211 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
9212 	{
9213 		const int numOfDedicatedAllocationImageToImageFormatsToTest = DE_LENGTH_OF_ARRAY(dedicatedAllocationImageToImageFormatsToTest);
9214 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfDedicatedAllocationImageToImageFormatsToTest; ++compatibleFormatsIndex)
9215 			dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
9216 	}
9217 
9218 	// 2D tests.
9219 	{
9220 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
9221 
9222 		TestParams	params;
9223 		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
9224 		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
9225 		params.src.image.extent		= defaultExtent;
9226 		params.dst.image.extent		= defaultExtent;
9227 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9228 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9229 		params.allocationKind		= allocationKind;
9230 		params.extensionUse			= extensionUse;
9231 
9232 		for (deInt32 i = 0; i < defaultSize; i += defaultQuarterSize)
9233 		{
9234 			const VkImageCopy				testCopy =
9235 			{
9236 				defaultSourceLayer,								// VkImageSubresourceLayers	srcSubresource;
9237 				{0, 0, 0},										// VkOffset3D				srcOffset;
9238 				defaultSourceLayer,								// VkImageSubresourceLayers	dstSubresource;
9239 				{i, defaultSize - i - defaultQuarterSize, 0},	// VkOffset3D				dstOffset;
9240 				{defaultQuarterSize, defaultQuarterSize, 1},		// VkExtent3D				extent;
9241 			};
9242 
9243 			CopyRegion	imageCopy;
9244 			imageCopy.imageCopy = testCopy;
9245 
9246 			params.regions.push_back(imageCopy);
9247 		}
9248 
9249 		const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
9250 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9251 		{
9252 			const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
9253 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9254 			{
9255 				params.src.image.format = compatibleFormats[srcFormatIndex];
9256 				if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
9257 					continue;
9258 
9259 				CopyColorTestParams	testParams;
9260 				testParams.params				= params;
9261 				testParams.compatibleFormats	= compatibleFormats;
9262 
9263 				const std::string testName		= getFormatCaseName(params.src.image.format);
9264 				const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
9265 				addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
9266 			}
9267 		}
9268 
9269 		group->addChild(subGroup.release());
9270 	}
9271 
9272 	// 1D tests.
9273 	{
9274 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
9275 
9276 		TestParams	params;
9277 		params.src.image.imageType	= VK_IMAGE_TYPE_1D;
9278 		params.dst.image.imageType	= VK_IMAGE_TYPE_1D;
9279 		params.src.image.extent		= default1dExtent;
9280 		params.dst.image.extent		= default1dExtent;
9281 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9282 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9283 		params.allocationKind		= allocationKind;
9284 		params.extensionUse			= extensionUse;
9285 
9286 		for (deInt32 i = defaultQuarterSize; i < defaultSize; i += defaultSize / 2)
9287 		{
9288 			const VkImageCopy				testCopy =
9289 			{
9290 				defaultSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
9291 				{0, 0, 0},					// VkOffset3D				srcOffset;
9292 				defaultSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
9293 				{i, 0, 0},					// VkOffset3D				dstOffset;
9294 				{defaultQuarterSize, 1, 1},	// VkExtent3D				extent;
9295 			};
9296 
9297 			CopyRegion	imageCopy;
9298 			imageCopy.imageCopy = testCopy;
9299 
9300 			params.regions.push_back(imageCopy);
9301 		}
9302 
9303 		const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
9304 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9305 		{
9306 			const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
9307 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9308 			{
9309 				params.src.image.format = compatibleFormats[srcFormatIndex];
9310 				if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
9311 					continue;
9312 
9313 				CopyColorTestParams	testParams;
9314 				testParams.params				= params;
9315 				testParams.compatibleFormats	= nullptr;
9316 
9317 				const std::string testName		= getFormatCaseName(params.src.image.format);
9318 				const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
9319 				addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
9320 			}
9321 		}
9322 
9323 		group->addChild(subGroup.release());
9324 	}
9325 
9326 	// 3D tests. Note we use smaller dimensions here for performance reasons.
9327 	{
9328 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
9329 
9330 		TestParams	params;
9331 		params.src.image.imageType	= VK_IMAGE_TYPE_3D;
9332 		params.dst.image.imageType	= VK_IMAGE_TYPE_3D;
9333 		params.src.image.extent		= default3dExtent;
9334 		params.dst.image.extent		= default3dExtent;
9335 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9336 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9337 		params.allocationKind		= allocationKind;
9338 		params.extensionUse			= extensionUse;
9339 
9340 		for (deInt32 i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
9341 		{
9342 			const VkImageCopy				testCopy =
9343 			{
9344 				defaultSourceLayer,													// VkImageSubresourceLayers	srcSubresource;
9345 				{0, 0, 0},															// VkOffset3D				srcOffset;
9346 				defaultSourceLayer,													// VkImageSubresourceLayers	dstSubresource;
9347 				{i, defaultQuarterSize - i - defaultSixteenthSize, i},				// VkOffset3D				dstOffset;
9348 				{defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize},	// VkExtent3D				extent;
9349 			};
9350 
9351 			CopyRegion	imageCopy;
9352 			imageCopy.imageCopy = testCopy;
9353 
9354 			params.regions.push_back(imageCopy);
9355 		}
9356 
9357 		const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
9358 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
9359 		{
9360 			const VkFormat*	compatibleFormats	= colorImageFormatsToTest[compatibleFormatsIndex];
9361 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
9362 			{
9363 				params.src.image.format = compatibleFormats[srcFormatIndex];
9364 				if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
9365 					continue;
9366 
9367 				CopyColorTestParams	testParams;
9368 				testParams.params				= params;
9369 				testParams.compatibleFormats	= nullptr;
9370 
9371 				const std::string testName		= getFormatCaseName(params.src.image.format);
9372 				const std::string description	= "Copy from source format " + getFormatCaseName(params.src.image.format);
9373 				addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
9374 			}
9375 		}
9376 
9377 		group->addChild(subGroup.release());
9378 	}
9379 }
9380 
addImageToImageDimensionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9381 void addImageToImageDimensionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9382 {
9383 	tcu::TestContext&		testCtx				= group->getTestContext();
9384 
9385 	const VkFormat			testFormats[][2]	=
9386 	{
9387 		// From compatibleFormats8Bit
9388 		{
9389 			VK_FORMAT_R4G4_UNORM_PACK8,
9390 			VK_FORMAT_R8_SRGB
9391 		},
9392 		// From compatibleFormats16Bit
9393 		{
9394 			VK_FORMAT_R4G4B4A4_UNORM_PACK16,
9395 			VK_FORMAT_R16_SFLOAT,
9396 		},
9397 		// From compatibleFormats24Bit
9398 		{
9399 			VK_FORMAT_R8G8B8_UNORM,
9400 			VK_FORMAT_B8G8R8_SRGB
9401 		},
9402 		// From compatibleFormats32Bit
9403 		{
9404 			VK_FORMAT_R8G8B8A8_UNORM,
9405 			VK_FORMAT_R32_SFLOAT
9406 		},
9407 		// From compatibleFormats48Bit
9408 		{
9409 			VK_FORMAT_R16G16B16_UNORM,
9410 			VK_FORMAT_R16G16B16_SFLOAT
9411 		},
9412 		// From compatibleFormats64Bit
9413 		{
9414 			VK_FORMAT_R16G16B16A16_UNORM,
9415 			VK_FORMAT_R64_SFLOAT
9416 		},
9417 		// From compatibleFormats96Bit
9418 		{
9419 			VK_FORMAT_R32G32B32_UINT,
9420 			VK_FORMAT_R32G32B32_SFLOAT
9421 		},
9422 		// From compatibleFormats128Bit
9423 		{
9424 			VK_FORMAT_R32G32B32A32_UINT,
9425 			VK_FORMAT_R64G64_SFLOAT
9426 		},
9427 		// From compatibleFormats192Bit
9428 		{
9429 			VK_FORMAT_R64G64B64_UINT,
9430 			VK_FORMAT_R64G64B64_SFLOAT,
9431 		},
9432 		// From compatibleFormats256Bit
9433 		{
9434 			VK_FORMAT_R64G64B64A64_UINT,
9435 			VK_FORMAT_R64G64B64A64_SFLOAT
9436 		}
9437 	};
9438 
9439 	const tcu::UVec2		imageDimensions[]	=
9440 	{
9441 		// large pot x small pot
9442 		tcu::UVec2(4096,	4u),
9443 		tcu::UVec2(8192,	4u),
9444 		tcu::UVec2(16384,	4u),
9445 		tcu::UVec2(32768,	4u),
9446 
9447 		// large pot x small npot
9448 		tcu::UVec2(4096,	6u),
9449 		tcu::UVec2(8192,	6u),
9450 		tcu::UVec2(16384,	6u),
9451 		tcu::UVec2(32768,	6u),
9452 
9453 		// small pot x large pot
9454 		tcu::UVec2(4u, 4096),
9455 		tcu::UVec2(4u, 8192),
9456 		tcu::UVec2(4u, 16384),
9457 		tcu::UVec2(4u, 32768),
9458 
9459 		// small npot x large pot
9460 		tcu::UVec2(6u, 4096),
9461 		tcu::UVec2(6u, 8192),
9462 		tcu::UVec2(6u, 16384),
9463 		tcu::UVec2(6u, 32768)
9464 	};
9465 
9466 	const VkImageLayout		copySrcLayouts[]	=
9467 	{
9468 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
9469 		VK_IMAGE_LAYOUT_GENERAL
9470 	};
9471 
9472 	const VkImageLayout		copyDstLayouts[]	=
9473 	{
9474 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
9475 		VK_IMAGE_LAYOUT_GENERAL
9476 	};
9477 
9478 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
9479 	{
9480 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(dedicatedAllocationImageToImageFormatsToTest); compatibleFormatsIndex++)
9481 			dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
9482 	}
9483 
9484 	// Image dimensions
9485 	for (size_t dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); dimensionNdx++)
9486 	{
9487 		CopyRegion				copyRegion;
9488 		CopyColorTestParams		testParams;
9489 
9490 		const VkExtent3D		extent			= { imageDimensions[dimensionNdx].x(), imageDimensions[dimensionNdx].y(), 1 };
9491 
9492 		const VkImageCopy		testCopy		=
9493 		{
9494 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9495 			{0, 0, 0},			// VkOffset3D				srcOffset;
9496 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9497 			{0, 0, 0},			// VkOffset3D				dstOffset;
9498 			extent,				// VkExtent3D				extent;
9499 		};
9500 
9501 		testParams.params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9502 		testParams.params.src.image.imageType	= VK_IMAGE_TYPE_2D;
9503 		testParams.params.src.image.extent		= extent;
9504 
9505 		testParams.params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
9506 		testParams.params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
9507 		testParams.params.dst.image.extent		= extent;
9508 
9509 		copyRegion.imageCopy					= testCopy;
9510 		testParams.params.allocationKind		= allocationKind;
9511 		testParams.params.extensionUse			= extensionUse;
9512 
9513 		testParams.params.regions.push_back(copyRegion);
9514 
9515 		const std::string	dimensionStr		= "src" + de::toString(testParams.params.src.image.extent.width) + "x" + de::toString(testParams.params.src.image.extent.height)
9516 												  + "_dst" + de::toString(testParams.params.dst.image.extent.width) + "x" + de::toString(testParams.params.dst.image.extent.height);
9517 		tcu::TestCaseGroup*	imageSizeGroup		= new tcu::TestCaseGroup(testCtx, dimensionStr.c_str(), ("Image sizes " + dimensionStr).c_str());
9518 
9519 		// Compatible formats for copying
9520 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
9521 		{
9522 			const VkFormat* compatibleFormats = testFormats[compatibleFormatsIndex];
9523 
9524 			testParams.compatibleFormats = compatibleFormats;
9525 
9526 			// Source image format
9527 			for (int srcFormatIndex = 0; srcFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); srcFormatIndex++)
9528 			{
9529 				testParams.params.src.image.format = testParams.compatibleFormats[srcFormatIndex];
9530 
9531 				if (!isSupportedByFramework(testParams.params.src.image.format) && !isCompressedFormat(testParams.params.src.image.format))
9532 					continue;
9533 
9534 				const std::string	srcDescription	= "Copy from source format " + getFormatCaseName(testParams.params.src.image.format);
9535 				tcu::TestCaseGroup*	srcFormatGroup	= new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.src.image.format).c_str(), srcDescription.c_str());
9536 
9537 				// Destination image format
9538 				for (int dstFormatIndex = 0; dstFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); dstFormatIndex++)
9539 				{
9540 					testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
9541 
9542 					if (!isSupportedByFramework(testParams.params.dst.image.format) && !isCompressedFormat(testParams.params.dst.image.format))
9543 						continue;
9544 
9545 					if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
9546 						continue;
9547 
9548 					if (isCompressedFormat(testParams.params.src.image.format) && isCompressedFormat(testParams.params.dst.image.format))
9549 					{
9550 						if ((getBlockWidth(testParams.params.src.image.format) != getBlockWidth(testParams.params.dst.image.format))
9551 							|| (getBlockHeight(testParams.params.src.image.format) != getBlockHeight(testParams.params.dst.image.format)))
9552 							continue;
9553 					}
9554 
9555 					const std::string	dstDescription	= "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
9556 					tcu::TestCaseGroup*	dstFormatGroup	= new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.dst.image.format).c_str(), dstDescription.c_str());
9557 
9558 					// Source/destionation image layouts
9559 					for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); srcLayoutNdx++)
9560 					{
9561 						testParams.params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
9562 
9563 						for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); dstLayoutNdx++)
9564 						{
9565 							testParams.params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
9566 
9567 							const std::string	testName	= getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
9568 							const std::string	description	= "From layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
9569 							const TestParams	params		= testParams.params;
9570 
9571 							dstFormatGroup->addChild(new CopyImageToImageTestCase(testCtx, testName, description, params));
9572 						}
9573 					}
9574 
9575 					srcFormatGroup->addChild(dstFormatGroup);
9576 				}
9577 
9578 				imageSizeGroup->addChild(srcFormatGroup);
9579 			}
9580 		}
9581 
9582 		group->addChild(imageSizeGroup);
9583 	}
9584 }
9585 
addImageToImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)9586 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
9587 {
9588 	const VkImageLayout copySrcLayouts[]		=
9589 	{
9590 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
9591 		VK_IMAGE_LAYOUT_GENERAL
9592 	};
9593 	const VkImageLayout copyDstLayouts[]		=
9594 	{
9595 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
9596 		VK_IMAGE_LAYOUT_GENERAL
9597 	};
9598 
9599 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
9600 	{
9601 		params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
9602 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
9603 		{
9604 			params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
9605 
9606 			const std::string testName		= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
9607 											  getImageLayoutCaseName(params.dst.image.operationLayout);
9608 			const std::string description	= "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
9609 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
9610 			group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
9611 		}
9612 	}
9613 }
9614 
addImageToImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9615 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9616 {
9617 	const VkFormat	depthAndStencilFormats[]	=
9618 	{
9619 		VK_FORMAT_D16_UNORM,
9620 		VK_FORMAT_X8_D24_UNORM_PACK32,
9621 		VK_FORMAT_D32_SFLOAT,
9622 		VK_FORMAT_S8_UINT,
9623 		VK_FORMAT_D16_UNORM_S8_UINT,
9624 		VK_FORMAT_D24_UNORM_S8_UINT,
9625 		VK_FORMAT_D32_SFLOAT_S8_UINT,
9626 	};
9627 
9628 	// 2D tests.
9629 	{
9630 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
9631 
9632 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9633 		{
9634 			TestParams	params;
9635 			params.src.image.imageType			= VK_IMAGE_TYPE_2D;
9636 			params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
9637 			params.src.image.extent				= defaultExtent;
9638 			params.dst.image.extent				= defaultExtent;
9639 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
9640 			params.dst.image.format				= params.src.image.format;
9641 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9642 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9643 			params.allocationKind				= allocationKind;
9644 			params.extensionUse					= extensionUse;
9645 			params.separateDepthStencilLayouts	= DE_FALSE;
9646 
9647 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9648 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9649 
9650 			const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9651 			const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9652 			const VkImageSubresourceLayers		defaultDSSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9653 
9654 			for (deInt32 i = 0; i < defaultSize; i += defaultQuarterSize)
9655 			{
9656 				CopyRegion			copyRegion;
9657 				const VkOffset3D	srcOffset	= {0, 0, 0};
9658 				const VkOffset3D	dstOffset	= {i, defaultSize - i - defaultQuarterSize, 0};
9659 				const VkExtent3D	extent		= {defaultQuarterSize, defaultQuarterSize, 1};
9660 
9661 				if (hasDepth)
9662 				{
9663 					const VkImageCopy				testCopy	=
9664 					{
9665 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9666 						srcOffset,					// VkOffset3D				srcOffset;
9667 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9668 						dstOffset,					// VkOffset3D				dstOffset;
9669 						extent,						// VkExtent3D				extent;
9670 					};
9671 
9672 					copyRegion.imageCopy	= testCopy;
9673 					params.regions.push_back(copyRegion);
9674 				}
9675 				if (hasStencil)
9676 				{
9677 					const VkImageCopy				testCopy	=
9678 					{
9679 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9680 						srcOffset,					// VkOffset3D				srcOffset;
9681 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9682 						dstOffset,					// VkOffset3D				dstOffset;
9683 						extent,						// VkExtent3D				extent;
9684 					};
9685 
9686 					copyRegion.imageCopy	= testCopy;
9687 					params.regions.push_back(copyRegion);
9688 				}
9689 			}
9690 
9691 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9692 			const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9693 			addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9694 
9695 			if (hasDepth && hasStencil)
9696 			{
9697 				params.separateDepthStencilLayouts	= DE_TRUE;
9698 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9699 				const std::string description2	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9700 				addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9701 
9702 				// DS Image copy
9703 				{
9704 					params.separateDepthStencilLayouts	= DE_FALSE;
9705 					// Clear previous vkImageCopy elements
9706 					params.regions.clear();
9707 
9708 					for (deInt32 i = 0; i < defaultSize; i += defaultQuarterSize)
9709 					{
9710 						CopyRegion			copyRegion;
9711 						const VkOffset3D	srcOffset	= {0, 0, 0};
9712 						const VkOffset3D	dstOffset	= {i, defaultSize - i - defaultQuarterSize, 0};
9713 						const VkExtent3D	extent		= {defaultQuarterSize, defaultQuarterSize, 1};
9714 
9715 						const VkImageCopy				testCopy	=
9716 						{
9717 							defaultDSSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
9718 							srcOffset,					// VkOffset3D				srcOffset;
9719 							defaultDSSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
9720 							dstOffset,					// VkOffset3D				dstOffset;
9721 							extent,						// VkExtent3D				extent;
9722 						};
9723 
9724 						copyRegion.imageCopy	= testCopy;
9725 						params.regions.push_back(copyRegion);
9726 					}
9727 
9728 					const std::string testName3		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
9729 					const std::string description3	= "Copy both depth and stencil aspects from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9730 					addTestGroup(subGroup.get(), testName3, description3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9731 				}
9732 			}
9733 		}
9734 
9735 		group->addChild(subGroup.release());
9736 	}
9737 
9738 	// 1D tests.
9739 	{
9740 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
9741 
9742 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9743 		{
9744 			TestParams	params;
9745 			params.src.image.imageType			= VK_IMAGE_TYPE_1D;
9746 			params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
9747 			params.src.image.extent				= default1dExtent;
9748 			params.dst.image.extent				= default1dExtent;
9749 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
9750 			params.dst.image.format				= params.src.image.format;
9751 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9752 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9753 			params.allocationKind				= allocationKind;
9754 			params.extensionUse					= extensionUse;
9755 
9756 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9757 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9758 
9759 			const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9760 			const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9761 
9762 			for (deInt32 i = defaultQuarterSize; i < defaultSize; i += defaultSize / 2)
9763 			{
9764 				CopyRegion			copyRegion;
9765 				const VkOffset3D	srcOffset	= {0, 0, 0};
9766 				const VkOffset3D	dstOffset	= {i, 0, 0};
9767 				const VkExtent3D	extent		= {defaultQuarterSize, 1, 1};
9768 
9769 				if (hasDepth)
9770 				{
9771 					const VkImageCopy				testCopy	=
9772 					{
9773 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9774 						srcOffset,					// VkOffset3D				srcOffset;
9775 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9776 						dstOffset,					// VkOffset3D				dstOffset;
9777 						extent,						// VkExtent3D				extent;
9778 					};
9779 
9780 					copyRegion.imageCopy	= testCopy;
9781 					params.regions.push_back(copyRegion);
9782 				}
9783 				if (hasStencil)
9784 				{
9785 					const VkImageCopy				testCopy	=
9786 					{
9787 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9788 						srcOffset,					// VkOffset3D				srcOffset;
9789 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9790 						dstOffset,					// VkOffset3D				dstOffset;
9791 						extent,						// VkExtent3D				extent;
9792 					};
9793 
9794 					copyRegion.imageCopy	= testCopy;
9795 					params.regions.push_back(copyRegion);
9796 				}
9797 			}
9798 
9799 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9800 			const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9801 			addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9802 
9803 			if (hasDepth && hasStencil)
9804 			{
9805 				params.separateDepthStencilLayouts	= DE_TRUE;
9806 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9807 				const std::string description2	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9808 				addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9809 			}
9810 		}
9811 
9812 		group->addChild(subGroup.release());
9813 	}
9814 
9815 	// 3D tests. Note we use smaller dimensions here for performance reasons.
9816 	{
9817 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
9818 
9819 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
9820 		{
9821 			TestParams	params;
9822 			params.src.image.imageType			= VK_IMAGE_TYPE_3D;
9823 			params.dst.image.imageType			= VK_IMAGE_TYPE_3D;
9824 			params.src.image.extent				= default3dExtent;
9825 			params.dst.image.extent				= default3dExtent;
9826 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
9827 			params.dst.image.format				= params.src.image.format;
9828 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9829 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
9830 			params.allocationKind				= allocationKind;
9831 			params.extensionUse					= extensionUse;
9832 
9833 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
9834 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
9835 
9836 			const VkImageSubresourceLayers		defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
9837 			const VkImageSubresourceLayers		defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
9838 
9839 			for (deInt32 i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
9840 			{
9841 				CopyRegion			copyRegion;
9842 				const VkOffset3D	srcOffset	= {0, 0, 0};
9843 				const VkOffset3D	dstOffset	= {i, defaultQuarterSize - i - defaultSixteenthSize, i};
9844 				const VkExtent3D	extent		= {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
9845 
9846 				if (hasDepth)
9847 				{
9848 					const VkImageCopy				testCopy	=
9849 					{
9850 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9851 						srcOffset,					// VkOffset3D				srcOffset;
9852 						defaultDepthSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9853 						dstOffset,					// VkOffset3D				dstOffset;
9854 						extent,						// VkExtent3D				extent;
9855 					};
9856 
9857 					copyRegion.imageCopy	= testCopy;
9858 					params.regions.push_back(copyRegion);
9859 				}
9860 				if (hasStencil)
9861 				{
9862 					const VkImageCopy				testCopy	=
9863 					{
9864 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
9865 						srcOffset,					// VkOffset3D				srcOffset;
9866 						defaultStencilSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
9867 						dstOffset,					// VkOffset3D				dstOffset;
9868 						extent,						// VkExtent3D				extent;
9869 					};
9870 
9871 					copyRegion.imageCopy	= testCopy;
9872 					params.regions.push_back(copyRegion);
9873 				}
9874 			}
9875 
9876 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
9877 			const std::string description	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
9878 			addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9879 
9880 			if (hasDepth && hasStencil)
9881 			{
9882 				params.separateDepthStencilLayouts	= DE_TRUE;
9883 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
9884 				const std::string description2	= "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
9885 				addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
9886 			}
9887 		}
9888 
9889 		group->addChild(subGroup.release());
9890 	}
9891 }
9892 
addImageToImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9893 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9894 {
9895 	addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind, extensionUse);
9896 	addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
9897 }
9898 
addImageToImage3dImagesTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9899 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9900 {
9901 	tcu::TestContext& testCtx	= group->getTestContext();
9902 
9903 	{
9904 		TestParams	params3DTo2D;
9905 		const deUint32	slicesLayers			= 16u;
9906 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
9907 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
9908 		params3DTo2D.src.image.extent			= defaultHalfExtent;
9909 		params3DTo2D.src.image.extent.depth		= slicesLayers;
9910 		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
9911 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9912 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
9913 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
9914 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
9915 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
9916 		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
9917 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9918 		params3DTo2D.allocationKind				= allocationKind;
9919 		params3DTo2D.extensionUse				= extensionUse;
9920 
9921 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
9922 		{
9923 			const VkImageSubresourceLayers	sourceLayer	=
9924 			{
9925 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
9926 				0u,							// deUint32				mipLevel;
9927 				0u,							// deUint32				baseArrayLayer;
9928 				1u							// deUint32				layerCount;
9929 			};
9930 
9931 			const VkImageSubresourceLayers	destinationLayer	=
9932 			{
9933 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
9934 				0u,							// deUint32				mipLevel;
9935 				slicesLayersNdx,			// deUint32				baseArrayLayer;
9936 				1u							// deUint32				layerCount;
9937 			};
9938 
9939 			const VkImageCopy				testCopy	=
9940 			{
9941 				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
9942 				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D				srcOffset;
9943 				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
9944 				{0, 0, 0},							// VkOffset3D				dstOffset;
9945 				defaultHalfExtent,					// VkExtent3D				extent;
9946 			};
9947 
9948 			CopyRegion	imageCopy;
9949 			imageCopy.imageCopy	= testCopy;
9950 
9951 			params3DTo2D.regions.push_back(imageCopy);
9952 		}
9953 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
9954 	}
9955 
9956 	{
9957 		TestParams	params2DTo3D;
9958 		const deUint32	slicesLayers			= 16u;
9959 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
9960 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
9961 		params2DTo3D.src.image.extent			= defaultHalfExtent;
9962 		params2DTo3D.src.image.extent.depth		= slicesLayers;
9963 		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
9964 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9965 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
9966 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
9967 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
9968 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
9969 		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
9970 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9971 		params2DTo3D.allocationKind				= allocationKind;
9972 		params2DTo3D.extensionUse				= extensionUse;
9973 
9974 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
9975 		{
9976 			const VkImageSubresourceLayers	sourceLayer	=
9977 			{
9978 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
9979 				0u,							// deUint32				mipLevel;
9980 				slicesLayersNdx,			// deUint32				baseArrayLayer;
9981 				1u							// deUint32				layerCount;
9982 			};
9983 
9984 			const VkImageSubresourceLayers	destinationLayer	=
9985 			{
9986 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
9987 				0u,							// deUint32				mipLevel;
9988 				0u,							// deUint32				baseArrayLayer;
9989 				1u							// deUint32				layerCount;
9990 			};
9991 
9992 			const VkImageCopy				testCopy	=
9993 			{
9994 				sourceLayer,						// VkImageSubresourceLayers	srcSubresource;
9995 				{0, 0, 0},							// VkOffset3D				srcOffset;
9996 				destinationLayer,					// VkImageSubresourceLayers	dstSubresource;
9997 				{0, 0, (deInt32)slicesLayersNdx},	// VkOffset3D				dstOffset;
9998 				defaultHalfExtent,					// VkExtent3D				extent;
9999 			};
10000 
10001 			CopyRegion	imageCopy;
10002 			imageCopy.imageCopy	= testCopy;
10003 
10004 			params2DTo3D.regions.push_back(imageCopy);
10005 		}
10006 
10007 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
10008 	}
10009 
10010 	{
10011 		TestParams	params3DTo2D;
10012 		const deUint32	slicesLayers			= 16u;
10013 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
10014 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10015 		params3DTo2D.src.image.extent			= defaultHalfExtent;
10016 		params3DTo2D.src.image.extent.depth		= slicesLayers;
10017 		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10018 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10019 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10020 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10021 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
10022 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
10023 		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10024 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10025 		params3DTo2D.allocationKind				= allocationKind;
10026 		params3DTo2D.extensionUse				= extensionUse;
10027 
10028 		{
10029 			const VkImageSubresourceLayers	sourceLayer	=
10030 			{
10031 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10032 				0u,							// deUint32				mipLevel;
10033 				0u,							// deUint32				baseArrayLayer;
10034 				1u							// deUint32				layerCount;
10035 			};
10036 
10037 			const VkImageSubresourceLayers	destinationLayer	=
10038 			{
10039 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10040 				0u,							// deUint32				mipLevel;
10041 				0,							// deUint32				baseArrayLayer;
10042 				slicesLayers				// deUint32				layerCount;
10043 			};
10044 
10045 			const VkImageCopy				testCopy	=
10046 			{
10047 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
10048 				{0, 0, 0},						// VkOffset3D				srcOffset;
10049 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
10050 				{0, 0, 0},						// VkOffset3D				dstOffset;
10051 				params3DTo2D.src.image.extent	// VkExtent3D				extent;
10052 			};
10053 
10054 			CopyRegion	imageCopy;
10055 			imageCopy.imageCopy	= testCopy;
10056 
10057 			params3DTo2D.regions.push_back(imageCopy);
10058 		}
10059 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
10060 	}
10061 
10062 	{
10063 		TestParams	params2DTo3D;
10064 		const deUint32	slicesLayers			= 16u;
10065 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
10066 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10067 		params2DTo3D.src.image.extent			= defaultHalfExtent;
10068 		params2DTo3D.src.image.extent.depth		= slicesLayers;
10069 		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10070 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10071 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
10072 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10073 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
10074 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
10075 		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10076 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10077 		params2DTo3D.allocationKind				= allocationKind;
10078 		params2DTo3D.extensionUse				= extensionUse;
10079 
10080 		{
10081 			const VkImageSubresourceLayers	sourceLayer	=
10082 			{
10083 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10084 				0u,							// deUint32				mipLevel;
10085 				0u,							// deUint32				baseArrayLayer;
10086 				slicesLayers				// deUint32				layerCount;
10087 			};
10088 
10089 			const VkImageSubresourceLayers	destinationLayer	=
10090 			{
10091 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10092 				0u,							// deUint32				mipLevel;
10093 				0u,							// deUint32				baseArrayLayer;
10094 				1u							// deUint32				layerCount;
10095 			};
10096 
10097 			const VkImageCopy				testCopy	=
10098 			{
10099 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
10100 				{0, 0, 0},						// VkOffset3D				srcOffset;
10101 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
10102 				{0, 0, 0},						// VkOffset3D				dstOffset;
10103 				params2DTo3D.src.image.extent,	// VkExtent3D				extent;
10104 			};
10105 
10106 			CopyRegion	imageCopy;
10107 			imageCopy.imageCopy	= testCopy;
10108 
10109 			params2DTo3D.regions.push_back(imageCopy);
10110 		}
10111 
10112 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
10113 	}
10114 
10115 	{
10116 		TestParams	params3DTo2D;
10117 		const deUint32	slicesLayers			= 16u;
10118 		params3DTo2D.src.image.imageType		= VK_IMAGE_TYPE_3D;
10119 		params3DTo2D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10120 		params3DTo2D.src.image.extent			= defaultHalfExtent;
10121 		params3DTo2D.src.image.extent.depth		= slicesLayers;
10122 		params3DTo2D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10123 		params3DTo2D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10124 		params3DTo2D.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10125 		params3DTo2D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10126 		params3DTo2D.dst.image.extent			= defaultHalfExtent;
10127 		params3DTo2D.dst.image.extent.depth		= slicesLayers;
10128 		params3DTo2D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10129 		params3DTo2D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10130 		params3DTo2D.allocationKind				= allocationKind;
10131 		params3DTo2D.extensionUse				= extensionUse;
10132 
10133 		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
10134 		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;
10135 
10136 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
10137 		{
10138 			const VkImageSubresourceLayers	sourceLayer	=
10139 			{
10140 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10141 				0u,							// deUint32				mipLevel;
10142 				0u,							// deUint32				baseArrayLayer;
10143 				1u							// deUint32				layerCount;
10144 			};
10145 
10146 			const VkImageSubresourceLayers	destinationLayer	=
10147 			{
10148 					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10149 					0u,								// deUint32				mipLevel;
10150 					slicesLayersNdx,				// deUint32				baseArrayLayer;
10151 					1u								// deUint32				layerCount;
10152 			};
10153 
10154 
10155 			const VkImageCopy				testCopy	=
10156 			{
10157 				sourceLayer,															// VkImageSubresourceLayers	srcSubresource;
10158 				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx},	// VkOffset3D				srcOffset;
10159 					destinationLayer,													// VkImageSubresourceLayers	dstSubresource;
10160 					{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},						// VkOffset3D				dstOffset;
10161 					{
10162 						(defaultHalfExtent.width - regionWidth*slicesLayersNdx),
10163 						(defaultHalfExtent.height - regionHeight*slicesLayersNdx),
10164 						1
10165 					}																	// VkExtent3D				extent;
10166 			};
10167 
10168 			CopyRegion	imageCopy;
10169 			imageCopy.imageCopy = testCopy;
10170 			params3DTo2D.regions.push_back(imageCopy);
10171 		}
10172 		group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
10173 	}
10174 
10175 	{
10176 		TestParams	params2DTo3D;
10177 		const deUint32	slicesLayers			= 16u;
10178 		params2DTo3D.src.image.imageType		= VK_IMAGE_TYPE_2D;
10179 		params2DTo3D.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10180 		params2DTo3D.src.image.extent			= defaultHalfExtent;
10181 		params2DTo3D.src.image.extent.depth		= slicesLayers;
10182 		params2DTo3D.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10183 		params2DTo3D.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10184 		params2DTo3D.dst.image.imageType		= VK_IMAGE_TYPE_3D;
10185 		params2DTo3D.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10186 		params2DTo3D.dst.image.extent			= defaultHalfExtent;
10187 		params2DTo3D.dst.image.extent.depth		= slicesLayers;
10188 		params2DTo3D.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10189 		params2DTo3D.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10190 		params2DTo3D.allocationKind				= allocationKind;
10191 		params2DTo3D.extensionUse				= extensionUse;
10192 
10193 		const deUint32 regionWidth				= defaultHalfExtent.width / slicesLayers -1;
10194 		const deUint32 regionHeight				= defaultHalfExtent.height / slicesLayers -1 ;
10195 
10196 		for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
10197 		{
10198 			const VkImageSubresourceLayers	sourceLayer	=
10199 			{
10200 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10201 				0u,							// deUint32				mipLevel;
10202 				slicesLayersNdx,			// deUint32				baseArrayLayer;
10203 				1u							// deUint32				layerCount;
10204 			};
10205 
10206 			const VkImageSubresourceLayers	destinationLayer	=
10207 			{
10208 				VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10209 				0u,							// deUint32				mipLevel;
10210 				0u,							// deUint32				baseArrayLayer;
10211 				1u							// deUint32				layerCount;
10212 			};
10213 
10214 			const VkImageCopy				testCopy	=
10215 			{
10216 				sourceLayer,																// VkImageSubresourceLayers	srcSubresource;
10217 				{(deInt32)(regionWidth*slicesLayersNdx), 0, 0},								// VkOffset3D				srcOffset;
10218 				destinationLayer,															// VkImageSubresourceLayers	dstSubresource;
10219 				{0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)},	// VkOffset3D				dstOffset;
10220 				{
10221 					defaultHalfExtent.width - regionWidth*slicesLayersNdx,
10222 					defaultHalfExtent.height - regionHeight*slicesLayersNdx,
10223 					1
10224 				}																			// VkExtent3D				extent;
10225 			};
10226 
10227 			CopyRegion	imageCopy;
10228 			imageCopy.imageCopy	= testCopy;
10229 
10230 			params2DTo3D.regions.push_back(imageCopy);
10231 		}
10232 
10233 		group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
10234 	}
10235 }
10236 
addImageToImageCubeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10237 void addImageToImageCubeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10238 {
10239 	tcu::TestContext& testCtx	= group->getTestContext();
10240 
10241 	{
10242 		TestParams	paramsCubeToArray;
10243 		const deUint32	arrayLayers					= 6u;
10244 		paramsCubeToArray.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10245 		paramsCubeToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
10246 		paramsCubeToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10247 		paramsCubeToArray.src.image.extent			= defaultHalfExtent;
10248 		paramsCubeToArray.src.image.extent.depth	= arrayLayers;
10249 		paramsCubeToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10250 		paramsCubeToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10251 		paramsCubeToArray.dst.image.createFlags		= 0;
10252 		paramsCubeToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10253 		paramsCubeToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10254 		paramsCubeToArray.dst.image.extent			= defaultHalfExtent;
10255 		paramsCubeToArray.dst.image.extent.depth	= arrayLayers;
10256 		paramsCubeToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10257 		paramsCubeToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10258 		paramsCubeToArray.allocationKind			= allocationKind;
10259 		paramsCubeToArray.extensionUse				= extensionUse;
10260 
10261 		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10262 		{
10263 			const VkImageSubresourceLayers	sourceLayer	=
10264 				{
10265 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10266 					0u,							// deUint32				mipLevel;
10267 					arrayLayersNdx,				// deUint32				baseArrayLayer;
10268 					1u							// deUint32				layerCount;
10269 				};
10270 
10271 			const VkImageSubresourceLayers	destinationLayer	=
10272 				{
10273 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10274 					0u,							// deUint32				mipLevel;
10275 					arrayLayersNdx,				// deUint32				baseArrayLayer;
10276 					1u							// deUint32				layerCount;
10277 				};
10278 
10279 			const VkImageCopy				testCopy	=
10280 				{
10281 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
10282 					{0, 0, 0},					// VkOffset3D				srcOffset;
10283 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
10284 					{0, 0, 0},					// VkOffset3D				dstOffset;
10285 					defaultHalfExtent				// VkExtent3D				extent;
10286 				};
10287 
10288 			CopyRegion	imageCopy;
10289 			imageCopy.imageCopy	= testCopy;
10290 
10291 			paramsCubeToArray.regions.push_back(imageCopy);
10292 		}
10293 
10294 		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_layers", "copy cube compatible image to 2d layers layer by layer", paramsCubeToArray));
10295 	}
10296 
10297 	{
10298 		TestParams	paramsCubeToArray;
10299 		const deUint32	arrayLayers					= 6u;
10300 		paramsCubeToArray.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10301 		paramsCubeToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
10302 		paramsCubeToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10303 		paramsCubeToArray.src.image.extent			= defaultHalfExtent;
10304 		paramsCubeToArray.src.image.extent.depth	= arrayLayers;
10305 		paramsCubeToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10306 		paramsCubeToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10307 		paramsCubeToArray.dst.image.createFlags		= 0;
10308 		paramsCubeToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10309 		paramsCubeToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10310 		paramsCubeToArray.dst.image.extent			= defaultHalfExtent;
10311 		paramsCubeToArray.dst.image.extent.depth	= arrayLayers;
10312 		paramsCubeToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10313 		paramsCubeToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10314 		paramsCubeToArray.allocationKind			= allocationKind;
10315 		paramsCubeToArray.extensionUse				= extensionUse;
10316 
10317 		{
10318 			const VkImageSubresourceLayers	sourceLayer	=
10319 				{
10320 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10321 					0u,							// deUint32				mipLevel;
10322 					0u,							// deUint32				baseArrayLayer;
10323 					arrayLayers					// deUint32				layerCount;
10324 				};
10325 
10326 			const VkImageSubresourceLayers	destinationLayer	=
10327 				{
10328 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10329 					0u,							// deUint32				mipLevel;
10330 					0u,							// deUint32				baseArrayLayer;
10331 					arrayLayers					// deUint32				layerCount;
10332 				};
10333 
10334 			const VkImageCopy				testCopy	=
10335 				{
10336 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
10337 					{0, 0, 0},					// VkOffset3D				srcOffset;
10338 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
10339 					{0, 0, 0},					// VkOffset3D				dstOffset;
10340 					defaultHalfExtent			// VkExtent3D				extent;
10341 				};
10342 
10343 			CopyRegion	imageCopy;
10344 			imageCopy.imageCopy	= testCopy;
10345 
10346 			paramsCubeToArray.regions.push_back(imageCopy);
10347 		}
10348 
10349 		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_whole", "copy cube compatible image to 2d layers all at once", paramsCubeToArray));
10350 	}
10351 
10352 	{
10353 		TestParams	paramsArrayToCube;
10354 		const deUint32	arrayLayers					= 6u;
10355 		paramsArrayToCube.src.image.createFlags		= 0;
10356 		paramsArrayToCube.src.image.imageType		= VK_IMAGE_TYPE_2D;
10357 		paramsArrayToCube.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10358 		paramsArrayToCube.src.image.extent			= defaultHalfExtent;
10359 		paramsArrayToCube.src.image.extent.depth	= arrayLayers;
10360 		paramsArrayToCube.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10361 		paramsArrayToCube.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10362 		paramsArrayToCube.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10363 		paramsArrayToCube.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10364 		paramsArrayToCube.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10365 		paramsArrayToCube.dst.image.extent			= defaultHalfExtent;
10366 		paramsArrayToCube.dst.image.extent.depth	= arrayLayers;
10367 		paramsArrayToCube.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10368 		paramsArrayToCube.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10369 		paramsArrayToCube.allocationKind			= allocationKind;
10370 		paramsArrayToCube.extensionUse				= extensionUse;
10371 
10372 		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10373 		{
10374 			const VkImageSubresourceLayers	sourceLayer	=
10375 				{
10376 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10377 					0u,							// deUint32				mipLevel;
10378 					arrayLayersNdx,				// deUint32				baseArrayLayer;
10379 					1u							// deUint32				layerCount;
10380 				};
10381 
10382 			const VkImageSubresourceLayers	destinationLayer =
10383 				{
10384 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10385 					0u,							// deUint32				mipLevel;
10386 					arrayLayersNdx,				// deUint32				baseArrayLayer;
10387 					1u							// deUint32				layerCount;
10388 				};
10389 
10390 			const VkImageCopy				testCopy =
10391 				{
10392 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
10393 					{0, 0, 0},					// VkOffset3D				srcOffset;
10394 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
10395 					{0, 0, 0},					// VkOffset3D				dstOffset;
10396 					defaultHalfExtent			// VkExtent3D				extent;
10397 				};
10398 
10399 			CopyRegion	imageCopy;
10400 			imageCopy.imageCopy	= testCopy;
10401 
10402 			paramsArrayToCube.regions.push_back(imageCopy);
10403 		}
10404 
10405 		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_layers", "copy 2d layers to cube compatible image layer by layer", paramsArrayToCube));
10406 	}
10407 
10408 	{
10409 		TestParams	paramsArrayToCube;
10410 		const deUint32	arrayLayers					= 6u;
10411 		paramsArrayToCube.src.image.createFlags		= 0;
10412 		paramsArrayToCube.src.image.imageType		= VK_IMAGE_TYPE_2D;
10413 		paramsArrayToCube.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10414 		paramsArrayToCube.src.image.extent			= defaultHalfExtent;
10415 		paramsArrayToCube.src.image.extent.depth	= arrayLayers;
10416 		paramsArrayToCube.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10417 		paramsArrayToCube.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10418 		paramsArrayToCube.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10419 		paramsArrayToCube.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10420 		paramsArrayToCube.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10421 		paramsArrayToCube.dst.image.extent			= defaultHalfExtent;
10422 		paramsArrayToCube.dst.image.extent.depth	= arrayLayers;
10423 		paramsArrayToCube.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10424 		paramsArrayToCube.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10425 		paramsArrayToCube.allocationKind			= allocationKind;
10426 		paramsArrayToCube.extensionUse				= extensionUse;
10427 
10428 		{
10429 			const VkImageSubresourceLayers sourceLayer =
10430 				{
10431 					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10432 					0u,								// deUint32				mipLevel;
10433 					0u,								// deUint32				baseArrayLayer;
10434 					arrayLayers						// deUint32				layerCount;
10435 				};
10436 
10437 			const VkImageSubresourceLayers destinationLayer =
10438 				{
10439 					VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10440 					0u,								// deUint32				mipLevel;
10441 					0u,								// deUint32				baseArrayLayer;
10442 					arrayLayers						// deUint32				layerCount;
10443 				};
10444 
10445 			const VkImageCopy				testCopy =
10446 				{
10447 					sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
10448 					{0, 0, 0},						// VkOffset3D				srcOffset;
10449 					destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
10450 					{0, 0, 0},						// VkOffset3D				dstOffset;
10451 					defaultHalfExtent				// VkExtent3D				extent;
10452 				};
10453 
10454 			CopyRegion imageCopy;
10455 			imageCopy.imageCopy = testCopy;
10456 
10457 			paramsArrayToCube.regions.push_back(imageCopy);
10458 		}
10459 
10460 		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_whole", "copy 2d layers to cube compatible image all at once", paramsArrayToCube));
10461 	}
10462 
10463 	{
10464 		TestParams	paramsCubeToArray;
10465 		const deUint32	arrayLayers					= 6u;
10466 		paramsCubeToArray.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10467 		paramsCubeToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
10468 		paramsCubeToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10469 		paramsCubeToArray.src.image.extent			= defaultHalfExtent;
10470 		paramsCubeToArray.src.image.extent.depth	= arrayLayers;
10471 		paramsCubeToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10472 		paramsCubeToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10473 		paramsCubeToArray.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10474 		paramsCubeToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10475 		paramsCubeToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10476 		paramsCubeToArray.dst.image.extent			= defaultHalfExtent;
10477 		paramsCubeToArray.dst.image.extent.depth	= arrayLayers;
10478 		paramsCubeToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10479 		paramsCubeToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10480 		paramsCubeToArray.allocationKind			= allocationKind;
10481 		paramsCubeToArray.extensionUse				= extensionUse;
10482 
10483 		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10484 		{
10485 			const VkImageSubresourceLayers	sourceLayer	=
10486 				{
10487 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10488 					0u,							// deUint32				mipLevel;
10489 					arrayLayersNdx,				// deUint32				baseArrayLayer;
10490 					1u							// deUint32				layerCount;
10491 				};
10492 
10493 			const VkImageSubresourceLayers	destinationLayer	=
10494 				{
10495 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10496 					0u,							// deUint32				mipLevel;
10497 					arrayLayersNdx,				// deUint32				baseArrayLayer;
10498 					1u							// deUint32				layerCount;
10499 				};
10500 
10501 			const VkImageCopy				testCopy	=
10502 				{
10503 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
10504 					{0, 0, 0},					// VkOffset3D				srcOffset;
10505 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
10506 					{0, 0, 0},					// VkOffset3D				dstOffset;
10507 					defaultHalfExtent				// VkExtent3D				extent;
10508 				};
10509 
10510 			CopyRegion	imageCopy;
10511 			imageCopy.imageCopy	= testCopy;
10512 
10513 			paramsCubeToArray.regions.push_back(imageCopy);
10514 		}
10515 
10516 		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_layers", "copy cube compatible image to cube compatible image layer by layer", paramsCubeToArray));
10517 	}
10518 
10519 	{
10520 		TestParams	paramsCubeToCube;
10521 		const deUint32	arrayLayers					= 6u;
10522 		paramsCubeToCube.src.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10523 		paramsCubeToCube.src.image.imageType		= VK_IMAGE_TYPE_2D;
10524 		paramsCubeToCube.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10525 		paramsCubeToCube.src.image.extent			= defaultHalfExtent;
10526 		paramsCubeToCube.src.image.extent.depth		= arrayLayers;
10527 		paramsCubeToCube.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10528 		paramsCubeToCube.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10529 		paramsCubeToCube.dst.image.createFlags		= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
10530 		paramsCubeToCube.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10531 		paramsCubeToCube.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10532 		paramsCubeToCube.dst.image.extent			= defaultHalfExtent;
10533 		paramsCubeToCube.dst.image.extent.depth		= arrayLayers;
10534 		paramsCubeToCube.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10535 		paramsCubeToCube.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10536 		paramsCubeToCube.allocationKind				= allocationKind;
10537 		paramsCubeToCube.extensionUse				= extensionUse;
10538 
10539 		{
10540 			const VkImageSubresourceLayers	sourceLayer	=
10541 				{
10542 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10543 					0u,							// deUint32				mipLevel;
10544 					0u,							// deUint32				baseArrayLayer;
10545 					arrayLayers					// deUint32				layerCount;
10546 				};
10547 
10548 			const VkImageSubresourceLayers	destinationLayer	=
10549 				{
10550 					VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10551 					0u,							// deUint32				mipLevel;
10552 					0u,							// deUint32				baseArrayLayer;
10553 					arrayLayers					// deUint32				layerCount;
10554 				};
10555 
10556 			const VkImageCopy				testCopy	=
10557 				{
10558 					sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
10559 					{0, 0, 0},					// VkOffset3D				srcOffset;
10560 					destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
10561 					{0, 0, 0},					// VkOffset3D				dstOffset;
10562 					defaultHalfExtent			// VkExtent3D				extent;
10563 				};
10564 
10565 			CopyRegion	imageCopy;
10566 			imageCopy.imageCopy	= testCopy;
10567 
10568 			paramsCubeToCube.regions.push_back(imageCopy);
10569 		}
10570 
10571 		group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_whole", "copy cube compatible image to cube compatible image all at once", paramsCubeToCube));
10572 	}
10573 }
10574 
addImageToImageArrayTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10575 void addImageToImageArrayTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10576 {
10577 	tcu::TestContext& testCtx	= group->getTestContext();
10578 
10579 	{
10580 		TestParams	paramsArrayToArray;
10581 		const deUint32	arrayLayers					= 16u;
10582 		paramsArrayToArray.src.image.imageType		= VK_IMAGE_TYPE_2D;
10583 		paramsArrayToArray.src.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10584 		paramsArrayToArray.src.image.extent			= defaultHalfExtent;
10585 		paramsArrayToArray.src.image.extent.depth	= arrayLayers;
10586 		paramsArrayToArray.src.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10587 		paramsArrayToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10588 		paramsArrayToArray.dst.image.imageType		= VK_IMAGE_TYPE_2D;
10589 		paramsArrayToArray.dst.image.format			= VK_FORMAT_R8G8B8A8_UINT;
10590 		paramsArrayToArray.dst.image.extent			= defaultHalfExtent;
10591 		paramsArrayToArray.dst.image.extent.depth	= arrayLayers;
10592 		paramsArrayToArray.dst.image.tiling			= VK_IMAGE_TILING_OPTIMAL;
10593 		paramsArrayToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10594 		paramsArrayToArray.allocationKind			= allocationKind;
10595 		paramsArrayToArray.extensionUse				= extensionUse;
10596 
10597 		for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
10598 		{
10599 			const VkImageSubresourceLayers	sourceLayer	=
10600 					{
10601 							VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10602 							0u,							// deUint32				mipLevel;
10603 							arrayLayersNdx,				// deUint32				baseArrayLayer;
10604 							1u							// deUint32				layerCount;
10605 					};
10606 
10607 			const VkImageSubresourceLayers	destinationLayer =
10608 					{
10609 							VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
10610 							0u,							// deUint32				mipLevel;
10611 							arrayLayersNdx,				// deUint32				baseArrayLayer;
10612 							1u							// deUint32				layerCount;
10613 					};
10614 
10615 			const VkImageCopy				testCopy =
10616 					{
10617 							sourceLayer,				// VkImageSubresourceLayers	srcSubresource;
10618 							{0, 0, 0},					// VkOffset3D				srcOffset;
10619 							destinationLayer,			// VkImageSubresourceLayers	dstSubresource;
10620 							{0, 0, 0},					// VkOffset3D				dstOffset;
10621 							defaultHalfExtent			// VkExtent3D				extent;
10622 					};
10623 
10624 			CopyRegion	imageCopy;
10625 			imageCopy.imageCopy	= testCopy;
10626 
10627 			paramsArrayToArray.regions.push_back(imageCopy);
10628 		}
10629 
10630 		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_layers", "copy 2d array image to 2d array image layer by layer", paramsArrayToArray));
10631 	}
10632 
10633 	{
10634 		TestParams	paramsArrayToArray;
10635 		const deUint32	arrayLayers						= 16u;
10636 		paramsArrayToArray.src.image.imageType			= VK_IMAGE_TYPE_2D;
10637 		paramsArrayToArray.src.image.format				= VK_FORMAT_R8G8B8A8_UINT;
10638 		paramsArrayToArray.src.image.extent				= defaultHalfExtent;
10639 		paramsArrayToArray.src.image.extent.depth		= arrayLayers;
10640 		paramsArrayToArray.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10641 		paramsArrayToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10642 		paramsArrayToArray.dst.image.imageType			= VK_IMAGE_TYPE_2D;
10643 		paramsArrayToArray.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
10644 		paramsArrayToArray.dst.image.extent				= defaultHalfExtent;
10645 		paramsArrayToArray.dst.image.extent.depth		= arrayLayers;
10646 		paramsArrayToArray.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10647 		paramsArrayToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10648 		paramsArrayToArray.allocationKind				= allocationKind;
10649 		paramsArrayToArray.extensionUse					= extensionUse;
10650 
10651 		{
10652 			const VkImageSubresourceLayers sourceLayer =
10653 					{
10654 							VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10655 							0u,								// deUint32				mipLevel;
10656 							0u,								// deUint32				baseArrayLayer;
10657 							arrayLayers						// deUint32				layerCount;
10658 					};
10659 
10660 			const VkImageSubresourceLayers destinationLayer =
10661 					{
10662 							VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10663 							0u,								// deUint32				mipLevel;
10664 							0u,								// deUint32				baseArrayLayer;
10665 							arrayLayers						// deUint32				layerCount;
10666 					};
10667 
10668 			const VkImageCopy				testCopy =
10669 					{
10670 							sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
10671 							{0, 0, 0},						// VkOffset3D				srcOffset;
10672 							destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
10673 							{0, 0, 0},						// VkOffset3D				dstOffset;
10674 							defaultHalfExtent				// VkExtent3D				extent;
10675 					};
10676 
10677 			CopyRegion imageCopy;
10678 			imageCopy.imageCopy = testCopy;
10679 
10680 			paramsArrayToArray.regions.push_back(imageCopy);
10681 		}
10682 
10683 		group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_whole", "copy 2d array image to 2d array image all at once", paramsArrayToArray));
10684 	}
10685 
10686 	{
10687 		TestParams	paramsArrayToArray;
10688 		const deUint32	arrayLayers						= 16u;
10689 		paramsArrayToArray.src.image.imageType			= VK_IMAGE_TYPE_2D;
10690 		paramsArrayToArray.src.image.extent				= defaultHalfExtent;
10691 		paramsArrayToArray.src.image.extent.depth		= arrayLayers;
10692 		paramsArrayToArray.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10693 		paramsArrayToArray.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10694 		paramsArrayToArray.dst.image.imageType			= VK_IMAGE_TYPE_2D;
10695 		paramsArrayToArray.dst.image.extent				= defaultHalfExtent;
10696 		paramsArrayToArray.dst.image.extent.depth		= arrayLayers;
10697 		paramsArrayToArray.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10698 		paramsArrayToArray.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10699 		paramsArrayToArray.allocationKind				= allocationKind;
10700 		paramsArrayToArray.extensionUse					= extensionUse;
10701 		paramsArrayToArray.mipLevels					= deLog2Floor32(deMaxu32(defaultHalfExtent.width, defaultHalfExtent.height)) + 1u;
10702 
10703 		for (deUint32 mipLevelNdx = 0u; mipLevelNdx < paramsArrayToArray.mipLevels; mipLevelNdx++)
10704 		{
10705 			const VkImageSubresourceLayers sourceLayer =
10706 			{
10707 				VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10708 				mipLevelNdx,					// deUint32				mipLevel;
10709 				0u,								// deUint32				baseArrayLayer;
10710 				arrayLayers						// deUint32				layerCount;
10711 			};
10712 
10713 			const VkImageSubresourceLayers destinationLayer =
10714 			{
10715 				VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
10716 				mipLevelNdx,					// deUint32				mipLevel;
10717 				0u,								// deUint32				baseArrayLayer;
10718 				arrayLayers						// deUint32				layerCount;
10719 			};
10720 
10721 			const VkExtent3D extent =
10722 			{
10723 				(deUint32)deMax(defaultHalfExtent.width >> mipLevelNdx, 1),		// deUint32    width;
10724 				(deUint32)deMax(defaultHalfExtent.height >> mipLevelNdx, 1),	// deUint32    height;
10725 				1u,																// deUint32    depth;
10726 			};
10727 
10728 			const VkImageCopy				testCopy =
10729 			{
10730 				sourceLayer,					// VkImageSubresourceLayers	srcSubresource;
10731 				{0, 0, 0},						// VkOffset3D				srcOffset;
10732 				destinationLayer,				// VkImageSubresourceLayers	dstSubresource;
10733 				{0, 0, 0},						// VkOffset3D				dstOffset;
10734 				extent							// VkExtent3D				extent;
10735 			};
10736 
10737 			CopyRegion imageCopy;
10738 			imageCopy.imageCopy = testCopy;
10739 
10740 			paramsArrayToArray.regions.push_back(imageCopy);
10741 		}
10742 
10743 		VkFormat imageFormats [] = { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_S8_UINT};
10744 
10745 		for (deUint32 imageFormatsNdx = 0; imageFormatsNdx < DE_LENGTH_OF_ARRAY(imageFormats); imageFormatsNdx++)
10746 		{
10747 			paramsArrayToArray.src.image.format = imageFormats[imageFormatsNdx];
10748 			paramsArrayToArray.dst.image.format = imageFormats[imageFormatsNdx];
10749 			for (deUint32 regionNdx = 0u; regionNdx < paramsArrayToArray.regions.size(); regionNdx++)
10750 			{
10751 				paramsArrayToArray.regions[regionNdx].imageCopy.srcSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
10752 				paramsArrayToArray.regions[regionNdx].imageCopy.dstSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
10753 			}
10754 			std::ostringstream testName;
10755 			const std::string formatName = getFormatName(imageFormats[imageFormatsNdx]);
10756 			testName << "array_to_array_whole_mipmap_" << de::toLower(formatName.substr(10));
10757 			group->addChild(new CopyImageToImageMipmapTestCase(testCtx, testName.str(), "copy 2d array mipmap image to 2d array mipmap image all at once", paramsArrayToArray));
10758 		}
10759 	}
10760 }
10761 
addImageToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10762 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10763 {
10764 	addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind, extensionUse);
10765 	addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind, extensionUse);
10766 	addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind, extensionUse);
10767 	addTestGroup(group, "dimensions", "Copying operations on different image dimensions", addImageToImageDimensionsTests, allocationKind, extensionUse);
10768 	addTestGroup(group, "cube", "Coping operations on cube compatible images", addImageToImageCubeTests, allocationKind, extensionUse);
10769 	addTestGroup(group, "array", "Copying operations on array of images", addImageToImageArrayTests, allocationKind, extensionUse);
10770 }
10771 
add1dImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10772 void add1dImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10773 {
10774 	tcu::TestContext& testCtx	= group->getTestContext();
10775 
10776 	{
10777 		TestParams	params;
10778 		params.src.image.imageType			= VK_IMAGE_TYPE_1D;
10779 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
10780 		params.src.image.extent				= default1dExtent;
10781 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10782 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10783 		params.dst.buffer.size				= defaultSize;
10784 		params.allocationKind				= allocationKind;
10785 		params.extensionUse					= extensionUse;
10786 
10787 		const VkBufferImageCopy	bufferImageCopy =
10788 		{
10789 			0u,											// VkDeviceSize				bufferOffset;
10790 			0u,											// deUint32					bufferRowLength;
10791 			0u,											// deUint32					bufferImageHeight;
10792 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
10793 			{0, 0, 0},									// VkOffset3D				imageOffset;
10794 			default1dExtent								// VkExtent3D				imageExtent;
10795 		};
10796 		CopyRegion	copyRegion;
10797 		copyRegion.bufferImageCopy = bufferImageCopy;
10798 
10799 		params.regions.push_back(copyRegion);
10800 
10801 		group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
10802 	}
10803 
10804 	{
10805 		TestParams				params;
10806 		deUint32				bufferImageHeight = defaultSize + 1u;
10807 		params.src.image.imageType			= VK_IMAGE_TYPE_1D;
10808 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
10809 		params.src.image.extent				= default1dExtent;
10810 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10811 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10812 		params.dst.buffer.size				= bufferImageHeight;
10813 		params.allocationKind				= allocationKind;
10814 		params.extensionUse					= extensionUse;
10815 
10816 		const VkBufferImageCopy	bufferImageCopy =
10817 		{
10818 			0u,											// VkDeviceSize				bufferOffset;
10819 			0u,											// deUint32					bufferRowLength;
10820 			bufferImageHeight,							// deUint32					bufferImageHeight;
10821 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
10822 			{0, 0, 0},									// VkOffset3D				imageOffset;
10823 			default1dExtent								// VkExtent3D				imageExtent;
10824 		};
10825 		CopyRegion	copyRegion;
10826 		copyRegion.bufferImageCopy = bufferImageCopy;
10827 
10828 		params.regions.push_back(copyRegion);
10829 
10830 		group->addChild(new CopyImageToBufferTestCase(testCtx, "larger_buffer", "Copy from image to a buffer that is larger than necessary", params));
10831 	}
10832 
10833 	{
10834 		TestParams				params;
10835 		deUint32				arrayLayers = 16u;
10836 		params.src.image.imageType = VK_IMAGE_TYPE_1D;
10837 		params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10838 		params.src.image.extent = default1dExtent;
10839 		params.src.image.extent.depth = arrayLayers;
10840 		params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10841 		params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10842 		params.dst.buffer.size = defaultSize * arrayLayers;
10843 		params.allocationKind = allocationKind;
10844 		params.extensionUse = extensionUse;
10845 
10846 		const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
10847 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
10848 		{
10849 			const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
10850 			const VkBufferImageCopy bufferImageCopy =
10851 			{
10852 				offset,													// VkDeviceSize				bufferOffset;
10853 				0u,														// deUint32					bufferRowLength;
10854 				defaultSize,											// deUint32					bufferImageHeight;
10855 				{
10856 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
10857 					0u,												// deUint32				mipLevel;
10858 					arrayLayerNdx,									// deUint32				baseArrayLayer;
10859 					1u,												// deUint32				layerCount;
10860 				},														// VkImageSubresourceLayers	imageSubresource;
10861 				{0, 0, 0},												// VkOffset3D				imageOffset;
10862 				default1dExtent										// VkExtent3D				imageExtent;
10863 			};
10864 			CopyRegion copyRegion;
10865 			copyRegion.bufferImageCopy = bufferImageCopy;
10866 
10867 			params.regions.push_back(copyRegion);
10868 		}
10869 
10870 		group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
10871 	}
10872 
10873 	{
10874 		TestParams				params;
10875 		deUint32				arrayLayers			= 16u;
10876 		deUint32				bufferImageHeight	= defaultSize + 1u;
10877 		params.src.image.imageType			= VK_IMAGE_TYPE_1D;
10878 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
10879 		params.src.image.extent				= default1dExtent;
10880 		params.src.image.extent.depth		= arrayLayers;
10881 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10882 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10883 		params.dst.buffer.size				= bufferImageHeight * arrayLayers;
10884 		params.allocationKind				= allocationKind;
10885 		params.extensionUse					= extensionUse;
10886 
10887 		const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
10888 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
10889 		{
10890 			const VkDeviceSize offset = bufferImageHeight * pixelSize * arrayLayerNdx;
10891 			const VkBufferImageCopy bufferImageCopy =
10892 			{
10893 				offset,													// VkDeviceSize				bufferOffset;
10894 				0u,														// deUint32					bufferRowLength;
10895 				bufferImageHeight,										// deUint32					bufferImageHeight;
10896 				{
10897 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
10898 					0u,												// deUint32				mipLevel;
10899 					arrayLayerNdx,									// deUint32				baseArrayLayer;
10900 					1u,												// deUint32				layerCount;
10901 				},														// VkImageSubresourceLayers	imageSubresource;
10902 				{0, 0, 0},												// VkOffset3D				imageOffset;
10903 				default1dExtent										// VkExtent3D				imageExtent;
10904 			};
10905 			CopyRegion copyRegion;
10906 			copyRegion.bufferImageCopy = bufferImageCopy;
10907 
10908 			params.regions.push_back(copyRegion);
10909 		}
10910 
10911 		group->addChild(new CopyImageToBufferTestCase(testCtx, "array_larger_buffer", "Copy each layer from array to a buffer that is larger than necessary", params));
10912 	}
10913 }
10914 
add2dImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10915 void add2dImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10916 {
10917 	tcu::TestContext& testCtx = group->getTestContext();
10918 
10919 	{
10920 		TestParams	params;
10921 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
10922 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
10923 		params.src.image.extent				= defaultExtent;
10924 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10925 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10926 		params.dst.buffer.size				= defaultSize * defaultSize;
10927 		params.allocationKind				= allocationKind;
10928 		params.extensionUse					= extensionUse;
10929 
10930 		const VkBufferImageCopy	bufferImageCopy	=
10931 		{
10932 			0u,											// VkDeviceSize				bufferOffset;
10933 			0u,											// deUint32					bufferRowLength;
10934 			0u,											// deUint32					bufferImageHeight;
10935 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
10936 			{0, 0, 0},									// VkOffset3D				imageOffset;
10937 			defaultExtent								// VkExtent3D				imageExtent;
10938 		};
10939 		CopyRegion	copyRegion;
10940 		copyRegion.bufferImageCopy	= bufferImageCopy;
10941 
10942 		params.regions.push_back(copyRegion);
10943 
10944 		group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
10945 	}
10946 
10947 	{
10948 		TestParams	params;
10949 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
10950 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
10951 		params.src.image.extent				= defaultExtent;
10952 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10953 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10954 		params.dst.buffer.size				= defaultSize * defaultSize;
10955 		params.allocationKind				= allocationKind;
10956 		params.extensionUse					= extensionUse;
10957 
10958 		const VkBufferImageCopy	bufferImageCopy	=
10959 		{
10960 			defaultSize * defaultHalfSize,				// VkDeviceSize				bufferOffset;
10961 			0u,											// deUint32					bufferRowLength;
10962 			0u,											// deUint32					bufferImageHeight;
10963 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
10964 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
10965 			defaultHalfExtent							// VkExtent3D				imageExtent;
10966 		};
10967 		CopyRegion	copyRegion;
10968 		copyRegion.bufferImageCopy	= bufferImageCopy;
10969 
10970 		params.regions.push_back(copyRegion);
10971 
10972 		group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
10973 	}
10974 
10975 	{
10976 		TestParams	params;
10977 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
10978 		params.src.image.format				= VK_FORMAT_R8_UNORM;
10979 		params.src.image.extent				= defaultExtent;
10980 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
10981 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10982 		params.dst.buffer.size				= defaultSize * defaultSize;
10983 		params.allocationKind				= allocationKind;
10984 		params.extensionUse					= extensionUse;
10985 
10986 		const VkBufferImageCopy	bufferImageCopy	=
10987 		{
10988 			defaultSize * defaultHalfSize + 1u,		// VkDeviceSize				bufferOffset;
10989 			0u,											// deUint32					bufferRowLength;
10990 			0u,											// deUint32					bufferImageHeight;
10991 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
10992 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
10993 			defaultHalfExtent							// VkExtent3D				imageExtent;
10994 		};
10995 		CopyRegion	copyRegion;
10996 		copyRegion.bufferImageCopy	= bufferImageCopy;
10997 
10998 		params.regions.push_back(copyRegion);
10999 
11000 		group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset_relaxed", "Copy from image to buffer with buffer offset not a multiple of 4", params));
11001 	}
11002 
11003 	{
11004 		TestParams	params;
11005 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11006 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11007 		params.src.image.extent				= defaultExtent;
11008 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11009 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11010 		params.dst.buffer.size				= defaultSize * defaultSize;
11011 		params.allocationKind				= allocationKind;
11012 		params.extensionUse					= extensionUse;
11013 
11014 		const int			pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
11015 		const VkDeviceSize	bufferSize	= pixelSize * params.dst.buffer.size;
11016 		const VkDeviceSize	offsetSize	= pixelSize * defaultQuarterSize * defaultQuarterSize;
11017 		deUint32			divisor		= 1;
11018 		for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
11019 		{
11020 			const deUint32			bufferRowLength		= defaultQuarterSize;
11021 			const deUint32			bufferImageHeight	= defaultQuarterSize;
11022 			const VkExtent3D		imageExtent			= {defaultQuarterSize / divisor, defaultQuarterSize, 1};
11023 			DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
11024 			DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
11025 			DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
11026 
11027 			CopyRegion				region;
11028 			const VkBufferImageCopy	bufferImageCopy		=
11029 			{
11030 				offset,						// VkDeviceSize				bufferOffset;
11031 				bufferRowLength,			// deUint32					bufferRowLength;
11032 				bufferImageHeight,			// deUint32					bufferImageHeight;
11033 				defaultSourceLayer,			// VkImageSubresourceLayers	imageSubresource;
11034 				{0, 0, 0},					// VkOffset3D				imageOffset;
11035 				imageExtent					// VkExtent3D				imageExtent;
11036 			};
11037 			region.bufferImageCopy	= bufferImageCopy;
11038 			params.regions.push_back(region);
11039 		}
11040 
11041 		group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
11042 	}
11043 
11044 	{
11045 		TestParams				params;
11046 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11047 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11048 		params.src.image.extent				= defaultExtent;
11049 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11050 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11051 		params.dst.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
11052 		params.allocationKind				= allocationKind;
11053 		params.extensionUse					= extensionUse;
11054 
11055 		const VkBufferImageCopy	bufferImageCopy	=
11056 		{
11057 			0u,											// VkDeviceSize				bufferOffset;
11058 			defaultSize,								// deUint32					bufferRowLength;
11059 			defaultSize,								// deUint32					bufferImageHeight;
11060 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11061 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11062 			defaultHalfExtent							// VkExtent3D				imageExtent;
11063 		};
11064 		CopyRegion				copyRegion;
11065 		copyRegion.bufferImageCopy	= bufferImageCopy;
11066 
11067 		params.regions.push_back(copyRegion);
11068 
11069 		group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
11070 	}
11071 
11072 	{
11073 		TestParams				params;
11074 		deUint32				bufferImageHeight = defaultSize + 1u;
11075 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11076 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11077 		params.src.image.extent				= defaultExtent;
11078 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11079 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11080 		params.dst.buffer.size				= bufferImageHeight * defaultSize;
11081 		params.allocationKind				= allocationKind;
11082 		params.extensionUse					= extensionUse;
11083 
11084 		const VkBufferImageCopy	bufferImageCopy =
11085 		{
11086 			0u,											// VkDeviceSize				bufferOffset;
11087 			defaultSize,								// deUint32					bufferRowLength;
11088 			bufferImageHeight,							// deUint32					bufferImageHeight;
11089 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11090 			{0, 0, 0},										// VkOffset3D				imageOffset;
11091 			defaultExtent								// VkExtent3D				imageExtent;
11092 		};
11093 		CopyRegion				copyRegion;
11094 		copyRegion.bufferImageCopy = bufferImageCopy;
11095 
11096 		params.regions.push_back(copyRegion);
11097 
11098 		group->addChild(new CopyImageToBufferTestCase(testCtx, "larger_buffer", "Copy from image to a buffer that is larger than necessary", params));
11099 	}
11100 
11101 	{
11102 		TestParams				params;
11103 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11104 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11105 		params.src.image.extent				= defaultExtent;
11106 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11107 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
11108 		params.dst.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
11109 		params.allocationKind				= allocationKind;
11110 		params.extensionUse					= extensionUse;
11111 
11112 		const VkBufferImageCopy	bufferImageCopy	=
11113 		{
11114 			defaultQuarterSize,							// VkDeviceSize				bufferOffset;
11115 			defaultSize,								// deUint32					bufferRowLength;
11116 			defaultSize,								// deUint32					bufferImageHeight;
11117 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11118 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11119 			defaultHalfExtent							// VkExtent3D				imageExtent;
11120 		};
11121 		CopyRegion				copyRegion;
11122 		copyRegion.bufferImageCopy	= bufferImageCopy;
11123 
11124 		params.regions.push_back(copyRegion);
11125 
11126 		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));
11127 	}
11128 
11129 	{
11130 		TestParams				params;
11131 		deUint32				arrayLayers = 16u;
11132 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11133 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11134 		params.src.image.extent				= defaultHalfExtent;
11135 		params.src.image.extent.depth		= arrayLayers;
11136 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11137 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11138 		params.dst.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
11139 		params.allocationKind				= allocationKind;
11140 		params.extensionUse					= extensionUse;
11141 
11142 		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
11143 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11144 		{
11145 			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11146 			const VkBufferImageCopy bufferImageCopy =
11147 				{
11148 					offset,													// VkDeviceSize				bufferOffset;
11149 					0u,														// deUint32					bufferRowLength;
11150 					0u,														// deUint32					bufferImageHeight;
11151 					{
11152 						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11153 						0u,												// deUint32				mipLevel;
11154 						arrayLayerNdx,									// deUint32				baseArrayLayer;
11155 						1u,												// deUint32				layerCount;
11156 					},														// VkImageSubresourceLayers	imageSubresource;
11157 					{0, 0, 0},												// VkOffset3D				imageOffset;
11158 					defaultHalfExtent										// VkExtent3D				imageExtent;
11159 				};
11160 			CopyRegion copyRegion;
11161 			copyRegion.bufferImageCopy = bufferImageCopy;
11162 
11163 			params.regions.push_back(copyRegion);
11164 		}
11165 		group->addChild(new CopyImageToBufferTestCase(testCtx, "array", "Copy each layer from array to buffer", params));
11166 	}
11167 
11168 	{
11169 		TestParams				params;
11170 		deUint32				arrayLayers			= 16u;
11171 		deUint32				imageBufferHeight	= defaultHalfSize + 1u;
11172 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11173 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11174 		params.src.image.extent				= defaultHalfExtent;
11175 		params.src.image.extent.depth		= arrayLayers;
11176 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11177 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11178 		params.dst.buffer.size				= defaultHalfSize * imageBufferHeight * arrayLayers;
11179 		params.allocationKind				= allocationKind;
11180 		params.extensionUse					= extensionUse;
11181 
11182 		const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
11183 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11184 		{
11185 			const VkDeviceSize offset = defaultHalfSize * imageBufferHeight * pixelSize * arrayLayerNdx;
11186 			const VkBufferImageCopy bufferImageCopy =
11187 			{
11188 				offset,													// VkDeviceSize				bufferOffset;
11189 				0u,														// deUint32					bufferRowLength;
11190 				imageBufferHeight,										// deUint32					bufferImageHeight;
11191 				{
11192 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11193 					0u,												// deUint32				mipLevel;
11194 					arrayLayerNdx,									// deUint32				baseArrayLayer;
11195 					1u,												// deUint32				layerCount;
11196 				},														// VkImageSubresourceLayers	imageSubresource;
11197 				{0, 0, 0},												// VkOffset3D				imageOffset;
11198 				defaultHalfExtent										// VkExtent3D				imageExtent;
11199 			};
11200 			CopyRegion copyRegion;
11201 			copyRegion.bufferImageCopy = bufferImageCopy;
11202 
11203 			params.regions.push_back(copyRegion);
11204 		}
11205 		group->addChild(new CopyImageToBufferTestCase(testCtx, "array_larger_buffer", "Copy each layer from array to a buffer that is larger than necessary", params));
11206 	}
11207 
11208 	{
11209 		TestParams				params;
11210 		deUint32				arrayLayers = 16u;
11211 		params.src.image.imageType			= VK_IMAGE_TYPE_2D;
11212 		params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11213 		params.src.image.extent				= defaultHalfExtent;
11214 		params.src.image.extent.depth		= arrayLayers;
11215 		params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11216 		params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11217 		params.dst.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
11218 		params.allocationKind				= allocationKind;
11219 		params.extensionUse					= extensionUse;
11220 
11221 		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.src.image.format));
11222 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11223 		{
11224 			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11225 			const VkBufferImageCopy bufferImageCopy =
11226 				{
11227 					offset,													// VkDeviceSize				bufferOffset;
11228 					defaultHalfSize,										// deUint32					bufferRowLength;
11229 					defaultHalfSize,										// deUint32					bufferImageHeight;
11230 					{
11231 						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11232 						0u,												// deUint32				mipLevel;
11233 						arrayLayerNdx,									// deUint32				baseArrayLayer;
11234 						1u,												// deUint32				layerCount;
11235 					},														// VkImageSubresourceLayers	imageSubresource;
11236 					{0, 0, 0},												// VkOffset3D				imageOffset;
11237 					defaultHalfExtent										// VkExtent3D				imageExtent;
11238 				};
11239 			CopyRegion copyRegion;
11240 			copyRegion.bufferImageCopy = bufferImageCopy;
11241 
11242 			params.regions.push_back(copyRegion);
11243 		}
11244 		group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
11245 	}
11246 }
11247 
addImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11248 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11249 {
11250 	addTestGroup(group, "1d_images", "Copying operations on 1d images", add1dImageToBufferTests, allocationKind, extensionUse);
11251 	addTestGroup(group, "2d_images", "Copying operations on 2d images", add2dImageToBufferTests, allocationKind, extensionUse);
11252 }
11253 
addBufferToDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11254 void addBufferToDepthStencilTests(tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11255 {
11256 	tcu::TestContext& testCtx = group->getTestContext();
11257 
11258 	const struct
11259 	{
11260 		const char*		name;
11261 		const VkFormat	format;
11262 	} depthAndStencilFormats[] =
11263 	{
11264 		{ "d16_unorm",				VK_FORMAT_D16_UNORM				},
11265 		{ "x8_d24_unorm_pack32",	VK_FORMAT_X8_D24_UNORM_PACK32	},
11266 		{ "d32_sfloat",				VK_FORMAT_D32_SFLOAT			},
11267 		{ "d16_unorm_s8_uint",		VK_FORMAT_D16_UNORM_S8_UINT		},
11268 		{ "d24_unorm_s8_uint",		VK_FORMAT_D24_UNORM_S8_UINT		},
11269 		{ "d32_sfloat_s8_uint",		VK_FORMAT_D32_SFLOAT_S8_UINT	}
11270 	};
11271 
11272 	const VkImageSubresourceLayers	depthSourceLayer		=
11273 	{
11274 		VK_IMAGE_ASPECT_DEPTH_BIT,	// VkImageAspectFlags	aspectMask;
11275 		0u,							// deUint32				mipLevel;
11276 		0u,							// deUint32				baseArrayLayer;
11277 		1u,							// deUint32				layerCount;
11278 	};
11279 
11280 	const VkBufferImageCopy			bufferDepthCopy			=
11281 	{
11282 		0u,											// VkDeviceSize				bufferOffset;
11283 		0u,											// deUint32					bufferRowLength;
11284 		0u,											// deUint32					bufferImageHeight;
11285 		depthSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11286 		{0, 0, 0},									// VkOffset3D				imageOffset;
11287 		defaultExtent								// VkExtent3D				imageExtent;
11288 	};
11289 
11290 	const VkBufferImageCopy			bufferDepthCopyOffset	=
11291 	{
11292 		32,											// VkDeviceSize				bufferOffset;
11293 		defaultHalfSize + defaultQuarterSize,		// deUint32					bufferRowLength;
11294 		defaultHalfSize + defaultQuarterSize,		// deUint32					bufferImageHeight;
11295 		depthSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11296 		{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11297 		defaultHalfExtent							// VkExtent3D				imageExtent;
11298 	};
11299 
11300 	const VkImageSubresourceLayers	stencilSourceLayer		=
11301 	{
11302 		VK_IMAGE_ASPECT_STENCIL_BIT,	// VkImageAspectFlags	aspectMask;
11303 		0u,								// deUint32				mipLevel;
11304 		0u,								// deUint32				baseArrayLayer;
11305 		1u,								// deUint32				layerCount;
11306 	};
11307 
11308 	const VkBufferImageCopy			bufferStencilCopy		=
11309 	{
11310 		0u,					// VkDeviceSize				bufferOffset;
11311 		0u,					// deUint32					bufferRowLength;
11312 		0u,					// deUint32					bufferImageHeight;
11313 		stencilSourceLayer,	// VkImageSubresourceLayers	imageSubresource;
11314 		{0, 0, 0},			// VkOffset3D				imageOffset;
11315 		defaultExtent		// VkExtent3D				imageExtent;
11316 	};
11317 
11318     const VkBufferImageCopy			bufferStencilCopyOffset	=
11319 	{
11320 		32,											// VkDeviceSize				bufferOffset;
11321 		defaultHalfSize + defaultQuarterSize,		// deUint32					bufferRowLength;
11322 		defaultHalfSize + defaultQuarterSize,		// deUint32					bufferImageHeight;
11323 		stencilSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11324 		{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11325 		defaultHalfExtent							// VkExtent3D				imageExtent;
11326 	};
11327 
11328     const bool						useOffset[]				= {false, true};
11329 
11330 	// Note: Depth stencil tests I want to do
11331 	// Formats: D16, D24S8, D32FS8
11332 	// Test writing each component with separate CopyBufferToImage commands
11333 	// Test writing both components in one CopyBufferToImage command
11334 	// Swap order of writes of Depth & Stencil
11335 	// whole surface, subimages?
11336 	// Similar tests as BufferToImage?
11337 	for (const auto config : depthAndStencilFormats)
11338 		for (const auto offset : useOffset)
11339 		{
11340 			// TODO: Check that this format is supported before creating tests?
11341 			//if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
11342 
11343 			CopyRegion					copyDepthRegion;
11344 			CopyRegion					copyStencilRegion;
11345 			TestParams					params;
11346 			const tcu::TextureFormat	format		= mapVkFormat(config.format);
11347 			const bool					hasDepth	= tcu::hasDepthComponent(format.order);
11348 			const bool					hasStencil	= tcu::hasStencilComponent(format.order);
11349 			std::string					description	= config.name;
11350 
11351 			if (offset)
11352 			{
11353 				copyDepthRegion.bufferImageCopy = bufferDepthCopyOffset;
11354 				copyStencilRegion.bufferImageCopy = bufferStencilCopyOffset;
11355 				description = "buffer_offset_" + description;
11356 				params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
11357 			}
11358 			else
11359 			{
11360 				copyDepthRegion.bufferImageCopy = bufferDepthCopy;
11361 				copyStencilRegion.bufferImageCopy = bufferStencilCopy;
11362 				params.src.buffer.size = defaultSize * defaultSize;
11363 			}
11364 
11365 			params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11366 			params.dst.image.format = config.format;
11367 			params.dst.image.extent = defaultExtent;
11368 			params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11369 			params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11370 			params.allocationKind = allocationKind;
11371 			params.extensionUse = extensionUse;
11372 
11373 			if (hasDepth && hasStencil)
11374 			{
11375 				params.singleCommand = DE_TRUE;
11376 
11377 				params.regions.push_back(copyDepthRegion);
11378 				params.regions.push_back(copyStencilRegion);
11379 
11380 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_DS", "Copy from depth&stencil to image", params));
11381 
11382 				params.singleCommand = DE_FALSE;
11383 
11384 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D_S", "Copy from depth then stencil to image", params));
11385 
11386 				params.regions.clear();
11387 				params.regions.push_back(copyStencilRegion);
11388 				params.regions.push_back(copyDepthRegion);
11389 
11390 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S_D", "Copy from depth then stencil to image", params));
11391 
11392 				params.singleCommand = DE_TRUE;
11393 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_SD", "Copy from depth&stencil to image", params));
11394 			}
11395 
11396 			if (hasStencil)
11397 			{
11398 				params.regions.clear();
11399 				params.regions.push_back(copyStencilRegion);
11400 
11401 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S", "Copy from stencil to image", params));
11402 			}
11403 
11404 			if (hasDepth)
11405 			{
11406 				params.regions.clear();
11407 				params.regions.push_back(copyDepthRegion);
11408 
11409 				group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D", "Copy from depth to image", params));
11410 			}
11411 		}
11412 }
11413 
add1dBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11414 void add1dBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11415 {
11416 	tcu::TestContext& testCtx	= group->getTestContext();
11417 
11418 	{
11419 		TestParams	params;
11420 		params.src.buffer.size				= defaultSize;
11421 		params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
11422 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
11423 		params.dst.image.extent				= default1dExtent;
11424 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11425 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11426 		params.allocationKind				= allocationKind;
11427 		params.extensionUse					= extensionUse;
11428 
11429 		const VkBufferImageCopy	bufferImageCopy =
11430 		{
11431 			0u,											// VkDeviceSize				bufferOffset;
11432 			0u,											// deUint32					bufferRowLength;
11433 			0u,											// deUint32					bufferImageHeight;
11434 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11435 			{0, 0, 0},									// VkOffset3D				imageOffset;
11436 			default1dExtent								// VkExtent3D				imageExtent;
11437 		};
11438 		CopyRegion	copyRegion;
11439 		copyRegion.bufferImageCopy = bufferImageCopy;
11440 
11441 		params.regions.push_back(copyRegion);
11442 
11443 		group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from tightly packed buffer to image", params));
11444 	}
11445 
11446 	{
11447 		TestParams				params;
11448 		deUint32				bufferImageHeight = defaultSize + 1u;
11449 		params.src.buffer.size				= bufferImageHeight;
11450 		params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
11451 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
11452 		params.dst.image.extent				= default1dExtent;
11453 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11454 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11455 		params.allocationKind				= allocationKind;
11456 		params.extensionUse					= extensionUse;
11457 
11458 		const VkBufferImageCopy	bufferImageCopy =
11459 		{
11460 			0u,											// VkDeviceSize				bufferOffset;
11461 			0u,											// deUint32					bufferRowLength;
11462 			bufferImageHeight,							// deUint32					bufferImageHeight;
11463 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11464 			{0, 0, 0},									// VkOffset3D				imageOffset;
11465 			default1dExtent								// VkExtent3D				imageExtent;
11466 		};
11467 		CopyRegion	copyRegion;
11468 		copyRegion.bufferImageCopy = bufferImageCopy;
11469 
11470 		params.regions.push_back(copyRegion);
11471 
11472 		group->addChild(new CopyBufferToImageTestCase(testCtx, "larger_buffer", "Copy from a buffer to image", params));
11473 	}
11474 
11475 	{
11476 		TestParams				params;
11477 		deUint32				arrayLayers = 16u;
11478 		params.src.buffer.size				= defaultSize * arrayLayers;
11479 		params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
11480 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11481 		params.dst.image.extent				= default1dExtent;
11482 		params.dst.image.extent.depth		= arrayLayers;
11483 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11484 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11485 		params.allocationKind				= allocationKind;
11486 		params.extensionUse					= extensionUse;
11487 
11488 		const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11489 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11490 		{
11491 			const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
11492 			const VkBufferImageCopy bufferImageCopy =
11493 			{
11494 				offset,													// VkDeviceSize				bufferOffset;
11495 				0u,														// deUint32					bufferRowLength;
11496 				0u,														// deUint32					bufferImageHeight;
11497 				{
11498 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11499 					0u,												// deUint32				mipLevel;
11500 					arrayLayerNdx,									// deUint32				baseArrayLayer;
11501 					1u,												// deUint32				layerCount;
11502 				},														// VkImageSubresourceLayers	imageSubresource;
11503 				{0, 0, 0},												// VkOffset3D				imageOffset;
11504 				default1dExtent											// VkExtent3D				imageExtent;
11505 			};
11506 			CopyRegion copyRegion;
11507 			copyRegion.bufferImageCopy = bufferImageCopy;
11508 
11509 			params.regions.push_back(copyRegion);
11510 		}
11511 
11512 		group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from a different part of the tightly packed buffer to each layer", params));
11513 	}
11514 
11515 	{
11516 		TestParams				params;
11517 		deUint32				arrayLayers = 16u;
11518 		deUint32				bufferImageHeight = defaultSize + 1u;
11519 		params.src.buffer.size				= defaultSize * arrayLayers;
11520 		params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
11521 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11522 		params.dst.image.extent				= default1dExtent;
11523 		params.dst.image.extent.depth		= arrayLayers;
11524 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11525 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11526 		params.allocationKind				= allocationKind;
11527 		params.extensionUse					= extensionUse;
11528 
11529 		const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11530 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11531 		{
11532 			const VkDeviceSize offset = defaultSize * pixelSize * arrayLayerNdx;
11533 			const VkBufferImageCopy bufferImageCopy =
11534 			{
11535 				offset,													// VkDeviceSize				bufferOffset;
11536 				0u,														// deUint32					bufferRowLength;
11537 				bufferImageHeight,										// deUint32					bufferImageHeight;
11538 				{
11539 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11540 					0u,												// deUint32				mipLevel;
11541 					arrayLayerNdx,									// deUint32				baseArrayLayer;
11542 					1u,												// deUint32				layerCount;
11543 				},														// VkImageSubresourceLayers	imageSubresource;
11544 				{0, 0, 0},												// VkOffset3D				imageOffset;
11545 				default1dExtent											// VkExtent3D				imageExtent;
11546 			};
11547 			CopyRegion copyRegion;
11548 			copyRegion.bufferImageCopy = bufferImageCopy;
11549 
11550 			params.regions.push_back(copyRegion);
11551 		}
11552 
11553 		group->addChild(new CopyBufferToImageTestCase(testCtx, "array_larger_buffer", "Copy from a different part of the buffer to each layer", params));
11554 	}
11555 }
11556 
add2dBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11557 void add2dBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11558 {
11559 	tcu::TestContext& testCtx = group->getTestContext();
11560 
11561 	{
11562 		TestParams	params;
11563 		params.src.buffer.size				= defaultSize * defaultSize;
11564 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11565 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UINT;
11566 		params.dst.image.extent				= defaultExtent;
11567 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11568 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11569 		params.allocationKind				= allocationKind;
11570 		params.extensionUse					= extensionUse;
11571 
11572 		const VkBufferImageCopy	bufferImageCopy	=
11573 		{
11574 			0u,											// VkDeviceSize				bufferOffset;
11575 			0u,											// deUint32					bufferRowLength;
11576 			0u,											// deUint32					bufferImageHeight;
11577 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11578 			{0, 0, 0},									// VkOffset3D				imageOffset;
11579 			defaultExtent								// VkExtent3D				imageExtent;
11580 		};
11581 		CopyRegion	copyRegion;
11582 		copyRegion.bufferImageCopy	= bufferImageCopy;
11583 
11584 		params.regions.push_back(copyRegion);
11585 
11586 		group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
11587 	}
11588 
11589 	{
11590 		TestParams	params;
11591 		params.src.buffer.size				= defaultSize * defaultSize;
11592 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11593 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11594 		params.dst.image.extent				= defaultExtent;
11595 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11596 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11597 		params.allocationKind				= allocationKind;
11598 		params.extensionUse					= extensionUse;
11599 
11600 		CopyRegion	region;
11601 		deUint32	divisor	= 1;
11602 		for (int offset = 0; (offset + defaultQuarterSize / divisor < defaultSize) && (defaultQuarterSize > divisor); offset += defaultQuarterSize / divisor++)
11603 		{
11604 			const VkBufferImageCopy	bufferImageCopy	=
11605 			{
11606 				0u,																// VkDeviceSize				bufferOffset;
11607 				0u,																// deUint32					bufferRowLength;
11608 				0u,																// deUint32					bufferImageHeight;
11609 				defaultSourceLayer,												// VkImageSubresourceLayers	imageSubresource;
11610 				{offset, defaultHalfSize, 0},									// VkOffset3D				imageOffset;
11611 				{defaultQuarterSize / divisor, defaultQuarterSize / divisor, 1}	// VkExtent3D				imageExtent;
11612 			};
11613 			region.bufferImageCopy	= bufferImageCopy;
11614 			params.regions.push_back(region);
11615 		}
11616 
11617 		group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
11618 	}
11619 
11620 	{
11621 		TestParams	params;
11622 		params.src.buffer.size				= defaultSize * defaultSize;
11623 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11624 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11625 		params.dst.image.extent				= defaultExtent;
11626 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11627 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11628 		params.allocationKind				= allocationKind;
11629 		params.extensionUse					= extensionUse;
11630 
11631 		const VkBufferImageCopy	bufferImageCopy	=
11632 		{
11633 			defaultQuarterSize,							// VkDeviceSize				bufferOffset;
11634 			defaultHalfSize + defaultQuarterSize,		// deUint32					bufferRowLength;
11635 			defaultHalfSize + defaultQuarterSize,		// deUint32					bufferImageHeight;
11636 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11637 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11638 			defaultHalfExtent							// VkExtent3D				imageExtent;
11639 		};
11640 		CopyRegion	copyRegion;
11641 		copyRegion.bufferImageCopy	= bufferImageCopy;
11642 
11643 		params.regions.push_back(copyRegion);
11644 
11645 		group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
11646 	}
11647 
11648 	{
11649 		TestParams	params;
11650 		params.src.buffer.size				= defaultSize * defaultSize;
11651 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11652 		params.dst.image.format				= VK_FORMAT_R8_UNORM;
11653 		params.dst.image.extent				= defaultExtent;
11654 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11655 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11656 		params.allocationKind				= allocationKind;
11657 		params.extensionUse					= extensionUse;
11658 
11659 		const VkBufferImageCopy	bufferImageCopy	=
11660 		{
11661 			defaultQuarterSize + 1u,						// VkDeviceSize				bufferOffset;
11662 			defaultHalfSize + defaultQuarterSize,		// deUint32					bufferRowLength;
11663 			defaultHalfSize + defaultQuarterSize,		// deUint32					bufferImageHeight;
11664 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11665 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11666 			defaultHalfExtent							// VkExtent3D				imageExtent;
11667 		};
11668 		CopyRegion	copyRegion;
11669 		copyRegion.bufferImageCopy	= bufferImageCopy;
11670 
11671 		params.regions.push_back(copyRegion);
11672 
11673 		group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset_relaxed", "Copy from buffer to image with buffer offset not a multiple of 4", params));
11674 	}
11675 
11676 	{
11677 		TestParams				params;
11678 		params.src.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
11679 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11680 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11681 		params.dst.image.extent				= defaultExtent;
11682 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11683 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11684 		params.allocationKind				= allocationKind;
11685 		params.extensionUse					= extensionUse;
11686 
11687 		const VkBufferImageCopy	bufferImageCopy	=
11688 		{
11689 			0u,											// VkDeviceSize				bufferOffset;
11690 			defaultSize,								// deUint32					bufferRowLength;
11691 			defaultSize,								// deUint32					bufferImageHeight;
11692 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11693 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11694 			defaultHalfExtent							// VkExtent3D				imageExtent;
11695 		};
11696 		CopyRegion				copyRegion;
11697 		copyRegion.bufferImageCopy	= bufferImageCopy;
11698 
11699 		params.regions.push_back(copyRegion);
11700 
11701 		group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from buffer that is just large enough to contain the accessed elements", params));
11702 	}
11703 
11704 	{
11705 		TestParams				params;
11706 		deUint32				bufferImageHeight = defaultSize + 1u;
11707 		params.src.buffer.size				= defaultSize * bufferImageHeight;
11708 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11709 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11710 		params.dst.image.extent				= defaultExtent;
11711 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11712 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11713 		params.allocationKind				= allocationKind;
11714 		params.extensionUse					= extensionUse;
11715 
11716 		const VkBufferImageCopy	bufferImageCopy	=
11717 		{
11718 			0u,											// VkDeviceSize				bufferOffset;
11719 			defaultSize,								// deUint32					bufferRowLength;
11720 			bufferImageHeight,							// deUint32					bufferImageHeight;
11721 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11722 			{0, 0, 0},										// VkOffset3D				imageOffset;
11723 			defaultHalfExtent							// VkExtent3D				imageExtent;
11724 		};
11725 		CopyRegion				copyRegion;
11726 		copyRegion.bufferImageCopy	= bufferImageCopy;
11727 
11728 		params.regions.push_back(copyRegion);
11729 
11730 		group->addChild(new CopyBufferToImageTestCase(testCtx, "larger_buffer", "Copy from buffer that is larger than necessary to image", params));
11731 	}
11732 
11733 	{
11734 		TestParams				params;
11735 		params.src.buffer.size				= (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultQuarterSize;
11736 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11737 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11738 		params.dst.image.extent				= defaultExtent;
11739 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11740 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11741 		params.allocationKind				= allocationKind;
11742 		params.extensionUse					= extensionUse;
11743 
11744 		const VkBufferImageCopy	bufferImageCopy	=
11745 		{
11746 			defaultQuarterSize,							// VkDeviceSize				bufferOffset;
11747 			defaultSize,								// deUint32					bufferRowLength;
11748 			defaultSize,								// deUint32					bufferImageHeight;
11749 			defaultSourceLayer,							// VkImageSubresourceLayers	imageSubresource;
11750 			{defaultQuarterSize, defaultQuarterSize, 0},	// VkOffset3D				imageOffset;
11751 			defaultHalfExtent							// VkExtent3D				imageExtent;
11752 		};
11753 		CopyRegion				copyRegion;
11754 		copyRegion.bufferImageCopy	= bufferImageCopy;
11755 
11756 		params.regions.push_back(copyRegion);
11757 
11758 		group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from buffer that is just large enough to contain the accessed elements", params));
11759 	}
11760 
11761 	{
11762 		TestParams				params;
11763 		deUint32				arrayLayers = 16u;
11764 		params.src.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
11765 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11766 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11767 		params.dst.image.extent				= defaultHalfExtent;
11768 		params.dst.image.extent.depth		= arrayLayers;
11769 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11770 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11771 		params.allocationKind				= allocationKind;
11772 		params.extensionUse					= extensionUse;
11773 
11774 		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11775 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11776 		{
11777 			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11778 			const VkBufferImageCopy bufferImageCopy =
11779 				{
11780 					offset,													// VkDeviceSize				bufferOffset;
11781 					0u,														// deUint32					bufferRowLength;
11782 					0u,														// deUint32					bufferImageHeight;
11783 					{
11784 						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11785 						0u,												// deUint32				mipLevel;
11786 						arrayLayerNdx,									// deUint32				baseArrayLayer;
11787 						1u,												// deUint32				layerCount;
11788 					},														// VkImageSubresourceLayers	imageSubresource;
11789 					{0, 0, 0},												// VkOffset3D				imageOffset;
11790 					defaultHalfExtent										// VkExtent3D				imageExtent;
11791 				};
11792 			CopyRegion copyRegion;
11793 			copyRegion.bufferImageCopy = bufferImageCopy;
11794 
11795 			params.regions.push_back(copyRegion);
11796 		}
11797 		group->addChild(new CopyBufferToImageTestCase(testCtx, "array", "Copy from a different part of the buffer to each layer", params));
11798 	}
11799 
11800 	{
11801 		TestParams				params;
11802 		deUint32				arrayLayers			= 16u;
11803 		deUint32				bufferImageHeight	= defaultHalfSize + 1u;
11804 		params.src.buffer.size				= defaultHalfSize * bufferImageHeight * arrayLayers;
11805 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11806 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11807 		params.dst.image.extent				= defaultHalfExtent;
11808 		params.dst.image.extent.depth		= arrayLayers;
11809 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11810 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11811 		params.allocationKind				= allocationKind;
11812 		params.extensionUse					= extensionUse;
11813 
11814 		const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11815 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11816 		{
11817 			const VkDeviceSize offset = defaultHalfSize * bufferImageHeight * pixelSize * arrayLayerNdx;
11818 			const VkBufferImageCopy bufferImageCopy =
11819 			{
11820 				offset,													// VkDeviceSize				bufferOffset;
11821 				defaultHalfSize,										// deUint32					bufferRowLength;
11822 				bufferImageHeight,										// deUint32					bufferImageHeight;
11823 				{
11824 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11825 					0u,												// deUint32				mipLevel;
11826 					arrayLayerNdx,									// deUint32				baseArrayLayer;
11827 					1u,												// deUint32				layerCount;
11828 				},														// VkImageSubresourceLayers	imageSubresource;
11829 				{0, 0, 0},												// VkOffset3D				imageOffset;
11830 				defaultHalfExtent										// VkExtent3D				imageExtent;
11831 			};
11832 			CopyRegion copyRegion;
11833 			copyRegion.bufferImageCopy = bufferImageCopy;
11834 
11835 			params.regions.push_back(copyRegion);
11836 		}
11837 		group->addChild(new CopyBufferToImageTestCase(testCtx, "array_larger_buffer", "Copy from different part of buffer to each layer", params));
11838 	}
11839 
11840 	{
11841 		TestParams				params;
11842 		deUint32				arrayLayers = 16u;
11843 		params.src.buffer.size				= defaultHalfSize * defaultHalfSize * arrayLayers;
11844 		params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
11845 		params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
11846 		params.dst.image.extent				= defaultHalfExtent;
11847 		params.dst.image.extent.depth		= arrayLayers;
11848 		params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
11849 		params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
11850 		params.allocationKind				= allocationKind;
11851 		params.extensionUse					= extensionUse;
11852 
11853 		const int pixelSize	= tcu::getPixelSize(mapVkFormat(params.dst.image.format));
11854 		for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
11855 		{
11856 			const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
11857 			const VkBufferImageCopy bufferImageCopy =
11858 				{
11859 					offset,													// VkDeviceSize				bufferOffset;
11860 					defaultHalfSize,										// deUint32					bufferRowLength;
11861 					defaultHalfSize,										// deUint32					bufferImageHeight;
11862 					{
11863 						VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	aspectMask;
11864 						0u,												// deUint32				mipLevel;
11865 						arrayLayerNdx,									// deUint32				baseArrayLayer;
11866 						1u,												// deUint32				layerCount;
11867 					},														// VkImageSubresourceLayers	imageSubresource;
11868 					{0, 0, 0},												// VkOffset3D				imageOffset;
11869 					defaultHalfExtent										// VkExtent3D				imageExtent;
11870 				};
11871 			CopyRegion copyRegion;
11872 			copyRegion.bufferImageCopy = bufferImageCopy;
11873 
11874 			params.regions.push_back(copyRegion);
11875 		}
11876 		group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from different part of tightly sized buffer to each layer", params));
11877 	}
11878 }
11879 
addBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11880 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11881 {
11882 	addTestGroup(group, "1d_images", "Copying operations on 1d images", add1dBufferToImageTests, allocationKind, extensionUse);
11883 	addTestGroup(group, "2d_images", "Copying operations on 2d images", add2dBufferToImageTests, allocationKind, extensionUse);
11884 }
11885 
addBufferToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11886 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11887 {
11888 	tcu::TestContext&				testCtx					= group->getTestContext();
11889 
11890 	{
11891 		TestParams			params;
11892 		params.src.buffer.size	= defaultSize;
11893 		params.dst.buffer.size	= defaultSize;
11894 		params.allocationKind	= allocationKind;
11895 		params.extensionUse		= extensionUse;
11896 
11897 		const VkBufferCopy	bufferCopy	=
11898 		{
11899 			0u,				// VkDeviceSize	srcOffset;
11900 			0u,				// VkDeviceSize	dstOffset;
11901 			defaultSize,	// VkDeviceSize	size;
11902 		};
11903 
11904 		CopyRegion	copyRegion;
11905 		copyRegion.bufferCopy	= bufferCopy;
11906 		params.regions.push_back(copyRegion);
11907 
11908 		group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
11909 	}
11910 
11911 	// Filter is VK_FILTER_NEAREST.
11912 	{
11913 		TestParams			params;
11914 		params.src.buffer.size	= defaultQuarterSize;
11915 		params.dst.buffer.size	= defaultQuarterSize;
11916 		params.allocationKind	= allocationKind;
11917 		params.extensionUse		= extensionUse;
11918 
11919 		const VkBufferCopy	bufferCopy	=
11920 		{
11921 			12u,	// VkDeviceSize	srcOffset;
11922 			4u,		// VkDeviceSize	dstOffset;
11923 			1u,		// VkDeviceSize	size;
11924 		};
11925 
11926 		CopyRegion	copyRegion;
11927 		copyRegion.bufferCopy = bufferCopy;
11928 		params.regions.push_back(copyRegion);
11929 
11930 		group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
11931 	}
11932 
11933 	{
11934 		const deUint32		size		= 16;
11935 		TestParams			params;
11936 		params.src.buffer.size	= size;
11937 		params.dst.buffer.size	= size * (size + 1);
11938 		params.allocationKind	= allocationKind;
11939 		params.extensionUse		= extensionUse;
11940 
11941 		// Copy region with size 1..size
11942 		for (unsigned int i = 1; i <= size; i++)
11943 		{
11944 			const VkBufferCopy	bufferCopy	=
11945 			{
11946 				0,			// VkDeviceSize	srcOffset;
11947 				i * size,	// VkDeviceSize	dstOffset;
11948 				i,			// VkDeviceSize	size;
11949 			};
11950 
11951 			CopyRegion	copyRegion;
11952 			copyRegion.bufferCopy = bufferCopy;
11953 			params.regions.push_back(copyRegion);
11954 		}
11955 
11956 		group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
11957 	}
11958 
11959 	{
11960 		TestParams params;
11961 		params.src.buffer.size	= 32;
11962 		params.dst.buffer.size	= 32;
11963 		params.allocationKind	= allocationKind;
11964 		params.extensionUse		= extensionUse;
11965 
11966 		// Copy four unaligned regions
11967 		for (unsigned int i = 0; i < 4; i++)
11968 		{
11969 			const VkBufferCopy bufferCopy
11970 			{
11971 				3 + i * 3,	// VkDeviceSize	srcOffset;	3  6   9  12
11972 				1 + i * 5,	// VkDeviceSize	dstOffset;	1  6  11  16
11973 				2 + i,		// VkDeviceSize	size;		2  3   4   5
11974 			};
11975 
11976 			CopyRegion copyRegion;
11977 			copyRegion.bufferCopy = bufferCopy;
11978 			params.regions.push_back(copyRegion);
11979 		}
11980 
11981 		group->addChild(new BufferToBufferTestCase(testCtx, "unaligned_regions", "Multiple unaligned regions", params));
11982 	}
11983 }
11984 
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,TestParams & params)11985 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, TestParams& params)
11986 {
11987 	tcu::TestContext& testCtx = group->getTestContext();
11988 
11989 	// Filter is VK_FILTER_NEAREST.
11990 	{
11991 		params.filter					= VK_FILTER_NEAREST;
11992 		const std::string description	= "Nearest filter";
11993 
11994 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
11995 		group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
11996 
11997 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
11998 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
11999 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
12000 
12001 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
12002 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
12003 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
12004 	}
12005 
12006 	// Filter is VK_FILTER_LINEAR.
12007 	{
12008 		params.filter					= VK_FILTER_LINEAR;
12009 		const std::string description	= "Linear filter";
12010 
12011 		params.dst.image.format	= VK_FORMAT_R8G8B8A8_UNORM;
12012 		group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
12013 
12014 		params.dst.image.format	= VK_FORMAT_R32_SFLOAT;
12015 		const std::string	descriptionOfRGBAToR32	(description + " and different formats (R8G8B8A8 -> R32)");
12016 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
12017 
12018 		params.dst.image.format	= VK_FORMAT_B8G8R8A8_UNORM;
12019 		const std::string	descriptionOfRGBAToBGRA	(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
12020 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
12021 	}
12022 
12023 	// Filter is VK_FILTER_CUBIC_EXT.
12024 	// Cubic filtering can only be used with 2D images.
12025 	if (params.dst.image.imageType == VK_IMAGE_TYPE_2D)
12026 	{
12027 		params.filter					= VK_FILTER_CUBIC_EXT;
12028 		const std::string description	= "Cubic filter";
12029 
12030 		params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12031 		group->addChild(new BlitImageTestCase(testCtx, "cubic", description, params));
12032 
12033 		params.dst.image.format = VK_FORMAT_R32_SFLOAT;
12034 		const std::string	descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
12035 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToR32, params));
12036 
12037 		params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
12038 		const std::string	descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
12039 		group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToBGRA, params));
12040 	}
12041 }
12042 
addBlittingImageSimpleWholeTests(tcu::TestCaseGroup * group,TestParams params)12043 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, TestParams params)
12044 {
12045 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12046 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12047 	params.src.image.extent			= defaultExtent;
12048 	params.dst.image.extent			= defaultExtent;
12049 	params.src.image.extent.depth	= imageDepth;
12050 	params.dst.image.extent.depth	= imageDepth;
12051 
12052 	{
12053 		const VkImageBlit imageBlit =
12054 		{
12055 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12056 			{
12057 				{ 0, 0, 0 },
12058 				{ defaultSize, defaultSize, imageDepth }
12059 			},					// VkOffset3D				srcOffsets[2];
12060 
12061 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12062 			{
12063 				{ 0, 0, 0 },
12064 				{ defaultSize, defaultSize, imageDepth }
12065 			}					// VkOffset3D				dstOffset[2];
12066 		};
12067 
12068 		CopyRegion region;
12069 		region.imageBlit = imageBlit;
12070 		params.regions.push_back(region);
12071 	}
12072 
12073 	addBlittingImageSimpleTests(group, params);
12074 }
12075 
addBlittingImageSimpleMirrorXYTests(tcu::TestCaseGroup * group,TestParams params)12076 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, TestParams params)
12077 {
12078 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12079 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12080 	params.src.image.extent			= defaultExtent;
12081 	params.dst.image.extent			= defaultExtent;
12082 	params.src.image.extent.depth	= imageDepth;
12083 	params.dst.image.extent.depth	= imageDepth;
12084 
12085 	{
12086 		const VkImageBlit imageBlit =
12087 		{
12088 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12089 			{
12090 				{0, 0, 0},
12091 				{defaultSize, defaultSize, imageDepth}
12092 			},					// VkOffset3D				srcOffsets[2];
12093 
12094 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12095 			{
12096 				{defaultSize, defaultSize, 0},
12097 				{0, 0, imageDepth}
12098 			}					// VkOffset3D				dstOffset[2];
12099 		};
12100 
12101 		CopyRegion region;
12102 		region.imageBlit = imageBlit;
12103 		params.regions.push_back(region);
12104 	}
12105 
12106 	addBlittingImageSimpleTests(group, params);
12107 }
12108 
addBlittingImageSimpleMirrorXTests(tcu::TestCaseGroup * group,TestParams params)12109 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, TestParams params)
12110 {
12111 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12112 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12113 	params.src.image.extent			= defaultExtent;
12114 	params.dst.image.extent			= defaultExtent;
12115 	params.src.image.extent.depth	= imageDepth;
12116 	params.dst.image.extent.depth	= imageDepth;
12117 
12118 	{
12119 		const VkImageBlit imageBlit =
12120 		{
12121 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12122 			{
12123 				{0, 0, 0},
12124 				{defaultSize, defaultSize, imageDepth}
12125 			},					// VkOffset3D				srcOffsets[2];
12126 
12127 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12128 			{
12129 				{defaultSize, 0, 0},
12130 				{0, defaultSize, imageDepth}
12131 			}					// VkOffset3D				dstOffset[2];
12132 		};
12133 
12134 		CopyRegion region;
12135 		region.imageBlit = imageBlit;
12136 		params.regions.push_back(region);
12137 	}
12138 
12139 	addBlittingImageSimpleTests(group, params);
12140 }
12141 
addBlittingImageSimpleMirrorYTests(tcu::TestCaseGroup * group,TestParams params)12142 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, TestParams params)
12143 {
12144 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12145 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12146 	params.src.image.extent			= defaultExtent;
12147 	params.dst.image.extent			= defaultExtent;
12148 	params.src.image.extent.depth	= imageDepth;
12149 	params.dst.image.extent.depth	= imageDepth;
12150 
12151 	{
12152 		const VkImageBlit imageBlit =
12153 		{
12154 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12155 			{
12156 				{0, 0, 0},
12157 				{defaultSize, defaultSize, imageDepth}
12158 			},					// VkOffset3D				srcOffsets[2];
12159 
12160 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12161 			{
12162 				{0, defaultSize, 0},
12163 				{defaultSize, 0, imageDepth}
12164 			}					// VkOffset3D				dstOffset[2];
12165 		};
12166 
12167 		CopyRegion region;
12168 		region.imageBlit = imageBlit;
12169 		params.regions.push_back(region);
12170 	}
12171 
12172 	addBlittingImageSimpleTests(group, params);
12173 }
12174 
addBlittingImageSimpleMirrorZTests(tcu::TestCaseGroup * group,TestParams params)12175 void addBlittingImageSimpleMirrorZTests (tcu::TestCaseGroup* group, TestParams params)
12176 {
12177 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12178 	DE_ASSERT(params.src.image.imageType == VK_IMAGE_TYPE_3D);
12179 	params.src.image.extent			= defaultExtent;
12180 	params.dst.image.extent			= defaultExtent;
12181 	params.src.image.extent.depth	= defaultSize;
12182 	params.dst.image.extent.depth	= defaultSize;
12183 
12184 	{
12185 		const VkImageBlit imageBlit =
12186 		{
12187 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12188 			{
12189 				{0, 0, 0},
12190 				{defaultSize, defaultSize, defaultSize}
12191 			},					// VkOffset3D				srcOffsets[2];
12192 
12193 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12194 			{
12195 				{0, 0, defaultSize},
12196 				{defaultSize, defaultSize, 0}
12197 			}					// VkOffset3D				dstOffset[2];
12198 		};
12199 
12200 		CopyRegion region;
12201 		region.imageBlit = imageBlit;
12202 		params.regions.push_back(region);
12203 	}
12204 
12205 	addBlittingImageSimpleTests(group, params);
12206 }
12207 
addBlittingImageSimpleMirrorSubregionsTests(tcu::TestCaseGroup * group,TestParams params)12208 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, TestParams params)
12209 {
12210 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12211 	const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12212 	params.src.image.extent			= defaultExtent;
12213 	params.dst.image.extent			= defaultExtent;
12214 	params.src.image.extent.depth	= imageDepth;
12215 	params.dst.image.extent.depth	= imageDepth;
12216 
12217 	// No mirroring.
12218 	{
12219 		const VkImageBlit imageBlit =
12220 		{
12221 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12222 			{
12223 				{0, 0, 0},
12224 				{defaultHalfSize, defaultHalfSize, imageDepth}
12225 			},					// VkOffset3D				srcOffsets[2];
12226 
12227 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12228 			{
12229 				{0, 0, 0},
12230 				{defaultHalfSize, defaultHalfSize, imageDepth}
12231 			}					// VkOffset3D				dstOffset[2];
12232 		};
12233 
12234 		CopyRegion region;
12235 		region.imageBlit = imageBlit;
12236 		params.regions.push_back(region);
12237 	}
12238 
12239 	// Flipping y coordinates.
12240 	{
12241 		const VkImageBlit imageBlit =
12242 		{
12243 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12244 			{
12245 				{defaultHalfSize, 0, 0},
12246 				{defaultSize, defaultHalfSize, imageDepth}
12247 			},					// VkOffset3D				srcOffsets[2];
12248 
12249 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12250 			{
12251 				{defaultHalfSize, defaultHalfSize, 0},
12252 				{defaultSize, 0, imageDepth}
12253 			}					// VkOffset3D				dstOffset[2];
12254 		};
12255 		CopyRegion region;
12256 		region.imageBlit = imageBlit;
12257 		params.regions.push_back(region);
12258 	}
12259 
12260 	// Flipping x coordinates.
12261 	{
12262 		const VkImageBlit imageBlit =
12263 		{
12264 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12265 			{
12266 				{0, defaultHalfSize, 0},
12267 				{defaultHalfSize, defaultSize, imageDepth}
12268 			},					// VkOffset3D				srcOffsets[2];
12269 
12270 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12271 			{
12272 				{defaultHalfSize, defaultHalfSize, 0},
12273 				{0, defaultSize, imageDepth}
12274 			}					// VkOffset3D				dstOffset[2];
12275 		};
12276 
12277 		CopyRegion region;
12278 		region.imageBlit = imageBlit;
12279 		params.regions.push_back(region);
12280 	}
12281 
12282 	// Flipping x and y coordinates.
12283 	{
12284 		const VkImageBlit imageBlit =
12285 		{
12286 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12287 			{
12288 				{defaultHalfSize, defaultHalfSize, 0},
12289 				{defaultSize, defaultSize, imageDepth}
12290 			},					// VkOffset3D				srcOffsets[2];
12291 
12292 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12293 			{
12294 				{defaultSize, defaultSize, 0},
12295 				{defaultHalfSize, defaultHalfSize, imageDepth}
12296 			}					// VkOffset3D				dstOffset[2];
12297 		};
12298 
12299 		CopyRegion region;
12300 		region.imageBlit = imageBlit;
12301 		params.regions.push_back(region);
12302 	}
12303 
12304 	addBlittingImageSimpleTests(group, params);
12305 }
12306 
addBlittingImageSimpleScalingWhole1Tests(tcu::TestCaseGroup * group,TestParams params)12307 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, TestParams params)
12308 {
12309 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12310 	const deInt32	imageDepth		= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12311 	const deInt32	halfImageDepth	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
12312 	params.src.image.extent			= defaultExtent;
12313 	params.dst.image.extent			= defaultHalfExtent;
12314 	params.src.image.extent.depth	= imageDepth;
12315 	params.dst.image.extent.depth	= halfImageDepth;
12316 
12317 	{
12318 		const VkImageBlit imageBlit =
12319 		{
12320 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12321 			{
12322 				{0, 0, 0},
12323 				{defaultSize, defaultSize, imageDepth}
12324 			},					// VkOffset3D					srcOffsets[2];
12325 
12326 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12327 			{
12328 				{0, 0, 0},
12329 				{defaultHalfSize, defaultHalfSize, halfImageDepth}
12330 			}					// VkOffset3D					dstOffset[2];
12331 		};
12332 
12333 		CopyRegion region;
12334 		region.imageBlit = imageBlit;
12335 		params.regions.push_back(region);
12336 	}
12337 
12338 	addBlittingImageSimpleTests(group, params);
12339 }
12340 
addBlittingImageSimpleScalingWhole2Tests(tcu::TestCaseGroup * group,TestParams params)12341 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, TestParams params)
12342 {
12343 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12344 	const deInt32	imageDepth		= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12345 	const deInt32	halfImageDepth	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
12346 	params.src.image.extent			= defaultHalfExtent;
12347 	params.dst.image.extent			= defaultExtent;
12348 	params.src.image.extent.depth	= halfImageDepth;
12349 	params.dst.image.extent.depth	= imageDepth;
12350 
12351 	{
12352 		const VkImageBlit imageBlit =
12353 		{
12354 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12355 			{
12356 				{0, 0, 0},
12357 				{defaultHalfSize, defaultHalfSize, halfImageDepth}
12358 			},					// VkOffset3D					srcOffsets[2];
12359 
12360 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12361 			{
12362 				{0, 0, 0},
12363 				{defaultSize, defaultSize, imageDepth}
12364 			}					// VkOffset3D					dstOffset[2];
12365 		};
12366 
12367 		CopyRegion region;
12368 		region.imageBlit = imageBlit;
12369 		params.regions.push_back(region);
12370 	}
12371 
12372 	addBlittingImageSimpleTests(group, params);
12373 }
12374 
addBlittingImageSimpleScalingAndOffsetTests(tcu::TestCaseGroup * group,TestParams params)12375 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, TestParams params)
12376 {
12377 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12378 	const deInt32	imageDepth		= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
12379 	const deInt32	srcDepthOffset	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultQuarterSize : 0;
12380 	const deInt32	srcDepthSize	= params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultQuarterSize * 3 : 1;
12381 	params.src.image.extent			= defaultExtent;
12382 	params.dst.image.extent			= defaultExtent;
12383 	params.src.image.extent.depth	= imageDepth;
12384 	params.dst.image.extent.depth	= imageDepth;
12385 
12386 	{
12387 		const VkImageBlit imageBlit =
12388 		{
12389 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12390 			{
12391 				{defaultQuarterSize, defaultQuarterSize, srcDepthOffset},
12392 				{defaultQuarterSize*3, defaultQuarterSize*3, srcDepthSize}
12393 			},					// VkOffset3D					srcOffsets[2];
12394 
12395 			defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12396 			{
12397 				{0, 0, 0},
12398 				{defaultSize, defaultSize, imageDepth}
12399 			}					// VkOffset3D					dstOffset[2];
12400 		};
12401 
12402 		CopyRegion region;
12403 		region.imageBlit = imageBlit;
12404 		params.regions.push_back(region);
12405 	}
12406 
12407 	addBlittingImageSimpleTests(group, params);
12408 }
12409 
addBlittingImageSimpleWithoutScalingPartialTests(tcu::TestCaseGroup * group,TestParams params)12410 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, TestParams params)
12411 {
12412 	DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
12413 	const bool is3dBlit = params.src.image.imageType == VK_IMAGE_TYPE_3D;
12414 	params.src.image.extent	= defaultExtent;
12415 	params.dst.image.extent	= defaultExtent;
12416 
12417 	if (is3dBlit)
12418 	{
12419 		params.src.image.extent.depth = defaultSize;
12420 		params.dst.image.extent.depth = defaultSize;
12421 	}
12422 
12423 	{
12424 		CopyRegion region;
12425 		for (int i = 0; i < defaultSize; i += defaultQuarterSize)
12426 		{
12427 			const VkImageBlit imageBlit =
12428 			{
12429 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
12430 				{
12431 					{defaultSize - defaultQuarterSize - i, defaultSize - defaultQuarterSize - i, is3dBlit ? defaultSize - defaultQuarterSize - i : 0},
12432 					{defaultSize - i, defaultSize - i, is3dBlit ? defaultSize - i : 1}
12433 				},					// VkOffset3D					srcOffsets[2];
12434 
12435 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
12436 				{
12437 					{i, i, is3dBlit ? i : 0},
12438 					{i + defaultQuarterSize, i + defaultQuarterSize, is3dBlit ? i + defaultQuarterSize : 1}
12439 				}					// VkOffset3D					dstOffset[2];
12440 			};
12441 			region.imageBlit = imageBlit;
12442 			params.regions.push_back(region);
12443 		}
12444 	}
12445 
12446 	addBlittingImageSimpleTests(group, params);
12447 }
12448 
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12449 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12450 {
12451 	TestParams params;
12452 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
12453 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12454 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12455 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
12456 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12457 	params.allocationKind				= allocationKind;
12458 	params.extensionUse					= extensionUse;
12459 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
12460 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
12461 	addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
12462 	addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, params);
12463 	addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, params);
12464 	addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, params);
12465 	addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
12466 	addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
12467 	addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
12468 	addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
12469 	addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
12470 
12471 	params.src.image.imageType			= VK_IMAGE_TYPE_3D;
12472 	params.dst.image.imageType			= VK_IMAGE_TYPE_3D;
12473 	addTestGroup(group, "whole_3d", "3D blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
12474 	addTestGroup(group, "mirror_xy_3d", "Flipping x and y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXYTests, params);
12475 	addTestGroup(group, "mirror_x_3d", "Flipping x coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXTests, params);
12476 	addTestGroup(group, "mirror_y_3d", "Flipping y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorYTests, params);
12477 	addTestGroup(group, "mirror_z_3d", "Flipping z coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorZTests, params);
12478 	addTestGroup(group, "mirror_subregions_3d", "Mirroring subregions in a 3D image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
12479 	addTestGroup(group, "scaling_whole1_3d", "3D blit a with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
12480 	addTestGroup(group, "scaling_whole2_3d", "3D blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
12481 	addTestGroup(group, "scaling_and_offset_3d", "3D blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
12482 	addTestGroup(group, "without_scaling_partial_3d", "3D blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
12483 }
12484 
12485 enum FilterMaskBits
12486 {
12487 	FILTER_MASK_NEAREST	= 0,			// Always tested.
12488 	FILTER_MASK_LINEAR	= (1u << 0),
12489 	FILTER_MASK_CUBIC	= (1u << 1),
12490 };
12491 
12492 using FilterMask = deUint32;
12493 
makeFilterMask(bool onlyNearest,bool discardCubicFilter)12494 FilterMask makeFilterMask (bool onlyNearest, bool discardCubicFilter)
12495 {
12496 	FilterMask mask = FILTER_MASK_NEAREST;
12497 
12498 	if (!onlyNearest)
12499 	{
12500 		mask |= FILTER_MASK_LINEAR;
12501 		if (!discardCubicFilter)
12502 			mask |= FILTER_MASK_CUBIC;
12503 	}
12504 
12505 	return mask;
12506 }
12507 
12508 struct BlitColorTestParams
12509 {
12510 	TestParams		params;
12511 	const VkFormat*	compatibleFormats;
12512 	FilterMask		testFilters;
12513 };
12514 
isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams & testParams)12515 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
12516 {
12517 	bool result = true;
12518 
12519 	if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
12520 	{
12521 		DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
12522 
12523 		result =
12524 			de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
12525 			de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
12526 	}
12527 
12528 	return result;
12529 }
12530 
12531 const VkFormat	linearOtherImageFormatsToTest[]	=
12532 {
12533 	// From compatibleFormats8Bit
12534 	VK_FORMAT_R4G4_UNORM_PACK8,
12535 	VK_FORMAT_R8_SRGB,
12536 
12537 	// From compatibleFormats16Bit
12538 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
12539 	VK_FORMAT_R16_SFLOAT,
12540 
12541 	// From compatibleFormats24Bit
12542 	VK_FORMAT_R8G8B8_UNORM,
12543 	VK_FORMAT_B8G8R8_SRGB,
12544 
12545 	// From compatibleFormats32Bit
12546 	VK_FORMAT_R8G8B8A8_UNORM,
12547 	VK_FORMAT_R32_SFLOAT,
12548 
12549 	// From compatibleFormats48Bit
12550 	VK_FORMAT_R16G16B16_UNORM,
12551 	VK_FORMAT_R16G16B16_SFLOAT,
12552 
12553 	// From compatibleFormats64Bit
12554 	VK_FORMAT_R16G16B16A16_UNORM,
12555 	VK_FORMAT_R64_SFLOAT,
12556 
12557 	// From compatibleFormats96Bit
12558 	VK_FORMAT_R32G32B32_UINT,
12559 	VK_FORMAT_R32G32B32_SFLOAT,
12560 
12561 	// From compatibleFormats128Bit
12562 	VK_FORMAT_R32G32B32A32_UINT,
12563 	VK_FORMAT_R64G64_SFLOAT,
12564 
12565 	// From compatibleFormats192Bit
12566 	VK_FORMAT_R64G64B64_UINT,
12567 	VK_FORMAT_R64G64B64_SFLOAT,
12568 
12569 	// From compatibleFormats256Bit
12570 	VK_FORMAT_R64G64B64A64_UINT,
12571 	VK_FORMAT_R64G64B64A64_SFLOAT,
12572 };
12573 
getBlitImageTilingLayoutCaseName(VkImageTiling tiling,VkImageLayout layout)12574 std::string getBlitImageTilingLayoutCaseName (VkImageTiling tiling, VkImageLayout layout)
12575 {
12576 	switch (tiling)
12577 	{
12578 		case VK_IMAGE_TILING_OPTIMAL:
12579 			return getImageLayoutCaseName(layout);
12580 		case VK_IMAGE_TILING_LINEAR:
12581 			return "linear";
12582 		default:
12583 			DE_ASSERT(false);
12584 			return "";
12585 	}
12586 }
12587 
addBlittingImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)12588 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
12589 {
12590 	tcu::TestContext& testCtx				= group->getTestContext();
12591 
12592 	FormatSet linearOtherImageFormatsToTestSet;
12593 	const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
12594 	for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter; ++otherImageFormatsIndex)
12595 		linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);
12596 
12597 	const VkImageTiling blitSrcTilings[]	=
12598 	{
12599 		VK_IMAGE_TILING_OPTIMAL,
12600 		VK_IMAGE_TILING_LINEAR,
12601 	};
12602 	const VkImageLayout blitSrcLayouts[]	=
12603 	{
12604 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
12605 		VK_IMAGE_LAYOUT_GENERAL
12606 	};
12607 	const VkImageTiling blitDstTilings[]	=
12608 	{
12609 		VK_IMAGE_TILING_OPTIMAL,
12610 		VK_IMAGE_TILING_LINEAR,
12611 	};
12612 	const VkImageLayout blitDstLayouts[]	=
12613 	{
12614 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
12615 		VK_IMAGE_LAYOUT_GENERAL
12616 	};
12617 
12618 	for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
12619 	{
12620 		testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];
12621 
12622 		for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
12623 		{
12624 			testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
12625 
12626 			// 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
12627 			if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
12628 				continue;
12629 
12630 			for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
12631 			{
12632 				testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];
12633 
12634 				for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
12635 				{
12636 					testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
12637 
12638 					// 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
12639 					if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
12640 						continue;
12641 
12642 					if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
12643 					    (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
12644 						continue;
12645 
12646 					testParams.params.filter			= VK_FILTER_NEAREST;
12647 					const std::string testName			= getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) + "_" +
12648 														  getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
12649 					const std::string description		= "Blit from layout " + getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) +
12650 														  " to " + getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
12651 					group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params));
12652 
12653 					if (testParams.testFilters & FILTER_MASK_LINEAR)
12654 					{
12655 						testParams.params.filter = VK_FILTER_LINEAR;
12656 						group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params));
12657 					}
12658 
12659 					if (testParams.testFilters & FILTER_MASK_CUBIC)
12660 					{
12661 						testParams.params.filter = VK_FILTER_CUBIC_EXT;
12662 						group->addChild(new BlitImageTestCase(testCtx, testName + "_cubic", description, testParams.params));
12663 					}
12664 
12665 					if ((testParams.params.src.image.imageType == VK_IMAGE_TYPE_3D) && !isCompressedFormat(testParams.params.src.image.format))
12666 					{
12667 						const struct
12668 						{
12669 							FillMode	mode;
12670 							const char*	name;
12671 						} modeList[] =
12672 						{
12673 							{ FILL_MODE_BLUE_RED_X, "x" },
12674 							{ FILL_MODE_BLUE_RED_Y, "y" },
12675 							{ FILL_MODE_BLUE_RED_Z, "z" },
12676 						};
12677 
12678 						auto otherParams = testParams;
12679 						otherParams.params.dst.image.fillMode = FILL_MODE_WHITE;
12680 
12681 						for (int i = 0; i < DE_LENGTH_OF_ARRAY(modeList); ++i)
12682 						{
12683 							otherParams.params.src.image.fillMode = modeList[i].mode;
12684 
12685 							otherParams.params.filter = VK_FILTER_LINEAR;
12686 							group->addChild(new BlitImageTestCase(testCtx, testName + "_linear_stripes_" + modeList[i].name, description, otherParams.params));
12687 
12688 							otherParams.params.filter = VK_FILTER_NEAREST;
12689 							group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest_stripes_" + modeList[i].name, description, otherParams.params));
12690 						}
12691 					}
12692 				}
12693 			}
12694 		}
12695 	}
12696 }
12697 
addBlittingImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)12698 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
12699 {
12700 	VkFormat srcFormat = testParams.params.src.image.format;
12701 
12702 	if (testParams.compatibleFormats)
12703 	{
12704 		for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
12705 		{
12706 			testParams.params.dst.image.format	= testParams.compatibleFormats[dstFormatIndex];
12707 			if (!isSupportedByFramework(testParams.params.dst.image.format))
12708 				continue;
12709 
12710 			if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
12711 				continue;
12712 
12713 			const std::string description	= "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
12714 			addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
12715 		}
12716 	}
12717 
12718 	// If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format
12719 	// When testParams.compatibleFormats is not nullptr but format is compressed we also need to add that format
12720 	// as it is not on compatibleFormats list
12721 	if (!testParams.compatibleFormats || isCompressedFormat(srcFormat))
12722 	{
12723 		testParams.params.dst.image.format = srcFormat;
12724 
12725 		const std::string description = "Blit destination format " + getFormatCaseName(srcFormat);
12726 		addTestGroup(group, getFormatCaseName(srcFormat), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
12727 	}
12728 }
12729 
12730 const VkFormat	compatibleFormatsUInts[]	=
12731 {
12732 	VK_FORMAT_R8_UINT,
12733 	VK_FORMAT_R8G8_UINT,
12734 	VK_FORMAT_R8G8B8_UINT,
12735 	VK_FORMAT_B8G8R8_UINT,
12736 	VK_FORMAT_R8G8B8A8_UINT,
12737 	VK_FORMAT_B8G8R8A8_UINT,
12738 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
12739 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
12740 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
12741 	VK_FORMAT_R16_UINT,
12742 	VK_FORMAT_R16G16_UINT,
12743 	VK_FORMAT_R16G16B16_UINT,
12744 	VK_FORMAT_R16G16B16A16_UINT,
12745 	VK_FORMAT_R32_UINT,
12746 	VK_FORMAT_R32G32_UINT,
12747 	VK_FORMAT_R32G32B32_UINT,
12748 	VK_FORMAT_R32G32B32A32_UINT,
12749 	VK_FORMAT_R64_UINT,
12750 	VK_FORMAT_R64G64_UINT,
12751 	VK_FORMAT_R64G64B64_UINT,
12752 	VK_FORMAT_R64G64B64A64_UINT,
12753 
12754 	VK_FORMAT_UNDEFINED
12755 };
12756 const VkFormat	compatibleFormatsSInts[]	=
12757 {
12758 	VK_FORMAT_R8_SINT,
12759 	VK_FORMAT_R8G8_SINT,
12760 	VK_FORMAT_R8G8B8_SINT,
12761 	VK_FORMAT_B8G8R8_SINT,
12762 	VK_FORMAT_R8G8B8A8_SINT,
12763 	VK_FORMAT_B8G8R8A8_SINT,
12764 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
12765 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
12766 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
12767 	VK_FORMAT_R16_SINT,
12768 	VK_FORMAT_R16G16_SINT,
12769 	VK_FORMAT_R16G16B16_SINT,
12770 	VK_FORMAT_R16G16B16A16_SINT,
12771 	VK_FORMAT_R32_SINT,
12772 	VK_FORMAT_R32G32_SINT,
12773 	VK_FORMAT_R32G32B32_SINT,
12774 	VK_FORMAT_R32G32B32A32_SINT,
12775 	VK_FORMAT_R64_SINT,
12776 	VK_FORMAT_R64G64_SINT,
12777 	VK_FORMAT_R64G64B64_SINT,
12778 	VK_FORMAT_R64G64B64A64_SINT,
12779 
12780 	VK_FORMAT_UNDEFINED
12781 };
12782 const VkFormat	compatibleFormatsFloats[]	=
12783 {
12784 	VK_FORMAT_R4G4_UNORM_PACK8,
12785 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
12786 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
12787 	VK_FORMAT_R5G6B5_UNORM_PACK16,
12788 	VK_FORMAT_B5G6R5_UNORM_PACK16,
12789 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
12790 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
12791 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
12792 	VK_FORMAT_R8_UNORM,
12793 	VK_FORMAT_R8_SNORM,
12794 	VK_FORMAT_R8_USCALED,
12795 	VK_FORMAT_R8_SSCALED,
12796 	VK_FORMAT_R8G8_UNORM,
12797 	VK_FORMAT_R8G8_SNORM,
12798 	VK_FORMAT_R8G8_USCALED,
12799 	VK_FORMAT_R8G8_SSCALED,
12800 	VK_FORMAT_R8G8B8_UNORM,
12801 	VK_FORMAT_R8G8B8_SNORM,
12802 	VK_FORMAT_R8G8B8_USCALED,
12803 	VK_FORMAT_R8G8B8_SSCALED,
12804 	VK_FORMAT_B8G8R8_UNORM,
12805 	VK_FORMAT_B8G8R8_SNORM,
12806 	VK_FORMAT_B8G8R8_USCALED,
12807 	VK_FORMAT_B8G8R8_SSCALED,
12808 	VK_FORMAT_R8G8B8A8_UNORM,
12809 	VK_FORMAT_R8G8B8A8_SNORM,
12810 	VK_FORMAT_R8G8B8A8_USCALED,
12811 	VK_FORMAT_R8G8B8A8_SSCALED,
12812 	VK_FORMAT_B8G8R8A8_UNORM,
12813 	VK_FORMAT_B8G8R8A8_SNORM,
12814 	VK_FORMAT_B8G8R8A8_USCALED,
12815 	VK_FORMAT_B8G8R8A8_SSCALED,
12816 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
12817 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
12818 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
12819 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
12820 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
12821 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
12822 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
12823 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
12824 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
12825 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
12826 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
12827 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
12828 	VK_FORMAT_R16_UNORM,
12829 	VK_FORMAT_R16_SNORM,
12830 	VK_FORMAT_R16_USCALED,
12831 	VK_FORMAT_R16_SSCALED,
12832 	VK_FORMAT_R16_SFLOAT,
12833 	VK_FORMAT_R16G16_UNORM,
12834 	VK_FORMAT_R16G16_SNORM,
12835 	VK_FORMAT_R16G16_USCALED,
12836 	VK_FORMAT_R16G16_SSCALED,
12837 	VK_FORMAT_R16G16_SFLOAT,
12838 	VK_FORMAT_R16G16B16_UNORM,
12839 	VK_FORMAT_R16G16B16_SNORM,
12840 	VK_FORMAT_R16G16B16_USCALED,
12841 	VK_FORMAT_R16G16B16_SSCALED,
12842 	VK_FORMAT_R16G16B16_SFLOAT,
12843 	VK_FORMAT_R16G16B16A16_UNORM,
12844 	VK_FORMAT_R16G16B16A16_SNORM,
12845 	VK_FORMAT_R16G16B16A16_USCALED,
12846 	VK_FORMAT_R16G16B16A16_SSCALED,
12847 	VK_FORMAT_R16G16B16A16_SFLOAT,
12848 	VK_FORMAT_R32_SFLOAT,
12849 	VK_FORMAT_R32G32_SFLOAT,
12850 	VK_FORMAT_R32G32B32_SFLOAT,
12851 	VK_FORMAT_R32G32B32A32_SFLOAT,
12852 	VK_FORMAT_R64_SFLOAT,
12853 	VK_FORMAT_R64G64_SFLOAT,
12854 	VK_FORMAT_R64G64B64_SFLOAT,
12855 	VK_FORMAT_R64G64B64A64_SFLOAT,
12856 	VK_FORMAT_B10G11R11_UFLOAT_PACK32,
12857 	VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
12858 
12859 	VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
12860 	VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
12861 
12862 	VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
12863 
12864 	VK_FORMAT_UNDEFINED
12865 };
12866 
12867 const VkFormat	compressedFormatsFloats[] =
12868 {
12869 	VK_FORMAT_BC1_RGB_UNORM_BLOCK,
12870 	VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
12871 	VK_FORMAT_BC2_UNORM_BLOCK,
12872 	VK_FORMAT_BC3_UNORM_BLOCK,
12873 	VK_FORMAT_BC4_UNORM_BLOCK,
12874 	VK_FORMAT_BC4_SNORM_BLOCK,
12875 	VK_FORMAT_BC5_UNORM_BLOCK,
12876 	VK_FORMAT_BC5_SNORM_BLOCK,
12877 	VK_FORMAT_BC6H_UFLOAT_BLOCK,
12878 	VK_FORMAT_BC6H_SFLOAT_BLOCK,
12879 	VK_FORMAT_BC7_UNORM_BLOCK,
12880 	VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
12881 	VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
12882 	VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
12883 	VK_FORMAT_EAC_R11_UNORM_BLOCK,
12884 	VK_FORMAT_EAC_R11_SNORM_BLOCK,
12885 	VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
12886 	VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
12887 	VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
12888 	VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
12889 	VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
12890 	VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
12891 	VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
12892 	VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
12893 	VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
12894 	VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
12895 	VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
12896 	VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
12897 	VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
12898 	VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
12899 	VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
12900 	VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
12901 
12902 	VK_FORMAT_UNDEFINED
12903 };
12904 
12905 const VkFormat	compatibleFormatsSrgb[]		=
12906 {
12907 	VK_FORMAT_R8_SRGB,
12908 	VK_FORMAT_R8G8_SRGB,
12909 	VK_FORMAT_R8G8B8_SRGB,
12910 	VK_FORMAT_B8G8R8_SRGB,
12911 	VK_FORMAT_R8G8B8A8_SRGB,
12912 	VK_FORMAT_B8G8R8A8_SRGB,
12913 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
12914 
12915 	VK_FORMAT_UNDEFINED
12916 };
12917 
12918 const VkFormat	compressedFormatsSrgb[] =
12919 {
12920 	VK_FORMAT_BC1_RGB_SRGB_BLOCK,
12921 	VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
12922 	VK_FORMAT_BC2_SRGB_BLOCK,
12923 	VK_FORMAT_BC3_SRGB_BLOCK,
12924 	VK_FORMAT_BC7_SRGB_BLOCK,
12925 	VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
12926 	VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
12927 	VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
12928 	VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
12929 	VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
12930 	VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
12931 	VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
12932 	VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
12933 	VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
12934 	VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
12935 	VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
12936 	VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
12937 	VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
12938 	VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
12939 	VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
12940 	VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
12941 	VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
12942 
12943 	VK_FORMAT_UNDEFINED
12944 };
12945 
12946 const VkFormat	dedicatedAllocationBlittingFormatsToTest[]	=
12947 {
12948 	// compatibleFormatsUInts
12949 	VK_FORMAT_R8_UINT,
12950 	VK_FORMAT_R64G64B64A64_UINT,
12951 
12952 	// compatibleFormatsSInts
12953 	VK_FORMAT_R8_SINT,
12954 	VK_FORMAT_R64G64B64A64_SINT,
12955 
12956 	// compatibleFormatsFloats
12957 	VK_FORMAT_R4G4_UNORM_PACK8,
12958 	VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
12959 
12960 	// compatibleFormatsSrgb
12961 	VK_FORMAT_R8_SRGB,
12962 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
12963 };
12964 
12965 // skip cubic filtering test for the following data formats
12966 const FormatSet	onlyNearestAndLinearFormatsToTest =
12967 {
12968 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
12969 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
12970 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
12971 	VK_FORMAT_A8B8G8R8_SINT_PACK32
12972 };
12973 
12974 // astc formats have diferent block sizes and thus require diferent resolutions for images
12975 enum class AstcImageSizeType
12976 {
12977 	SIZE_64_64 = 0,
12978 	SIZE_60_64,
12979 	SIZE_64_60,
12980 	SIZE_60_60,
12981 };
12982 
12983 const std::map<VkFormat, AstcImageSizeType> astcSizes
12984 {
12985 	{ VK_FORMAT_ASTC_4x4_SRGB_BLOCK,	AstcImageSizeType::SIZE_64_64 },
12986 	{ VK_FORMAT_ASTC_4x4_UNORM_BLOCK,	AstcImageSizeType::SIZE_64_64 },
12987 	{ VK_FORMAT_ASTC_5x4_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_64 },
12988 	{ VK_FORMAT_ASTC_5x4_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_64 },
12989 	{ VK_FORMAT_ASTC_5x5_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
12990 	{ VK_FORMAT_ASTC_5x5_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
12991 	{ VK_FORMAT_ASTC_6x5_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
12992 	{ VK_FORMAT_ASTC_6x5_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
12993 	{ VK_FORMAT_ASTC_6x6_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
12994 	{ VK_FORMAT_ASTC_6x6_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
12995 	{ VK_FORMAT_ASTC_8x5_SRGB_BLOCK,	AstcImageSizeType::SIZE_64_60 },
12996 	{ VK_FORMAT_ASTC_8x5_UNORM_BLOCK,	AstcImageSizeType::SIZE_64_60 },
12997 	{ VK_FORMAT_ASTC_8x6_SRGB_BLOCK,	AstcImageSizeType::SIZE_64_60 },
12998 	{ VK_FORMAT_ASTC_8x6_UNORM_BLOCK,	AstcImageSizeType::SIZE_64_60 },
12999 	{ VK_FORMAT_ASTC_8x8_SRGB_BLOCK,	AstcImageSizeType::SIZE_64_64 },
13000 	{ VK_FORMAT_ASTC_8x8_UNORM_BLOCK,	AstcImageSizeType::SIZE_64_64 },
13001 	{ VK_FORMAT_ASTC_10x5_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13002 	{ VK_FORMAT_ASTC_10x5_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13003 	{ VK_FORMAT_ASTC_10x6_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13004 	{ VK_FORMAT_ASTC_10x6_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13005 	{ VK_FORMAT_ASTC_10x8_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_64 },
13006 	{ VK_FORMAT_ASTC_10x8_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_64 },
13007 	{ VK_FORMAT_ASTC_10x10_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13008 	{ VK_FORMAT_ASTC_10x10_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13009 	{ VK_FORMAT_ASTC_12x10_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13010 	{ VK_FORMAT_ASTC_12x10_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13011 	{ VK_FORMAT_ASTC_12x12_SRGB_BLOCK,	AstcImageSizeType::SIZE_60_60 },
13012 	{ VK_FORMAT_ASTC_12x12_UNORM_BLOCK,	AstcImageSizeType::SIZE_60_60 }
13013 };
13014 
create2DCopyRegions(deInt32 srcWidth,deInt32 srcHeight,deInt32 dstWidth,deInt32 dstHeight)13015 std::vector<CopyRegion> create2DCopyRegions(deInt32 srcWidth, deInt32 srcHeight, deInt32 dstWidth, deInt32 dstHeight)
13016 {
13017 	CopyRegion				region;
13018 	std::vector<CopyRegion>	regionsVector;
13019 
13020 	deInt32					fourthOfSrcWidth	= srcWidth / 4;
13021 	deInt32					fourthOfSrcHeight	= srcHeight / 4;
13022 	deInt32					fourthOfDstWidth	= dstWidth / 4;
13023 	deInt32					fourthOfDstHeight	= dstHeight / 4;
13024 
13025 	// to the top of resulting image copy whole source image but with increasingly smaller sizes
13026 	for (int i = 0, j = 1; (i + fourthOfDstWidth / j < dstWidth) && (fourthOfDstWidth > j); i += fourthOfDstWidth / j++)
13027 	{
13028 		region.imageBlit =
13029 		{
13030 			defaultSourceLayer,						// VkImageSubresourceLayers		srcSubresource;
13031 			{
13032 				{0, 0, 0},
13033 				{srcWidth, srcHeight, 1}
13034 			},										// VkOffset3D					srcOffsets[2];
13035 
13036 			defaultSourceLayer,						// VkImageSubresourceLayers		dstSubresource;
13037 			{
13038 				{i, 0, 0},
13039 				{i + fourthOfDstWidth / j, fourthOfDstHeight / j, 1}
13040 			}										// VkOffset3D					dstOffset[2];
13041 		};
13042 		regionsVector.push_back(region);
13043 	}
13044 
13045 	// to the bottom of resulting image copy parts of source image;
13046 	for (int i = 0; i < 4; ++i)
13047 	{
13048 		int srcX = i * fourthOfSrcWidth;
13049 		int srcY = i * fourthOfSrcHeight;
13050 		int dstX = i * fourthOfDstWidth;
13051 
13052 		region.imageBlit =
13053 		{
13054 			defaultSourceLayer,						// VkImageSubresourceLayers		srcSubresource;
13055 			{
13056 				{srcX, srcY, 0},
13057 				{srcX + fourthOfSrcWidth, srcY + fourthOfSrcHeight, 1}
13058 			},										// VkOffset3D					srcOffsets[2];
13059 
13060 			defaultSourceLayer,						// VkImageSubresourceLayers		dstSubresource;
13061 			{
13062 				{dstX, 2 * fourthOfDstHeight, 0},
13063 				{dstX + fourthOfDstWidth, 3 * fourthOfDstHeight, 1}
13064 			}										// VkOffset3D					dstOffset[2];
13065 		};
13066 
13067 		regionsVector.push_back(region);
13068 	}
13069 
13070 	return regionsVector;
13071 }
13072 
addBlittingImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13073 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13074 {
13075 	const struct {
13076 		const VkFormat*	sourceFormats;
13077 		const VkFormat*	destinationFormats;
13078 		const bool		onlyNearest;
13079 	}	colorImageFormatsToTestBlit[] =
13080 	{
13081 		{ compatibleFormatsUInts,	compatibleFormatsUInts,		true	},
13082 		{ compatibleFormatsSInts,	compatibleFormatsSInts,		true	},
13083 		{ compatibleFormatsFloats,	compatibleFormatsFloats,	false	},
13084 		{ compressedFormatsFloats,	compatibleFormatsFloats,	false	},
13085 		{ compatibleFormatsSrgb,	compatibleFormatsSrgb,		false	},
13086 		{ compressedFormatsSrgb,	compatibleFormatsSrgb,		false	},
13087 	};
13088 
13089 	const int	numOfColorImageFormatsToTest		= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
13090 
13091 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
13092 	{
13093 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
13094 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
13095 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
13096 	}
13097 
13098 	// 2D tests.
13099 	{
13100 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
13101 
13102 		TestParams	params;
13103 		params.src.image.imageType	= VK_IMAGE_TYPE_2D;
13104 		params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
13105 		params.src.image.extent		= defaultExtent;
13106 		params.dst.image.extent		= defaultExtent;
13107 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13108 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13109 		params.allocationKind		= allocationKind;
13110 		params.extensionUse			= extensionUse;
13111 
13112 		// create all required copy regions
13113 		const std::map<AstcImageSizeType, std::vector<CopyRegion> > imageRegions
13114 		{
13115 			{ AstcImageSizeType::SIZE_64_64, create2DCopyRegions(64, 64,	64, 64) },
13116 			{ AstcImageSizeType::SIZE_60_64, create2DCopyRegions(60, 64,	60, 64) },
13117 			{ AstcImageSizeType::SIZE_64_60, create2DCopyRegions(64, 60,	64, 60) },
13118 			{ AstcImageSizeType::SIZE_60_60, create2DCopyRegions(60, 60,	60, 60) },
13119 		};
13120 
13121 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13122 		{
13123 			const VkFormat*	sourceFormats		= colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
13124 			const VkFormat*	destinationFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].destinationFormats;
13125 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13126 			for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13127 			{
13128 				VkFormat srcFormat		= sourceFormats[srcFormatIndex];
13129 				params.src.image.format = srcFormat;
13130 
13131 				const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
13132 
13133 				// most of tests are using regions caluculated for 64x64 size but astc formats require custom regions
13134 				params.regions = imageRegions.at(AstcImageSizeType::SIZE_64_64);
13135 				if (isCompressedFormat(srcFormat) && isAstcFormat(mapVkCompressedFormat(srcFormat)))
13136 					params.regions = imageRegions.at(astcSizes.at(srcFormat));
13137 
13138 				// use the fact that first region contains the size of full source image
13139 				// and make source and destination the same size - this is needed for astc formats
13140 				const VkOffset3D&	srcImageSize	= params.regions[0].imageBlit.srcOffsets[1];
13141 				VkExtent3D&			srcImageExtent	= params.src.image.extent;
13142 				VkExtent3D&			dstImageExtent	= params.dst.image.extent;
13143 				srcImageExtent.width	= srcImageSize.x;
13144 				srcImageExtent.height	= srcImageSize.y;
13145 				dstImageExtent.width	= srcImageSize.x;
13146 				dstImageExtent.height	= srcImageSize.y;
13147 
13148 				BlitColorTestParams testParams
13149 				{
13150 					params,
13151 					destinationFormats,
13152 					makeFilterMask(onlyNearest, onlyNearestAndLinear)
13153 				};
13154 
13155 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
13156 				addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
13157 			}
13158 		}
13159 
13160 		group->addChild(subGroup.release());
13161 	}
13162 
13163 	// 1D tests.
13164 	{
13165 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
13166 
13167 		TestParams	params;
13168 		params.src.image.imageType	= VK_IMAGE_TYPE_1D;
13169 		params.dst.image.imageType	= VK_IMAGE_TYPE_1D;
13170 		params.src.image.extent		= default1dExtent;
13171 		params.dst.image.extent		= default1dExtent;
13172 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13173 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13174 		params.allocationKind		= allocationKind;
13175 		params.extensionUse			= extensionUse;
13176 
13177 		CopyRegion	region;
13178 		for (int i = 0; i < defaultSize; i += defaultSize / 2)
13179 		{
13180 			const VkImageBlit			imageBlit	=
13181 			{
13182 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
13183 				{
13184 					{0, 0, 0},
13185 					{defaultSize, 1, 1}
13186 				},					// VkOffset3D					srcOffsets[2];
13187 
13188 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
13189 				{
13190 					{i, 0, 0},
13191 					{i + defaultQuarterSize, 1, 1}
13192 				}					// VkOffset3D					dstOffset[2];
13193 			};
13194 			region.imageBlit	= imageBlit;
13195 			params.regions.push_back(region);
13196 		}
13197 
13198 		{
13199 			const VkImageBlit			imageBlit	=
13200 			{
13201 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
13202 				{
13203 					{0, 0, 0},
13204 					{defaultQuarterSize, 1, 1}
13205 				},					// VkOffset3D					srcOffsets[2];
13206 
13207 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
13208 				{
13209 					{defaultQuarterSize, 0, 0},
13210 					{2 * defaultQuarterSize, 1, 1}
13211 				}					// VkOffset3D					dstOffset[2];
13212 			};
13213 			region.imageBlit	= imageBlit;
13214 			params.regions.push_back(region);
13215 		}
13216 
13217 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13218 		{
13219 			const VkFormat*	sourceFormats		= colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
13220 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13221 			for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13222 			{
13223 				params.src.image.format	= sourceFormats[srcFormatIndex];
13224 				if (!isSupportedByFramework(params.src.image.format))
13225 					continue;
13226 
13227 				// Cubic filtering can only be used with 2D images.
13228 				const bool onlyNearestAndLinear	= true;
13229 
13230 				BlitColorTestParams testParams
13231 				{
13232 					params,
13233 					nullptr,
13234 					makeFilterMask(onlyNearest, onlyNearestAndLinear)
13235 				};
13236 
13237 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
13238 				addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
13239 			}
13240 		}
13241 
13242 		group->addChild(subGroup.release());
13243 	}
13244 
13245 	// 3D tests. Note we use smaller dimensions here for performance reasons.
13246 	{
13247 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
13248 
13249 		TestParams	params;
13250 		params.src.image.imageType	= VK_IMAGE_TYPE_3D;
13251 		params.dst.image.imageType	= VK_IMAGE_TYPE_3D;
13252 		params.src.image.extent		= default3dExtent;
13253 		params.dst.image.extent		= default3dExtent;
13254 		params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13255 		params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13256 		params.allocationKind		= allocationKind;
13257 		params.extensionUse			= extensionUse;
13258 
13259 		CopyRegion	region;
13260 		for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultQuarterSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
13261 		{
13262 			const VkImageBlit			imageBlit	=
13263 			{
13264 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
13265 				{
13266 					{0, 0, 0},
13267 					{defaultQuarterSize, defaultQuarterSize, defaultQuarterSize}
13268 				},					// VkOffset3D					srcOffsets[2];
13269 
13270 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
13271 				{
13272 					{i, 0, i},
13273 					{i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j}
13274 				}					// VkOffset3D					dstOffset[2];
13275 			};
13276 			region.imageBlit	= imageBlit;
13277 			params.regions.push_back(region);
13278 		}
13279 		for (int i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
13280 		{
13281 			const VkImageBlit			imageBlit	=
13282 			{
13283 				defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
13284 				{
13285 					{i, i, i},
13286 					{i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize}
13287 				},					// VkOffset3D					srcOffsets[2];
13288 
13289 				defaultSourceLayer,	// VkImageSubresourceLayers	dstSubresource;
13290 				{
13291 					{i, defaultQuarterSize / 2, i},
13292 					{i + defaultSixteenthSize, defaultQuarterSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize}
13293 				}					// VkOffset3D					dstOffset[2];
13294 			};
13295 			region.imageBlit	= imageBlit;
13296 			params.regions.push_back(region);
13297 		}
13298 
13299 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13300 		{
13301 			const VkFormat*	sourceFormats		= colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
13302 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13303 			for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13304 			{
13305 				params.src.image.format	= sourceFormats[srcFormatIndex];
13306 				if (!isSupportedByFramework(params.src.image.format))
13307 					continue;
13308 
13309 				// Cubic filtering can only be used with 2D images.
13310 				const bool onlyNearestAndLinear	= true;
13311 
13312 				BlitColorTestParams testParams
13313 				{
13314 					params,
13315 					nullptr,
13316 					makeFilterMask(onlyNearest, onlyNearestAndLinear)
13317 				};
13318 
13319 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
13320 				addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
13321 			}
13322 		}
13323 
13324 		group->addChild(subGroup.release());
13325 	}
13326 }
13327 
addBlittingImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)13328 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
13329 {
13330 	const VkImageLayout blitSrcLayouts[]	=
13331 	{
13332 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
13333 		VK_IMAGE_LAYOUT_GENERAL
13334 	};
13335 	const VkImageLayout blitDstLayouts[]	=
13336 	{
13337 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
13338 		VK_IMAGE_LAYOUT_GENERAL
13339 	};
13340 
13341 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
13342 	{
13343 		params.src.image.operationLayout	= blitSrcLayouts[srcLayoutNdx];
13344 
13345 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
13346 		{
13347 			params.dst.image.operationLayout	= blitDstLayouts[dstLayoutNdx];
13348 			params.filter						= VK_FILTER_NEAREST;
13349 
13350 			const std::string testName		= getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
13351 											  getImageLayoutCaseName(params.dst.image.operationLayout);
13352 			const std::string description	= "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
13353 											  " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
13354 
13355 			group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params));
13356 		}
13357 	}
13358 }
13359 
addBlittingImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13360 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13361 {
13362 	const VkFormat	depthAndStencilFormats[]	=
13363 	{
13364 		VK_FORMAT_D16_UNORM,
13365 		VK_FORMAT_X8_D24_UNORM_PACK32,
13366 		VK_FORMAT_D32_SFLOAT,
13367 		VK_FORMAT_S8_UINT,
13368 		VK_FORMAT_D16_UNORM_S8_UINT,
13369 		VK_FORMAT_D24_UNORM_S8_UINT,
13370 		VK_FORMAT_D32_SFLOAT_S8_UINT,
13371 	};
13372 
13373 	const VkImageSubresourceLayers	defaultDepthSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
13374 	const VkImageSubresourceLayers	defaultStencilSourceLayer	= { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
13375 	const VkImageSubresourceLayers	defaultDSSourceLayer		= { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
13376 
13377 	// 2D tests
13378 	{
13379 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
13380 
13381 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
13382 		{
13383 			TestParams	params;
13384 			params.src.image.imageType			= VK_IMAGE_TYPE_2D;
13385 			params.src.image.extent				= defaultExtent;
13386 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
13387 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
13388 			params.dst.image.extent				= defaultExtent;
13389 			params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
13390 			params.dst.image.format				= params.src.image.format;
13391 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
13392 			params.allocationKind				= allocationKind;
13393 			params.extensionUse					= extensionUse;
13394 			params.separateDepthStencilLayouts	= DE_FALSE;
13395 
13396 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
13397 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
13398 
13399 			CopyRegion	region;
13400 			for (int i = 0, j = 1; (i + defaultQuarterSize / j < defaultSize) && (defaultQuarterSize > j); i += defaultQuarterSize / j++)
13401 			{
13402 				const VkOffset3D	srcOffset0	= {0, 0, 0};
13403 				const VkOffset3D	srcOffset1	= {defaultSize, defaultSize, 1};
13404 				const VkOffset3D	dstOffset0	= {i, 0, 0};
13405 				const VkOffset3D	dstOffset1	= {i + defaultQuarterSize / j, defaultQuarterSize / j, 1};
13406 
13407 				if (hasDepth)
13408 				{
13409 					const VkImageBlit			imageBlit	=
13410 					{
13411 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13412 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
13413 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13414 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
13415 					};
13416 					region.imageBlit	= imageBlit;
13417 					params.regions.push_back(region);
13418 				}
13419 				if (hasStencil)
13420 				{
13421 					const VkImageBlit			imageBlit	=
13422 					{
13423 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13424 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
13425 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13426 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
13427 					};
13428 					region.imageBlit	= imageBlit;
13429 					params.regions.push_back(region);
13430 				}
13431 			}
13432 			for (int i = 0; i < defaultSize; i += defaultQuarterSize)
13433 			{
13434 				const VkOffset3D	srcOffset0	= {i, i, 0};
13435 				const VkOffset3D	srcOffset1	= {i + defaultQuarterSize, i + defaultQuarterSize, 1};
13436 				const VkOffset3D	dstOffset0	= {i, defaultSize / 2, 0};
13437 				const VkOffset3D	dstOffset1	= {i + defaultQuarterSize, defaultSize / 2 + defaultQuarterSize, 1};
13438 
13439 				if (hasDepth)
13440 				{
13441 					const VkImageBlit			imageBlit	=
13442 					{
13443 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13444 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13445 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13446 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
13447 					};
13448 					region.imageBlit	= imageBlit;
13449 					params.regions.push_back(region);
13450 				}
13451 				if (hasStencil)
13452 				{
13453 					const VkImageBlit			imageBlit	=
13454 					{
13455 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13456 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13457 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13458 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
13459 					};
13460 					region.imageBlit	= imageBlit;
13461 					params.regions.push_back(region);
13462 				}
13463 				if (hasDepth && hasStencil)
13464 				{
13465 					const VkOffset3D			dstDSOffset0	= {i, 3 * defaultQuarterSize, 0};
13466 					const VkOffset3D			dstDSOffset1	= {i + defaultQuarterSize, defaultSize, 1};
13467 					const VkImageBlit			imageBlit	=
13468 					{
13469 						defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
13470 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13471 						defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
13472 						{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
13473 					};
13474 					region.imageBlit	= imageBlit;
13475 					params.regions.push_back(region);
13476 				}
13477 			}
13478 
13479 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
13480 			const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
13481 											" to " + getFormatCaseName(params.dst.image.format);
13482 			addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13483 
13484 			if (hasDepth && hasStencil)
13485 			{
13486 				params.separateDepthStencilLayouts	= DE_TRUE;
13487 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" +
13488 												getFormatCaseName(params.dst.image.format) + "_separate_layouts";
13489 				const std::string description2	= "Blit from " + getFormatCaseName(params.src.image.format) +
13490 												" to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
13491 				addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13492 			}
13493 		}
13494 
13495 		group->addChild(subGroup.release());
13496 	}
13497 
13498 	// 1D tests
13499 	{
13500 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
13501 
13502 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
13503 		{
13504 			TestParams	params;
13505 			params.src.image.imageType			= VK_IMAGE_TYPE_1D;
13506 			params.dst.image.imageType			= VK_IMAGE_TYPE_1D;
13507 			params.src.image.extent				= default1dExtent;
13508 			params.dst.image.extent				= default1dExtent;
13509 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
13510 			params.dst.image.format				= params.src.image.format;
13511 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
13512 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
13513 			params.allocationKind				= allocationKind;
13514 			params.extensionUse					= extensionUse;
13515 
13516 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
13517 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
13518 
13519 			CopyRegion	region;
13520 			for (int i = 0; i < defaultSize; i += defaultSize / 2)
13521 			{
13522 				const VkOffset3D	srcOffset0	= {0, 0, 0};
13523 				const VkOffset3D	srcOffset1	= {defaultSize, 1, 1};
13524 				const VkOffset3D	dstOffset0	= {i, 0, 0};
13525 				const VkOffset3D	dstOffset1	= {i + defaultQuarterSize, 1, 1};
13526 
13527 				if (hasDepth)
13528 				{
13529 					const VkImageBlit			imageBlit	=
13530 					{
13531 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13532 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
13533 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13534 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
13535 					};
13536 					region.imageBlit	= imageBlit;
13537 					params.regions.push_back(region);
13538 				}
13539 				if (hasStencil)
13540 				{
13541 					const VkImageBlit			imageBlit	=
13542 					{
13543 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13544 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
13545 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13546 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
13547 					};
13548 					region.imageBlit	= imageBlit;
13549 					params.regions.push_back(region);
13550 				}
13551 			}
13552 
13553 			{
13554 				const VkOffset3D	srcOffset0	= {0, 0, 0};
13555 				const VkOffset3D	srcOffset1	= {defaultQuarterSize, 1, 1};
13556 				const VkOffset3D	dstOffset0	= {defaultQuarterSize, 0, 0};
13557 				const VkOffset3D	dstOffset1	= {2 * defaultQuarterSize, 1, 1};
13558 
13559 				if (hasDepth)
13560 				{
13561 					const VkImageBlit			imageBlit	=
13562 					{
13563 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13564 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13565 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13566 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
13567 					};
13568 					region.imageBlit	= imageBlit;
13569 					params.regions.push_back(region);
13570 				}
13571 				if (hasStencil)
13572 				{
13573 					const VkImageBlit			imageBlit	=
13574 					{
13575 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13576 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13577 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13578 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
13579 					};
13580 					region.imageBlit	= imageBlit;
13581 					params.regions.push_back(region);
13582 				}
13583 				if (hasDepth && hasStencil)
13584 				{
13585 					const VkOffset3D			dstDSOffset0	= {3 * defaultQuarterSize, 0, 0};
13586 					const VkOffset3D			dstDSOffset1	= {3 * defaultQuarterSize + defaultQuarterSize / 2, 1, 1};
13587 					const VkImageBlit			imageBlit	=
13588 					{
13589 						defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
13590 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13591 						defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
13592 						{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
13593 					};
13594 					region.imageBlit	= imageBlit;
13595 					params.regions.push_back(region);
13596 				}
13597 			}
13598 
13599 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
13600 			const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
13601 											" to " + getFormatCaseName(params.dst.image.format);
13602 			addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13603 
13604 			if (hasDepth && hasStencil)
13605 			{
13606 				params.separateDepthStencilLayouts	= DE_TRUE;
13607 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" +
13608 												getFormatCaseName(params.dst.image.format) + "_separate_layouts";
13609 				const std::string description2	= "Blit from " + getFormatCaseName(params.src.image.format) +
13610 												" to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
13611 				addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13612 			}
13613 		}
13614 
13615 		group->addChild(subGroup.release());
13616 	}
13617 
13618 	// 3D tests. Note we use smaller dimensions here for performance reasons.
13619 	{
13620 		de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
13621 
13622 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
13623 		{
13624 			TestParams	params;
13625 			params.src.image.imageType			= VK_IMAGE_TYPE_3D;
13626 			params.dst.image.imageType			= VK_IMAGE_TYPE_3D;
13627 			params.src.image.extent				= default3dExtent;
13628 			params.dst.image.extent				= default3dExtent;
13629 			params.src.image.format				= depthAndStencilFormats[compatibleFormatsIndex];
13630 			params.dst.image.format				= params.src.image.format;
13631 			params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
13632 			params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
13633 			params.allocationKind				= allocationKind;
13634 			params.extensionUse					= extensionUse;
13635 
13636 			bool hasDepth	= tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
13637 			bool hasStencil	= tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
13638 
13639 			CopyRegion	region;
13640 			for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultQuarterSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
13641 			{
13642 				const VkOffset3D	srcOffset0	= {0, 0, 0};
13643 				const VkOffset3D	srcOffset1	= {defaultQuarterSize, defaultQuarterSize, defaultQuarterSize};
13644 				const VkOffset3D	dstOffset0	= {i, 0, i};
13645 				const VkOffset3D	dstOffset1	= {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j};
13646 
13647 				if (hasDepth)
13648 				{
13649 					const VkImageBlit			imageBlit	=
13650 					{
13651 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13652 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
13653 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13654 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
13655 					};
13656 					region.imageBlit	= imageBlit;
13657 					params.regions.push_back(region);
13658 				}
13659 				if (hasStencil)
13660 				{
13661 					const VkImageBlit			imageBlit	=
13662 					{
13663 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13664 						{ srcOffset0 , srcOffset1 },	// VkOffset3D					srcOffsets[2];
13665 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13666 						{ dstOffset0 , dstOffset1 },	// VkOffset3D					dstOffset[2];
13667 					};
13668 					region.imageBlit	= imageBlit;
13669 					params.regions.push_back(region);
13670 				}
13671 			}
13672 			for (int i = 0; i < defaultQuarterSize; i += defaultSixteenthSize)
13673 			{
13674 				const VkOffset3D	srcOffset0	= {i, i, i};
13675 				const VkOffset3D	srcOffset1	= {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize};
13676 				const VkOffset3D	dstOffset0	= {i, defaultQuarterSize / 2, i};
13677 				const VkOffset3D	dstOffset1	= {i + defaultSixteenthSize, defaultQuarterSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize};
13678 
13679 				if (hasDepth)
13680 				{
13681 					const VkImageBlit			imageBlit	=
13682 					{
13683 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13684 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13685 						defaultDepthSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13686 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
13687 					};
13688 					region.imageBlit	= imageBlit;
13689 					params.regions.push_back(region);
13690 				}
13691 				if (hasStencil)
13692 				{
13693 					const VkImageBlit			imageBlit	=
13694 					{
13695 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	srcSubresource;
13696 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13697 						defaultStencilSourceLayer,		// VkImageSubresourceLayers	dstSubresource;
13698 						{ dstOffset0, dstOffset1 }		// VkOffset3D					dstOffset[2];
13699 					};
13700 					region.imageBlit	= imageBlit;
13701 					params.regions.push_back(region);
13702 				}
13703 				if (hasDepth && hasStencil)
13704 				{
13705 					const VkOffset3D			dstDSOffset0	= {i, 3 * defaultSixteenthSize, i};
13706 					const VkOffset3D			dstDSOffset1	= {i + defaultSixteenthSize, defaultQuarterSize, i + defaultSixteenthSize};
13707 					const VkImageBlit			imageBlit	=
13708 					{
13709 						defaultDSSourceLayer,			// VkImageSubresourceLayers	srcSubresource;
13710 						{ srcOffset0, srcOffset1 },		// VkOffset3D					srcOffsets[2];
13711 						defaultDSSourceLayer,			// VkImageSubresourceLayers	dstSubresource;
13712 						{ dstDSOffset0, dstDSOffset1 }	// VkOffset3D					dstOffset[2];
13713 					};
13714 					region.imageBlit	= imageBlit;
13715 					params.regions.push_back(region);
13716 				}
13717 			}
13718 
13719 			const std::string testName		= getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
13720 			const std::string description	= "Blit from " + getFormatCaseName(params.src.image.format) +
13721 											" to " + getFormatCaseName(params.dst.image.format);
13722 			addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13723 
13724 			if (hasDepth && hasStencil)
13725 			{
13726 				params.separateDepthStencilLayouts	= DE_TRUE;
13727 				const std::string testName2		= getFormatCaseName(params.src.image.format) + "_" +
13728 												getFormatCaseName(params.dst.image.format) + "_separate_layouts";
13729 				const std::string description2	= "Blit from " + getFormatCaseName(params.src.image.format) +
13730 												" to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
13731 				addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
13732 			}
13733 		}
13734 
13735 		group->addChild(subGroup.release());
13736 	}
13737 }
13738 
addBlittingImageAllFormatsMipmapFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)13739 void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
13740 {
13741 	tcu::TestContext& testCtx				= group->getTestContext();
13742 
13743 	const VkImageLayout blitSrcLayouts[]	=
13744 	{
13745 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
13746 		VK_IMAGE_LAYOUT_GENERAL
13747 	};
13748 	const VkImageLayout blitDstLayouts[]	=
13749 	{
13750 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
13751 		VK_IMAGE_LAYOUT_GENERAL
13752 	};
13753 
13754 	for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
13755 	{
13756 		testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
13757 		for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
13758 		{
13759 			testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
13760 
13761 			testParams.params.filter			= VK_FILTER_NEAREST;
13762 			const std::string testName			= getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
13763 												  getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
13764 			const std::string description		= "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
13765 												  " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
13766 			group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params));
13767 
13768 			if (testParams.testFilters & FILTER_MASK_LINEAR)
13769 			{
13770 				testParams.params.filter = VK_FILTER_LINEAR;
13771 				group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params));
13772 			}
13773 
13774 			if (testParams.testFilters & FILTER_MASK_CUBIC)
13775 			{
13776 				testParams.params.filter = VK_FILTER_CUBIC_EXT;
13777 				group->addChild(new BlitMipmapTestCase(testCtx, testName + "_cubic", description, testParams.params));
13778 			}
13779 		}
13780 	}
13781 }
13782 
addBlittingImageAllFormatsBaseLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13783 void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13784 {
13785 	const struct
13786 	{
13787 		const VkFormat* const	compatibleFormats;
13788 		const bool				onlyNearest;
13789 	}	colorImageFormatsToTestBlit[]			=
13790 	{
13791 		{ compatibleFormatsUInts,	true	},
13792 		{ compatibleFormatsSInts,	true	},
13793 		{ compatibleFormatsFloats,	false	},
13794 		{ compatibleFormatsSrgb,	false	},
13795 	};
13796 
13797 	const int	numOfColorImageFormatsToTest	= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
13798 
13799 	const int	layerCountsToTest[]				=
13800 	{
13801 		1,
13802 		6
13803 	};
13804 
13805 	TestParams	params;
13806 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
13807 	params.src.image.extent		= defaultExtent;
13808 	params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13809 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
13810 	params.dst.image.extent		= defaultExtent;
13811 	params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13812 	params.allocationKind		= allocationKind;
13813 	params.extensionUse			= extensionUse;
13814 	params.mipLevels			= deLog2Floor32(deMaxu32(defaultExtent.width, defaultExtent.height)) + 1u;
13815 	params.singleCommand		= DE_TRUE;
13816 
13817 	CopyRegion	region;
13818 	for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
13819 	{
13820 		VkImageSubresourceLayers	destLayer	= defaultSourceLayer;
13821 		destLayer.mipLevel = mipLevelNdx;
13822 
13823 		const VkImageBlit			imageBlit	=
13824 		{
13825 			defaultSourceLayer,	// VkImageSubresourceLayers	srcSubresource;
13826 			{
13827 				{0, 0, 0},
13828 				{defaultSize, defaultSize, 1}
13829 			},					// VkOffset3D					srcOffsets[2];
13830 
13831 			destLayer,			// VkImageSubresourceLayers	dstSubresource;
13832 			{
13833 				{0, 0, 0},
13834 				{defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
13835 			}					// VkOffset3D					dstOffset[2];
13836 		};
13837 		region.imageBlit	= imageBlit;
13838 		params.regions.push_back(region);
13839 	}
13840 
13841 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
13842 	{
13843 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
13844 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
13845 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
13846 	}
13847 
13848 	for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
13849 	{
13850 		const int						layerCount		= layerCountsToTest[layerCountIndex];
13851 		const std::string				layerGroupName	= "layercount_" + de::toString(layerCount);
13852 		const std::string				layerGroupDesc	= "Blit mipmaps with layerCount = " + de::toString(layerCount);
13853 
13854 		de::MovePtr<tcu::TestCaseGroup>	layerCountGroup	(new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
13855 
13856 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13857 		{
13858 			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
13859 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13860 
13861 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13862 			{
13863 				params.src.image.format	= compatibleFormats[srcFormatIndex];
13864 				params.dst.image.format	= compatibleFormats[srcFormatIndex];
13865 
13866 				if (!isSupportedByFramework(params.src.image.format))
13867 					continue;
13868 
13869 				const bool onlyNearestAndLinear	= de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
13870 
13871 				const std::string description	= "Blit source format " + getFormatCaseName(params.src.image.format);
13872 
13873 				BlitColorTestParams testParams;
13874 				testParams.params				= params;
13875 				testParams.compatibleFormats	= compatibleFormats;
13876 				testParams.testFilters			= makeFilterMask(onlyNearest, onlyNearestAndLinear);
13877 
13878 				testParams.params.src.image.extent.depth = layerCount;
13879 				testParams.params.dst.image.extent.depth = layerCount;
13880 
13881 				for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
13882 				{
13883 					testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
13884 					testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
13885 				}
13886 
13887 				addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
13888 			}
13889 		}
13890 		group->addChild(layerCountGroup.release());
13891 	}
13892 }
13893 
addBlittingImageAllFormatsPreviousLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)13894 void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
13895 {
13896 	const struct
13897 	{
13898 		const VkFormat* const	compatibleFormats;
13899 		const bool				onlyNearest;
13900 	}	colorImageFormatsToTestBlit[]			=
13901 	{
13902 		{ compatibleFormatsUInts,	true	},
13903 		{ compatibleFormatsSInts,	true	},
13904 		{ compatibleFormatsFloats,	false	},
13905 		{ compatibleFormatsSrgb,	false	},
13906 	};
13907 
13908 	const int	numOfColorImageFormatsToTest	= DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
13909 
13910 	const int	layerCountsToTest[]				=
13911 	{
13912 		1,
13913 		6
13914 	};
13915 
13916 	TestParams	params;
13917 	params.src.image.imageType	= VK_IMAGE_TYPE_2D;
13918 	params.src.image.extent		= defaultExtent;
13919 	params.src.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13920 	params.dst.image.imageType	= VK_IMAGE_TYPE_2D;
13921 	params.dst.image.extent		= defaultExtent;
13922 	params.dst.image.tiling		= VK_IMAGE_TILING_OPTIMAL;
13923 	params.allocationKind		= allocationKind;
13924 	params.extensionUse			= extensionUse;
13925 	params.mipLevels			= deLog2Floor32(deMaxu32(defaultExtent.width, defaultExtent.height)) + 1u;
13926 	params.singleCommand		= DE_FALSE;
13927 
13928 	CopyRegion	region;
13929 	for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
13930 	{
13931 		VkImageSubresourceLayers	srcLayer	= defaultSourceLayer;
13932 		VkImageSubresourceLayers	destLayer	= defaultSourceLayer;
13933 
13934 		srcLayer.mipLevel	= mipLevelNdx - 1u;
13935 		destLayer.mipLevel	= mipLevelNdx;
13936 
13937 		const VkImageBlit			imageBlit	=
13938 		{
13939 			srcLayer,			// VkImageSubresourceLayers	srcSubresource;
13940 			{
13941 				{0, 0, 0},
13942 				{defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}
13943 			},					// VkOffset3D					srcOffsets[2];
13944 
13945 			destLayer,			// VkImageSubresourceLayers	dstSubresource;
13946 			{
13947 				{0, 0, 0},
13948 				{defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
13949 			}					// VkOffset3D					dstOffset[2];
13950 		};
13951 		region.imageBlit	= imageBlit;
13952 		params.regions.push_back(region);
13953 	}
13954 
13955 	if (allocationKind == ALLOCATION_KIND_DEDICATED)
13956 	{
13957 		const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
13958 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
13959 			dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
13960 	}
13961 
13962 	for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
13963 	{
13964 		const int						layerCount		= layerCountsToTest[layerCountIndex];
13965 		const std::string				layerGroupName	= "layercount_" + de::toString(layerCount);
13966 		const std::string				layerGroupDesc	= "Blit mipmaps with layerCount = " + de::toString(layerCount);
13967 
13968 		de::MovePtr<tcu::TestCaseGroup>	layerCountGroup	(new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
13969 
13970 		for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
13971 		{
13972 			const VkFormat*	compatibleFormats	= colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
13973 			const bool		onlyNearest			= colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
13974 
13975 			for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
13976 			{
13977 				params.src.image.format						= compatibleFormats[srcFormatIndex];
13978 				params.dst.image.format						= compatibleFormats[srcFormatIndex];
13979 
13980 				if (!isSupportedByFramework(params.src.image.format))
13981 					continue;
13982 
13983 				const bool			onlyNearestAndLinear	= de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
13984 
13985 				const std::string	description				= "Blit source format " + getFormatCaseName(params.src.image.format);
13986 
13987 				BlitColorTestParams	testParams;
13988 				testParams.params							= params;
13989 				testParams.compatibleFormats				= compatibleFormats;
13990 				testParams.testFilters						= makeFilterMask(onlyNearest, onlyNearestAndLinear);
13991 
13992 				testParams.params.src.image.extent.depth	= layerCount;
13993 				testParams.params.dst.image.extent.depth	= layerCount;
13994 
13995 				for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
13996 				{
13997 					testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
13998 					testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
13999 				}
14000 
14001 				addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
14002 			}
14003 		}
14004 		group->addChild(layerCountGroup.release());
14005 	}
14006 
14007 	for (int multiLayer = 0; multiLayer < 2; multiLayer++)
14008 	{
14009 		const int layerCount = multiLayer ? 6 : 1;
14010 
14011 		for (int barrierCount = 1; barrierCount < 4; barrierCount++)
14012 		{
14013 			if (layerCount != 1 || barrierCount != 1)
14014 			{
14015 				const std::string				barrierGroupName = (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
14016 				const std::string				barrierGroupDesc = "Use " + de::toString(barrierCount) + " image barriers";
14017 
14018 				de::MovePtr<tcu::TestCaseGroup>	barrierCountGroup(new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str(), barrierGroupDesc.c_str()));
14019 
14020 				params.barrierCount = barrierCount;
14021 
14022 				// Only go through a few common formats
14023 				for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
14024 				{
14025 					params.src.image.format						= compatibleFormatsUInts[srcFormatIndex];
14026 					params.dst.image.format						= compatibleFormatsUInts[srcFormatIndex];
14027 
14028 					if (!isSupportedByFramework(params.src.image.format))
14029 						continue;
14030 
14031 					const std::string description				= "Blit source format " + getFormatCaseName(params.src.image.format);
14032 
14033 					BlitColorTestParams testParams;
14034 					testParams.params							= params;
14035 					testParams.compatibleFormats				= compatibleFormatsUInts;
14036 					testParams.testFilters						= FILTER_MASK_NEAREST;
14037 
14038 					testParams.params.src.image.extent.depth	= layerCount;
14039 					testParams.params.dst.image.extent.depth	= layerCount;
14040 
14041 					for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
14042 					{
14043 						testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
14044 						testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
14045 					}
14046 
14047 					addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
14048 				}
14049 				group->addChild(barrierCountGroup.release());
14050 			}
14051 		}
14052 	}
14053 }
14054 
addBlittingImageAllFormatsMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14055 void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14056 {
14057 	addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind, extensionUse);
14058 	addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind, extensionUse);
14059 }
14060 
addBlittingImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14061 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14062 {
14063 	addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind, extensionUse);
14064 	addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
14065 	addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind, extensionUse);
14066 }
14067 
addBlittingImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14068 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14069 {
14070 	addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind, extensionUse);
14071 	addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind, extensionUse);
14072 }
14073 
14074 const VkSampleCountFlagBits	samples[]		=
14075 {
14076 	VK_SAMPLE_COUNT_2_BIT,
14077 	VK_SAMPLE_COUNT_4_BIT,
14078 	VK_SAMPLE_COUNT_8_BIT,
14079 	VK_SAMPLE_COUNT_16_BIT,
14080 	VK_SAMPLE_COUNT_32_BIT,
14081 	VK_SAMPLE_COUNT_64_BIT
14082 };
14083 const VkExtent3D			resolveExtent	= {256u, 256u, 1};
14084 
addResolveImageWholeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14085 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14086 {
14087 	TestParams	params;
14088 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14089 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14090 	params.src.image.extent				= resolveExtent;
14091 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14092 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14093 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14094 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14095 	params.dst.image.extent				= resolveExtent;
14096 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14097 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14098 	params.allocationKind				= allocationKind;
14099 	params.extensionUse					= extensionUse;
14100 
14101 	{
14102 		const VkImageSubresourceLayers	sourceLayer	=
14103 		{
14104 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14105 			0u,							// deUint32				mipLevel;
14106 			0u,							// deUint32				baseArrayLayer;
14107 			1u							// deUint32				layerCount;
14108 		};
14109 		const VkImageResolve			testResolve	=
14110 		{
14111 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
14112 			{0, 0, 0},		// VkOffset3D				srcOffset;
14113 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
14114 			{0, 0, 0},		// VkOffset3D				dstOffset;
14115 			resolveExtent,	// VkExtent3D				extent;
14116 		};
14117 
14118 		CopyRegion	imageResolve;
14119 		imageResolve.imageResolve	= testResolve;
14120 		params.regions.push_back(imageResolve);
14121 	}
14122 
14123 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14124 	{
14125 		params.imageOffset = false;
14126 		params.samples					= samples[samplesIndex];
14127 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14128 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
14129 		params.imageOffset = true;
14130 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14131 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params));
14132 		}
14133 	}
14134 }
14135 
addResolveImagePartialTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14136 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14137 {
14138 	TestParams	params;
14139 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14140 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14141 	params.src.image.extent				= resolveExtent;
14142 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14143 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14144 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14145 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14146 	params.dst.image.extent				= resolveExtent;
14147 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14148 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14149 	params.allocationKind				= allocationKind;
14150 	params.extensionUse					= extensionUse;
14151 
14152 	{
14153 		const VkImageSubresourceLayers	sourceLayer	=
14154 		{
14155 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14156 			0u,							// deUint32				mipLevel;
14157 			0u,							// deUint32				baseArrayLayer;
14158 			1u							// deUint32				layerCount;
14159 		};
14160 		const VkImageResolve			testResolve	=
14161 		{
14162 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
14163 			{0, 0, 0},		// VkOffset3D				srcOffset;
14164 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
14165 			{64u, 64u, 0},		// VkOffset3D				dstOffset;
14166 			{128u, 128u, 1u},	// VkExtent3D				extent;
14167 		};
14168 
14169 		CopyRegion	imageResolve;
14170 		imageResolve.imageResolve = testResolve;
14171 		params.regions.push_back(imageResolve);
14172 	}
14173 
14174 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14175 	{
14176 		params.samples					= samples[samplesIndex];
14177 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14178 		params.imageOffset = false;
14179 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
14180 		params.imageOffset = true;
14181 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14182 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params));
14183 		}
14184 	}
14185 }
14186 
addResolveImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14187 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14188 {
14189 	TestParams	params;
14190 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14191 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14192 	params.src.image.extent				= resolveExtent;
14193 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14194 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14195 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14196 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14197 	params.dst.image.extent				= resolveExtent;
14198 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14199 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14200 	params.allocationKind				= allocationKind;
14201 	params.extensionUse					= extensionUse;
14202 	params.imageOffset					= allocationKind != ALLOCATION_KIND_DEDICATED;
14203 
14204 	{
14205 		const VkImageSubresourceLayers	sourceLayer	=
14206 		{
14207 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14208 			0u,							// deUint32				mipLevel;
14209 			0u,							// deUint32				baseArrayLayer;
14210 			1u							// deUint32				layerCount;
14211 		};
14212 
14213 		for (int i = 0; i < 256; i += 64)
14214 		{
14215 			const VkImageResolve			testResolve	=
14216 			{
14217 				sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
14218 				{i, i, 0},		// VkOffset3D				srcOffset;
14219 				sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
14220 				{i, 0, 0},		// VkOffset3D				dstOffset;
14221 				{64u, 64u, 1u},	// VkExtent3D				extent;
14222 			};
14223 
14224 			CopyRegion	imageResolve;
14225 			imageResolve.imageResolve = testResolve;
14226 			params.regions.push_back(imageResolve);
14227 		}
14228 	}
14229 
14230 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14231 	{
14232 		params.samples					= samples[samplesIndex];
14233 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14234 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
14235 	}
14236 }
14237 
addResolveImageWholeCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14238 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14239 {
14240 	TestParams	params;
14241 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14242 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14243 	params.src.image.extent				= defaultExtent;
14244 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14245 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14246 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14247 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14248 	params.dst.image.extent				= defaultExtent;
14249 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14250 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14251 	params.allocationKind				= allocationKind;
14252 	params.extensionUse					= extensionUse;
14253 
14254 	{
14255 		const VkImageSubresourceLayers	sourceLayer	=
14256 		{
14257 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14258 			0u,							// deUint32				mipLevel;
14259 			0u,							// deUint32				baseArrayLayer;
14260 			1u							// deUint32				layerCount;
14261 		};
14262 
14263 		const VkImageResolve			testResolve	=
14264 		{
14265 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14266 			{0, 0, 0},			// VkOffset3D				srcOffset;
14267 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14268 			{0, 0, 0},			// VkOffset3D				dstOffset;
14269 			defaultExtent,		// VkExtent3D				extent;
14270 		};
14271 
14272 		CopyRegion	imageResolve;
14273 		imageResolve.imageResolve	= testResolve;
14274 		params.regions.push_back(imageResolve);
14275 	}
14276 
14277 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14278 	{
14279 		params.samples					= samples[samplesIndex];
14280 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14281 		params.imageOffset = false;
14282 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14283 		params.imageOffset = true;
14284 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14285 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14286 		}
14287 	}
14288 }
14289 
addComputeAndTransferQueueTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14290 void addComputeAndTransferQueueTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14291 {
14292 	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)"));
14293 	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)"));
14294 
14295 	TestParams	params;
14296 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14297 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14298 	params.src.image.extent				= defaultExtent;
14299 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14300 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14301 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14302 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14303 	params.dst.image.extent				= defaultExtent;
14304 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14305 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14306 	params.allocationKind				= allocationKind;
14307 	params.extensionUse					= extensionUse;
14308 
14309 	{
14310 		const VkImageSubresourceLayers	sourceLayer	=
14311 		{
14312 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14313 			0u,							// deUint32				mipLevel;
14314 			0u,							// deUint32				baseArrayLayer;
14315 			1u							// deUint32				layerCount;
14316 		};
14317 
14318 		const VkImageResolve			testResolve	=
14319 		{
14320 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14321 			{0, 0, 0},			// VkOffset3D				srcOffset;
14322 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14323 			{0, 0, 0},			// VkOffset3D				dstOffset;
14324 			defaultExtent,		// VkExtent3D				extent;
14325 		};
14326 
14327 		CopyRegion	imageResolve;
14328 		imageResolve.imageResolve	= testResolve;
14329 		params.regions.push_back(imageResolve);
14330 	}
14331 
14332 	for (const auto& sample : samples)
14333 	{
14334 		params.samples					= sample;
14335 		const std::string description	= "With " + getSampleCountCaseName(sample);
14336 		computeGroup->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(sample), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_COMPUTE));
14337 		transferGroup->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(sample), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_TRANSFER));
14338 	}
14339 
14340 	group->addChild(computeGroup.release());
14341 	group->addChild(transferGroup.release());
14342 }
14343 
addResolveImageWholeCopyWithoutCabBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14344 void addResolveImageWholeCopyWithoutCabBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14345 {
14346 	TestParams	params;
14347 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14348 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14349 	params.src.image.extent				= defaultExtent;
14350 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14351 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14352 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14353 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14354 	params.dst.image.extent				= defaultExtent;
14355 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14356 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14357 	params.allocationKind				= allocationKind;
14358 	params.extensionUse					= extensionUse;
14359 
14360 	{
14361 		const VkImageSubresourceLayers	sourceLayer	=
14362 		{
14363 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14364 			0u,							// deUint32				mipLevel;
14365 			0u,							// deUint32				baseArrayLayer;
14366 			1u							// deUint32				layerCount;
14367 		};
14368 
14369 		const VkImageResolve			testResolve	=
14370 		{
14371 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14372 			{0, 0, 0},			// VkOffset3D				srcOffset;
14373 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14374 			{0, 0, 0},			// VkOffset3D				dstOffset;
14375 			defaultExtent,		// VkExtent3D				extent;
14376 		};
14377 
14378 		CopyRegion	imageResolve;
14379 		imageResolve.imageResolve	= testResolve;
14380 		params.regions.push_back(imageResolve);
14381 	}
14382 
14383 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14384 	{
14385 		params.samples					= samples[samplesIndex];
14386 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14387 		params.imageOffset = false;
14388 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
14389 		params.imageOffset = true;
14390 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14391 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
14392 		}
14393 	}
14394 }
14395 
addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14396 void addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14397 {
14398 	TestParams	params;
14399 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14400 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14401 	params.src.image.extent				= defaultExtent;
14402 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14403 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14404 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14405 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14406 	params.dst.image.extent				= defaultExtent;
14407 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14408 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14409 	params.allocationKind				= allocationKind;
14410 	params.extensionUse					= extensionUse;
14411 
14412 	{
14413 		const VkImageSubresourceLayers	sourceLayer	=
14414 		{
14415 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14416 			0u,							// deUint32				mipLevel;
14417 			0u,							// deUint32				baseArrayLayer;
14418 			1u							// deUint32				layerCount;
14419 		};
14420 
14421 		const VkImageResolve			testResolve	=
14422 		{
14423 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14424 			{0, 0, 0},			// VkOffset3D				srcOffset;
14425 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14426 			{0, 0, 0},			// VkOffset3D				dstOffset;
14427 			defaultExtent,		// VkExtent3D				extent;
14428 		};
14429 
14430 		CopyRegion	imageResolve;
14431 		imageResolve.imageResolve	= testResolve;
14432 		params.regions.push_back(imageResolve);
14433 	}
14434 
14435 	const struct
14436 	{
14437 		VkImageLayout	layout;
14438 		std::string		name;
14439 	}	imageLayouts[]			=
14440 	{
14441 		{ VK_IMAGE_LAYOUT_GENERAL,					"general"							},
14442 		{ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,		"transfer_src_optimal"				},
14443 		{ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		"transfer_dst_optimal"				}
14444 	};
14445 
14446 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14447 	for (int srcLayoutIndex = 0; srcLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++srcLayoutIndex)
14448 	for (int dstLayoutIndex = 0; dstLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++dstLayoutIndex)
14449 	{
14450 		params.src.image.operationLayout	= imageLayouts[srcLayoutIndex].layout;
14451 		params.dst.image.operationLayout	= imageLayouts[dstLayoutIndex].layout;
14452 		if (params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
14453 			params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
14454 			continue;
14455 		params.samples						= samples[samplesIndex];
14456 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14457 		std::string testName = getSampleCountCaseName(samples[samplesIndex]) + "_" + imageLayouts[srcLayoutIndex].name + "_" + imageLayouts[dstLayoutIndex].name;
14458 		params.imageOffset = false;
14459 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName, description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14460 		params.imageOffset = true;
14461 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14462 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
14463 		}
14464 	}
14465 }
14466 
addResolveImageLayerCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14467 void addResolveImageLayerCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14468 {
14469 	TestParams	params;
14470 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14471 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14472 	params.src.image.extent				= defaultExtent;
14473 	params.src.image.extent.depth		= 5u;
14474 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14475 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14476 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14477 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14478 	params.dst.image.extent				= defaultExtent;
14479 	params.dst.image.extent.depth		= 5u;
14480 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14481 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14482 	params.allocationKind				= allocationKind;
14483 	params.extensionUse					= extensionUse;
14484 
14485 	for (deUint32 layerNdx=0; layerNdx < params.src.image.extent.depth; ++layerNdx)
14486 	{
14487 		const VkImageSubresourceLayers	sourceLayer	=
14488 		{
14489 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
14490 			0u,								// deUint32				mipLevel;
14491 			layerNdx,						// deUint32				baseArrayLayer;
14492 			1u								// deUint32				layerCount;
14493 		};
14494 
14495 		const VkImageResolve			testResolve	=
14496 		{
14497 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14498 			{0, 0, 0},			// VkOffset3D				srcOffset;
14499 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14500 			{0, 0, 0},			// VkOffset3D				dstOffset;
14501 			defaultExtent,		// VkExtent3D				extent;
14502 		};
14503 
14504 		CopyRegion	imageResolve;
14505 		imageResolve.imageResolve	= testResolve;
14506 		params.regions.push_back(imageResolve);
14507 	}
14508 
14509 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14510 	{
14511 		params.samples					= samples[samplesIndex];
14512 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14513 		params.imageOffset = false;
14514 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
14515 		params.imageOffset = true;
14516 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14517 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
14518 		}
14519 	}
14520 }
14521 
addResolveCopyImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14522 void addResolveCopyImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14523 {
14524 	TestParams	params;
14525 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14526 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14527 	params.src.image.extent				= resolveExtent;
14528 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14529 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14530 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14531 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14532 	params.dst.image.extent				= resolveExtent;
14533 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14534 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14535 	params.allocationKind				= allocationKind;
14536 	params.extensionUse					= extensionUse;
14537 
14538 	int32_t		imageHalfWidth	= getExtent3D(params.src.image).width / 2;
14539 	int32_t		imageHalfHeight	= getExtent3D(params.src.image).height / 2;
14540 	VkExtent3D	halfImageExtent	= {resolveExtent.width / 2, resolveExtent.height / 2, 1u};
14541 
14542 	// Lower right corner to lower left corner.
14543 	{
14544 		const VkImageSubresourceLayers	sourceLayer	=
14545 		{
14546 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
14547 			0u,								// deUint32				mipLevel;
14548 			0u,								// deUint32				baseArrayLayer;
14549 			1u								// deUint32				layerCount;
14550 		};
14551 
14552 		const VkImageResolve			testResolve	=
14553 		{
14554 			sourceLayer,							// VkImageSubresourceLayers	srcSubresource;
14555 			{imageHalfWidth, imageHalfHeight, 0},	// VkOffset3D				srcOffset;
14556 			sourceLayer,							// VkImageSubresourceLayers	dstSubresource;
14557 			{0, imageHalfHeight, 0},				// VkOffset3D				dstOffset;
14558 			halfImageExtent,									// VkExtent3D				extent;
14559 		};
14560 
14561 		CopyRegion	imageResolve;
14562 		imageResolve.imageResolve	= testResolve;
14563 		params.regions.push_back(imageResolve);
14564 	}
14565 
14566 	// Upper right corner to lower right corner.
14567 	{
14568 		const VkImageSubresourceLayers	sourceLayer	=
14569 		{
14570 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
14571 			0u,								// deUint32				mipLevel;
14572 			0u,								// deUint32				baseArrayLayer;
14573 			1u								// deUint32				layerCount;
14574 		};
14575 
14576 		const VkImageResolve			testResolve	=
14577 		{
14578 			sourceLayer,							// VkImageSubresourceLayers	srcSubresource;
14579 			{imageHalfWidth, 0, 0},					// VkOffset3D				srcOffset;
14580 			sourceLayer,							// VkImageSubresourceLayers	dstSubresource;
14581 			{imageHalfWidth, imageHalfHeight, 0},	// VkOffset3D				dstOffset;
14582 			halfImageExtent,									// VkExtent3D				extent;
14583 		};
14584 
14585 		CopyRegion	imageResolve;
14586 		imageResolve.imageResolve	= testResolve;
14587 		params.regions.push_back(imageResolve);
14588 	}
14589 
14590 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14591 	{
14592 		params.samples					= samples[samplesIndex];
14593 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14594 		params.imageOffset = false;
14595 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
14596 		params.imageOffset = true;
14597 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14598 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
14599 		}
14600 	}
14601 }
14602 
addResolveImageWholeArrayImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14603 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14604 {
14605 	TestParams	params;
14606 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14607 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14608 	params.src.image.extent				= defaultExtent;
14609 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14610 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14611 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14612 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14613 	params.dst.image.extent				= defaultExtent;
14614 	params.dst.image.extent.depth		= 5u;
14615 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14616 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14617 	params.allocationKind				= allocationKind;
14618 	params.extensionUse					= extensionUse;
14619 
14620 	for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
14621 	{
14622 		const VkImageSubresourceLayers	sourceLayer	=
14623 		{
14624 			VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
14625 			0u,								// deUint32				mipLevel;
14626 			layerNdx,						// deUint32				baseArrayLayer;
14627 			1u								// deUint32				layerCount;
14628 		};
14629 
14630 		const VkImageResolve			testResolve	=
14631 		{
14632 			sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14633 			{0, 0, 0},			// VkOffset3D				srcOffset;
14634 			sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14635 			{0, 0, 0},			// VkOffset3D				dstOffset;
14636 			defaultExtent,		// VkExtent3D				extent;
14637 		};
14638 
14639 		CopyRegion	imageResolve;
14640 		imageResolve.imageResolve	= testResolve;
14641 		params.regions.push_back(imageResolve);
14642 	}
14643 
14644 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14645 	{
14646 		params.samples					= samples[samplesIndex];
14647 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14648 		params.imageOffset = false;
14649 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14650 		params.imageOffset = true;
14651 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14652 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14653 		}
14654 	}
14655 }
14656 
addResolveImageWholeArrayImageSingleRegionTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14657 void addResolveImageWholeArrayImageSingleRegionTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14658 {
14659 	TestParams	params;
14660 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14661 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14662 	params.src.image.extent				= defaultExtent;
14663 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14664 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14665 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14666 	params.dst.image.extent				= defaultExtent;
14667 	params.dst.image.extent.depth		= 5u;
14668 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14669 	params.allocationKind				= allocationKind;
14670 	params.extensionUse					= extensionUse;
14671 
14672 	const VkImageSubresourceLayers	sourceLayer	=
14673 	{
14674 		VK_IMAGE_ASPECT_COLOR_BIT,		// VkImageAspectFlags	aspectMask;
14675 		0u,								// uint32_t				mipLevel;
14676 		0,						// uint32_t				baseArrayLayer;
14677 		params.dst.image.extent.depth			// uint32_t				layerCount;
14678 	};
14679 
14680 	const VkImageResolve			testResolve	=
14681 	{
14682 		sourceLayer,		// VkImageSubresourceLayers	srcSubresource;
14683 		{0, 0, 0},			// VkOffset3D				srcOffset;
14684 		sourceLayer,		// VkImageSubresourceLayers	dstSubresource;
14685 		{0, 0, 0},			// VkOffset3D				dstOffset;
14686 		defaultExtent,		// VkExtent3D				extent;
14687 	};
14688 
14689 	CopyRegion	imageResolve;
14690 	imageResolve.imageResolve	= testResolve;
14691 	params.regions.push_back(imageResolve);
14692 
14693 	for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14694 	{
14695 		params.samples					= samples[samplesIndex];
14696 		const std::string description	= "With " + getSampleCountCaseName(samples[samplesIndex]);
14697 		params.imageOffset = false;
14698 		group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14699 		params.imageOffset = true;
14700 		if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14701 			group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]) + "_bind_offset", description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
14702 		}
14703 	}
14704 }
14705 
addResolveImageDiffImageSizeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14706 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14707 {
14708 	tcu::TestContext&	testCtx			= group->getTestContext();
14709 	TestParams			params;
14710 	params.src.image.imageType			= VK_IMAGE_TYPE_2D;
14711 	params.src.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14712 	params.src.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14713 	params.src.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
14714 	params.dst.image.imageType			= VK_IMAGE_TYPE_2D;
14715 	params.dst.image.format				= VK_FORMAT_R8G8B8A8_UNORM;
14716 	params.dst.image.tiling				= VK_IMAGE_TILING_OPTIMAL;
14717 	params.dst.image.operationLayout	= VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
14718 	params.allocationKind				= allocationKind;
14719 	params.extensionUse					= extensionUse;
14720 
14721 	{
14722 		const VkImageSubresourceLayers	sourceLayer	=
14723 		{
14724 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
14725 			0u,							// deUint32				mipLevel;
14726 			0u,							// deUint32				baseArrayLayer;
14727 			1u							// deUint32				layerCount;
14728 		};
14729 		const VkImageResolve			testResolve	=
14730 		{
14731 			sourceLayer,	// VkImageSubresourceLayers	srcSubresource;
14732 			{0, 0, 0},		// VkOffset3D				srcOffset;
14733 			sourceLayer,	// VkImageSubresourceLayers	dstSubresource;
14734 			{0, 0, 0},		// VkOffset3D				dstOffset;
14735 			resolveExtent,	// VkExtent3D				extent;
14736 		};
14737 		CopyRegion	imageResolve;
14738 		imageResolve.imageResolve	= testResolve;
14739 		params.regions.push_back(imageResolve);
14740 	}
14741 
14742 	const VkExtent3D imageExtents[]		=
14743 	{
14744 		{ resolveExtent.width + 10,	resolveExtent.height,		resolveExtent.depth },
14745 		{ resolveExtent.width,		resolveExtent.height * 2,	resolveExtent.depth },
14746 		{ resolveExtent.width,		resolveExtent.height,		resolveExtent.depth + 10 }
14747 	};
14748 
14749 	for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
14750 	{
14751 		const VkExtent3D&	srcImageSize	= imageExtents[srcImageExtentIndex];
14752 		params.src.image.extent				= srcImageSize;
14753 		params.dst.image.extent				= resolveExtent;
14754 		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14755 		{
14756 			params.samples	= samples[samplesIndex];
14757 			std::ostringstream testName;
14758 			testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
14759 			std::ostringstream description;
14760 			description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
14761 						<< srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
14762 			group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
14763 		}
14764 	}
14765 	for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
14766 	{
14767 		const VkExtent3D&	dstImageSize	= imageExtents[dstImageExtentIndex];
14768 		params.src.image.extent				= resolveExtent;
14769 		params.dst.image.extent				= dstImageSize;
14770 		for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
14771 		{
14772 			params.samples	= samples[samplesIndex];
14773 			std::ostringstream testName;
14774 			testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
14775 			std::ostringstream description;
14776 			description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
14777 						<< dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
14778 			params.imageOffset = false;
14779 			group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
14780 			params.imageOffset = true;
14781 			if (allocationKind != ALLOCATION_KIND_DEDICATED) {
14782 				group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str() + "_bind_offset", description.str(), params));
14783 			}
14784 		}
14785 	}
14786 }
14787 
addDepthStencilCopyMSAATest(tcu::TestCaseGroup * group,DepthStencilMSAA::TestParameters testCreateParams)14788 void addDepthStencilCopyMSAATest (tcu::TestCaseGroup* group, DepthStencilMSAA::TestParameters testCreateParams)
14789 {
14790 	// Run all the tests with one of the bare depth format and one bare stencil format + mandatory combined formats.
14791 	const struct
14792 	{
14793 		const std::string	name;
14794 		const VkFormat		vkFormat;
14795 	} depthAndStencilFormats[] =
14796 	{
14797 		{ "d32_sfloat",				VK_FORMAT_D32_SFLOAT		},
14798 		{ "s8_uint",				VK_FORMAT_S8_UINT			},
14799 		{ "d16_unorm_s8_uint",		VK_FORMAT_D16_UNORM_S8_UINT	},
14800 		{ "d24_unorm_s8_uint",		VK_FORMAT_D24_UNORM_S8_UINT	},
14801 	};
14802 
14803 	// Both image layouts will be tested only with full image copy tests to limit the number of tests.
14804 	const VkImageLayout srcImageLayouts[] =
14805 	{
14806 		VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
14807 		VK_IMAGE_LAYOUT_GENERAL
14808 	};
14809 	const VkImageLayout dstImageLayouts[] =
14810 	{
14811 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
14812 		VK_IMAGE_LAYOUT_GENERAL
14813 	};
14814 
14815 	for (const auto &srcLayout : srcImageLayouts)
14816 	{
14817 		for (const auto &dstLayout : dstImageLayouts)
14818 		{
14819 			testCreateParams.srcImageLayout = srcLayout;
14820 			testCreateParams.dstImageLayout = dstLayout;
14821 			for (const auto &format : depthAndStencilFormats)
14822 			{
14823 				testCreateParams.imageFormat	= format.vkFormat;
14824 				const auto textureFormat		= mapVkFormat(format.vkFormat);
14825 				bool hasDepth					= tcu::hasDepthComponent(textureFormat.order);
14826 				bool hasStencil					= tcu::hasStencilComponent(textureFormat.order);
14827 				std::string testNameBase		= format.name + "_" + (testCreateParams.copyOptions == DepthStencilMSAA::COPY_WHOLE_IMAGE ? getImageLayoutCaseName(srcLayout) + "_" + getImageLayoutCaseName(dstLayout) + "_": "");
14828 
14829 				if (hasDepth)
14830 				{
14831 					testCreateParams.copyAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
14832 					for (auto sample : samples)
14833 					{
14834 						testCreateParams.samples = sample;
14835 						std::string description = "Copy depth component with sample count: " + getSampleCountCaseName(sample);
14836 						testCreateParams.imageOffset = false;
14837 						group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "D_" + getSampleCountCaseName(sample), description, testCreateParams));
14838 						testCreateParams.imageOffset = true;
14839 						if (testCreateParams.allocationKind != ALLOCATION_KIND_DEDICATED) {
14840 							group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "D_" + getSampleCountCaseName(sample) + "_bind_offset", description, testCreateParams));
14841 						}
14842 					}
14843 				}
14844 
14845 				if (hasStencil)
14846 				{
14847 					testCreateParams.copyAspect = VK_IMAGE_ASPECT_STENCIL_BIT;
14848 					for (auto sample : samples)
14849 					{
14850 						testCreateParams.samples = sample;
14851 						std::string description = "Copy stencil component with sample count: " + getSampleCountCaseName(sample);
14852 						testCreateParams.imageOffset = false;
14853 						group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "S_" + getSampleCountCaseName(sample), description, testCreateParams));
14854 						testCreateParams.imageOffset = true;
14855 						if (testCreateParams.allocationKind != ALLOCATION_KIND_DEDICATED) {
14856 							group->addChild(new DepthStencilMSAATestCase(group->getTestContext(), testNameBase + "S_" + getSampleCountCaseName(sample) + "_bind_offset", description, testCreateParams));
14857 						}
14858 					}
14859 				}
14860 			}
14861 			if (testCreateParams.copyOptions != DepthStencilMSAA::COPY_WHOLE_IMAGE)
14862 				break;
14863 		}
14864 		if (testCreateParams.copyOptions != DepthStencilMSAA::COPY_WHOLE_IMAGE)
14865 			break;
14866 	}
14867 }
14868 
addDepthStencilCopyMSAATestGroup(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14869 void addDepthStencilCopyMSAATestGroup (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14870 {
14871 	// Allocation kind, extension use copy option parameters are defined here. Rest of the parameters are defined in `addDepthStencilCopyMSAATest` function.
14872 	DepthStencilMSAA::TestParameters testParams = {};
14873 	testParams.allocationKind	= allocationKind;
14874 	testParams.extensionUse		= extensionUse;
14875 
14876 	testParams.copyOptions = DepthStencilMSAA::COPY_WHOLE_IMAGE;
14877 	addTestGroup(group, "whole", "Copy from depth stencil to depth stencil with multi sample tests", addDepthStencilCopyMSAATest, testParams);
14878 
14879 	testParams.copyOptions = DepthStencilMSAA::COPY_PARTIAL;
14880 	addTestGroup(group, "partial", "Copy from depth stencil to depth stencil with multi sample tests", addDepthStencilCopyMSAATest, testParams);
14881 
14882 	testParams.copyOptions = DepthStencilMSAA::COPY_ARRAY_TO_ARRAY;
14883 	addTestGroup(group, "array_to_array", "Copy from array layer to array layer", addDepthStencilCopyMSAATest, testParams);
14884 }
14885 
addBufferCopyOffsetTests(tcu::TestCaseGroup * group)14886 void addBufferCopyOffsetTests (tcu::TestCaseGroup* group)
14887 {
14888 	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"));
14889 
14890 	for (deUint32 srcOffset = 0u; srcOffset < BufferOffsetParams::kMaxOffset; ++srcOffset)
14891 	for (deUint32 dstOffset = 0u; dstOffset < BufferOffsetParams::kMaxOffset; ++dstOffset)
14892 	{
14893 		BufferOffsetParams params{srcOffset, dstOffset};
14894 		addFunctionCase(subGroup.get(), de::toString(srcOffset) + "_" + de::toString(dstOffset), "", bufferOffsetTest, params);
14895 	}
14896 
14897 	group->addChild(subGroup.release());
14898 }
14899 
addResolveImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14900 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14901 {
14902 	addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind, extensionUse);
14903 	addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind, extensionUse);
14904 	addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind, extensionUse);
14905 	addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind, extensionUse);
14906 	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);
14907 	addComputeAndTransferQueueTests(group, allocationKind, extensionUse);
14908 	addTestGroup(group, "diff_layout_copy_before_resolving", "Resolve from image to image (whole copy before resolving with different layouts)", addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests, allocationKind, extensionUse);
14909 	addTestGroup(group, "layer_copy_before_resolving", "Resolve from image to image (layer copy before resolving)", addResolveImageLayerCopyBeforeResolvingTests, allocationKind, extensionUse);
14910 	addTestGroup(group, "copy_with_regions_before_resolving", "Resolve from image to image (region copy before resolving)", addResolveCopyImageWithRegionsTests, allocationKind, extensionUse);
14911 	addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind, extensionUse);
14912 	addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind, extensionUse);
14913 	addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind, extensionUse);
14914 }
14915 
addCopiesAndBlittingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)14916 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
14917 {
14918 	addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind, extensionUse);
14919 	addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind, extensionUse);
14920 	addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind, extensionUse);
14921 	addTestGroup(group, "buffer_to_depthstencil", "Copy from buffer to depth/Stencil", addBufferToDepthStencilTests, allocationKind, extensionUse);
14922 	addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind, extensionUse);
14923 	addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind, extensionUse);
14924 	addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind, extensionUse);
14925 	addTestGroup(group, "depth_stencil_msaa_copy", "Copy depth/stencil with MSAA", addDepthStencilCopyMSAATestGroup, allocationKind, extensionUse);
14926 }
14927 
addCoreCopiesAndBlittingTests(tcu::TestCaseGroup * group)14928 void addCoreCopiesAndBlittingTests(tcu::TestCaseGroup* group)
14929 {
14930 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED, EXTENSION_USE_NONE);
14931 	addBufferCopyOffsetTests(group);
14932 }
14933 
14934 
addDedicatedAllocationCopiesAndBlittingTests(tcu::TestCaseGroup * group)14935 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
14936 {
14937 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_NONE);
14938 }
14939 
14940 #ifndef CTS_USES_VULKANSC
addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup * group)14941 void addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup* group)
14942 {
14943 	addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_COPY_COMMANDS2);
14944 }
14945 #endif // CTS_USES_VULKANSC
14946 
14947 } // anonymous
14948 
createCopiesAndBlittingTests(tcu::TestContext & testCtx)14949 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
14950 {
14951 	de::MovePtr<tcu::TestCaseGroup>	copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
14952 
14953 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", "Core Copies And Blitting Tests", addCoreCopiesAndBlittingTests));
14954 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation",	"Copies And Blitting Tests For Dedicated Memory Allocation",	addDedicatedAllocationCopiesAndBlittingTests));
14955 #ifndef CTS_USES_VULKANSC
14956 	copiesAndBlittingTests->addChild(createTestGroup(testCtx, "copy_commands2", "Copies And Blitting Tests using KHR_copy_commands2", addExtensionCopiesAndBlittingTests));
14957 #endif // CTS_USES_VULKANSC
14958 
14959 	return copiesAndBlittingTests.release();
14960 }
14961 
14962 } // api
14963 } // vkt
14964