/*------------------------------------------------------------------------
* 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) {}
};

void checkExternalMemoryProperties (const vk::VkExternalMemoryProperties& properties)
{
	// If obtaining the properties did not fail, the compatible handle types should indicate our handle type at least.
	if ((properties.compatibleHandleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT) == 0)
		TCU_FAIL("compatibleHandleTypes does not include the host allocation bit");

	// If this is host memory, it cannot require dedicated allocation.
	if ((properties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0)
		TCU_FAIL("externalMemoryFeatures for host allocated format includes dedicated allocation bit");

	// Memory should be importable to bind it to an image or buffer.
	if ((properties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0)
		TCU_FAIL("externalMemoryFeatures for host allocated format does not include the importable bit");
}

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									(VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage);
	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);
	void							verifyFormatProperties						(VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage);

	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						(VkDeviceSize size);
	void						copyResultBuffertoBuffer						(VkDeviceSize size);
	void						submitCommands									(VkCommandBuffer commandBuffer, VkFence fence);
	Move<VkBuffer>				createDataBuffer								(VkDeviceSize size, VkBufferUsageFlags usage);
	void						fillBuffer										(VkDeviceSize size);
	void						verifyBufferProperties							(VkBufferUsageFlags usage);

	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())
{
	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;
	const VkImageTiling					tiling							= VK_IMAGE_TILING_OPTIMAL;
	const VkImageUsageFlags				usageFlags						= (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |	VK_IMAGE_USAGE_TRANSFER_DST_BIT);

	m_image								= createImage(m_testParams.m_format, tiling, usageFlags);

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

	// Verify image format properties before proceeding.
	verifyFormatProperties(m_testParams.m_format, tiling, usageFlags);

	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 (VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage)
{
	const vk::VkExternalMemoryImageCreateInfo	externalInfo =
	{
		vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
		DE_NULL,
		(vk::VkExternalMemoryHandleTypeFlags)VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT
	};

	const VkImageCreateInfo						imageCreateInfo =
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType
		&externalInfo,							// const void*				pNext
		0u,										// VkImageCreateFlags		flags
		VK_IMAGE_TYPE_2D,						// VkImageType				imageType
		format,									// VkFormat					format
		{ 100, 100, 1 },						// VkExtent3D				extent
		1,										// deUint32					mipLevels
		1,										// deUint32					arrayLayers
		VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples
		tiling,									// VkImageTiling			tiling
		usage,									// 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));
	flushAlloc(m_vkd, m_device, *m_vertexBufferAllocation);

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

void ExternalMemoryHostRenderImageTestInstance::verifyFormatProperties (VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage)
{
	const VkPhysicalDeviceExternalImageFormatInfo externalInfo = {
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
		DE_NULL,
		VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT
	};

	const VkPhysicalDeviceImageFormatInfo2 formatInfo = {
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,	// VkStructureType       sType;
		&externalInfo,											// const void*           pNext;
		format,													// VkFormat              format;
		VK_IMAGE_TYPE_2D,										// VkImageType           type;
		tiling,													// VkImageTiling         tiling;
		usage,													// VkImageUsageFlags     usage;
		0u														// VkImageCreateFlags    flags;
	};

	vk::VkExternalImageFormatProperties externalProperties = {
		VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
		DE_NULL,
		vk::VkExternalMemoryProperties()
	};

	vk::VkImageFormatProperties2 formatProperties = {
		VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
		&externalProperties,
		vk::VkImageFormatProperties()
	};

	// Memory type bits have been verified to be compatible previously. The call below should not fail.
	VK_CHECK(m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties2(m_context.getPhysicalDevice(), &formatInfo, &formatProperties));

	checkExternalMemoryProperties(externalProperties.externalMemoryProperties);
}

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();
	const VkBufferUsageFlags				usageFlags									= (VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
	void*									pointerReturnedByMapMemory;
	deUint32								hostPointerMemoryTypeBits;
	deUint32								memoryTypeIndexToTest;
	VkMemoryRequirements					bufferMemoryRequirements;

	m_dataBuffer							= createDataBuffer(dataBufferSize, usageFlags);

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

	// Verify buffer properties with external host memory.
	verifyBufferProperties(usageFlags);

	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(dataBufferSize);
	prepareBufferForHostAccess(dataBufferSize);
	endCommandBuffer(m_vkd, *m_cmdBuffer);

	//record second command buffer
	beginCommandBuffer(m_vkd, *m_cmdBufferCopy);
	copyResultBuffertoBuffer(dataBufferSize);
	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, VK_WHOLE_SIZE);
	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, VK_WHOLE_SIZE);
	//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)
{
	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)
{
	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, VkBufferUsageFlags usage)
{
	const vk::VkExternalMemoryBufferCreateInfo	externalInfo =
	{
		vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
		DE_NULL,
		(vk::VkExternalMemoryHandleTypeFlags)VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT
	};

	const VkBufferCreateInfo					dataBufferCreateInfo =
	{
		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType
		&externalInfo,							// const void*			pNext
		0,										// VkBufferCreateFlags	flag
		size,									// VkDeviceSize			size
		usage,									// 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)
{
	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);
}

void ExternalMemoryHostSynchronizationTestInstance::verifyBufferProperties (VkBufferUsageFlags usage)
{
	const VkPhysicalDeviceExternalBufferInfo bufferInfo = {
		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,	// VkStructureType                       sType;
		DE_NULL,												// const void*                           pNext;
		0,														// VkBufferCreateFlags                   flags;
		usage,													// VkBufferUsageFlags                    usage;
		VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT	// VkExternalMemoryHandleTypeFlagBits    handleType;
	};

	VkExternalBufferProperties props = {
		VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,	// VkStructureType               sType;
		DE_NULL,										// void*                         pNext;
		VkExternalMemoryProperties()					// VkExternalMemoryProperties    externalMemoryProperties;
	};

	m_context.getInstanceInterface().getPhysicalDeviceExternalBufferProperties(m_context.getPhysicalDevice(), &bufferInfo, &props);

	checkExternalMemoryProperties(props.externalMemoryProperties);
}

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

struct FormatName
{
	vk::VkFormat	format;
	std::string		name;
};

void checkSupport (Context& context)
{
	context.requireDeviceFunctionality("VK_EXT_external_memory_host");
}

} // 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 InstanceFactory1WithSupport<ExternalMemoryHostBaseTestInstance, VkDeviceSize, FunctionSupport0> (testCtx, tcu::NODETYPE_SELF_VALIDATE, "minImportedHostPointerAlignment_x1",
																																	"allocate minImportedHostPointerAlignment multiplied by 1", 1, checkSupport));
	simpleAllocation->addChild(new InstanceFactory1WithSupport<ExternalMemoryHostBaseTestInstance, VkDeviceSize, FunctionSupport0> (testCtx, tcu::NODETYPE_SELF_VALIDATE, "minImportedHostPointerAlignment_x3",
																																	"allocate minImportedHostPointerAlignment multiplied by 3", 3, checkSupport));
	group ->addChild(simpleAllocation.release());

	const std::vector<FormatName> testFormats = {
		{ vk::VK_FORMAT_R8G8B8A8_UNORM,			"r8g8b8a8_unorm"		},
		{ vk::VK_FORMAT_R16G16B16A16_UNORM,		"r16g16b16a16_unorm"	},
		{ vk::VK_FORMAT_R16G16B16A16_SFLOAT,	"r16g16b16a16_sfloat"	},
		{ vk::VK_FORMAT_R32G32B32A32_SFLOAT,	"r32g32b32a32_sfloat"	},
	};

	for (const auto& formatName : testFormats)
	{
		with_zero_offset->addChild(new InstanceFactory1WithSupport<ExternalMemoryHostRenderImageTestInstance, TestParams, FunctionSupport0, AddPrograms>	(testCtx, tcu::NODETYPE_SELF_VALIDATE,
																																							 formatName.name, formatName.name, AddPrograms(),
																																							 TestParams(formatName.format), checkSupport));
	}
	bind_image_memory_and_render->addChild(with_zero_offset.release());

	for (const auto& formatName : testFormats)
	{
		with_non_zero_offset->addChild(new InstanceFactory1WithSupport<ExternalMemoryHostRenderImageTestInstance, TestParams, FunctionSupport0, AddPrograms>	(testCtx, tcu::NODETYPE_SELF_VALIDATE,
																																								 formatName.name, formatName.name, AddPrograms(),
																																								 TestParams(formatName.format, true), checkSupport));
	}
	bind_image_memory_and_render->addChild(with_non_zero_offset.release());

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

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

} // memory
} // vkt
