/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Memory binding test excercising VK_KHR_bind_memory2 extension.
 *//*--------------------------------------------------------------------*/

#include "vktMemoryBindingTests.hpp"

#include "vktTestCase.hpp"
#include "tcuTestLog.hpp"

#include "vkPlatform.hpp"
#include "gluVarType.hpp"
#include "deStringUtil.hpp"
#include "vkPrograms.hpp"
#include "vkQueryUtil.hpp"
#include "vkRefUtil.hpp"
#include "deSharedPtr.hpp"
#include "vktTestCase.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkImageUtil.hpp"

#include <algorithm>

namespace vkt
{
namespace memory
{
namespace
{

using namespace vk;

typedef const VkMemoryDedicatedAllocateInfo									ConstDedicatedInfo;
typedef de::SharedPtr<Move<VkDeviceMemory> >								MemoryRegionPtr;
typedef std::vector<MemoryRegionPtr>										MemoryRegionsList;
typedef de::SharedPtr<Move<VkBuffer> >										BufferPtr;
typedef std::vector<BufferPtr>												BuffersList;
typedef de::SharedPtr<Move<VkImage> >										ImagePtr;
typedef std::vector<ImagePtr>												ImagesList;
typedef std::vector<VkBindBufferMemoryInfo>									BindBufferMemoryInfosList;
typedef std::vector<VkBindImageMemoryInfo>									BindImageMemoryInfosList;

class MemoryMappingRAII
{
public:
										MemoryMappingRAII					(const DeviceInterface&	deviceInterface,
																			 const VkDevice&		device,
																			 VkDeviceMemory			deviceMemory,
																			 VkDeviceSize			offset,
																			 VkDeviceSize			size,
																			 VkMemoryMapFlags		flags)
										: vk								(deviceInterface)
										, dev								(device)
										, memory							(deviceMemory)
										, hostPtr							(DE_NULL)

	{
		vk.mapMemory(dev, memory, offset, size, flags, &hostPtr);
	}

										~MemoryMappingRAII					()
	{
		vk.unmapMemory(dev, memory);
		hostPtr = DE_NULL;
	}

	void*								ptr									()
	{
		return hostPtr;
	}

	void								flush								()
	{
		const VkMappedMemoryRange		range								= makeMemoryRange(0, VK_WHOLE_SIZE);
		VK_CHECK(vk.flushMappedMemoryRanges(dev, 1u, &range));
	}

	void								invalidate							()
	{
		const VkMappedMemoryRange		range								= makeMemoryRange(0, VK_WHOLE_SIZE);
		VK_CHECK(vk.invalidateMappedMemoryRanges(dev, 1u, &range));
	}


protected:
	const DeviceInterface&				vk;
	const VkDevice&						dev;
	VkDeviceMemory						memory;
	void*								hostPtr;

