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

#include "vktApiExternalMemoryTests.hpp"

#include "vktTestCaseUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkDeviceUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkPlatform.hpp"
#include "vkMemUtil.hpp"
#include "vkApiVersion.hpp"

#include "tcuTestLog.hpp"

#include "deUniquePtr.hpp"
#include "deStringUtil.hpp"
#include "deRandom.hpp"

#include "deMemory.h"

#include "vktExternalMemoryUtil.hpp"

#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
#	include <unistd.h>
#	include <fcntl.h>
#	include <errno.h>
#	include <sys/types.h>
#	include <sys/socket.h>
#endif

#if (DE_OS == DE_OS_WIN32)
#	define WIN32_LEAN_AND_MEAN
#	include <windows.h>
#	include <Dxgi1_2.h>
#endif

using tcu::TestLog;
using namespace vkt::ExternalMemoryUtil;

namespace vkt
{
namespace api
{
namespace
{


std::string getFormatCaseName (vk::VkFormat format)
{
	return de::toLower(de::toString(getFormatStr(format)).substr(10));
}

vk::VkMemoryDedicatedRequirements getMemoryDedicatedRequirements (const vk::DeviceInterface&	vkd,
																  vk::VkDevice					device,
																  vk::VkBuffer					buffer)
{
	const vk::VkBufferMemoryRequirementsInfo2	requirementInfo			=
	{
		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
		DE_NULL,
		buffer
	};
	vk::VkMemoryDedicatedRequirements			dedicatedRequirements	=
	{
		vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
		DE_NULL,
		VK_FALSE,
		VK_FALSE
	};
	vk::VkMemoryRequirements2					requirements			=
	{
		vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
		&dedicatedRequirements,
		{ 0u, 0u, 0u }
	};

	vkd.getBufferMemoryRequirements2(device, &requirementInfo, &requirements);

	return dedicatedRequirements;
}

vk::VkMemoryDedicatedRequirements getMemoryDedicatedRequirements (const vk::DeviceInterface&	vkd,
																  vk::VkDevice					device,
																  vk::VkImage					image)
{
	const vk::VkImageMemoryRequirementsInfo2	requirementInfo		=
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
		DE_NULL,
		image
	};
	vk::VkMemoryDedicatedRequirements		dedicatedRequirements	=
	{
		vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
		DE_NULL,
		VK_FALSE,
		VK_FALSE
	};
	vk::VkMemoryRequirements2				requirements			=
	{
		vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
		&dedicatedRequirements,
		{ 0u, 0u, 0u }
	};

	vkd.getImageMemoryRequirements2(device, &requirementInfo, &requirements);

	return dedicatedRequirements;
}

void writeHostMemory (const vk::DeviceInterface&	vkd,
					  vk::VkDevice					device,
					  vk::VkDeviceMemory			memory,
					  size_t						size,
					  const void*					data)
{
	void* const ptr = vk::mapMemory(vkd, device, memory, 0, size, 0);

	deMemcpy(ptr, data, size);

	flushMappedMemoryRange(vkd, device, memory, 0, size);

	vkd.unmapMemory(device, memory);
}

void checkHostMemory (const vk::DeviceInterface&	vkd,
					  vk::VkDevice					device,
					  vk::VkDeviceMemory			memory,
					  size_t						size,
					  const void*					data)
{
	void* const ptr = vk::mapMemory(vkd, device, memory, 0, size, 0);

	invalidateMappedMemoryRange(vkd, device, memory, 0, size);

	if (deMemCmp(ptr, data, size) != 0)
		TCU_FAIL("Memory contents don't match");

	vkd.unmapMemory(device, memory);
}

std::vector<deUint8> genTestData (deUint32 seed, size_t size)
{
	de::Random				rng		(seed);
	std::vector<deUint8>	data	(size);

	for (size_t ndx = 0; ndx < size; ndx++)
	{
		data[ndx] = rng.getUint8();
	}

	return data;
}

deUint32 chooseQueueFamilyIndex (const vk::InstanceInterface&	vki,
								 vk::VkPhysicalDevice			device,
								 vk::VkQueueFlags				requireFlags)
{
	const std::vector<vk::VkQueueFamilyProperties> properties (vk::getPhysicalDeviceQueueFamilyProperties(vki, device));

	for (deUint32 queueFamilyIndex = 0; queueFamilyIndex < (deUint32)properties.size(); queueFamilyIndex++)
	{
		if ((properties[queueFamilyIndex].queueFlags & requireFlags) == requireFlags)
			return queueFamilyIndex;
	}

	TCU_THROW(NotSupportedError, "Queue type not supported");
}

std::vector<std::string> getInstanceExtensions (const deUint32 instanceVersion,
												const vk::VkExternalSemaphoreHandleTypeFlags	externalSemaphoreTypes,
												const vk::VkExternalMemoryHandleTypeFlags		externalMemoryTypes,
												const vk::VkExternalFenceHandleTypeFlags		externalFenceTypes)
{
	std::vector<std::string> instanceExtensions;

	if (!vk::isCoreInstanceExtension(instanceVersion, "VK_KHR_get_physical_device_properties2"))
		instanceExtensions.push_back("VK_KHR_get_physical_device_properties2");

	if (externalSemaphoreTypes != 0)
		if (!vk::isCoreInstanceExtension(instanceVersion, "VK_KHR_external_semaphore_capabilities"))
			instanceExtensions.push_back("VK_KHR_external_semaphore_capabilities");

	if (externalMemoryTypes != 0)
		if (!vk::isCoreInstanceExtension(instanceVersion, "VK_KHR_external_memory_capabilities"))
			instanceExtensions.push_back("VK_KHR_external_memory_capabilities");

	if (externalFenceTypes != 0)
		if (!vk::isCoreInstanceExtension(instanceVersion, "VK_KHR_external_fence_capabilities"))
			instanceExtensions.push_back("VK_KHR_external_fence_capabilities");

	return instanceExtensions;
}

vk::Move<vk::VkInstance> createInstance (const vk::PlatformInterface&					vkp,
										 const deUint32									version,
										 const vk::VkExternalSemaphoreHandleTypeFlags	externalSemaphoreTypes,
										 const vk::VkExternalMemoryHandleTypeFlags		externalMemoryTypes,
										 const vk::VkExternalFenceHandleTypeFlags		externalFenceTypes)
{
	try
	{
		return vk::createDefaultInstance(vkp, version, std::vector<std::string>(), getInstanceExtensions(version, externalSemaphoreTypes, externalMemoryTypes, externalFenceTypes));
	}
	catch (const vk::Error& error)
	{
		if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
			TCU_THROW(NotSupportedError, "Required extensions not supported");

		throw;
	}
}

vk::Move<vk::VkDevice> createDevice (const deUint32									apiVersion,
									 const vk::PlatformInterface&					vkp,
									 vk::VkInstance									instance,
									 const vk::InstanceInterface&					vki,
									 vk::VkPhysicalDevice							physicalDevice,
									 const vk::VkExternalSemaphoreHandleTypeFlags	externalSemaphoreTypes,
									 const vk::VkExternalMemoryHandleTypeFlags		externalMemoryTypes,
									 const vk::VkExternalFenceHandleTypeFlags		externalFenceTypes,
									 deUint32										queueFamilyIndex,
									 bool											useDedicatedAllocs = false)
{
	bool	useExternalSemaphore = false;
	bool	useExternalFence = false;
	bool	useExternalMemory = false;
	std::vector<const char*>	deviceExtensions;

	if ((externalSemaphoreTypes
			& (vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
				| vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)) != 0)
	{
		deviceExtensions.push_back("VK_KHR_external_semaphore_fd");
		useExternalSemaphore = true;
	}

	if ((externalFenceTypes
			& (vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
				| vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)) != 0)
	{
		deviceExtensions.push_back("VK_KHR_external_fence_fd");
		useExternalFence = true;
	}

	if (useDedicatedAllocs)
	{
		if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_dedicated_allocation"))
			deviceExtensions.push_back("VK_KHR_dedicated_allocation");
		if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_get_memory_requirements2"))
			deviceExtensions.push_back("VK_KHR_get_memory_requirements2");
	}

	if ((externalMemoryTypes
			& vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) != 0)
	{
		deviceExtensions.push_back("VK_KHR_external_memory_fd");
		useExternalMemory = true;
	}

	if ((externalSemaphoreTypes
			& (vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
				| vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)) != 0)
	{
		deviceExtensions.push_back("VK_KHR_external_semaphore_win32");
		useExternalSemaphore = true;
	}

	if ((externalFenceTypes
			& (vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
				| vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)) != 0)
	{
		deviceExtensions.push_back("VK_KHR_external_fence_win32");
		useExternalFence = true;
	}

	if ((externalMemoryTypes
			& (vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
			   | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT
			   | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT
			   | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT
			   | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT
			   | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT)) != 0)
	{
		deviceExtensions.push_back("VK_KHR_external_memory_win32");
		useExternalMemory = true;
	}

	if ((externalMemoryTypes
		& vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) != 0)
	{
		deviceExtensions.push_back("VK_ANDROID_external_memory_android_hardware_buffer");
		useExternalMemory = true;
		if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_sampler_ycbcr_conversion"))
			deviceExtensions.push_back("VK_KHR_sampler_ycbcr_conversion");
		if (!vk::isCoreDeviceExtension(apiVersion, "VK_EXT_queue_family_foreign"))
			deviceExtensions.push_back("VK_EXT_queue_family_foreign");
	}

	if (useExternalSemaphore)
	{
		if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_external_semaphore"))
			deviceExtensions.push_back("VK_KHR_external_semaphore");
	}

	if (useExternalFence)
	{
		if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_external_fence"))
			deviceExtensions.push_back("VK_KHR_external_fence");
	}

	if (useExternalMemory)
	{
		if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_external_memory"))
			deviceExtensions.push_back("VK_KHR_external_memory");
	}

	const float								priority				= 0.5f;
	const vk::VkDeviceQueueCreateInfo		queues[]				=
	{
		{
			vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
			DE_NULL,
			0u,

			queueFamilyIndex,
			1u,
			&priority
		}
	};
	const vk::VkDeviceCreateInfo			deviceCreateInfo		=
	{
		vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
		DE_NULL,
		0u,

		DE_LENGTH_OF_ARRAY(queues),
		queues,

		0u,
		DE_NULL,

		(deUint32)deviceExtensions.size(),
		deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0],
		DE_NULL
	};

	try
	{
		return vk::createDevice(vkp, instance, vki, physicalDevice, &deviceCreateInfo);
	}
	catch (const vk::Error& error)
	{
		if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
			TCU_THROW(NotSupportedError, "Required extensions not supported");

		throw;
	}
}

vk::VkQueue getQueue (const vk::DeviceInterface&	vkd,
					  vk::VkDevice					device,
					  deUint32						queueFamilyIndex)
{
	vk::VkQueue queue;

	vkd.getDeviceQueue(device, queueFamilyIndex, 0, &queue);

	return queue;
}

void checkSemaphoreSupport (const vk::InstanceInterface&				vki,
							vk::VkPhysicalDevice						device,
							vk::VkExternalSemaphoreHandleTypeFlagBits	externalType)
{
	const vk::VkPhysicalDeviceExternalSemaphoreInfo	info		=
	{
		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
		DE_NULL,
		externalType
	};
	vk::VkExternalSemaphoreProperties				properties	=
	{
		vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
		DE_NULL,
		0u,
		0u,
		0u
	};

	vki.getPhysicalDeviceExternalSemaphoreProperties(device, &info, &properties);

	if ((properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) == 0)
		TCU_THROW(NotSupportedError, "Semaphore doesn't support exporting in external type");

	if ((properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT) == 0)
		TCU_THROW(NotSupportedError, "Semaphore doesn't support importing in external type");
}

void checkFenceSupport (const vk::InstanceInterface&			vki,
						vk::VkPhysicalDevice					device,
						vk::VkExternalFenceHandleTypeFlagBits	externalType)
{
	const vk::VkPhysicalDeviceExternalFenceInfo	info		=
	{
		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
		DE_NULL,
		externalType
	};
	vk::VkExternalFenceProperties				properties	=
	{
		vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
		DE_NULL,
		0u,
		0u,
		0u
	};

	vki.getPhysicalDeviceExternalFenceProperties(device, &info, &properties);

	if ((properties.externalFenceFeatures & vk::VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT) == 0)
		TCU_THROW(NotSupportedError, "Fence doesn't support exporting in external type");

	if ((properties.externalFenceFeatures & vk::VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT) == 0)
		TCU_THROW(NotSupportedError, "Fence doesn't support importing in external type");
}

void checkBufferSupport (const vk::InstanceInterface&				vki,
						 vk::VkPhysicalDevice						device,
						 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
						 vk::VkBufferViewCreateFlags				createFlag,
						 vk::VkBufferUsageFlags						usageFlag,
						 bool										dedicated)
{
	const vk::VkPhysicalDeviceExternalBufferInfo	info		=
	{
		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
		DE_NULL,

		createFlag,
		usageFlag,
		externalType
	};
	vk::VkExternalBufferProperties					properties	=
	{
		vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
		DE_NULL,

		{ 0u, 0u, 0u }
	};

	vki.getPhysicalDeviceExternalBufferProperties(device, &info, &properties);

	if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) == 0)
		TCU_THROW(NotSupportedError, "External handle type doesn't support exporting buffer");

	if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0)
		TCU_THROW(NotSupportedError, "External handle type doesn't support importing buffer");

	if (!dedicated && (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0)
		TCU_THROW(NotSupportedError, "External handle type requires dedicated allocation");
}

void checkImageSupport (const vk::InstanceInterface&						vki,
						 vk::VkPhysicalDevice								device,
						 vk::VkExternalMemoryHandleTypeFlagBits				externalType,
						 vk::VkImageViewCreateFlags							createFlag,
						 vk::VkImageUsageFlags								usageFlag,
						 vk::VkFormat										format,
						 vk::VkImageTiling									tiling,
						 bool												dedicated)
{
	const vk::VkPhysicalDeviceExternalImageFormatInfo	externalInfo		=
	{
		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
		DE_NULL,
		externalType
	};
	const vk::VkPhysicalDeviceImageFormatInfo2			info				=
	{
		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
		&externalInfo,

		format,
		vk::VK_IMAGE_TYPE_2D,
		tiling,
		usageFlag,
		createFlag,
	};
	vk::VkExternalImageFormatProperties					externalProperties	=
	{
		vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
		DE_NULL,
		{ 0u, 0u, 0u }
	};
	vk::VkImageFormatProperties2						properties			=
	{
		vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
		&externalProperties,
		{
			{ 0u, 0u, 0u },
			0u,
			0u,
			0u,
			0u
		}
	};

	vki.getPhysicalDeviceImageFormatProperties2(device, &info, &properties);

	if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) == 0)
		TCU_THROW(NotSupportedError, "External handle type doesn't support exporting image");

	if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0)
		TCU_THROW(NotSupportedError, "External handle type doesn't support importing image");

	if (!dedicated && (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0)
		TCU_THROW(NotSupportedError, "External handle type requires dedicated allocation");
}

void submitDummySignal (const vk::DeviceInterface&	vkd,
						vk::VkQueue					queue,
						vk::VkSemaphore				semaphore)
{
	const vk::VkSubmitInfo submit =
	{
		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
		DE_NULL,

		0u,
		DE_NULL,
		DE_NULL,

		0u,
		DE_NULL,

		1u,
		&semaphore
	};

	VK_CHECK(vkd.queueSubmit(queue, 1, &submit, (vk::VkFence)0u));
}

