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

#include "vktSynchronizationWin32KeyedMutexTests.hpp"

#include "vkDeviceUtil.hpp"
#include "vkPlatform.hpp"
#include "vkCmdUtil.hpp"
#include "vktTestCaseUtil.hpp"
#include "deSharedPtr.hpp"

#include "vktSynchronizationUtil.hpp"
#include "vktSynchronizationOperation.hpp"
#include "vktSynchronizationOperationTestData.hpp"
#include "vktExternalMemoryUtil.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktCustomInstancesDevices.hpp"

#include "tcuResultCollector.hpp"
#include "tcuTestLog.hpp"
#include "tcuCommandLine.hpp"

#if (DE_OS == DE_OS_WIN32)
#	define WIN32_LEAN_AND_MEAN
#	define NOMINMAX
#	include <windows.h>
#	include <aclapi.h>
#	include <versionhelpers.h>
#	include <d3d11_2.h>
#	include <d3dcompiler.h>

typedef HRESULT				(WINAPI * LPD3DX11COMPILEFROMMEMORY)(LPCSTR,
																 SIZE_T,
																 LPCSTR,
																 CONST D3D10_SHADER_MACRO*,
																 LPD3D10INCLUDE,
																 LPCSTR,
																 LPCSTR,
																 UINT,
																 UINT,
																 void*, /* ID3DX11ThreadPump */
																 ID3D10Blob** ,
																 ID3D10Blob** ,
																 HRESULT*);
#endif

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

namespace vkt
{
using namespace vk;
namespace synchronization
{
namespace
{
using namespace vk;
using de::SharedPtr;

static const ResourceDescription s_resourcesWin32KeyedMutex[] =
{
	{ RESOURCE_TYPE_BUFFER,	tcu::IVec4( 0x4000, 0, 0, 0),	vk::VK_IMAGE_TYPE_LAST,	vk::VK_FORMAT_UNDEFINED,			(vk::VkImageAspectFlags)0,		vk::VK_SAMPLE_COUNT_1_BIT },	// 16 KiB (min max UBO range)
	{ RESOURCE_TYPE_BUFFER,	tcu::IVec4(0x40000, 0, 0, 0),	vk::VK_IMAGE_TYPE_LAST,	vk::VK_FORMAT_UNDEFINED,			(vk::VkImageAspectFlags)0,		vk::VK_SAMPLE_COUNT_1_BIT },	// 256 KiB

	{ RESOURCE_TYPE_IMAGE,	tcu::IVec4(128, 128, 0, 0),		vk::VK_IMAGE_TYPE_2D,	vk::VK_FORMAT_R8_UNORM,				vk::VK_IMAGE_ASPECT_COLOR_BIT,	vk::VK_SAMPLE_COUNT_1_BIT },
	{ RESOURCE_TYPE_IMAGE,	tcu::IVec4(128, 128, 0, 0),		vk::VK_IMAGE_TYPE_2D,	vk::VK_FORMAT_R16_UINT,				vk::VK_IMAGE_ASPECT_COLOR_BIT,	vk::VK_SAMPLE_COUNT_1_BIT },
	{ RESOURCE_TYPE_IMAGE,	tcu::IVec4(128, 128, 0, 0),		vk::VK_IMAGE_TYPE_2D,	vk::VK_FORMAT_R8G8B8A8_UNORM,		vk::VK_IMAGE_ASPECT_COLOR_BIT,	vk::VK_SAMPLE_COUNT_1_BIT },
	{ RESOURCE_TYPE_IMAGE,	tcu::IVec4(128, 128, 0, 0),		vk::VK_IMAGE_TYPE_2D,	vk::VK_FORMAT_R16G16B16A16_UINT,	vk::VK_IMAGE_ASPECT_COLOR_BIT,	vk::VK_SAMPLE_COUNT_1_BIT },
	{ RESOURCE_TYPE_IMAGE,	tcu::IVec4(128, 128, 0, 0),		vk::VK_IMAGE_TYPE_2D,	vk::VK_FORMAT_R32G32B32A32_SFLOAT,	vk::VK_IMAGE_ASPECT_COLOR_BIT,	vk::VK_SAMPLE_COUNT_1_BIT },
};

struct TestConfig
{
								TestConfig		(const ResourceDescription&					resource_,
												 OperationName								writeOp_,
												 OperationName								readOp_,
												 vk::VkExternalMemoryHandleTypeFlagBits		memoryHandleTypeBuffer_,
												 vk::VkExternalMemoryHandleTypeFlagBits		memoryHandleTypeImage_)
		: resource					(resource_)
		, writeOp					(writeOp_)
		, readOp					(readOp_)
		, memoryHandleTypeBuffer	(memoryHandleTypeBuffer_)
		, memoryHandleTypeImage		(memoryHandleTypeImage_)
	{
	}

	const ResourceDescription							resource;
	const OperationName									writeOp;
	const OperationName									readOp;
	const vk::VkExternalMemoryHandleTypeFlagBits		memoryHandleTypeBuffer;
	const vk::VkExternalMemoryHandleTypeFlagBits		memoryHandleTypeImage;
};

bool checkQueueFlags (vk::VkQueueFlags availableFlags, const vk::VkQueueFlags neededFlags)
{
	if ((availableFlags & (vk::VK_QUEUE_GRAPHICS_BIT | vk::VK_QUEUE_COMPUTE_BIT)) != 0)
		availableFlags |= vk::VK_QUEUE_TRANSFER_BIT;

	return (availableFlags & neededFlags) != 0;
}

class SimpleAllocation : public vk::Allocation
{
public:
								SimpleAllocation	(const vk::DeviceInterface&	vkd,
													 vk::VkDevice				device,
													 const vk::VkDeviceMemory	memory);
								~SimpleAllocation	(void);

private:
	const vk::DeviceInterface&	m_vkd;
	const vk::VkDevice			m_device;
};

SimpleAllocation::SimpleAllocation (const vk::DeviceInterface&	vkd,
									vk::VkDevice				device,
									const vk::VkDeviceMemory	memory)
	: Allocation	(memory, 0, DE_NULL)
	, m_vkd			(vkd)
	, m_device		(device)
{
}

SimpleAllocation::~SimpleAllocation (void)
{
	m_vkd.freeMemory(m_device, getMemory(), DE_NULL);
}

CustomInstance createTestInstance (Context& context)
{
	std::vector<std::string> extensions;
	extensions.push_back("VK_KHR_get_physical_device_properties2");
	extensions.push_back("VK_KHR_external_memory_capabilities");

	return createCustomInstanceWithExtensions(context, extensions);
}

vk::Move<vk::VkDevice> createTestDevice (Context&						context,
										 vk::VkInstance					instance,
										 const vk::InstanceInterface&	vki,
										 vk::VkPhysicalDevice			physicalDevice)
{
	const bool										validationEnabled		= context.getTestContext().getCommandLine().isValidationEnabled();
	const deUint32									apiVersion				= context.getUsedApiVersion();
	const vk::PlatformInterface&					vkp						= context.getPlatformInterface();
	const float										priority				= 0.0f;
	const std::vector<vk::VkQueueFamilyProperties>	queueFamilyProperties	= vk::getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
	std::vector<deUint32>							queueFamilyIndices		(queueFamilyProperties.size(), 0xFFFFFFFFu);
	std::vector<const char*>						extensions;

	if (!isCoreDeviceExtension(apiVersion, "VK_KHR_external_memory"))
		extensions.push_back("VK_KHR_external_memory");
	if (!isCoreDeviceExtension(apiVersion, "VK_KHR_dedicated_allocation"))
		extensions.push_back("VK_KHR_dedicated_allocation");
	if (!isCoreDeviceExtension(apiVersion, "VK_KHR_get_memory_requirements2"))
		extensions.push_back("VK_KHR_get_memory_requirements2");

	extensions.push_back("VK_KHR_external_memory_win32");
	extensions.push_back("VK_KHR_win32_keyed_mutex");

	try
	{
		std::vector<vk::VkDeviceQueueCreateInfo>	queues;

		for (size_t ndx = 0; ndx < queueFamilyProperties.size(); ndx++)
		{
			const vk::VkDeviceQueueCreateInfo	createInfo	=
			{
				vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
				DE_NULL,
				0u,

				(deUint32)ndx,
				1u,
				&priority
			};

			queues.push_back(createInfo);
		}

		const vk::VkDeviceCreateInfo		createInfo			=
		{
			vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
			DE_NULL,
			0u,

			(deUint32)queues.size(),
			&queues[0],

			0u,
			DE_NULL,

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

		return createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &createInfo);
	}
	catch (const vk::Error& error)
	{
		if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
			TCU_THROW(NotSupportedError, "Required extensions not supported");
		else
			throw;
	}
}

deUint32 chooseMemoryType (deUint32 bits)
{
	DE_ASSERT(bits != 0);

	for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
	{
		if ((bits & (1u << memoryTypeIndex)) != 0)
			return memoryTypeIndex;
	}

	DE_FATAL("No supported memory types");
	return -1;
}

bool isOpaqueHandleType (const vk::VkExternalMemoryHandleTypeFlagBits handleType)
{
	switch (handleType)
	{
	case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
	case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:
	case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
		return true;
	case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT:
	case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT:
	case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT:
	case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT:
	case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
	case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT:
	case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:
		return false;
	default:
		TCU_THROW(InternalError, "Unknown handle type or multiple bits set");
	}
}

vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface&				vkd,
										   vk::VkDevice								device,
										   const vk::VkMemoryRequirements&			requirements,
										   vk::VkExternalMemoryHandleTypeFlagBits	externalType,
										   NativeHandle&							handle,
										   bool										requiresDedicated,
										   vk::VkBuffer								buffer,
										   vk::VkImage								image)
{
	const vk::VkMemoryDedicatedAllocateInfo	dedicatedInfo	=
	{
		vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
		DE_NULL,
		image,
		buffer,
	};
	const vk::VkImportMemoryWin32HandleInfoKHR	importInfo		=
	{
		vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
		(requiresDedicated) ? &dedicatedInfo : DE_NULL,
		externalType,
		handle.getWin32Handle(),
		(vk::pt::Win32LPCWSTR)NULL
	};

	deUint32 handleCompatibleMemoryTypeBits = ~0u;
	if(!isOpaqueHandleType(externalType))
	{
		vk::VkMemoryWin32HandlePropertiesKHR memoryWin32HandleProperties =
		{
			vk::VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR,
			DE_NULL,
			0u
		};
		VK_CHECK(vkd.getMemoryWin32HandlePropertiesKHR(device, externalType, handle.getWin32Handle(), &memoryWin32HandleProperties));
		handleCompatibleMemoryTypeBits &= memoryWin32HandleProperties.memoryTypeBits;
	}

	const vk::VkMemoryAllocateInfo				info			=
	{
		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
		&importInfo,
		requirements.size,
		chooseMemoryType(requirements.memoryTypeBits & handleCompatibleMemoryTypeBits)
	};

	vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));

