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

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(),
		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.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		= 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)
#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));
		const std::vector<std::string>			deviceExtensions;
		OperationContext						operationContext	(m_context, 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				(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