void submitDummySignalAndGetSemaphoreNative (	const vk::DeviceInterface&						vk,
												vk::VkDevice									device,
												vk::VkQueue										queue,
												deUint32										queueFamilyIndex,
												vk::VkSemaphore									semaphore,
												vk::VkExternalSemaphoreHandleTypeFlagBits		externalType,
												NativeHandle&									nativeHandle)
{
	const vk::Unique<vk::VkCommandPool>		cmdPool(createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex, DE_NULL));
	const vk::Unique<vk::VkCommandBuffer>	cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const vk::VkEventCreateInfo eventCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
		DE_NULL,
		0u
	};

	const vk::Unique<vk::VkEvent> event(createEvent(vk, device, &eventCreateInfo, DE_NULL));

	const vk::VkCommandBufferBeginInfo cmdBufferBeginInfo =
	{
		vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
		DE_NULL,
		vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
		DE_NULL,
	};

	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
	/*
		The submitDummySignal function calls vkQueueSubmit with an empty VkSubmitInfo structure and a
		VkSemaphore to be signalled when the work is finished. Because there is no work in the submission, vkQueueSubmit
		may signal the semaphore immediately. When a semaphore's file descriptor is obtained using vkGetFenceFdKHR, if the
		handle type is VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR, vkGetFenceFdKHR is allowed to return -1 if the fence
		is already signalled, instead of a file descriptor, . In order to make sure that a valid file descriptor is returned
		we use vkCmdWaitEvents to make sure that vkQueueSubmit doesn't signal the fence.
	*/
	vk.cmdWaitEvents(*cmdBuffer, 1, &event.get(), vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL);
	vk.endCommandBuffer(*cmdBuffer);

	const vk::VkSubmitInfo submit =
	{
		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
		DE_NULL,

		0u,
		DE_NULL,
		DE_NULL,

		1u,
		&cmdBuffer.get(),

		1u,
		&semaphore
	};

	VK_CHECK(vk.queueSubmit(queue, 1, &submit, (vk::VkFence)0u));

	getSemaphoreNative(vk, device, semaphore, externalType, nativeHandle);

	VK_CHECK(vk.setEvent(device, *event));

	VK_CHECK(vk.queueWaitIdle(queue));
}

void submitDummyWait (const vk::DeviceInterface&	vkd,
					  vk::VkQueue					queue,
					  vk::VkSemaphore				semaphore)
{
	const vk::VkPipelineStageFlags	stage	= vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
	const vk::VkSubmitInfo			submit	=
	{
		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
		DE_NULL,

		1u,
		&semaphore,
		&stage,

		0u,
		DE_NULL,

		0u,
		DE_NULL,
	};

	VK_CHECK(vkd.queueSubmit(queue, 1, &submit, (vk::VkFence)0u));
}

void submitDummySignal (const vk::DeviceInterface&	vkd,
						vk::VkQueue					queue,
						vk::VkFence					fence)
{
	const vk::VkSubmitInfo submit =
	{
		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
		DE_NULL,

		0u,
		DE_NULL,
		DE_NULL,

		0u,
		DE_NULL,

		0u,
		DE_NULL
	};

	VK_CHECK(vkd.queueSubmit(queue, 1, &submit, fence));
}

void submitDummySignalAndGetFenceNative (	const vk::DeviceInterface&					vk,
											vk::VkDevice								device,
											vk::VkQueue									queue,
											deUint32									queueFamilyIndex,
											vk::VkFence									fence,
											vk::VkExternalFenceHandleTypeFlagBits		externalType,
											NativeHandle&								nativeHandle)
{
	const vk::Unique<vk::VkCommandPool>		cmdPool(createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex, DE_NULL));
	const vk::Unique<vk::VkCommandBuffer>	cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	const vk::VkEventCreateInfo eventCreateInfo =
	{
		vk::VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
		DE_NULL,
		0u
	};

	const vk::Unique<vk::VkEvent> event(createEvent(vk, device, &eventCreateInfo, DE_NULL));

	const vk::VkCommandBufferBeginInfo cmdBufferBeginInfo =
	{
		vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
		DE_NULL,
		vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
		DE_NULL,
	};

	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
	/*
		The submitDummySignal function calls vkQueueSubmit with an empty VkSubmitInfo structure and a
		VkFence to be signalled when the work is finished. Because there is no work in the submission, vkQueueSubmit
		could signal the fence immediately. When a fence's file descriptor is obtained using vkGetFenceFdKHR, if the
		handle type is VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR, vkGetFenceFdKHR is allowed to return -1 instead of a
		file descriptor, if the fence is already signalled. In order to make sure that a valid file descriptor is returned
		we use vkCmdWaitEvents to make sure that vkQueueSubmit doesn't signal the fence.
	*/
	vk.cmdWaitEvents(*cmdBuffer, 1, &event.get(), vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL);
	vk.endCommandBuffer(*cmdBuffer);

	const vk::VkSubmitInfo submit =
	{
		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
		DE_NULL,

		0u,
		DE_NULL,
		DE_NULL,

		1u,
		&cmdBuffer.get(),

		0u,
		DE_NULL
	};

	VK_CHECK(vk.queueSubmit(queue, 1, &submit, fence));

	getFenceNative(vk, device, fence, externalType, nativeHandle);

	VK_CHECK(vk.setEvent(device, *event));

	VK_CHECK(vk.queueWaitIdle(queue));
}

tcu::TestStatus testSemaphoreQueries (Context& context, vk::VkExternalSemaphoreHandleTypeFlagBits externalType)
{
	const vk::PlatformInterface&		vkp				(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance		(createInstance(vkp, context.getUsedApiVersion(), externalType, 0u, 0u));
	const vk::InstanceDriver			vki				(vkp, *instance);
	const vk::VkPhysicalDevice			device			(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));

	TestLog&							log				= context.getTestContext().getLog();

	const vk::VkPhysicalDeviceExternalSemaphoreInfo	info		=
	{
		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
		DE_NULL,
		externalType
	};
	vk::VkExternalSemaphoreProperties				properties	=
	{
		vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
		DE_NULL,
		0u,
		0u,
		0u
	};

	vki.getPhysicalDeviceExternalSemaphoreProperties(device, &info, &properties);
	log << TestLog::Message << properties << TestLog::EndMessage;

	TCU_CHECK(properties.pNext == DE_NULL);
	TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES);

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

struct SemaphoreTestConfig
{
													SemaphoreTestConfig	(vk::VkExternalSemaphoreHandleTypeFlagBits	externalType_,
																		 Permanence										permanence_)
		: externalType		(externalType_)
		, permanence		(permanence_)
	{
	}

	vk::VkExternalSemaphoreHandleTypeFlagBits	externalType;
	Permanence									permanence;
};

tcu::TestStatus testSemaphoreWin32Create (Context&					context,
										  const SemaphoreTestConfig	config)
{
#if (DE_OS == DE_OS_WIN32)
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>					device			(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver							vkd				(vkp, *instance, *device);
		const vk::VkQueue								queue			(getQueue(vkd, *device, queueFamilyIndex));
		const vk::VkExportSemaphoreWin32HandleInfoKHR	win32ExportInfo	=
		{
			vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
			DE_NULL,

			(vk::pt::Win32SecurityAttributesPtr)DE_NULL,
			DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
			DE_NULL
		};
		const vk::VkExportSemaphoreCreateInfo			exportCreateInfo=
		{
			vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
			&win32ExportInfo,
			(vk::VkExternalMemoryHandleTypeFlags)config.externalType
		};
		const vk::VkSemaphoreCreateInfo					createInfo		=
		{
			vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
			&exportCreateInfo,
			0u
		};
		const vk::Unique<vk::VkSemaphore>				semaphore		(vk::createSemaphore(vkd, *device, &createInfo));

		if (transference == TRANSFERENCE_COPY)
			submitDummySignal(vkd, queue, *semaphore);

		NativeHandle									handleA;
		getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handleA);

		{
			const vk::VkSemaphoreImportFlags			flags			= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
			const vk::Unique<vk::VkSemaphore>			semaphoreA		(createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));

			if (transference == TRANSFERENCE_COPY)
				submitDummyWait(vkd, queue, *semaphoreA);
			else if (transference == TRANSFERENCE_REFERENCE)
			{
				submitDummySignal(vkd, queue, *semaphore);
				submitDummyWait(vkd, queue, *semaphoreA);
			}
			else
				DE_FATAL("Unknown transference.");

			VK_CHECK(vkd.queueWaitIdle(queue));
		}

		return tcu::TestStatus::pass("Pass");
	}
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
#endif
}

tcu::TestStatus testSemaphoreImportTwice (Context&					context,
										  const SemaphoreTestConfig	config)
{
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>		device			(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd				(vkp, *instance, *device);
		const vk::VkQueue					queue			(getQueue(vkd, *device, queueFamilyIndex));
		const vk::Unique<vk::VkSemaphore>	semaphore		(createExportableSemaphore(vkd, *device, config.externalType));
		NativeHandle						handleA;

		if (transference == TRANSFERENCE_COPY)
			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphore, config.externalType, handleA);
		else
			getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handleA);

		{
			NativeHandle						handleB		(handleA);
			const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
			const vk::Unique<vk::VkSemaphore>	semaphoreA	(createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
			const vk::Unique<vk::VkSemaphore>	semaphoreB	(createAndImportSemaphore(vkd, *device, config.externalType, handleB, flags));

			if (transference == TRANSFERENCE_COPY)
				submitDummyWait(vkd, queue, *semaphoreA);
			else if (transference == TRANSFERENCE_REFERENCE)
			{
				submitDummySignal(vkd, queue, *semaphoreA);
				submitDummyWait(vkd, queue, *semaphoreB);
			}
			else
				DE_FATAL("Unknown transference.");

			VK_CHECK(vkd.queueWaitIdle(queue));
		}

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

tcu::TestStatus testSemaphoreImportReimport (Context&					context,
											 const SemaphoreTestConfig	config)
{
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>		device			(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd				(vkp, *instance, *device);
		const vk::VkQueue					queue			(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkSemaphore>	semaphoreA		(createExportableSemaphore(vkd, *device, config.externalType));
		NativeHandle						handleA;

		if (transference == TRANSFERENCE_COPY)
			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handleA);
		else
			getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handleA);

		NativeHandle						handleB		(handleA);
		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
		const vk::Unique<vk::VkSemaphore>	semaphoreB	(createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));

		importSemaphore(vkd, *device, *semaphoreB, config.externalType, handleB, flags);

		if (transference == TRANSFERENCE_COPY)
			submitDummyWait(vkd, queue, *semaphoreB);
		else if (transference == TRANSFERENCE_REFERENCE)
		{
			submitDummySignal(vkd, queue, *semaphoreA);
			submitDummyWait(vkd, queue, *semaphoreB);
		}
		else
			DE_FATAL("Unknown transference.");

		VK_CHECK(vkd.queueWaitIdle(queue));

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

tcu::TestStatus testSemaphoreSignalExportImportWait (Context&					context,
													 const SemaphoreTestConfig	config)
{
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>		device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd					(vkp, *instance, *device);
		const vk::VkQueue					queue				(getQueue(vkd, *device, queueFamilyIndex));
		const vk::Unique<vk::VkSemaphore>	semaphoreA			(createExportableSemaphore(vkd, *device, config.externalType));
		{
			NativeHandle	handle;

			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle);

			{
				const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
				const vk::Unique<vk::VkSemaphore>	semaphoreB	(createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
				submitDummyWait(vkd, queue, *semaphoreB);

				VK_CHECK(vkd.queueWaitIdle(queue));
			}
		}

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

tcu::TestStatus testSemaphoreExportSignalImportWait (Context&					context,
													 const SemaphoreTestConfig	config)
{
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::VkSemaphoreImportFlags	flags				= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;

	DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>		device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd					(vkp, *instance, *device);
		const vk::VkQueue					queue				(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkSemaphore>	semaphoreA			(createExportableSemaphore(vkd, *device, config.externalType));
		NativeHandle						handle;

		getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);

		submitDummySignal(vkd, queue, *semaphoreA);
		{
			{
				const vk::Unique<vk::VkSemaphore>	semaphoreB	(createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));

				submitDummyWait(vkd, queue, *semaphoreB);
				VK_CHECK(vkd.queueWaitIdle(queue));
			}
		}

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

tcu::TestStatus testSemaphoreExportImportSignalWait (Context&					context,
													 const SemaphoreTestConfig	config)
{
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd			(vkp, *instance, *device);
		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
		NativeHandle						handle;

		submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle);

		const vk::Unique<vk::VkSemaphore>	semaphoreB	(createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));

		submitDummySignal(vkd, queue, *semaphoreA);
		submitDummyWait(vkd, queue, *semaphoreB);

		VK_CHECK(vkd.queueWaitIdle(queue));

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

tcu::TestStatus testSemaphoreSignalImport (Context&						context,
										   const SemaphoreTestConfig	config)
{
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd			(vkp, *instance, *device);
		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
		const vk::Unique<vk::VkSemaphore>	semaphoreB	(createSemaphore(vkd, *device));
		NativeHandle						handle;

		submitDummySignal(vkd, queue, *semaphoreB);
		VK_CHECK(vkd.queueWaitIdle(queue));

		if (transference == TRANSFERENCE_COPY)
			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle);
		else
			getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);

		importSemaphore(vkd, *device, *semaphoreB, config.externalType, handle, flags);

		if (transference == TRANSFERENCE_COPY)
			submitDummyWait(vkd, queue, *semaphoreB);
		else if (transference == TRANSFERENCE_REFERENCE)
		{
			submitDummySignal(vkd, queue, *semaphoreA);
			submitDummyWait(vkd, queue, *semaphoreB);
		}
		else
			DE_FATAL("Unknown transference.");

		VK_CHECK(vkd.queueWaitIdle(queue));

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

tcu::TestStatus testSemaphoreSignalWaitImport (Context&						context,
											   const SemaphoreTestConfig	config)
{
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd			(vkp, *instance, *device);
		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
		const vk::Unique<vk::VkSemaphore>	semaphoreB	(createSemaphore(vkd, *device));
		NativeHandle						handle;

		if (transference == TRANSFERENCE_COPY)
			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle);
		else
			getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);

		submitDummySignal(vkd, queue, *semaphoreB);
		submitDummyWait(vkd, queue, *semaphoreB);

		VK_CHECK(vkd.queueWaitIdle(queue));

		importSemaphore(vkd, *device, *semaphoreB, config.externalType, handle, flags);

		if (transference == TRANSFERENCE_COPY)
			submitDummyWait(vkd, queue, *semaphoreB);
		else if (transference == TRANSFERENCE_REFERENCE)
		{
			submitDummySignal(vkd, queue, *semaphoreA);
			submitDummyWait(vkd, queue, *semaphoreB);
		}
		else
			DE_FATAL("Unknown transference.");

		VK_CHECK(vkd.queueWaitIdle(queue));

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

tcu::TestStatus testSemaphoreMultipleExports (Context&					context,
											  const SemaphoreTestConfig	config)
{
	const size_t						exportCount			= 4 * 1024;
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd			(vkp, *instance, *device);
		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));
		const vk::Unique<vk::VkSemaphore>	semaphore	(createExportableSemaphore(vkd, *device, config.externalType));

		for (size_t exportNdx = 0; exportNdx < exportCount; exportNdx++)
		{
			NativeHandle handle;

			if (transference == TRANSFERENCE_COPY)
				submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphore, config.externalType, handle);
			else
				getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handle);
		}

		submitDummySignal(vkd, queue, *semaphore);
		submitDummyWait(vkd, queue, *semaphore);

		VK_CHECK(vkd.queueWaitIdle(queue));
	}

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

