/*------------------------------------------------------------------------
 * 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 "vktSynchronizationUtil.hpp"
#include "vktSynchronizationOperation.hpp"
#include "vktSynchronizationOperationTestData.hpp"
#include "vktExternalMemoryUtil.hpp"

#include "tcuResultCollector.hpp"
#include "tcuTestLog.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
{

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

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

vk::Move<vk::VkInstance> createInstance (const vk::PlatformInterface& vkp, deUint32 version)
{
	try
	{
		std::vector<std::string> extensions;
		if (!isCoreInstanceExtension(version, "VK_KHR_get_physical_device_properties2"))
			extensions.push_back("VK_KHR_get_physical_device_properties2");
		if (!isCoreInstanceExtension(version, "VK_KHR_get_physical_device_properties2"))
			extensions.push_back("VK_KHR_external_memory_capabilities");

		return vk::createDefaultInstance(vkp, version, std::vector<std::string>(), extensions);
	}
	catch (const vk::Error& error)
	{
		if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
			TCU_THROW(NotSupportedError, "Required external memory extensions not supported by the instance");
		else
			throw;
	}
}

vk::VkPhysicalDevice getPhysicalDevice (const vk::InstanceInterface&	vki,
										vk::VkInstance					instance,
										const tcu::CommandLine&			cmdLine)
{
	return vk::chooseDevice(vki, instance, cmdLine);
}

vk::Move<vk::VkDevice> createDevice (const deUint32									apiVersion,
									 const vk::PlatformInterface&					vkp,
									 vk::VkInstance									instance,
									 const vk::InstanceInterface&					vki,
									 vk::VkPhysicalDevice							physicalDevice)
{
	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 vk::createDevice(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(),
		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,
			vk::VK_SAMPLE_COUNT_1_BIT,
			vk::VK_IMAGE_TILING_OPTIMAL,
			readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags(),
			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.getResourceUsageFlags() | writeOp.getResourceUsageFlags();
		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		= writeSync.stageMask;
	const vk::VkAccessFlags				srcAccessMask		= writeSync.accessMask;

	const vk::VkPipelineStageFlags		dstStageMask		= readSync.stageMask;
	const vk::VkAccessFlags				dstAccessMask		= 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		= readSync.stageMask;
	const vk::VkAccessFlags				srcAccessMask		= readSync.accessMask;

	const vk::VkPipelineStageFlags		dstStageMask		= readSync.stageMask;
	const vk::VkAccessFlags				dstAccessMask		= 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*));

			InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);

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

			SetSecurityDescriptorDacl(pSD, TRUE, *ppACL, FALSE);
		}

		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,
						  const ResourceDescription&	resourceDesc)
		: m_resourceDesc			(resourceDesc)
#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:
	const ResourceDescription	m_resourceDesc;

#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 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::Unique<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 de::UniquePtr<DX11OperationSupport>			m_supportDX11;

	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				(createInstance(context.getPlatformInterface(), context.getUsedApiVersion()))

	, m_vki						(context.getPlatformInterface(), *m_instance)
	, m_physicalDevice			(getPhysicalDevice(m_vki, *m_instance, context.getTestContext().getCommandLine()))
	, m_queueFamilies			(vk::getPhysicalDeviceQueueFamilyProperties(m_vki, m_physicalDevice))
	, m_queueFamilyIndices		(getFamilyIndices(m_queueFamilies))
	, m_device					(createDevice(context.getUsedApiVersion(), context.getPlatformInterface(), *m_instance, m_vki, m_physicalDevice))
	, m_vkd						(context.getPlatformInterface(), *m_instance, *m_device)

	, m_supportDX11				(new DX11OperationSupport(m_vki, m_physicalDevice, config.resource))

	, 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->getResourceUsageFlags() | m_supportWriteOp->getResourceUsageFlags(),
			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->getResourceUsageFlags() | m_supportWriteOp->getResourceUsageFlags(),
			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));
		const std::vector<std::string>			deviceExtensions;
		OperationContext						operationContext	(m_context.getUsedApiVersion(), m_vki, m_vkd, m_physicalDevice, *m_device, allocator, deviceExtensions, 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				(m_supportDX11->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->getSyncInfo();
		const SyncInfo							readSync			= readOp->getSyncInfo();

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

	// 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

tcu::TestCaseGroup* createWin32KeyedMutexTest (tcu::TestContext& testCtx)
{
	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"
		},
	};
	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "win32_keyed_mutex", ""));

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

	return group.release();
}

} // synchronization
} // vkt