	handle.disown();

	return memory;
}

de::MovePtr<vk::Allocation> importAndBindMemory (const vk::DeviceInterface&					vkd,
												 vk::VkDevice								device,
												 vk::VkBuffer								buffer,
												 NativeHandle&								nativeHandle,
												 vk::VkExternalMemoryHandleTypeFlagBits		externalType)
{
	const vk::VkBufferMemoryRequirementsInfo2	requirementsInfo		=
	{
		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, &requirementsInfo, &requirements);

	vk::Move<vk::VkDeviceMemory> memory = importMemory(vkd, device, requirements.memoryRequirements, externalType, nativeHandle, !!dedicatedRequirements.requiresDedicatedAllocation, buffer, DE_NULL);
	VK_CHECK(vkd.bindBufferMemory(device, buffer, *memory, 0u));

	return de::MovePtr<vk::Allocation>(new SimpleAllocation(vkd, device, memory.disown()));
}

de::MovePtr<vk::Allocation> importAndBindMemory (const vk::DeviceInterface&						vkd,
												 vk::VkDevice									device,
												 vk::VkImage									image,
												 NativeHandle&									nativeHandle,
												 vk::VkExternalMemoryHandleTypeFlagBits			externalType)
{
	const vk::VkImageMemoryRequirementsInfo2	requirementsInfo		=
	{
		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, &requirementsInfo, &requirements);

	vk::Move<vk::VkDeviceMemory> memory = importMemory(vkd, device, requirements.memoryRequirements, externalType, nativeHandle, !!dedicatedRequirements.requiresDedicatedAllocation, DE_NULL, image);
	VK_CHECK(vkd.bindImageMemory(device, image, *memory, 0u));

	return de::MovePtr<vk::Allocation>(new SimpleAllocation(vkd, device, memory.disown()));
}

de::MovePtr<Resource> importResource (const vk::DeviceInterface&				vkd,
									  vk::VkDevice								device,
									  const ResourceDescription&				resourceDesc,
									  const std::vector<deUint32>&				queueFamilyIndices,
									  const OperationSupport&					readOp,
									  const OperationSupport&					writeOp,
									  NativeHandle&								nativeHandle,
									  vk::VkExternalMemoryHandleTypeFlagBits	externalType)
{
	if (resourceDesc.type == RESOURCE_TYPE_IMAGE)
	{
		const vk::VkExtent3D								extent					=
		{
			(deUint32)resourceDesc.size.x(),
			de::max(1u, (deUint32)resourceDesc.size.y()),
			de::max(1u, (deUint32)resourceDesc.size.z())
		};
		const vk::VkImageSubresourceRange					subresourceRange		=
		{
			resourceDesc.imageAspect,
			0u,
			1u,
			0u,
			1u
		};
		const vk::VkImageSubresourceLayers					subresourceLayers		=
		{
			resourceDesc.imageAspect,
			0u,
			0u,
			1u
		};
		const vk::VkExternalMemoryImageCreateInfo			externalInfo			=
		{
			vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
			DE_NULL,
			(vk::VkExternalMemoryHandleTypeFlags)externalType
		};
		const vk::VkImageCreateInfo							createInfo				=
		{
			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
			&externalInfo,
			0u,

			resourceDesc.imageType,
			resourceDesc.imageFormat,
			extent,
			1u,
			1u,
			resourceDesc.imageSamples,
			vk::VK_IMAGE_TILING_OPTIMAL,
			readOp.getInResourceUsageFlags() | writeOp.getOutResourceUsageFlags(),
			vk::VK_SHARING_MODE_EXCLUSIVE,

			(deUint32)queueFamilyIndices.size(),
			&queueFamilyIndices[0],
			vk::VK_IMAGE_LAYOUT_UNDEFINED
		};

		vk::Move<vk::VkImage>								image					= vk::createImage(vkd, device, &createInfo);
		de::MovePtr<vk::Allocation>							allocation				= importAndBindMemory(vkd, device, *image, nativeHandle, externalType);

		return de::MovePtr<Resource>(new Resource(image, allocation, extent, resourceDesc.imageType, resourceDesc.imageFormat, subresourceRange, subresourceLayers));
	}
	else
	{
		const vk::VkDeviceSize								offset					= 0u;
		const vk::VkDeviceSize								size					= static_cast<vk::VkDeviceSize>(resourceDesc.size.x());
		const vk::VkBufferUsageFlags						usage					= readOp.getInResourceUsageFlags() | writeOp.getOutResourceUsageFlags();
		const vk::VkExternalMemoryBufferCreateInfo			externalInfo			=
		{
			vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
			DE_NULL,
			(vk::VkExternalMemoryHandleTypeFlags)externalType
		};
		const vk::VkBufferCreateInfo						createInfo				=
		{
			vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
			&externalInfo,
			0u,

			size,
			usage,
			vk::VK_SHARING_MODE_EXCLUSIVE,
			(deUint32)queueFamilyIndices.size(),
			&queueFamilyIndices[0]
		};
		vk::Move<vk::VkBuffer>								buffer					= vk::createBuffer(vkd, device, &createInfo);
		de::MovePtr<vk::Allocation>							allocation				= importAndBindMemory(vkd, device, *buffer, nativeHandle, externalType);

		return de::MovePtr<Resource>(new Resource(resourceDesc.type, buffer, allocation, offset, size));
	}
}

void recordWriteBarrier (const vk::DeviceInterface&	vkd,
						 vk::VkCommandBuffer		commandBuffer,
						 const Resource&			resource,
						 const SyncInfo&			writeSync,
						 deUint32					writeQueueFamilyIndex,
						 const SyncInfo&			readSync)
{
	const vk::VkPipelineStageFlags		srcStageMask		= static_cast<VkPipelineStageFlags>(writeSync.stageMask);
	const vk::VkAccessFlags				srcAccessMask		= static_cast<VkAccessFlags>(writeSync.accessMask);

	const vk::VkPipelineStageFlags		dstStageMask		= static_cast<VkPipelineStageFlags>(readSync.stageMask);
	const vk::VkAccessFlags				dstAccessMask		= static_cast<VkAccessFlags>(readSync.accessMask);

	const vk::VkDependencyFlags			dependencyFlags		= 0;

	if (resource.getType() == RESOURCE_TYPE_IMAGE)
	{
		const vk::VkImageMemoryBarrier	barrier				=
		{
			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
			DE_NULL,

			srcAccessMask,
			dstAccessMask,

			writeSync.imageLayout,
			readSync.imageLayout,

			writeQueueFamilyIndex,
			VK_QUEUE_FAMILY_EXTERNAL,

			resource.getImage().handle,
			resource.getImage().subresourceRange
		};

		vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, (const vk::VkImageMemoryBarrier*)&barrier);
	}
	else
	{
		const vk::VkBufferMemoryBarrier	barrier				=
		{
			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
			DE_NULL,

			srcAccessMask,
			dstAccessMask,

			writeQueueFamilyIndex,
			VK_QUEUE_FAMILY_EXTERNAL,

			resource.getBuffer().handle,
			0u,
			VK_WHOLE_SIZE
		};

		vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 1u, (const vk::VkBufferMemoryBarrier*)&barrier, 0u, (const vk::VkImageMemoryBarrier*)DE_NULL);
	}
}