tcu::TestStatus testSemaphoreMultipleImports (Context&					context,
											  const SemaphoreTestConfig	config)
{
	const size_t						importCount			= 4 * 1024;
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd			(vkp, *instance, *device);
		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));
		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
		NativeHandle						handleA;

		if (transference == TRANSFERENCE_COPY)
			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handleA);
		else
			getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handleA);

		for (size_t importNdx = 0; importNdx < importCount; importNdx++)
		{
			NativeHandle						handleB		(handleA);
			const vk::Unique<vk::VkSemaphore>	semaphoreB	(createAndImportSemaphore(vkd, *device, config.externalType, handleB, flags));
		}

		if (transference == TRANSFERENCE_COPY)
		{
			importSemaphore(vkd, *device, *semaphoreA, config.externalType, handleA, flags);
			submitDummyWait(vkd, queue, *semaphoreA);
		}
		else if (transference == TRANSFERENCE_REFERENCE)
		{
			submitDummySignal(vkd, queue, *semaphoreA);
			submitDummyWait(vkd, queue, *semaphoreA);
		}
		else
			DE_FATAL("Unknown transference.");

		VK_CHECK(vkd.queueWaitIdle(queue));
	}

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

tcu::TestStatus testSemaphoreTransference (Context&						context,
										   const SemaphoreTestConfig	config)
{
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(),  vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd			(vkp, *instance, *device);
		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
		NativeHandle						handle;

		submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle);

		{
			const vk::Unique<vk::VkSemaphore>	semaphoreB			(createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));

			if (config.permanence == PERMANENCE_PERMANENT)
			{
				if (transference == TRANSFERENCE_COPY)
				{
					submitDummySignal(vkd, queue, *semaphoreA);
					submitDummyWait(vkd, queue, *semaphoreB);
					VK_CHECK(vkd.queueWaitIdle(queue));

					submitDummySignal(vkd, queue, *semaphoreB);

					submitDummyWait(vkd, queue, *semaphoreA);
					submitDummyWait(vkd, queue, *semaphoreB);
					VK_CHECK(vkd.queueWaitIdle(queue));
				}
				else if (transference== TRANSFERENCE_REFERENCE)
				{
					submitDummyWait(vkd, queue, *semaphoreB);
					VK_CHECK(vkd.queueWaitIdle(queue));

					submitDummySignal(vkd, queue, *semaphoreA);
					submitDummyWait(vkd, queue, *semaphoreB);

					submitDummySignal(vkd, queue, *semaphoreB);
					submitDummyWait(vkd, queue, *semaphoreA);
					VK_CHECK(vkd.queueWaitIdle(queue));
				}
				else
					DE_FATAL("Unknown transference.");
			}
			else if (config.permanence == PERMANENCE_TEMPORARY)
			{
				if (transference == TRANSFERENCE_COPY)
				{
					submitDummySignal(vkd, queue, *semaphoreA);
					submitDummyWait(vkd, queue, *semaphoreB);
					VK_CHECK(vkd.queueWaitIdle(queue));

					submitDummySignal(vkd, queue, *semaphoreB);

					submitDummyWait(vkd, queue, *semaphoreA);
					submitDummyWait(vkd, queue, *semaphoreB);
					VK_CHECK(vkd.queueWaitIdle(queue));
				}
				else if (transference== TRANSFERENCE_REFERENCE)
				{
					submitDummyWait(vkd, queue, *semaphoreB);
					VK_CHECK(vkd.queueWaitIdle(queue));

					submitDummySignal(vkd, queue, *semaphoreA);
					submitDummySignal(vkd, queue, *semaphoreB);

					submitDummyWait(vkd, queue, *semaphoreB);
					submitDummyWait(vkd, queue, *semaphoreA);
					VK_CHECK(vkd.queueWaitIdle(queue));
				}
				else
					DE_FATAL("Unknown transference.");
			}
			else
				DE_FATAL("Unknown permanence.");
		}

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

tcu::TestStatus testSemaphoreFdDup (Context&					context,
									const SemaphoreTestConfig	config)
{
#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd			(vkp, *instance, *device);
		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));

		TestLog&							log			= context.getTestContext().getLog();
		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));

		{
			NativeHandle		fd;

			if (transference == TRANSFERENCE_COPY)
				submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, fd);
			else
				getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, fd);

			NativeHandle		newFd	(dup(fd.getFd()));

			if (newFd.getFd() < 0)
				log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;

			TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for semaphores fd");

			{
				const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, newFd, flags));

				if (transference == TRANSFERENCE_COPY)
					submitDummyWait(vkd, queue, *semaphoreB);
				else if (transference == TRANSFERENCE_REFERENCE)
				{
					submitDummySignal(vkd, queue, *semaphoreA);
					submitDummyWait(vkd, queue, *semaphoreB);
				}
				else
					DE_FATAL("Unknown permanence.");

				VK_CHECK(vkd.queueWaitIdle(queue));
			}
		}

		return tcu::TestStatus::pass("Pass");
	}
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
#endif
}

tcu::TestStatus testSemaphoreFdDup2 (Context&					context,
									 const SemaphoreTestConfig	config)
{
#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd			(vkp, *instance, *device);
		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));

		TestLog&							log			= context.getTestContext().getLog();
		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
		const vk::Unique<vk::VkSemaphore>	semaphoreB	(createExportableSemaphore(vkd, *device, config.externalType));

		{
			NativeHandle		fd, secondFd;

			if (transference == TRANSFERENCE_COPY)
			{
				submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, fd);
				submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreB, config.externalType, secondFd);
			}
			else
			{
				getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, fd);
				getSemaphoreNative(vkd, *device, *semaphoreB, config.externalType, secondFd);
			}

			int					newFd		(dup2(fd.getFd(), secondFd.getFd()));

			if (newFd < 0)
				log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;

			TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for fences fd");

			{
				const vk::Unique<vk::VkSemaphore> semaphoreC (createAndImportSemaphore(vkd, *device, config.externalType, secondFd, flags));

				if (transference == TRANSFERENCE_COPY)
					submitDummyWait(vkd, queue, *semaphoreC);
				else if (transference == TRANSFERENCE_REFERENCE)
				{
					submitDummySignal(vkd, queue, *semaphoreA);
					submitDummyWait(vkd, queue, *semaphoreC);
				}
				else
					DE_FATAL("Unknown permanence.");

				VK_CHECK(vkd.queueWaitIdle(queue));
			}
		}

		return tcu::TestStatus::pass("Pass");
	}
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support dup2()");
#endif
}

tcu::TestStatus testSemaphoreFdDup3 (Context&					context,
									 const SemaphoreTestConfig	config)
{
#if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd			(vkp, *instance, *device);
		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));

		TestLog&							log			= context.getTestContext().getLog();
		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
		const vk::Unique<vk::VkSemaphore>	semaphoreB	(createExportableSemaphore(vkd, *device, config.externalType));

		{
			NativeHandle						fd, secondFd;

			if (transference == TRANSFERENCE_COPY)
			{
				submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, fd);
				submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreB, config.externalType, secondFd);
			}
			else
			{
				getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, fd);
				getSemaphoreNative(vkd, *device, *semaphoreB, config.externalType, secondFd);
			}

			const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
			const int							newFd		(dup3(fd.getFd(), secondFd.getFd(), 0));

			if (newFd < 0)
				log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;

			TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for fences fd");

			{
				const vk::Unique<vk::VkSemaphore> semaphoreC (createAndImportSemaphore(vkd, *device, config.externalType, secondFd, flags));

				if (transference == TRANSFERENCE_COPY)
					submitDummyWait(vkd, queue, *semaphoreC);
				else if (transference == TRANSFERENCE_REFERENCE)
				{
					submitDummySignal(vkd, queue, *semaphoreA);
					submitDummyWait(vkd, queue, *semaphoreC);
				}
				else
					DE_FATAL("Unknown permanence.");

				VK_CHECK(vkd.queueWaitIdle(queue));
			}
		}

		return tcu::TestStatus::pass("Pass");
	}
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support dup3()");
#endif
}

tcu::TestStatus testSemaphoreFdSendOverSocket (Context&						context,
											   const SemaphoreTestConfig	config)
{
#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkSemaphoreSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
		const vk::DeviceDriver				vkd			(vkp, *instance, *device);
		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));

		TestLog&							log			= context.getTestContext().getLog();
		const vk::Unique<vk::VkSemaphore>	semaphore	(createExportableSemaphore(vkd, *device, config.externalType));
		NativeHandle						fd;

		if (transference == TRANSFERENCE_COPY)
			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphore, config.externalType, fd);
		else
			getSemaphoreNative(vkd, *device, *semaphore, config.externalType, fd);

		{
			int sv[2];

			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
			{
				log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
				TCU_FAIL("Failed to create socket pair");
			}

			{
				const NativeHandle	srcSocket	(sv[0]);
				const NativeHandle	dstSocket	(sv[1]);
				std::string			sendData	("deqp");

				// Send FD
				{
					const int			fdRaw	(fd.getFd());
					msghdr				msg;
					cmsghdr*			cmsg;
					char				buffer[CMSG_SPACE(sizeof(int))];
					iovec				iov		= { &sendData[0], sendData.length()};

					deMemset(&msg, 0, sizeof(msg));

					msg.msg_control		= buffer;
					msg.msg_controllen	= sizeof(buffer);
					msg.msg_iovlen		= 1;
					msg.msg_iov			= &iov;

					cmsg				= CMSG_FIRSTHDR(&msg);
					cmsg->cmsg_level	= SOL_SOCKET;
					cmsg->cmsg_type		= SCM_RIGHTS;
					cmsg->cmsg_len		= CMSG_LEN(sizeof(int));

					deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
					msg.msg_controllen = cmsg->cmsg_len;

					if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
					{
						log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
						TCU_FAIL("Failed to send fd over socket");
					}
				}

				// Recv FD
				{
					msghdr			msg;
					char			buffer[CMSG_SPACE(sizeof(int))];
					std::string		recvData	(4, '\0');
					iovec			iov			= { &recvData[0], recvData.length() };

					deMemset(&msg, 0, sizeof(msg));

					msg.msg_control		= buffer;
					msg.msg_controllen	= sizeof(buffer);
					msg.msg_iovlen		= 1;
					msg.msg_iov			= &iov;

					const ssize_t	bytes = recvmsg(dstSocket.getFd(), &msg, 0);

					if (bytes < 0)
					{
						log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
						TCU_FAIL("Failed to recv fd over socket");

					}
					else if (bytes != (ssize_t)sendData.length())
					{
						TCU_FAIL("recvmsg() returned unpexpected number of bytes");
					}
					else
					{
						const vk::VkSemaphoreImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
						const cmsghdr* const				cmsg	= CMSG_FIRSTHDR(&msg);
						int									newFd_;
						deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
						NativeHandle						newFd	(newFd_);

						TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
						TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
						TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
						TCU_CHECK(recvData == sendData);
						TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");

						{
							const vk::Unique<vk::VkSemaphore> newSemaphore (createAndImportSemaphore(vkd, *device, config.externalType, newFd, flags));

							if (transference == TRANSFERENCE_COPY)
								submitDummyWait(vkd, queue, *newSemaphore);
							else if (transference == TRANSFERENCE_REFERENCE)
							{
								submitDummySignal(vkd, queue, *newSemaphore);
								submitDummyWait(vkd, queue, *newSemaphore);
							}
							else
								DE_FATAL("Unknown permanence.");

							VK_CHECK(vkd.queueWaitIdle(queue));
						}
					}
				}
			}
		}
	}

	return tcu::TestStatus::pass("Pass");
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
#endif
}

tcu::TestStatus testFenceQueries (Context& context, vk::VkExternalFenceHandleTypeFlagBits externalType)
{
	const vk::PlatformInterface&					vkp			(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>				instance	(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, externalType));
	const vk::InstanceDriver						vki			(vkp, *instance);
	const vk::VkPhysicalDevice						device		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));

	TestLog&										log			= context.getTestContext().getLog();

	const vk::VkPhysicalDeviceExternalFenceInfo		info		=
	{
		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
		DE_NULL,
		externalType
	};
	vk::VkExternalFenceProperties					properties	=
	{
		vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
		DE_NULL,
		0u,
		0u,
		0u
	};

	vki.getPhysicalDeviceExternalFenceProperties(device, &info, &properties);
	log << TestLog::Message << properties << TestLog::EndMessage;

	TCU_CHECK(properties.pNext == DE_NULL);
	TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES);

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

struct FenceTestConfig
{
												FenceTestConfig	(vk::VkExternalFenceHandleTypeFlagBits	externalType_,
																 Permanence									permanence_)
		: externalType		(externalType_)
		, permanence		(permanence_)
	{
	}

	vk::VkExternalFenceHandleTypeFlagBits	externalType;
	Permanence								permanence;
};


tcu::TestStatus testFenceWin32Create (Context&				context,
									  const FenceTestConfig	config)
{
#if (DE_OS == DE_OS_WIN32)
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>				device			(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver						vkd				(vkp, *instance, *device);
		const vk::VkQueue							queue			(getQueue(vkd, *device, queueFamilyIndex));
		const vk::VkExportFenceWin32HandleInfoKHR	win32ExportInfo	=
		{
			vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR,
			DE_NULL,

			(vk::pt::Win32SecurityAttributesPtr)DE_NULL,
			DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
			DE_NULL
		};
		const vk::VkExportFenceCreateInfo			exportCreateInfo=
		{
			vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
			&win32ExportInfo,
			(vk::VkExternalFenceHandleTypeFlags)config.externalType
		};
		const vk::VkFenceCreateInfo					createInfo		=
		{
			vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
			&exportCreateInfo,
			0u
		};
		const vk::Unique<vk::VkFence>				fence			(vk::createFence(vkd, *device, &createInfo));

		if (transference == TRANSFERENCE_COPY)
			submitDummySignal(vkd, queue, *fence);

		NativeHandle								handleA;
		getFenceNative(vkd, *device, *fence, config.externalType, handleA);

		{
			const vk::VkFenceImportFlags			flags			= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
			const vk::Unique<vk::VkFence>			fenceA			(createAndImportFence(vkd, *device, config.externalType, handleA, flags));

			if (transference == TRANSFERENCE_COPY)
				VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
			else if (transference == TRANSFERENCE_REFERENCE)
			{
				submitDummySignal(vkd, queue, *fence);
				VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
			}
			else
				DE_FATAL("Unknown transference.");

			VK_CHECK(vkd.queueWaitIdle(queue));
		}

		return tcu::TestStatus::pass("Pass");
	}
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
#endif
}

tcu::TestStatus testFenceImportTwice (Context&				context,
									  const FenceTestConfig	config)
{
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>	device		(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd			(vkp, *instance, *device);
		const vk::VkQueue				queue		(getQueue(vkd, *device, queueFamilyIndex));
		const vk::Unique<vk::VkFence>	fence		(createExportableFence(vkd, *device, config.externalType));
		NativeHandle					handleA;

		if (transference == TRANSFERENCE_COPY)
			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fence, config.externalType, handleA);
		else
			getFenceNative(vkd, *device, *fence, config.externalType, handleA);

		{
			NativeHandle					handleB	(handleA);
			const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
			const vk::Unique<vk::VkFence>	fenceA	(createAndImportFence(vkd, *device, config.externalType, handleA, flags));
			const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handleB, flags));

			if (transference == TRANSFERENCE_COPY)
				VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
			else if (transference == TRANSFERENCE_REFERENCE)
			{
				submitDummySignal(vkd, queue, *fenceA);
				VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
			}
			else
				DE_FATAL("Unknown transference.");

			VK_CHECK(vkd.queueWaitIdle(queue));
		}

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

tcu::TestStatus testFenceImportReimport (Context&				context,
										 const FenceTestConfig	config)
{
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd		(vkp, *instance, *device);
		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
		NativeHandle					handleA;

		if (transference == TRANSFERENCE_COPY)
			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handleA);
		else
			getFenceNative(vkd, *device, *fenceA, config.externalType, handleA);

		NativeHandle					handleB	(handleA);
		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
		const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handleA, flags));

		importFence(vkd, *device, *fenceB, config.externalType, handleB, flags);

		if (transference == TRANSFERENCE_COPY)
			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
		else if (transference == TRANSFERENCE_REFERENCE)
		{
			submitDummySignal(vkd, queue, *fenceA);
			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
		}
		else
			DE_FATAL("Unknown transference.");

		VK_CHECK(vkd.queueWaitIdle(queue));

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

