/*------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2018 The Khronos Group Inc.
* Copyright (c) 2018 Intel Corporation
*
* 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 VK_EXT_external_memory_host extension tests.
*//*--------------------------------------------------------------------*/

#include "vktMemoryExternalMemoryHostTests.hpp"

#include "vktTestCaseUtil.hpp"

#include "deMath.h"

#include "vkQueryUtil.hpp"
#include "vkImageUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkTypeUtil.hpp"
#include "vkCmdUtil.hpp"


#include "tcuTestLog.hpp"
#include "tcuImageCompare.hpp"

namespace vkt
{
namespace memory
{
namespace
{

using namespace vk;

inline deUint32 getBit (deUint32 src, int ndx)
{
	return (src >> ndx) & 1;
}

inline bool isBitSet (deUint32 src, int ndx)
{
	return getBit(src, ndx) != 0;
}

struct TestParams
{
	VkFormat		m_format;
	bool			m_useOffset;

	TestParams		(VkFormat f, bool offset = false) : m_format(f) , m_useOffset(offset) {}
};

class ExternalMemoryHostBaseTestInstance : public TestInstance
{
public:
									ExternalMemoryHostBaseTestInstance			(Context& context, VkDeviceSize allocationSize);
									~ExternalMemoryHostBaseTestInstance			(void);
protected:
	virtual tcu::TestStatus			iterate										(void);
	VkDeviceSize					getMinImportedHostPointerAlignment			(void);
	deUint32						getHostPointerMemoryTypeBits				(void* hostPointer);
	Move<VkDeviceMemory>			allocateMemoryFromHostPointer				(deUint32 memoryTypeIndex);
	void							logMemoryTypeIndexPropertyFlags				(deUint32 index);
	bool							findCompatibleMemoryTypeIndexToTest			(deUint32 resourceMemoryTypeBits, deUint32 hostPointerMemoryTypeBits, deUint32* outMemoryTypeIndexToTest);
	bool							findMemoryTypeIndexToTest					(deUint32 hostPointerMemoryTypeBits, deUint32* outMemoryTypeIndexToTest);

	const InstanceInterface&						m_vki;
	const DeviceInterface&							m_vkd;
	tcu::TestLog&									m_log;
	const VkDevice									m_device;
	const VkPhysicalDevice							m_physicalDevice;
	const VkQueue									m_queue;
	const vk::VkPhysicalDeviceMemoryProperties		m_memoryProps;
	VkDeviceSize									m_minImportedHostPointerAlignment;
	VkDeviceSize									m_allocationSize;
	void*											m_hostMemoryAlloc;
	Allocator&										m_allocator;
	Move<VkDeviceMemory>							m_deviceMemoryAllocatedFromHostPointer;
};

class ExternalMemoryHostRenderImageTestInstance : public ExternalMemoryHostBaseTestInstance
{
public:
									ExternalMemoryHostRenderImageTestInstance	(Context& context, TestParams testParams);
protected:
	virtual tcu::TestStatus			iterate										(void);
	Move<VkImage>					createImage									(VkImageTiling tiling);
	Move<VkImageView>				createImageView								(void);
	Move<VkBuffer>					createBindMemoryInitializeVertexBuffer		(void);
	Move<VkBuffer>					createBindMemoryResultBuffer				(void);
	Move<VkFramebuffer>				createFramebuffer							(void);
	Move<VkDescriptorSet>			createAndUpdateDescriptorSet				(void);
	Move<VkPipelineLayout>			createPipelineLayout						(void);
	Move<VkPipeline>				createPipeline								(void);
	Move<VkRenderPass>				createRenderPass							(void);
	void							clear										(VkClearColorValue color);
	void							draw										(void);
	void							copyResultImagetoBuffer						(void);
	void							prepareReferenceImage						(tcu::PixelBufferAccess& reference);

	TestParams										m_testParams;
	Move<VkImage>									m_image;
	Move<VkImageView>								m_imageView;
	Move<VkRenderPass>								m_renderPass;
	Move<VkFramebuffer>								m_framebuffer;
	Move<VkBuffer>									m_vertexBuffer;
	Move<VkBuffer>									m_resultBuffer;
	de::MovePtr<Allocation>							m_vertexBufferAllocation;
	de::MovePtr<Allocation>							m_resultBufferAllocation;
	Move<VkDescriptorPool>							m_descriptorPool;
	Move<VkDescriptorSetLayout>						m_descriptorSetLayout;
	Move<VkDescriptorSet>							m_descriptorSet;
	Move<VkShaderModule>							m_vertexShaderModule;
	Move<VkShaderModule>							m_fragmentShaderModule;
	Move<VkPipelineLayout>							m_pipelineLayout;
	Move<VkPipeline>								m_pipeline;
	Move<VkCommandPool>								m_cmdPool;
	Move<VkCommandBuffer>							m_cmdBuffer;
};

class ExternalMemoryHostSynchronizationTestInstance : public ExternalMemoryHostRenderImageTestInstance
{
public:
								ExternalMemoryHostSynchronizationTestInstance	(Context& context, TestParams testParams);
protected:
	virtual tcu::TestStatus		iterate											(void);
	void						prepareBufferForHostAccess						(void);
	void						copyResultBuffertoBuffer						(void);
	void						submitCommands									(VkCommandBuffer commandBuffer, VkFence fence);
	Move<VkBuffer>				createDataBuffer								(void);
	void						fillBuffer										(void);