void recordReadBarrier (const vk::DeviceInterface&	vkd,
						vk::VkCommandBuffer			commandBuffer,
						const Resource&				resource,
						const SyncInfo&				writeSync,
						const SyncInfo&				readSync,
						deUint32					readQueueFamilyIndex)
{
	const vk::VkPipelineStageFlags		srcStageMask		= static_cast<VkPipelineStageFlags>(readSync.stageMask);
	const vk::VkAccessFlags				srcAccessMask		= static_cast<VkAccessFlags>(readSync.accessMask);

	const vk::VkPipelineStageFlags		dstStageMask		= static_cast<VkPipelineStageFlags>(readSync.stageMask);
	const vk::VkAccessFlags				dstAccessMask		= static_cast<VkAccessFlags>(readSync.accessMask);

	const vk::VkDependencyFlags			dependencyFlags		= 0;

	if (resource.getType() == RESOURCE_TYPE_IMAGE)
	{
		const vk::VkImageMemoryBarrier	barrier				=
		{
			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
			DE_NULL,

			srcAccessMask,
			dstAccessMask,

			writeSync.imageLayout,
			readSync.imageLayout,

			VK_QUEUE_FAMILY_EXTERNAL,
			readQueueFamilyIndex,

			resource.getImage().handle,
			resource.getImage().subresourceRange
		};

		vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, (const vk::VkImageMemoryBarrier*)&barrier);
	}
	else
	{
		const vk::VkBufferMemoryBarrier	barrier				=
		{
			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
			DE_NULL,

			srcAccessMask,
			dstAccessMask,

			VK_QUEUE_FAMILY_EXTERNAL,
			readQueueFamilyIndex,

			resource.getBuffer().handle,
			0u,
			VK_WHOLE_SIZE
		};

		vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 1u, (const vk::VkBufferMemoryBarrier*)&barrier, 0u, (const vk::VkImageMemoryBarrier*)DE_NULL);
	}
}

std::vector<deUint32> getFamilyIndices (const std::vector<vk::VkQueueFamilyProperties>& properties)
{
	std::vector<deUint32> indices (properties.size(), 0);

	for (deUint32 ndx = 0; ndx < properties.size(); ndx++)
		indices[ndx] = ndx;

	return indices;
}

class DX11Operation
{
public:
	enum Buffer
	{
		BUFFER_VK_WRITE,
		BUFFER_VK_READ,
		BUFFER_COUNT,
	};

	enum KeyedMutex
	{
		KEYED_MUTEX_INIT		= 0,
		KEYED_MUTEX_VK_WRITE	= 1,
		KEYED_MUTEX_DX_COPY		= 2,
		KEYED_MUTEX_VK_VERIFY	= 3,
		KEYED_MUTEX_DONE		= 4,
	};

#if (DE_OS == DE_OS_WIN32)
	DX11Operation (const ResourceDescription&					resourceDesc,
				   vk::VkExternalMemoryHandleTypeFlagBits		memoryHandleType,
				   ID3D11Device*								pDevice,
				   ID3D11DeviceContext*							pContext,
				   LPD3DX11COMPILEFROMMEMORY					fnD3DX11CompileFromMemory,
				   pD3DCompile									fnD3DCompile)
		: m_resourceDesc				(resourceDesc)

		, m_pDevice						(pDevice)
		, m_pContext					(pContext)
		, m_fnD3DX11CompileFromMemory	(fnD3DX11CompileFromMemory)
		, m_fnD3DCompile				(fnD3DCompile)

		, m_pRenderTargetView			(0)
		, m_pVertexShader				(0)
		, m_pPixelShader				(0)
		, m_pVertexBuffer				(0)
		, m_pTextureRV					(0)
		, m_pSamplerLinear				(0)
		, m_numFrames					(0)
	{
		HRESULT	hr;

		if (memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT ||
			memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT)

			m_isMemNtHandle = true;
		else
			m_isMemNtHandle = false;

		m_securityAttributes.lpSecurityDescriptor = 0;

		for (UINT i = 0; i < BUFFER_COUNT; i++)
		{
			m_pTexture[i] = NULL;
			m_pBuffer[i] = NULL;
			m_keyedMutex[i] = NULL;
		}

		if (m_resourceDesc.type == RESOURCE_TYPE_BUFFER)
		{
			// SHARED_NTHANDLE is not supported with CreateBuffer().
			TCU_CHECK_INTERNAL(!m_isMemNtHandle);

			D3D11_BUFFER_DESC descBuf = { };
			descBuf.ByteWidth = (UINT)m_resourceDesc.size.x();
			descBuf.Usage = D3D11_USAGE_DEFAULT;
			descBuf.BindFlags = 0;
			descBuf.CPUAccessFlags = 0;
			descBuf.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
			descBuf.StructureByteStride = 0;

			for (UINT i = 0; i < BUFFER_COUNT; ++i)
			{
				hr = m_pDevice->CreateBuffer(&descBuf, NULL, &m_pBuffer[i]);
				if (FAILED(hr))
					TCU_FAIL("Failed to create a buffer");

				m_sharedMemHandle[i] = 0;

				IDXGIResource* tempResource = NULL;
				hr = m_pBuffer[i]->QueryInterface(__uuidof(IDXGIResource), (void**)&tempResource);
				if (FAILED(hr))
					TCU_FAIL("Query interface of IDXGIResource failed");
				hr = tempResource->GetSharedHandle(&m_sharedMemHandle[i]);
				tempResource->Release();
				if (FAILED(hr))
					TCU_FAIL("Failed to get DX shared handle");

				hr = m_pBuffer[i]->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&m_keyedMutex[i]);
				if (FAILED(hr))
					TCU_FAIL("Query interface of IDXGIKeyedMutex failed");

				// Take ownership of the lock.
				m_keyedMutex[i]->AcquireSync(KEYED_MUTEX_INIT, INFINITE);
			}

			// Release the buffer write lock for Vulkan to write into.
			m_keyedMutex[BUFFER_VK_WRITE]->ReleaseSync(KEYED_MUTEX_VK_WRITE);

			m_sharedMemSize = descBuf.ByteWidth;
			m_sharedMemOffset = 0;
		}
		else
		{
			DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);

			for (UINT i = 0; i < BUFFER_COUNT; ++i)
			{
				D3D11_TEXTURE2D_DESC descColor = { };
				descColor.Width = m_resourceDesc.size.x();
				descColor.Height = m_resourceDesc.size.y();
				descColor.MipLevels = 1;
				descColor.ArraySize = 1;
				descColor.Format = getDxgiFormat(m_resourceDesc.imageFormat);
				descColor.SampleDesc.Count = 1;
				descColor.SampleDesc.Quality = 0;
				descColor.Usage = D3D11_USAGE_DEFAULT;
				descColor.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
				descColor.CPUAccessFlags = 0;

				if (m_isMemNtHandle)
					descColor.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
				else
					descColor.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;

				hr = m_pDevice->CreateTexture2D(&descColor, NULL, &m_pTexture[i]);
				if (FAILED(hr))
					TCU_FAIL("Unable to create DX11 texture");

				m_sharedMemHandle[i] = 0;

				if (m_isMemNtHandle)
				{
					IDXGIResource1* tempResource1 = NULL;
					hr = m_pTexture[i]->QueryInterface(__uuidof(IDXGIResource1), (void**)&tempResource1);
					if (FAILED(hr))
						TCU_FAIL("Unable to query IDXGIResource1 interface");

					hr = tempResource1->CreateSharedHandle(getSecurityAttributes(), DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, /*lpName*/NULL, &m_sharedMemHandle[i]);
					tempResource1->Release();
					if (FAILED(hr))
						TCU_FAIL("Enable to get DX shared handle");
				}
				else
				{
					IDXGIResource* tempResource = NULL;
					hr = m_pTexture[i]->QueryInterface(__uuidof(IDXGIResource), (void**)&tempResource);
					if (FAILED(hr))
						TCU_FAIL("Query interface of IDXGIResource failed");
					hr = tempResource->GetSharedHandle(&m_sharedMemHandle[i]);
					tempResource->Release();
					if (FAILED(hr))
						TCU_FAIL("Failed to get DX shared handle");
				}

				hr = m_pTexture[i]->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&m_keyedMutex[i]);
				if (FAILED(hr))
					TCU_FAIL("Unable to query DX11 keyed mutex interface");