tcu::TestStatus testFenceSignalExportImportWait (Context&				context,
												 const FenceTestConfig	config)
{
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd		(vkp, *instance, *device);
		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));

		{
			NativeHandle	handle;

			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle);

			{
				const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
				const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handle, flags));
				VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));

				VK_CHECK(vkd.queueWaitIdle(queue));
			}
		}

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

tcu::TestStatus testFenceExportSignalImportWait (Context&				context,
												 const FenceTestConfig	config)
{
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::VkFenceImportFlags		flags				= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;

	DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd		(vkp, *instance, *device);
		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
		NativeHandle					handle;

		getFenceNative(vkd, *device, *fenceA, config.externalType, handle);

		submitDummySignal(vkd, queue, *fenceA);
		{
			{
				const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handle, flags));

				VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
				VK_CHECK(vkd.queueWaitIdle(queue));
			}
		}

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

tcu::TestStatus testFenceExportImportSignalWait (Context&				context,
												 const FenceTestConfig	config)
{
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkFenceImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>	device		(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd			(vkp, *instance, *device);
		const vk::VkQueue				queue		(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
		NativeHandle					handle;

		getFenceNative(vkd, *device, *fenceA, config.externalType, handle);

		const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handle, flags));

		submitDummySignal(vkd, queue, *fenceA);
		VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));

		VK_CHECK(vkd.queueWaitIdle(queue));

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

tcu::TestStatus testFenceSignalImport (Context&					context,
									   const FenceTestConfig	config)
{
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd		(vkp, *instance, *device);
		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
		const vk::Unique<vk::VkFence>	fenceB	(createFence(vkd, *device));
		NativeHandle					handle;

		submitDummySignal(vkd, queue, *fenceB);
		VK_CHECK(vkd.queueWaitIdle(queue));

		if (transference == TRANSFERENCE_COPY)
			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle);
		else
			getFenceNative(vkd, *device, *fenceA, config.externalType, handle);

		importFence(vkd, *device, *fenceB, config.externalType, handle, flags);

		if (transference == TRANSFERENCE_COPY)
			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
		else if (transference == TRANSFERENCE_REFERENCE)
		{
			submitDummySignal(vkd, queue, *fenceA);
			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
		}
		else
			DE_FATAL("Unknown transference.");

		VK_CHECK(vkd.queueWaitIdle(queue));

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

tcu::TestStatus testFenceReset (Context&				context,
								const FenceTestConfig	config)
{
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd		(vkp, *instance, *device);
		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
		const vk::Unique<vk::VkFence>	fenceB	(createFence(vkd, *device));
		const vk::Unique<vk::VkFence>	fenceC	(createFence(vkd, *device));
		NativeHandle					handle;

		submitDummySignal(vkd, queue, *fenceB);
		VK_CHECK(vkd.queueWaitIdle(queue));

		submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle);
		NativeHandle					handleB	(handle);
		importFence(vkd, *device, *fenceB, config.externalType, handleB, flags);
		importFence(vkd, *device, *fenceC, config.externalType, handle, flags);

		VK_CHECK(vkd.queueWaitIdle(queue));
		VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));

		if (config.permanence == PERMANENCE_TEMPORARY || transference == TRANSFERENCE_COPY)
		{
			// vkResetFences() should restore fenceBs prior payload and reset that no affecting fenceCs payload
			// or fenceB should be separate copy of the payload and not affect fenceC
			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));

			// vkResetFences() should have restored fenceBs prior state and should be now reset
			// or fenceB should have it's separate payload
			submitDummySignal(vkd, queue, *fenceB);
			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
		}
		else if (config.permanence == PERMANENCE_PERMANENT)
		{
			DE_ASSERT(transference == TRANSFERENCE_REFERENCE);

			// Reset fences should have reset all of the fences
			submitDummySignal(vkd, queue, *fenceC);

			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
		}
		else
			DE_FATAL("Unknown permanence");

		VK_CHECK(vkd.queueWaitIdle(queue));

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

tcu::TestStatus testFenceSignalWaitImport (Context&					context,
										   const FenceTestConfig	config)
{
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkFenceImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>	device		(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd			(vkp, *instance, *device);
		const vk::VkQueue				queue		(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
		const vk::Unique<vk::VkFence>	fenceB	(createFence(vkd, *device));
		NativeHandle					handle;

		if (transference == TRANSFERENCE_COPY)
			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle);
		else
			getFenceNative(vkd, *device, *fenceA, config.externalType, handle);

		submitDummySignal(vkd, queue, *fenceB);
		VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));

		VK_CHECK(vkd.queueWaitIdle(queue));

		importFence(vkd, *device, *fenceB, config.externalType, handle, flags);

		if (transference == TRANSFERENCE_COPY)
			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
		else if (transference == TRANSFERENCE_REFERENCE)
		{
			submitDummySignal(vkd, queue, *fenceA);
			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
		}
		else
			DE_FATAL("Unknown transference.");

		VK_CHECK(vkd.queueWaitIdle(queue));

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

tcu::TestStatus testFenceMultipleExports (Context&				context,
										  const FenceTestConfig	config)
{
	const size_t						exportCount			= 4 * 1024;
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd		(vkp, *instance, *device);
		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
		const vk::Unique<vk::VkFence>	fence	(createExportableFence(vkd, *device, config.externalType));

		for (size_t exportNdx = 0; exportNdx < exportCount; exportNdx++)
		{
			NativeHandle handle;

			if (transference == TRANSFERENCE_COPY)
				submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fence, config.externalType, handle);
			else
				getFenceNative(vkd, *device, *fence, config.externalType, handle);
		}

		submitDummySignal(vkd, queue, *fence);
		VK_CHECK(vkd.waitForFences(*device, 1u, &*fence, VK_TRUE, ~0ull));

		VK_CHECK(vkd.queueWaitIdle(queue));
	}

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

tcu::TestStatus testFenceMultipleImports (Context&				context,
										  const FenceTestConfig	config)
{
	const size_t						importCount			= 4 * 1024;
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd		(vkp, *instance, *device);
		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
		NativeHandle					handleA;

		if (transference == TRANSFERENCE_COPY)
			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handleA);
		else
			getFenceNative(vkd, *device, *fenceA, config.externalType, handleA);

		for (size_t importNdx = 0; importNdx < importCount; importNdx++)
		{
			NativeHandle					handleB		(handleA);
			const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handleB, flags));
		}

		if (transference == TRANSFERENCE_COPY)
		{
			importFence(vkd, *device, *fenceA, config.externalType, handleA, flags);
			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
		}
		else if (transference == TRANSFERENCE_REFERENCE)
		{
			submitDummySignal(vkd, queue, *fenceA);
			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
		}
		else
			DE_FATAL("Unknown transference.");

		VK_CHECK(vkd.queueWaitIdle(queue));
	}

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

tcu::TestStatus testFenceTransference (Context&					context,
									   const FenceTestConfig	config)
{
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd		(vkp, *instance, *device);
		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));

		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
		NativeHandle					handle;

		submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle);

		{
			const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handle, flags));

			if (config.permanence == PERMANENCE_PERMANENT)
			{
				if (transference == TRANSFERENCE_COPY)
				{
					submitDummySignal(vkd, queue, *fenceA);
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
					VK_CHECK(vkd.queueWaitIdle(queue));

					VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
					submitDummySignal(vkd, queue, *fenceB);

					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
					VK_CHECK(vkd.queueWaitIdle(queue));
				}
				else if (transference== TRANSFERENCE_REFERENCE)
				{
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
					VK_CHECK(vkd.queueWaitIdle(queue));

					VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
					submitDummySignal(vkd, queue, *fenceA);
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));

					VK_CHECK(vkd.resetFences(*device, 1u, &*fenceA));
					submitDummySignal(vkd, queue, *fenceB);
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
					VK_CHECK(vkd.queueWaitIdle(queue));
				}
				else
					DE_FATAL("Unknown transference.");
			}
			else if (config.permanence == PERMANENCE_TEMPORARY)
			{
				if (transference == TRANSFERENCE_COPY)
				{
					submitDummySignal(vkd, queue, *fenceA);
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
					VK_CHECK(vkd.queueWaitIdle(queue));

					VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
					submitDummySignal(vkd, queue, *fenceB);

					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
					VK_CHECK(vkd.queueWaitIdle(queue));
				}
				else if (transference == TRANSFERENCE_REFERENCE)
				{
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
					VK_CHECK(vkd.queueWaitIdle(queue));

					VK_CHECK(vkd.resetFences(*device, 1u, &*fenceA));
					VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
					submitDummySignal(vkd, queue, *fenceA);
					submitDummySignal(vkd, queue, *fenceB);

					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
					VK_CHECK(vkd.queueWaitIdle(queue));
				}
				else
					DE_FATAL("Unknown transference.");
			}
			else
				DE_FATAL("Unknown permanence.");
		}

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

tcu::TestStatus testFenceFdDup (Context&				context,
								const FenceTestConfig	config)
{
#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd		(vkp, *instance, *device);
		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));

		TestLog&						log		= context.getTestContext().getLog();
		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));

		{
			NativeHandle		fd;

			if (transference == TRANSFERENCE_COPY)
				submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, fd);
			else
				getFenceNative(vkd, *device, *fenceA, config.externalType, fd);

			NativeHandle		newFd	(dup(fd.getFd()));

			if (newFd.getFd() < 0)
				log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;

			TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for fences fd");

			{
				const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, newFd, flags));

				if (transference == TRANSFERENCE_COPY)
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
				else if (transference == TRANSFERENCE_REFERENCE)
				{
					submitDummySignal(vkd, queue, *fenceA);
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
				}
				else
					DE_FATAL("Unknown permanence.");

				VK_CHECK(vkd.queueWaitIdle(queue));
			}
		}

		return tcu::TestStatus::pass("Pass");
	}
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
#endif
}

tcu::TestStatus testFenceFdDup2 (Context&				context,
								 const FenceTestConfig	config)
{
#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd		(vkp, *instance, *device);
		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));

		TestLog&						log		= context.getTestContext().getLog();
		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
		const vk::Unique<vk::VkFence>	fenceB	(createExportableFence(vkd, *device, config.externalType));

		{
			NativeHandle		fd, secondFd;

			if (transference == TRANSFERENCE_COPY)
			{
				submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, fd);
				submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceB, config.externalType, secondFd);
			}
			else
			{
				getFenceNative(vkd, *device, *fenceA, config.externalType, fd);
				getFenceNative(vkd, *device, *fenceB, config.externalType, secondFd);
			}

			int					newFd		(dup2(fd.getFd(), secondFd.getFd()));

			if (newFd < 0)
				log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;

			TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for fences fd");

			{
				const vk::Unique<vk::VkFence> fenceC (createAndImportFence(vkd, *device, config.externalType, secondFd, flags));

				if (transference == TRANSFERENCE_COPY)
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
				else if (transference == TRANSFERENCE_REFERENCE)
				{
					submitDummySignal(vkd, queue, *fenceA);
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
				}
				else
					DE_FATAL("Unknown permanence.");

				VK_CHECK(vkd.queueWaitIdle(queue));
			}
		}

		return tcu::TestStatus::pass("Pass");
	}
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support dup2()");
#endif
}

tcu::TestStatus testFenceFdDup3 (Context&				context,
								 const FenceTestConfig	config)
{
#if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd		(vkp, *instance, *device);
		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));

		TestLog&						log		= context.getTestContext().getLog();
		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
		const vk::Unique<vk::VkFence>	fenceB	(createExportableFence(vkd, *device, config.externalType));

		{
			NativeHandle					fd, secondFd;

			if (transference == TRANSFERENCE_COPY)
			{
				submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, fd);
				submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceB, config.externalType, secondFd);
			}
			else
			{
				getFenceNative(vkd, *device, *fenceA, config.externalType, fd);
				getFenceNative(vkd, *device, *fenceB, config.externalType, secondFd);
			}

			const vk::VkFenceImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
			const int						newFd		(dup3(fd.getFd(), secondFd.getFd(), 0));

			if (newFd < 0)
				log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;

			TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for fences fd");

			{
				const vk::Unique<vk::VkFence> fenceC (createAndImportFence(vkd, *device, config.externalType, secondFd, flags));

				if (transference == TRANSFERENCE_COPY)
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
				else if (transference == TRANSFERENCE_REFERENCE)
				{
					submitDummySignal(vkd, queue, *fenceA);
					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
				}
				else
					DE_FATAL("Unknown permanence.");

				VK_CHECK(vkd.queueWaitIdle(queue));
			}
		}

		return tcu::TestStatus::pass("Pass");
	}
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support dup3()");
#endif
}

tcu::TestStatus testFenceFdSendOverSocket (Context&					context,
										   const FenceTestConfig	config)
{
#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
	const Transference					transference		(getHandelTypeTransferences(config.externalType));
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	checkFenceSupport(vki, physicalDevice, config.externalType);

	{
		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
		const vk::DeviceDriver			vkd		(vkp, *instance, *device);
		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));

		TestLog&						log		= context.getTestContext().getLog();
		const vk::Unique<vk::VkFence>	fence	(createExportableFence(vkd, *device, config.externalType));
		NativeHandle					fd;

		if (transference == TRANSFERENCE_COPY)
			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fence, config.externalType, fd);
		else
			getFenceNative(vkd, *device, *fence, config.externalType, fd);

		{
			int sv[2];

			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
			{
				log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
				TCU_FAIL("Failed to create socket pair");
			}

			{
				const NativeHandle	srcSocket	(sv[0]);
				const NativeHandle	dstSocket	(sv[1]);
				std::string			sendData	("deqp");

				// Send FD
				{
					const int			fdRaw	(fd.getFd());
					msghdr				msg;
					cmsghdr*			cmsg;
					char				buffer[CMSG_SPACE(sizeof(int))];
					iovec				iov		= { &sendData[0], sendData.length()};

					deMemset(&msg, 0, sizeof(msg));

					msg.msg_control		= buffer;
					msg.msg_controllen	= sizeof(buffer);
					msg.msg_iovlen		= 1;
					msg.msg_iov			= &iov;

					cmsg				= CMSG_FIRSTHDR(&msg);
					cmsg->cmsg_level	= SOL_SOCKET;
					cmsg->cmsg_type		= SCM_RIGHTS;
					cmsg->cmsg_len		= CMSG_LEN(sizeof(int));

					deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
					msg.msg_controllen = cmsg->cmsg_len;

					if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
					{
						log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
						TCU_FAIL("Failed to send fd over socket");
					}
				}

				// Recv FD
				{
					msghdr			msg;
					char			buffer[CMSG_SPACE(sizeof(int))];
					std::string		recvData	(4, '\0');
					iovec			iov			= { &recvData[0], recvData.length() };

					deMemset(&msg, 0, sizeof(msg));

					msg.msg_control		= buffer;
					msg.msg_controllen	= sizeof(buffer);
					msg.msg_iovlen		= 1;
					msg.msg_iov			= &iov;

					const ssize_t	bytes = recvmsg(dstSocket.getFd(), &msg, 0);

					if (bytes < 0)
					{
						log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
						TCU_FAIL("Failed to recv fd over socket");

					}
					else if (bytes != (ssize_t)sendData.length())
					{
						TCU_FAIL("recvmsg() returned unpexpected number of bytes");
					}
					else
					{
						const vk::VkFenceImportFlags		flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
						const cmsghdr* const				cmsg	= CMSG_FIRSTHDR(&msg);
						int									newFd_;
						deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
						NativeHandle						newFd	(newFd_);

						TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
						TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
						TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
						TCU_CHECK(recvData == sendData);
						TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");

						{
							const vk::Unique<vk::VkFence> newFence (createAndImportFence(vkd, *device, config.externalType, newFd, flags));

							if (transference == TRANSFERENCE_COPY)
								VK_CHECK(vkd.waitForFences(*device, 1u, &*newFence, VK_TRUE, ~0ull));
							else if (transference == TRANSFERENCE_REFERENCE)
							{
								submitDummySignal(vkd, queue, *newFence);
								VK_CHECK(vkd.waitForFences(*device, 1u, &*newFence, VK_TRUE, ~0ull));
							}
							else
								DE_FATAL("Unknown permanence.");

							VK_CHECK(vkd.queueWaitIdle(queue));
						}
					}
				}
			}
		}
	}

	return tcu::TestStatus::pass("Pass");
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
#endif
}