	Move<VkBuffer>				m_dataBuffer;
	Move<VkCommandPool>			m_cmdPoolCopy;
	Move<VkCommandBuffer>		m_cmdBufferCopy;
	Move<VkFence>				m_fence_1;
	Move<VkFence>				m_fence_2;
	Move<VkEvent>				m_event;
};

ExternalMemoryHostBaseTestInstance::ExternalMemoryHostBaseTestInstance (Context& context, VkDeviceSize allocationSize)
	: TestInstance							(context)
	, m_vki									(m_context.getInstanceInterface())
	, m_vkd									(m_context.getDeviceInterface())
	, m_log									(m_context.getTestContext().getLog())
	, m_device								(m_context.getDevice())
	, m_physicalDevice						(m_context.getPhysicalDevice())
	, m_queue								(m_context.getUniversalQueue())
	, m_memoryProps							(getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
	, m_minImportedHostPointerAlignment		(getMinImportedHostPointerAlignment())
	, m_allocationSize						(m_minImportedHostPointerAlignment * allocationSize)
	, m_allocator							(m_context.getDefaultAllocator())
{
	if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_external_memory_host"))
		throw tcu::NotSupportedError("VK_EXT_external_memory_host is not supported");

	m_hostMemoryAlloc	=	deAlignedMalloc((size_t)m_allocationSize, (size_t)m_minImportedHostPointerAlignment);

	if (!m_hostMemoryAlloc)
		TCU_FAIL("Failed to allocate memory block.");

	DE_ASSERT(deIsAlignedPtr(m_hostMemoryAlloc, (deUintptr)m_minImportedHostPointerAlignment));
}

ExternalMemoryHostBaseTestInstance::~ExternalMemoryHostBaseTestInstance (void)
{
	deAlignedFree(m_hostMemoryAlloc);
}

VkDeviceSize ExternalMemoryHostBaseTestInstance::getMinImportedHostPointerAlignment (void)
{
	VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalMemoryHostProperties	=
	{
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT,		//VkStructureType		sType
		DE_NULL,																	//void*					pNext
		0																			//VkDeviceSize			minImportedHostPointerAlignment
	};

	VkPhysicalDeviceProperties2						propertiesDeviceProperties2;
	propertiesDeviceProperties2.sType				= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
	propertiesDeviceProperties2.pNext				= &externalMemoryHostProperties;

	m_vki.getPhysicalDeviceProperties2(m_physicalDevice, &propertiesDeviceProperties2);

	m_log	<< tcu::TestLog::Message << "VkPhysicalDeviceExternalMemoryHostPropertiesEXT::minImportedHostPointerAlignment is "
			<< externalMemoryHostProperties.minImportedHostPointerAlignment << tcu::TestLog::EndMessage;

	if (externalMemoryHostProperties.minImportedHostPointerAlignment > 65536)
		TCU_FAIL("minImportedHostPointerAlignment is exceeding the supported limit");

	return externalMemoryHostProperties.minImportedHostPointerAlignment;
}

deUint32 ExternalMemoryHostBaseTestInstance::getHostPointerMemoryTypeBits (void* hostPointer)
{
	VkExternalMemoryHandleTypeFlagBits			externalMemoryHandleTypeFlagBits = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;

	VkMemoryHostPointerPropertiesEXT			memoryHostPointerProperties;
	memoryHostPointerProperties.sType			= VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT;
	memoryHostPointerProperties.pNext			= DE_NULL;

	VK_CHECK(m_vkd.getMemoryHostPointerPropertiesEXT(m_device, externalMemoryHandleTypeFlagBits, hostPointer, &memoryHostPointerProperties));

	m_log << tcu::TestLog::Message << "memoryTypeBits value: " << memoryHostPointerProperties.memoryTypeBits << tcu::TestLog::EndMessage;

	return memoryHostPointerProperties.memoryTypeBits;
}

Move<VkDeviceMemory> ExternalMemoryHostBaseTestInstance::allocateMemoryFromHostPointer (deUint32 memoryTypeIndex)
{
	VkImportMemoryHostPointerInfoEXT							importMemoryHostPointerInfo;
	importMemoryHostPointerInfo.sType							= VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT;
	importMemoryHostPointerInfo.pNext							= DE_NULL;
	importMemoryHostPointerInfo.handleType						= VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
	importMemoryHostPointerInfo.pHostPointer					= m_hostMemoryAlloc;

	VkMemoryAllocateInfo										memoryAllocateInfo;
	memoryAllocateInfo.sType									= VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
	memoryAllocateInfo.pNext									= &importMemoryHostPointerInfo;
	memoryAllocateInfo.allocationSize							= m_allocationSize;
	memoryAllocateInfo.memoryTypeIndex							= memoryTypeIndex;

	return allocateMemory(m_vkd, m_device, &memoryAllocateInfo, DE_NULL);
}

void ExternalMemoryHostBaseTestInstance::logMemoryTypeIndexPropertyFlags (deUint32 index)
{
	m_log << tcu::TestLog::Message << "Memory Type index " << index << " property flags:" << tcu::TestLog::EndMessage;
	m_log << tcu::TestLog::Message << getMemoryPropertyFlagsStr(m_memoryProps.memoryTypes[index].propertyFlags) << tcu::TestLog::EndMessage;
}

bool ExternalMemoryHostBaseTestInstance::findCompatibleMemoryTypeIndexToTest (deUint32 resourceMemoryTypeBits, deUint32 hostPointerMemoryTypeBits, deUint32* outMemoryTypeIndexToTest)
{
	for (deUint32 bitMaskPosition = 0; bitMaskPosition < VK_MAX_MEMORY_TYPES; bitMaskPosition++)
	{
		if (isBitSet(resourceMemoryTypeBits & hostPointerMemoryTypeBits, bitMaskPosition))
		{
			logMemoryTypeIndexPropertyFlags(bitMaskPosition);
			*outMemoryTypeIndexToTest = bitMaskPosition;
			return true;
		}
	}
	return false;
}

bool ExternalMemoryHostBaseTestInstance::findMemoryTypeIndexToTest (deUint32 hostPointerMemoryTypeBits, deUint32* outMemoryTypeIndexToTest)
{
	return findCompatibleMemoryTypeIndexToTest(~0u, hostPointerMemoryTypeBits, outMemoryTypeIndexToTest);
}

tcu::TestStatus ExternalMemoryHostBaseTestInstance::iterate (void)
{
	deUint32			hostPointerMemoryTypeBits;
	deUint32			memoryTypeIndexToTest;

	//realocate to meet requirements for host memory alignment
	m_hostMemoryAlloc			= deAlignedRealloc(m_hostMemoryAlloc, (size_t)m_minImportedHostPointerAlignment, (size_t)m_minImportedHostPointerAlignment);
	m_allocationSize			= m_minImportedHostPointerAlignment;

	//check if reallocation is successfull
	if (!m_hostMemoryAlloc)
		TCU_FAIL("Failed to reallocate memory block.");

	DE_ASSERT(deIsAlignedPtr(m_hostMemoryAlloc, (deUintptr)m_minImportedHostPointerAlignment));

	//find the usable memory type index
	hostPointerMemoryTypeBits	= getHostPointerMemoryTypeBits(m_hostMemoryAlloc);
	if (findMemoryTypeIndexToTest(hostPointerMemoryTypeBits, &memoryTypeIndexToTest))
		m_deviceMemoryAllocatedFromHostPointer = allocateMemoryFromHostPointer(memoryTypeIndexToTest);
	else
		return tcu::TestStatus::fail("Fail");

	return tcu::TestStatus::pass("Pass");
}

ExternalMemoryHostRenderImageTestInstance::ExternalMemoryHostRenderImageTestInstance (Context& context, TestParams testParams)
		: ExternalMemoryHostBaseTestInstance	(context, 1)
		, m_testParams							(testParams)
{
}

tcu::TestStatus ExternalMemoryHostRenderImageTestInstance::iterate ()
{
	VkClearColorValue					clearColorBlue					= { { 0.0f, 0.0f, 1.0f, 1.0f } };
	const deUint32						queueFamilyIndex				= m_context.getUniversalQueueFamilyIndex();
	deUint32							hostPointerMemoryTypeBits;
	deUint32							memoryTypeIndexToTest;
	VkMemoryRequirements				imageMemoryRequirements;

	m_image								= createImage(VK_IMAGE_TILING_OPTIMAL);

	//check memory requirements and reallocate memory if needed
	imageMemoryRequirements				= getImageMemoryRequirements(m_vkd, m_device, *m_image);

	if (m_testParams.m_useOffset == false)
	{
		VkDeviceSize requiredSize = imageMemoryRequirements.size;
		if (requiredSize > m_allocationSize)
		{
			//calculate new size, this must me a multiple of minImportedHostPointerAlignment
			VkDeviceSize newHostAllocationSize	= VkDeviceSize(deCeilFloatToInt32((float(requiredSize) / float(m_minImportedHostPointerAlignment))) * m_minImportedHostPointerAlignment);

			m_log	<< tcu::TestLog::Message << "Realloc needed (required size: "  << requiredSize <<  "). " << "New host allocation size: " << newHostAllocationSize << ")."
					<< tcu::TestLog::EndMessage;
			//realocate
			m_hostMemoryAlloc					= deAlignedRealloc(m_hostMemoryAlloc, (size_t)newHostAllocationSize, (size_t)m_minImportedHostPointerAlignment);
			m_allocationSize					= newHostAllocationSize;
		}
	}

	if (m_testParams.m_useOffset == true)
	{
		VkDeviceSize requiredSize = imageMemoryRequirements.size + imageMemoryRequirements.alignment;
		if (requiredSize > m_allocationSize)
		{
			VkDeviceSize newHostAllocationSize	= VkDeviceSize(deCeilFloatToInt32((float(requiredSize) / float(m_minImportedHostPointerAlignment))) * m_minImportedHostPointerAlignment);

			m_log	<< tcu::TestLog::Message << "Realloc needed (required size: " << requiredSize << "). " << "New host allocation size: " << newHostAllocationSize << ")."
					<< tcu::TestLog::EndMessage;
			m_hostMemoryAlloc					= deAlignedRealloc(m_hostMemoryAlloc, (size_t)newHostAllocationSize, (size_t)m_minImportedHostPointerAlignment);
			m_allocationSize					= newHostAllocationSize;
		}
	}
	//check if reallocation is successfull
	if (!m_hostMemoryAlloc)
		TCU_FAIL("Failed to reallocate memory block.");

	DE_ASSERT(deIsAlignedPtr(m_hostMemoryAlloc, (deUintptr)m_minImportedHostPointerAlignment));

	//find the usable memory type index
	hostPointerMemoryTypeBits			= getHostPointerMemoryTypeBits(m_hostMemoryAlloc);
	if (findCompatibleMemoryTypeIndexToTest(imageMemoryRequirements.memoryTypeBits, hostPointerMemoryTypeBits, &memoryTypeIndexToTest))
		m_deviceMemoryAllocatedFromHostPointer = allocateMemoryFromHostPointer(memoryTypeIndexToTest);
	else
		TCU_THROW(NotSupportedError, "Compatible memory type not found");

	VK_CHECK(m_vkd.bindImageMemory(m_device, *m_image, *m_deviceMemoryAllocatedFromHostPointer, (m_testParams.m_useOffset ? imageMemoryRequirements.alignment : 0)));

	m_imageView								= createImageView();
	m_renderPass							= createRenderPass();
	m_framebuffer							= createFramebuffer();
	m_vertexBuffer							= createBindMemoryInitializeVertexBuffer();
	m_resultBuffer							= createBindMemoryResultBuffer();

	vk::DescriptorSetLayoutBuilder			builder;

	builder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);

	m_descriptorSetLayout					= builder.build(m_vkd, m_device, (vk::VkDescriptorSetLayoutCreateFlags)0);

	m_descriptorPool						= DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
																	 .build(m_vkd, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);

	m_pipelineLayout						= createPipelineLayout();
	m_descriptorSet							= createAndUpdateDescriptorSet();

	m_vertexShaderModule					= createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("position_only.vert"), 0);
	m_fragmentShaderModule					= createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("only_color_out.frag"), 0);