				// Take ownership of the lock.
				m_keyedMutex[i]->AcquireSync(KEYED_MUTEX_INIT, INFINITE);
			}

			m_sharedMemSize = 0;
			m_sharedMemOffset = 0;

			hr = m_pDevice->CreateRenderTargetView(m_pTexture[BUFFER_VK_READ], NULL, &m_pRenderTargetView);
			if (FAILED(hr))
				TCU_FAIL("Unable to create DX11 render target view");

			m_pContext->OMSetRenderTargets(1, &m_pRenderTargetView, NULL);

			// Setup the viewport
			D3D11_VIEWPORT vp;
			vp.Width = (FLOAT)m_resourceDesc.size.x();
			vp.Height = (FLOAT)m_resourceDesc.size.y();
			vp.MinDepth = 0.0f;
			vp.MaxDepth = 1.0f;
			vp.TopLeftX = 0;
			vp.TopLeftY = 0;
			m_pContext->RSSetViewports(1, &vp);

			// Compile the vertex shader
			LPCSTR shader =
				"Texture2D txDiffuse : register(t0);\n"
				"SamplerState samLinear : register(s0);\n"
				"struct VS_INPUT\n"
				"{\n"
				"    float4 Pos : POSITION;\n"
				"    float2 Tex : TEXCOORD0;\n"
				"};\n"
				"struct PS_INPUT\n"
				"{\n"
				"    float4 Pos : SV_POSITION;\n"
				"    float2 Tex : TEXCOORD0;\n"
				"};\n"
				"PS_INPUT VS(VS_INPUT input)\n"
				"{\n"
				"    PS_INPUT output = (PS_INPUT)0;\n"
				"    output.Pos = input.Pos;\n"
				"    output.Tex = input.Tex;\n"
				"\n"
				"    return output;\n"
				"}\n"
				"float4 PS(PS_INPUT input) : SV_Target\n"
				"{\n"
				"    return txDiffuse.Sample(samLinear, input.Tex);\n"
				"}\n";

			// Define the input layout
			D3D11_INPUT_ELEMENT_DESC layout[] =
			{
				{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
				{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
			};

			createShaders(shader, "VS", "vs_4_0", ARRAYSIZE(layout), layout, &m_pVertexShader, "PS", "ps_4_0", &m_pPixelShader);

			struct SimpleVertex
			{
				float Pos[3];
				float Tex[2];
			};

			SimpleVertex vertices[] =
			{
				{ { -1.f, -1.f, 0.0f }, { 0.0f, 1.0f } },
				{ { -1.f,  1.f, 0.0f }, { 0.0f, 0.0f } },
				{ {  1.f, -1.f, 0.0f }, { 1.0f, 1.0f } },
				{ {  1.f,  1.f, 0.0f }, { 1.0f, 0.0f } },
			};

			D3D11_BUFFER_DESC bd = { };
			bd.Usage = D3D11_USAGE_DEFAULT;
			bd.ByteWidth = sizeof (vertices);
			bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
			bd.CPUAccessFlags = 0;
			D3D11_SUBRESOURCE_DATA InitData = { };
			InitData.pSysMem = vertices;
			hr = m_pDevice->CreateBuffer(&bd, &InitData, &m_pVertexBuffer);
			if (FAILED(hr))
				TCU_FAIL("Failed to create DX11 vertex buffer");

			// Set vertex buffer
			UINT stride = sizeof (SimpleVertex);
			UINT offset = 0;
			m_pContext->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset);

			// Set primitive topology
			m_pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);

			m_pTextureRV = NULL;

			D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = { };
			SRVDesc.Format = getDxgiFormat(m_resourceDesc.imageFormat);
			SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
			SRVDesc.Texture2D.MipLevels = 1;

			hr = m_pDevice->CreateShaderResourceView(m_pTexture[BUFFER_VK_WRITE], &SRVDesc, &m_pTextureRV);
			if (FAILED(hr))
				TCU_FAIL("Failed to create DX11 resource view");

			// Create the sample state
			D3D11_SAMPLER_DESC sampDesc = { };
			sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
			sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
			sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
			sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
			sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
			sampDesc.MinLOD = 0;
			sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
			hr = m_pDevice->CreateSamplerState(&sampDesc, &m_pSamplerLinear);
			if (FAILED(hr))
				TCU_FAIL("Failed to create DX11 sampler state");

			// Release the lock for VK to write into the texture.
			m_keyedMutex[BUFFER_VK_WRITE]->ReleaseSync(KEYED_MUTEX_VK_WRITE);
		}
	}

	~DX11Operation ()
	{
		cleanup();
	}
#endif // #if (DE_OS == DE_OS_WIN32)

	NativeHandle getNativeHandle (Buffer buffer)
	{
#if (DE_OS == DE_OS_WIN32)
		return NativeHandle((m_isMemNtHandle) ? NativeHandle::WIN32HANDLETYPE_NT : NativeHandle::WIN32HANDLETYPE_KMT, vk::pt::Win32Handle(m_sharedMemHandle[buffer]));
#else
		DE_UNREF(buffer);
		return NativeHandle();
#endif
	}

	void copyMemory ()
	{
#if (DE_OS == DE_OS_WIN32)
		m_keyedMutex[BUFFER_VK_WRITE]->AcquireSync(KEYED_MUTEX_DX_COPY, INFINITE);

		if (m_resourceDesc.type == RESOURCE_TYPE_BUFFER) {
			m_pContext->CopySubresourceRegion(m_pBuffer[BUFFER_VK_READ], 0, 0, 0, 0, m_pBuffer[BUFFER_VK_WRITE], 0, NULL);
		} else {
			m_pContext->OMSetRenderTargets(1, &m_pRenderTargetView, NULL);

			const FLOAT gray[] = { 0.f, 0.f, 1.f, 1.f };
			m_pContext->ClearRenderTargetView(m_pRenderTargetView, gray);

			m_pContext->VSSetShader(m_pVertexShader, NULL, 0);
			m_pContext->PSSetShader(m_pPixelShader, NULL, 0);
			m_pContext->PSSetShaderResources(0, 1, &m_pTextureRV);
			m_pContext->PSSetSamplers(0, 1, &m_pSamplerLinear);
			m_pContext->Draw(4, 0);
		}

		m_keyedMutex[BUFFER_VK_WRITE]->ReleaseSync(KEYED_MUTEX_DONE);
		m_keyedMutex[BUFFER_VK_READ]->ReleaseSync(KEYED_MUTEX_VK_VERIFY);
#endif // #if (DE_OS == DE_OS_WIN32)
	}