tcu::TestStatus testBufferQueries (Context& context, vk::VkExternalMemoryHandleTypeFlagBits externalType)
{
	const vk::VkBufferCreateFlags		createFlags[]		=
	{
		0u,
		vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT,
		vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT|vk::VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,
		vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT|vk::VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
	};
	const vk::VkBufferUsageFlags		usageFlags[]		=
	{
		vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
		vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,
		vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
		vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
		vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
		vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
		vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
		vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
		vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
	};
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, externalType, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const vk::VkPhysicalDeviceFeatures	deviceFeatures		(vk::getPhysicalDeviceFeatures(vki, physicalDevice));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	// VkDevice is only created if physical device claims to support any of these types.
	vk::Move<vk::VkDevice>				device;
	de::MovePtr<vk::DeviceDriver>		vkd;
	bool								deviceHasDedicated	= false;

	TestLog&							log					= context.getTestContext().getLog();

	for (size_t createFlagNdx = 0; createFlagNdx < DE_LENGTH_OF_ARRAY(createFlags); createFlagNdx++)
	for (size_t usageFlagNdx = 0; usageFlagNdx < DE_LENGTH_OF_ARRAY(usageFlags); usageFlagNdx++)
	{
		const vk::VkBufferViewCreateFlags				createFlag		= createFlags[createFlagNdx];
		const vk::VkBufferUsageFlags					usageFlag		= usageFlags[usageFlagNdx];
		const vk::VkPhysicalDeviceExternalBufferInfo	info			=
		{
			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
			DE_NULL,
			createFlag,
			usageFlag,
			externalType
		};
		vk::VkExternalBufferProperties					properties		=
		{
			vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
			DE_NULL,
			{ 0u, 0u, 0u }
		};

		if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT) != 0) &&
			(deviceFeatures.sparseBinding == VK_FALSE))
			continue;

		if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) != 0) &&
			(deviceFeatures.sparseResidencyAliased == VK_FALSE))
			continue;

		if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) != 0) &&
			(deviceFeatures.sparseResidencyBuffer == VK_FALSE))
			continue;

		vki.getPhysicalDeviceExternalBufferProperties(physicalDevice, &info, &properties);

		log << TestLog::Message << properties << TestLog::EndMessage;

		TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES);
		TCU_CHECK(properties.pNext == DE_NULL);
		// \todo [2017-06-06 pyry] Can we validate anything else? Compatible types?

		if ((properties.externalMemoryProperties.externalMemoryFeatures & (vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT|vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT)) != 0)
		{
			const bool	requiresDedicated	= (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0;

			if (!device || (requiresDedicated && !deviceHasDedicated))
			{
				// \note We need to re-create with dedicated mem extensions if previous device instance didn't have them
				try
				{
					device				= createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, externalType, 0u, queueFamilyIndex, requiresDedicated);
					vkd					= de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vkp, *instance, *device));
					deviceHasDedicated	= requiresDedicated;
				}
				catch (const tcu::NotSupportedError& e)
				{
					log << e;
					TCU_FAIL("Physical device claims to support handle type but required extensions are not supported");
				}
			}
		}

		if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) != 0)
		{
			DE_ASSERT(!!device);
			DE_ASSERT(vkd);

			if (deviceHasDedicated)
			{
				const vk::Unique<vk::VkBuffer>				buffer						(createExternalBuffer(*vkd, *device, queueFamilyIndex, externalType, 1024u, createFlag, usageFlag));
				const vk::VkMemoryDedicatedRequirements		reqs						(getMemoryDedicatedRequirements(*vkd, *device, *buffer));
				const bool									propertiesRequiresDedicated	= (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0;
				const bool									objectRequiresDedicated		= (reqs.requiresDedicatedAllocation != VK_FALSE);

				if (propertiesRequiresDedicated != objectRequiresDedicated)
					TCU_FAIL("vkGetPhysicalDeviceExternalBufferProperties and vkGetBufferMemoryRequirements2 report different dedicated requirements");
			}
			else
			{
				// We can't query whether dedicated memory is required or not on per-object basis.
				// This check should be redundant as the code above tries to create device with
				// VK_KHR_dedicated_allocation & VK_KHR_get_memory_requirements2 if dedicated memory
				// is required. However, checking again doesn't hurt.
				TCU_CHECK((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) == 0);
			}
		}
	}

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

struct MemoryTestConfig
{
												MemoryTestConfig	(vk::VkExternalMemoryHandleTypeFlagBits	externalType_,
																	 bool										hostVisible_,
																	 bool										dedicated_)
		: externalType	(externalType_)
		, hostVisible	(hostVisible_)
		, dedicated		(dedicated_)
	{
	}

	vk::VkExternalMemoryHandleTypeFlagBits	externalType;
	bool									hostVisible;
	bool									dedicated;
};

#if (DE_OS == DE_OS_WIN32)
deUint32 chooseMemoryType (deUint32 bits)
{
	if (bits == 0)
		TCU_THROW(NotSupportedError, "No compatible memory type found");

	return deCtz32(bits);
}
#endif

tcu::TestStatus testMemoryWin32Create (Context& context, MemoryTestConfig config)
{
#if (DE_OS == DE_OS_WIN32)
	const vk::PlatformInterface&				vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>			instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver					vki					(vkp, *instance);
	const vk::VkPhysicalDevice					physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32								queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::Unique<vk::VkDevice>				device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
	const vk::DeviceDriver						vkd					(vkp, *instance, *device);
	const vk::VkBufferUsageFlags				usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	const deUint32								seed				= 1261033864u;
	const vk::VkDeviceSize						bufferSize			= 1024;
	const std::vector<deUint8>					testData			(genTestData(seed, (size_t)bufferSize));

	const vk::VkPhysicalDeviceMemoryProperties	memoryProps			= vk::getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice());
	const deUint32								compatibleMemTypes	= vk::getCompatibleMemoryTypes(memoryProps, config.hostVisible ? vk::MemoryRequirement::HostVisible : vk::MemoryRequirement::Any);

	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);

	// \note Buffer is only allocated to get memory requirements
	deUint32									exportedMemoryTypeIndex	= ~0U;
	const vk::Unique<vk::VkBuffer>				buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
	const vk::VkMemoryRequirements				requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
	const vk::VkExportMemoryWin32HandleInfoKHR	win32Info				=
	{
		vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
		DE_NULL,

		(vk::pt::Win32SecurityAttributesPtr)DE_NULL,
		DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
		DE_NULL
	};
	const vk::VkExportMemoryAllocateInfo		exportInfo			=
	{
		vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
		&win32Info,
		(vk::VkExternalMemoryHandleTypeFlags)config.externalType
	};

	exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits & compatibleMemTypes);
	const vk::VkMemoryAllocateInfo				info				=
	{
		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
		&exportInfo,
		requirements.size,
		exportedMemoryTypeIndex
	};
	const vk::Unique<vk::VkDeviceMemory>		memory				(vk::allocateMemory(vkd, *device, &info));
	NativeHandle								handleA;

	if (config.hostVisible)
		writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);

	getMemoryNative(vkd, *device, *memory, config.externalType, handleA);

	{
		const vk::Unique<vk::VkDeviceMemory>	memoryA	(importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleA));

		if (config.hostVisible)
		{
			const std::vector<deUint8>		testDataA		(genTestData(seed ^ 124798807u, (size_t)bufferSize));
			const std::vector<deUint8>		testDataB		(genTestData(seed ^ 970834278u, (size_t)bufferSize));

			checkHostMemory(vkd, *device, *memoryA, testData.size(), &testData[0]);
			checkHostMemory(vkd, *device, *memory,  testData.size(), &testData[0]);

			writeHostMemory(vkd, *device, *memoryA, testDataA.size(), &testDataA[0]);
			writeHostMemory(vkd, *device, *memory,  testDataA.size(), &testDataB[0]);

			checkHostMemory(vkd, *device, *memoryA, testData.size(), &testDataB[0]);
			checkHostMemory(vkd, *device, *memory,  testData.size(), &testDataB[0]);
		}
	}

	return tcu::TestStatus::pass("Pass");
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
#endif
}

tcu::TestStatus testMemoryImportTwice (Context& context, MemoryTestConfig config)
{
	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver				vki					(vkp, *instance);
	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
	const vk::DeviceDriver					vkd					(vkp, *instance, *device);
	const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	const deUint32							seed				= 1261033864u;
	const vk::VkDeviceSize					bufferSize			= 1024;
	const std::vector<deUint8>				testData			(genTestData(seed, (size_t)bufferSize));

	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);

	deUint32								exportedMemoryTypeIndex	= ~0U;
	// \note Buffer is only allocated to get memory requirements
	const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
	const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
	const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
	NativeHandle							handleA;

	if (config.hostVisible)
		writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);

	getMemoryNative(vkd, *device, *memory, config.externalType, handleA);

	{
		const vk::Unique<vk::VkBuffer>			bufferA	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
		const vk::Unique<vk::VkBuffer>			bufferB	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
		NativeHandle							handleB	(handleA);
		const vk::Unique<vk::VkDeviceMemory>	memoryA	(config.dedicated
														 ? importDedicatedMemory(vkd, *device, *bufferA, requirements, config.externalType, exportedMemoryTypeIndex, handleA)
														 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleA));
		const vk::Unique<vk::VkDeviceMemory>	memoryB	(config.dedicated
														 ? importDedicatedMemory(vkd, *device, *bufferB, requirements, config.externalType, exportedMemoryTypeIndex, handleB)
														 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleB));

		if (config.hostVisible)
		{
			const std::vector<deUint8>		testDataA		(genTestData(seed ^ 124798807u, (size_t)bufferSize));
			const std::vector<deUint8>		testDataB		(genTestData(seed ^ 970834278u, (size_t)bufferSize));

			checkHostMemory(vkd, *device, *memoryA, testData.size(), &testData[0]);
			checkHostMemory(vkd, *device, *memoryB, testData.size(), &testData[0]);

			writeHostMemory(vkd, *device, *memoryA, testData.size(), &testDataA[0]);
			writeHostMemory(vkd, *device, *memoryB, testData.size(), &testDataB[0]);

			checkHostMemory(vkd, *device, *memoryA, testData.size(), &testDataB[0]);
			checkHostMemory(vkd, *device, *memory, testData.size(), &testDataB[0]);
		}
	}

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

tcu::TestStatus testMemoryMultimpleImports (Context& context, MemoryTestConfig config)
{
	const size_t							count				= 4 * 1024;
	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver				vki					(vkp, *instance);
	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
	const vk::DeviceDriver					vkd					(vkp, *instance, *device);
	const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	const vk::VkDeviceSize					bufferSize			= 1024;

	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);

	deUint32								exportedMemoryTypeIndex	= ~0U;
	// \note Buffer is only allocated to get memory requirements
	const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
	const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
	const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
	NativeHandle							handleA;

	getMemoryNative(vkd, *device, *memory, config.externalType, handleA);

	for (size_t ndx = 0; ndx < count; ndx++)
	{
		const vk::Unique<vk::VkBuffer>			bufferB	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
		NativeHandle							handleB	(handleA);
		const vk::Unique<vk::VkDeviceMemory>	memoryB	(config.dedicated
														 ? importDedicatedMemory(vkd, *device, *bufferB, requirements, config.externalType, exportedMemoryTypeIndex, handleB)
														 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleB));
	}

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

tcu::TestStatus testMemoryMultimpleExports (Context& context, MemoryTestConfig config)
{
	const size_t							count				= 4 * 1024;
	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver				vki					(vkp, *instance);
	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
	const vk::DeviceDriver					vkd					(vkp, *instance, *device);
	const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	const vk::VkDeviceSize					bufferSize			= 1024;

	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);

	deUint32								exportedMemoryTypeIndex	= ~0U;
	// \note Buffer is only allocated to get memory requirements
	const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
	const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
	const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));

	for (size_t ndx = 0; ndx < count; ndx++)
	{
		NativeHandle	handle;
		getMemoryNative(vkd, *device, *memory, config.externalType, handle);
	}

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

tcu::TestStatus testMemoryFdDup (Context& context, MemoryTestConfig config)
{
#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	{
		const vk::Unique<vk::VkDevice>			device			(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
		const vk::DeviceDriver					vkd				(vkp, *instance, *device);

		TestLog&								log				= context.getTestContext().getLog();
		const vk::VkBufferUsageFlags			usage			= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
		const vk::VkDeviceSize					bufferSize		= 1024;
		const deUint32							seed			= 851493858u;
		const std::vector<deUint8>				testData		(genTestData(seed, (size_t)bufferSize));

		checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);

		deUint32								exportedMemoryTypeIndex	= ~0U;
		// \note Buffer is only allocated to get memory requirements
		const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
		const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
		const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));

		if (config.hostVisible)
			writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);

		const NativeHandle						fd				(getMemoryFd(vkd, *device, *memory, config.externalType));
		NativeHandle							newFd			(dup(fd.getFd()));

		if (newFd.getFd() < 0)
			log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;

		TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for memorys fd");

		{
			const vk::Unique<vk::VkBuffer>			newBuffer	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
			const vk::Unique<vk::VkDeviceMemory>	newMemory	(config.dedicated
																 ? importDedicatedMemory(vkd, *device, *newBuffer, requirements, config.externalType, exportedMemoryTypeIndex, newFd)
																 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, newFd));

			if (config.hostVisible)
			{
				const std::vector<deUint8>	testDataA	(genTestData(seed ^ 672929437u, (size_t)bufferSize));

				checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);

				writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
				checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
			}
		}

		return tcu::TestStatus::pass("Pass");
	}
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
#endif
}

tcu::TestStatus testMemoryFdDup2 (Context& context, MemoryTestConfig config)
{
#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	{
		const vk::Unique<vk::VkDevice>			device			(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
		const vk::DeviceDriver					vkd				(vkp, *instance, *device);

		TestLog&								log				= context.getTestContext().getLog();
		const vk::VkBufferUsageFlags			usage			= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
		const vk::VkDeviceSize					bufferSize		= 1024;
		const deUint32							seed			= 224466865u;
		const std::vector<deUint8>				testData		(genTestData(seed, (size_t)bufferSize));

		checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);

		deUint32								exportedMemoryTypeIndex	= ~0U;
		// \note Buffer is only allocated to get memory requirements
		const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
		const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
		const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));

		if (config.hostVisible)
			writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);

		const NativeHandle						fd				(getMemoryFd(vkd, *device, *memory, config.externalType));
		NativeHandle							secondFd		(getMemoryFd(vkd, *device, *memory, config.externalType));
		const int								newFd			(dup2(fd.getFd(), secondFd.getFd()));

		if (newFd < 0)
			log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;

		TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for memorys fd");

		{
			const vk::Unique<vk::VkBuffer>			newBuffer	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
			const vk::Unique<vk::VkDeviceMemory>	newMemory	(config.dedicated
																 ? importDedicatedMemory(vkd, *device, *newBuffer, requirements, config.externalType, exportedMemoryTypeIndex, secondFd)
																 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, secondFd));

			if (config.hostVisible)
			{
				const std::vector<deUint8>	testDataA	(genTestData(seed ^ 99012346u, (size_t)bufferSize));

				checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);

				writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
				checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
			}
		}

		return tcu::TestStatus::pass("Pass");
	}
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
#endif
}