	const VkMappedMemoryRange			makeMemoryRange						(VkDeviceSize			offset,
																			 VkDeviceSize			size)
	{
		const VkMappedMemoryRange		range								=
		{
			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
			DE_NULL,
			memory,
			offset,
			size
		};
		return range;
	}
};

class SimpleRandomGenerator
{
public:
										SimpleRandomGenerator				(deUint32				seed)
										: value								(seed)
	{}
	deUint32							getNext								()
	{
		value += 1;
		value ^= (value << 21);
		value ^= (value >> 15);
		value ^= (value << 4);
		return value;
	}
protected:
	deUint32							value;
};

struct BindingCaseParameters
{
	VkBufferCreateFlags					flags;
	VkBufferUsageFlags					usage;
	VkSharingMode						sharing;
	VkDeviceSize						bufferSize;
	VkExtent3D							imageSize;
	deUint32							targetsCount;
	VkImageCreateFlags					imageCreateFlags;
	bool								usePriority;
};

BindingCaseParameters					makeBindingCaseParameters			(deUint32				targetsCount,
																			 deUint32				width,
																			 deUint32				height,
																			 VkImageCreateFlags		imageCreateFlags,
																			 bool					usePriority)
{
	BindingCaseParameters				params;
	deMemset(&params, 0, sizeof(BindingCaseParameters));
	params.imageSize.width = width;
	params.imageSize.height = height;
	params.imageSize.depth = 1;
	params.bufferSize = params.imageSize.width * params.imageSize.height * params.imageSize.depth * sizeof(deUint32);
	params.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	params.targetsCount = targetsCount;
	params.imageCreateFlags = imageCreateFlags;
	params.usePriority = usePriority;
	return params;
}

BindingCaseParameters					makeBindingCaseParameters			(deUint32				targetsCount,
																			 VkBufferUsageFlags		usage,
																			 VkSharingMode			sharing,
																			 VkDeviceSize			bufferSize,
																			 VkImageCreateFlags		imageCreateFlags,
																			 bool					usePriority)
{
	BindingCaseParameters				params								=
	{
		0,																	// VkBufferCreateFlags	flags;
		usage,																// VkBufferUsageFlags	usage;
		sharing,															// VkSharingMode		sharing;
		bufferSize,															// VkDeviceSize			bufferSize;
		{0u, 0u, 0u},														// VkExtent3D			imageSize;
		targetsCount,														// deUint32				targetsCount;
		imageCreateFlags,													// VkImageCreateFlags	imageCreateFlags
		usePriority,														// bool					usePriority
	};
	return params;
}

VkImageCreateInfo						makeImageCreateInfo					(BindingCaseParameters&	params)
{
	const VkImageCreateInfo				imageParams							=
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,								// VkStructureType		sType;
		DE_NULL,															// const void*			pNext;
		params.imageCreateFlags,											// VkImageCreateFlags	flags;
		VK_IMAGE_TYPE_2D,													// VkImageType			imageType;
		VK_FORMAT_R8G8B8A8_UINT,											// VkFormat				format;
		params.imageSize,													// VkExtent3D			extent;
		1u,																	// deUint32				mipLevels;
		1u,																	// deUint32				arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,												// VkSampleCountFlagBits samples;
		VK_IMAGE_TILING_LINEAR,												// VkImageTiling		tiling;
		VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,	// VkImageUsageFlags	usage;
		VK_SHARING_MODE_EXCLUSIVE,											// VkSharingMode		sharingMode;
		0u,																	// deUint32				queueFamilyIndexCount;
		DE_NULL,															// const deUint32*		pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout		initialLayout;
	};
	return imageParams;
}

VkBufferCreateInfo						makeBufferCreateInfo				(Context&				ctx,
																			 BindingCaseParameters&	params)
{
	const deUint32						queueFamilyIndex					= ctx.getUniversalQueueFamilyIndex();
	VkBufferCreateInfo					bufferParams						=
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,								// VkStructureType		sType;
		DE_NULL,															// const void*			pNext;
		params.flags,														// VkBufferCreateFlags	flags;
		params.bufferSize,													// VkDeviceSize			size;
		params.usage,														// VkBufferUsageFlags	usage;
		params.sharing,														// VkSharingMode		sharingMode;
		1u,																	// uint32_t				queueFamilyIndexCount;
		&queueFamilyIndex,													// const uint32_t*		pQueueFamilyIndices;
	};
	return bufferParams;
}

const VkMemoryAllocateInfo				makeMemoryAllocateInfo				(VkMemoryRequirements&	memReqs,
																			 const void*	next)
{
	const deUint32						heapTypeIndex						= (deUint32)deCtz32(memReqs.memoryTypeBits);
	const VkMemoryAllocateInfo			allocateParams						=
	{
		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,								// VkStructureType		sType;
		next,																// const void*			pNext;
		memReqs.size,														// VkDeviceSize			allocationSize;
		heapTypeIndex,														// uint32_t				memoryTypeIndex;
	};
	return allocateParams;
}

enum MemoryHostVisibility
{
	MemoryAny,
	MemoryHostVisible
};

deUint32								selectMatchingMemoryType			(Context&				ctx,
																			 VkMemoryRequirements&	memReqs,
																			 MemoryHostVisibility	memoryVisibility)
{
	const VkPhysicalDevice				vkPhysicalDevice					= ctx.getPhysicalDevice();
	const InstanceInterface&			vkInstance							= ctx.getInstanceInterface();
	VkPhysicalDeviceMemoryProperties	memoryProperties;

	vkInstance.getPhysicalDeviceMemoryProperties(vkPhysicalDevice, &memoryProperties);
	if (memoryVisibility == MemoryHostVisible)
	{
		for (deUint32 typeNdx = 0; typeNdx < memoryProperties.memoryTypeCount; ++typeNdx)
		{
			const deBool				isInAllowed							= (memReqs.memoryTypeBits & (1u << typeNdx)) != 0u;
			const deBool				hasRightProperties					= (memoryProperties.memoryTypes[typeNdx].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0u;
			if (isInAllowed && hasRightProperties)
				return typeNdx;
		}
	}
	return (deUint32)deCtz32(memReqs.memoryTypeBits);
}

const VkMemoryAllocateInfo				makeMemoryAllocateInfo				(Context&				ctx,
																			 VkMemoryRequirements&	memReqs,
																			 MemoryHostVisibility	memoryVisibility)
{
	const deUint32						heapTypeIndex						= selectMatchingMemoryType(ctx, memReqs, memoryVisibility);
	const VkMemoryAllocateInfo			allocateParams						=
	{
		VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,								// VkStructureType		sType;
		DE_NULL,															// const void*			pNext;
		memReqs.size,														// VkDeviceSize			allocationSize;
		heapTypeIndex,														// uint32_t				memoryTypeIndex;
	};
	return allocateParams;
}

ConstDedicatedInfo						makeDedicatedAllocationInfo			(VkBuffer				buffer)
{
	ConstDedicatedInfo					dedicatedAllocationInfo				=
	{
		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,				// VkStructureType		sType
		DE_NULL,															// const void*			pNext
		DE_NULL,															// VkImage				image
		buffer																// VkBuffer				buffer
	};
	return dedicatedAllocationInfo;
}

ConstDedicatedInfo						makeDedicatedAllocationInfo			(VkImage				image)
{
	ConstDedicatedInfo					dedicatedAllocationInfo				=
	{
		VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,				// VkStructureType		sType
		DE_NULL,															// const void*			pNext
		image,																// VkImage				image
		DE_NULL																// VkBuffer				buffer
	};
	return dedicatedAllocationInfo;
}

const VkBindBufferMemoryInfo			makeBufferMemoryBindingInfo			(VkBuffer				buffer,
																			 VkDeviceMemory			memory)
{
	const VkBindBufferMemoryInfo		bufferMemoryBinding					=
	{
		VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR,						// VkStructureType		sType;
		DE_NULL,															// const void*			pNext;
		buffer,																// VkBuffer				buffer;
		memory,																// VkDeviceMemory		memory;
		0u,																	// VkDeviceSize			memoryOffset;
	};
	return bufferMemoryBinding;
}

const VkBindImageMemoryInfo				makeImageMemoryBindingInfo			(VkImage				image,
																			 VkDeviceMemory			memory)
{
	const VkBindImageMemoryInfo		imageMemoryBinding					=
	{
		VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR,						// VkStructureType		sType;
		DE_NULL,															// const void*			pNext;
		image,																// VkImage				image;
		memory,																// VkDeviceMemory		memory;
		0u,																	// VkDeviceSize			memoryOffset;
	};
	return imageMemoryBinding;
}

const VkMemoryPriorityAllocateInfoEXT	makeMemoryPriorityAllocateInfo		(const void *	pNext,
																			 float			priority)
{
	const VkMemoryPriorityAllocateInfoEXT	info						=
	{
		VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT,				// VkStructureType		sType;
		pNext,																// const void*			pNext;
		priority,															// float				priority
	};
	return info;
}

enum TransferDirection
{
	TransferToResource														= 0,
	TransferFromResource													= 1
};

const VkBufferMemoryBarrier				makeMemoryBarrierInfo				(VkBuffer				buffer,
																			 VkDeviceSize			size,
																			 TransferDirection		direction)
{
	const deBool fromRes													= direction == TransferFromResource;
	const VkAccessFlags					srcMask								= static_cast<VkAccessFlags>(fromRes ? VK_ACCESS_HOST_WRITE_BIT : VK_ACCESS_TRANSFER_WRITE_BIT);
	const VkAccessFlags					dstMask								= static_cast<VkAccessFlags>(fromRes ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_HOST_READ_BIT);
	const VkBufferMemoryBarrier			bufferBarrier						=
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,							// VkStructureType		sType;
		DE_NULL,															// const void*			pNext;
		srcMask,															// VkAccessFlags		srcAccessMask;
		dstMask,															// VkAccessFlags		dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,											// deUint32				srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,											// deUint32				dstQueueFamilyIndex;
		buffer,																// VkBuffer				buffer;
		0u,																	// VkDeviceSize			offset;
		size																// VkDeviceSize			size;
	};
	return bufferBarrier;
}

const VkImageMemoryBarrier				makeMemoryBarrierInfo				(VkImage				image,
																			 VkAccessFlags			srcAccess,
																			 VkAccessFlags			dstAccess,
																			 VkImageLayout			oldLayout,
																			 VkImageLayout			newLayout)
{
	const VkImageAspectFlags			aspect								= VK_IMAGE_ASPECT_COLOR_BIT;
	const VkImageMemoryBarrier			imageBarrier						=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,								// VkStructureType		sType;
		DE_NULL,															// const void*			pNext;
		srcAccess,															// VkAccessFlags		srcAccessMask;
		dstAccess,															// VkAccessFlags		dstAccessMask;
		oldLayout,															// VkImageLayout		oldLayout;
		newLayout,															// VkImageLayout		newLayout;
		VK_QUEUE_FAMILY_IGNORED,											// deUint32				srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,											// deUint32				dstQueueFamilyIndex;
		image,																// VkImage				image;
		{																	// VkImageSubresourceRange subresourceRange;
			aspect,															// VkImageAspectFlags	aspect;
			0u,																// deUint32				baseMipLevel;
			1u,																// deUint32				mipLevels;
			0u,																// deUint32				baseArraySlice;
			1u,																// deUint32				arraySize;
		}
	};
	return imageBarrier;
}