	m_pipeline								= createPipeline();

	m_cmdPool								= createCommandPool(m_vkd, m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
	m_cmdBuffer								= allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);


	beginCommandBuffer(m_vkd, *m_cmdBuffer);

	clear(clearColorBlue);
	draw();
	copyResultImagetoBuffer();

	endCommandBuffer(m_vkd, *m_cmdBuffer);

	submitCommandsAndWait(m_vkd, m_device, m_queue, *m_cmdBuffer);

	tcu::ConstPixelBufferAccess				result(mapVkFormat(m_testParams.m_format), tcu::IVec3(100,100,1), m_resultBufferAllocation->getHostPtr());

	std::vector<float>						referenceData(40000, 0);
	tcu::PixelBufferAccess					reference(mapVkFormat(m_testParams.m_format), tcu::IVec3(100, 100, 1), referenceData.data());

	prepareReferenceImage(reference);

	if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Comparison", "Comparison", reference, result, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR))
		return tcu::TestStatus::fail("Fail");

	return tcu::TestStatus::pass("Pass");
}

Move<VkImage>  ExternalMemoryHostRenderImageTestInstance::createImage (VkImageTiling tiling)
{
	const VkImageCreateInfo			imageCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,					// VkStructureType			sType
		DE_NULL,												// const void*				pNext
		DE_NULL,												// VkImageCreateFlags		flags
		VK_IMAGE_TYPE_2D,										// VkImageType				imageType
		m_testParams.m_format,									// VkFormat					format
		{ 100, 100, 1 },										// VkExtent3D				extent
		1,														// deUint32					mipLevels
		1,														// deUint32					arrayLayers
		VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits	samples
		tiling,													// VkImageTiling			tiling
		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
		VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
		VK_IMAGE_USAGE_TRANSFER_DST_BIT,						// VkImageUsageFlags		usage
		VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode			sharingMode
		0,														// deUint32					queueFamilyIndexCount
		DE_NULL,												// const deUint32*			pQueueFamilyIndices
		VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			initialLayout
	};