tcu::TestStatus testMemoryFdDup3 (Context& context, MemoryTestConfig config)
{
#if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	{
		const vk::Unique<vk::VkDevice>			device			(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
		const vk::DeviceDriver					vkd				(vkp, *instance, *device);

		TestLog&								log				= context.getTestContext().getLog();
		const vk::VkBufferUsageFlags			usage			= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
		const vk::VkDeviceSize					bufferSize		= 1024;
		const deUint32							seed			= 2554088961u;
		const std::vector<deUint8>				testData		(genTestData(seed, (size_t)bufferSize));

		checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);

		deUint32								exportedMemoryTypeIndex	= ~0U;
		// \note Buffer is only allocated to get memory requirements
		const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
		const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
		const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));

		if (config.hostVisible)
			writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);

		const NativeHandle						fd				(getMemoryFd(vkd, *device, *memory, config.externalType));
		NativeHandle							secondFd		(getMemoryFd(vkd, *device, *memory, config.externalType));
		const int								newFd			(dup3(fd.getFd(), secondFd.getFd(), 0));

		if (newFd < 0)
			log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;

		TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for memorys fd");

		{
			const vk::Unique<vk::VkBuffer>			newBuffer	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
			const vk::Unique<vk::VkDeviceMemory>	newMemory	(config.dedicated
																 ? importDedicatedMemory(vkd, *device, *newBuffer, requirements, config.externalType, exportedMemoryTypeIndex, secondFd)
																 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, secondFd));

			if (config.hostVisible)
			{
				const std::vector<deUint8>	testDataA	(genTestData(seed ^ 4210342378u, (size_t)bufferSize));

				checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);

				writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
				checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
			}
		}

		return tcu::TestStatus::pass("Pass");
	}
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
#endif
}

tcu::TestStatus testMemoryFdSendOverSocket (Context& context, MemoryTestConfig config)
{
#if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
	const vk::PlatformInterface&				vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>			instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver					vki					(vkp, *instance);
	const vk::VkPhysicalDevice					physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32								queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	{
		const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
		const vk::DeviceDriver					vkd					(vkp, *instance, *device);

		TestLog&								log					= context.getTestContext().getLog();
		const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
		const vk::VkDeviceSize					bufferSize			= 1024;
		const deUint32							seed				= 3403586456u;
		const std::vector<deUint8>				testData			(genTestData(seed, (size_t)bufferSize));

		checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);

		deUint32								exportedMemoryTypeIndex	= ~0U;
		// \note Buffer is only allocated to get memory requirements
		const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
		const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
		const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));

		if (config.hostVisible)
			writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);

		const NativeHandle						fd					(getMemoryFd(vkd, *device, *memory, config.externalType));

		{
			int sv[2];

			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
			{
				log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
				TCU_FAIL("Failed to create socket pair");
			}

			{
				const NativeHandle	srcSocket	(sv[0]);
				const NativeHandle	dstSocket	(sv[1]);
				std::string			sendData	("deqp");

				// Send FD
				{
					const int			fdRaw	(fd.getFd());
					msghdr				msg;
					cmsghdr*			cmsg;
					char				tmpBuffer[CMSG_SPACE(sizeof(int))];
					iovec				iov		= { &sendData[0], sendData.length()};

					deMemset(&msg, 0, sizeof(msg));

					msg.msg_control		= tmpBuffer;
					msg.msg_controllen	= sizeof(tmpBuffer);
					msg.msg_iovlen		= 1;
					msg.msg_iov			= &iov;

					cmsg				= CMSG_FIRSTHDR(&msg);
					cmsg->cmsg_level	= SOL_SOCKET;
					cmsg->cmsg_type		= SCM_RIGHTS;
					cmsg->cmsg_len		= CMSG_LEN(sizeof(int));

					deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
					msg.msg_controllen = cmsg->cmsg_len;

					if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
					{
						log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
						TCU_FAIL("Failed to send fd over socket");
					}
				}

				// Recv FD
				{
					msghdr			msg;
					char			tmpBuffer[CMSG_SPACE(sizeof(int))];
					std::string		recvData	(4, '\0');
					iovec			iov			= { &recvData[0], recvData.length() };

					deMemset(&msg, 0, sizeof(msg));

					msg.msg_control		= tmpBuffer;
					msg.msg_controllen	= sizeof(tmpBuffer);
					msg.msg_iovlen		= 1;
					msg.msg_iov			= &iov;

					const ssize_t	bytes = recvmsg(dstSocket.getFd(), &msg, 0);

					if (bytes < 0)
					{
						log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
						TCU_FAIL("Failed to recv fd over socket");

					}
					else if (bytes != (ssize_t)sendData.length())
					{
						TCU_FAIL("recvmsg() returned unpexpected number of bytes");
					}
					else
					{
						const cmsghdr* const	cmsg	= CMSG_FIRSTHDR(&msg);
						int						newFd_;
						deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
						NativeHandle			newFd	(newFd_);

						TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
						TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
						TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
						TCU_CHECK(recvData == sendData);
						TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");

						{
							const vk::Unique<vk::VkBuffer>			newBuffer	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
							const vk::Unique<vk::VkDeviceMemory>	newMemory	(config.dedicated
																				 ? importDedicatedMemory(vkd, *device, *newBuffer, requirements, config.externalType, exportedMemoryTypeIndex, newFd)
																				 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, newFd));

							if (config.hostVisible)
							{
								const std::vector<deUint8>	testDataA	(genTestData(seed ^ 23478978u, (size_t)bufferSize));

								checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);

								writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
								checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
							}
						}
					}
				}
			}
		}
	}

	return tcu::TestStatus::pass("Pass");
#else
	DE_UNREF(context);
	DE_UNREF(config);
	TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
#endif
}

struct BufferTestConfig
{
											BufferTestConfig	(vk::VkExternalMemoryHandleTypeFlagBits		externalType_,
																 bool										dedicated_)
		: externalType	(externalType_)
		, dedicated		(dedicated_)
	{
	}

	vk::VkExternalMemoryHandleTypeFlagBits	externalType;
	bool									dedicated;
};

tcu::TestStatus testBufferBindExportImportBind (Context&				context,
												const BufferTestConfig	config)
{
	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver				vki					(vkp, *instance);
	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
	const vk::DeviceDriver					vkd					(vkp, *instance, *device);
	const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	const vk::VkDeviceSize					bufferSize			= 1024;

	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);

	deUint32								exportedMemoryTypeIndex	= ~0U;
	// \note Buffer is only allocated to get memory requirements
	const vk::Unique<vk::VkBuffer>			bufferA					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
	const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *bufferA));
	const vk::Unique<vk::VkDeviceMemory>	memoryA					(allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0, exportedMemoryTypeIndex));
	NativeHandle							handle;

	VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));

	getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);

	{
		const vk::Unique<vk::VkBuffer>			bufferB	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
		const vk::Unique<vk::VkDeviceMemory>	memoryB	(config.dedicated
														 ? importDedicatedMemory(vkd, *device, *bufferB, requirements, config.externalType, exportedMemoryTypeIndex, handle)
														 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));

		VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
	}

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

tcu::TestStatus testBufferExportBindImportBind (Context&				context,
												const BufferTestConfig	config)
{
	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver				vki					(vkp, *instance);
	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
	const vk::DeviceDriver					vkd					(vkp, *instance, *device);
	const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	const vk::VkDeviceSize					bufferSize			= 1024;

	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);

	deUint32								exportedMemoryTypeIndex	= ~0U;
	// \note Buffer is only allocated to get memory requirements
	const vk::Unique<vk::VkBuffer>			bufferA					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
	const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *bufferA));
	const vk::Unique<vk::VkDeviceMemory>	memoryA					(allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0, exportedMemoryTypeIndex));
	NativeHandle							handle;

	getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
	VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));

	{
		const vk::Unique<vk::VkBuffer>			bufferB	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
		const vk::Unique<vk::VkDeviceMemory>	memoryB	(config.dedicated
														 ? importDedicatedMemory(vkd, *device, *bufferB, requirements, config.externalType, exportedMemoryTypeIndex, handle)
														 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));

		VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
	}

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

tcu::TestStatus testBufferExportImportBindBind (Context&				context,
												const BufferTestConfig	config)
{
	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver				vki					(vkp, *instance);
	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
	const vk::DeviceDriver					vkd					(vkp, *instance, *device);
	const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	const vk::VkDeviceSize					bufferSize			= 1024;

	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);

	deUint32								exportedMemoryTypeIndex	= ~0U;
	// \note Buffer is only allocated to get memory requirements
	const vk::Unique<vk::VkBuffer>			bufferA					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
	const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *bufferA));
	const vk::Unique<vk::VkDeviceMemory>	memoryA					(allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0, exportedMemoryTypeIndex));
	NativeHandle							handle;

	getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);

	{
		const vk::Unique<vk::VkBuffer>			bufferB	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
		const vk::Unique<vk::VkDeviceMemory>	memoryB	(config.dedicated
														 ? importDedicatedMemory(vkd, *device, *bufferB, requirements, config.externalType, exportedMemoryTypeIndex, handle)
														 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));

		VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
		VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
	}

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

tcu::TestStatus testImageQueries (Context& context, vk::VkExternalMemoryHandleTypeFlagBits externalType)
{
	const vk::VkImageCreateFlags		createFlags[]		=
	{
		0u,
		vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT,
		vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT|vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,
		vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT|vk::VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,
		vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
		vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT
	};
	const vk::VkImageUsageFlags			usageFlags[]		=
	{
		vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
		vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
		vk::VK_IMAGE_USAGE_SAMPLED_BIT,
		vk::VK_IMAGE_USAGE_STORAGE_BIT,
		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
		vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
		vk::VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
		vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
	};
	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, externalType, 0u));
	const vk::InstanceDriver			vki					(vkp, *instance);
	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const vk::VkPhysicalDeviceFeatures	deviceFeatures		(vk::getPhysicalDeviceFeatures(vki, physicalDevice));
	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));

	// VkDevice is only created if physical device claims to support any of these types.
	vk::Move<vk::VkDevice>				device;
	de::MovePtr<vk::DeviceDriver>		vkd;
	bool								deviceHasDedicated	= false;

	TestLog&							log					= context.getTestContext().getLog();

	for (size_t createFlagNdx = 0; createFlagNdx < DE_LENGTH_OF_ARRAY(createFlags); createFlagNdx++)
	for (size_t usageFlagNdx = 0; usageFlagNdx < DE_LENGTH_OF_ARRAY(usageFlags); usageFlagNdx++)
	{
		const vk::VkImageViewCreateFlags						createFlag		= createFlags[createFlagNdx];
		const vk::VkImageUsageFlags								usageFlag		= usageFlags[usageFlagNdx];
		const vk::VkFormat										format			= vk::VK_FORMAT_R8G8B8A8_UNORM;
		const vk::VkImageType									type			= vk::VK_IMAGE_TYPE_2D;
		const vk::VkImageTiling									tiling			= vk::VK_IMAGE_TILING_OPTIMAL;
		const vk::VkPhysicalDeviceExternalImageFormatInfo		externalInfo	=
		{
			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
			DE_NULL,
			externalType
		};
		const vk::VkPhysicalDeviceImageFormatInfo2				info			=
		{
			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
			&externalInfo,

			format,
			type,
			tiling,
			usageFlag,
			createFlag,
		};
		vk::VkExternalImageFormatProperties						externalProperties	=
		{
			vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
			DE_NULL,
			{ 0u, 0u, 0u }
		};
		vk::VkImageFormatProperties2							properties			=
		{
			vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
			&externalProperties,
			{
				{ 0u, 0u, 0u },
				0u,
				0u,
				0u,
				0u
			}
		};

		if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != 0) &&
			(deviceFeatures.sparseBinding == VK_FALSE))
			continue;

		if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) != 0) &&
			(deviceFeatures.sparseResidencyImage2D == VK_FALSE))
			continue;

		if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) != 0) &&
			(deviceFeatures.sparseResidencyAliased == VK_FALSE))
			continue;

		vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &info, &properties);

		log << TestLog::Message << externalProperties << TestLog::EndMessage;
		TCU_CHECK(externalProperties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES);
		TCU_CHECK(externalProperties.pNext == DE_NULL);
		// \todo [2017-06-06 pyry] Can we validate anything else? Compatible types?

		if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & (vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT|vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT)) != 0)
		{
			const bool	requiresDedicated	= (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0;

			if (!device || (requiresDedicated && !deviceHasDedicated))
			{
				// \note We need to re-create with dedicated mem extensions if previous device instance didn't have them
				try
				{
					device				= createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, externalType, 0u, queueFamilyIndex, requiresDedicated);
					vkd					= de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vkp, *instance, *device));
					deviceHasDedicated	= requiresDedicated;
				}
				catch (const tcu::NotSupportedError& e)
				{
					log << e;
					TCU_FAIL("Physical device claims to support handle type but required extensions are not supported");
				}
			}
		}

		if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) != 0)
		{
			DE_ASSERT(!!device);
			DE_ASSERT(vkd);

			if (deviceHasDedicated)
			{
				const vk::Unique<vk::VkImage>				image						(createExternalImage(*vkd, *device, queueFamilyIndex, externalType, format, 16u, 16u, tiling, createFlag, usageFlag));
				const vk::VkMemoryDedicatedRequirements		reqs						(getMemoryDedicatedRequirements(*vkd, *device, *image));
				const bool									propertiesRequiresDedicated	= (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0;
				const bool									objectRequiresDedicated		= (reqs.requiresDedicatedAllocation != VK_FALSE);

				if (propertiesRequiresDedicated != objectRequiresDedicated)
					TCU_FAIL("vkGetPhysicalDeviceExternalBufferProperties and vkGetBufferMemoryRequirements2 report different dedicated requirements");
			}
			else
			{
				// We can't query whether dedicated memory is required or not on per-object basis.
				// This check should be redundant as the code above tries to create device with
				// VK_KHR_dedicated_allocation & VK_KHR_get_memory_requirements2 if dedicated memory
				// is required. However, checking again doesn't hurt.
				TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) == 0);
			}
		}
	}

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

struct ImageTestConfig
{
											ImageTestConfig	(vk::VkExternalMemoryHandleTypeFlagBits		externalType_,
															 bool										dedicated_)
		: externalType	(externalType_)
		, dedicated		(dedicated_)
	{
	}

	vk::VkExternalMemoryHandleTypeFlagBits	externalType;
	bool									dedicated;
};

tcu::TestStatus testImageBindExportImportBind (Context&					context,
											   const ImageTestConfig	config)
{
	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver				vki					(vkp, *instance);
	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
	const vk::DeviceDriver					vkd					(vkp, *instance, *device);
	const vk::VkImageUsageFlags				usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	const vk::VkFormat						format				= vk::VK_FORMAT_R8G8B8A8_UNORM;
	const deUint32							width				= 64u;
	const deUint32							height				= 64u;
	const vk::VkImageTiling					tiling				= vk::VK_IMAGE_TILING_OPTIMAL;

	checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);

	deUint32								exportedMemoryTypeIndex	= ~0U;
	const vk::Unique<vk::VkImage>			imageA					(createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
	const vk::VkMemoryRequirements			requirements			(getImageMemoryRequirements(vkd, *device, *imageA));
	const vk::Unique<vk::VkDeviceMemory>	memoryA					(allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0, exportedMemoryTypeIndex));
	NativeHandle							handle;

	VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));

	getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);

	{
		const vk::Unique<vk::VkImage>			imageB	(createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
		const vk::Unique<vk::VkDeviceMemory>	memoryB	(config.dedicated
														 ? importDedicatedMemory(vkd, *device, *imageB, requirements, config.externalType, exportedMemoryTypeIndex, handle)
														 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));

		VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
	}

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