Move<VkCommandBuffer>					createCommandBuffer					(const DeviceInterface&	vk,
																			 VkDevice				device,
																			 VkCommandPool			commandPool)
{
	const VkCommandBufferAllocateInfo allocInfo =
	{
		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
		DE_NULL,
		commandPool,
		VK_COMMAND_BUFFER_LEVEL_PRIMARY,
		1
	};
	return allocateCommandBuffer(vk, device, &allocInfo);
}


template<typename TTarget>
void									createBindingTargets				(std::vector<de::SharedPtr<Move<TTarget> > >&
																									targets,
																			 Context&				ctx,
																			 BindingCaseParameters	params);

template<>
void									createBindingTargets<VkBuffer>		(BuffersList&			targets,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	const deUint32						count								= params.targetsCount;
	const VkDevice						vkDevice							= ctx.getDevice();
	const DeviceInterface&				vk									= ctx.getDeviceInterface();

	targets.reserve(count);
	for (deUint32 i = 0u; i < count; ++i)
	{
		VkBufferCreateInfo				bufferParams						= makeBufferCreateInfo(ctx, params);
		targets.push_back(BufferPtr(new Move<VkBuffer>(createBuffer(vk, vkDevice, &bufferParams))));
	}
}

template<>
void									createBindingTargets<VkImage>		(ImagesList&			targets,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	const deUint32						count								= params.targetsCount;
	const VkDevice						vkDevice							= ctx.getDevice();
	const DeviceInterface&				vk									= ctx.getDeviceInterface();

	targets.reserve(count);
	for (deUint32 i = 0u; i < count; ++i)
	{
		VkImageCreateInfo				imageParams							= makeImageCreateInfo(params);
		targets.push_back(ImagePtr(new Move<VkImage>(createImage(vk, vkDevice, &imageParams))));
	}
}