	return vk::createImage(m_vkd, m_device, &imageCreateInfo, DE_NULL);
}

Move<VkFramebuffer>  ExternalMemoryHostRenderImageTestInstance::createFramebuffer ()
{
	const VkFramebufferCreateInfo framebufferCreateInfo =
	{
		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType				sType
		DE_NULL,											// const void*					pNext
		(VkFramebufferCreateFlags)0,
		*m_renderPass,										// VkRenderPass					renderPass
		1,													// deUint32						attachmentCount
		&m_imageView.get(),									// const VkImageView*			pAttachments
		100,												// deUint32						width
		100,												// deUint32						height
		1													// deUint32						layers
	};
	return vk::createFramebuffer(m_vkd, m_device, &framebufferCreateInfo);
}

Move<VkImageView>  ExternalMemoryHostRenderImageTestInstance::createImageView ()
{
	const VkImageViewCreateInfo		imageViewCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,																// VkStructureType			sType
		DE_NULL,																								// const void*				pNext
		0,																										// VkImageViewCreateFlags	flags
		*m_image,																								// VkImage					image
		VK_IMAGE_VIEW_TYPE_2D,																					// VkImageViewType			viewType
		m_testParams.m_format,																					// VkFormat					format
		{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},		// VkComponentMapping		components
		{ VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 }																// VkImageSubresourceRange	subresourceRange
	};
	return vk::createImageView(m_vkd, m_device, &imageViewCreateInfo);
}

Move<VkBuffer>  ExternalMemoryHostRenderImageTestInstance::createBindMemoryInitializeVertexBuffer ()
{
	Move<VkBuffer>						buffer;
	float								triangleData[]					= { -1.0f,  -1.0f, 0.0f, 1.0f,
																		    -1.0f,   1.0f, 0.0f, 1.0f,
																			 0.0f,   1.0f, 0.0f, 1.0f,
																			 0.0f,  -1.0f, 0.0f, 1.0f };
	const VkBufferCreateInfo			vertexBufferCreateInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
		DE_NULL,								// const void*			pNext
		0,										// VkBufferCreateFlags	flag
		sizeof(triangleData),					// VkDeviceSize			size
		VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,		// VkBufferUsageFlags	usage
		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
		0,										// deUint32				queueFamilyCount
		DE_NULL									// const deUint32*		pQueueFamilyIndices
	};
	buffer																= vk::createBuffer(m_vkd, m_device, &vertexBufferCreateInfo, DE_NULL);
	const VkMemoryRequirements			bufferMemoryRequirements		= getBufferMemoryRequirements(m_vkd, m_device, *buffer);
										m_vertexBufferAllocation		= m_allocator.allocate(bufferMemoryRequirements, MemoryRequirement::HostVisible);

	VK_CHECK(m_vkd.bindBufferMemory(m_device, *buffer, m_vertexBufferAllocation->getMemory(), m_vertexBufferAllocation->getOffset()));

	void* const							mapPtr							= m_vertexBufferAllocation->getHostPtr();

	deMemcpy(mapPtr, triangleData, sizeof(triangleData));
	flushMappedMemoryRange(m_vkd, m_device, m_vertexBufferAllocation->getMemory(), m_vertexBufferAllocation->getOffset(), sizeof(triangleData));

	return buffer;
}

Move<VkBuffer>  ExternalMemoryHostRenderImageTestInstance::createBindMemoryResultBuffer ()
{
	Move<VkBuffer>						buffer;
	VkDeviceSize						size						= 10000 * vk::mapVkFormat(m_testParams.m_format).getPixelSize();

	const VkBufferCreateInfo			resultBufferCreateInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,						// VkStructureType		sType
		DE_NULL,													// const void*			pNext
		0,															// VkBufferCreateFlags	flags
		size,														// VkDeviceSize			size
		VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
		VK_BUFFER_USAGE_TRANSFER_DST_BIT,							// VkBufferUsageFlags	usage
		VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode		sharingMode
		0,															// deUint32				queueFamilyCount
		DE_NULL														// const deUint32*		pQueueFamilyIndices
	};
	buffer															= vk::createBuffer(m_vkd, m_device, &resultBufferCreateInfo, DE_NULL);

	const VkMemoryRequirements			bufferMemoryRequirements	= getBufferMemoryRequirements(m_vkd, m_device, *buffer);
	m_resultBufferAllocation									    = m_allocator.allocate(bufferMemoryRequirements, MemoryRequirement::HostVisible);

	VK_CHECK(m_vkd.bindBufferMemory(m_device, *buffer, m_resultBufferAllocation->getMemory(), m_resultBufferAllocation->getOffset()));

	return buffer;
}