tcu::TestStatus testImageExportBindImportBind (Context&					context,
											   const ImageTestConfig	config)
{
	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver				vki					(vkp, *instance);
	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
	const vk::DeviceDriver					vkd					(vkp, *instance, *device);
	const vk::VkImageUsageFlags				usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	const vk::VkFormat						format				= vk::VK_FORMAT_R8G8B8A8_UNORM;
	const deUint32							width				= 64u;
	const deUint32							height				= 64u;
	const vk::VkImageTiling					tiling				= vk::VK_IMAGE_TILING_OPTIMAL;

	checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);

	deUint32								exportedMemoryTypeIndex	= ~0U;
	const vk::Unique<vk::VkImage>			imageA					(createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
	const vk::VkMemoryRequirements			requirements			(getImageMemoryRequirements(vkd, *device, *imageA));
	const vk::Unique<vk::VkDeviceMemory>	memoryA					(allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0, exportedMemoryTypeIndex));
	NativeHandle							handle;

	getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
	VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));

	{
		const vk::Unique<vk::VkImage>			imageB	(createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
		const vk::Unique<vk::VkDeviceMemory>	memoryB	(config.dedicated
														 ? importDedicatedMemory(vkd, *device, *imageB, requirements, config.externalType, exportedMemoryTypeIndex, handle)
														 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));

		VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
	}

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

tcu::TestStatus testImageExportImportBindBind (Context&					context,
											   const ImageTestConfig	config)
{
	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
	const vk::InstanceDriver				vki					(vkp, *instance);
	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
	const vk::DeviceDriver					vkd					(vkp, *instance, *device);
	const vk::VkImageUsageFlags				usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
	const vk::VkFormat						format				= vk::VK_FORMAT_R8G8B8A8_UNORM;
	const deUint32							width				= 64u;
	const deUint32							height				= 64u;
	const vk::VkImageTiling					tiling				= vk::VK_IMAGE_TILING_OPTIMAL;

	checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);

	deUint32								exportedMemoryTypeIndex	= ~0U;
	// \note Image is only allocated to get memory requirements
	const vk::Unique<vk::VkImage>			imageA					(createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
	const vk::VkMemoryRequirements			requirements			(getImageMemoryRequirements(vkd, *device, *imageA));
	const vk::Unique<vk::VkDeviceMemory>	memoryA					(allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0, exportedMemoryTypeIndex));
	NativeHandle							handle;

	getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);

	{
		const vk::Unique<vk::VkImage>			imageB	(createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
		const vk::Unique<vk::VkDeviceMemory>	memoryB	(config.dedicated
														 ? importDedicatedMemory(vkd, *device, *imageB, requirements, config.externalType, exportedMemoryTypeIndex, handle)
														 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));

		VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
		VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
	}

	return tcu::TestStatus::pass("Pass");
}
de::MovePtr<tcu::TestCaseGroup> createFenceTests (tcu::TestContext& testCtx, vk::VkExternalFenceHandleTypeFlagBits externalType)
{
	const struct
	{
		const char* const	name;
		const Permanence	permanence;
	} permanences[] =
	{
		{ "temporary", PERMANENCE_TEMPORARY	},
		{ "permanent", PERMANENCE_PERMANENT	}
	};

	de::MovePtr<tcu::TestCaseGroup> fenceGroup (new tcu::TestCaseGroup(testCtx, externalFenceTypeToName(externalType), externalFenceTypeToName(externalType)));

	addFunctionCase(fenceGroup.get(), "info",	"Test external fence queries.",	testFenceQueries,	externalType);

	for (size_t permanenceNdx = 0; permanenceNdx < DE_LENGTH_OF_ARRAY(permanences); permanenceNdx++)
	{
		const Permanence		permanence		(permanences[permanenceNdx].permanence);
		const char* const		permanenceName	(permanences[permanenceNdx].name);
		const FenceTestConfig	config			(externalType, permanence);

		if (!isSupportedPermanence(externalType, permanence))
			continue;

		if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
			|| externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
		{
			addFunctionCase(fenceGroup.get(), std::string("create_win32_") + permanenceName,	"Test creating fence with win32 properties.",	testFenceWin32Create,	config);
		}

		addFunctionCase(fenceGroup.get(), std::string("import_twice_") + permanenceName,				"Test importing fence twice.",											testFenceImportTwice,				config);
		addFunctionCase(fenceGroup.get(), std::string("reimport_") + permanenceName,					"Test importing again over previously imported fence.",					testFenceImportReimport,			config);
		addFunctionCase(fenceGroup.get(), std::string("import_multiple_times_") + permanenceName,		"Test importing fence multiple times.",									testFenceMultipleImports,			config);
		addFunctionCase(fenceGroup.get(), std::string("signal_export_import_wait_") + permanenceName,	"Test signaling, exporting, importing and waiting for the sempahore.",	testFenceSignalExportImportWait,	config);
		addFunctionCase(fenceGroup.get(), std::string("signal_import_") + permanenceName,				"Test signaling and importing the fence.",								testFenceSignalImport,				config);
		addFunctionCase(fenceGroup.get(), std::string("reset_") + permanenceName,						"Test resetting the fence.",											testFenceReset,						config);
		addFunctionCase(fenceGroup.get(), std::string("transference_") + permanenceName,				"Test fences transference.",											testFenceTransference,				config);

		if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
			|| externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
		{
			// \note Not supported on WIN32 handles
			addFunctionCase(fenceGroup.get(), std::string("export_multiple_times_") + permanenceName,	"Test exporting fence multiple times.",		testFenceMultipleExports,	config);

			addFunctionCase(fenceGroup.get(), std::string("dup_") + permanenceName,						"Test calling dup() on exported fence.",	testFenceFdDup,				config);
			addFunctionCase(fenceGroup.get(), std::string("dup2_") + permanenceName,					"Test calling dup2() on exported fence.",	testFenceFdDup2,			config);
			addFunctionCase(fenceGroup.get(), std::string("dup3_") + permanenceName,					"Test calling dup3() on exported fence.",	testFenceFdDup3,			config);
			addFunctionCase(fenceGroup.get(), std::string("send_over_socket_") + permanenceName,		"Test sending fence fd over socket.",		testFenceFdSendOverSocket,	config);
		}

		if (getHandelTypeTransferences(externalType) == TRANSFERENCE_REFERENCE)
		{
			addFunctionCase(fenceGroup.get(), std::string("signal_wait_import_") + permanenceName,			"Test signaling and then waiting for the the sepmahore.",			testFenceSignalWaitImport,			config);
			addFunctionCase(fenceGroup.get(), std::string("export_signal_import_wait_") + permanenceName,	"Test exporting, signaling, importing and waiting for the fence.",	testFenceExportSignalImportWait,	config);
			addFunctionCase(fenceGroup.get(), std::string("export_import_signal_wait_") + permanenceName,	"Test exporting, importing, signaling and waiting for the fence.",	testFenceExportImportSignalWait,	config);
		}
	}

	return fenceGroup;
}

bool ValidateAHardwareBuffer(vk::VkFormat format, deUint64 requiredAhbUsage, const vk::DeviceDriver& vkd, const vk::VkDevice& device, vk::VkImageCreateFlags createFlag, deUint32 layerCount, bool& enableMaxLayerTest)
{
	DE_UNREF(createFlag);

	AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance();
	if (!ahbApi)
	{
		TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles");
	}

#if (DE_OS == DE_OS_ANDROID)
	// If CubeMap create flag is used and AHB doesn't support CubeMap return false.
	if(!AndroidHardwareBufferExternalApi::supportsCubeMap() && (createFlag & vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT))
		return false;
#endif

	vk::pt::AndroidHardwareBufferPtr ahb = ahbApi->allocate(64u, 64u, layerCount, ahbApi->vkFormatToAhbFormat(format), requiredAhbUsage);
	if (ahb.internal == DE_NULL)
	{
		enableMaxLayerTest = false;
		// try again with layerCount '1'
		ahb = ahbApi->allocate(64u, 64u, 1u, ahbApi->vkFormatToAhbFormat(format), requiredAhbUsage);
		if (ahb.internal == DE_NULL)
		{
			return false;
		}
	}
	NativeHandle nativeHandle(ahb);
	vk::VkAndroidHardwareBufferFormatPropertiesANDROID formatProperties =
	{
		vk::VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID,
		DE_NULL,
		vk::VK_FORMAT_UNDEFINED,
		0u,
		0u,
		{ vk::VK_COMPONENT_SWIZZLE_IDENTITY, vk::VK_COMPONENT_SWIZZLE_IDENTITY, vk::VK_COMPONENT_SWIZZLE_IDENTITY, vk::VK_COMPONENT_SWIZZLE_IDENTITY },
		vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
		vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
		vk::VK_CHROMA_LOCATION_COSITED_EVEN,
		vk::VK_CHROMA_LOCATION_COSITED_EVEN
	};
	vk::VkAndroidHardwareBufferPropertiesANDROID bufferProperties =
	{
		vk::VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID,
		&formatProperties,
		0u,
		0u
	};

	VK_CHECK(vkd.getAndroidHardwareBufferPropertiesANDROID(device, ahb, &bufferProperties));
	TCU_CHECK(formatProperties.format != vk::VK_FORMAT_UNDEFINED);
	TCU_CHECK(formatProperties.format == format);
	TCU_CHECK(formatProperties.externalFormat != 0u);
	TCU_CHECK((formatProperties.formatFeatures & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u);
	TCU_CHECK((formatProperties.formatFeatures & (vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT | vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) != 0u);
	return true;
}

tcu::TestStatus testAndroidHardwareBufferImageFormat  (Context& context, vk::VkFormat format)
{
	AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance();
	if (!ahbApi)
	{
		TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles");
	}

	const vk::VkExternalMemoryHandleTypeFlagBits  externalMemoryType  =	vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
	const vk::PlatformInterface&				  vkp					(context.getPlatformInterface());
	const vk::Unique<vk::VkInstance>			  instance				(createInstance(vkp, context.getUsedApiVersion(), externalMemoryType, 0u, 0u));
	const vk::InstanceDriver					  vki					(vkp, *instance);
	const vk::VkPhysicalDevice					  physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
	const deUint32								  queueFamilyIndex		(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
	const vk::Unique<vk::VkDevice>				  device				(createDevice(context.getUsedApiVersion(), vkp, *instance, vki, physicalDevice, 0u, externalMemoryType, 0u, queueFamilyIndex));
	const vk::DeviceDriver						  vkd					(vkp, *instance, *device);
	TestLog&									  log				  = context.getTestContext().getLog();
	const vk::VkPhysicalDeviceLimits			  limits			  = getPhysicalDeviceProperties(vki, physicalDevice).limits;

	vk::VkPhysicalDeviceProtectedMemoryFeatures		protectedFeatures;
	protectedFeatures.sType				= vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
	protectedFeatures.pNext				= DE_NULL;
	protectedFeatures.protectedMemory	= VK_FALSE;

	vk::VkPhysicalDeviceFeatures2					deviceFeatures;
	deviceFeatures.sType		= vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
	deviceFeatures.pNext		= &protectedFeatures;

	vki.getPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures);

	const vk::VkImageUsageFlagBits				  usageFlags[]		  =
	{
		vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
		vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
		vk::VK_IMAGE_USAGE_SAMPLED_BIT,
		vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
	};
	const vk::VkImageCreateFlagBits				  createFlags[]		  =
	{
		vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
		vk::VK_IMAGE_CREATE_EXTENDED_USAGE_BIT,
		vk::VK_IMAGE_CREATE_PROTECTED_BIT,
		vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,
	};
	const vk::VkImageTiling						  tilings[]			  =
	{
		vk::VK_IMAGE_TILING_OPTIMAL,
		vk::VK_IMAGE_TILING_LINEAR,
	};
	deUint64 mustSupportAhbUsageFlags = ahbApi->mustSupportAhbUsageFlags();
	const size_t	numOfUsageFlags				= DE_LENGTH_OF_ARRAY(usageFlags);
	const size_t	numOfCreateFlags			= DE_LENGTH_OF_ARRAY(createFlags);
	const size_t	numOfFlagCombos				= 1u << (numOfUsageFlags + numOfCreateFlags);
	const size_t	numOfTilings				= DE_LENGTH_OF_ARRAY(tilings);

	for (size_t combo = 0; combo < numOfFlagCombos; combo++)
	{
		vk::VkImageUsageFlags	usage				= 0;
		vk::VkImageCreateFlags	createFlag			= 0;
		deUint64				requiredAhbUsage	= 0;
		bool					enableMaxLayerTest	= true;
		for (size_t usageNdx = 0; usageNdx < numOfUsageFlags; usageNdx++)
		{
			if ((combo & (1u << usageNdx)) == 0)
				continue;
			usage |= usageFlags[usageNdx];
			requiredAhbUsage |= ahbApi->vkUsageToAhbUsage(usageFlags[usageNdx]);
		}
		for (size_t createFlagNdx = 0; createFlagNdx < numOfCreateFlags; createFlagNdx++)
		{
			const size_t	bit	= numOfUsageFlags + createFlagNdx;
			if ((combo & (1u << bit)) == 0)
				continue;
			if (((createFlags[createFlagNdx] & vk::VK_IMAGE_CREATE_PROTECTED_BIT) == vk::VK_IMAGE_CREATE_PROTECTED_BIT ) &&
				(protectedFeatures.protectedMemory == VK_FALSE))
				continue;
			createFlag |= createFlags[createFlagNdx];
			requiredAhbUsage |= ahbApi->vkCreateToAhbUsage(createFlags[createFlagNdx]);
		}

		// Only test a combination if the usage flags include at least one of the AHARDWAREBUFFER_USAGE_GPU_* flag.
		if ((requiredAhbUsage & mustSupportAhbUsageFlags) == 0u)
			continue;

		// Only test a combination if AHardwareBuffer can be successfully allocated for it.
		if (!ValidateAHardwareBuffer(format, requiredAhbUsage, vkd, *device, createFlag, limits.maxImageArrayLayers, enableMaxLayerTest))
			continue;

		bool foundAnyUsableTiling = false;
		for (size_t tilingIndex = 0; tilingIndex < numOfTilings; tilingIndex++)
		{
			const vk::VkImageTiling tiling = tilings[tilingIndex];

			const vk::VkPhysicalDeviceExternalImageFormatInfo	externalInfo		=
			{
				vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
				DE_NULL,
				vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID
			};
			const vk::VkPhysicalDeviceImageFormatInfo2			info				=
			{
				vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
				&externalInfo,
				format,
				vk::VK_IMAGE_TYPE_2D,
				tiling,
				usage,
				createFlag,
			};

			vk::VkAndroidHardwareBufferUsageANDROID				ahbUsageProperties	=
			{
				vk::VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID,
				DE_NULL,
				0u
			};
			vk::VkExternalImageFormatProperties					externalProperties	=
			{
				vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
				&ahbUsageProperties,
				{ 0u, 0u, 0u }
			};
			vk::VkImageFormatProperties2						properties			=
			{
				vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
				&externalProperties,
				{
					{ 0u, 0u, 0u },
					0u,
					0u,
					0u,
					0u
				}
			};

			if (vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &info, &properties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
			{
				log << TestLog::Message << "Tiling " << tiling << " is not supported." << TestLog::EndMessage;
				continue;
			}

			foundAnyUsableTiling = true;

			TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) != 0);
			TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) != 0);
			TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0);
			deUint32 maxWidth   = properties.imageFormatProperties.maxExtent.width;
			deUint32 maxHeight  = properties.imageFormatProperties.maxExtent.height;
			TCU_CHECK(maxWidth >= 4096);
			TCU_CHECK(maxHeight >= 4096);
			// Even if not requested, at least one of GPU_* usage flags must be present.
			TCU_CHECK((ahbUsageProperties.androidHardwareBufferUsage & mustSupportAhbUsageFlags) != 0u);
			// The AHB usage flags corresponding to the create and usage flags used in info must be present.
			TCU_CHECK((ahbUsageProperties.androidHardwareBufferUsage & requiredAhbUsage) == requiredAhbUsage);

			log << TestLog::Message << "Required flags: " << std::hex << requiredAhbUsage << " Actual flags: " << std::hex << ahbUsageProperties.androidHardwareBufferUsage
				<< TestLog::EndMessage;

			struct ImageSize
			{
				deUint32 width;
				deUint32 height;
			};
			ImageSize sizes[] =
			{
				{64u, 64u},
				{1024u, 2096u},
			};
			for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(sizes); i++)
			{
				deUint32								exportedMemoryTypeIndex	= ~0U;
				const vk::Unique<vk::VkImage>			image					(createExternalImage(vkd, *device, queueFamilyIndex, externalMemoryType, format, sizes[i].width, sizes[i].height, tiling, createFlag, usage));
				const vk::VkMemoryRequirements			requirements			(getImageMemoryRequirements(vkd, *device, *image));
				const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vkd, *device, requirements, externalMemoryType, *image, exportedMemoryTypeIndex));
				NativeHandle							handle;

				VK_CHECK(vkd.bindImageMemory(*device, *image, *memory, 0u));
				getMemoryNative(vkd, *device, *memory, externalMemoryType, handle);

				deUint32 ahbFormat = 0;
				deUint64 anhUsage  = 0;
				ahbApi->describe(handle.getAndroidHardwareBuffer(), DE_NULL, DE_NULL, DE_NULL, &ahbFormat, &anhUsage, DE_NULL);
				TCU_CHECK(ahbFormat == ahbApi->vkFormatToAhbFormat(format));
				TCU_CHECK((anhUsage & requiredAhbUsage) == requiredAhbUsage);

				// Let watchdog know we're alive
				context.getTestContext().touchWatchdog();
			}

			if (properties.imageFormatProperties.maxMipLevels > 1u)
			{
				deUint32								exportedMemoryTypeIndex	= ~0U;
				const vk::Unique<vk::VkImage>			image					(createExternalImage(vkd, *device, queueFamilyIndex, externalMemoryType, format, 64u, 64u, tiling, createFlag, usage, properties.imageFormatProperties.maxMipLevels));
				const vk::VkMemoryRequirements			requirements			(getImageMemoryRequirements(vkd, *device, *image));
				const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vkd, *device, requirements, externalMemoryType, *image, exportedMemoryTypeIndex));
				NativeHandle							handle;

				VK_CHECK(vkd.bindImageMemory(*device, *image, *memory, 0u));
				getMemoryNative(vkd, *device, *memory, externalMemoryType, handle);

				deUint32 ahbFormat = 0;
				deUint64 anhUsage  = 0;
				ahbApi->describe(handle.getAndroidHardwareBuffer(), DE_NULL, DE_NULL, DE_NULL, &ahbFormat, &anhUsage, DE_NULL);
				TCU_CHECK(ahbFormat == ahbApi->vkFormatToAhbFormat(format));
				TCU_CHECK((anhUsage & requiredAhbUsage) == requiredAhbUsage);
			}

			if ((properties.imageFormatProperties.maxArrayLayers > 1u) && enableMaxLayerTest)
			{
				deUint32								exportedMemoryTypeIndex	= ~0U;
				const vk::Unique<vk::VkImage>			image					(createExternalImage(vkd, *device, queueFamilyIndex, externalMemoryType, format, 64u, 64u, tiling, createFlag, usage, 1u, properties.imageFormatProperties.maxArrayLayers));
				const vk::VkMemoryRequirements			requirements			(getImageMemoryRequirements(vkd, *device, *image));
				const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vkd, *device, requirements, externalMemoryType, *image, exportedMemoryTypeIndex));
				NativeHandle							handle;

				VK_CHECK(vkd.bindImageMemory(*device, *image, *memory, 0u));
				getMemoryNative(vkd, *device, *memory, externalMemoryType, handle);

				deUint32 ahbFormat = 0;
				deUint64 anhUsage  = 0;
				ahbApi->describe(handle.getAndroidHardwareBuffer(), DE_NULL, DE_NULL, DE_NULL, &ahbFormat, &anhUsage, DE_NULL);
				TCU_CHECK(ahbFormat == ahbApi->vkFormatToAhbFormat(format));
				TCU_CHECK((anhUsage & requiredAhbUsage) == requiredAhbUsage);
			}
		}

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

