11077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell/*------------------------------------------------------------------------
21077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * Vulkan Conformance Tests
31077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * ------------------------
41077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell *
51077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * Copyright (c) 2017 The Khronos Group Inc.
61077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell *
71077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * Licensed under the Apache License, Version 2.0 (the "License");
81077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * you may not use this file except in compliance with the License.
91077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * You may obtain a copy of the License at
101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell *
111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell *      http://www.apache.org/licenses/LICENSE-2.0
121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell *
131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * Unless required by applicable law or agreed to in writing, software
141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * distributed under the License is distributed on an "AS IS" BASIS,
151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * See the License for the specific language governing permissions and
171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * limitations under the License.
181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell *
191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell *//*!
201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * \file
211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell * \brief Synchronization tests for resources shared with DX11 keyed mutex
221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell *//*--------------------------------------------------------------------*/
231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#include "vktSynchronizationWin32KeyedMutexTests.hpp"
251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#include "vkDeviceUtil.hpp"
271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#include "vkPlatform.hpp"
281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#include "vktTestCaseUtil.hpp"
301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#include "vktSynchronizationUtil.hpp"
321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#include "vktSynchronizationOperation.hpp"
331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#include "vktSynchronizationOperationTestData.hpp"
341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#include "vktExternalMemoryUtil.hpp"
351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#include "tcuResultCollector.hpp"
371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#include "tcuTestLog.hpp"
381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#	define WIN32_LEAN_AND_MEAN
411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#	define NOMINMAX
421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#	include <windows.h>
431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#	include <aclapi.h>
441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#	include "VersionHelpers.h"
451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#	include "d3d11_2.h"
461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#	include "d3dcompiler.h"
471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Danielltypedef HRESULT				(WINAPI * LPD3DX11COMPILEFROMMEMORY)(LPCSTR,
491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																 SIZE_T,
501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																 LPCSTR,
511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																 CONST D3D10_SHADER_MACRO*,
521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																 LPD3D10INCLUDE,
531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																 LPCSTR,
541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																 LPCSTR,
551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																 UINT,
561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																 UINT,
571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																 void*, /* ID3DX11ThreadPump */
581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																 ID3D10Blob** ,
591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																 ID3D10Blob** ,
601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																 HRESULT*);
611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif
621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellusing tcu::TestLog;
641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellusing namespace vkt::ExternalMemoryUtil;
651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellnamespace vkt
671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
68e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazinusing namespace vk;
691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellnamespace synchronization
701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellnamespace
721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellstatic const ResourceDescription s_resourcesWin32KeyedMutex[] =
751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{ 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)
771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{ RESOURCE_TYPE_BUFFER,	tcu::IVec4(0x40000, 0, 0, 0),	vk::VK_IMAGE_TYPE_LAST,	vk::VK_FORMAT_UNDEFINED,			(vk::VkImageAspectFlags)0	  },	// 256 KiB
781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{ 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 },
801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{ 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 },
811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{ 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 },
821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{ 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 },
831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{ 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 },
841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell};
851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellstruct TestConfig
871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
881effe1447ee45b189b838be052373e207251af76Alexander Galazin								TestConfig		(const ResourceDescription&					resource_,
891effe1447ee45b189b838be052373e207251af76Alexander Galazin												 OperationName								writeOp_,
901effe1447ee45b189b838be052373e207251af76Alexander Galazin												 OperationName								readOp_,
9133b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin												 vk::VkExternalMemoryHandleTypeFlagBits		memoryHandleTypeBuffer_,
9233b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin												 vk::VkExternalMemoryHandleTypeFlagBits		memoryHandleTypeImage_)
931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		: resource					(resource_)
941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, writeOp					(writeOp_)
951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, readOp					(readOp_)
961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, memoryHandleTypeBuffer	(memoryHandleTypeBuffer_)
971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, memoryHandleTypeImage		(memoryHandleTypeImage_)
981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
1001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
1011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const ResourceDescription							resource;
1021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const OperationName									writeOp;
1031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const OperationName									readOp;
10433b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	const vk::VkExternalMemoryHandleTypeFlagBits		memoryHandleTypeBuffer;
10533b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	const vk::VkExternalMemoryHandleTypeFlagBits		memoryHandleTypeImage;
1061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell};
1071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
1081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellbool checkQueueFlags (vk::VkQueueFlags availableFlags, const vk::VkQueueFlags neededFlags)
1091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
1101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	if ((availableFlags & (vk::VK_QUEUE_GRAPHICS_BIT | vk::VK_QUEUE_COMPUTE_BIT)) != 0)
1111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		availableFlags |= vk::VK_QUEUE_TRANSFER_BIT;
1121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
1131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	return (availableFlags & neededFlags) != 0;
1141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
1151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
1161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellclass SimpleAllocation : public vk::Allocation
1171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
1181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellpublic:
1191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell								SimpleAllocation	(const vk::DeviceInterface&	vkd,
1201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell													 vk::VkDevice				device,
1211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell													 const vk::VkDeviceMemory	memory);
1221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell								~SimpleAllocation	(void);
1231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
1241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellprivate:
1251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const vk::DeviceInterface&	m_vkd;
1261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const vk::VkDevice			m_device;
1271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell};
1281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
1291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers DaniellSimpleAllocation::SimpleAllocation (const vk::DeviceInterface&	vkd,
1301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									vk::VkDevice				device,
1311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									const vk::VkDeviceMemory	memory)
1321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	: Allocation	(memory, 0, DE_NULL)
1331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_vkd			(vkd)
1341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_device		(device)
1351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
1361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
1371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
1381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers DaniellSimpleAllocation::~SimpleAllocation (void)
1391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
1401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	m_vkd.freeMemory(m_device, getMemory(), DE_NULL);
1411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
1421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
143aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazinvk::Move<vk::VkInstance> createInstance (const vk::PlatformInterface& vkp, deUint32 version)
1441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
1451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	try
1461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
1471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		std::vector<std::string> extensions;
148e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin		if (!isCoreInstanceExtension(version, "VK_KHR_get_physical_device_properties2"))
149e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin			extensions.push_back("VK_KHR_get_physical_device_properties2");
150e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin		if (!isCoreInstanceExtension(version, "VK_KHR_get_physical_device_properties2"))
151e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin			extensions.push_back("VK_KHR_external_memory_capabilities");
1521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
153aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin		return vk::createDefaultInstance(vkp, version, std::vector<std::string>(), extensions);
1541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
1551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	catch (const vk::Error& error)
1561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
1571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
1581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_THROW(NotSupportedError, "Required external memory extensions not supported by the instance");
1591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		else
1601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			throw;
1611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
1621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
1631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
1641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellvk::VkPhysicalDevice getPhysicalDevice (const vk::InstanceInterface&	vki,
1651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										vk::VkInstance					instance,
1661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										const tcu::CommandLine&			cmdLine)
1671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
1681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	return vk::chooseDevice(vki, instance, cmdLine);
1691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
1701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
171e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazinvk::Move<vk::VkDevice> createDevice (const deUint32									apiVersion,
172e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin									 const vk::InstanceInterface&					vki,
1731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									 vk::VkPhysicalDevice							physicalDevice)
1741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
1751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const float										priority				= 0.0f;
1761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const std::vector<vk::VkQueueFamilyProperties>	queueFamilyProperties	= vk::getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
1771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	std::vector<deUint32>							queueFamilyIndices		(queueFamilyProperties.size(), 0xFFFFFFFFu);
1781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	std::vector<const char*>						extensions;
1791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
180e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin	if (!isCoreDeviceExtension(apiVersion, "VK_KHR_external_memory"))
181e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin		extensions.push_back("VK_KHR_external_memory");
182e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin	if (!isCoreDeviceExtension(apiVersion, "VK_KHR_dedicated_allocation"))
183e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin		extensions.push_back("VK_KHR_dedicated_allocation");
184e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin	if (!isCoreDeviceExtension(apiVersion, "VK_KHR_get_memory_requirements2"))
185e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin		extensions.push_back("VK_KHR_get_memory_requirements2");
186e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin
1871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	extensions.push_back("VK_KHR_external_memory_win32");
1881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	extensions.push_back("VK_KHR_win32_keyed_mutex");
1891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
1901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	try
1911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
1921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		std::vector<vk::VkDeviceQueueCreateInfo>	queues;
1931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
1941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		for (size_t ndx = 0; ndx < queueFamilyProperties.size(); ndx++)
1951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
1961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			const vk::VkDeviceQueueCreateInfo	createInfo	=
1971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
1981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
1991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				DE_NULL,
2001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				0u,
2011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				(deUint32)ndx,
2031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				1u,
2041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&priority
2051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			};
2061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			queues.push_back(createInfo);
2081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
2091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const vk::VkDeviceCreateInfo		createInfo			=
2111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
2121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
2131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_NULL,
2141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u,
2151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			(deUint32)queues.size(),
2171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			&queues[0],
2181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u,
2201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_NULL,
2211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			(deUint32)extensions.size(),
2231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			extensions.empty() ? DE_NULL : &extensions[0],
2241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u
2251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
2261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		return vk::createDevice(vki, physicalDevice, &createInfo);
2281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
2291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	catch (const vk::Error& error)
2301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
2311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
2321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_THROW(NotSupportedError, "Required extensions not supported");
2331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		else
2341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			throw;
2351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
2361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
2371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers DanielldeUint32 chooseMemoryType (deUint32 bits)
2391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
2401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	DE_ASSERT(bits != 0);
2411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
2431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
2441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if ((bits & (1u << memoryTypeIndex)) != 0)
2451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			return memoryTypeIndex;
2461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
2471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	DE_FATAL("No supported memory types");
2491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	return -1;
2501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
2511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2521effe1447ee45b189b838be052373e207251af76Alexander Galazinvk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface&				vkd,
2531effe1447ee45b189b838be052373e207251af76Alexander Galazin										   vk::VkDevice								device,
2541effe1447ee45b189b838be052373e207251af76Alexander Galazin										   const vk::VkMemoryRequirements&			requirements,
25533b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin										   vk::VkExternalMemoryHandleTypeFlagBits	externalType,
2561effe1447ee45b189b838be052373e207251af76Alexander Galazin										   NativeHandle&							handle,
2571effe1447ee45b189b838be052373e207251af76Alexander Galazin										   bool										requiresDedicated,
2581effe1447ee45b189b838be052373e207251af76Alexander Galazin										   vk::VkBuffer								buffer,
2591effe1447ee45b189b838be052373e207251af76Alexander Galazin										   vk::VkImage								image)
2601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
26133b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	const vk::VkMemoryDedicatedAllocateInfo	dedicatedInfo	=
2621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
26333b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
2641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		DE_NULL,
2651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		image,
2661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		buffer,
2671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	};
2681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const vk::VkImportMemoryWin32HandleInfoKHR	importInfo		=
2691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
2701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
2711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		(requiresDedicated) ? &dedicatedInfo : DE_NULL,
2721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		externalType,
2731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		handle.getWin32Handle(),
2741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell        NULL
2751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	};
2761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const vk::VkMemoryAllocateInfo				info			=
2781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
2791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
2801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		&importInfo,
2811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		requirements.size,
2821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		chooseMemoryType(requirements.memoryTypeBits)
2831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	};
2841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
2861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	handle.disown();
2881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	return memory;
2901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
2911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
2921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellde::MovePtr<vk::Allocation> importAndBindMemory (const vk::DeviceInterface&					vkd,
2931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell												 vk::VkDevice								device,
2941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell												 vk::VkBuffer								buffer,
2951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell												 NativeHandle&								nativeHandle,
2961effe1447ee45b189b838be052373e207251af76Alexander Galazin												 vk::VkExternalMemoryHandleTypeFlagBits		externalType)
2971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
29833b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	const vk::VkBufferMemoryRequirementsInfo2	requirementsInfo		=
2991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
30033b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
3011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		DE_NULL,
3021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		buffer,
3031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	};
30433b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	vk::VkMemoryDedicatedRequirements			dedicatedRequirements	=
3051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
30633b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
3071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		DE_NULL,
3081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		VK_FALSE,
3091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		VK_FALSE,
3101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	};
31133b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	vk::VkMemoryRequirements2					requirements			=
3121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
31333b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		&dedicatedRequirements,
3151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{ 0u, 0u, 0u, },
3161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	};
31733b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	vkd.getBufferMemoryRequirements2(device, &requirementsInfo, &requirements);
3181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
3191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	vk::Move<vk::VkDeviceMemory> memory = importMemory(vkd, device, requirements.memoryRequirements, externalType, nativeHandle, !!dedicatedRequirements.requiresDedicatedAllocation, buffer, DE_NULL);
3201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	VK_CHECK(vkd.bindBufferMemory(device, buffer, *memory, 0u));
3211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
3221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	return de::MovePtr<vk::Allocation>(new SimpleAllocation(vkd, device, memory.disown()));
3231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
3241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
3251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellde::MovePtr<vk::Allocation> importAndBindMemory (const vk::DeviceInterface&						vkd,
3261effe1447ee45b189b838be052373e207251af76Alexander Galazin												 vk::VkDevice									device,
3271effe1447ee45b189b838be052373e207251af76Alexander Galazin												 vk::VkImage									image,
3281effe1447ee45b189b838be052373e207251af76Alexander Galazin												 NativeHandle&									nativeHandle,
3291effe1447ee45b189b838be052373e207251af76Alexander Galazin												 vk::VkExternalMemoryHandleTypeFlagBits			externalType)
3301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
3311effe1447ee45b189b838be052373e207251af76Alexander Galazin	const vk::VkImageMemoryRequirementsInfo2	requirementsInfo		=
3321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
33333b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
3341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		DE_NULL,
3351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		image,
3361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	};
33733b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	vk::VkMemoryDedicatedRequirements			dedicatedRequirements	=
3381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
33933b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
3401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		DE_NULL,
3411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		VK_FALSE,
3421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		VK_FALSE,
3431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	};
34433b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	vk::VkMemoryRequirements2					requirements			=
3451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
34633b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
3471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		&dedicatedRequirements,
3481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{ 0u, 0u, 0u, },
3491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	};
35033b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	vkd.getImageMemoryRequirements2(device, &requirementsInfo, &requirements);
3511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
3521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	vk::Move<vk::VkDeviceMemory> memory = importMemory(vkd, device, requirements.memoryRequirements, externalType, nativeHandle, !!dedicatedRequirements.requiresDedicatedAllocation, DE_NULL, image);
3531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	VK_CHECK(vkd.bindImageMemory(device, image, *memory, 0u));
3541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
3551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	return de::MovePtr<vk::Allocation>(new SimpleAllocation(vkd, device, memory.disown()));
3561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
3571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
3581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellde::MovePtr<Resource> importResource (const vk::DeviceInterface&				vkd,
3591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									  vk::VkDevice								device,
3601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									  const ResourceDescription&				resourceDesc,
3611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									  const std::vector<deUint32>&				queueFamilyIndices,
3621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									  const OperationSupport&					readOp,
3631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									  const OperationSupport&					writeOp,
3641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									  NativeHandle&								nativeHandle,
36533b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin									  vk::VkExternalMemoryHandleTypeFlagBits	externalType)
3661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
3671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	if (resourceDesc.type == RESOURCE_TYPE_IMAGE)
3681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
3691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const vk::VkExtent3D								extent					=
3701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
3711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			(deUint32)resourceDesc.size.x(),
3721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			de::max(1u, (deUint32)resourceDesc.size.y()),
3731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			de::max(1u, (deUint32)resourceDesc.size.z())
3741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
3751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const vk::VkImageSubresourceRange					subresourceRange		=
3761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
3771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			resourceDesc.imageAspect,
3781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u,
3791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			1u,
3801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u,
3811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			1u
3821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
3831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const vk::VkImageSubresourceLayers					subresourceLayers		=
3841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
3851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			resourceDesc.imageAspect,
3861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u,
3871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u,
3881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			1u
3891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
3901effe1447ee45b189b838be052373e207251af76Alexander Galazin		const vk::VkExternalMemoryImageCreateInfo			externalInfo			=
3911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
39233b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
3931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_NULL,
39433b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			(vk::VkExternalMemoryHandleTypeFlags)externalType
3951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
3961effe1447ee45b189b838be052373e207251af76Alexander Galazin		const vk::VkImageCreateInfo							createInfo				=
3971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
3981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			&externalInfo,
4001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u,
4011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			resourceDesc.imageType,
4031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			resourceDesc.imageFormat,
4041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			extent,
4051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			1u,
4061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			1u,
4071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_SAMPLE_COUNT_1_BIT,
4081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_IMAGE_TILING_OPTIMAL,
4091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags(),
4101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_SHARING_MODE_EXCLUSIVE,
4111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			(deUint32)queueFamilyIndices.size(),
4131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			&queueFamilyIndices[0],
4141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_IMAGE_LAYOUT_UNDEFINED
4151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
4161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4171effe1447ee45b189b838be052373e207251af76Alexander Galazin		vk::Move<vk::VkImage>								image					= vk::createImage(vkd, device, &createInfo);
4181effe1447ee45b189b838be052373e207251af76Alexander Galazin		de::MovePtr<vk::Allocation>							allocation				= importAndBindMemory(vkd, device, *image, nativeHandle, externalType);
4191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		return de::MovePtr<Resource>(new Resource(image, allocation, extent, resourceDesc.imageType, resourceDesc.imageFormat, subresourceRange, subresourceLayers));
4211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
4221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	else
4231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
4241effe1447ee45b189b838be052373e207251af76Alexander Galazin		const vk::VkDeviceSize								offset					= 0u;
4251effe1447ee45b189b838be052373e207251af76Alexander Galazin		const vk::VkDeviceSize								size					= static_cast<vk::VkDeviceSize>(resourceDesc.size.x());
4261effe1447ee45b189b838be052373e207251af76Alexander Galazin		const vk::VkBufferUsageFlags						usage					= readOp.getResourceUsageFlags() | writeOp.getResourceUsageFlags();
4271effe1447ee45b189b838be052373e207251af76Alexander Galazin		const vk::VkExternalMemoryBufferCreateInfo			externalInfo			=
4281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
42933b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
4301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_NULL,
43133b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			(vk::VkExternalMemoryHandleTypeFlags)externalType
4321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
4331effe1447ee45b189b838be052373e207251af76Alexander Galazin		const vk::VkBufferCreateInfo						createInfo				=
4341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
4351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
4361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			&externalInfo,
4371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u,
4381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			size,
4401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			usage,
4411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_SHARING_MODE_EXCLUSIVE,
4421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			(deUint32)queueFamilyIndices.size(),
4431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			&queueFamilyIndices[0]
4441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
4451effe1447ee45b189b838be052373e207251af76Alexander Galazin		vk::Move<vk::VkBuffer>								buffer					= vk::createBuffer(vkd, device, &createInfo);
4461effe1447ee45b189b838be052373e207251af76Alexander Galazin		de::MovePtr<vk::Allocation>							allocation				= importAndBindMemory(vkd, device, *buffer, nativeHandle, externalType);
4471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		return de::MovePtr<Resource>(new Resource(resourceDesc.type, buffer, allocation, offset, size));
4491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
4501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
4511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellvoid recordWriteBarrier (const vk::DeviceInterface&	vkd,
4531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						 vk::VkCommandBuffer		commandBuffer,
4541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						 const Resource&			resource,
4551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						 const SyncInfo&			writeSync,
4561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						 deUint32					writeQueueFamilyIndex,
4571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						 const SyncInfo&			readSync)
4581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
4591effe1447ee45b189b838be052373e207251af76Alexander Galazin	const vk::VkPipelineStageFlags		srcStageMask		= writeSync.stageMask;
4601effe1447ee45b189b838be052373e207251af76Alexander Galazin	const vk::VkAccessFlags				srcAccessMask		= writeSync.accessMask;
4611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4621effe1447ee45b189b838be052373e207251af76Alexander Galazin	const vk::VkPipelineStageFlags		dstStageMask		= readSync.stageMask;
4631effe1447ee45b189b838be052373e207251af76Alexander Galazin	const vk::VkAccessFlags				dstAccessMask		= readSync.accessMask;
4641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4651effe1447ee45b189b838be052373e207251af76Alexander Galazin	const vk::VkDependencyFlags			dependencyFlags		= 0;
4661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	if (resource.getType() == RESOURCE_TYPE_IMAGE)
4681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
4691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const vk::VkImageMemoryBarrier	barrier				=
4701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
4711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
4721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_NULL,
4731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			srcAccessMask,
4751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			dstAccessMask,
4761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			writeSync.imageLayout,
4781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			readSync.imageLayout,
4791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			writeQueueFamilyIndex,
48133b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			VK_QUEUE_FAMILY_EXTERNAL,
4821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			resource.getImage().handle,
4841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			resource.getImage().subresourceRange
4851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
4861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, (const vk::VkImageMemoryBarrier*)&barrier);
4881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
4891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	else
4901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
4911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const vk::VkBufferMemoryBarrier	barrier				=
4921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
4931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
4941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_NULL,
4951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			srcAccessMask,
4971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			dstAccessMask,
4981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
4991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			writeQueueFamilyIndex,
50033b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			VK_QUEUE_FAMILY_EXTERNAL,
5011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			resource.getBuffer().handle,
5031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u,
5041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			VK_WHOLE_SIZE
5051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
5061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 1u, (const vk::VkBufferMemoryBarrier*)&barrier, 0u, (const vk::VkImageMemoryBarrier*)DE_NULL);
5081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
5091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
5101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellvoid recordReadBarrier (const vk::DeviceInterface&	vkd,
5121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						vk::VkCommandBuffer			commandBuffer,
5131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						const Resource&				resource,
5141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						const SyncInfo&				writeSync,
5151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						const SyncInfo&				readSync,
5161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						deUint32					readQueueFamilyIndex)
5171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
5181effe1447ee45b189b838be052373e207251af76Alexander Galazin	const vk::VkPipelineStageFlags		srcStageMask		= readSync.stageMask;
5191effe1447ee45b189b838be052373e207251af76Alexander Galazin	const vk::VkAccessFlags				srcAccessMask		= readSync.accessMask;
5201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5211effe1447ee45b189b838be052373e207251af76Alexander Galazin	const vk::VkPipelineStageFlags		dstStageMask		= readSync.stageMask;
5221effe1447ee45b189b838be052373e207251af76Alexander Galazin	const vk::VkAccessFlags				dstAccessMask		= readSync.accessMask;
5231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5241effe1447ee45b189b838be052373e207251af76Alexander Galazin	const vk::VkDependencyFlags			dependencyFlags		= 0;
5251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	if (resource.getType() == RESOURCE_TYPE_IMAGE)
5271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
5281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const vk::VkImageMemoryBarrier	barrier				=
5291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
5301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
5311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_NULL,
5321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			srcAccessMask,
5341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			dstAccessMask,
5351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			writeSync.imageLayout,
5371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			readSync.imageLayout,
5381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
53933b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			VK_QUEUE_FAMILY_EXTERNAL,
5401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			readQueueFamilyIndex,
5411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			resource.getImage().handle,
5431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			resource.getImage().subresourceRange
5441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
5451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, (const vk::VkImageMemoryBarrier*)&barrier);
5471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
5481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	else
5491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
5501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const vk::VkBufferMemoryBarrier	barrier				=
5511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
5521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
5531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_NULL,
5541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			srcAccessMask,
5561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			dstAccessMask,
5571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
55833b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			VK_QUEUE_FAMILY_EXTERNAL,
5591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			readQueueFamilyIndex,
5601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			resource.getBuffer().handle,
5621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u,
5631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			VK_WHOLE_SIZE
5641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
5651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 1u, (const vk::VkBufferMemoryBarrier*)&barrier, 0u, (const vk::VkImageMemoryBarrier*)DE_NULL);
5671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
5681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
5691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellstd::vector<deUint32> getFamilyIndices (const std::vector<vk::VkQueueFamilyProperties>& properties)
5711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
5721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	std::vector<deUint32> indices (properties.size(), 0);
5731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	for (deUint32 ndx = 0; ndx < properties.size(); ndx++)
5751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		indices[ndx] = ndx;
5761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	return indices;
5781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
5791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellclass DX11Operation
5811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
5821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellpublic:
5831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	enum Buffer
5841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
5851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		BUFFER_VK_WRITE,
5861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		BUFFER_VK_READ,
5871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		BUFFER_COUNT,
5881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	};
5891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	enum KeyedMutex
5911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
5921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		KEYED_MUTEX_INIT		= 0,
5931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		KEYED_MUTEX_VK_WRITE	= 1,
5941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		KEYED_MUTEX_DX_COPY		= 2,
5951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		KEYED_MUTEX_VK_VERIFY	= 3,
5961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		KEYED_MUTEX_DONE		= 4,
5971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	};
5981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
5991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
6001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	DX11Operation (const ResourceDescription&					resourceDesc,
60133b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin				   vk::VkExternalMemoryHandleTypeFlagBits		memoryHandleType,
6021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				   ID3D11Device*								pDevice,
6031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				   ID3D11DeviceContext*							pContext,
6041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				   LPD3DX11COMPILEFROMMEMORY					fnD3DX11CompileFromMemory,
6051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				   pD3DCompile									fnD3DCompile)
6061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		: m_resourceDesc				(resourceDesc)
6071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_pDevice						(pDevice)
6091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_pContext					(pContext)
6101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_fnD3DX11CompileFromMemory	(fnD3DX11CompileFromMemory)
6111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_fnD3DCompile				(fnD3DCompile)
6121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_pRenderTargetView			(0)
6141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_pVertexShader				(0)
6151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_pPixelShader				(0)
6161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_pVertexBuffer				(0)
6171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_pTextureRV					(0)
6181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_pSamplerLinear				(0)
6191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_numFrames					(0)
6201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
6211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		HRESULT	hr;
6221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
62333b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		if (memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT ||
62433b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT)
6251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_isMemNtHandle = true;
6271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		else
6281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_isMemNtHandle = false;
6291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		m_securityAttributes.lpSecurityDescriptor = 0;
6311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		for (UINT i = 0; i < BUFFER_COUNT; i++)
6331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
6341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pTexture[i] = NULL;
6351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pBuffer[i] = NULL;
6361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_keyedMutex[i] = NULL;
6371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
6381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_resourceDesc.type == RESOURCE_TYPE_BUFFER)
6401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
6411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// SHARED_NTHANDLE is not supported with CreateBuffer().
6421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_CHECK_INTERNAL(!m_isMemNtHandle);
6431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			D3D11_BUFFER_DESC descBuf = { };
6451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			descBuf.ByteWidth = (UINT)m_resourceDesc.size.x();
6461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			descBuf.Usage = D3D11_USAGE_DEFAULT;
6471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			descBuf.BindFlags = 0;
6481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			descBuf.CPUAccessFlags = 0;
6491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			descBuf.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
6501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			descBuf.StructureByteStride = 0;
6511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			for (UINT i = 0; i < BUFFER_COUNT; ++i)
6531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
6541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				hr = m_pDevice->CreateBuffer(&descBuf, NULL, &m_pBuffer[i]);
6551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (FAILED(hr))
6561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					TCU_FAIL("Failed to create a buffer");
6571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_sharedMemHandle[i] = 0;
6591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				IDXGIResource* tempResource = NULL;
6611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				hr = m_pBuffer[i]->QueryInterface(__uuidof(IDXGIResource), (void**)&tempResource);
6621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (FAILED(hr))
6631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					TCU_FAIL("Query interface of IDXGIResource failed");
6641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				hr = tempResource->GetSharedHandle(&m_sharedMemHandle[i]);
6651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				tempResource->Release();
6661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (FAILED(hr))
6671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					TCU_FAIL("Failed to get DX shared handle");
6681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				hr = m_pBuffer[i]->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&m_keyedMutex[i]);
6701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (FAILED(hr))
6711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					TCU_FAIL("Query interface of IDXGIKeyedMutex failed");
6721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				// Take ownership of the lock.
6741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_keyedMutex[i]->AcquireSync(KEYED_MUTEX_INIT, INFINITE);
6751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			}
6761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// Release the buffer write lock for Vulkan to write into.
6781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_keyedMutex[BUFFER_VK_WRITE]->ReleaseSync(KEYED_MUTEX_VK_WRITE);
6791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_sharedMemSize = descBuf.ByteWidth;
6811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_sharedMemOffset = 0;
6821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
6831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		else
6841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
6851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_ASSERT(m_resourceDesc.type == RESOURCE_TYPE_IMAGE);
6861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
6871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			for (UINT i = 0; i < BUFFER_COUNT; ++i)
6881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
6891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				D3D11_TEXTURE2D_DESC descColor = { };
6901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				descColor.Width = m_resourceDesc.size.x();
6911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				descColor.Height = m_resourceDesc.size.y();
6921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				descColor.MipLevels = 1;
6931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				descColor.ArraySize = 1;
6941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				descColor.Format = getDxgiFormat(m_resourceDesc.imageFormat);
6951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				descColor.SampleDesc.Count = 1;
6961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				descColor.SampleDesc.Quality = 0;
6971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				descColor.Usage = D3D11_USAGE_DEFAULT;
6981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				descColor.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
6991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				descColor.CPUAccessFlags = 0;
7001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (m_isMemNtHandle)
7021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					descColor.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
7031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				else
7041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					descColor.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
7051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				hr = m_pDevice->CreateTexture2D(&descColor, NULL, &m_pTexture[i]);
7071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (FAILED(hr))
7081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					TCU_FAIL("Unable to create DX11 texture");
7091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_sharedMemHandle[i] = 0;
7111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (m_isMemNtHandle)
7131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{
7141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					IDXGIResource1* tempResource1 = NULL;
7151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					hr = m_pTexture[i]->QueryInterface(__uuidof(IDXGIResource1), (void**)&tempResource1);
7161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					if (FAILED(hr))
7171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						TCU_FAIL("Unable to query IDXGIResource1 interface");
7181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					hr = tempResource1->CreateSharedHandle(getSecurityAttributes(), DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, /*lpName*/NULL, &m_sharedMemHandle[i]);
7201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					tempResource1->Release();
7211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					if (FAILED(hr))
7221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						TCU_FAIL("Enable to get DX shared handle");
7231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				}
7241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				else
7251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{
7261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					IDXGIResource* tempResource = NULL;
7271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					hr = m_pTexture[i]->QueryInterface(__uuidof(IDXGIResource), (void**)&tempResource);
7281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					if (FAILED(hr))
7291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						TCU_FAIL("Query interface of IDXGIResource failed");
7301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					hr = tempResource->GetSharedHandle(&m_sharedMemHandle[i]);
7311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					tempResource->Release();
7321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					if (FAILED(hr))
7331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						TCU_FAIL("Failed to get DX shared handle");
7341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				}
7351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				hr = m_pTexture[i]->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&m_keyedMutex[i]);
7371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (FAILED(hr))
7381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					TCU_FAIL("Unable to query DX11 keyed mutex interface");
7391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				// Take ownership of the lock.
7411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_keyedMutex[i]->AcquireSync(KEYED_MUTEX_INIT, INFINITE);
7421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			}
7431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_sharedMemSize = 0;
7451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_sharedMemOffset = 0;
7461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			hr = m_pDevice->CreateRenderTargetView(m_pTexture[BUFFER_VK_READ], NULL, &m_pRenderTargetView);
7481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (FAILED(hr))
7491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_FAIL("Unable to create DX11 render target view");
7501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->OMSetRenderTargets(1, &m_pRenderTargetView, NULL);
7521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// Setup the viewport
7541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			D3D11_VIEWPORT vp;
7551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vp.Width = (FLOAT)m_resourceDesc.size.x();
7561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vp.Height = (FLOAT)m_resourceDesc.size.y();
7571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vp.MinDepth = 0.0f;
7581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vp.MaxDepth = 1.0f;
7591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vp.TopLeftX = 0;
7601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vp.TopLeftY = 0;
7611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->RSSetViewports(1, &vp);
7621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// Compile the vertex shader
7641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			LPCSTR shader =
7651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"Texture2D txDiffuse : register(t0);\n"
7661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"SamplerState samLinear : register(s0);\n"
7671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"struct VS_INPUT\n"
7681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"{\n"
7691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"    float4 Pos : POSITION;\n"
7701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"    float2 Tex : TEXCOORD0;\n"
7711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"};\n"
7721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"struct PS_INPUT\n"
7731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"{\n"
7741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"    float4 Pos : SV_POSITION;\n"
7751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"    float2 Tex : TEXCOORD0;\n"
7761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"};\n"
7771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"PS_INPUT VS(VS_INPUT input)\n"
7781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"{\n"
7791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"    PS_INPUT output = (PS_INPUT)0;\n"
7801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"    output.Pos = input.Pos;\n"
7811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"    output.Tex = input.Tex;\n"
7821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"\n"
7831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"    return output;\n"
7841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"}\n"
7851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"float4 PS(PS_INPUT input) : SV_Target\n"
7861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"{\n"
7871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"    return txDiffuse.Sample(samLinear, input.Tex);\n"
7881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				"}\n";
7891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// Define the input layout
7911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			D3D11_INPUT_ELEMENT_DESC layout[] =
7921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
7931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
7941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
7951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			};
7961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			createShaders(shader, "VS", "vs_4_0", ARRAYSIZE(layout), layout, &m_pVertexShader, "PS", "ps_4_0", &m_pPixelShader);
7981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
7991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			struct SimpleVertex
8001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
8011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				float Pos[3];
8021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				float Tex[2];
8031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			};
8041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			SimpleVertex vertices[] =
8061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
8071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{ { -1.f, -1.f, 0.0f }, { 0.0f, 1.0f } },
8081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{ { -1.f,  1.f, 0.0f }, { 0.0f, 0.0f } },
8091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{ {  1.f, -1.f, 0.0f }, { 1.0f, 1.0f } },
8101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{ {  1.f,  1.f, 0.0f }, { 1.0f, 0.0f } },
8111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			};
8121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			D3D11_BUFFER_DESC bd = { };
8141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			bd.Usage = D3D11_USAGE_DEFAULT;
8151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			bd.ByteWidth = sizeof (vertices);
8161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
8171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			bd.CPUAccessFlags = 0;
8181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			D3D11_SUBRESOURCE_DATA InitData = { };
8191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			InitData.pSysMem = vertices;
8201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			hr = m_pDevice->CreateBuffer(&bd, &InitData, &m_pVertexBuffer);
8211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (FAILED(hr))
8221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_FAIL("Failed to create DX11 vertex buffer");
8231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// Set vertex buffer
8251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			UINT stride = sizeof (SimpleVertex);
8261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			UINT offset = 0;
8271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset);
8281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// Set primitive topology
8301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
8311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pTextureRV = NULL;
8331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc = { };
8351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			SRVDesc.Format = getDxgiFormat(m_resourceDesc.imageFormat);
8361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
8371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			SRVDesc.Texture2D.MipLevels = 1;
8381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			hr = m_pDevice->CreateShaderResourceView(m_pTexture[BUFFER_VK_WRITE], &SRVDesc, &m_pTextureRV);
8401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (FAILED(hr))
8411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_FAIL("Failed to create DX11 resource view");
8421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// Create the sample state
8441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			D3D11_SAMPLER_DESC sampDesc = { };
8451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
8461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
8471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
8481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
8491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
8501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			sampDesc.MinLOD = 0;
8511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
8521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			hr = m_pDevice->CreateSamplerState(&sampDesc, &m_pSamplerLinear);
8531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (FAILED(hr))
8541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_FAIL("Failed to create DX11 sampler state");
8551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// Release the lock for VK to write into the texture.
8571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_keyedMutex[BUFFER_VK_WRITE]->ReleaseSync(KEYED_MUTEX_VK_WRITE);
8581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
8591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
8601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	~DX11Operation ()
8621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
8631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		cleanup();
8641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
8651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif // #if (DE_OS == DE_OS_WIN32)
8661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	NativeHandle getNativeHandle (Buffer buffer)
8681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
8691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
8701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		return NativeHandle((m_isMemNtHandle) ? NativeHandle::WIN32HANDLETYPE_NT : NativeHandle::WIN32HANDLETYPE_KMT, vk::pt::Win32Handle(m_sharedMemHandle[buffer]));
8711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#else
8721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		DE_UNREF(buffer);
8731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		return NativeHandle();
8741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif
8751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
8761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	void copyMemory ()
8781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
8791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
8801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		m_keyedMutex[BUFFER_VK_WRITE]->AcquireSync(KEYED_MUTEX_DX_COPY, INFINITE);
8811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_resourceDesc.type == RESOURCE_TYPE_BUFFER) {
8831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->CopySubresourceRegion(m_pBuffer[BUFFER_VK_READ], 0, 0, 0, 0, m_pBuffer[BUFFER_VK_WRITE], 0, NULL);
8841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		} else {
8851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->OMSetRenderTargets(1, &m_pRenderTargetView, NULL);
8861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			const FLOAT gray[] = { 0.f, 0.f, 1.f, 1.f };
8881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->ClearRenderTargetView(m_pRenderTargetView, gray);
8891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->VSSetShader(m_pVertexShader, NULL, 0);
8911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->PSSetShader(m_pPixelShader, NULL, 0);
8921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->PSSetShaderResources(0, 1, &m_pTextureRV);
8931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->PSSetSamplers(0, 1, &m_pSamplerLinear);
8941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->Draw(4, 0);
8951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
8961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
8971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		m_keyedMutex[BUFFER_VK_WRITE]->ReleaseSync(KEYED_MUTEX_DONE);
8981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		m_keyedMutex[BUFFER_VK_READ]->ReleaseSync(KEYED_MUTEX_VK_VERIFY);
8991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif // #if (DE_OS == DE_OS_WIN32)
9001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
9011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
9031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	void d3dx11CompileShader (const char* shaderCode, const char * entryPoint, const char* shaderModel, ID3D10Blob** ppBlobOut)
9041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
9051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		HRESULT hr;
9061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		ID3D10Blob* pErrorBlob;
9081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		hr = m_fnD3DX11CompileFromMemory (shaderCode,
9091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										  strlen(shaderCode),
9101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										  "Memory",
9111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										  NULL,
9121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										  NULL,
9131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										  entryPoint,
9141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										  shaderModel,
9151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										  0,
9161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										  0,
9171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										  NULL,
9181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										  ppBlobOut,
9191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										  &pErrorBlob,
9201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell										  NULL);
9211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (pErrorBlob)
9221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			pErrorBlob->Release();
9231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (FAILED(hr))
9251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_FAIL("D3DX11CompileFromMemory failed to compile shader");
9261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
9271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	void d3dCompileShader (const char* shaderCode, const char * entryPoint, const char* shaderModel, ID3DBlob** ppBlobOut)
9291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
9301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		HRESULT hr;
9311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		ID3DBlob* pErrorBlob;
9331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		hr = m_fnD3DCompile (shaderCode,
9341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell							 strlen(shaderCode),
9351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell							 NULL,
9361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell							 NULL,
9371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell							 NULL,
9381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell							 entryPoint,
9391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell							 shaderModel,
9401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell							 0,
9411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell							 0,
9421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell							 ppBlobOut,
9431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell							 &pErrorBlob);
9441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (pErrorBlob)
9451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			pErrorBlob->Release();
9461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (FAILED(hr))
9481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_FAIL("D3DCompile failed to compile shader");
9491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
9501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	void createShaders (const char* shaderSrc,
9521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						const char* vsEntryPoint,
9531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						const char* vsShaderModel,
9541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						UINT numLayoutDesc,
9551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						D3D11_INPUT_ELEMENT_DESC* pLayoutDesc,
9561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						ID3D11VertexShader** pVertexShader,
9571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						const char* psEntryPoint,
9581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						const char* psShaderModel,
9591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						ID3D11PixelShader** pPixelShader)
9601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
9611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		HRESULT	hr;
9621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_fnD3DX11CompileFromMemory) {
9641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// VS
9651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			ID3D10Blob* pVSBlob;
9661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			d3dx11CompileShader(shaderSrc, vsEntryPoint, vsShaderModel, &pVSBlob);
9671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			hr = m_pDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, pVertexShader);
9691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (FAILED(hr))
9701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_FAIL("Failed to create DX11 vertex shader");
9711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			ID3D11InputLayout *pVertexLayout;
9731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			hr = m_pDevice->CreateInputLayout(pLayoutDesc, numLayoutDesc, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &pVertexLayout);
9741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (FAILED(hr))
9751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_FAIL("Failed to create vertex input layout");
9761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->IASetInputLayout(pVertexLayout);
9781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			pVertexLayout->Release();
9791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			pVSBlob->Release();
9801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// PS
9821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			ID3D10Blob* pPSBlob;
9831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			d3dx11CompileShader(shaderSrc, psEntryPoint, psShaderModel, &pPSBlob);
9841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			hr = m_pDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, pPixelShader);
9861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (FAILED(hr))
9871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_FAIL("Failed to create DX11 pixel shader");
9881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		} else {
9891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// VS
9901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			ID3DBlob* pVSBlob;
9911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			d3dCompileShader(shaderSrc, vsEntryPoint, vsShaderModel, &pVSBlob);
9921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			hr = m_pDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, pVertexShader);
9941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (FAILED(hr))
9951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_FAIL("Failed to create DX11 vertex shader");
9961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
9971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			ID3D11InputLayout *pVertexLayout;
9981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			hr = m_pDevice->CreateInputLayout(pLayoutDesc, numLayoutDesc, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &pVertexLayout);
9991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (FAILED(hr))
10001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_FAIL("Failed to create vertex input layout");
10011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->IASetInputLayout(pVertexLayout);
10031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			pVertexLayout->Release();
10041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			pVSBlob->Release();
10051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			// PS
10071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			ID3DBlob* pPSBlob;
10081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			d3dCompileShader(shaderSrc, psEntryPoint, psShaderModel, &pPSBlob);
10091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			hr = m_pDevice->CreatePixelShader(pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, pPixelShader);
10111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (FAILED(hr))
10121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_FAIL("Failed to create DX11 pixel shader");
10131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
10141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
10151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif // #if (DE_OS == DE_OS_WIN32)
10161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellprivate:
10181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
10191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	void cleanup ()
10201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
10211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_securityAttributes.lpSecurityDescriptor)
10221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
10231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			freeSecurityDescriptor(m_securityAttributes.lpSecurityDescriptor);
10241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_securityAttributes.lpSecurityDescriptor = NULL;
10251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
10261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_pContext)
10281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->ClearState();
10291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_pRenderTargetView)
10311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
10321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pRenderTargetView->Release();
10331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pRenderTargetView = NULL;
10341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
10351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_pSamplerLinear)
10371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
10381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pSamplerLinear->Release();
10391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pSamplerLinear = NULL;
10401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
10411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_pTextureRV)
10431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
10441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pTextureRV->Release();
10451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pTextureRV = NULL;
10461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
10471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_pVertexBuffer)
10491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
10501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pVertexBuffer->Release();
10511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pVertexBuffer = NULL;
10521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
10531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_pVertexShader)
10551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
10561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pVertexShader->Release();
10571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pVertexShader = NULL;
10581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
10591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_pPixelShader)
10611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
10621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pPixelShader->Release();
10631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pPixelShader = NULL;
10641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
10651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		for (int i = 0; i < BUFFER_COUNT; i++)
10671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
10681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (m_keyedMutex[i])
10691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
10701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_keyedMutex[i]->AcquireSync(KEYED_MUTEX_DONE, INFINITE);
10711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_keyedMutex[i]->Release();
10721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_keyedMutex[i] = NULL;
10731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			}
10741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (m_isMemNtHandle && m_sharedMemHandle[i]) {
10761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				CloseHandle(m_sharedMemHandle[i]);
10771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_sharedMemHandle[i] = 0;
10781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			}
10791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (m_pBuffer[i]) {
10811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_pBuffer[i]->Release();
10821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_pBuffer[i] = NULL;
10831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			}
10841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (m_pTexture[i]) {
10861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_pTexture[i]->Release();
10871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_pTexture[i] = NULL;
10881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			}
10891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
10901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
10911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	static void* getSecurityDescriptor ()
10931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
10941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR)deCalloc(SECURITY_DESCRIPTOR_MIN_LENGTH + 2 * sizeof (void**));
10951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
10961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (pSD)
10971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
10981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			PSID*	ppEveryoneSID	= (PSID*)((PBYTE)pSD + SECURITY_DESCRIPTOR_MIN_LENGTH);
10991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			PACL*	ppACL			= (PACL*)((PBYTE)ppEveryoneSID + sizeof(PSID*));
11001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
11021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			SID_IDENTIFIER_AUTHORITY	SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
11041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, ppEveryoneSID);
11051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			EXPLICIT_ACCESS	ea = { };
11071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			ea.grfAccessPermissions = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
11081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			ea.grfAccessMode = SET_ACCESS;
11091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			ea.grfInheritance = INHERIT_ONLY;
11101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
11111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
11121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			ea.Trustee.ptstrName = (LPTSTR)*ppEveryoneSID;
11131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			SetEntriesInAcl(1, &ea, NULL, ppACL);
11151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			SetSecurityDescriptorDacl(pSD, TRUE, *ppACL, FALSE);
11171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
11181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		return pSD;
11201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
11211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	static void freeSecurityDescriptor (void* pSD)
11231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
11241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (pSD)
11251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
11261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			PSID*	ppEveryoneSID	= (PSID*)((PBYTE)pSD + SECURITY_DESCRIPTOR_MIN_LENGTH);
11271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			PACL*	ppACL			= (PACL*)((PBYTE)ppEveryoneSID + sizeof(PSID*));
11281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (*ppEveryoneSID)
11301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				FreeSid(*ppEveryoneSID);
11311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (*ppACL)
11331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				LocalFree(*ppACL);
11341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			deFree(pSD);
11361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
11371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
11381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	static DXGI_FORMAT getDxgiFormat (vk::VkFormat format)
11401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
11411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		switch (format)
11421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
11431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			case vk::VK_FORMAT_R8_UNORM:
11441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				return DXGI_FORMAT_R8_UNORM;
11451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			case vk::VK_FORMAT_R16_UINT:
11461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				return DXGI_FORMAT_R16_UINT;
11471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			case vk::VK_FORMAT_R8G8B8A8_UNORM:
11481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				return DXGI_FORMAT_R8G8B8A8_UNORM;
11491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			case vk::VK_FORMAT_R16G16B16A16_UINT:
11501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				return DXGI_FORMAT_R16G16B16A16_UINT;
11511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			case vk::VK_FORMAT_R32G32B32A32_SFLOAT:
11521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				return DXGI_FORMAT_R32G32B32A32_FLOAT;
11531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			case vk::VK_FORMAT_D16_UNORM:
11541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				return DXGI_FORMAT_D16_UNORM;
11551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			case vk::VK_FORMAT_D32_SFLOAT:
11561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				return DXGI_FORMAT_D32_FLOAT;
11571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			default:
11581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_CHECK_INTERNAL(!"Unsupported DXGI format");
11591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				return DXGI_FORMAT_UNKNOWN;
11601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
11611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
11621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ResourceDescription			m_resourceDesc;
11641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
1165a1f746c62c645a09758cfa938a95315785ac56b8Boris Zanin	deUint64					m_sharedMemSize;
1166a1f746c62c645a09758cfa938a95315785ac56b8Boris Zanin	deUint64					m_sharedMemOffset;
11671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	HANDLE						m_sharedMemHandle[BUFFER_COUNT];
11681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	bool						m_isMemNtHandle;
11691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ID3D11Device*				m_pDevice;
11711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ID3D11DeviceContext*		m_pContext;
11721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	LPD3DX11COMPILEFROMMEMORY	m_fnD3DX11CompileFromMemory;
11731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	pD3DCompile					m_fnD3DCompile;
11741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ID3D11RenderTargetView*		m_pRenderTargetView;
11761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ID3D11VertexShader*			m_pVertexShader;
11771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ID3D11PixelShader*			m_pPixelShader;
11781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ID3D11Buffer*				m_pVertexBuffer;
11791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ID3D11ShaderResourceView*	m_pTextureRV;
11801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ID3D11SamplerState*			m_pSamplerLinear;
11811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ID3D11Texture2D*			m_pTexture[BUFFER_COUNT];
11831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ID3D11Buffer*				m_pBuffer[BUFFER_COUNT];
11841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	IDXGIKeyedMutex*			m_keyedMutex[BUFFER_COUNT];
11851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	UINT						m_numFrames;
11861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	SECURITY_ATTRIBUTES			m_securityAttributes;
11871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	SECURITY_ATTRIBUTES* getSecurityAttributes ()
11891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
11901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		m_securityAttributes.nLength = sizeof (SECURITY_ATTRIBUTES);
11911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		m_securityAttributes.bInheritHandle = TRUE;
11921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (!m_securityAttributes.lpSecurityDescriptor)
11931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_securityAttributes.lpSecurityDescriptor = getSecurityDescriptor();
11941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
11951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		return &m_securityAttributes;
11961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
11971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif // #if (DE_OS == DE_OS_WIN32)
11981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell};
11991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellclass DX11OperationSupport
12011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
12021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellpublic:
12031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	DX11OperationSupport (const vk::InstanceInterface&	vki,
12041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						  vk::VkPhysicalDevice			physicalDevice,
12051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						  const ResourceDescription&	resourceDesc)
12061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		: m_resourceDesc			(resourceDesc)
12071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
12081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_hD3D11Lib					(0)
12091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_hD3DX11Lib					(0)
12101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_hD3DCompilerLib				(0)
12111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_hDxgiLib					(0)
12121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_fnD3D11CreateDevice			(0)
12131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_fnD3DX11CompileFromMemory	(0)
12141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		, m_fnD3DCompile				(0)
12151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif
12161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
12171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
12181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		HRESULT										hr;
12191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
122033b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vk::VkPhysicalDeviceIDProperties		propertiesId = { vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES };
122133b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vk::VkPhysicalDeviceProperties2			properties = { vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 };
12221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		properties.pNext = &propertiesId;
12241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
122533b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vki.getPhysicalDeviceProperties2(physicalDevice, &properties);
12261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (!propertiesId.deviceLUIDValid)
12271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_FAIL("Physical device deviceLUIDValid is not valid");
12281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		m_hD3D11Lib = LoadLibrary("d3d11.dll");
12311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (!m_hD3D11Lib)
12321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_FAIL("Failed to load d3d11.dll");
12331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		m_fnD3D11CreateDevice = (LPD3D11CREATEDEVICE) GetProcAddress(m_hD3D11Lib, "D3D11CreateDevice");
12361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (!m_fnD3D11CreateDevice)
12371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_FAIL("Unable to find D3D11CreateDevice() function");
12381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		m_hD3DX11Lib = LoadLibrary("d3dx11_42.dll");
12401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_hD3DX11Lib)
12411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_fnD3DX11CompileFromMemory =  (LPD3DX11COMPILEFROMMEMORY) GetProcAddress(m_hD3DX11Lib, "D3DX11CompileFromMemory");
12421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		else
12431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
12441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_hD3DCompilerLib = LoadLibrary("d3dcompiler_43.dll");
12451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (!m_hD3DCompilerLib)
12461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_hD3DCompilerLib = LoadLibrary("d3dcompiler_47.dll");
12471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (!m_hD3DCompilerLib)
12481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_FAIL("Unable to load DX11 d3dcompiler_43.dll or d3dcompiler_47.dll");
12491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_fnD3DCompile = (pD3DCompile)GetProcAddress(m_hD3DCompilerLib, "D3DCompile");
12511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (!m_fnD3DCompile)
12521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				TCU_FAIL("Unable to load find D3DCompile");
12531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
12541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		m_hDxgiLib = LoadLibrary("dxgi.dll");
12561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (!m_hDxgiLib)
12571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_FAIL("Unable to load DX11 dxgi.dll");
12581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		typedef HRESULT (WINAPI *LPCREATEDXGIFACTORY1)(REFIID riid, void** ppFactory);
12601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		LPCREATEDXGIFACTORY1 CreateDXGIFactory1 = (LPCREATEDXGIFACTORY1)GetProcAddress(m_hDxgiLib, "CreateDXGIFactory1");
12611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (!CreateDXGIFactory1)
12621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_FAIL("Unable to load find CreateDXGIFactory1");
12631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		IDXGIFactory1* pFactory = NULL;
12651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		hr = CreateDXGIFactory1(__uuidof(IDXGIFactory), (void**)&pFactory);
12661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (FAILED(hr))
12671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_FAIL("Unable to create IDXGIFactory interface");
12681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		IDXGIAdapter *pAdapter = NULL;
12701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		for (UINT i = 0; pFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND; ++i)
12711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
12721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DXGI_ADAPTER_DESC desc;
12731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			pAdapter->GetDesc(&desc);
12741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (deMemCmp(&desc.AdapterLuid, propertiesId.deviceLUID, VK_LUID_SIZE_KHR) == 0)
12761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				break;
12771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
12781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		pFactory->Release();
12791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		D3D_FEATURE_LEVEL fLevel[] = {D3D_FEATURE_LEVEL_11_0};
12811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		UINT devflags = D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS | // no separate D3D11 worker thread
12821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if 0
12831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						D3D11_CREATE_DEVICE_DEBUG | // useful for diagnosing DX failures
12841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif
12851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell						D3D11_CREATE_DEVICE_SINGLETHREADED;
12861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		hr = m_fnD3D11CreateDevice (pAdapter,
12881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									pAdapter ? D3D_DRIVER_TYPE_UNKNOWN : D3D_DRIVER_TYPE_HARDWARE,
12891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									NULL,
12901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									devflags,
12911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									fLevel,
12921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									DE_LENGTH_OF_ARRAY(fLevel),
12931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									D3D11_SDK_VERSION,
12941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									&m_pDevice,
12951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									NULL,
12961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell									&m_pContext);
12971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
12981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (pAdapter) {
12991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			pAdapter->Release();
13001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
13011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (!m_pDevice)
13031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_FAIL("Failed to created DX11 device");
13041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (!m_pContext)
13051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_FAIL("Failed to created DX11 context");
13061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#else
13071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		DE_UNREF(vki);
13081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		DE_UNREF(physicalDevice);
13091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		TCU_THROW(NotSupportedError, "OS not supported");
13101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif
13111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
13121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	~DX11OperationSupport ()
13141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
13151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
13161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		cleanup ();
13171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif
13181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
13191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
13211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	void cleanup ()
13221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
13231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_pContext) {
13241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext->Release();
13251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pContext = 0;
13261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
13271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_pDevice) {
13291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pDevice->Release();
13301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_pDevice = 0;
13311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
13321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_hDxgiLib)
13341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
13351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			FreeLibrary(m_hDxgiLib);
13361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_hDxgiLib = 0;
13371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
13381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_hD3DCompilerLib)
13401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
13411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			FreeLibrary(m_hD3DCompilerLib);
13421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_hD3DCompilerLib = 0;
13431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
13441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_hD3DX11Lib)
13461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
13471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			FreeLibrary(m_hD3DX11Lib);
13481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_hD3DX11Lib = 0;
13491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
13501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_hD3D11Lib)
13521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
13531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			FreeLibrary(m_hD3D11Lib);
13541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_hD3D11Lib = 0;
13551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
13561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
13571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif
13591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
136033b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	virtual de::MovePtr<DX11Operation> build (const ResourceDescription& resourceDesc, vk::VkExternalMemoryHandleTypeFlagBits memoryHandleType) const
13611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
13621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
13631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		return de::MovePtr<DX11Operation>(new DX11Operation(resourceDesc, memoryHandleType, m_pDevice, m_pContext, m_fnD3DX11CompileFromMemory, m_fnD3DCompile));
13641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#else
13651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		DE_UNREF(resourceDesc);
13661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		DE_UNREF(memoryHandleType);
13671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		TCU_THROW(NotSupportedError, "OS not supported");
13681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif
13691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
13701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellprivate:
13721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const ResourceDescription	m_resourceDesc;
13731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
13751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	typedef HRESULT				(WINAPI *LPD3D11CREATEDEVICE)(IDXGIAdapter*,
13761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell															  D3D_DRIVER_TYPE,
13771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell															  HMODULE,
13781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell															  UINT,
13791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell															  const D3D_FEATURE_LEVEL*,
13801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell															  UINT,
13811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell															  UINT,
13821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell															  ID3D11Device **,
13831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell															  D3D_FEATURE_LEVEL*,
13841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell															  ID3D11DeviceContext**);
13851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	HMODULE						m_hD3D11Lib;
13871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	HMODULE						m_hD3DX11Lib;
13881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	HMODULE						m_hD3DCompilerLib;
13891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	HMODULE						m_hDxgiLib;
13901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	LPD3D11CREATEDEVICE			m_fnD3D11CreateDevice;
13911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	LPD3DX11COMPILEFROMMEMORY	m_fnD3DX11CompileFromMemory;
13921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	pD3DCompile					m_fnD3DCompile;
13931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ID3D11Device*				m_pDevice;
13941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	ID3D11DeviceContext*		m_pContext;
13951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif
13961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell};
13971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
13981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellclass Win32KeyedMutexTestInstance : public TestInstance
13991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
14001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellpublic:
14011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell														Win32KeyedMutexTestInstance	(Context&	context,
14021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell																					 TestConfig	config);
14031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	virtual tcu::TestStatus								iterate					(void);
14051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellprivate:
14071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const TestConfig									m_config;
14081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const de::UniquePtr<OperationSupport>				m_supportWriteOp;
14091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const de::UniquePtr<OperationSupport>				m_supportReadOp;
14101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const vk::Unique<vk::VkInstance>					m_instance;
14121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const vk::InstanceDriver							m_vki;
14141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const vk::VkPhysicalDevice							m_physicalDevice;
14151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const std::vector<vk::VkQueueFamilyProperties>		m_queueFamilies;
14161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const std::vector<deUint32>							m_queueFamilyIndices;
14171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const vk::Unique<vk::VkDevice>						m_device;
14181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const vk::DeviceDriver								m_vkd;
14191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const de::UniquePtr<DX11OperationSupport>			m_supportDX11;
14211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
142233b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin	const vk::VkExternalMemoryHandleTypeFlagBits		m_memoryHandleType;
14231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	// \todo Should this be moved to the group same way as in the other tests?
14251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	PipelineCacheData									m_pipelineCacheData;
14261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	tcu::ResultCollector								m_resultCollector;
14271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	size_t												m_queueNdx;
14281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	bool												m_useDedicatedAllocation;
14301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell};
14311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers DaniellWin32KeyedMutexTestInstance::Win32KeyedMutexTestInstance	(Context&		context,
14331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell															 TestConfig		config)
14341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	: TestInstance				(context)
14351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_config					(config)
14361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_supportWriteOp			(makeOperationSupport(config.writeOp, config.resource))
14371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_supportReadOp			(makeOperationSupport(config.readOp, config.resource))
14381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
1439aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin	, m_instance				(createInstance(context.getPlatformInterface(), context.getUsedApiVersion()))
14401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_vki						(context.getPlatformInterface(), *m_instance)
14421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_physicalDevice			(getPhysicalDevice(m_vki, *m_instance, context.getTestContext().getCommandLine()))
14431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_queueFamilies			(vk::getPhysicalDeviceQueueFamilyProperties(m_vki, m_physicalDevice))
14441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_queueFamilyIndices		(getFamilyIndices(m_queueFamilies))
1445e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin	, m_device					(createDevice(context.getUsedApiVersion(), m_vki, m_physicalDevice))
14461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_vkd						(m_vki, *m_device)
14471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_supportDX11				(new DX11OperationSupport(m_vki, m_physicalDevice, config.resource))
14491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_memoryHandleType		((m_config.resource.type == RESOURCE_TYPE_IMAGE) ? m_config.memoryHandleTypeImage : m_config.memoryHandleTypeBuffer)
14511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_resultCollector			(context.getTestContext().getLog())
14531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_queueNdx				(0)
14541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	, m_useDedicatedAllocation	(false)
14561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
14571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#if (DE_OS == DE_OS_WIN32)
14581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	TestLog& log = m_context.getTestContext().getLog();
14591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
14601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	// Check resource support
14611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	if (m_config.resource.type == RESOURCE_TYPE_IMAGE)
14621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
146333b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		if (m_memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT && !IsWindows8OrGreater())
14641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_THROW(NotSupportedError, "Memory handle type not supported by this OS");
14651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
146633b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		const vk::VkPhysicalDeviceExternalImageFormatInfo	externalInfo		=
14671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
146833b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
14691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_NULL,
14701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_memoryHandleType
14711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
147233b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		const vk::VkPhysicalDeviceImageFormatInfo2			imageFormatInfo		=
14731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
1474aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
14751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			&externalInfo,
14761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_config.resource.imageFormat,
14771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_config.resource.imageType,
14781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VK_IMAGE_TILING_OPTIMAL,
14791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_supportReadOp->getResourceUsageFlags() | m_supportWriteOp->getResourceUsageFlags(),
14801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u
14811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
148233b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vk::VkExternalImageFormatProperties					externalProperties	=
14831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
148471bbfa85d25fad23437bdbc070c3223949c49f94Piers Daniell			vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
14851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_NULL,
14861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{ 0u, 0u, 0u }
14871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
148833b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vk::VkImageFormatProperties2						formatProperties	=
14891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
1490aae4252b14d3f5fc1594706fecc567b84c64f1adAlexander Galazin			vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
14911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			&externalProperties,
14921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
14931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{ 0u, 0u, 0u },
14941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				0u,
14951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				0u,
14961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				0u,
14971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				0u,
14981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			}
14991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
150033b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		VK_CHECK(m_vki.getPhysicalDeviceImageFormatProperties2(m_physicalDevice, &imageFormatInfo, &formatProperties));
15011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		// \todo How to log this nicely?
15031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		log << TestLog::Message << "External image format properties: " << imageFormatInfo << "\n"<< externalProperties << TestLog::EndMessage;
15041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
150533b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0)
15061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_THROW(NotSupportedError, "Importing image resource not supported");
15071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
150833b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		if (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT)
15091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_useDedicatedAllocation = true;
15101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
15111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	else
15121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
151333b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		if (m_memoryHandleType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT && !IsWindows8OrGreater())
15141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_THROW(NotSupportedError, "Memory handle type not supported by this OS");
15151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
151633b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		const vk::VkPhysicalDeviceExternalBufferInfo		info	=
15171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
151833b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
15191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_NULL,
15201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			0u,
15221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_supportReadOp->getResourceUsageFlags() | m_supportWriteOp->getResourceUsageFlags(),
15231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_memoryHandleType
15241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
152533b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		vk::VkExternalBufferProperties						properties			=
15261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
152733b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
15281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_NULL,
15291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{ 0u, 0u, 0u}
15301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		};
153133b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		m_vki.getPhysicalDeviceExternalBufferProperties(m_physicalDevice, &info, &properties);
15321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		log << TestLog::Message << "External buffer properties: " << info << "\n" << properties << TestLog::EndMessage;
15341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
153533b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0)
15361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_THROW(NotSupportedError, "Importing memory type not supported");
15371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
153833b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin		if (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT)
15391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			m_useDedicatedAllocation = true;
15401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
15411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#else
15421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	DE_UNREF(m_useDedicatedAllocation);
15431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	TCU_THROW(NotSupportedError, "OS not supported");
15441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell#endif
15451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
15461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Danielltcu::TestStatus Win32KeyedMutexTestInstance::iterate (void)
15481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
15491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	TestLog&									log					(m_context.getTestContext().getLog());
15501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	try
15521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
15531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const deUint32							queueFamily			= (deUint32)m_queueNdx;
15541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const tcu::ScopedLogSection				queuePairSection	(log, "Queue-" + de::toString(queueFamily), "Queue-" + de::toString(queueFamily));
15561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const vk::VkQueue						queue				(getDeviceQueue(m_vkd, *m_device, queueFamily, 0u));
15581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const vk::Unique<vk::VkCommandPool>		commandPool			(createCommandPool(m_vkd, *m_device, 0u, queueFamily));
15591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const vk::Unique<vk::VkCommandBuffer>	commandBufferWrite	(allocateCommandBuffer(m_vkd, *m_device, *commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
15601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const vk::Unique<vk::VkCommandBuffer>	commandBufferRead	(allocateCommandBuffer(m_vkd, *m_device, *commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
15611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		vk::SimpleAllocator						allocator			(m_vkd, *m_device, vk::getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice));
15621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const std::vector<std::string>			deviceExtensions;
1563e808b407039c05dc9822e81973a3aecb2c7dab47Alexander Galazin		OperationContext						operationContext	(m_context.getUsedApiVersion(), m_vki, m_vkd, m_physicalDevice, *m_device, allocator, deviceExtensions, m_context.getBinaryCollection(), m_pipelineCacheData);
15641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (!checkQueueFlags(m_queueFamilies[m_queueNdx].queueFlags, vk::VK_QUEUE_GRAPHICS_BIT))
15661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			TCU_THROW(NotSupportedError, "Operation not supported by the source queue");
15671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const de::UniquePtr<DX11Operation>		dx11Op				(m_supportDX11->build(m_config.resource, m_memoryHandleType));
15691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		NativeHandle nativeHandleWrite = dx11Op->getNativeHandle(DX11Operation::BUFFER_VK_WRITE);
15711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const de::UniquePtr<Resource>			resourceWrite		(importResource(m_vkd, *m_device, m_config.resource, m_queueFamilyIndices, *m_supportReadOp, *m_supportWriteOp, nativeHandleWrite, m_memoryHandleType));
15721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		NativeHandle nativeHandleRead = dx11Op->getNativeHandle(DX11Operation::BUFFER_VK_READ);
15741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const de::UniquePtr<Resource>			resourceRead		(importResource(m_vkd, *m_device, m_config.resource, m_queueFamilyIndices, *m_supportReadOp, *m_supportWriteOp, nativeHandleRead, m_memoryHandleType));
15751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const de::UniquePtr<Operation>			writeOp				(m_supportWriteOp->build(operationContext, *resourceWrite));
15771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const de::UniquePtr<Operation>			readOp				(m_supportReadOp->build(operationContext, *resourceRead));
15781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const SyncInfo							writeSync			= writeOp->getSyncInfo();
15801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const SyncInfo							readSync			= readOp->getSyncInfo();
15811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		beginCommandBuffer(m_vkd, *commandBufferWrite);
15831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		writeOp->recordCommands(*commandBufferWrite);
15841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		recordWriteBarrier(m_vkd, *commandBufferWrite, *resourceWrite, writeSync, queueFamily, readSync);
15851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		endCommandBuffer(m_vkd, *commandBufferWrite);
15861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		beginCommandBuffer(m_vkd, *commandBufferRead);
15881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		recordReadBarrier(m_vkd, *commandBufferRead, *resourceRead, writeSync, readSync, queueFamily);
15891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		readOp->recordCommands(*commandBufferRead);
15901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		endCommandBuffer(m_vkd, *commandBufferRead);
15911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
15921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
15931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VkDeviceMemory							memory			= resourceWrite->getMemory();
1594a1f746c62c645a09758cfa938a95315785ac56b8Boris Zanin			deUint64									keyInit			= DX11Operation::KEYED_MUTEX_VK_WRITE;
1595a1f746c62c645a09758cfa938a95315785ac56b8Boris Zanin			deUint32									timeout			= 0xFFFFFFFF; // INFINITE
1596a1f746c62c645a09758cfa938a95315785ac56b8Boris Zanin			deUint64									keyExternal		= DX11Operation::KEYED_MUTEX_DX_COPY;
15971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VkWin32KeyedMutexAcquireReleaseInfoKHR	keyedMutexInfo	=
15981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
15991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				vk::VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR,
16001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				DE_NULL,
16011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				1,
16031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&memory,
16041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&keyInit,
16051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&timeout,
16061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				1,
16081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&memory,
16091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&keyExternal,
16101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			};
16111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			const vk::VkCommandBuffer	commandBuffer	= *commandBufferWrite;
16131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			const vk::VkSubmitInfo		submitInfo			=
16141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
16151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
16161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&keyedMutexInfo,
16171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				0u,
16191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				DE_NULL,
16201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				DE_NULL,
16211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				1u,
16231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&commandBuffer,
16241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				0u,
16251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				DE_NULL
16261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			};
16271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			VK_CHECK(m_vkd.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
16291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
16301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		dx11Op->copyMemory();
16321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
16341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VkDeviceMemory							memory			= resourceRead->getMemory();
1635a1f746c62c645a09758cfa938a95315785ac56b8Boris Zanin			deUint64									keyInternal		= DX11Operation::KEYED_MUTEX_VK_VERIFY;
1636a1f746c62c645a09758cfa938a95315785ac56b8Boris Zanin			deUint32									timeout			= 0xFFFFFFFF; // INFINITE
1637a1f746c62c645a09758cfa938a95315785ac56b8Boris Zanin			deUint64									keyExternal		= DX11Operation::KEYED_MUTEX_DONE;
16381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			vk::VkWin32KeyedMutexAcquireReleaseInfoKHR	keyedMutexInfo	=
16391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
16401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				vk::VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR,
16411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				DE_NULL,
16421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				1,
16441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&memory,
16451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&keyInternal,
16461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&timeout,
16471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				1,
16491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&memory,
16501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&keyExternal,
16511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			};
16521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			const vk::VkCommandBuffer	commandBuffer	= *commandBufferRead;
16541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			const vk::VkSubmitInfo		submitInfo			=
16551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
16561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
16571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&keyedMutexInfo,
16581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				0u,
16601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				DE_NULL,
16611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				DE_NULL,
16621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				1u,
16641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				&commandBuffer,
16651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				0u,
16661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				DE_NULL
16671077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			};
16681077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			VK_CHECK(m_vkd.queueSubmit(queue, 1u, &submitInfo, DE_NULL));
16701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
16711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		VK_CHECK(m_vkd.queueWaitIdle(queue));
16731077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16741077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
16751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			const Data	expected	= writeOp->getData();
16761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			const Data	actual		= readOp->getData();
16771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16781077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			DE_ASSERT(expected.size == actual.size);
16791077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			if (0 != deMemCmp(expected.data, actual.data, expected.size))
16811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
16821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				const size_t		maxBytesLogged	= 256;
16831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				std::ostringstream	expectedData;
16841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				std::ostringstream	actualData;
16851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				size_t				byteNdx			= 0;
16861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				// Find first byte difference
16881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				for (; actual.data[byteNdx] == expected.data[byteNdx]; byteNdx++)
16891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{
16901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					// Nothing
16911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				}
16921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				log << TestLog::Message << "First different byte at offset: " << byteNdx << TestLog::EndMessage;
16941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
16951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				// Log 8 previous bytes before the first incorrect byte
16961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (byteNdx > 8)
16971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{
16981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					expectedData << "... ";
16991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					actualData << "... ";
17001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					byteNdx -= 8;
17021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				}
17031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				else
17041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					byteNdx = 0;
17051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				for (size_t i = 0; i < maxBytesLogged && byteNdx < expected.size; i++, byteNdx++)
17071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{
17081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					expectedData << (i > 0 ? ", " : "") << (deUint32)expected.data[byteNdx];
17091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					actualData << (i > 0 ? ", " : "") << (deUint32)actual.data[byteNdx];
17101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				}
17111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (expected.size > byteNdx)
17131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{
17141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					expectedData << "...";
17151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					actualData << "...";
17161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				}
17171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				log << TestLog::Message << "Expected data: (" << expectedData.str() << ")" << TestLog::EndMessage;
17191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				log << TestLog::Message << "Actual data: (" << actualData.str() << ")" << TestLog::EndMessage;
17201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				m_resultCollector.fail("Memory contents don't match");
17221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			}
17231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
17241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
17251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	catch (const tcu::NotSupportedError& error)
17261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
17271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		log << TestLog::Message << "Not supported: " << error.getMessage() << TestLog::EndMessage;
17281077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
17291077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	catch (const tcu::TestError& error)
17301077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
17311077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		m_resultCollector.fail(std::string("Exception: ") + error.getMessage());
17321077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
17331077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17341077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	// Move to next queue
17351077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
17361077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		m_queueNdx++;
17371077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17381077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (m_queueNdx >= m_queueFamilies.size())
17391077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
17401077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
17411077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
17421077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		else
17431077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
17441077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			return tcu::TestStatus::incomplete();
17451077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
17461077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
17471077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
17481077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17491077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniellstruct Progs
17501077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
17511077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	void init (vk::SourceCollections& dst, TestConfig config) const
17521077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
17531077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const de::UniquePtr<OperationSupport>	readOp	(makeOperationSupport(config.readOp, config.resource));
17541077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const de::UniquePtr<OperationSupport>	writeOp	(makeOperationSupport(config.writeOp, config.resource));
17551077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17561077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		readOp->initPrograms(dst);
17571077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		writeOp->initPrograms(dst);
17581077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
17591077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell};
17601077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17611077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell} // anonymous
17621077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17631077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Danielltcu::TestCaseGroup* createWin32KeyedMutexTest (tcu::TestContext& testCtx)
17641077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell{
17651077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	const struct
17661077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
17671effe1447ee45b189b838be052373e207251af76Alexander Galazin		vk::VkExternalMemoryHandleTypeFlagBits			memoryHandleTypeBuffer;
17681effe1447ee45b189b838be052373e207251af76Alexander Galazin		vk::VkExternalMemoryHandleTypeFlagBits			memoryHandleTypeImage;
17691077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const char*										nameSuffix;
17701077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	} cases[] =
17711077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
17721077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
177333b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			(vk::VkExternalMemoryHandleTypeFlagBits)0u,				// DX11 doesn't support buffers with an NT handle
177433b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT,
17751077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			"_nt"
17761077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		},
17771077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
177833b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
177933b5a8a9652e2ad55029dccd970f0e7a39af917fAlexander Galazin			vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT,
17801077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			"_kmt"
17811077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		},
17821077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	};
17831077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "win32_keyed_mutex", ""));
17841077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17851077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	for (size_t writeOpNdx = 0; writeOpNdx < DE_LENGTH_OF_ARRAY(s_writeOps); ++writeOpNdx)
17861077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	for (size_t readOpNdx = 0; readOpNdx < DE_LENGTH_OF_ARRAY(s_readOps); ++readOpNdx)
17871077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	{
17881077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const OperationName	writeOp		= s_writeOps[writeOpNdx];
17891077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const OperationName	readOp		= s_readOps[readOpNdx];
17901077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		const std::string	opGroupName	= getOperationName(writeOp) + "_" + getOperationName(readOp);
17911077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		bool				empty		= true;
17921077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17931077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		de::MovePtr<tcu::TestCaseGroup> opGroup	(new tcu::TestCaseGroup(testCtx, opGroupName.c_str(), ""));
17941077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17951077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		for (size_t resourceNdx = 0; resourceNdx < DE_LENGTH_OF_ARRAY(s_resourcesWin32KeyedMutex); ++resourceNdx)
17961077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		{
17971077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			const ResourceDescription&	resource	= s_resourcesWin32KeyedMutex[resourceNdx];
17981077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
17991077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			for (size_t caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
18001077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			{
18011077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (resource.type == RESOURCE_TYPE_BUFFER && !cases[caseNdx].memoryHandleTypeBuffer)
18021077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					continue;
18031077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
18041077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (resource.type == RESOURCE_TYPE_IMAGE && !cases[caseNdx].memoryHandleTypeImage)
18051077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					continue;
18061077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
18071077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				std::string	name	= getResourceName(resource) + cases[caseNdx].nameSuffix;
18081077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
18091077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				if (isResourceSupported(writeOp, resource) && isResourceSupported(readOp, resource))
18101077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				{
18111077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					const TestConfig config (resource, writeOp, readOp, cases[caseNdx].memoryHandleTypeBuffer, cases[caseNdx].memoryHandleTypeImage);
18121077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
18131077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					opGroup->addChild(new InstanceFactory1<Win32KeyedMutexTestInstance, TestConfig, Progs>(testCtx, tcu::NODETYPE_SELF_VALIDATE,  name, "", Progs(), config));
18141077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell					empty = false;
18151077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell				}
18161077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			}
18171077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		}
18181077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
18191077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell		if (!empty)
18201077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell			group->addChild(opGroup.release());
18211077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	}
18221077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
18231077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell	return group.release();
18241077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell}
18251077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell
18261077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell} // synchronization
18271077dac0fc457cf3f9f8345c61a9b78b96eb73ddPiers Daniell} // vkt
1828