#if (DE_OS == DE_OS_WIN32)
	void d3dx11CompileShader (const char* shaderCode, const char * entryPoint, const char* shaderModel, ID3D10Blob** ppBlobOut)
	{
		HRESULT hr;

		ID3D10Blob* pErrorBlob;
		hr = m_fnD3DX11CompileFromMemory (shaderCode,
										  strlen(shaderCode),
										  "Memory",
										  NULL,
										  NULL,
										  entryPoint,
										  shaderModel,
										  0,
										  0,
										  NULL,
										  ppBlobOut,
										  &pErrorBlob,
										  NULL);
		if (pErrorBlob)
			pErrorBlob->Release();

		if (FAILED(hr))
			TCU_FAIL("D3DX11CompileFromMemory failed to compile shader");
	}

	void d3dCompileShader (const char* shaderCode, const char * entryPoint, const char* shaderModel, ID3DBlob** ppBlobOut)
	{
		HRESULT hr;

		ID3DBlob* pErrorBlob;
		hr = m_fnD3DCompile (shaderCode,
							 strlen(shaderCode),
							 NULL,
							 NULL,
							 NULL,
							 entryPoint,
							 shaderModel,
							 0,
							 0,
							 ppBlobOut,
							 &pErrorBlob);
		if (pErrorBlob)
			pErrorBlob->Release();

		if (FAILED(hr))
			TCU_FAIL("D3DCompile failed to compile shader");
	}

	void createShaders (const char* shaderSrc,
						const char* vsEntryPoint,
						const char* vsShaderModel,
						UINT numLayoutDesc,
						D3D11_INPUT_ELEMENT_DESC* pLayoutDesc,
						ID3D11VertexShader** pVertexShader,
						const char* psEntryPoint,
						const char* psShaderModel,
						ID3D11PixelShader** pPixelShader)
{
		HRESULT	hr;

		if (m_fnD3DX11CompileFromMemory) {
			// VS
			ID3D10Blob* pVSBlob;
			d3dx11CompileShader(shaderSrc, vsEntryPoint, vsShaderModel, &pVSBlob);

			hr = m_pDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, pVertexShader);
			if (FAILED(hr))
				TCU_FAIL("Failed to create DX11 vertex shader");

			ID3D11InputLayout *pVertexLayout;
			hr = m_pDevice->CreateInputLayout(pLayoutDesc, numLayoutDesc, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &pVertexLayout);
			if (FAILED(hr))
				TCU_FAIL("Failed to create vertex input layout");

			m_pContext->IASetInputLayout(pVertexLayout);
			pVertexLayout->Release();
			pVSBlob->Release();

			// PS
			ID3D10Blob* pPSBlob;
			d3dx11CompileShader(shaderSrc, psEntryPoint, psShaderModel, &pPSBlob);

			hr = m_pDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, pPixelShader);
			if (FAILED(hr))
				TCU_FAIL("Failed to create DX11 pixel shader");
		} else {
			// VS
			ID3DBlob* pVSBlob;
			d3dCompileShader(shaderSrc, vsEntryPoint, vsShaderModel, &pVSBlob);

			hr = m_pDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, pVertexShader);
			if (FAILED(hr))
				TCU_FAIL("Failed to create DX11 vertex shader");

			ID3D11InputLayout *pVertexLayout;
			hr = m_pDevice->CreateInputLayout(pLayoutDesc, numLayoutDesc, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &pVertexLayout);
			if (FAILED(hr))
				TCU_FAIL("Failed to create vertex input layout");

			m_pContext->IASetInputLayout(pVertexLayout);
			pVertexLayout->Release();
			pVSBlob->Release();

			// PS
			ID3DBlob* pPSBlob;
			d3dCompileShader(shaderSrc, psEntryPoint, psShaderModel, &pPSBlob);

			hr = m_pDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, pPixelShader);
			if (FAILED(hr))
				TCU_FAIL("Failed to create DX11 pixel shader");
		}
	}
#endif // #if (DE_OS == DE_OS_WIN32)

private:
#if (DE_OS == DE_OS_WIN32)
	void cleanup ()
	{
		if (m_securityAttributes.lpSecurityDescriptor)
		{
			freeSecurityDescriptor(m_securityAttributes.lpSecurityDescriptor);
			m_securityAttributes.lpSecurityDescriptor = NULL;
		}

		if (m_pContext)
			m_pContext->ClearState();

		if (m_pRenderTargetView)
		{
			m_pRenderTargetView->Release();
			m_pRenderTargetView = NULL;
		}

		if (m_pSamplerLinear)
		{
			m_pSamplerLinear->Release();
			m_pSamplerLinear = NULL;
		}

		if (m_pTextureRV)
		{
			m_pTextureRV->Release();
			m_pTextureRV = NULL;
		}

		if (m_pVertexBuffer)
		{
			m_pVertexBuffer->Release();
			m_pVertexBuffer = NULL;
		}

		if (m_pVertexShader)
		{
			m_pVertexShader->Release();
			m_pVertexShader = NULL;
		}

		if (m_pPixelShader)
		{
			m_pPixelShader->Release();
			m_pPixelShader = NULL;
		}

		for (int i = 0; i < BUFFER_COUNT; i++)
		{
			if (m_keyedMutex[i])
			{
				m_keyedMutex[i]->AcquireSync(KEYED_MUTEX_DONE, INFINITE);
				m_keyedMutex[i]->Release();
				m_keyedMutex[i] = NULL;
			}

			if (m_isMemNtHandle && m_sharedMemHandle[i]) {
				CloseHandle(m_sharedMemHandle[i]);
				m_sharedMemHandle[i] = 0;
			}

			if (m_pBuffer[i]) {
				m_pBuffer[i]->Release();
				m_pBuffer[i] = NULL;
			}

			if (m_pTexture[i]) {
				m_pTexture[i]->Release();
				m_pTexture[i] = NULL;
			}
		}
	}

	static void* getSecurityDescriptor ()
	{
		PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR)deCalloc(SECURITY_DESCRIPTOR_MIN_LENGTH + 2 * sizeof (void**));

		if (pSD)
		{
			PSID*	ppEveryoneSID	= (PSID*)((PBYTE)pSD + SECURITY_DESCRIPTOR_MIN_LENGTH);
			PACL*	ppACL			= (PACL*)((PBYTE)ppEveryoneSID + sizeof(PSID*));

			bool res = InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
			DE_ASSERT(res);

			SID_IDENTIFIER_AUTHORITY	SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
			AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, ppEveryoneSID);

			EXPLICIT_ACCESS	ea = { };
			ea.grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
			ea.grfAccessMode = SET_ACCESS;
			ea.grfInheritance = INHERIT_ONLY;
			ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
			ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
			ea.Trustee.ptstrName = (LPTSTR)*ppEveryoneSID;

			SetEntriesInAcl(1, &ea, NULL, ppACL);

			res = SetSecurityDescriptorDacl(pSD, TRUE, *ppACL, FALSE);
			DE_ASSERT(res);
		}

		return pSD;
	}

	static void freeSecurityDescriptor (void* pSD)
	{
		if (pSD)
		{
			PSID*	ppEveryoneSID	= (PSID*)((PBYTE)pSD + SECURITY_DESCRIPTOR_MIN_LENGTH);
			PACL*	ppACL			= (PACL*)((PBYTE)ppEveryoneSID + sizeof(PSID*));

			if (*ppEveryoneSID)
				FreeSid(*ppEveryoneSID);

			if (*ppACL)
				LocalFree(*ppACL);

			deFree(pSD);
		}
	}

	static DXGI_FORMAT getDxgiFormat (vk::VkFormat format)
	{
		switch (format)
		{
			case vk::VK_FORMAT_R8_UNORM:
				return DXGI_FORMAT_R8_UNORM;
			case vk::VK_FORMAT_R16_UINT:
				return DXGI_FORMAT_R16_UINT;
			case vk::VK_FORMAT_R8G8B8A8_UNORM:
				return DXGI_FORMAT_R8G8B8A8_UNORM;
			case vk::VK_FORMAT_R16G16B16A16_UINT:
				return DXGI_FORMAT_R16G16B16A16_UINT;
			case vk::VK_FORMAT_R32G32B32A32_SFLOAT:
				return DXGI_FORMAT_R32G32B32A32_FLOAT;
			case vk::VK_FORMAT_D16_UNORM:
				return DXGI_FORMAT_D16_UNORM;
			case vk::VK_FORMAT_D32_SFLOAT:
				return DXGI_FORMAT_D32_FLOAT;
			default:
				TCU_CHECK_INTERNAL(!"Unsupported DXGI format");
				return DXGI_FORMAT_UNKNOWN;
		}
	}

	ResourceDescription			m_resourceDesc;

	deUint64					m_sharedMemSize;
	deUint64					m_sharedMemOffset;
	HANDLE						m_sharedMemHandle[BUFFER_COUNT];
	bool						m_isMemNtHandle;

	ID3D11Device*				m_pDevice;
	ID3D11DeviceContext*		m_pContext;
	LPD3DX11COMPILEFROMMEMORY	m_fnD3DX11CompileFromMemory;
	pD3DCompile					m_fnD3DCompile;

	ID3D11RenderTargetView*		m_pRenderTargetView;
	ID3D11VertexShader*			m_pVertexShader;
	ID3D11PixelShader*			m_pPixelShader;
	ID3D11Buffer*				m_pVertexBuffer;
	ID3D11ShaderResourceView*	m_pTextureRV;
	ID3D11SamplerState*			m_pSamplerLinear;

	ID3D11Texture2D*			m_pTexture[BUFFER_COUNT];
	ID3D11Buffer*				m_pBuffer[BUFFER_COUNT];
	IDXGIKeyedMutex*			m_keyedMutex[BUFFER_COUNT];
	UINT						m_numFrames;
	SECURITY_ATTRIBUTES			m_securityAttributes;

	SECURITY_ATTRIBUTES* getSecurityAttributes ()
	{
		m_securityAttributes.nLength = sizeof (SECURITY_ATTRIBUTES);
		m_securityAttributes.bInheritHandle = TRUE;
		if (!m_securityAttributes.lpSecurityDescriptor)
			m_securityAttributes.lpSecurityDescriptor = getSecurityDescriptor();

		return &m_securityAttributes;
	}
#endif // #if (DE_OS == DE_OS_WIN32)
};