de::MovePtr<tcu::TestCaseGroup> createFenceTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> fenceGroup (new tcu::TestCaseGroup(testCtx, "fence", "Tests for external fences."));

	fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT).release());
	fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT).release());
	fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT).release());
	fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT).release());

	return fenceGroup;
}

de::MovePtr<tcu::TestCaseGroup> createSemaphoreTests (tcu::TestContext& testCtx, vk::VkExternalSemaphoreHandleTypeFlagBits externalType)
{
	const struct
	{
		const char* const	name;
		const Permanence	permanence;
	} permanences[] =
	{
		{ "temporary", PERMANENCE_TEMPORARY	},
		{ "permanent", PERMANENCE_PERMANENT	}
	};

	de::MovePtr<tcu::TestCaseGroup> semaphoreGroup (new tcu::TestCaseGroup(testCtx, externalSemaphoreTypeToName(externalType), externalSemaphoreTypeToName(externalType)));

	addFunctionCase(semaphoreGroup.get(), "info",	"Test external semaphore queries.",	testSemaphoreQueries,	externalType);

	for (size_t permanenceNdx = 0; permanenceNdx < DE_LENGTH_OF_ARRAY(permanences); permanenceNdx++)
	{
		const Permanence			permanence		(permanences[permanenceNdx].permanence);
		const char* const			permanenceName	(permanences[permanenceNdx].name);
		const SemaphoreTestConfig	config			(externalType, permanence);

		if (!isSupportedPermanence(externalType, permanence))
			continue;

		if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
			|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
		{
			addFunctionCase(semaphoreGroup.get(), std::string("create_win32_") + permanenceName,	"Test creating semaphore with win32 properties.",	testSemaphoreWin32Create,	config);
		}

		addFunctionCase(semaphoreGroup.get(), std::string("import_twice_") + permanenceName,				"Test importing semaphore twice.",										testSemaphoreImportTwice,				config);
		addFunctionCase(semaphoreGroup.get(), std::string("reimport_") + permanenceName,					"Test importing again over previously imported semaphore.",				testSemaphoreImportReimport,			config);
		addFunctionCase(semaphoreGroup.get(), std::string("import_multiple_times_") + permanenceName,		"Test importing semaphore multiple times.",								testSemaphoreMultipleImports,			config);
		addFunctionCase(semaphoreGroup.get(), std::string("signal_export_import_wait_") + permanenceName,	"Test signaling, exporting, importing and waiting for the sempahore.",	testSemaphoreSignalExportImportWait,	config);
		addFunctionCase(semaphoreGroup.get(), std::string("signal_import_") + permanenceName,				"Test signaling and importing the semaphore.",							testSemaphoreSignalImport,				config);
		addFunctionCase(semaphoreGroup.get(), std::string("transference_") + permanenceName,				"Test semaphores transference.",										testSemaphoreTransference,				config);

		if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
			|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
		{
			// \note Not supported on WIN32 handles
			addFunctionCase(semaphoreGroup.get(), std::string("export_multiple_times_") + permanenceName,	"Test exporting semaphore multiple times.",		testSemaphoreMultipleExports,	config);

			addFunctionCase(semaphoreGroup.get(), std::string("dup_") + permanenceName,						"Test calling dup() on exported semaphore.",	testSemaphoreFdDup,				config);
			addFunctionCase(semaphoreGroup.get(), std::string("dup2_") + permanenceName,					"Test calling dup2() on exported semaphore.",	testSemaphoreFdDup2,			config);
			addFunctionCase(semaphoreGroup.get(), std::string("dup3_") + permanenceName,					"Test calling dup3() on exported semaphore.",	testSemaphoreFdDup3,			config);
			addFunctionCase(semaphoreGroup.get(), std::string("send_over_socket_") + permanenceName,		"Test sending semaphore fd over socket.",		testSemaphoreFdSendOverSocket,	config);
		}

		if (getHandelTypeTransferences(externalType) == TRANSFERENCE_REFERENCE)
		{
			addFunctionCase(semaphoreGroup.get(), std::string("signal_wait_import_") + permanenceName,			"Test signaling and then waiting for the the sepmahore.",				testSemaphoreSignalWaitImport,			config);
			addFunctionCase(semaphoreGroup.get(), std::string("export_signal_import_wait_") + permanenceName,	"Test exporting, signaling, importing and waiting for the semaphore.",	testSemaphoreExportSignalImportWait,	config);
			addFunctionCase(semaphoreGroup.get(), std::string("export_import_signal_wait_") + permanenceName,	"Test exporting, importing, signaling and waiting for the semaphore.",	testSemaphoreExportImportSignalWait,	config);
		}
	}

	return semaphoreGroup;
}

de::MovePtr<tcu::TestCaseGroup> createSemaphoreTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> semaphoreGroup (new tcu::TestCaseGroup(testCtx, "semaphore", "Tests for external semaphores."));

	semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT).release());
	semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT).release());
	semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT).release());
	semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT).release());

	return semaphoreGroup;
}

de::MovePtr<tcu::TestCaseGroup> createMemoryTests (tcu::TestContext& testCtx, vk::VkExternalMemoryHandleTypeFlagBits externalType)
{
	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, externalMemoryTypeToName(externalType), "Tests for external memory"));

	for (size_t dedicatedNdx = 0; dedicatedNdx < 2; dedicatedNdx++)
	{
		const bool						dedicated		(dedicatedNdx == 1);
		de::MovePtr<tcu::TestCaseGroup>	dedicatedGroup	(new tcu::TestCaseGroup(testCtx, dedicated ? "dedicated" : "suballocated", ""));

		for (size_t hostVisibleNdx = 0; hostVisibleNdx < 2; hostVisibleNdx++)
		{
			const bool						hostVisible			(hostVisibleNdx == 1);
			de::MovePtr<tcu::TestCaseGroup>	hostVisibleGroup	(new tcu::TestCaseGroup(testCtx, hostVisible ? "host_visible" : "device_only", ""));
			const MemoryTestConfig			memoryConfig		(externalType, hostVisible, dedicated);

			if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
				|| externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
			{
				addFunctionCase(hostVisibleGroup.get(), "create_win32",	"Test creating memory with win32 properties .",		testMemoryWin32Create,	memoryConfig);
			}

			addFunctionCase(hostVisibleGroup.get(), "import_twice",				"Test importing memory object twice.",			testMemoryImportTwice,		memoryConfig);
			addFunctionCase(hostVisibleGroup.get(), "import_multiple_times",	"Test importing memory object multiple times.",	testMemoryMultimpleImports,	memoryConfig);

			if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
			{
				addFunctionCase(hostVisibleGroup.get(), "dup",									"Test calling dup() on exported memory.",	testMemoryFdDup,			memoryConfig);
				addFunctionCase(hostVisibleGroup.get(), "dup2",									"Test calling dup2() on exported memory.",	testMemoryFdDup2,			memoryConfig);
				addFunctionCase(hostVisibleGroup.get(), "dup3",									"Test calling dup3() on exported memory.",	testMemoryFdDup3,			memoryConfig);
				addFunctionCase(hostVisibleGroup.get(), "send_over_socket",						"Test sending memory fd over socket.",		testMemoryFdSendOverSocket,	memoryConfig);
				// \note Not supported on WIN32 handles
				addFunctionCase(hostVisibleGroup.get(), "export_multiple_times",				"Test exporting memory multiple times.",	testMemoryMultimpleExports,	memoryConfig);
			}

			dedicatedGroup->addChild(hostVisibleGroup.release());
		}

		{
			de::MovePtr<tcu::TestCaseGroup>	bufferGroup		(new tcu::TestCaseGroup(testCtx, "buffer", ""));
			const BufferTestConfig			bufferConfig	(externalType, dedicated);

			addFunctionCase(bufferGroup.get(), "info",						"External buffer memory info query.",						testBufferQueries,				externalType);
			addFunctionCase(bufferGroup.get(), "bind_export_import_bind",	"Test binding, exporting, importing and binding buffer.",	testBufferBindExportImportBind,	bufferConfig);
			addFunctionCase(bufferGroup.get(), "export_bind_import_bind",	"Test exporting, binding, importing and binding buffer.",	testBufferExportBindImportBind,	bufferConfig);
			addFunctionCase(bufferGroup.get(), "export_import_bind_bind",	"Test exporting, importind and binding buffer.",			testBufferExportImportBindBind,	bufferConfig);

			dedicatedGroup->addChild(bufferGroup.release());
		}

		{
			de::MovePtr<tcu::TestCaseGroup> imageGroup	(new tcu::TestCaseGroup(testCtx, "image", ""));
			const ImageTestConfig			imageConfig	(externalType, dedicated);

			addFunctionCase(imageGroup.get(), "info",						"External image memory info query.",						testImageQueries,				externalType);
			addFunctionCase(imageGroup.get(), "bind_export_import_bind",	"Test binding, exporting, importing and binding image.",	testImageBindExportImportBind,	imageConfig);
			addFunctionCase(imageGroup.get(), "export_bind_import_bind",	"Test exporting, binding, importing and binding image.",	testImageExportBindImportBind,	imageConfig);
			addFunctionCase(imageGroup.get(), "export_import_bind_bind",	"Test exporting, importind and binding image.",				testImageExportImportBindBind,	imageConfig);

			dedicatedGroup->addChild(imageGroup.release());
		}

		group->addChild(dedicatedGroup.release());
	}

	if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
	{
		de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx, "image_formats", "Test minimum image format support"));

		const vk::VkFormat	ahbFormats[]	=
		{
			vk::VK_FORMAT_R8G8B8_UNORM,
			vk::VK_FORMAT_R8G8B8A8_UNORM,
			vk::VK_FORMAT_R5G6B5_UNORM_PACK16,
			vk::VK_FORMAT_R16G16B16A16_SFLOAT,
			vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32,
		};
		const size_t		numOfAhbFormats	= DE_LENGTH_OF_ARRAY(ahbFormats);

		for (size_t ahbFormatNdx = 0; ahbFormatNdx < numOfAhbFormats; ahbFormatNdx++)
		{
			const vk::VkFormat	format			= ahbFormats[ahbFormatNdx];
			const std::string	testCaseName	= getFormatCaseName(format);

			addFunctionCase(formatGroup.get(), testCaseName, "", testAndroidHardwareBufferImageFormat, format);
		}

		group->addChild(formatGroup.release());
	}

	return group;
}

de::MovePtr<tcu::TestCaseGroup> createMemoryTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "memory", "Tests for external memory"));

	group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT).release());
	group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT).release());
	group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT).release());
	group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID).release());

	return group;
}

} // anonymous

tcu::TestCaseGroup* createExternalMemoryTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "external", "Tests for external Vulkan objects"));

	group->addChild(createSemaphoreTests(testCtx).release());
	group->addChild(createMemoryTests(testCtx).release());
	group->addChild(createFenceTests(testCtx).release());

	return group.release();
}

} // api
} // vkt