Move<VkDescriptorSet>  ExternalMemoryHostRenderImageTestInstance::createAndUpdateDescriptorSet ()
{
	Move<VkDescriptorSet>				descriptorSet;
	VkDescriptorBufferInfo				descriptorInfo;

	const VkDescriptorSetAllocateInfo	allocInfo =
	{
		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType                             sType
		DE_NULL,										// const void*                                 pNext
		*m_descriptorPool,								// VkDescriptorPool                            descriptorPool
		1u,												// deUint32                                    setLayoutCount
		&(m_descriptorSetLayout.get())					// const VkDescriptorSetLayout*                pSetLayouts
	};

	descriptorSet						= allocateDescriptorSet(m_vkd, m_device, &allocInfo);
	descriptorInfo						= makeDescriptorBufferInfo(*m_vertexBuffer, (VkDeviceSize)0u, sizeof(float) * 16);

	DescriptorSetUpdateBuilder()
		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
		.update(m_vkd, m_device);

	return descriptorSet;
}

Move<VkPipelineLayout> ExternalMemoryHostRenderImageTestInstance::createPipelineLayout ()
{
	const VkPipelineLayoutCreateInfo	pipelineLayoutParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
		DE_NULL,										// const void*					pNext
		(VkPipelineLayoutCreateFlags)0,					// VkPipelineLayoutCreateFlags	flags
		1u,												// deUint32						descriptorSetCount
		&(m_descriptorSetLayout.get()),					// const VkDescriptorSetLayout*	pSetLayouts
		0u,												// deUint32						pushConstantRangeCount
		DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
	};

	return vk::createPipelineLayout(m_vkd, m_device, &pipelineLayoutParams);
}

Move<VkPipeline> ExternalMemoryHostRenderImageTestInstance::createPipeline ()
{
	Move<VkPipeline>								pipeline;
	const std::vector<VkViewport>					viewports(1, makeViewport(tcu::UVec2(100,100)));
	const std::vector<VkRect2D>						scissors(1, makeRect2D(tcu::UVec2(100, 100)));
	const VkPrimitiveTopology						topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
	const VkPipelineVertexInputStateCreateInfo		vertexInputStateParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType								sType
		DE_NULL,													// const void*									pNext
		0u,															// vkPipelineVertexInputStateCreateFlags		flags
		0u,															// deUint32										bindingCount
		DE_NULL,													// const VkVertexInputBindingDescription*		pVertexBindingDescriptions
		0u,															// deUint32										attributeCount
		DE_NULL,													// const VkVertexInputAttributeDescription*		pVertexAttributeDescriptions
	};

	return	    makeGraphicsPipeline(	m_vkd,						// const DeviceInterface&                       vk
										m_device,					// const VkDevice                               device
										*m_pipelineLayout,			// const VkPipelineLayout                       pipelineLayout
										*m_vertexShaderModule,		// const VkShaderModule                         vertexShaderModule
										DE_NULL,					// const VkShaderModule                         tessellationControlShaderModule
										DE_NULL,					// const VkShaderModule                         tessellationEvalShaderModule
										DE_NULL,					// const VkShaderModule                         geometryShaderModule
										*m_fragmentShaderModule,	// const VkShaderModule                         fragmentShaderModule
										*m_renderPass,				// const VkRenderPass                           renderPass
										viewports,					// const std::vector<VkViewport>&               viewports
										scissors,					// const std::vector<VkRect2D>&                 scissors
										topology,					// const VkPrimitiveTopology                    topology
										0u,							// const deUint32                               subpass
										0u,							// const deUint32                               patchControlPoints
										&vertexInputStateParams);	// const VkPipelineVertexInputStateCreateInfo*  vertexInputStateCreateInfo
}

void ExternalMemoryHostRenderImageTestInstance::clear (VkClearColorValue color)
{
	const struct VkImageSubresourceRange	subRangeColor	=
	{
		VK_IMAGE_ASPECT_COLOR_BIT,  // VkImageAspectFlags  aspectMask
		0u,                         // deUint32            baseMipLevel
		1u,                         // deUint32            mipLevels
		0u,                         // deUint32            baseArrayLayer
		1u,                         // deUint32            arraySize
	};
	const VkImageMemoryBarrier				imageBarrier	=
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType
		DE_NULL,										// const void*				pNext
		0u,												// VkAccessFlags			srcAccessMask
		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			dstAccessMask
		VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout			oldLayout
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			newLayout
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex
		*m_image,										// VkImage					image
		subRangeColor									// VkImageSubresourceRange	subresourceRange
	};

	m_vkd.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, DE_FALSE, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
	m_vkd.cmdClearColorImage(*m_cmdBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &color, 1, &subRangeColor);
}

void ExternalMemoryHostRenderImageTestInstance::draw ()
{
	const struct VkImageSubresourceRange	subRangeColor =
	{
		VK_IMAGE_ASPECT_COLOR_BIT,  // VkImageAspectFlags  aspectMask
		0u,                         // deUint32            baseMipLevel
		1u,                         // deUint32            mipLevels
		0u,                         // deUint32            baseArrayLayer
		1u,                         // deUint32            arraySize
	};
	const VkImageMemoryBarrier				imageBarrier =
	{
		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType
		DE_NULL,										// const void*				pNext
		VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags			srcAccessMask
		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			dstAccessMask
		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout			oldLayout
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// VkImageLayout			newLayout
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex
		VK_QUEUE_FAMILY_IGNORED,						// deUint32					dstQueueFamilyIndex
		*m_image,										// VkImage					image
		subRangeColor									// VkImageSubresourceRange	subresourceRange
	};
	m_vkd.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, DE_FALSE, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);

	beginRenderPass(m_vkd, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, 75, 100), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
	m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
	m_vkd.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &(*m_descriptorSet), 0, DE_NULL);
	m_vkd.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
	endRenderPass(m_vkd, *m_cmdBuffer);
}

void ExternalMemoryHostRenderImageTestInstance::copyResultImagetoBuffer ()
{
	copyImageToBuffer(m_vkd, *m_cmdBuffer, *m_image, *m_resultBuffer, tcu::IVec2(100, 100));
}

