Home | History | Annotate | Download | only in memory
      1 /*-------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2017 The Khronos Group Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  * http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Memory binding test excercising VK_KHR_bind_memory2 extension.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "vktMemoryBindingTests.hpp"
     25 
     26 #include "vktTestCase.hpp"
     27 #include "tcuTestLog.hpp"
     28 
     29 #include "vkPlatform.hpp"
     30 #include "gluVarType.hpp"
     31 #include "deStringUtil.hpp"
     32 #include "vkPrograms.hpp"
     33 #include "vkQueryUtil.hpp"
     34 #include "vkRefUtil.hpp"
     35 #include "deSharedPtr.hpp"
     36 #include "vktTestCase.hpp"
     37 #include "vkTypeUtil.hpp"
     38 
     39 #include <algorithm>
     40 
     41 namespace vkt
     42 {
     43 namespace memory
     44 {
     45 namespace
     46 {
     47 
     48 using namespace vk;
     49 
     50 typedef const VkMemoryDedicatedAllocateInfo									ConstDedicatedInfo;
     51 typedef de::SharedPtr<Move<VkDeviceMemory> >								MemoryRegionPtr;
     52 typedef std::vector<MemoryRegionPtr>										MemoryRegionsList;
     53 typedef de::SharedPtr<Move<VkBuffer> >										BufferPtr;
     54 typedef std::vector<BufferPtr>												BuffersList;
     55 typedef de::SharedPtr<Move<VkImage> >										ImagePtr;
     56 typedef std::vector<ImagePtr>												ImagesList;
     57 typedef std::vector<VkBindBufferMemoryInfo>									BindBufferMemoryInfosList;
     58 typedef std::vector<VkBindImageMemoryInfo>									BindImageMemoryInfosList;
     59 
     60 class MemoryMappingRAII
     61 {
     62 public:
     63 										MemoryMappingRAII					(const DeviceInterface&	deviceInterface,
     64 																			 const VkDevice&		device,
     65 																			 VkDeviceMemory			deviceMemory,
     66 																			 VkDeviceSize			offset,
     67 																			 VkDeviceSize			size,
     68 																			 VkMemoryMapFlags		flags)
     69 										: vk								(deviceInterface)
     70 										, dev								(device)
     71 										, memory							(deviceMemory)
     72 										, hostPtr							(DE_NULL)
     73 
     74 	{
     75 		vk.mapMemory(dev, memory, offset, size, flags, &hostPtr);
     76 	}
     77 
     78 										~MemoryMappingRAII					()
     79 	{
     80 		vk.unmapMemory(dev, memory);
     81 		hostPtr = DE_NULL;
     82 	}
     83 
     84 	void*								ptr									()
     85 	{
     86 		return hostPtr;
     87 	}
     88 
     89 	void								flush								(VkDeviceSize			offset,
     90 																			 VkDeviceSize			size)
     91 	{
     92 		const VkMappedMemoryRange		range								= makeMemoryRange(offset, size);
     93 		VK_CHECK(vk.flushMappedMemoryRanges(dev, 1u, &range));
     94 	}
     95 
     96 protected:
     97 	const DeviceInterface&				vk;
     98 	const VkDevice&						dev;
     99 	VkDeviceMemory						memory;
    100 	void*								hostPtr;
    101 
    102 	const VkMappedMemoryRange			makeMemoryRange						(VkDeviceSize			offset,
    103 																			 VkDeviceSize			size)
    104 	{
    105 		const VkMappedMemoryRange		range								=
    106 		{
    107 			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
    108 			DE_NULL,
    109 			memory,
    110 			offset,
    111 			size
    112 		};
    113 		return range;
    114 	}
    115 };
    116 
    117 class SimpleRandomGenerator
    118 {
    119 public:
    120 										SimpleRandomGenerator				(deUint32				seed)
    121 										: value								(seed)
    122 	{}
    123 	deUint32							getNext								()
    124 	{
    125 		value += 1;
    126 		value ^= (value << 21);
    127 		value ^= (value >> 15);
    128 		value ^= (value << 4);
    129 		return value;
    130 	}
    131 protected:
    132 	deUint32							value;
    133 };
    134 
    135 struct BindingCaseParameters
    136 {
    137 	VkBufferCreateFlags					flags;
    138 	VkBufferUsageFlags					usage;
    139 	VkSharingMode						sharing;
    140 	VkDeviceSize						bufferSize;
    141 	VkExtent3D							imageSize;
    142 	deUint32							targetsCount;
    143 };
    144 
    145 BindingCaseParameters					makeBindingCaseParameters			(deUint32				targetsCount,
    146 																			 deUint32				width,
    147 																			 deUint32				height)
    148 {
    149 	BindingCaseParameters				params;
    150 	deMemset(&params, 0, sizeof(BindingCaseParameters));
    151 	params.imageSize.width = width;
    152 	params.imageSize.height = height;
    153 	params.imageSize.depth = 1;
    154 	params.bufferSize = params.imageSize.width * params.imageSize.height * params.imageSize.depth * sizeof(deUint32);
    155 	params.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
    156 	params.targetsCount = targetsCount;
    157 	return params;
    158 }
    159 
    160 BindingCaseParameters					makeBindingCaseParameters			(deUint32				targetsCount,
    161 																			 VkBufferUsageFlags		usage,
    162 																			 VkSharingMode			sharing,
    163 																			 VkDeviceSize			bufferSize)
    164 {
    165 	BindingCaseParameters				params								=
    166 	{
    167 		0,																	// VkBufferCreateFlags	flags;
    168 		usage,																// VkBufferUsageFlags	usage;
    169 		sharing,															// VkSharingMode		sharing;
    170 		bufferSize,															// VkDeviceSize			bufferSize;
    171 		{0u, 0u, 0u},														// VkExtent3D			imageSize;
    172 		targetsCount														// deUint32				targetsCount;
    173 	};
    174 	return params;
    175 }
    176 
    177 VkImageCreateInfo						makeImageCreateInfo					(BindingCaseParameters&	params)
    178 {
    179 	const VkImageCreateInfo				imageParams							=
    180 	{
    181 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,								// VkStructureType		sType;
    182 		DE_NULL,															// const void*			pNext;
    183 		0u,																	// VkImageCreateFlags	flags;
    184 		VK_IMAGE_TYPE_2D,													// VkImageType			imageType;
    185 		VK_FORMAT_R8G8B8A8_UINT,											// VkFormat				format;
    186 		params.imageSize,													// VkExtent3D			extent;
    187 		1u,																	// deUint32				mipLevels;
    188 		1u,																	// deUint32				arrayLayers;
    189 		VK_SAMPLE_COUNT_1_BIT,												// VkSampleCountFlagBits samples;
    190 		VK_IMAGE_TILING_LINEAR,												// VkImageTiling		tiling;
    191 		VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
    192 		VK_SHARING_MODE_EXCLUSIVE,											// VkSharingMode		sharingMode;
    193 		0u,																	// deUint32				queueFamilyIndexCount;
    194 		DE_NULL,															// const deUint32*		pQueueFamilyIndices;
    195 		VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout		initialLayout;
    196 	};
    197 	return imageParams;
    198 }
    199 
    200 VkBufferCreateInfo						makeBufferCreateInfo				(Context&				ctx,
    201 																			 BindingCaseParameters&	params)
    202 {
    203 	const deUint32						queueFamilyIndex					= ctx.getUniversalQueueFamilyIndex();
    204 	VkBufferCreateInfo					bufferParams						=
    205 	{
    206 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,								// VkStructureType		sType;
    207 		DE_NULL,															// const void*			pNext;
    208 		params.flags,														// VkBufferCreateFlags	flags;
    209 		params.bufferSize,													// VkDeviceSize			size;
    210 		params.usage,														// VkBufferUsageFlags	usage;
    211 		params.sharing,														// VkSharingMode		sharingMode;
    212 		1u,																	// uint32_t				queueFamilyIndexCount;
    213 		&queueFamilyIndex,													// const uint32_t*		pQueueFamilyIndices;
    214 	};
    215 	return bufferParams;
    216 }
    217 
    218 const VkMemoryAllocateInfo				makeMemoryAllocateInfo				(VkMemoryRequirements&	memReqs,
    219 																			 ConstDedicatedInfo*	next)
    220 {
    221 	const deUint32						heapTypeIndex						= (deUint32)deCtz32(memReqs.memoryTypeBits);
    222 	const VkMemoryAllocateInfo			allocateParams						=
    223 	{
    224 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,								// VkStructureType		sType;
    225 		next,																// const void*			pNext;
    226 		memReqs.size,														// VkDeviceSize			allocationSize;
    227 		heapTypeIndex,														// uint32_t				memoryTypeIndex;
    228 	};
    229 	return allocateParams;
    230 }
    231 
    232 enum MemoryHostVisibility
    233 {
    234 	MemoryAny,
    235 	MemoryHostVisible
    236 };
    237 
    238 deUint32								selectMatchingMemoryType			(Context&				ctx,
    239 																			 VkMemoryRequirements&	memReqs,
    240 																			 MemoryHostVisibility	memoryVisibility)
    241 {
    242 	const VkPhysicalDevice				vkPhysicalDevice					= ctx.getPhysicalDevice();
    243 	const InstanceInterface&			vkInstance							= ctx.getInstanceInterface();
    244 	VkPhysicalDeviceMemoryProperties	memoryProperties;
    245 
    246 	vkInstance.getPhysicalDeviceMemoryProperties(vkPhysicalDevice, &memoryProperties);
    247 	if (memoryVisibility == MemoryHostVisible)
    248 	{
    249 		for (deUint32 typeNdx = 0; typeNdx < memoryProperties.memoryTypeCount; ++typeNdx)
    250 		{
    251 			const deBool				isInAllowed							= (memReqs.memoryTypeBits & (1u << typeNdx)) != 0u;
    252 			const deBool				hasRightProperties					= (memoryProperties.memoryTypes[typeNdx].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0u;
    253 			if (isInAllowed && hasRightProperties)
    254 				return typeNdx;
    255 		}
    256 	}
    257 	return (deUint32)deCtz32(memReqs.memoryTypeBits);
    258 }
    259 
    260 const VkMemoryAllocateInfo				makeMemoryAllocateInfo				(Context&				ctx,
    261 																			 VkMemoryRequirements&	memReqs,
    262 																			 MemoryHostVisibility	memoryVisibility)
    263 {
    264 	const deUint32						heapTypeIndex						= selectMatchingMemoryType(ctx, memReqs, memoryVisibility);
    265 	const VkMemoryAllocateInfo			allocateParams						=
    266 	{
    267 		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,								// VkStructureType		sType;
    268 		DE_NULL,															// const void*			pNext;
    269 		memReqs.size,														// VkDeviceSize			allocationSize;
    270 		heapTypeIndex,														// uint32_t				memoryTypeIndex;
    271 	};
    272 	return allocateParams;
    273 }
    274 
    275 ConstDedicatedInfo						makeDedicatedAllocationInfo			(VkBuffer				buffer)
    276 {
    277 	ConstDedicatedInfo					dedicatedAllocationInfo				=
    278 	{
    279 		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,				// VkStructureType		sType
    280 		DE_NULL,															// const void*			pNext
    281 		DE_NULL,															// VkImage				image
    282 		buffer																// VkBuffer				buffer
    283 	};
    284 	return dedicatedAllocationInfo;
    285 }
    286 
    287 ConstDedicatedInfo						makeDedicatedAllocationInfo			(VkImage				image)
    288 {
    289 	ConstDedicatedInfo					dedicatedAllocationInfo				=
    290 	{
    291 		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,				// VkStructureType		sType
    292 		DE_NULL,															// const void*			pNext
    293 		image,																// VkImage				image
    294 		DE_NULL																// VkBuffer				buffer
    295 	};
    296 	return dedicatedAllocationInfo;
    297 }
    298 
    299 const VkBindBufferMemoryInfo			makeBufferMemoryBindingInfo			(VkBuffer				buffer,
    300 																			 VkDeviceMemory			memory)
    301 {
    302 	const VkBindBufferMemoryInfo		bufferMemoryBinding					=
    303 	{
    304 		VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR,						// VkStructureType		sType;
    305 		DE_NULL,															// const void*			pNext;
    306 		buffer,																// VkBuffer				buffer;
    307 		memory,																// VkDeviceMemory		memory;
    308 		0u,																	// VkDeviceSize			memoryOffset;
    309 	};
    310 	return bufferMemoryBinding;
    311 }
    312 
    313 const VkBindImageMemoryInfo				makeImageMemoryBindingInfo			(VkImage				image,
    314 																			 VkDeviceMemory			memory)
    315 {
    316 	const VkBindImageMemoryInfo		imageMemoryBinding					=
    317 	{
    318 		VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR,						// VkStructureType		sType;
    319 		DE_NULL,															// const void*			pNext;
    320 		image,																// VkImage				image;
    321 		memory,																// VkDeviceMemory		memory;
    322 		0u,																	// VkDeviceSize			memoryOffset;
    323 	};
    324 	return imageMemoryBinding;
    325 }
    326 
    327 enum TransferDirection
    328 {
    329 	TransferToResource														= 0,
    330 	TransferFromResource													= 1
    331 };
    332 
    333 const VkBufferMemoryBarrier				makeMemoryBarrierInfo				(VkBuffer				buffer,
    334 																			 VkDeviceSize			size,
    335 																			 TransferDirection		direction)
    336 {
    337 	const deBool fromRes													= direction == TransferFromResource;
    338 	const VkAccessFlags					srcMask								= static_cast<VkAccessFlags>(fromRes ? VK_ACCESS_HOST_WRITE_BIT : VK_ACCESS_TRANSFER_WRITE_BIT);
    339 	const VkAccessFlags					dstMask								= static_cast<VkAccessFlags>(fromRes ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_HOST_READ_BIT);
    340 	const VkBufferMemoryBarrier			bufferBarrier						=
    341 	{
    342 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,							// VkStructureType		sType;
    343 		DE_NULL,															// const void*			pNext;
    344 		srcMask,															// VkAccessFlags		srcAccessMask;
    345 		dstMask,															// VkAccessFlags		dstAccessMask;
    346 		VK_QUEUE_FAMILY_IGNORED,											// deUint32				srcQueueFamilyIndex;
    347 		VK_QUEUE_FAMILY_IGNORED,											// deUint32				dstQueueFamilyIndex;
    348 		buffer,																// VkBuffer				buffer;
    349 		0u,																	// VkDeviceSize			offset;
    350 		size																// VkDeviceSize			size;
    351 	};
    352 	return bufferBarrier;
    353 }
    354 
    355 const VkImageMemoryBarrier				makeMemoryBarrierInfo				(VkImage				image,
    356 																			 VkAccessFlags			srcAccess,
    357 																			 VkAccessFlags			dstAccess,
    358 																			 VkImageLayout			oldLayout,
    359 																			 VkImageLayout			newLayout)
    360 {
    361 	const VkImageAspectFlags			aspect								= VK_IMAGE_ASPECT_COLOR_BIT;
    362 	const VkImageMemoryBarrier			imageBarrier						=
    363 	{
    364 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,								// VkStructureType		sType;
    365 		DE_NULL,															// const void*			pNext;
    366 		srcAccess,															// VkAccessFlags		srcAccessMask;
    367 		dstAccess,															// VkAccessFlags		dstAccessMask;
    368 		oldLayout,															// VkImageLayout		oldLayout;
    369 		newLayout,															// VkImageLayout		newLayout;
    370 		VK_QUEUE_FAMILY_IGNORED,											// deUint32				srcQueueFamilyIndex;
    371 		VK_QUEUE_FAMILY_IGNORED,											// deUint32				dstQueueFamilyIndex;
    372 		image,																// VkImage				image;
    373 		{																	// VkImageSubresourceRange subresourceRange;
    374 			aspect,															// VkImageAspectFlags	aspect;
    375 			0u,																// deUint32				baseMipLevel;
    376 			1u,																// deUint32				mipLevels;
    377 			0u,																// deUint32				baseArraySlice;
    378 			1u,																// deUint32				arraySize;
    379 		}
    380 	};
    381 	return imageBarrier;
    382 }
    383 
    384 const VkCommandBufferBeginInfo			makeCommandBufferInfo				()
    385 {
    386 	const VkCommandBufferBeginInfo		cmdBufferBeginInfo					=
    387 	{
    388 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
    389 		DE_NULL,
    390 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
    391 		static_cast<const VkCommandBufferInheritanceInfo*>(DE_NULL)
    392 	};
    393 	return cmdBufferBeginInfo;
    394 }
    395 
    396 const VkSubmitInfo						makeSubmitInfo						(const VkCommandBuffer&	commandBuffer)
    397 {
    398 	const VkSubmitInfo					submitInfo							=
    399 	{
    400 		VK_STRUCTURE_TYPE_SUBMIT_INFO,										// VkStructureType		sType;
    401 		DE_NULL,															// const void*			pNext;
    402 		0u,																	// deUint32				waitSemaphoreCount;
    403 		DE_NULL,															// const VkSemaphore*	pWaitSemaphores;
    404 		(const VkPipelineStageFlags*)DE_NULL,								// const VkPipelineStageFlags* flags;
    405 		1u,																	// deUint32				commandBufferCount;
    406 		&commandBuffer,														// const VkCommandBuffer* pCommandBuffers;
    407 		0u,																	// deUint32				signalSemaphoreCount;
    408 		DE_NULL																// const VkSemaphore*	pSignalSemaphores;
    409 	};
    410 	return submitInfo;
    411 }
    412 
    413 Move<VkCommandBuffer>					createCommandBuffer					(const DeviceInterface&	vk,
    414 																			 VkDevice				device,
    415 																			 VkCommandPool			commandPool)
    416 {
    417 	const VkCommandBufferAllocateInfo allocInfo =
    418 	{
    419 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
    420 		DE_NULL,
    421 		commandPool,
    422 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,
    423 		1
    424 	};
    425 	return allocateCommandBuffer(vk, device, &allocInfo);
    426 }
    427 
    428 
    429 template<typename TTarget>
    430 void									createBindingTargets				(std::vector<de::SharedPtr<Move<TTarget> > >&
    431 																									targets,
    432 																			 Context&				ctx,
    433 																			 BindingCaseParameters	params);
    434 
    435 template<>
    436 void									createBindingTargets<VkBuffer>		(BuffersList&			targets,
    437 																			 Context&				ctx,
    438 																			 BindingCaseParameters	params)
    439 {
    440 	const deUint32						count								= params.targetsCount;
    441 	const VkDevice						vkDevice							= ctx.getDevice();
    442 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    443 
    444 	targets.reserve(count);
    445 	for (deUint32 i = 0u; i < count; ++i)
    446 	{
    447 		VkBufferCreateInfo				bufferParams						= makeBufferCreateInfo(ctx, params);
    448 		targets.push_back(BufferPtr(new Move<VkBuffer>(createBuffer(vk, vkDevice, &bufferParams))));
    449 	}
    450 }
    451 
    452 template<>
    453 void									createBindingTargets<VkImage>		(ImagesList&			targets,
    454 																			 Context&				ctx,
    455 																			 BindingCaseParameters	params)
    456 {
    457 	const deUint32						count								= params.targetsCount;
    458 	const VkDevice						vkDevice							= ctx.getDevice();
    459 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    460 
    461 	targets.reserve(count);
    462 	for (deUint32 i = 0u; i < count; ++i)
    463 	{
    464 		VkImageCreateInfo				imageParams							= makeImageCreateInfo(params);
    465 		targets.push_back(ImagePtr(new Move<VkImage>(createImage(vk, vkDevice, &imageParams))));
    466 	}
    467 }
    468 
    469 template<typename TTarget, deBool TDedicated>
    470 void									createMemory						(std::vector<de::SharedPtr<Move<TTarget> > >&
    471 																									targets,
    472 																			 MemoryRegionsList&		memory,
    473 																			 Context&				ctx,
    474 																			 BindingCaseParameters	params);
    475 
    476 template<>
    477 void									createMemory<VkBuffer, DE_FALSE>	(BuffersList&			targets,
    478 																			 MemoryRegionsList&		memory,
    479 																			 Context&				ctx,
    480 																			 BindingCaseParameters	params)
    481 {
    482 	DE_UNREF(params);
    483 	const deUint32						count								= static_cast<deUint32>(targets.size());
    484 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    485 	const VkDevice						vkDevice							= ctx.getDevice();
    486 
    487 	memory.reserve(count);
    488 	for (deUint32 i = 0; i < count; ++i)
    489 	{
    490 		VkMemoryRequirements			memReqs;
    491 
    492 		vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);
    493 
    494 		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, DE_NULL);
    495 		VkDeviceMemory					rawMemory							= DE_NULL;
    496 
    497 		vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
    498 		memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
    499 	}
    500 }
    501 
    502 template<>
    503 void									createMemory<VkImage, DE_FALSE>		(ImagesList&			targets,
    504 																			 MemoryRegionsList&		memory,
    505 																			 Context&				ctx,
    506 																			 BindingCaseParameters	params)
    507 {
    508 	DE_UNREF(params);
    509 	const deUint32						count								= static_cast<deUint32>(targets.size());
    510 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    511 	const VkDevice						vkDevice							= ctx.getDevice();
    512 
    513 	memory.reserve(count);
    514 	for (deUint32 i = 0; i < count; ++i)
    515 	{
    516 		VkMemoryRequirements			memReqs;
    517 		vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);
    518 
    519 		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, DE_NULL);
    520 		VkDeviceMemory					rawMemory							= DE_NULL;
    521 
    522 		vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
    523 		memory.push_back(de::SharedPtr<Move<VkDeviceMemory> >(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
    524 	}
    525 }
    526 
    527 template<>
    528 void									createMemory<VkBuffer, DE_TRUE>		(BuffersList&			targets,
    529 																			 MemoryRegionsList&		memory,
    530 																			 Context&				ctx,
    531 																			 BindingCaseParameters	params)
    532 {
    533 	DE_UNREF(params);
    534 	const deUint32						count								= static_cast<deUint32>(targets.size());
    535 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    536 	const VkDevice						vkDevice							= ctx.getDevice();
    537 
    538 	memory.reserve(count);
    539 	for (deUint32 i = 0; i < count; ++i)
    540 	{
    541 		VkMemoryRequirements			memReqs;
    542 
    543 		vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);
    544 
    545 		ConstDedicatedInfo				dedicatedAllocationInfo				= makeDedicatedAllocationInfo(**targets[i]);;
    546 		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, &dedicatedAllocationInfo);
    547 		VkDeviceMemory					rawMemory							= DE_NULL;
    548 
    549 		vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
    550 		memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
    551 	}
    552 }
    553 
    554 template<>
    555 void									createMemory<VkImage, DE_TRUE>		(ImagesList&			targets,
    556 																			 MemoryRegionsList&		memory,
    557 																			 Context&				ctx,
    558 																			 BindingCaseParameters	params)
    559 {
    560 	DE_UNREF(params);
    561 	const deUint32						count								= static_cast<deUint32>(targets.size());
    562 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    563 	const VkDevice						vkDevice							= ctx.getDevice();
    564 
    565 	memory.reserve(count);
    566 	for (deUint32 i = 0; i < count; ++i)
    567 	{
    568 		VkMemoryRequirements			memReqs;
    569 		vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);
    570 
    571 		ConstDedicatedInfo				dedicatedAllocationInfo				= makeDedicatedAllocationInfo(**targets[i]);
    572 		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, &dedicatedAllocationInfo);
    573 		VkDeviceMemory					rawMemory							= DE_NULL;
    574 
    575 		vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
    576 		memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
    577 	}
    578 }
    579 
    580 template<typename TTarget>
    581 void									makeBinding							(std::vector<de::SharedPtr<Move<TTarget> > >&
    582 																									targets,
    583 																			 MemoryRegionsList&		memory,
    584 																			 Context&				ctx,
    585 																			 BindingCaseParameters	params);
    586 
    587 template<>
    588 void									makeBinding<VkBuffer>				(BuffersList&			targets,
    589 																			 MemoryRegionsList&		memory,
    590 																			 Context&				ctx,
    591 																			 BindingCaseParameters	params)
    592 {
    593 	DE_UNREF(params);
    594 	const deUint32						count								= static_cast<deUint32>(targets.size());
    595 	const VkDevice						vkDevice							= ctx.getDevice();
    596 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    597 	BindBufferMemoryInfosList			bindMemoryInfos;
    598 
    599 	for (deUint32 i = 0; i < count; ++i)
    600 	{
    601 		bindMemoryInfos.push_back(makeBufferMemoryBindingInfo(**targets[i], **memory[i]));
    602 	}
    603 
    604 	VK_CHECK(vk.bindBufferMemory2(vkDevice, count, &bindMemoryInfos.front()));
    605 }
    606 
    607 template<>
    608 void									makeBinding<VkImage>				(ImagesList&			targets,
    609 																			 MemoryRegionsList&		memory,
    610 																			 Context&				ctx,
    611 																			 BindingCaseParameters	params)
    612 {
    613 	DE_UNREF(params);
    614 	const deUint32						count								= static_cast<deUint32>(targets.size());
    615 	const VkDevice						vkDevice							= ctx.getDevice();
    616 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    617 	BindImageMemoryInfosList			bindMemoryInfos;
    618 
    619 	for (deUint32 i = 0; i < count; ++i)
    620 	{
    621 		bindMemoryInfos.push_back(makeImageMemoryBindingInfo(**targets[i], **memory[i]));
    622 	}
    623 
    624 	VK_CHECK(vk.bindImageMemory2(vkDevice, count, &bindMemoryInfos.front()));
    625 }
    626 
    627 template <typename TTarget>
    628 void									fillUpResource						(Move<VkBuffer>&		source,
    629 																			 Move<TTarget>&			target,
    630 																			 Context&				ctx,
    631 																			 BindingCaseParameters	params);
    632 
    633 template <>
    634 void									fillUpResource<VkBuffer>			(Move<VkBuffer>&		source,
    635 																			 Move<VkBuffer>&		target,
    636 																			 Context&				ctx,
    637 																			 BindingCaseParameters	params)
    638 {
    639 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    640 	const VkDevice						vkDevice							= ctx.getDevice();
    641 	const VkQueue						queue								= ctx.getUniversalQueue();
    642 
    643 	const VkBufferMemoryBarrier			srcBufferBarrier					= makeMemoryBarrierInfo(*source, params.bufferSize, TransferFromResource);
    644 	const VkBufferMemoryBarrier			dstBufferBarrier					= makeMemoryBarrierInfo(*target, params.bufferSize, TransferToResource);
    645 
    646 	const VkCommandBufferBeginInfo		cmdBufferBeginInfo					= makeCommandBufferInfo();
    647 	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
    648 	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);
    649 	VkBufferCopy						bufferCopy							= { 0u, 0u, params.bufferSize };
    650 
    651 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
    652 	vk.cmdPipelineBarrier(*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);
    653 	vk.cmdCopyBuffer(*cmdBuffer, *source, *target, 1, &bufferCopy);
    654 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
    655 	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
    656 
    657 	const VkSubmitInfo					submitInfo							= makeSubmitInfo(*cmdBuffer);
    658 	Move<VkFence>						fence								= createFence(vk, vkDevice);
    659 
    660 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
    661 	VK_CHECK(vk.waitForFences(vkDevice, 1, &*fence, DE_TRUE, ~(0ull)));
    662 }
    663 
    664 template <>
    665 void									fillUpResource<VkImage>				(Move<VkBuffer>&		source,
    666 																			 Move<VkImage>&			target,
    667 																			 Context&				ctx,
    668 																			 BindingCaseParameters	params)
    669 {
    670 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    671 	const VkDevice						vkDevice							= ctx.getDevice();
    672 	const VkQueue						queue								= ctx.getUniversalQueue();
    673 
    674 	const VkBufferMemoryBarrier			srcBufferBarrier					= makeMemoryBarrierInfo(*source, params.bufferSize, TransferFromResource);
    675 	const VkImageMemoryBarrier			preImageBarrier						= makeMemoryBarrierInfo(*target, 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
    676 	const VkImageMemoryBarrier			dstImageBarrier						= makeMemoryBarrierInfo(*target, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
    677 
    678 	const VkCommandBufferBeginInfo		cmdBufferBeginInfo					= makeCommandBufferInfo();
    679 	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
    680 	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);
    681 
    682 	const VkBufferImageCopy				copyRegion							=
    683 	{
    684 		0u,																	// VkDeviceSize			bufferOffset;
    685 		params.imageSize.width,												// deUint32				bufferRowLength;
    686 		params.imageSize.height,											// deUint32				bufferImageHeight;
    687 		{
    688 			VK_IMAGE_ASPECT_COLOR_BIT,										// VkImageAspectFlags	aspect;
    689 			0u,																// deUint32				mipLevel;
    690 			0u,																// deUint32				baseArrayLayer;
    691 			1u,																// deUint32				layerCount;
    692 		},																	// VkImageSubresourceLayers imageSubresource;
    693 		{ 0, 0, 0 },														// VkOffset3D			imageOffset;
    694 		params.imageSize													// VkExtent3D			imageExtent;
    695 	};
    696 
    697 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
    698 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 1, &preImageBarrier);
    699 	vk.cmdCopyBufferToImage(*cmdBuffer, *source, *target, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, (&copyRegion));
    700 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
    701 	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
    702 
    703 	const VkSubmitInfo					submitInfo							= makeSubmitInfo(*cmdBuffer);
    704 	Move<VkFence>						fence								= createFence(vk, vkDevice);
    705 
    706 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
    707 	VK_CHECK(vk.waitForFences(vkDevice, 1, &*fence, DE_TRUE, ~(0ull)));
    708 }
    709 
    710 template <typename TTarget>
    711 void									readUpResource						(Move<TTarget>&			source,
    712 																			 Move<VkBuffer>&		target,
    713 																			 Context&				ctx,
    714 																			 BindingCaseParameters	params);
    715 
    716 template <>
    717 void									readUpResource						(Move<VkBuffer>&		source,
    718 																			 Move<VkBuffer>&		target,
    719 																			 Context&				ctx,
    720 																			 BindingCaseParameters	params)
    721 {
    722 	fillUpResource(source, target, ctx, params);
    723 }
    724 
    725 template <>
    726 void									readUpResource						(Move<VkImage>&			source,
    727 																			 Move<VkBuffer>&		target,
    728 																			 Context&				ctx,
    729 																			 BindingCaseParameters	params)
    730 {
    731 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    732 	const VkDevice						vkDevice							= ctx.getDevice();
    733 	const VkQueue						queue								= ctx.getUniversalQueue();
    734 
    735 	const VkImageMemoryBarrier			srcImageBarrier						= makeMemoryBarrierInfo(*source, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
    736 	const VkBufferMemoryBarrier			dstBufferBarrier					= makeMemoryBarrierInfo(*target, params.bufferSize, TransferToResource);
    737 	const VkImageMemoryBarrier			postImageBarrier					= makeMemoryBarrierInfo(*source, VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
    738 
    739 	const VkCommandBufferBeginInfo		cmdBufferBeginInfo					= makeCommandBufferInfo();
    740 	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
    741 	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);
    742 
    743 	const VkBufferImageCopy				copyRegion							=
    744 	{
    745 		0u,																	// VkDeviceSize			bufferOffset;
    746 		params.imageSize.width,												// deUint32				bufferRowLength;
    747 		params.imageSize.height,											// deUint32				bufferImageHeight;
    748 		{
    749 			VK_IMAGE_ASPECT_COLOR_BIT,										// VkImageAspectFlags	aspect;
    750 			0u,																// deUint32				mipLevel;
    751 			0u,																// deUint32				baseArrayLayer;
    752 			1u,																// deUint32				layerCount;
    753 		},																	// VkImageSubresourceLayers imageSubresource;
    754 		{ 0, 0, 0 },														// VkOffset3D			imageOffset;
    755 		params.imageSize													// VkExtent3D			imageExtent;
    756 	};
    757 
    758 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
    759 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
    760 	vk.cmdCopyImageToBuffer(*cmdBuffer, *source, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *target, 1, (&copyRegion));
    761 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 1, &postImageBarrier);
    762 	VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
    763 
    764 	const VkSubmitInfo					submitInfo							= makeSubmitInfo(*cmdBuffer);
    765 	Move<VkFence>						fence								= createFence(vk, vkDevice);
    766 
    767 	VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
    768 	VK_CHECK(vk.waitForFences(vkDevice, 1, &*fence, DE_TRUE, ~(0ull)));
    769 }
    770 
    771 void									createBuffer						(Move<VkBuffer>&		buffer,
    772 																			 Move<VkDeviceMemory>&	memory,
    773 																			 Context&				ctx,
    774 																			 BindingCaseParameters	params)
    775 {
    776 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    777 	const VkDevice						vkDevice							= ctx.getDevice();
    778 	VkBufferCreateInfo					bufferParams						= makeBufferCreateInfo(ctx, params);
    779 	VkMemoryRequirements				memReqs;
    780 
    781 	buffer = createBuffer(vk, vkDevice, &bufferParams);
    782 	vk.getBufferMemoryRequirements(vkDevice, *buffer, &memReqs);
    783 
    784 	const VkMemoryAllocateInfo			memAlloc							= makeMemoryAllocateInfo(ctx, memReqs, MemoryHostVisible);
    785 	VkDeviceMemory						rawMemory							= DE_NULL;
    786 
    787 	vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
    788 	memory = Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL));
    789 	VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, *memory, 0u));
    790 }
    791 
    792 void									pushData							(VkDeviceMemory			memory,
    793 																			 deUint32				dataSeed,
    794 																			 Context&				ctx,
    795 																			 BindingCaseParameters	params)
    796 {
    797 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    798 	const VkDevice						vkDevice							= ctx.getDevice();
    799 	MemoryMappingRAII					hostMemory							(vk, vkDevice, memory, 0u, params.bufferSize, 0u);
    800 	deUint8*							hostBuffer							= static_cast<deUint8*>(hostMemory.ptr());
    801 	SimpleRandomGenerator				random								(dataSeed);
    802 
    803 	for (deUint32 i = 0u; i < params.bufferSize; ++i)
    804 	{
    805 		hostBuffer[i] = static_cast<deUint8>(random.getNext() & 0xFFu);
    806 	}
    807 	hostMemory.flush(0u, params.bufferSize);
    808 }
    809 
    810 deBool									checkData							(VkDeviceMemory			memory,
    811 																			 deUint32				dataSeed,
    812 																			 Context&				ctx,
    813 																			 BindingCaseParameters	params)
    814 {
    815 	const DeviceInterface&				vk									= ctx.getDeviceInterface();
    816 	const VkDevice						vkDevice							= ctx.getDevice();
    817 	MemoryMappingRAII					hostMemory							(vk, vkDevice, memory, 0u, params.bufferSize, 0u);
    818 	deUint8*							hostBuffer							= static_cast<deUint8*>(hostMemory.ptr());
    819 	SimpleRandomGenerator				random								(dataSeed);
    820 
    821 	for (deUint32 i = 0u; i < params.bufferSize; ++i)
    822 	{
    823 		if (hostBuffer[i] != static_cast<deUint8>(random.getNext() & 0xFFu) )
    824 			return DE_FALSE;
    825 	}
    826 	return DE_TRUE;
    827 }
    828 
    829 template<typename TTarget, deBool TDedicated>
    830 class MemoryBindingInstance : public TestInstance
    831 {
    832 public:
    833 										MemoryBindingInstance				(Context&				ctx,
    834 																			 BindingCaseParameters	params)
    835 										: TestInstance						(ctx)
    836 										, m_params							(params)
    837 	{
    838 	}
    839 
    840 	virtual tcu::TestStatus				iterate								(void)
    841 	{
    842 		const std::vector<std::string>&	extensions							= m_context.getDeviceExtensions();
    843 		const deBool					isSupported							= isDeviceExtensionSupported(m_context.getUsedApiVersion(), extensions, "VK_KHR_bind_memory2");
    844 		if (!isSupported)
    845 		{
    846 			TCU_THROW(NotSupportedError, "Not supported");
    847 		}
    848 
    849 		std::vector<de::SharedPtr<Move<TTarget> > >
    850 										targets;
    851 		MemoryRegionsList				memory;
    852 
    853 		createBindingTargets<TTarget>(targets, m_context, m_params);
    854 		createMemory<TTarget, TDedicated>(targets, memory, m_context, m_params);
    855 		makeBinding<TTarget>(targets, memory, m_context, m_params);
    856 
    857 		Move<VkBuffer>					srcBuffer;
    858 		Move<VkDeviceMemory>			srcMemory;
    859 
    860 		createBuffer(srcBuffer, srcMemory, m_context, m_params);
    861 		pushData(*srcMemory, 1, m_context, m_params);
    862 
    863 		Move<VkBuffer>					dstBuffer;
    864 		Move<VkDeviceMemory>			dstMemory;
    865 
    866 		createBuffer(dstBuffer, dstMemory, m_context, m_params);
    867 
    868 		deBool							passed								= DE_TRUE;
    869 		for (deUint32 i = 0; passed && i < m_params.targetsCount; ++i)
    870 		{
    871 			fillUpResource(srcBuffer, *targets[i], m_context, m_params);
    872 			readUpResource(*targets[i], dstBuffer, m_context, m_params);
    873 			passed = checkData(*dstMemory, 1, m_context, m_params);
    874 		}
    875 
    876 		return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
    877 	}
    878 private:
    879 	BindingCaseParameters				m_params;
    880 };
    881 
    882 template<typename TTarget, deBool TDedicated>
    883 class AliasedMemoryBindingInstance : public TestInstance
    884 {
    885 public:
    886 										AliasedMemoryBindingInstance		(Context&				ctx,
    887 																			 BindingCaseParameters	params)
    888 										: TestInstance						(ctx)
    889 										, m_params							(params)
    890 	{
    891 	}
    892 
    893 	virtual tcu::TestStatus				iterate								(void)
    894 	{
    895 		const std::vector<std::string>&	extensions							= m_context.getDeviceExtensions();
    896 		const deBool					isSupported							= isDeviceExtensionSupported(m_context.getUsedApiVersion(), extensions, "VK_KHR_bind_memory2");
    897 		if (!isSupported)
    898 		{
    899 			TCU_THROW(NotSupportedError, "Not supported");
    900 		}
    901 
    902 		std::vector<de::SharedPtr<Move<TTarget> > >
    903 										targets[2];
    904 		MemoryRegionsList				memory;
    905 
    906 		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(targets); ++i)
    907 			createBindingTargets<TTarget>(targets[i], m_context, m_params);
    908 		createMemory<TTarget, TDedicated>(targets[0], memory, m_context, m_params);
    909 		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(targets); ++i)
    910 			makeBinding<TTarget>(targets[i], memory, m_context, m_params);
    911 
    912 		Move<VkBuffer>					srcBuffer;
    913 		Move<VkDeviceMemory>			srcMemory;
    914 
    915 		createBuffer(srcBuffer, srcMemory, m_context, m_params);
    916 		pushData(*srcMemory, 2, m_context, m_params);
    917 
    918 		Move<VkBuffer>					dstBuffer;
    919 		Move<VkDeviceMemory>			dstMemory;
    920 
    921 		createBuffer(dstBuffer, dstMemory, m_context, m_params);
    922 
    923 		deBool							passed								= DE_TRUE;
    924 		for (deUint32 i = 0; passed && i < m_params.targetsCount; ++i)
    925 		{
    926 			fillUpResource(srcBuffer, *(targets[0][i]), m_context, m_params);
    927 			readUpResource(*(targets[1][i]), dstBuffer, m_context, m_params);
    928 			passed = checkData(*dstMemory, 2, m_context, m_params);
    929 		}
    930 
    931 		return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
    932 	}
    933 private:
    934 	BindingCaseParameters				m_params;
    935 };
    936 
    937 template<typename TInstance>
    938 class MemoryBindingTest : public TestCase
    939 {
    940 public:
    941 										MemoryBindingTest					(tcu::TestContext&		testCtx,
    942 																			 const std::string&		name,
    943 																			 const std::string&		description,
    944 																			 BindingCaseParameters	params)
    945 										: TestCase							(testCtx, name, description)
    946 										, m_params							(params)
    947 	{
    948 	}
    949 
    950 	virtual								~MemoryBindingTest					(void)
    951 	{
    952 	}
    953 
    954 	virtual TestInstance*				createInstance						(Context&				ctx) const
    955 	{
    956 		return new TInstance(ctx, m_params);
    957 	}
    958 
    959 private:
    960 	BindingCaseParameters				m_params;
    961 };
    962 
    963 } // unnamed namespace
    964 
    965 tcu::TestCaseGroup* createMemoryBindingTests (tcu::TestContext& testCtx)
    966 {
    967 	de::MovePtr<tcu::TestCaseGroup>		group								(new tcu::TestCaseGroup(testCtx, "binding", "Memory binding tests."));
    968 
    969 	de::MovePtr<tcu::TestCaseGroup>		regular								(new tcu::TestCaseGroup(testCtx, "regular", "Basic memory binding tests."));
    970 	de::MovePtr<tcu::TestCaseGroup>		aliasing							(new tcu::TestCaseGroup(testCtx, "aliasing", "Memory binding tests with aliasing of two resources."));
    971 
    972 	de::MovePtr<tcu::TestCaseGroup>		regular_suballocated				(new tcu::TestCaseGroup(testCtx, "suballocated", "Basic memory binding tests with suballocated memory."));
    973 	de::MovePtr<tcu::TestCaseGroup>		regular_dedicated					(new tcu::TestCaseGroup(testCtx, "dedicated", "Basic memory binding tests with deditatedly allocated memory."));
    974 
    975 	de::MovePtr<tcu::TestCaseGroup>		aliasing_suballocated				(new tcu::TestCaseGroup(testCtx, "suballocated", "Memory binding tests with aliasing of two resources with suballocated mamory."));
    976 
    977 	const VkDeviceSize					allocationSizes[]					= {	33, 257, 4087, 8095, 1*1024*1024 + 1	};
    978 
    979 	for (deUint32 sizeNdx = 0u; sizeNdx < DE_LENGTH_OF_ARRAY(allocationSizes); ++sizeNdx )
    980 	{
    981 		const VkDeviceSize				bufferSize							= allocationSizes[sizeNdx];
    982 		const BindingCaseParameters		params								= makeBindingCaseParameters(10, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, bufferSize);
    983 		std::ostringstream				testName;
    984 
    985 		testName << "buffer_" << bufferSize;
    986 		regular_suballocated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkBuffer, DE_FALSE> >(testCtx, testName.str(), " ", params));
    987 		regular_dedicated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkBuffer, DE_TRUE> >(testCtx, testName.str(), " ", params));
    988 		aliasing_suballocated->addChild(new MemoryBindingTest<AliasedMemoryBindingInstance<VkBuffer, DE_FALSE> >(testCtx, testName.str(), " ", params));
    989 	}
    990 
    991 	const deUint32						imageSizes[]						= {	8, 33, 257	};
    992 
    993 	for (deUint32 widthNdx = 0u; widthNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++widthNdx )
    994 	for (deUint32 heightNdx = 0u; heightNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++heightNdx )
    995 	{
    996 		const deUint32					width								= imageSizes[widthNdx];
    997 		const deUint32					height								= imageSizes[heightNdx];
    998 		const BindingCaseParameters		regularparams						= makeBindingCaseParameters(10, width, height);
    999 		std::ostringstream				testName;
   1000 
   1001 		testName << "image_" << width << '_' << height;
   1002 		regular_suballocated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkImage, DE_FALSE> >(testCtx, testName.str(), " ", regularparams));
   1003 		regular_dedicated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkImage, DE_TRUE> >(testCtx, testName.str(), "", regularparams));
   1004 		aliasing_suballocated->addChild(new MemoryBindingTest<AliasedMemoryBindingInstance<VkImage, DE_FALSE> >(testCtx, testName.str(), " ", regularparams));
   1005 	}
   1006 
   1007 	regular->addChild(regular_suballocated.release());
   1008 	regular->addChild(regular_dedicated.release());
   1009 
   1010 	aliasing->addChild(aliasing_suballocated.release());
   1011 
   1012 	group->addChild(regular.release());
   1013 	group->addChild(aliasing.release());
   1014 
   1015 	return group.release();
   1016 }
   1017 
   1018 } // memory
   1019 } // vkt
   1020