class DX11OperationSupport
{
public:
	DX11OperationSupport (const vk::InstanceInterface&	vki,
						  vk::VkPhysicalDevice			physicalDevice)
#if (DE_OS == DE_OS_WIN32)
		: m_hD3D11Lib					(0)
		, m_hD3DX11Lib					(0)
		, m_hD3DCompilerLib				(0)
		, m_hDxgiLib					(0)
		, m_fnD3D11CreateDevice			(0)
		, m_fnD3DX11CompileFromMemory	(0)
		, m_fnD3DCompile				(0)
#endif
	{
#if (DE_OS == DE_OS_WIN32)
		HRESULT										hr;

		vk::VkPhysicalDeviceIDProperties		propertiesId = { vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES };
		vk::VkPhysicalDeviceProperties2			properties = { vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 };

		properties.pNext = &propertiesId;

		vki.getPhysicalDeviceProperties2(physicalDevice, &properties);
		if (!propertiesId.deviceLUIDValid)
			TCU_FAIL("Physical device deviceLUIDValid is not valid");


		m_hD3D11Lib = LoadLibrary("d3d11.dll");
		if (!m_hD3D11Lib)
			TCU_FAIL("Failed to load d3d11.dll");


		m_fnD3D11CreateDevice = (LPD3D11CREATEDEVICE) GetProcAddress(m_hD3D11Lib, "D3D11CreateDevice");
		if (!m_fnD3D11CreateDevice)
			TCU_FAIL("Unable to find D3D11CreateDevice() function");

		m_hD3DX11Lib = LoadLibrary("d3dx11_42.dll");
		if (m_hD3DX11Lib)
			m_fnD3DX11CompileFromMemory =  (LPD3DX11COMPILEFROMMEMORY) GetProcAddress(m_hD3DX11Lib, "D3DX11CompileFromMemory");
		else
		{
			m_hD3DCompilerLib = LoadLibrary("d3dcompiler_43.dll");
			if (!m_hD3DCompilerLib)
				m_hD3DCompilerLib = LoadLibrary("d3dcompiler_47.dll");
			if (!m_hD3DCompilerLib)
				TCU_FAIL("Unable to load DX11 d3dcompiler_43.dll or d3dcompiler_47.dll");

			m_fnD3DCompile = (pD3DCompile)GetProcAddress(m_hD3DCompilerLib, "D3DCompile");
			if (!m_fnD3DCompile)
				TCU_FAIL("Unable to load find D3DCompile");
		}

		m_hDxgiLib = LoadLibrary("dxgi.dll");
		if (!m_hDxgiLib)
			TCU_FAIL("Unable to load DX11 dxgi.dll");

		typedef HRESULT (WINAPI *LPCREATEDXGIFACTORY1)(REFIID riid, void** ppFactory);
		LPCREATEDXGIFACTORY1 CreateDXGIFactory1 = (LPCREATEDXGIFACTORY1)GetProcAddress(m_hDxgiLib, "CreateDXGIFactory1");
		if (!CreateDXGIFactory1)
			TCU_FAIL("Unable to load find CreateDXGIFactory1");

		IDXGIFactory1* pFactory = NULL;
		hr = CreateDXGIFactory1(__uuidof(IDXGIFactory), (void**)&pFactory);
		if (FAILED(hr))
			TCU_FAIL("Unable to create IDXGIFactory interface");

		IDXGIAdapter *pAdapter = NULL;
		for (UINT i = 0; pFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++i)
		{
			DXGI_ADAPTER_DESC desc;
			pAdapter->GetDesc(&desc);

			if (deMemCmp(&desc.AdapterLuid, propertiesId.deviceLUID, VK_LUID_SIZE_KHR) == 0)
				break;
		}
		pFactory->Release();

		D3D_FEATURE_LEVEL fLevel[] = {D3D_FEATURE_LEVEL_11_0};
		UINT devflags = D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS | // no separate D3D11 worker thread
#if 0
						D3D11_CREATE_DEVICE_DEBUG | // useful for diagnosing DX failures
#endif
						D3D11_CREATE_DEVICE_SINGLETHREADED;

		hr = m_fnD3D11CreateDevice (pAdapter,
									pAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE,
									NULL,
									devflags,
									fLevel,
									DE_LENGTH_OF_ARRAY(fLevel),
									D3D11_SDK_VERSION,
									&m_pDevice,
									NULL,
									&m_pContext);

		if (pAdapter) {
			pAdapter->Release();
		}

		if (!m_pDevice)
			TCU_FAIL("Failed to created DX11 device");
		if (!m_pContext)
			TCU_FAIL("Failed to created DX11 context");
#else
		DE_UNREF(vki);
		DE_UNREF(physicalDevice);
		TCU_THROW(NotSupportedError, "OS not supported");
#endif
	}

	~DX11OperationSupport ()
	{
#if (DE_OS == DE_OS_WIN32)
		cleanup ();
#endif
	}

#if (DE_OS == DE_OS_WIN32)
	void cleanup ()
	{
		if (m_pContext) {
			m_pContext->Release();
			m_pContext = 0;
		}

		if (m_pDevice) {
			m_pDevice->Release();
			m_pDevice = 0;
		}

		if (m_hDxgiLib)
		{
			FreeLibrary(m_hDxgiLib);
			m_hDxgiLib = 0;
		}

		if (m_hD3DCompilerLib)
		{
			FreeLibrary(m_hD3DCompilerLib);
			m_hD3DCompilerLib = 0;
		}

		if (m_hD3DX11Lib)
		{
			FreeLibrary(m_hD3DX11Lib);
			m_hD3DX11Lib = 0;
		}

		if (m_hD3D11Lib)
		{
			FreeLibrary(m_hD3D11Lib);
			m_hD3D11Lib = 0;
		}
	}

#endif

	virtual de::MovePtr<DX11Operation> build (const ResourceDescription& resourceDesc, vk::VkExternalMemoryHandleTypeFlagBits memoryHandleType) const
	{
#if (DE_OS == DE_OS_WIN32)
		return de::MovePtr<DX11Operation>(new DX11Operation(resourceDesc, memoryHandleType, m_pDevice, m_pContext, m_fnD3DX11CompileFromMemory, m_fnD3DCompile));
#else
		DE_UNREF(resourceDesc);
		DE_UNREF(memoryHandleType);
		TCU_THROW(NotSupportedError, "OS not supported");
#endif
	}

private:

#if (DE_OS == DE_OS_WIN32)
	typedef HRESULT				(WINAPI *LPD3D11CREATEDEVICE)(IDXGIAdapter*,
															  D3D_DRIVER_TYPE,
															  HMODULE,
															  UINT,
															  const D3D_FEATURE_LEVEL*,
															  UINT,
															  UINT,
															  ID3D11Device **,
															  D3D_FEATURE_LEVEL*,
															  ID3D11DeviceContext**);

	HMODULE						m_hD3D11Lib;
	HMODULE						m_hD3DX11Lib;
	HMODULE						m_hD3DCompilerLib;
	HMODULE						m_hDxgiLib;
	LPD3D11CREATEDEVICE			m_fnD3D11CreateDevice;
	LPD3DX11COMPILEFROMMEMORY	m_fnD3DX11CompileFromMemory;
	pD3DCompile					m_fnD3DCompile;
	ID3D11Device*				m_pDevice;
	ID3D11DeviceContext*		m_pContext;
#endif
};

// Class to wrap a singleton instance and device
class InstanceAndDevice
{
	InstanceAndDevice	(Context& context)
		: m_instance		(createTestInstance(context))
		, m_vki				(m_instance.getDriver())
		, m_physicalDevice	(vk::chooseDevice(m_vki, m_instance, context.getTestContext().getCommandLine()))
		, m_logicalDevice	(createTestDevice(context, m_instance, m_vki, m_physicalDevice))
		, m_supportDX11		(new DX11OperationSupport(m_vki, m_physicalDevice))
	{
	}

public:

	static vk::VkInstance getInstance(Context& context)
	{
		if (!m_instanceAndDevice)
			m_instanceAndDevice = SharedPtr<InstanceAndDevice>(new InstanceAndDevice(context));

		return m_instanceAndDevice->m_instance;
	}
	static const vk::InstanceDriver& getDriver()
	{
		DE_ASSERT(m_instanceAndDevice);
		return m_instanceAndDevice->m_instance.getDriver();
	}
	static vk::VkPhysicalDevice getPhysicalDevice()
	{
		DE_ASSERT(m_instanceAndDevice);
		return m_instanceAndDevice->m_physicalDevice;
	}
	static const Unique<vk::VkDevice>& getDevice()
	{
		DE_ASSERT(m_instanceAndDevice);
		return m_instanceAndDevice->m_logicalDevice;
	}
	static const de::UniquePtr<DX11OperationSupport>& getSupportDX11()
	{
		DE_ASSERT(m_instanceAndDevice);
		return m_instanceAndDevice->m_supportDX11;
	}
	static void collectMessages()
	{
		DE_ASSERT(m_instanceAndDevice);
		m_instanceAndDevice->m_instance.collectMessages();
	}

