Home | History | Annotate | Download | only in vulkan
      1 /*-------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2016 Google Inc.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  * \brief Vulkan external memory utilities
     20  *//*--------------------------------------------------------------------*/
     21 
     22 #include "vktExternalMemoryUtil.hpp"
     23 
     24 #include "vkQueryUtil.hpp"
     25 
     26 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
     27 #	include <unistd.h>
     28 #	include <fcntl.h>
     29 #	include <errno.h>
     30 #	include <sys/types.h>
     31 #	include <sys/socket.h>
     32 #endif
     33 
     34 #if (DE_OS == DE_OS_WIN32)
     35 #	define WIN32_LEAN_AND_MEAN
     36 #	include <windows.h>
     37 #endif
     38 
     39 #if (DE_OS == DE_OS_ANDROID) && defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
     40 #	include <android/hardware_buffer.h>
     41 #	define USE_ANDROID_O_HARDWARE_BUFFER 1
     42 #endif
     43 
     44 namespace vkt
     45 {
     46 namespace ExternalMemoryUtil
     47 {
     48 namespace
     49 {
     50 deUint32 chooseMemoryType (deUint32 bits)
     51 {
     52 	DE_ASSERT(bits != 0);
     53 
     54 	for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
     55 	{
     56 		if ((bits & (1u << memoryTypeIndex)) != 0)
     57 			return memoryTypeIndex;
     58 	}
     59 
     60 	DE_FATAL("No supported memory types");
     61 	return -1;
     62 }
     63 
     64 } // anonymous
     65 
     66 NativeHandle::NativeHandle (void)
     67 	: m_fd						(-1)
     68 	, m_win32HandleType			(WIN32HANDLETYPE_LAST)
     69 	, m_win32Handle				(DE_NULL)
     70 	, m_androidHardwareBuffer	(DE_NULL)
     71 {
     72 }
     73 
     74 NativeHandle::NativeHandle (const NativeHandle& other)
     75 	: m_fd						(-1)
     76 	, m_win32HandleType			(WIN32HANDLETYPE_LAST)
     77 	, m_win32Handle				(DE_NULL)
     78 	, m_androidHardwareBuffer	(DE_NULL)
     79 {
     80 	if (other.m_fd >= 0)
     81 	{
     82 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
     83 		DE_ASSERT(!other.m_win32Handle.internal);
     84 		DE_ASSERT(!other.m_androidHardwareBuffer.internal);
     85 		m_fd = dup(other.m_fd);
     86 		TCU_CHECK(m_fd >= 0);
     87 #else
     88 		DE_FATAL("Platform doesn't support file descriptors");
     89 #endif
     90 	}
     91 	else if (other.m_win32Handle.internal)
     92 	{
     93 #if (DE_OS == DE_OS_WIN32)
     94 		m_win32HandleType = other.m_win32HandleType;
     95 
     96 		switch (other.m_win32HandleType)
     97 		{
     98 			case WIN32HANDLETYPE_NT:
     99 			{
    100 				DE_ASSERT(other.m_fd == -1);
    101 				DE_ASSERT(!other.m_androidHardwareBuffer.internal);
    102 
    103 				const HANDLE process = ::GetCurrentProcess();
    104 				::DuplicateHandle(process, other.m_win32Handle.internal, process, &m_win32Handle.internal, 0, TRUE, DUPLICATE_SAME_ACCESS);
    105 
    106 				break;
    107 			}
    108 
    109 			case WIN32HANDLETYPE_KMT:
    110 			{
    111 				m_win32Handle = other.m_win32Handle;
    112 				break;
    113 			}
    114 
    115 			default:
    116 				DE_FATAL("Unknown win32 handle type");
    117 		}
    118 #else
    119 		DE_FATAL("Platform doesn't support win32 handles");
    120 #endif
    121 	}
    122 #if defined(USE_ANDROID_O_HARDWARE_BUFFER)
    123 	else if (other.m_androidHardwareBuffer.internal)
    124 	{
    125 		DE_ASSERT(other.m_fd == -1);
    126 		DE_ASSERT(!other.m_win32Handle.internal);
    127 		m_androidHardwareBuffer = other.m_androidHardwareBuffer;
    128 		AHardwareBuffer_acquire((AHardwareBuffer*)m_androidHardwareBuffer.internal);
    129 	}
    130 #endif
    131 	else
    132 		DE_FATAL("Native handle can't be duplicated");
    133 }
    134 
    135 NativeHandle::NativeHandle (int fd)
    136 	: m_fd						(fd)
    137 	, m_win32HandleType			(WIN32HANDLETYPE_LAST)
    138 	, m_win32Handle				(DE_NULL)
    139 	, m_androidHardwareBuffer	(DE_NULL)
    140 {
    141 }
    142 
    143 NativeHandle::NativeHandle (Win32HandleType handleType, vk::pt::Win32Handle handle)
    144 	: m_fd						(-1)
    145 	, m_win32HandleType			(handleType)
    146 	, m_win32Handle				(handle)
    147 	, m_androidHardwareBuffer	(DE_NULL)
    148 {
    149 }
    150 
    151 NativeHandle::NativeHandle (vk::pt::AndroidHardwareBufferPtr buffer)
    152 	: m_fd						(-1)
    153 	, m_win32HandleType			(WIN32HANDLETYPE_LAST)
    154 	, m_win32Handle				(DE_NULL)
    155 	, m_androidHardwareBuffer	(buffer)
    156 {
    157 }
    158 
    159 NativeHandle::~NativeHandle (void)
    160 {
    161 	reset();
    162 }
    163 
    164 void NativeHandle::reset (void)
    165 {
    166 	if (m_fd >= 0)
    167 	{
    168 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
    169 		DE_ASSERT(!m_win32Handle.internal);
    170 		DE_ASSERT(!m_androidHardwareBuffer.internal);
    171 		::close(m_fd);
    172 #else
    173 		DE_FATAL("Platform doesn't support file descriptors");
    174 #endif
    175 	}
    176 
    177 	if (m_win32Handle.internal)
    178 	{
    179 #if (DE_OS == DE_OS_WIN32)
    180 		switch (m_win32HandleType)
    181 		{
    182 			case WIN32HANDLETYPE_NT:
    183 				DE_ASSERT(m_fd == -1);
    184 				DE_ASSERT(!m_androidHardwareBuffer.internal);
    185 				::CloseHandle((HANDLE)m_win32Handle.internal);
    186 				break;
    187 
    188 			case WIN32HANDLETYPE_KMT:
    189 				break;
    190 
    191 			default:
    192 				DE_FATAL("Unknown win32 handle type");
    193 		}
    194 #else
    195 		DE_FATAL("Platform doesn't support win32 handles");
    196 #endif
    197 	}
    198 
    199 #if defined(USE_ANDROID_O_HARDWARE_BUFFER)
    200 	if (m_androidHardwareBuffer.internal)
    201 	{
    202 		DE_ASSERT(m_fd == -1);
    203 		DE_ASSERT(!m_win32Handle.internal);
    204 		AHardwareBuffer_release((AHardwareBuffer*)m_androidHardwareBuffer.internal);
    205 	}
    206 #endif
    207 
    208 	m_fd					= -1;
    209 	m_win32Handle			= vk::pt::Win32Handle(DE_NULL);
    210 	m_win32HandleType		= WIN32HANDLETYPE_LAST;
    211 	m_androidHardwareBuffer	= vk::pt::AndroidHardwareBufferPtr(DE_NULL);
    212 }
    213 
    214 NativeHandle& NativeHandle::operator= (int fd)
    215 {
    216 	reset();
    217 
    218 	m_fd = fd;
    219 
    220 	return *this;
    221 }
    222 
    223 NativeHandle& NativeHandle::operator= (vk::pt::AndroidHardwareBufferPtr buffer)
    224 {
    225 	reset();
    226 
    227 	m_androidHardwareBuffer = buffer;
    228 
    229 	return *this;
    230 }
    231 
    232 void NativeHandle::setWin32Handle (Win32HandleType type, vk::pt::Win32Handle handle)
    233 {
    234 	reset();
    235 
    236 	m_win32HandleType	= type;
    237 	m_win32Handle		= handle;
    238 }
    239 
    240 void NativeHandle::disown (void)
    241 {
    242 	m_fd = -1;
    243 	m_win32Handle = vk::pt::Win32Handle(DE_NULL);
    244 	m_androidHardwareBuffer = vk::pt::AndroidHardwareBufferPtr(DE_NULL);
    245 }
    246 
    247 vk::pt::Win32Handle NativeHandle::getWin32Handle (void) const
    248 {
    249 	DE_ASSERT(m_fd == -1);
    250 	DE_ASSERT(!m_androidHardwareBuffer.internal);
    251 	return m_win32Handle;
    252 }
    253 
    254 int NativeHandle::getFd (void) const
    255 {
    256 	DE_ASSERT(!m_win32Handle.internal);
    257 	DE_ASSERT(!m_androidHardwareBuffer.internal);
    258 	return m_fd;
    259 }
    260 
    261 
    262 vk::pt::AndroidHardwareBufferPtr NativeHandle::getAndroidHardwareBuffer (void) const
    263 {
    264 	DE_ASSERT(m_fd == -1);
    265 	DE_ASSERT(!m_win32Handle.internal);
    266 	return m_androidHardwareBuffer;
    267 }
    268 
    269 const char* externalSemaphoreTypeToName (vk::VkExternalSemaphoreHandleTypeFlagBits type)
    270 {
    271 	switch (type)
    272 	{
    273 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
    274 			return "opaque_fd";
    275 
    276 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
    277 			return "opaque_win32";
    278 
    279 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
    280 			return "opaque_win32_kmt";
    281 
    282 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT:
    283 			return "d3d12_fenc";
    284 
    285 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
    286 			return "sync_fd";
    287 
    288 		default:
    289 			DE_FATAL("Unknown external semaphore type");
    290 			return DE_NULL;
    291 	}
    292 }
    293 
    294 const char* externalFenceTypeToName (vk::VkExternalFenceHandleTypeFlagBits type)
    295 {
    296 	switch (type)
    297 	{
    298 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
    299 			return "opaque_fd";
    300 
    301 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
    302 			return "opaque_win32";
    303 
    304 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
    305 			return "opaque_win32_kmt";
    306 
    307 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
    308 			return "sync_fd";
    309 
    310 		default:
    311 			DE_FATAL("Unknown external fence type");
    312 			return DE_NULL;
    313 	}
    314 }
    315 
    316 const char* externalMemoryTypeToName (vk::VkExternalMemoryHandleTypeFlagBits type)
    317 {
    318 	switch (type)
    319 	{
    320 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
    321 			return "opaque_fd";
    322 
    323 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:
    324 			return "opaque_win32";
    325 
    326 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
    327 			return "opaque_win32_kmt";
    328 
    329 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT:
    330 			return "d3d11_texture";
    331 
    332 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT:
    333 			return "d3d11_texture_kmt";
    334 
    335 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT:
    336 			return "d3d12_heap";
    337 
    338 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT:
    339 			return "d3d12_resource";
    340 
    341 		case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:
    342 			return "android_hardware_buffer";
    343 
    344 		default:
    345 			DE_FATAL("Unknown external memory type");
    346 			return DE_NULL;
    347 	}
    348 }
    349 
    350 bool isSupportedPermanence (vk::VkExternalSemaphoreHandleTypeFlagBits	type,
    351 							Permanence										permanence)
    352 {
    353 	switch (type)
    354 	{
    355 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
    356 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
    357 			return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
    358 
    359 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
    360 			return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
    361 
    362 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
    363 			return permanence == PERMANENCE_TEMPORARY;
    364 
    365 		default:
    366 			DE_FATAL("Unknown external semaphore type");
    367 			return false;
    368 	}
    369 }
    370 
    371 Transference getHandelTypeTransferences (vk::VkExternalSemaphoreHandleTypeFlagBits type)
    372 {
    373 	switch (type)
    374 	{
    375 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
    376 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
    377 			return TRANSFERENCE_REFERENCE;
    378 
    379 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
    380 			return TRANSFERENCE_REFERENCE;
    381 
    382 		case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
    383 			return TRANSFERENCE_COPY;
    384 
    385 		default:
    386 			DE_FATAL("Unknown external semaphore type");
    387 			return TRANSFERENCE_REFERENCE;
    388 	}
    389 }
    390 
    391 bool isSupportedPermanence (vk::VkExternalFenceHandleTypeFlagBits	type,
    392 							Permanence									permanence)
    393 {
    394 	switch (type)
    395 	{
    396 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
    397 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
    398 			return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
    399 
    400 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
    401 			return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
    402 
    403 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
    404 			return permanence == PERMANENCE_TEMPORARY;
    405 
    406 		default:
    407 			DE_FATAL("Unknown external fence type");
    408 			return false;
    409 	}
    410 }
    411 
    412 Transference getHandelTypeTransferences (vk::VkExternalFenceHandleTypeFlagBits type)
    413 {
    414 	switch (type)
    415 	{
    416 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
    417 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
    418 			return TRANSFERENCE_REFERENCE;
    419 
    420 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
    421 			return TRANSFERENCE_REFERENCE;
    422 
    423 		case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
    424 			return TRANSFERENCE_COPY;
    425 
    426 		default:
    427 			DE_FATAL("Unknown external fence type");
    428 			return TRANSFERENCE_REFERENCE;
    429 	}
    430 }
    431 
    432 int getMemoryFd (const vk::DeviceInterface&					vkd,
    433 				 vk::VkDevice								device,
    434 				 vk::VkDeviceMemory							memory,
    435 				 vk::VkExternalMemoryHandleTypeFlagBits		externalType)
    436 {
    437 	const vk::VkMemoryGetFdInfoKHR	info	=
    438 	{
    439 		vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
    440 		DE_NULL,
    441 
    442 		memory,
    443 		externalType
    444 	};
    445 	int								fd		= -1;
    446 
    447 	VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd));
    448 	TCU_CHECK(fd >= 0);
    449 
    450 	return fd;
    451 }
    452 
    453 void getMemoryNative (const vk::DeviceInterface&					vkd,
    454 						 vk::VkDevice								device,
    455 						 vk::VkDeviceMemory							memory,
    456 						 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
    457 						 NativeHandle&								nativeHandle)
    458 {
    459 	if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
    460 	{
    461 		const vk::VkMemoryGetFdInfoKHR	info	=
    462 		{
    463 			vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
    464 			DE_NULL,
    465 
    466 			memory,
    467 			externalType
    468 		};
    469 		int								fd		= -1;
    470 
    471 		VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd));
    472 		TCU_CHECK(fd >= 0);
    473 		nativeHandle = fd;
    474 	}
    475 	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
    476 		|| externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
    477 	{
    478 		const vk::VkMemoryGetWin32HandleInfoKHR	info	=
    479 		{
    480 			vk::VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
    481 			DE_NULL,
    482 
    483 			memory,
    484 			externalType
    485 		};
    486 		vk::pt::Win32Handle						handle	(DE_NULL);
    487 
    488 		VK_CHECK(vkd.getMemoryWin32HandleKHR(device, &info, &handle));
    489 
    490 		switch (externalType)
    491 		{
    492 			case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:
    493 				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
    494 				break;
    495 
    496 			case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
    497 				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
    498 				break;
    499 
    500 			default:
    501 				DE_FATAL("Unknown external memory handle type");
    502 		}
    503 	}
    504 	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
    505 	{
    506 		const vk::VkMemoryGetAndroidHardwareBufferInfoANDROID	info	=
    507 		{
    508 			vk::VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
    509 			DE_NULL,
    510 
    511 			memory,
    512 		};
    513 		vk::pt::AndroidHardwareBufferPtr						ahb	(DE_NULL);
    514 
    515 		VK_CHECK(vkd.getMemoryAndroidHardwareBufferANDROID(device, &info, &ahb));
    516 		TCU_CHECK(ahb.internal);
    517 		nativeHandle = ahb;
    518 	}
    519 	else
    520 		DE_FATAL("Unknown external memory handle type");
    521 }
    522 
    523 vk::Move<vk::VkFence> createExportableFence (const vk::DeviceInterface&					vkd,
    524 											 vk::VkDevice								device,
    525 											 vk::VkExternalFenceHandleTypeFlagBits		externalType)
    526 {
    527 	const vk::VkExportFenceCreateInfo	exportCreateInfo	=
    528 	{
    529 		vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
    530 		DE_NULL,
    531 		(vk::VkExternalFenceHandleTypeFlags)externalType
    532 	};
    533 	const vk::VkFenceCreateInfo				createInfo			=
    534 	{
    535 		vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
    536 		&exportCreateInfo,
    537 		0u
    538 	};
    539 
    540 	return vk::createFence(vkd, device, &createInfo);
    541 }
    542 
    543 int getFenceFd (const vk::DeviceInterface&					vkd,
    544 				vk::VkDevice								device,
    545 				vk::VkFence									fence,
    546 				vk::VkExternalFenceHandleTypeFlagBits		externalType)
    547 {
    548 	const vk::VkFenceGetFdInfoKHR	info	=
    549 	{
    550 		vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
    551 		DE_NULL,
    552 
    553 		fence,
    554 		externalType
    555 	};
    556 	int								fd	= -1;
    557 
    558 	VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd));
    559 	TCU_CHECK(fd >= 0);
    560 
    561 	return fd;
    562 }
    563 
    564 void getFenceNative (const vk::DeviceInterface&					vkd,
    565 					 vk::VkDevice								device,
    566 					 vk::VkFence								fence,
    567 					 vk::VkExternalFenceHandleTypeFlagBits		externalType,
    568 					 NativeHandle&								nativeHandle)
    569 {
    570 	if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
    571 		|| externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
    572 	{
    573 		const vk::VkFenceGetFdInfoKHR	info	=
    574 		{
    575 			vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
    576 			DE_NULL,
    577 
    578 			fence,
    579 			externalType
    580 		};
    581 		int								fd	= -1;
    582 
    583 		VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd));
    584 		TCU_CHECK(fd >= 0);
    585 		nativeHandle = fd;
    586 	}
    587 	else if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
    588 		|| externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
    589 	{
    590 		const vk::VkFenceGetWin32HandleInfoKHR	info	=
    591 		{
    592 			vk::VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR,
    593 			DE_NULL,
    594 
    595 			fence,
    596 			externalType
    597 		};
    598 		vk::pt::Win32Handle						handle	(DE_NULL);
    599 
    600 		VK_CHECK(vkd.getFenceWin32HandleKHR(device, &info, &handle));
    601 
    602 		switch (externalType)
    603 		{
    604 			case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
    605 				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
    606 				break;
    607 
    608 			case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
    609 				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
    610 				break;
    611 
    612 			default:
    613 				DE_FATAL("Unknow external memory handle type");
    614 		}
    615 	}
    616 	else
    617 		DE_FATAL("Unknow external fence handle type");
    618 }
    619 
    620 void importFence (const vk::DeviceInterface&				vkd,
    621 				  const vk::VkDevice						device,
    622 				  const vk::VkFence							fence,
    623 				  vk::VkExternalFenceHandleTypeFlagBits		externalType,
    624 				  NativeHandle&								handle,
    625 				  vk::VkFenceImportFlags					flags)
    626 {
    627 	if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
    628 		|| externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
    629 	{
    630 		const vk::VkImportFenceFdInfoKHR	importInfo	=
    631 		{
    632 			vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
    633 			DE_NULL,
    634 			fence,
    635 			flags,
    636 			externalType,
    637 			handle.getFd()
    638 		};
    639 
    640 		VK_CHECK(vkd.importFenceFdKHR(device, &importInfo));
    641 		handle.disown();
    642 	}
    643 	else if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
    644 			|| externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
    645 	{
    646 		const vk::VkImportFenceWin32HandleInfoKHR	importInfo	=
    647 		{
    648 			vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
    649 			DE_NULL,
    650 			fence,
    651 			flags,
    652 			externalType,
    653 			handle.getWin32Handle(),
    654 			DE_NULL
    655 		};
    656 
    657 		VK_CHECK(vkd.importFenceWin32HandleKHR(device, &importInfo));
    658 		// \note File descriptors and win32 handles behave differently, but this call wil make it seem like they would behave in same way
    659 		handle.reset();
    660 	}
    661 	else
    662 		DE_FATAL("Unknown fence external handle type");
    663 }
    664 
    665 vk::Move<vk::VkFence> createAndImportFence (const vk::DeviceInterface&				vkd,
    666 											const vk::VkDevice						device,
    667 											vk::VkExternalFenceHandleTypeFlagBits	externalType,
    668 											NativeHandle&							handle,
    669 											vk::VkFenceImportFlags					flags)
    670 {
    671 	vk::Move<vk::VkFence>	fence	(createFence(vkd, device));
    672 
    673 	importFence(vkd, device, *fence, externalType, handle, flags);
    674 
    675 	return fence;
    676 }
    677 
    678 vk::Move<vk::VkSemaphore> createExportableSemaphore (const vk::DeviceInterface&					vkd,
    679 													 vk::VkDevice								device,
    680 													 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType)
    681 {
    682 	const vk::VkExportSemaphoreCreateInfo	exportCreateInfo	=
    683 	{
    684 		vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
    685 		DE_NULL,
    686 		(vk::VkExternalSemaphoreHandleTypeFlags)externalType
    687 	};
    688 	const vk::VkSemaphoreCreateInfo				createInfo			=
    689 	{
    690 		vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
    691 		&exportCreateInfo,
    692 		0u
    693 	};
    694 
    695 	return vk::createSemaphore(vkd, device, &createInfo);
    696 }
    697 
    698 int getSemaphoreFd (const vk::DeviceInterface&					vkd,
    699 					vk::VkDevice								device,
    700 					vk::VkSemaphore								semaphore,
    701 					vk::VkExternalSemaphoreHandleTypeFlagBits	externalType)
    702 {
    703 	const vk::VkSemaphoreGetFdInfoKHR	info	=
    704 	{
    705 		vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
    706 		DE_NULL,
    707 
    708 		semaphore,
    709 		externalType
    710 	};
    711 	int										fd	= -1;
    712 
    713 	VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
    714 	TCU_CHECK(fd >= 0);
    715 
    716 	return fd;
    717 }
    718 
    719 void getSemaphoreNative (const vk::DeviceInterface&					vkd,
    720 						 vk::VkDevice								device,
    721 						 vk::VkSemaphore							semaphore,
    722 						 vk::VkExternalSemaphoreHandleTypeFlagBits	externalType,
    723 						 NativeHandle&								nativeHandle)
    724 {
    725 	if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
    726 		|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
    727 	{
    728 		const vk::VkSemaphoreGetFdInfoKHR	info	=
    729 		{
    730 			vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
    731 			DE_NULL,
    732 
    733 			semaphore,
    734 			externalType
    735 		};
    736 		int										fd	= -1;
    737 
    738 		VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
    739 		TCU_CHECK(fd >= 0);
    740 		nativeHandle = fd;
    741 	}
    742 	else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
    743 		|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
    744 	{
    745 		const vk::VkSemaphoreGetWin32HandleInfoKHR	info	=
    746 		{
    747 			vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
    748 			DE_NULL,
    749 
    750 			semaphore,
    751 			externalType
    752 		};
    753 		vk::pt::Win32Handle							handle	(DE_NULL);
    754 
    755 		VK_CHECK(vkd.getSemaphoreWin32HandleKHR(device, &info, &handle));
    756 
    757 		switch (externalType)
    758 		{
    759 			case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
    760 				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
    761 				break;
    762 
    763 			case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
    764 				nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
    765 				break;
    766 
    767 			default:
    768 				DE_FATAL("Unknow external memory handle type");
    769 		}
    770 	}
    771 	else
    772 		DE_FATAL("Unknow external semaphore handle type");
    773 }
    774 
    775 void importSemaphore (const vk::DeviceInterface&					vkd,
    776 					  const vk::VkDevice							device,
    777 					  const vk::VkSemaphore							semaphore,
    778 					  vk::VkExternalSemaphoreHandleTypeFlagBits		externalType,
    779 					  NativeHandle&									handle,
    780 					  vk::VkSemaphoreImportFlags					flags)
    781 {
    782 	if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
    783 		|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
    784 	{
    785 		const vk::VkImportSemaphoreFdInfoKHR	importInfo	=
    786 		{
    787 			vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
    788 			DE_NULL,
    789 			semaphore,
    790 			flags,
    791 			externalType,
    792 			handle.getFd()
    793 		};
    794 
    795 		VK_CHECK(vkd.importSemaphoreFdKHR(device, &importInfo));
    796 		handle.disown();
    797 	}
    798 	else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
    799 			|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
    800 	{
    801 		const vk::VkImportSemaphoreWin32HandleInfoKHR	importInfo	=
    802 		{
    803 			vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
    804 			DE_NULL,
    805 			semaphore,
    806 			flags,
    807 			externalType,
    808 			handle.getWin32Handle(),
    809 			DE_NULL
    810 		};
    811 
    812 		VK_CHECK(vkd.importSemaphoreWin32HandleKHR(device, &importInfo));
    813 		// \note File descriptors and win32 handles behave differently, but this call wil make it seem like they would behave in same way
    814 		handle.reset();
    815 	}
    816 	else
    817 		DE_FATAL("Unknown semaphore external handle type");
    818 }
    819 
    820 vk::Move<vk::VkSemaphore> createAndImportSemaphore (const vk::DeviceInterface&						vkd,
    821 													const vk::VkDevice								device,
    822 													vk::VkExternalSemaphoreHandleTypeFlagBits		externalType,
    823 													NativeHandle&									handle,
    824 													vk::VkSemaphoreImportFlags						flags)
    825 {
    826 	vk::Move<vk::VkSemaphore>	semaphore	(createSemaphore(vkd, device));
    827 
    828 	importSemaphore(vkd, device, *semaphore, externalType, handle, flags);
    829 
    830 	return semaphore;
    831 }
    832 
    833 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface&					vkd,
    834 													   vk::VkDevice									device,
    835 													   const vk::VkMemoryRequirements&				requirements,
    836 													   vk::VkExternalMemoryHandleTypeFlagBits		externalType,
    837 													   vk::VkBuffer									buffer,
    838 													   deUint32&									exportedMemoryTypeIndex)
    839 {
    840 	exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits);
    841 	const vk::VkMemoryDedicatedAllocateInfo	dedicatedInfo	=
    842 	{
    843 		vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
    844 		DE_NULL,
    845 
    846 		(vk::VkImage)0,
    847 		buffer
    848 	};
    849 	const vk::VkExportMemoryAllocateInfo	exportInfo	=
    850 	{
    851 		vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
    852 		!!buffer ? &dedicatedInfo : DE_NULL,
    853 		(vk::VkExternalMemoryHandleTypeFlags)externalType
    854 	};
    855 	const vk::VkMemoryAllocateInfo			info		=
    856 	{
    857 		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
    858 		&exportInfo,
    859 		requirements.size,
    860 		exportedMemoryTypeIndex
    861 	};
    862 	return vk::allocateMemory(vkd, device, &info);
    863 }
    864 
    865 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface&					vkd,
    866 													   vk::VkDevice									device,
    867 													   const vk::VkMemoryRequirements&				requirements,
    868 													   vk::VkExternalMemoryHandleTypeFlagBits		externalType,
    869 													   vk::VkImage									image,
    870 													   deUint32&									exportedMemoryTypeIndex)
    871 {
    872 	exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits);
    873 	const vk::VkMemoryDedicatedAllocateInfo	dedicatedInfo	=
    874 	{
    875 		vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
    876 		DE_NULL,
    877 
    878 		image,
    879 		(vk::VkBuffer)0
    880 	};
    881 	const vk::VkExportMemoryAllocateInfo	exportInfo	=
    882 	{
    883 		vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
    884 		!!image ? &dedicatedInfo : DE_NULL,
    885 		(vk::VkExternalMemoryHandleTypeFlags)externalType
    886 	};
    887 	const vk::VkMemoryAllocateInfo			info		=
    888 	{
    889 		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
    890 		&exportInfo,
    891 		requirements.size,
    892 		exportedMemoryTypeIndex
    893 	};
    894 	return vk::allocateMemory(vkd, device, &info);
    895 }
    896 
    897 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::InstanceInterface&					vki,
    898 													   vk::VkPhysicalDevice							physicalDevice,
    899 													   const vk::DeviceInterface&					vkd,
    900 													   vk::VkDevice									device,
    901 													   const vk::VkMemoryRequirements&				requirements,
    902 													   vk::VkExternalMemoryHandleTypeFlagBits		externalType,
    903 													   bool											hostVisible,
    904 													   vk::VkBuffer									buffer,
    905 													   deUint32&									exportedMemoryTypeIndex)
    906 {
    907 	const vk::VkPhysicalDeviceMemoryProperties properties = vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
    908 
    909 	for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= requirements.memoryTypeBits; memoryTypeIndex++)
    910 	{
    911 		if (((requirements.memoryTypeBits & (1u << memoryTypeIndex)) != 0)
    912 			&& (((properties.memoryTypes[memoryTypeIndex].propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) == hostVisible))
    913 		{
    914 			const vk::VkMemoryDedicatedAllocateInfo	dedicatedInfo	=
    915 			{
    916 				vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
    917 				DE_NULL,
    918 
    919 				(vk::VkImage)0,
    920 				buffer
    921 			};
    922 			const vk::VkExportMemoryAllocateInfo	exportInfo	=
    923 			{
    924 				vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
    925 				!!buffer ? &dedicatedInfo : DE_NULL,
    926 				(vk::VkExternalMemoryHandleTypeFlags)externalType
    927 			};
    928 			const vk::VkMemoryAllocateInfo			info		=
    929 			{
    930 				vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
    931 				&exportInfo,
    932 				requirements.size,
    933 				memoryTypeIndex
    934 			};
    935 
    936 			exportedMemoryTypeIndex = memoryTypeIndex;
    937 			return vk::allocateMemory(vkd, device, &info);
    938 		}
    939 	}
    940 
    941 	TCU_THROW(NotSupportedError, "No supported memory type found");
    942 }
    943 
    944 static vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface&				vkd,
    945 												  vk::VkDevice								device,
    946 												  vk::VkBuffer								buffer,
    947 												  vk::VkImage								image,
    948 												  const vk::VkMemoryRequirements&			requirements,
    949 												  vk::VkExternalMemoryHandleTypeFlagBits	externalType,
    950 												  deUint32									memoryTypeIndex,
    951 												  NativeHandle&								handle)
    952 {
    953 	const bool	isDedicated		= !!buffer || !!image;
    954 
    955 	DE_ASSERT(!buffer || !image);
    956 
    957 	if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
    958 	{
    959 		const vk::VkImportMemoryFdInfoKHR			importInfo		=
    960 		{
    961 			vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
    962 			DE_NULL,
    963 			externalType,
    964 			handle.getFd()
    965 		};
    966 		const vk::VkMemoryDedicatedAllocateInfo		dedicatedInfo	=
    967 		{
    968 			vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
    969 			&importInfo,
    970 			image,
    971 			buffer,
    972 		};
    973 		const vk::VkMemoryAllocateInfo				info			=
    974 		{
    975 			vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
    976 			(isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
    977 			requirements.size,
    978 			(memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex
    979 		};
    980 		vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
    981 
    982 		handle.disown();
    983 
    984 		return memory;
    985 	}
    986 	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
    987 			|| externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
    988 	{
    989 		const vk::VkImportMemoryWin32HandleInfoKHR	importInfo		=
    990 		{
    991 			vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
    992 			DE_NULL,
    993 			externalType,
    994 			handle.getWin32Handle(),
    995 			DE_NULL
    996 		};
    997 		const vk::VkMemoryDedicatedAllocateInfo		dedicatedInfo	=
    998 		{
    999 			vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
   1000 			&importInfo,
   1001 			image,
   1002 			buffer,
   1003 		};
   1004 		const vk::VkMemoryAllocateInfo				info			=
   1005 		{
   1006 			vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
   1007 			(isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
   1008 			requirements.size,
   1009 			(memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits)  : memoryTypeIndex
   1010 		};
   1011 		vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
   1012 
   1013 		handle.disown();
   1014 
   1015 		return memory;
   1016 	}
   1017 #if defined(USE_ANDROID_O_HARDWARE_BUFFER)
   1018 	else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
   1019 	{
   1020 		AHardwareBuffer_Desc desc;
   1021 		AHardwareBuffer_describe(static_cast<const AHardwareBuffer*>(handle.getAndroidHardwareBuffer().internal), &desc);
   1022 
   1023 		DE_ASSERT(desc.format == AHARDWAREBUFFER_FORMAT_BLOB || image != 0);
   1024 
   1025 		vk::VkImportAndroidHardwareBufferInfoANDROID	importInfo =
   1026 		{
   1027 			vk::VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
   1028 			DE_NULL,
   1029 			handle.getAndroidHardwareBuffer()
   1030 		};
   1031 		const vk::VkMemoryDedicatedAllocateInfo		dedicatedInfo =
   1032 		{
   1033 			vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
   1034 			&importInfo,
   1035 			image,
   1036 			buffer,
   1037 		};
   1038 		const vk::VkMemoryAllocateInfo					info =
   1039 		{
   1040 			vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
   1041 			(isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
   1042 			requirements.size,
   1043 			(memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits)  : memoryTypeIndex
   1044 		};
   1045 		vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
   1046 
   1047 		return memory;
   1048 	}
   1049 #endif // (USE_ANDROID_O_HARDWARE_BUFFER)
   1050 	else
   1051 	{
   1052 		DE_FATAL("Unknown external memory type");
   1053 		return vk::Move<vk::VkDeviceMemory>();
   1054 	}
   1055 }
   1056 
   1057 vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface&					vkd,
   1058 										   vk::VkDevice									device,
   1059 										   const vk::VkMemoryRequirements&				requirements,
   1060 										   vk::VkExternalMemoryHandleTypeFlagBits		externalType,
   1061 										   deUint32										memoryTypeIndex,
   1062 										   NativeHandle&								handle)
   1063 {
   1064 	return importMemory(vkd, device, (vk::VkBuffer)0, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle);
   1065 }
   1066 
   1067 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface&					vkd,
   1068 													vk::VkDevice								device,
   1069 													vk::VkBuffer								buffer,
   1070 													const vk::VkMemoryRequirements&				requirements,
   1071 													vk::VkExternalMemoryHandleTypeFlagBits		externalType,
   1072 													deUint32									memoryTypeIndex,
   1073 													NativeHandle&								handle)
   1074 {
   1075 	return importMemory(vkd, device, buffer, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle);
   1076 }
   1077 
   1078 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface&					vkd,
   1079 													vk::VkDevice								device,
   1080 													vk::VkImage									image,
   1081 													const vk::VkMemoryRequirements&				requirements,
   1082 													vk::VkExternalMemoryHandleTypeFlagBits		externalType,
   1083 													deUint32									memoryTypeIndex,
   1084 													NativeHandle&								handle)
   1085 {
   1086 	return importMemory(vkd, device, (vk::VkBuffer)0, image, requirements, externalType, memoryTypeIndex, handle);
   1087 }
   1088 
   1089 vk::Move<vk::VkBuffer> createExternalBuffer (const vk::DeviceInterface&					vkd,
   1090 											 vk::VkDevice								device,
   1091 											 deUint32									queueFamilyIndex,
   1092 											 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
   1093 											 vk::VkDeviceSize							size,
   1094 											 vk::VkBufferCreateFlags					createFlags,
   1095 											 vk::VkBufferUsageFlags						usageFlags)
   1096 {
   1097 	const vk::VkExternalMemoryBufferCreateInfo			externalCreateInfo	=
   1098 	{
   1099 		vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
   1100 		DE_NULL,
   1101 		(vk::VkExternalMemoryHandleTypeFlags)externalType
   1102 	};
   1103 	const vk::VkBufferCreateInfo						createInfo			=
   1104 	{
   1105 		vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
   1106 		&externalCreateInfo,
   1107 		createFlags,
   1108 		size,
   1109 		usageFlags,
   1110 		vk::VK_SHARING_MODE_EXCLUSIVE,
   1111 		1u,
   1112 		&queueFamilyIndex
   1113 	};
   1114 
   1115 	return vk::createBuffer(vkd, device, &createInfo);
   1116 }
   1117 
   1118 vk::Move<vk::VkImage> createExternalImage (const vk::DeviceInterface&					vkd,
   1119 										   vk::VkDevice									device,
   1120 										   deUint32										queueFamilyIndex,
   1121 										   vk::VkExternalMemoryHandleTypeFlagBits		externalType,
   1122 										   vk::VkFormat									format,
   1123 										   deUint32										width,
   1124 										   deUint32										height,
   1125 										   vk::VkImageTiling							tiling,
   1126 										   vk::VkImageCreateFlags						createFlags,
   1127 										   vk::VkImageUsageFlags						usageFlags,
   1128 										   deUint32 mipLevels,
   1129 										   deUint32 arrayLayers)
   1130 {
   1131 	const vk::VkExternalMemoryImageCreateInfo		externalCreateInfo	=
   1132 	{
   1133 		vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
   1134 		DE_NULL,
   1135 		(vk::VkExternalMemoryHandleTypeFlags)externalType
   1136 	};
   1137 	const vk::VkImageCreateInfo						createInfo			=
   1138 	{
   1139 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
   1140 		&externalCreateInfo,
   1141 		createFlags,
   1142 		vk::VK_IMAGE_TYPE_2D,
   1143 		format,
   1144 		{ width, height, 1u, },
   1145 		mipLevels,
   1146 		arrayLayers,
   1147 		vk::VK_SAMPLE_COUNT_1_BIT,
   1148 		tiling,
   1149 		usageFlags,
   1150 		vk::VK_SHARING_MODE_EXCLUSIVE,
   1151 		1,
   1152 		&queueFamilyIndex,
   1153 		vk::VK_IMAGE_LAYOUT_UNDEFINED
   1154 	};
   1155 
   1156 	return vk::createImage(vkd, device, &createInfo);
   1157 }
   1158 
   1159 } // ExternalMemoryUtil
   1160 } // vkt
   1161