template<typename TTarget, deBool TDedicated>
void									createMemory						(std::vector<de::SharedPtr<Move<TTarget> > >&
																									targets,
																			 MemoryRegionsList&		memory,
																			 Context&				ctx,
																			 BindingCaseParameters	params);

template<>
void									createMemory<VkBuffer, DE_FALSE>	(BuffersList&			targets,
																			 MemoryRegionsList&		memory,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	DE_UNREF(params);
	const deUint32						count								= static_cast<deUint32>(targets.size());
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	const VkDevice						vkDevice							= ctx.getDevice();

	memory.reserve(count);
	for (deUint32 i = 0; i < count; ++i)
	{
		VkMemoryRequirements			memReqs;

		vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);

		VkMemoryPriorityAllocateInfoEXT	priority							= makeMemoryPriorityAllocateInfo(DE_NULL, ((float)i)/((float)count));
		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, params.usePriority ? &priority : DE_NULL);
		VkDeviceMemory					rawMemory							= DE_NULL;

		vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
		memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
	}
}

template<>
void									createMemory<VkImage, DE_FALSE>		(ImagesList&			targets,
																			 MemoryRegionsList&		memory,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	DE_UNREF(params);
	const deUint32						count								= static_cast<deUint32>(targets.size());
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	const VkDevice						vkDevice							= ctx.getDevice();

	memory.reserve(count);
	for (deUint32 i = 0; i < count; ++i)
	{
		VkMemoryRequirements			memReqs;
		vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);

		VkMemoryPriorityAllocateInfoEXT	priority							= makeMemoryPriorityAllocateInfo(DE_NULL, ((float)i)/((float)count));
		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, params.usePriority ? &priority : DE_NULL);
		VkDeviceMemory					rawMemory							= DE_NULL;

		vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
		memory.push_back(de::SharedPtr<Move<VkDeviceMemory> >(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
	}
}