	static void destroy()
	{
		m_instanceAndDevice.clear();
	}

private:
	CustomInstance								m_instance;
	const vk::InstanceDriver&					m_vki;
	const vk::VkPhysicalDevice					m_physicalDevice;
	const Unique<vk::VkDevice>					m_logicalDevice;
	const de::UniquePtr<DX11OperationSupport>	m_supportDX11;

	static SharedPtr<InstanceAndDevice>	m_instanceAndDevice;
};
SharedPtr<InstanceAndDevice>		InstanceAndDevice::m_instanceAndDevice;


class Win32KeyedMutexTestInstance : public TestInstance
{
public:
														Win32KeyedMutexTestInstance	(Context&	context,
																					 TestConfig	config);

	virtual tcu::TestStatus								iterate					(void);

private:
	const TestConfig									m_config;
	const de::UniquePtr<OperationSupport>				m_supportWriteOp;
	const de::UniquePtr<OperationSupport>				m_supportReadOp;

	const vk::VkInstance								m_instance;

	const vk::InstanceDriver&							m_vki;
	const vk::VkPhysicalDevice							m_physicalDevice;
	const std::vector<vk::VkQueueFamilyProperties>		m_queueFamilies;
	const std::vector<deUint32>							m_queueFamilyIndices;
	const vk::Unique<vk::VkDevice>&						m_device;
	const vk::DeviceDriver								m_vkd;

	const vk::VkExternalMemoryHandleTypeFlagBits		m_memoryHandleType;

	// \todo Should this be moved to the group same way as in the other tests?
	PipelineCacheData									m_pipelineCacheData;
	tcu::ResultCollector								m_resultCollector;
	size_t												m_queueNdx;

	bool												m_useDedicatedAllocation;
};

Win32KeyedMutexTestInstance::Win32KeyedMutexTestInstance	(Context&		context,
															 TestConfig		config)
	: TestInstance				(context)
	, m_config					(config)
	, m_supportWriteOp			(makeOperationSupport(config.writeOp, config.resource))
	, m_supportReadOp			(makeOperationSupport(config.readOp, config.resource))

	, m_instance				(InstanceAndDevice::getInstance(context))

	, m_vki						(InstanceAndDevice::getDriver())
	, m_physicalDevice			(InstanceAndDevice::getPhysicalDevice())
	, m_queueFamilies			(vk::getPhysicalDeviceQueueFamilyProperties(m_vki, m_physicalDevice))
	, m_queueFamilyIndices		(getFamilyIndices(m_queueFamilies))
	, m_device					(InstanceAndDevice::getDevice())
	, m_vkd						(context.getPlatformInterface(), m_instance, *m_device)

	, m_memoryHandleType		((m_config.resource.type == RESOURCE_TYPE_IMAGE) ? m_config.memoryHandleTypeImage : m_config.memoryHandleTypeBuffer)

	, m_resultCollector			(context.getTestContext().getLog())
	, m_queueNdx				(0)

	, m_useDedicatedAllocation	(false)
{
#if (DE_OS == DE_OS_WIN32)
	TestLog& log = m_context.getTestContext().getLog();

	// Check resource support
	if (m_config.resource.type == RESOURCE_TYPE_IMAGE)
	{
		if (m_memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT && !IsWindows8OrGreater())
			TCU_THROW(NotSupportedError, "Memory handle type not supported by this OS");

		const vk::VkPhysicalDeviceExternalImageFormatInfo	externalInfo		=
		{
			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
			DE_NULL,
			m_memoryHandleType
		};
		const vk::VkPhysicalDeviceImageFormatInfo2			imageFormatInfo		=
		{
			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
			&externalInfo,
			m_config.resource.imageFormat,
			m_config.resource.imageType,
			vk::VK_IMAGE_TILING_OPTIMAL,
			m_supportReadOp->getInResourceUsageFlags() | m_supportWriteOp->getOutResourceUsageFlags(),
			0u
		};
		vk::VkExternalImageFormatProperties					externalProperties	=
		{
			vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
			DE_NULL,
			{ 0u, 0u, 0u }
		};
		vk::VkImageFormatProperties2						formatProperties	=
		{
			vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
			&externalProperties,
			{
				{ 0u, 0u, 0u },
				0u,
				0u,
				0u,
				0u,
			}
		};
		const vk::VkResult res = m_vki.getPhysicalDeviceImageFormatProperties2(m_physicalDevice, &imageFormatInfo, &formatProperties);
		if (res == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
			TCU_THROW(NotSupportedError, "Handle type is not compatible");
		VK_CHECK(res);

		// \todo How to log this nicely?
		log << TestLog::Message << "External image format properties: " << imageFormatInfo << "\n"<< externalProperties << TestLog::EndMessage;

		if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0)
			TCU_THROW(NotSupportedError, "Importing image resource not supported");

		if (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT)
			m_useDedicatedAllocation = true;
	}
	else
	{
		if (m_memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT && !IsWindows8OrGreater())
			TCU_THROW(NotSupportedError, "Memory handle type not supported by this OS");

		const vk::VkPhysicalDeviceExternalBufferInfo		info	=
		{
			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
			DE_NULL,

			0u,
			m_supportReadOp->getInResourceUsageFlags() | m_supportWriteOp->getOutResourceUsageFlags(),
			m_memoryHandleType
		};
		vk::VkExternalBufferProperties						properties			=
		{
			vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
			DE_NULL,
			{ 0u, 0u, 0u}
		};
		m_vki.getPhysicalDeviceExternalBufferProperties(m_physicalDevice, &info, &properties);

		log << TestLog::Message << "External buffer properties: " << info << "\n" << properties << TestLog::EndMessage;

		if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0)
			TCU_THROW(NotSupportedError, "Importing memory type not supported");

		if (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT)
			m_useDedicatedAllocation = true;
	}
#else
	DE_UNREF(m_useDedicatedAllocation);
	TCU_THROW(NotSupportedError, "OS not supported");
#endif
}