void ExternalMemoryHostRenderImageTestInstance::prepareReferenceImage (tcu::PixelBufferAccess& reference)
{
	for (int w=0; w < 100; w++)
		for (int h = 0; h < 100; h++)
		{
			if (w < 50)					reference.setPixel(tcu::Vec4(0, 1, 0, 1), w, h);
			if ((w >= 50) && (w < 75))	reference.setPixel(tcu::Vec4(1, 0, 0, 1), w, h);
			if (w >=75)					reference.setPixel(tcu::Vec4(0, 0, 1, 1), w, h);
		}
}

Move<VkRenderPass> ExternalMemoryHostRenderImageTestInstance::createRenderPass ()
{
	const VkAttachmentDescription			colorAttachmentDescription =
	{
		(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags    flags
		m_testParams.m_format,						// VkFormat                        format
		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits           samples
		VK_ATTACHMENT_LOAD_OP_CLEAR,				// VkAttachmentLoadOp              loadOp
		VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp             storeOp
		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp              stencilLoadOp
		VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp             stencilStoreOp
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout                   initialLayout
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout                   finalLayout
	};

	std::vector<VkAttachmentDescription>	attachmentDescriptions;
	attachmentDescriptions.push_back(colorAttachmentDescription);

	const VkAttachmentReference				colorAttachmentRef =
	{
		0u,											// deUint32         attachment
		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout    layout
	};

	const VkSubpassDescription				subpassDescription =
	{
		(VkSubpassDescriptionFlags)0,				// VkSubpassDescriptionFlags       flags
		VK_PIPELINE_BIND_POINT_GRAPHICS,			// VkPipelineBindPoint             pipelineBindPoint
		0u,											// deUint32                        inputAttachmentCount
		DE_NULL,									// const VkAttachmentReference*    pInputAttachments
		1u,											// deUint32                        colorAttachmentCount
		&colorAttachmentRef,						// const VkAttachmentReference*    pColorAttachments
		DE_NULL,									// const VkAttachmentReference*    pResolveAttachments
		DE_NULL,									// const VkAttachmentReference*    pDepthStencilAttachment
		0u,											// deUint32                        preserveAttachmentCount
		DE_NULL										// const deUint32*                 pPreserveAttachments
	};

	const VkRenderPassCreateInfo			renderPassInfo =
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	// VkStructureType                   sType
		DE_NULL,									// const void*                       pNext
		(VkRenderPassCreateFlags)0,					// VkRenderPassCreateFlags           flags
		(deUint32)attachmentDescriptions.size(),	// deUint32                          attachmentCount
		&attachmentDescriptions[0],					// const VkAttachmentDescription*    pAttachments
		1u,											// deUint32                          subpassCount
		&subpassDescription,						// const VkSubpassDescription*       pSubpasses
		0u,											// deUint32                          dependencyCount
		DE_NULL										// const VkSubpassDependency*        pDependencies
	};

	return vk::createRenderPass(m_vkd, m_device, &renderPassInfo);
}

ExternalMemoryHostSynchronizationTestInstance::ExternalMemoryHostSynchronizationTestInstance (Context& context, TestParams testParams)
	: ExternalMemoryHostRenderImageTestInstance (context, testParams)
{
}