template<>
void									createMemory<VkBuffer, DE_TRUE>		(BuffersList&			targets,
																			 MemoryRegionsList&		memory,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	DE_UNREF(params);
	const deUint32						count								= static_cast<deUint32>(targets.size());
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	const VkDevice						vkDevice							= ctx.getDevice();

	memory.reserve(count);
	for (deUint32 i = 0; i < count; ++i)
	{
		VkMemoryRequirements			memReqs;

		vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);

		ConstDedicatedInfo				dedicatedAllocationInfo				= makeDedicatedAllocationInfo(**targets[i]);
		VkMemoryPriorityAllocateInfoEXT	priority							= makeMemoryPriorityAllocateInfo(&dedicatedAllocationInfo, ((float)i)/((float)count));
		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, params.usePriority ? &priority : (const void *)&dedicatedAllocationInfo);
		VkDeviceMemory					rawMemory							= DE_NULL;

		vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
		memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
	}
}

template<>
void									createMemory<VkImage, DE_TRUE>		(ImagesList&			targets,
																			 MemoryRegionsList&		memory,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	DE_UNREF(params);
	const deUint32						count								= static_cast<deUint32>(targets.size());
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	const VkDevice						vkDevice							= ctx.getDevice();

	memory.reserve(count);
	for (deUint32 i = 0; i < count; ++i)
	{
		VkMemoryRequirements			memReqs;
		vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);

		ConstDedicatedInfo				dedicatedAllocationInfo				= makeDedicatedAllocationInfo(**targets[i]);
		VkMemoryPriorityAllocateInfoEXT	priority							= makeMemoryPriorityAllocateInfo(&dedicatedAllocationInfo, ((float)i)/((float)count));
		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, params.usePriority ? &priority : (const void *)&dedicatedAllocationInfo);
		VkDeviceMemory					rawMemory							= DE_NULL;

		vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
		memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
	}
}

template<typename TTarget>
void									makeBinding							(std::vector<de::SharedPtr<Move<TTarget> > >&
																									targets,
																			 MemoryRegionsList&		memory,
																			 Context&				ctx,
																			 BindingCaseParameters	params);

template<>
void									makeBinding<VkBuffer>				(BuffersList&			targets,
																			 MemoryRegionsList&		memory,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	DE_UNREF(params);
	const deUint32						count								= static_cast<deUint32>(targets.size());
	const VkDevice						vkDevice							= ctx.getDevice();
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	BindBufferMemoryInfosList			bindMemoryInfos;

	for (deUint32 i = 0; i < count; ++i)
	{
		bindMemoryInfos.push_back(makeBufferMemoryBindingInfo(**targets[i], **memory[i]));
	}

	VK_CHECK(vk.bindBufferMemory2(vkDevice, count, &bindMemoryInfos.front()));
}

template<>
void									makeBinding<VkImage>				(ImagesList&			targets,
																			 MemoryRegionsList&		memory,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	DE_UNREF(params);
	const deUint32						count								= static_cast<deUint32>(targets.size());
	const VkDevice						vkDevice							= ctx.getDevice();
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	BindImageMemoryInfosList			bindMemoryInfos;

	for (deUint32 i = 0; i < count; ++i)
	{
		bindMemoryInfos.push_back(makeImageMemoryBindingInfo(**targets[i], **memory[i]));
	}

	VK_CHECK(vk.bindImageMemory2(vkDevice, count, &bindMemoryInfos.front()));
}

template <typename TTarget>
void									fillUpResource						(Move<VkBuffer>&		source,
																			 Move<TTarget>&			target,
																			 Context&				ctx,
																			 BindingCaseParameters	params);

template <>
void									fillUpResource<VkBuffer>			(Move<VkBuffer>&		source,
																			 Move<VkBuffer>&		target,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	const VkDevice						vkDevice							= ctx.getDevice();
	const VkQueue						queue								= ctx.getUniversalQueue();

	const VkBufferMemoryBarrier			srcBufferBarrier					= makeMemoryBarrierInfo(*source, params.bufferSize, TransferFromResource);
	const VkBufferMemoryBarrier			dstBufferBarrier					= makeMemoryBarrierInfo(*target, params.bufferSize, TransferToResource);

	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);
	VkBufferCopy						bufferCopy							= { 0u, 0u, params.bufferSize };

	beginCommandBuffer(vk, *cmdBuffer);
	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);
	vk.cmdCopyBuffer(*cmdBuffer, *source, *target, 1, &bufferCopy);
	vk.cmdPipelineBarrier(*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);
	endCommandBuffer(vk, *cmdBuffer);

	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
}