tcu::TestStatus Win32KeyedMutexTestInstance::iterate (void)
{
	TestLog&									log					(m_context.getTestContext().getLog());

	try
	{
		const deUint32							queueFamily			= (deUint32)m_queueNdx;

		const tcu::ScopedLogSection				queuePairSection	(log, "Queue-" + de::toString(queueFamily), "Queue-" + de::toString(queueFamily));

		const vk::VkQueue						queue				(getDeviceQueue(m_vkd, *m_device, queueFamily, 0u));
		const vk::Unique<vk::VkCommandPool>		commandPool			(createCommandPool(m_vkd, *m_device, 0u, queueFamily));
		const vk::Unique<vk::VkCommandBuffer>	commandBufferWrite	(allocateCommandBuffer(m_vkd, *m_device, *commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
		const vk::Unique<vk::VkCommandBuffer>	commandBufferRead	(allocateCommandBuffer(m_vkd, *m_device, *commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
		vk::SimpleAllocator						allocator			(m_vkd, *m_device, vk::getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice));
		OperationContext						operationContext	(m_context, SynchronizationType::LEGACY, m_vki, m_vkd, m_physicalDevice, *m_device, allocator, m_context.getBinaryCollection(), m_pipelineCacheData);

		if (!checkQueueFlags(m_queueFamilies[m_queueNdx].queueFlags, vk::VK_QUEUE_GRAPHICS_BIT))
			TCU_THROW(NotSupportedError, "Operation not supported by the source queue");

		const de::UniquePtr<DX11Operation>		dx11Op				(InstanceAndDevice::getSupportDX11()->build(m_config.resource, m_memoryHandleType));

		NativeHandle nativeHandleWrite = dx11Op->getNativeHandle(DX11Operation::BUFFER_VK_WRITE);
		const de::UniquePtr<Resource>			resourceWrite		(importResource(m_vkd, *m_device, m_config.resource, m_queueFamilyIndices, *m_supportReadOp, *m_supportWriteOp, nativeHandleWrite, m_memoryHandleType));

		NativeHandle nativeHandleRead = dx11Op->getNativeHandle(DX11Operation::BUFFER_VK_READ);
		const de::UniquePtr<Resource>			resourceRead		(importResource(m_vkd, *m_device, m_config.resource, m_queueFamilyIndices, *m_supportReadOp, *m_supportWriteOp, nativeHandleRead, m_memoryHandleType));

		const de::UniquePtr<Operation>			writeOp				(m_supportWriteOp->build(operationContext, *resourceWrite));
		const de::UniquePtr<Operation>			readOp				(m_supportReadOp->build(operationContext, *resourceRead));

		const SyncInfo							writeSync			= writeOp->getOutSyncInfo();
		const SyncInfo							readSync			= readOp->getInSyncInfo();

		beginCommandBuffer(m_vkd, *commandBufferWrite);
		writeOp->recordCommands(*commandBufferWrite);
		recordWriteBarrier(m_vkd, *commandBufferWrite, *resourceWrite, writeSync, queueFamily, readSync);
		endCommandBuffer(m_vkd, *commandBufferWrite);

		beginCommandBuffer(m_vkd, *commandBufferRead);
		recordReadBarrier(m_vkd, *commandBufferRead, *resourceRead, writeSync, readSync, queueFamily);
		readOp->recordCommands(*commandBufferRead);
		endCommandBuffer(m_vkd, *commandBufferRead);

		{
			vk::VkDeviceMemory							memory			= resourceWrite->getMemory();
			deUint64									keyInit			= DX11Operation::KEYED_MUTEX_VK_WRITE;
			deUint32									timeout			= 0xFFFFFFFF; // INFINITE
			deUint64									keyExternal		= DX11Operation::KEYED_MUTEX_DX_COPY;
			vk::VkWin32KeyedMutexAcquireReleaseInfoKHR	keyedMutexInfo	=
			{
				vk::VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR,
				DE_NULL,

				1,
				&memory,
				&keyInit,
				&timeout,

				1,
				&memory,
				&keyExternal,
			};

			const vk::VkCommandBuffer	commandBuffer	= *commandBufferWrite;
			const vk::VkSubmitInfo		submitInfo			=
			{
				vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
				&keyedMutexInfo,

				0u,
				DE_NULL,
				DE_NULL,

				1u,
				&commandBuffer,
				0u,
				DE_NULL
			};

			VK_CHECK(m_vkd.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
		}

		dx11Op->copyMemory();

		{
			vk::VkDeviceMemory							memory			= resourceRead->getMemory();
			deUint64									keyInternal		= DX11Operation::KEYED_MUTEX_VK_VERIFY;
			deUint32									timeout			= 0xFFFFFFFF; // INFINITE
			deUint64									keyExternal		= DX11Operation::KEYED_MUTEX_DONE;
			vk::VkWin32KeyedMutexAcquireReleaseInfoKHR	keyedMutexInfo	=
			{
				vk::VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR,
				DE_NULL,

				1,
				&memory,
				&keyInternal,
				&timeout,

				1,
				&memory,
				&keyExternal,
			};

			const vk::VkCommandBuffer	commandBuffer	= *commandBufferRead;
			const vk::VkSubmitInfo		submitInfo			=
			{
				vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
				&keyedMutexInfo,

				0u,
				DE_NULL,
				DE_NULL,

				1u,
				&commandBuffer,
				0u,
				DE_NULL
			};

			VK_CHECK(m_vkd.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
		}

		VK_CHECK(m_vkd.queueWaitIdle(queue));

		{
			const Data	expected	= writeOp->getData();
			const Data	actual		= readOp->getData();

			DE_ASSERT(expected.size == actual.size);

			if (0 != deMemCmp(expected.data, actual.data, expected.size))
			{
				const size_t		maxBytesLogged	= 256;
				std::ostringstream	expectedData;
				std::ostringstream	actualData;
				size_t				byteNdx			= 0;

				// Find first byte difference
				for (; actual.data[byteNdx] == expected.data[byteNdx]; byteNdx++)
				{
					// Nothing
				}

				log << TestLog::Message << "First different byte at offset: " << byteNdx << TestLog::EndMessage;

				// Log 8 previous bytes before the first incorrect byte
				if (byteNdx > 8)
				{
					expectedData << "... ";
					actualData << "... ";

					byteNdx -= 8;
				}
				else
					byteNdx = 0;

				for (size_t i = 0; i < maxBytesLogged && byteNdx < expected.size; i++, byteNdx++)
				{
					expectedData << (i > 0 ? ", " : "") << (deUint32)expected.data[byteNdx];
					actualData << (i > 0 ? ", " : "") << (deUint32)actual.data[byteNdx];
				}

				if (expected.size > byteNdx)
				{
					expectedData << "...";
					actualData << "...";
				}

				log << TestLog::Message << "Expected data: (" << expectedData.str() << ")" << TestLog::EndMessage;
				log << TestLog::Message << "Actual data: (" << actualData.str() << ")" << TestLog::EndMessage;

				m_resultCollector.fail("Memory contents don't match");
			}
		}
	}
	catch (const tcu::NotSupportedError& error)
	{
		log << TestLog::Message << "Not supported: " << error.getMessage() << TestLog::EndMessage;
	}
	catch (const tcu::TestError& error)
	{
		m_resultCollector.fail(std::string("Exception: ") + error.getMessage());
	}

	// Collect possible validation errors.
	InstanceAndDevice::collectMessages();

	// Move to next queue
	{
		m_queueNdx++;

		if (m_queueNdx >= m_queueFamilies.size())
		{
			return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
		}
		else
		{
			return tcu::TestStatus::incomplete();
		}
	}
}

struct Progs
{
	void init (vk::SourceCollections& dst, TestConfig config) const
	{
		const de::UniquePtr<OperationSupport>	readOp	(makeOperationSupport(config.readOp, config.resource));
		const de::UniquePtr<OperationSupport>	writeOp	(makeOperationSupport(config.writeOp, config.resource));

		readOp->initPrograms(dst);
		writeOp->initPrograms(dst);
	}
};

} // anonymous

static void createTests (tcu::TestCaseGroup* group)
{
	tcu::TestContext& testCtx = group->getTestContext();
	const struct
	{
		vk::VkExternalMemoryHandleTypeFlagBits			memoryHandleTypeBuffer;
		vk::VkExternalMemoryHandleTypeFlagBits			memoryHandleTypeImage;
		const char*										nameSuffix;
	} cases[] =
	{
		{
			(vk::VkExternalMemoryHandleTypeFlagBits)0u,				// DX11 doesn't support buffers with an NT handle
			vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT,
			"_nt"
		},
		{
			vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
			vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT,
			"_kmt"
		},
	};

	for (size_t writeOpNdx = 0; writeOpNdx < DE_LENGTH_OF_ARRAY(s_writeOps); ++writeOpNdx)
	for (size_t readOpNdx = 0; readOpNdx < DE_LENGTH_OF_ARRAY(s_readOps); ++readOpNdx)
	{
		const OperationName	writeOp		= s_writeOps[writeOpNdx];
		const OperationName	readOp		= s_readOps[readOpNdx];
		const std::string	opGroupName	= getOperationName(writeOp) + "_" + getOperationName(readOp);
		bool				empty		= true;

		de::MovePtr<tcu::TestCaseGroup> opGroup	(new tcu::TestCaseGroup(testCtx, opGroupName.c_str(), ""));

		for (size_t resourceNdx = 0; resourceNdx < DE_LENGTH_OF_ARRAY(s_resourcesWin32KeyedMutex); ++resourceNdx)
		{
			const ResourceDescription&	resource	= s_resourcesWin32KeyedMutex[resourceNdx];

			for (size_t caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
			{
				if (resource.type == RESOURCE_TYPE_BUFFER && !cases[caseNdx].memoryHandleTypeBuffer)
					continue;

				if (resource.type == RESOURCE_TYPE_IMAGE && !cases[caseNdx].memoryHandleTypeImage)
					continue;

				std::string	name	= getResourceName(resource) + cases[caseNdx].nameSuffix;

				if (isResourceSupported(writeOp, resource) && isResourceSupported(readOp, resource))
				{
					const TestConfig config (resource, writeOp, readOp, cases[caseNdx].memoryHandleTypeBuffer, cases[caseNdx].memoryHandleTypeImage);

					opGroup->addChild(new InstanceFactory1<Win32KeyedMutexTestInstance, TestConfig, Progs>(testCtx, tcu::NODETYPE_SELF_VALIDATE,  name, "", Progs(), config));
					empty = false;
				}
			}
		}

		if (!empty)
			group->addChild(opGroup.release());
	}
}

static void cleanupGroup (tcu::TestCaseGroup* group)
{
	DE_UNREF(group);
	// Destroy singleton object
	InstanceAndDevice::destroy();
}

tcu::TestCaseGroup* createWin32KeyedMutexTest (tcu::TestContext& testCtx)
{
	return createTestGroup(testCtx, "win32_keyed_mutex", "", createTests, cleanupGroup);
}

} // synchronization
} // vkt