tcu::TestStatus ExternalMemoryHostSynchronizationTestInstance::iterate ()
{
	DE_ASSERT(m_testParams.m_format == VK_FORMAT_R8G8B8A8_UNORM);

	const deUint32							queueFamilyIndex							= m_context.getUniversalQueueFamilyIndex();
	const VkDeviceSize						dataBufferSize								= 10000 * vk::mapVkFormat(m_testParams.m_format).getPixelSize();
	void*									pointerReturnedByMapMemory;
	deUint32								hostPointerMemoryTypeBits;
	deUint32								memoryTypeIndexToTest;
	VkMemoryRequirements					bufferMemoryRequirements;

	m_dataBuffer							= createDataBuffer();

	//check memory requirements
	bufferMemoryRequirements				= getBufferMemoryRequirements(m_vkd, m_device, *m_dataBuffer);
	VkDeviceSize requiredSize				= bufferMemoryRequirements.size;
	//reallocate memory if needed
	if (requiredSize > m_allocationSize)
	{
		VkDeviceSize newHostAllocationSize	= VkDeviceSize(deCeilFloatToInt32((float(requiredSize) / float(m_minImportedHostPointerAlignment))) * m_minImportedHostPointerAlignment);

		m_log << tcu::TestLog::Message << "Realloc needed (required size: " << requiredSize << "). "
			<< "New host allocation size: " << newHostAllocationSize << ")." << tcu::TestLog::EndMessage;

		m_hostMemoryAlloc					= deAlignedRealloc(m_hostMemoryAlloc, (size_t)newHostAllocationSize, (size_t)m_minImportedHostPointerAlignment);
		m_allocationSize					= newHostAllocationSize;
	}

	//check if reallocation is successfull
	if (!m_hostMemoryAlloc)
		TCU_FAIL("Failed to reallocate memory block.");

	DE_ASSERT(deIsAlignedPtr(m_hostMemoryAlloc, (deUintptr)m_minImportedHostPointerAlignment));

	//find the usable memory type index
	hostPointerMemoryTypeBits				= getHostPointerMemoryTypeBits(m_hostMemoryAlloc);
	if (findCompatibleMemoryTypeIndexToTest(bufferMemoryRequirements.memoryTypeBits, hostPointerMemoryTypeBits, &memoryTypeIndexToTest))
		m_deviceMemoryAllocatedFromHostPointer = allocateMemoryFromHostPointer(memoryTypeIndexToTest);
	else
		TCU_THROW(NotSupportedError, "Compatible memory type not found");

	VK_CHECK(m_vkd.bindBufferMemory(m_device, *m_dataBuffer, *m_deviceMemoryAllocatedFromHostPointer, 0));

	m_resultBuffer							= createBindMemoryResultBuffer();
	m_cmdPool								= createCommandPool(m_vkd, m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
	m_cmdBuffer								= allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	m_cmdBufferCopy							= allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

	m_event									= createEvent(m_vkd, m_device);
	m_fence_1								= createFence(m_vkd, m_device);
	m_fence_2								= createFence(m_vkd, m_device);

	//record first command buffer
	beginCommandBuffer(m_vkd, *m_cmdBuffer);
	fillBuffer();
	prepareBufferForHostAccess();
	endCommandBuffer(m_vkd, *m_cmdBuffer);

	//record second command buffer
	beginCommandBuffer(m_vkd, *m_cmdBufferCopy);
	copyResultBuffertoBuffer();
	endCommandBuffer(m_vkd, *m_cmdBufferCopy);

	submitCommands(*m_cmdBuffer, *m_fence_1);
	submitCommands(*m_cmdBufferCopy, *m_fence_2);

	//wait for fence_1 and modify image on host
	VK_CHECK(m_vkd.waitForFences(m_device, 1u, &m_fence_1.get(), DE_TRUE, ~0ull));
	pointerReturnedByMapMemory				= mapMemory(m_vkd, m_device, *m_deviceMemoryAllocatedFromHostPointer, 0, dataBufferSize, 0);
	invalidateMappedMemoryRange(m_vkd, m_device, *m_deviceMemoryAllocatedFromHostPointer, 0, dataBufferSize);
	tcu::PixelBufferAccess bufferSurface(mapVkFormat(m_testParams.m_format), 100, 100, 1, (100 * vk::mapVkFormat(m_testParams.m_format).getPixelSize()), 0, m_hostMemoryAlloc);
	prepareReferenceImage(bufferSurface);
	flushMappedMemoryRange(m_vkd, m_device, *m_deviceMemoryAllocatedFromHostPointer, 0, dataBufferSize);
	//compare memory pointed by both pointers
	if (deMemCmp(m_hostMemoryAlloc, pointerReturnedByMapMemory, (size_t)dataBufferSize) != 0)
		TCU_FAIL("Failed memcmp check.");
	m_vkd.unmapMemory(m_device, *m_deviceMemoryAllocatedFromHostPointer);
	VK_CHECK(m_vkd.setEvent(m_device, *m_event));

	//wait for fence_2 before checking result
	VK_CHECK(m_vkd.waitForFences(m_device, 1u, &m_fence_2.get(), DE_TRUE, ~0ull));

	void * bufferDataPointer				= static_cast<char*>(m_resultBufferAllocation->getHostPtr()) + m_resultBufferAllocation->getOffset();
	tcu::ConstPixelBufferAccess				result(mapVkFormat(m_testParams.m_format), tcu::IVec3(100, 100, 1), bufferDataPointer);

	std::vector<float>						referenceData((unsigned int)dataBufferSize, 0);
	tcu::PixelBufferAccess					reference(mapVkFormat(m_testParams.m_format), tcu::IVec3(100, 100, 1), referenceData.data());

	prepareReferenceImage(reference);

	if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Comparison", "Comparison", reference, result, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR))
		return tcu::TestStatus::fail("Fail");

	return tcu::TestStatus::pass("Pass");
}

void ExternalMemoryHostSynchronizationTestInstance::prepareBufferForHostAccess ()
{
	VkDeviceSize					size								= 10000 * vk::mapVkFormat(m_testParams.m_format).getPixelSize();
	const VkBufferMemoryBarrier		bufferBarrier =
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
		DE_NULL,									// const void*		pNext;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
		*m_dataBuffer,								// VkBuffer			buffer;
		0u,											// VkDeviceSize		offset;
		size										// VkDeviceSize		size;
	};

	m_vkd.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, DE_FALSE, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
}

void ExternalMemoryHostSynchronizationTestInstance::copyResultBuffertoBuffer ()
{
	VkDeviceSize					size								= 10000 * vk::mapVkFormat(m_testParams.m_format).getPixelSize();
	const VkBufferMemoryBarrier		bufferBarrier =
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
		DE_NULL,									// const void*		pNext;
		VK_ACCESS_HOST_WRITE_BIT,					// VkAccessFlags	srcAccessMask;
		VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
		*m_dataBuffer,								// VkBuffer			buffer;
		0u,											// VkDeviceSize		offset;
		size										// VkDeviceSize		size;
	};

	const VkBufferCopy				region_all =
	{
		0,		//VkDeviceSize srcOffset;
		0,		//VkDeviceSize dstOffset;
		size	//VkDeviceSize size;
	};

	m_vkd.cmdWaitEvents(*m_cmdBufferCopy, 1, &m_event.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, DE_NULL, 1, &bufferBarrier, 0, DE_NULL);
	m_vkd.cmdCopyBuffer(*m_cmdBufferCopy, *m_dataBuffer, *m_resultBuffer, 1, &region_all);
}

void ExternalMemoryHostSynchronizationTestInstance::submitCommands (VkCommandBuffer commandBuffer, VkFence fence)
{
	const VkSubmitInfo		submitInfo =
	{
		VK_STRUCTURE_TYPE_SUBMIT_INFO,						// VkStructureType				sType
		DE_NULL,											// const void*					pNext
		0u,													// deUint32						waitSemaphoreCount
		DE_NULL,											// const VkSemaphore*			pWaitSemaphores
		(const VkPipelineStageFlags*)DE_NULL,				// const VkPipelineStageFlags*	pWaitDstStageMask
		1u,													// deUint32						commandBufferCount
		&commandBuffer,										// const VkCommandBuffer*		pCommandBuffers
		0u,													// deUint32						signalSemaphoreCount
		DE_NULL,											// const VkSemaphore*			pSignalSemaphores
	};

	VK_CHECK(m_vkd.queueSubmit(m_queue, 1u, &submitInfo, fence));
}