template <>
void									fillUpResource<VkImage>				(Move<VkBuffer>&		source,
																			 Move<VkImage>&			target,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	const VkDevice						vkDevice							= ctx.getDevice();
	const VkQueue						queue								= ctx.getUniversalQueue();

	const VkBufferMemoryBarrier			srcBufferBarrier					= makeMemoryBarrierInfo(*source, params.bufferSize, TransferFromResource);
	const VkImageMemoryBarrier			preImageBarrier						= makeMemoryBarrierInfo(*target, 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
	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);

	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);

	const VkBufferImageCopy				copyRegion							=
	{
		0u,																	// VkDeviceSize			bufferOffset;
		params.imageSize.width,												// deUint32				bufferRowLength;
		params.imageSize.height,											// deUint32				bufferImageHeight;
		{
			VK_IMAGE_ASPECT_COLOR_BIT,										// VkImageAspectFlags	aspect;
			0u,																// deUint32				mipLevel;
			0u,																// deUint32				baseArrayLayer;
			1u,																// deUint32				layerCount;
		},																	// VkImageSubresourceLayers imageSubresource;
		{ 0, 0, 0 },														// VkOffset3D			imageOffset;
		params.imageSize													// VkExtent3D			imageExtent;
	};

	beginCommandBuffer(vk, *cmdBuffer);
	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 1, &preImageBarrier);
	vk.cmdCopyBufferToImage(*cmdBuffer, *source, *target, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, (&copyRegion));
	vk.cmdPipelineBarrier(*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);
	endCommandBuffer(vk, *cmdBuffer);

	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
}

template <typename TTarget>
void									readUpResource						(Move<TTarget>&			source,
																			 Move<VkBuffer>&		target,
																			 Context&				ctx,
																			 BindingCaseParameters	params);

template <>
void									readUpResource						(Move<VkBuffer>&		source,
																			 Move<VkBuffer>&		target,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	fillUpResource(source, target, ctx, params);
}

template <>
void									readUpResource						(Move<VkImage>&			source,
																			 Move<VkBuffer>&		target,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	const VkDevice						vkDevice							= ctx.getDevice();
	const VkQueue						queue								= ctx.getUniversalQueue();

	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);

	beginCommandBuffer(vk, *cmdBuffer);
	copyImageToBuffer(vk, *cmdBuffer, *source, *target, tcu::IVec2(params.imageSize.width, params.imageSize.height), VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
	endCommandBuffer(vk, *cmdBuffer);

	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
}


template <typename TTarget>
void									layoutTransitionResource			(Move<TTarget>&			target,
																			 Context&				ctx);

template <>
void									layoutTransitionResource			(Move<VkBuffer>&		target,
																			 Context&				ctx)
{
	DE_UNREF(target);
	DE_UNREF(ctx);
}

template <>
void									layoutTransitionResource<VkImage>	(Move<VkImage>&			target,
																			 Context&				ctx)
{
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	const VkDevice						vkDevice							= ctx.getDevice();
	const VkQueue						queue								= ctx.getUniversalQueue();

	const VkImageMemoryBarrier			preImageBarrier						= makeMemoryBarrierInfo(*target, 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);

	Move<VkCommandPool>					commandPool							= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
	Move<VkCommandBuffer>				cmdBuffer							= createCommandBuffer(vk, vkDevice, *commandPool);

	beginCommandBuffer(vk, *cmdBuffer);
	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, &preImageBarrier);
	endCommandBuffer(vk, *cmdBuffer);

	submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
}


void									createBuffer						(Move<VkBuffer>&		buffer,
																			 Move<VkDeviceMemory>&	memory,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	const VkDevice						vkDevice							= ctx.getDevice();
	VkBufferCreateInfo					bufferParams						= makeBufferCreateInfo(ctx, params);
	VkMemoryRequirements				memReqs;

	buffer = createBuffer(vk, vkDevice, &bufferParams);
	vk.getBufferMemoryRequirements(vkDevice, *buffer, &memReqs);

	const VkMemoryAllocateInfo			memAlloc							= makeMemoryAllocateInfo(ctx, memReqs, MemoryHostVisible);
	VkDeviceMemory						rawMemory							= DE_NULL;

	vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
	memory = Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL));
	VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, *memory, 0u));
}

void									pushData							(VkDeviceMemory			memory,
																			 deUint32				dataSeed,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	const VkDevice						vkDevice							= ctx.getDevice();
	MemoryMappingRAII					hostMemory							(vk, vkDevice, memory, 0u, params.bufferSize, 0u);
	deUint8*							hostBuffer							= static_cast<deUint8*>(hostMemory.ptr());
	SimpleRandomGenerator				random								(dataSeed);

	for (deUint32 i = 0u; i < params.bufferSize; ++i)
	{
		hostBuffer[i] = static_cast<deUint8>(random.getNext() & 0xFFu);
	}
	hostMemory.flush();
}

