/*-------------------------------------------------------------------------
 * 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