Move<VkBuffer> ExternalMemoryHostSynchronizationTestInstance::createDataBuffer ()
{
	VkDeviceSize					size								= 10000 * vk::mapVkFormat(m_testParams.m_format).getPixelSize();
	const VkBufferCreateInfo		dataBufferCreateInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
		DE_NULL,								// const void*			pNext
		0,										// VkBufferCreateFlags	flag
		size,									// VkDeviceSize			size
		VK_BUFFER_USAGE_TRANSFER_DST_BIT |
		VK_BUFFER_USAGE_TRANSFER_SRC_BIT,		// VkBufferUsageFlags	usage
		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode
		0,										// deUint32				queueFamilyCount
		DE_NULL									// const deUint32*		pQueueFamilyIndices
	};
	return vk::createBuffer(m_vkd, m_device, &dataBufferCreateInfo, DE_NULL);
}

void ExternalMemoryHostSynchronizationTestInstance::fillBuffer ()
{
	VkDeviceSize					size								= 10000 * vk::mapVkFormat(m_testParams.m_format).getPixelSize();
	const VkBufferMemoryBarrier		bufferBarrier =
	{
		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
		DE_NULL,									// const void*		pNext;
		0u,											// VkAccessFlags	srcAccessMask;
		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	dstAccessMask;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
		*m_dataBuffer,								// VkBuffer			buffer;
		0u,											// VkDeviceSize		offset;
		size										// VkDeviceSize		size;
	};

	m_vkd.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, DE_FALSE, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
	m_vkd.cmdFillBuffer(*m_cmdBuffer, *m_dataBuffer, 0, size, 0xFFFFFFFF);
}

struct AddPrograms
{
	void init (vk::SourceCollections& sources, TestParams testParams) const
	{
			//unused parameter
			DE_UNREF(testParams);

			const char* const vertexShader =
			"#version 430\n"

			"layout(std430, binding = 0) buffer BufferPos {\n"
			"vec4 p[100];\n"
			"} pos;\n"

			"out gl_PerVertex{\n"
			"vec4 gl_Position;\n"
			"};\n"

			"void main() {\n"
			"gl_Position = pos.p[gl_VertexIndex];\n"
			"}\n";

		sources.glslSources.add("position_only.vert")
			<< glu::VertexSource(vertexShader);

		const char* const fragmentShader =
			"#version 430\n"

			"layout(location = 0) out vec4 my_FragColor;\n"

			"void main() {\n"
			"my_FragColor = vec4(0,1,0,1);\n"
			"}\n";

		sources.glslSources.add("only_color_out.frag")
			<< glu::FragmentSource(fragmentShader);
	}
};

} // unnamed namespace

tcu::TestCaseGroup* createMemoryExternalMemoryHostTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup>	group(new tcu::TestCaseGroup(testCtx, "external_memory_host", "VK_EXT_external_memory_host extension tests."));
	de::MovePtr<tcu::TestCaseGroup>	simpleAllocation(new tcu::TestCaseGroup(testCtx, "simple_allocation", "simple allocation tests."));
	de::MovePtr<tcu::TestCaseGroup>	bind_image_memory_and_render(new tcu::TestCaseGroup(testCtx, "bind_image_memory_and_render", "render tests."));
	de::MovePtr<tcu::TestCaseGroup>	with_zero_offset(new tcu::TestCaseGroup(testCtx, "with_zero_offset", "bind object with zero offset specified"));
	de::MovePtr<tcu::TestCaseGroup>	with_non_zero_offset(new tcu::TestCaseGroup(testCtx, "with_non_zero_offset", "bind object with zero offset specified"));
	de::MovePtr<tcu::TestCaseGroup>	synchronization(new tcu::TestCaseGroup(testCtx, "synchronization", "synchronization tests."));

	//test cases:
	simpleAllocation->addChild(new InstanceFactory1<ExternalMemoryHostBaseTestInstance, VkDeviceSize> (testCtx, tcu::NODETYPE_SELF_VALIDATE, "minImportedHostPointerAlignment_x1",
																									  "allocate minImportedHostPointerAlignment multiplied by 1", 1));
	simpleAllocation->addChild(new InstanceFactory1<ExternalMemoryHostBaseTestInstance, VkDeviceSize> (testCtx, tcu::NODETYPE_SELF_VALIDATE, "minImportedHostPointerAlignment_x3",
																									  "allocate minImportedHostPointerAlignment multiplied by 3", 3));
	group ->addChild(simpleAllocation.release());

	const VkFormat testFormats[] = {
		VK_FORMAT_R8G8B8A8_UNORM,
		VK_FORMAT_R16G16B16A16_UNORM,
		VK_FORMAT_R16G16B16A16_SFLOAT,
		VK_FORMAT_R32G32B32A32_SFLOAT
	};

	const std::string testNames[] = {
		"r8g8b8a8_unorm",
		"r16g16b16a16_unorm",
		"r16g16b16a16_sfloat",
		"r32g32b32a32_sfloat"
	};

	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(testFormats); formatNdx++)
	{
		std::string testName = testNames[formatNdx];
		with_zero_offset->addChild(new InstanceFactory1<ExternalMemoryHostRenderImageTestInstance, TestParams, AddPrograms>	(testCtx, tcu::NODETYPE_SELF_VALIDATE,
																															testName, testName, AddPrograms(),
																															TestParams(testFormats[formatNdx])));
	}
	bind_image_memory_and_render->addChild(with_zero_offset.release());

	for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(testFormats); formatNdx++)
	{
		std::string testName = testNames[formatNdx];
		with_non_zero_offset->addChild(new InstanceFactory1<ExternalMemoryHostRenderImageTestInstance, TestParams, AddPrograms>	(testCtx, tcu::NODETYPE_SELF_VALIDATE,
																																testName, testName, AddPrograms(),
																																TestParams(testFormats[formatNdx], true)));
	}
	bind_image_memory_and_render->addChild(with_non_zero_offset.release());

	group->addChild(bind_image_memory_and_render.release());

	synchronization->addChild(new InstanceFactory1<ExternalMemoryHostSynchronizationTestInstance, TestParams, AddPrograms>	(testCtx, tcu::NODETYPE_SELF_VALIDATE,
																															"synchronization", "synchronization", AddPrograms(),
																															TestParams(testFormats[0], true)));
	group->addChild(synchronization.release());
	return group.release();
}

} // memory
} // vkt