deBool									checkData							(VkDeviceMemory			memory,
																			 deUint32				dataSeed,
																			 Context&				ctx,
																			 BindingCaseParameters	params)
{
	const DeviceInterface&				vk									= ctx.getDeviceInterface();
	const VkDevice						vkDevice							= ctx.getDevice();
	MemoryMappingRAII					hostMemory							(vk, vkDevice, memory, 0u, params.bufferSize, 0u);
	deUint8*							hostBuffer							= static_cast<deUint8*>(hostMemory.ptr());
	SimpleRandomGenerator				random								(dataSeed);

	hostMemory.invalidate();

	for (deUint32 i = 0u; i < params.bufferSize; ++i)
	{
		if (hostBuffer[i] != static_cast<deUint8>(random.getNext() & 0xFFu) )
			return DE_FALSE;
	}
	return DE_TRUE;
}

template<typename TTarget, deBool TDedicated>
class MemoryBindingInstance : public TestInstance
{
public:
										MemoryBindingInstance				(Context&				ctx,
																			 BindingCaseParameters	params)
										: TestInstance						(ctx)
										, m_params							(params)
	{
	}

	virtual tcu::TestStatus				iterate								(void)
	{
		std::vector<de::SharedPtr<Move<TTarget> > >
										targets;
		MemoryRegionsList				memory;

		createBindingTargets<TTarget>(targets, m_context, m_params);
		createMemory<TTarget, TDedicated>(targets, memory, m_context, m_params);
		makeBinding<TTarget>(targets, memory, m_context, m_params);

		Move<VkBuffer>					srcBuffer;
		Move<VkDeviceMemory>			srcMemory;

		createBuffer(srcBuffer, srcMemory, m_context, m_params);
		pushData(*srcMemory, 1, m_context, m_params);

		Move<VkBuffer>					dstBuffer;
		Move<VkDeviceMemory>			dstMemory;

		createBuffer(dstBuffer, dstMemory, m_context, m_params);

		deBool							passed								= DE_TRUE;
		for (deUint32 i = 0; passed && i < m_params.targetsCount; ++i)
		{
			fillUpResource(srcBuffer, *targets[i], m_context, m_params);
			readUpResource(*targets[i], dstBuffer, m_context, m_params);
			passed = checkData(*dstMemory, 1, m_context, m_params);
		}

		return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
	}
private:
	BindingCaseParameters				m_params;
};

template<typename TTarget, deBool TDedicated>
class AliasedMemoryBindingInstance : public TestInstance
{
public:
										AliasedMemoryBindingInstance		(Context&				ctx,
																			 BindingCaseParameters	params)
										: TestInstance						(ctx)
										, m_params							(params)
	{
	}

	virtual tcu::TestStatus				iterate								(void)
	{
		std::vector<de::SharedPtr<Move<TTarget> > >
										targets[2];
		MemoryRegionsList				memory;

		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(targets); ++i)
			createBindingTargets<TTarget>(targets[i], m_context, m_params);
		createMemory<TTarget, TDedicated>(targets[0], memory, m_context, m_params);
		for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(targets); ++i)
			makeBinding<TTarget>(targets[i], memory, m_context, m_params);

		Move<VkBuffer>					srcBuffer;
		Move<VkDeviceMemory>			srcMemory;

		createBuffer(srcBuffer, srcMemory, m_context, m_params);
		pushData(*srcMemory, 2, m_context, m_params);

		Move<VkBuffer>					dstBuffer;
		Move<VkDeviceMemory>			dstMemory;

		createBuffer(dstBuffer, dstMemory, m_context, m_params);

		deBool							passed								= DE_TRUE;
		for (deUint32 i = 0; passed && i < m_params.targetsCount; ++i)
		{
			// Do a layout transition on alias 1 before we transition and write to alias 0
			layoutTransitionResource(*(targets[1][i]), m_context);
			fillUpResource(srcBuffer, *(targets[0][i]), m_context, m_params);
			readUpResource(*(targets[1][i]), dstBuffer, m_context, m_params);
			passed = checkData(*dstMemory, 2, m_context, m_params);
		}

		return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
	}
private:
	BindingCaseParameters				m_params;
};

template<typename TInstance>
class MemoryBindingTest : public TestCase
{
public:
										MemoryBindingTest					(tcu::TestContext&		testCtx,
																			 const std::string&		name,
																			 const std::string&		description,
																			 BindingCaseParameters	params)
										: TestCase							(testCtx, name, description)
										, m_params							(params)
	{
	}

	virtual								~MemoryBindingTest					(void)
	{
	}

