/*-------------------------------------------------------------------------
 * 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,					// 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,					// 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,							// 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,							// VkStructureType		sType;
		DE_NULL,															// const void*			pNext;
		image,																// VkImage				image;
		memory,																// VkDeviceMemory		memory;
		0u,																	// VkDeviceSize			memoryOffset;
	};
	return imageMemoryBinding;
}

#ifndef CTS_USES_VULKANSC
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;
}
#endif

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);

#ifdef CTS_USES_VULKANSC
		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, DE_NULL);
#else
		VkMemoryPriorityAllocateInfoEXT	priority							= makeMemoryPriorityAllocateInfo(DE_NULL, ((float)i)/((float)count));
		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, params.usePriority ? &priority : DE_NULL);
#endif
		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);

#ifdef CTS_USES_VULKANSC
		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, DE_NULL);
#else
		VkMemoryPriorityAllocateInfoEXT	priority							= makeMemoryPriorityAllocateInfo(DE_NULL, ((float)i)/((float)count));
		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, params.usePriority ? &priority : DE_NULL);
#endif

		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]);
#ifdef CTS_USES_VULKANSC
		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, (const void *)&dedicatedAllocationInfo);
#else
		VkMemoryPriorityAllocateInfoEXT	priority							= makeMemoryPriorityAllocateInfo(&dedicatedAllocationInfo, ((float)i)/((float)count));
		const VkMemoryAllocateInfo		memAlloc							= makeMemoryAllocateInfo(memReqs, params.usePriority ? &priority : (const void *)&dedicatedAllocationInfo);
#endif

		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]);

#ifdef CTS_USES_VULKANSC
		const VkMemoryAllocateInfo		memAlloc						= makeMemoryAllocateInfo(memReqs, (const void *)&dedicatedAllocationInfo);
#else
		VkMemoryPriorityAllocateInfoEXT	priority						= makeMemoryPriorityAllocateInfo(&dedicatedAllocationInfo, ((float)i)/((float)count));
		const VkMemoryAllocateInfo		memAlloc						= makeMemoryAllocateInfo(memReqs, params.usePriority ? &priority : (const void *)&dedicatedAllocationInfo);
#endif

		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");

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

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."));

#ifdef CTS_USES_VULKANSC
	const int iterations = 1;
#else
	const int iterations = 2;
#endif

	for (int i = 0; i < iterations; ++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