	virtual TestInstance*				createInstance						(Context&				ctx) const
	{
		return new TInstance(ctx, m_params);
	}

	virtual void						checkSupport						(Context&				ctx) const
	{
		ctx.requireDeviceFunctionality("VK_KHR_bind_memory2");

		if (m_params.usePriority && !ctx.getMemoryPriorityFeaturesEXT().memoryPriority)
			TCU_THROW(NotSupportedError, "VK_EXT_memory_priority Not supported");
	}

private:
	BindingCaseParameters				m_params;
};

} // unnamed namespace

tcu::TestCaseGroup* createMemoryBindingTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>		group								(new tcu::TestCaseGroup(testCtx, "binding", "Memory binding tests."));

	for (int i = 0; i < 2; ++i)
	{
		bool usePriority = i != 0;
		de::MovePtr<tcu::TestCaseGroup>		regular								(new tcu::TestCaseGroup(testCtx, "regular", "Basic memory binding tests."));
		de::MovePtr<tcu::TestCaseGroup>		aliasing							(new tcu::TestCaseGroup(testCtx, "aliasing", "Memory binding tests with aliasing of two resources."));

		de::MovePtr<tcu::TestCaseGroup>		regular_suballocated				(new tcu::TestCaseGroup(testCtx, "suballocated", "Basic memory binding tests with suballocated memory."));
		de::MovePtr<tcu::TestCaseGroup>		regular_dedicated					(new tcu::TestCaseGroup(testCtx, "dedicated", "Basic memory binding tests with deditatedly allocated memory."));

		de::MovePtr<tcu::TestCaseGroup>		aliasing_suballocated				(new tcu::TestCaseGroup(testCtx, "suballocated", "Memory binding tests with aliasing of two resources with suballocated mamory."));

		const VkDeviceSize					allocationSizes[]					= {	33, 257, 4087, 8095, 1*1024*1024 + 1	};

		for (deUint32 sizeNdx = 0u; sizeNdx < DE_LENGTH_OF_ARRAY(allocationSizes); ++sizeNdx )
		{
			const VkDeviceSize				bufferSize							= allocationSizes[sizeNdx];
			const BindingCaseParameters		params								= makeBindingCaseParameters(10, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, bufferSize, 0u, usePriority);
			const BindingCaseParameters		aliasparams							= makeBindingCaseParameters(10, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, bufferSize, VK_IMAGE_CREATE_ALIAS_BIT, usePriority);
			std::ostringstream				testName;

			testName << "buffer_" << bufferSize;
			regular_suballocated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkBuffer, DE_FALSE> >(testCtx, testName.str(), " ", params));
			regular_dedicated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkBuffer, DE_TRUE> >(testCtx, testName.str(), " ", params));
			aliasing_suballocated->addChild(new MemoryBindingTest<AliasedMemoryBindingInstance<VkBuffer, DE_FALSE> >(testCtx, testName.str(), " ", aliasparams));
		}

		const deUint32						imageSizes[]						= {	8, 33, 257	};

		for (deUint32 widthNdx = 0u; widthNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++widthNdx )
		for (deUint32 heightNdx = 0u; heightNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++heightNdx )
		{
			const deUint32					width								= imageSizes[widthNdx];
			const deUint32					height								= imageSizes[heightNdx];
			const BindingCaseParameters		regularparams						= makeBindingCaseParameters(10, width, height, 0u, usePriority);
			const BindingCaseParameters		aliasparams							= makeBindingCaseParameters(10, width, height, VK_IMAGE_CREATE_ALIAS_BIT, usePriority);
			std::ostringstream				testName;

			testName << "image_" << width << '_' << height;
			regular_suballocated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkImage, DE_FALSE> >(testCtx, testName.str(), " ", regularparams));
			regular_dedicated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkImage, DE_TRUE> >(testCtx, testName.str(), "", regularparams));
			aliasing_suballocated->addChild(new MemoryBindingTest<AliasedMemoryBindingInstance<VkImage, DE_FALSE> >(testCtx, testName.str(), " ", aliasparams));
		}

		regular->addChild(regular_suballocated.release());
		regular->addChild(regular_dedicated.release());

		aliasing->addChild(aliasing_suballocated.release());
		if (usePriority) {
			de::MovePtr<tcu::TestCaseGroup>		priority	(new tcu::TestCaseGroup(testCtx, "priority", "Using VK_EXT_memory_priority."));
			priority->addChild(regular.release());
			priority->addChild(aliasing.release());
			group->addChild(priority.release());
		} else {
			group->addChild(regular.release());
			group->addChild(aliasing.release());
		}
	}

	return group.release();
}

} // memory
} // vkt
