Home | History | Annotate | Download | only in api
      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 API tests
     20  *//*--------------------------------------------------------------------*/
     21 
     22 #include "vktApiExternalMemoryTests.hpp"
     23 
     24 #include "vktTestCaseUtil.hpp"
     25 #include "vkRefUtil.hpp"
     26 #include "vkDeviceUtil.hpp"
     27 #include "vkQueryUtil.hpp"
     28 #include "vkPlatform.hpp"
     29 #include "vkMemUtil.hpp"
     30 #include "vkApiVersion.hpp"
     31 
     32 #include "tcuTestLog.hpp"
     33 
     34 #include "deUniquePtr.hpp"
     35 #include "deStringUtil.hpp"
     36 #include "deRandom.hpp"
     37 
     38 #include "deMemory.h"
     39 
     40 #include "vktExternalMemoryUtil.hpp"
     41 
     42 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
     43 #	include <unistd.h>
     44 #	include <fcntl.h>
     45 #	include <errno.h>
     46 #	include <sys/types.h>
     47 #	include <sys/socket.h>
     48 #endif
     49 
     50 #if (DE_OS == DE_OS_WIN32)
     51 #	define WIN32_LEAN_AND_MEAN
     52 #	include <windows.h>
     53 #	include <Dxgi1_2.h>
     54 #endif
     55 
     56 #if (DE_OS == DE_OS_ANDROID) && defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
     57 #	define USE_ANDROID_O_HARDWARE_BUFFER
     58 #endif
     59 
     60 #if (DE_OS == DE_OS_ANDROID) && defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__)
     61 #	define USE_ANDROID_P_HARDWARE_BUFFER
     62 #endif
     63 
     64 #if defined(USE_ANDROID_O_HARDWARE_BUFFER)
     65 #	include <android/hardware_buffer.h>
     66 #endif
     67 
     68 using tcu::TestLog;
     69 using namespace vkt::ExternalMemoryUtil;
     70 
     71 namespace vkt
     72 {
     73 namespace api
     74 {
     75 namespace
     76 {
     77 
     78 
     79 std::string getFormatCaseName (vk::VkFormat format)
     80 {
     81 	return de::toLower(de::toString(getFormatStr(format)).substr(10));
     82 }
     83 
     84 vk::VkMemoryDedicatedRequirements getMemoryDedicatedRequirements (const vk::DeviceInterface&	vkd,
     85 																  vk::VkDevice					device,
     86 																  vk::VkBuffer					buffer)
     87 {
     88 	const vk::VkBufferMemoryRequirementsInfo2	requirementInfo			=
     89 	{
     90 		vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
     91 		DE_NULL,
     92 		buffer
     93 	};
     94 	vk::VkMemoryDedicatedRequirements			dedicatedRequirements	=
     95 	{
     96 		vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
     97 		DE_NULL,
     98 		VK_FALSE,
     99 		VK_FALSE
    100 	};
    101 	vk::VkMemoryRequirements2					requirements			=
    102 	{
    103 		vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
    104 		&dedicatedRequirements,
    105 		{ 0u, 0u, 0u }
    106 	};
    107 
    108 	vkd.getBufferMemoryRequirements2(device, &requirementInfo, &requirements);
    109 
    110 	return dedicatedRequirements;
    111 }
    112 
    113 vk::VkMemoryDedicatedRequirements getMemoryDedicatedRequirements (const vk::DeviceInterface&	vkd,
    114 																  vk::VkDevice					device,
    115 																  vk::VkImage					image)
    116 {
    117 	const vk::VkImageMemoryRequirementsInfo2	requirementInfo		=
    118 	{
    119 		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
    120 		DE_NULL,
    121 		image
    122 	};
    123 	vk::VkMemoryDedicatedRequirements		dedicatedRequirements	=
    124 	{
    125 		vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
    126 		DE_NULL,
    127 		VK_FALSE,
    128 		VK_FALSE
    129 	};
    130 	vk::VkMemoryRequirements2				requirements			=
    131 	{
    132 		vk::VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
    133 		&dedicatedRequirements,
    134 		{ 0u, 0u, 0u }
    135 	};
    136 
    137 	vkd.getImageMemoryRequirements2(device, &requirementInfo, &requirements);
    138 
    139 	return dedicatedRequirements;
    140 }
    141 
    142 void writeHostMemory (const vk::DeviceInterface&	vkd,
    143 					  vk::VkDevice					device,
    144 					  vk::VkDeviceMemory			memory,
    145 					  size_t						size,
    146 					  const void*					data)
    147 {
    148 	void* const ptr = vk::mapMemory(vkd, device, memory, 0, size, 0);
    149 
    150 	deMemcpy(ptr, data, size);
    151 
    152 	flushMappedMemoryRange(vkd, device, memory, 0, size);
    153 
    154 	vkd.unmapMemory(device, memory);
    155 }
    156 
    157 void checkHostMemory (const vk::DeviceInterface&	vkd,
    158 					  vk::VkDevice					device,
    159 					  vk::VkDeviceMemory			memory,
    160 					  size_t						size,
    161 					  const void*					data)
    162 {
    163 	void* const ptr = vk::mapMemory(vkd, device, memory, 0, size, 0);
    164 
    165 	invalidateMappedMemoryRange(vkd, device, memory, 0, size);
    166 
    167 	if (deMemCmp(ptr, data, size) != 0)
    168 		TCU_FAIL("Memory contents don't match");
    169 
    170 	vkd.unmapMemory(device, memory);
    171 }
    172 
    173 std::vector<deUint8> genTestData (deUint32 seed, size_t size)
    174 {
    175 	de::Random				rng		(seed);
    176 	std::vector<deUint8>	data	(size);
    177 
    178 	for (size_t ndx = 0; ndx < size; ndx++)
    179 	{
    180 		data[ndx] = rng.getUint8();
    181 	}
    182 
    183 	return data;
    184 }
    185 
    186 deUint32 chooseQueueFamilyIndex (const vk::InstanceInterface&	vki,
    187 								 vk::VkPhysicalDevice			device,
    188 								 vk::VkQueueFlags				requireFlags)
    189 {
    190 	const std::vector<vk::VkQueueFamilyProperties> properties (vk::getPhysicalDeviceQueueFamilyProperties(vki, device));
    191 
    192 	for (deUint32 queueFamilyIndex = 0; queueFamilyIndex < (deUint32)properties.size(); queueFamilyIndex++)
    193 	{
    194 		if ((properties[queueFamilyIndex].queueFlags & requireFlags) == requireFlags)
    195 			return queueFamilyIndex;
    196 	}
    197 
    198 	TCU_THROW(NotSupportedError, "Queue type not supported");
    199 }
    200 
    201 std::vector<std::string> getInstanceExtensions (const deUint32 instanceVersion,
    202 												const vk::VkExternalSemaphoreHandleTypeFlags	externalSemaphoreTypes,
    203 												const vk::VkExternalMemoryHandleTypeFlags		externalMemoryTypes,
    204 												const vk::VkExternalFenceHandleTypeFlags		externalFenceTypes)
    205 {
    206 	std::vector<std::string> instanceExtensions;
    207 
    208 	if (!vk::isCoreInstanceExtension(instanceVersion, "VK_KHR_get_physical_device_properties2"))
    209 		instanceExtensions.push_back("VK_KHR_get_physical_device_properties2");
    210 
    211 	if (externalSemaphoreTypes != 0)
    212 		if (!vk::isCoreInstanceExtension(instanceVersion, "VK_KHR_external_semaphore_capabilities"))
    213 			instanceExtensions.push_back("VK_KHR_external_semaphore_capabilities");
    214 
    215 	if (externalMemoryTypes != 0)
    216 		if (!vk::isCoreInstanceExtension(instanceVersion, "VK_KHR_external_memory_capabilities"))
    217 			instanceExtensions.push_back("VK_KHR_external_memory_capabilities");
    218 
    219 	if (externalFenceTypes != 0)
    220 		if (!vk::isCoreInstanceExtension(instanceVersion, "VK_KHR_external_fence_capabilities"))
    221 			instanceExtensions.push_back("VK_KHR_external_fence_capabilities");
    222 
    223 	return instanceExtensions;
    224 }
    225 
    226 vk::Move<vk::VkInstance> createInstance (const vk::PlatformInterface&					vkp,
    227 										 const deUint32									version,
    228 										 const vk::VkExternalSemaphoreHandleTypeFlags	externalSemaphoreTypes,
    229 										 const vk::VkExternalMemoryHandleTypeFlags		externalMemoryTypes,
    230 										 const vk::VkExternalFenceHandleTypeFlags		externalFenceTypes)
    231 {
    232 	try
    233 	{
    234 		return vk::createDefaultInstance(vkp, version, std::vector<std::string>(), getInstanceExtensions(version, externalSemaphoreTypes, externalMemoryTypes, externalFenceTypes));
    235 	}
    236 	catch (const vk::Error& error)
    237 	{
    238 		if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
    239 			TCU_THROW(NotSupportedError, "Required extensions not supported");
    240 
    241 		throw;
    242 	}
    243 }
    244 
    245 vk::Move<vk::VkDevice> createDevice (const deUint32									apiVersion,
    246 									 const vk::InstanceInterface&					vki,
    247 									 vk::VkPhysicalDevice							physicalDevice,
    248 									 const vk::VkExternalSemaphoreHandleTypeFlags	externalSemaphoreTypes,
    249 									 const vk::VkExternalMemoryHandleTypeFlags		externalMemoryTypes,
    250 									 const vk::VkExternalFenceHandleTypeFlags		externalFenceTypes,
    251 									 deUint32										queueFamilyIndex,
    252 									 bool											useDedicatedAllocs = false)
    253 {
    254 	std::vector<const char*>	deviceExtensions;
    255 
    256 	if ((externalSemaphoreTypes
    257 			& (vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
    258 				| vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)) != 0)
    259 	{
    260 		deviceExtensions.push_back("VK_KHR_external_semaphore_fd");
    261 	}
    262 
    263 	if ((externalFenceTypes
    264 			& (vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
    265 				| vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)) != 0)
    266 	{
    267 		deviceExtensions.push_back("VK_KHR_external_fence_fd");
    268 	}
    269 
    270 	if (useDedicatedAllocs)
    271 	{
    272 		if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_dedicated_allocation"))
    273 			deviceExtensions.push_back("VK_KHR_dedicated_allocation");
    274 		if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_get_memory_requirements2"))
    275 			deviceExtensions.push_back("VK_KHR_get_memory_requirements2");
    276 	}
    277 
    278 	if ((externalMemoryTypes
    279 			& vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) != 0)
    280 	{
    281 		deviceExtensions.push_back("VK_KHR_external_memory_fd");
    282 	}
    283 
    284 	if ((externalSemaphoreTypes
    285 			& (vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
    286 				| vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)) != 0)
    287 	{
    288 		deviceExtensions.push_back("VK_KHR_external_semaphore_win32");
    289 	}
    290 
    291 	if ((externalFenceTypes
    292 			& (vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
    293 				| vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)) != 0)
    294 	{
    295 		deviceExtensions.push_back("VK_KHR_external_fence_win32");
    296 	}
    297 
    298 	if ((externalMemoryTypes
    299 			& (vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
    300 			   | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT
    301 			   | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT
    302 			   | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT
    303 			   | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT
    304 			   | vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT)) != 0)
    305 	{
    306 		deviceExtensions.push_back("VK_KHR_external_memory_win32");
    307 	}
    308 
    309 	if ((externalMemoryTypes
    310 			& vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) != 0)
    311 	{
    312 		deviceExtensions.push_back("VK_ANDROID_external_memory_android_hardware_buffer");
    313 	}
    314 
    315 	const float								priority				= 0.5f;
    316 	const vk::VkDeviceQueueCreateInfo		queues[]				=
    317 	{
    318 		{
    319 			vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
    320 			DE_NULL,
    321 			0u,
    322 
    323 			queueFamilyIndex,
    324 			1u,
    325 			&priority
    326 		}
    327 	};
    328 	const vk::VkDeviceCreateInfo			deviceCreateInfo		=
    329 	{
    330 		vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
    331 		DE_NULL,
    332 		0u,
    333 
    334 		DE_LENGTH_OF_ARRAY(queues),
    335 		queues,
    336 
    337 		0u,
    338 		DE_NULL,
    339 
    340 		(deUint32)deviceExtensions.size(),
    341 		deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0],
    342 		DE_NULL
    343 	};
    344 
    345 	try
    346 	{
    347 		return vk::createDevice(vki, physicalDevice, &deviceCreateInfo);
    348 	}
    349 	catch (const vk::Error& error)
    350 	{
    351 		if (error.getError() == vk::VK_ERROR_EXTENSION_NOT_PRESENT)
    352 			TCU_THROW(NotSupportedError, "Required extensions not supported");
    353 
    354 		throw;
    355 	}
    356 }
    357 
    358 vk::VkQueue getQueue (const vk::DeviceInterface&	vkd,
    359 					  vk::VkDevice					device,
    360 					  deUint32						queueFamilyIndex)
    361 {
    362 	vk::VkQueue queue;
    363 
    364 	vkd.getDeviceQueue(device, queueFamilyIndex, 0, &queue);
    365 
    366 	return queue;
    367 }
    368 
    369 void checkSemaphoreSupport (const vk::InstanceInterface&				vki,
    370 							vk::VkPhysicalDevice						device,
    371 							vk::VkExternalSemaphoreHandleTypeFlagBits	externalType)
    372 {
    373 	const vk::VkPhysicalDeviceExternalSemaphoreInfo	info		=
    374 	{
    375 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
    376 		DE_NULL,
    377 		externalType
    378 	};
    379 	vk::VkExternalSemaphoreProperties				properties	=
    380 	{
    381 		vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
    382 		DE_NULL,
    383 		0u,
    384 		0u,
    385 		0u
    386 	};
    387 
    388 	vki.getPhysicalDeviceExternalSemaphoreProperties(device, &info, &properties);
    389 
    390 	if ((properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) == 0)
    391 		TCU_THROW(NotSupportedError, "Semaphore doesn't support exporting in external type");
    392 
    393 	if ((properties.externalSemaphoreFeatures & vk::VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT) == 0)
    394 		TCU_THROW(NotSupportedError, "Semaphore doesn't support importing in external type");
    395 }
    396 
    397 void checkFenceSupport (const vk::InstanceInterface&			vki,
    398 						vk::VkPhysicalDevice					device,
    399 						vk::VkExternalFenceHandleTypeFlagBits	externalType)
    400 {
    401 	const vk::VkPhysicalDeviceExternalFenceInfo	info		=
    402 	{
    403 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
    404 		DE_NULL,
    405 		externalType
    406 	};
    407 	vk::VkExternalFenceProperties				properties	=
    408 	{
    409 		vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
    410 		DE_NULL,
    411 		0u,
    412 		0u,
    413 		0u
    414 	};
    415 
    416 	vki.getPhysicalDeviceExternalFenceProperties(device, &info, &properties);
    417 
    418 	if ((properties.externalFenceFeatures & vk::VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT) == 0)
    419 		TCU_THROW(NotSupportedError, "Fence doesn't support exporting in external type");
    420 
    421 	if ((properties.externalFenceFeatures & vk::VK_EXTERNAL_FENCE_FEATURE_IMPORTABLE_BIT) == 0)
    422 		TCU_THROW(NotSupportedError, "Fence doesn't support importing in external type");
    423 }
    424 
    425 void checkBufferSupport (const vk::InstanceInterface&				vki,
    426 						 vk::VkPhysicalDevice						device,
    427 						 vk::VkExternalMemoryHandleTypeFlagBits		externalType,
    428 						 vk::VkBufferViewCreateFlags				createFlag,
    429 						 vk::VkBufferUsageFlags						usageFlag,
    430 						 bool										dedicated)
    431 {
    432 	const vk::VkPhysicalDeviceExternalBufferInfo	info		=
    433 	{
    434 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
    435 		DE_NULL,
    436 
    437 		createFlag,
    438 		usageFlag,
    439 		externalType
    440 	};
    441 	vk::VkExternalBufferProperties					properties	=
    442 	{
    443 		vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
    444 		DE_NULL,
    445 
    446 		{ 0u, 0u, 0u }
    447 	};
    448 
    449 	vki.getPhysicalDeviceExternalBufferProperties(device, &info, &properties);
    450 
    451 	if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) == 0)
    452 		TCU_THROW(NotSupportedError, "External handle type doesn't support exporting buffer");
    453 
    454 	if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0)
    455 		TCU_THROW(NotSupportedError, "External handle type doesn't support importing buffer");
    456 
    457 	if (!dedicated && (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0)
    458 		TCU_THROW(NotSupportedError, "External handle type requires dedicated allocation");
    459 }
    460 
    461 void checkImageSupport (const vk::InstanceInterface&						vki,
    462 						 vk::VkPhysicalDevice								device,
    463 						 vk::VkExternalMemoryHandleTypeFlagBits				externalType,
    464 						 vk::VkImageViewCreateFlags							createFlag,
    465 						 vk::VkImageUsageFlags								usageFlag,
    466 						 vk::VkFormat										format,
    467 						 vk::VkImageTiling									tiling,
    468 						 bool												dedicated)
    469 {
    470 	const vk::VkPhysicalDeviceExternalImageFormatInfo	externalInfo		=
    471 	{
    472 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
    473 		DE_NULL,
    474 		externalType
    475 	};
    476 	const vk::VkPhysicalDeviceImageFormatInfo2			info				=
    477 	{
    478 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
    479 		&externalInfo,
    480 
    481 		format,
    482 		vk::VK_IMAGE_TYPE_2D,
    483 		tiling,
    484 		usageFlag,
    485 		createFlag,
    486 	};
    487 	vk::VkExternalImageFormatProperties					externalProperties	=
    488 	{
    489 		vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
    490 		DE_NULL,
    491 		{ 0u, 0u, 0u }
    492 	};
    493 	vk::VkImageFormatProperties2						properties			=
    494 	{
    495 		vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
    496 		&externalProperties,
    497 		{
    498 			{ 0u, 0u, 0u },
    499 			0u,
    500 			0u,
    501 			0u,
    502 			0u
    503 		}
    504 	};
    505 
    506 	vki.getPhysicalDeviceImageFormatProperties2(device, &info, &properties);
    507 
    508 	if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) == 0)
    509 		TCU_THROW(NotSupportedError, "External handle type doesn't support exporting image");
    510 
    511 	if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0)
    512 		TCU_THROW(NotSupportedError, "External handle type doesn't support importing image");
    513 
    514 	if (!dedicated && (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0)
    515 		TCU_THROW(NotSupportedError, "External handle type requires dedicated allocation");
    516 }
    517 
    518 void submitDummySignal (const vk::DeviceInterface&	vkd,
    519 						vk::VkQueue					queue,
    520 						vk::VkSemaphore				semaphore)
    521 {
    522 	const vk::VkSubmitInfo submit =
    523 	{
    524 		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
    525 		DE_NULL,
    526 
    527 		0u,
    528 		DE_NULL,
    529 		DE_NULL,
    530 
    531 		0u,
    532 		DE_NULL,
    533 
    534 		1u,
    535 		&semaphore
    536 	};
    537 
    538 	VK_CHECK(vkd.queueSubmit(queue, 1, &submit, (vk::VkFence)0u));
    539 }
    540 
    541 void submitDummySignalAndGetSemaphoreNative (	const vk::DeviceInterface&						vk,
    542 												vk::VkDevice									device,
    543 												vk::VkQueue										queue,
    544 												deUint32										queueFamilyIndex,
    545 												vk::VkSemaphore									semaphore,
    546 												vk::VkExternalSemaphoreHandleTypeFlagBits		externalType,
    547 												NativeHandle&									nativeHandle)
    548 {
    549 	const vk::Unique<vk::VkCommandPool>		cmdPool(createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex, DE_NULL));
    550 	const vk::Unique<vk::VkCommandBuffer>	cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
    551 
    552 	const vk::VkEventCreateInfo eventCreateInfo =
    553 	{
    554 		vk::VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
    555 		DE_NULL,
    556 		0u
    557 	};
    558 
    559 	const vk::Unique<vk::VkEvent> event(createEvent(vk, device, &eventCreateInfo, DE_NULL));
    560 
    561 	const vk::VkCommandBufferBeginInfo cmdBufferBeginInfo =
    562 	{
    563 		vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
    564 		DE_NULL,
    565 		vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
    566 		DE_NULL,
    567 	};
    568 
    569 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
    570 	/*
    571 		The submitDummySignal function calls vkQueueSubmit with an empty VkSubmitInfo structure and a
    572 		VkSemaphore to be signalled when the work is finished. Because there is no work in the submission, vkQueueSubmit
    573 		may signal the semaphore immediately. When a semaphore's file descriptor is obtained using vkGetFenceFdKHR, if the
    574 		handle type is VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR, vkGetFenceFdKHR is allowed to return -1 if the fence
    575 		is already signalled, instead of a file descriptor, . In order to make sure that a valid file descriptor is returned
    576 		we use vkCmdWaitEvents to make sure that vkQueueSubmit doesn't signal the fence.
    577 	*/
    578 	vk.cmdWaitEvents(*cmdBuffer, 1, &event.get(), vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL);
    579 	vk.endCommandBuffer(*cmdBuffer);
    580 
    581 	const vk::VkSubmitInfo submit =
    582 	{
    583 		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
    584 		DE_NULL,
    585 
    586 		0u,
    587 		DE_NULL,
    588 		DE_NULL,
    589 
    590 		1u,
    591 		&cmdBuffer.get(),
    592 
    593 		1u,
    594 		&semaphore
    595 	};
    596 
    597 	VK_CHECK(vk.queueSubmit(queue, 1, &submit, (vk::VkFence)0u));
    598 
    599 	getSemaphoreNative(vk, device, semaphore, externalType, nativeHandle);
    600 
    601 	VK_CHECK(vk.setEvent(device, *event));
    602 
    603 	VK_CHECK(vk.queueWaitIdle(queue));
    604 }
    605 
    606 void submitDummyWait (const vk::DeviceInterface&	vkd,
    607 					  vk::VkQueue					queue,
    608 					  vk::VkSemaphore				semaphore)
    609 {
    610 	const vk::VkPipelineStageFlags	stage	= vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
    611 	const vk::VkSubmitInfo			submit	=
    612 	{
    613 		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
    614 		DE_NULL,
    615 
    616 		1u,
    617 		&semaphore,
    618 		&stage,
    619 
    620 		0u,
    621 		DE_NULL,
    622 
    623 		0u,
    624 		DE_NULL,
    625 	};
    626 
    627 	VK_CHECK(vkd.queueSubmit(queue, 1, &submit, (vk::VkFence)0u));
    628 }
    629 
    630 void submitDummySignal (const vk::DeviceInterface&	vkd,
    631 						vk::VkQueue					queue,
    632 						vk::VkFence					fence)
    633 {
    634 	const vk::VkSubmitInfo submit =
    635 	{
    636 		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
    637 		DE_NULL,
    638 
    639 		0u,
    640 		DE_NULL,
    641 		DE_NULL,
    642 
    643 		0u,
    644 		DE_NULL,
    645 
    646 		0u,
    647 		DE_NULL
    648 	};
    649 
    650 	VK_CHECK(vkd.queueSubmit(queue, 1, &submit, fence));
    651 }
    652 
    653 void submitDummySignalAndGetFenceNative (	const vk::DeviceInterface&					vk,
    654 											vk::VkDevice								device,
    655 											vk::VkQueue									queue,
    656 											deUint32									queueFamilyIndex,
    657 											vk::VkFence									fence,
    658 											vk::VkExternalFenceHandleTypeFlagBits		externalType,
    659 											NativeHandle&								nativeHandle)
    660 {
    661 	const vk::Unique<vk::VkCommandPool>		cmdPool(createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex, DE_NULL));
    662 	const vk::Unique<vk::VkCommandBuffer>	cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
    663 
    664 	const vk::VkEventCreateInfo eventCreateInfo =
    665 	{
    666 		vk::VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,
    667 		DE_NULL,
    668 		0u
    669 	};
    670 
    671 	const vk::Unique<vk::VkEvent> event(createEvent(vk, device, &eventCreateInfo, DE_NULL));
    672 
    673 	const vk::VkCommandBufferBeginInfo cmdBufferBeginInfo =
    674 	{
    675 		vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
    676 		DE_NULL,
    677 		vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
    678 		DE_NULL,
    679 	};
    680 
    681 	VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
    682 	/*
    683 		The submitDummySignal function calls vkQueueSubmit with an empty VkSubmitInfo structure and a
    684 		VkFence to be signalled when the work is finished. Because there is no work in the submission, vkQueueSubmit
    685 		could signal the fence immediately. When a fence's file descriptor is obtained using vkGetFenceFdKHR, if the
    686 		handle type is VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR, vkGetFenceFdKHR is allowed to return -1 instead of a
    687 		file descriptor, if the fence is already signalled. In order to make sure that a valid file descriptor is returned
    688 		we use vkCmdWaitEvents to make sure that vkQueueSubmit doesn't signal the fence.
    689 	*/
    690 	vk.cmdWaitEvents(*cmdBuffer, 1, &event.get(), vk::VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL);
    691 	vk.endCommandBuffer(*cmdBuffer);
    692 
    693 	const vk::VkSubmitInfo submit =
    694 	{
    695 		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
    696 		DE_NULL,
    697 
    698 		0u,
    699 		DE_NULL,
    700 		DE_NULL,
    701 
    702 		1u,
    703 		&cmdBuffer.get(),
    704 
    705 		0u,
    706 		DE_NULL
    707 	};
    708 
    709 	VK_CHECK(vk.queueSubmit(queue, 1, &submit, fence));
    710 
    711 	getFenceNative(vk, device, fence, externalType, nativeHandle);
    712 
    713 	VK_CHECK(vk.setEvent(device, *event));
    714 
    715 	VK_CHECK(vk.queueWaitIdle(queue));
    716 }
    717 
    718 tcu::TestStatus testSemaphoreQueries (Context& context, vk::VkExternalSemaphoreHandleTypeFlagBits externalType)
    719 {
    720 	const vk::PlatformInterface&		vkp				(context.getPlatformInterface());
    721 	const vk::Unique<vk::VkInstance>	instance		(createInstance(vkp, context.getUsedApiVersion(), externalType, 0u, 0u));
    722 	const vk::InstanceDriver			vki				(vkp, *instance);
    723 	const vk::VkPhysicalDevice			device			(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
    724 
    725 	TestLog&							log				= context.getTestContext().getLog();
    726 
    727 	const vk::VkPhysicalDeviceExternalSemaphoreInfo	info		=
    728 	{
    729 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
    730 		DE_NULL,
    731 		externalType
    732 	};
    733 	vk::VkExternalSemaphoreProperties				properties	=
    734 	{
    735 		vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
    736 		DE_NULL,
    737 		0u,
    738 		0u,
    739 		0u
    740 	};
    741 
    742 	vki.getPhysicalDeviceExternalSemaphoreProperties(device, &info, &properties);
    743 	log << TestLog::Message << properties << TestLog::EndMessage;
    744 
    745 	TCU_CHECK(properties.pNext == DE_NULL);
    746 	TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES);
    747 
    748 	return tcu::TestStatus::pass("Pass");
    749 }
    750 
    751 struct SemaphoreTestConfig
    752 {
    753 													SemaphoreTestConfig	(vk::VkExternalSemaphoreHandleTypeFlagBits	externalType_,
    754 																		 Permanence										permanence_)
    755 		: externalType		(externalType_)
    756 		, permanence		(permanence_)
    757 	{
    758 	}
    759 
    760 	vk::VkExternalSemaphoreHandleTypeFlagBits	externalType;
    761 	Permanence									permanence;
    762 };
    763 
    764 tcu::TestStatus testSemaphoreWin32Create (Context&					context,
    765 										  const SemaphoreTestConfig	config)
    766 {
    767 #if (DE_OS == DE_OS_WIN32)
    768 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
    769 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
    770 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
    771 	const vk::InstanceDriver			vki					(vkp, *instance);
    772 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
    773 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
    774 
    775 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
    776 
    777 	{
    778 		const vk::Unique<vk::VkDevice>					device			(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
    779 		const vk::DeviceDriver							vkd				(vki, *device);
    780 		const vk::VkQueue								queue			(getQueue(vkd, *device, queueFamilyIndex));
    781 		const vk::VkExportSemaphoreWin32HandleInfoKHR	win32ExportInfo	=
    782 		{
    783 			vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR,
    784 			DE_NULL,
    785 
    786 			(vk::pt::Win32SecurityAttributesPtr)DE_NULL,
    787 			DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
    788 			DE_NULL
    789 		};
    790 		const vk::VkExportSemaphoreCreateInfo			exportCreateInfo=
    791 		{
    792 			vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
    793 			&win32ExportInfo,
    794 			(vk::VkExternalMemoryHandleTypeFlags)config.externalType
    795 		};
    796 		const vk::VkSemaphoreCreateInfo					createInfo		=
    797 		{
    798 			vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
    799 			&exportCreateInfo,
    800 			0u
    801 		};
    802 		const vk::Unique<vk::VkSemaphore>				semaphore		(vk::createSemaphore(vkd, *device, &createInfo));
    803 
    804 		if (transference == TRANSFERENCE_COPY)
    805 			submitDummySignal(vkd, queue, *semaphore);
    806 
    807 		NativeHandle									handleA;
    808 		getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handleA);
    809 
    810 		{
    811 			const vk::VkSemaphoreImportFlags			flags			= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
    812 			const vk::Unique<vk::VkSemaphore>			semaphoreA		(createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
    813 
    814 			if (transference == TRANSFERENCE_COPY)
    815 				submitDummyWait(vkd, queue, *semaphoreA);
    816 			else if (transference == TRANSFERENCE_REFERENCE)
    817 			{
    818 				submitDummySignal(vkd, queue, *semaphore);
    819 				submitDummyWait(vkd, queue, *semaphoreA);
    820 			}
    821 			else
    822 				DE_FATAL("Unknown transference.");
    823 
    824 			VK_CHECK(vkd.queueWaitIdle(queue));
    825 		}
    826 
    827 		return tcu::TestStatus::pass("Pass");
    828 	}
    829 #else
    830 	DE_UNREF(context);
    831 	DE_UNREF(config);
    832 	TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
    833 #endif
    834 }
    835 
    836 tcu::TestStatus testSemaphoreImportTwice (Context&					context,
    837 										  const SemaphoreTestConfig	config)
    838 {
    839 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
    840 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
    841 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
    842 	const vk::InstanceDriver			vki					(vkp, *instance);
    843 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
    844 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
    845 
    846 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
    847 
    848 	{
    849 		const vk::Unique<vk::VkDevice>		device			(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
    850 		const vk::DeviceDriver				vkd				(vki, *device);
    851 		const vk::VkQueue					queue			(getQueue(vkd, *device, queueFamilyIndex));
    852 		const vk::Unique<vk::VkSemaphore>	semaphore		(createExportableSemaphore(vkd, *device, config.externalType));
    853 		NativeHandle						handleA;
    854 
    855 		if (transference == TRANSFERENCE_COPY)
    856 			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphore, config.externalType, handleA);
    857 		else
    858 			getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handleA);
    859 
    860 		{
    861 			NativeHandle						handleB		(handleA);
    862 			const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
    863 			const vk::Unique<vk::VkSemaphore>	semaphoreA	(createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
    864 			const vk::Unique<vk::VkSemaphore>	semaphoreB	(createAndImportSemaphore(vkd, *device, config.externalType, handleB, flags));
    865 
    866 			if (transference == TRANSFERENCE_COPY)
    867 				submitDummyWait(vkd, queue, *semaphoreA);
    868 			else if (transference == TRANSFERENCE_REFERENCE)
    869 			{
    870 				submitDummySignal(vkd, queue, *semaphoreA);
    871 				submitDummyWait(vkd, queue, *semaphoreB);
    872 			}
    873 			else
    874 				DE_FATAL("Unknown transference.");
    875 
    876 			VK_CHECK(vkd.queueWaitIdle(queue));
    877 		}
    878 
    879 		return tcu::TestStatus::pass("Pass");
    880 	}
    881 }
    882 
    883 tcu::TestStatus testSemaphoreImportReimport (Context&					context,
    884 											 const SemaphoreTestConfig	config)
    885 {
    886 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
    887 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
    888 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
    889 	const vk::InstanceDriver			vki					(vkp, *instance);
    890 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
    891 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
    892 
    893 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
    894 
    895 	{
    896 		const vk::Unique<vk::VkDevice>		device			(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
    897 		const vk::DeviceDriver				vkd				(vki, *device);
    898 		const vk::VkQueue					queue			(getQueue(vkd, *device, queueFamilyIndex));
    899 
    900 		const vk::Unique<vk::VkSemaphore>	semaphoreA		(createExportableSemaphore(vkd, *device, config.externalType));
    901 		NativeHandle						handleA;
    902 
    903 		if (transference == TRANSFERENCE_COPY)
    904 			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handleA);
    905 		else
    906 			getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handleA);
    907 
    908 		NativeHandle						handleB		(handleA);
    909 		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
    910 		const vk::Unique<vk::VkSemaphore>	semaphoreB	(createAndImportSemaphore(vkd, *device, config.externalType, handleA, flags));
    911 
    912 		importSemaphore(vkd, *device, *semaphoreB, config.externalType, handleB, flags);
    913 
    914 		if (transference == TRANSFERENCE_COPY)
    915 			submitDummyWait(vkd, queue, *semaphoreB);
    916 		else if (transference == TRANSFERENCE_REFERENCE)
    917 		{
    918 			submitDummySignal(vkd, queue, *semaphoreA);
    919 			submitDummyWait(vkd, queue, *semaphoreB);
    920 		}
    921 		else
    922 			DE_FATAL("Unknown transference.");
    923 
    924 		VK_CHECK(vkd.queueWaitIdle(queue));
    925 
    926 		return tcu::TestStatus::pass("Pass");
    927 	}
    928 }
    929 
    930 tcu::TestStatus testSemaphoreSignalExportImportWait (Context&					context,
    931 													 const SemaphoreTestConfig	config)
    932 {
    933 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
    934 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
    935 	const vk::InstanceDriver			vki					(vkp, *instance);
    936 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
    937 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
    938 
    939 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
    940 
    941 	{
    942 		const vk::Unique<vk::VkDevice>		device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
    943 		const vk::DeviceDriver				vkd					(vki, *device);
    944 		const vk::VkQueue					queue				(getQueue(vkd, *device, queueFamilyIndex));
    945 		const vk::Unique<vk::VkSemaphore>	semaphoreA			(createExportableSemaphore(vkd, *device, config.externalType));
    946 		{
    947 			NativeHandle	handle;
    948 
    949 			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle);
    950 
    951 			{
    952 				const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
    953 				const vk::Unique<vk::VkSemaphore>	semaphoreB	(createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
    954 				submitDummyWait(vkd, queue, *semaphoreB);
    955 
    956 				VK_CHECK(vkd.queueWaitIdle(queue));
    957 			}
    958 		}
    959 
    960 		return tcu::TestStatus::pass("Pass");
    961 	}
    962 }
    963 
    964 tcu::TestStatus testSemaphoreExportSignalImportWait (Context&					context,
    965 													 const SemaphoreTestConfig	config)
    966 {
    967 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
    968 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
    969 	const vk::InstanceDriver			vki					(vkp, *instance);
    970 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
    971 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
    972 	const vk::VkSemaphoreImportFlags	flags				= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
    973 
    974 	DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
    975 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
    976 
    977 	{
    978 		const vk::Unique<vk::VkDevice>		device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
    979 		const vk::DeviceDriver				vkd					(vki, *device);
    980 		const vk::VkQueue					queue				(getQueue(vkd, *device, queueFamilyIndex));
    981 
    982 		const vk::Unique<vk::VkSemaphore>	semaphoreA			(createExportableSemaphore(vkd, *device, config.externalType));
    983 		NativeHandle						handle;
    984 
    985 		getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
    986 
    987 		submitDummySignal(vkd, queue, *semaphoreA);
    988 		{
    989 			{
    990 				const vk::Unique<vk::VkSemaphore>	semaphoreB	(createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
    991 
    992 				submitDummyWait(vkd, queue, *semaphoreB);
    993 				VK_CHECK(vkd.queueWaitIdle(queue));
    994 			}
    995 		}
    996 
    997 		return tcu::TestStatus::pass("Pass");
    998 	}
    999 }
   1000 
   1001 tcu::TestStatus testSemaphoreExportImportSignalWait (Context&					context,
   1002 													 const SemaphoreTestConfig	config)
   1003 {
   1004 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1005 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
   1006 	const vk::InstanceDriver			vki					(vkp, *instance);
   1007 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1008 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1009 
   1010 	DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
   1011 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
   1012 
   1013 	{
   1014 		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
   1015 		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
   1016 		const vk::DeviceDriver				vkd			(vki, *device);
   1017 		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));
   1018 
   1019 		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
   1020 		NativeHandle						handle;
   1021 
   1022 		submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle);
   1023 
   1024 		const vk::Unique<vk::VkSemaphore>	semaphoreB	(createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
   1025 
   1026 		submitDummySignal(vkd, queue, *semaphoreA);
   1027 		submitDummyWait(vkd, queue, *semaphoreB);
   1028 
   1029 		VK_CHECK(vkd.queueWaitIdle(queue));
   1030 
   1031 		return tcu::TestStatus::pass("Pass");
   1032 	}
   1033 }
   1034 
   1035 tcu::TestStatus testSemaphoreSignalImport (Context&						context,
   1036 										   const SemaphoreTestConfig	config)
   1037 {
   1038 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1039 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1040 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
   1041 	const vk::InstanceDriver			vki					(vkp, *instance);
   1042 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1043 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1044 
   1045 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
   1046 
   1047 	{
   1048 		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
   1049 		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
   1050 		const vk::DeviceDriver				vkd			(vki, *device);
   1051 		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));
   1052 
   1053 		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
   1054 		const vk::Unique<vk::VkSemaphore>	semaphoreB	(createSemaphore(vkd, *device));
   1055 		NativeHandle						handle;
   1056 
   1057 		submitDummySignal(vkd, queue, *semaphoreB);
   1058 		VK_CHECK(vkd.queueWaitIdle(queue));
   1059 
   1060 		if (transference == TRANSFERENCE_COPY)
   1061 			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle);
   1062 		else
   1063 			getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
   1064 
   1065 		importSemaphore(vkd, *device, *semaphoreB, config.externalType, handle, flags);
   1066 
   1067 		if (transference == TRANSFERENCE_COPY)
   1068 			submitDummyWait(vkd, queue, *semaphoreB);
   1069 		else if (transference == TRANSFERENCE_REFERENCE)
   1070 		{
   1071 			submitDummySignal(vkd, queue, *semaphoreA);
   1072 			submitDummyWait(vkd, queue, *semaphoreB);
   1073 		}
   1074 		else
   1075 			DE_FATAL("Unknown transference.");
   1076 
   1077 		VK_CHECK(vkd.queueWaitIdle(queue));
   1078 
   1079 		return tcu::TestStatus::pass("Pass");
   1080 	}
   1081 }
   1082 
   1083 tcu::TestStatus testSemaphoreSignalWaitImport (Context&						context,
   1084 											   const SemaphoreTestConfig	config)
   1085 {
   1086 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1087 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1088 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
   1089 	const vk::InstanceDriver			vki					(vkp, *instance);
   1090 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1091 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1092 
   1093 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
   1094 
   1095 	{
   1096 		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
   1097 		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
   1098 		const vk::DeviceDriver				vkd			(vki, *device);
   1099 		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));
   1100 
   1101 		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
   1102 		const vk::Unique<vk::VkSemaphore>	semaphoreB	(createSemaphore(vkd, *device));
   1103 		NativeHandle						handle;
   1104 
   1105 		if (transference == TRANSFERENCE_COPY)
   1106 			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle);
   1107 		else
   1108 			getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handle);
   1109 
   1110 		submitDummySignal(vkd, queue, *semaphoreB);
   1111 		submitDummyWait(vkd, queue, *semaphoreB);
   1112 
   1113 		VK_CHECK(vkd.queueWaitIdle(queue));
   1114 
   1115 		importSemaphore(vkd, *device, *semaphoreB, config.externalType, handle, flags);
   1116 
   1117 		if (transference == TRANSFERENCE_COPY)
   1118 			submitDummyWait(vkd, queue, *semaphoreB);
   1119 		else if (transference == TRANSFERENCE_REFERENCE)
   1120 		{
   1121 			submitDummySignal(vkd, queue, *semaphoreA);
   1122 			submitDummyWait(vkd, queue, *semaphoreB);
   1123 		}
   1124 		else
   1125 			DE_FATAL("Unknown transference.");
   1126 
   1127 		VK_CHECK(vkd.queueWaitIdle(queue));
   1128 
   1129 		return tcu::TestStatus::pass("Pass");
   1130 	}
   1131 }
   1132 
   1133 tcu::TestStatus testSemaphoreMultipleExports (Context&					context,
   1134 											  const SemaphoreTestConfig	config)
   1135 {
   1136 	const size_t						exportCount			= 4 * 1024;
   1137 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1138 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1139 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
   1140 	const vk::InstanceDriver			vki					(vkp, *instance);
   1141 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1142 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1143 
   1144 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
   1145 
   1146 	{
   1147 		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
   1148 		const vk::DeviceDriver				vkd			(vki, *device);
   1149 		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));
   1150 		const vk::Unique<vk::VkSemaphore>	semaphore	(createExportableSemaphore(vkd, *device, config.externalType));
   1151 
   1152 		for (size_t exportNdx = 0; exportNdx < exportCount; exportNdx++)
   1153 		{
   1154 			NativeHandle handle;
   1155 
   1156 			if (transference == TRANSFERENCE_COPY)
   1157 				submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphore, config.externalType, handle);
   1158 			else
   1159 				getSemaphoreNative(vkd, *device, *semaphore, config.externalType, handle);
   1160 		}
   1161 
   1162 		submitDummySignal(vkd, queue, *semaphore);
   1163 		submitDummyWait(vkd, queue, *semaphore);
   1164 
   1165 		VK_CHECK(vkd.queueWaitIdle(queue));
   1166 	}
   1167 
   1168 	return tcu::TestStatus::pass("Pass");
   1169 }
   1170 
   1171 tcu::TestStatus testSemaphoreMultipleImports (Context&					context,
   1172 											  const SemaphoreTestConfig	config)
   1173 {
   1174 	const size_t						importCount			= 4 * 1024;
   1175 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1176 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1177 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
   1178 	const vk::InstanceDriver			vki					(vkp, *instance);
   1179 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1180 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1181 
   1182 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
   1183 
   1184 	{
   1185 		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
   1186 		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
   1187 		const vk::DeviceDriver				vkd			(vki, *device);
   1188 		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));
   1189 		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
   1190 		NativeHandle						handleA;
   1191 
   1192 		if (transference == TRANSFERENCE_COPY)
   1193 			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handleA);
   1194 		else
   1195 			getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, handleA);
   1196 
   1197 		for (size_t importNdx = 0; importNdx < importCount; importNdx++)
   1198 		{
   1199 			NativeHandle						handleB		(handleA);
   1200 			const vk::Unique<vk::VkSemaphore>	semaphoreB	(createAndImportSemaphore(vkd, *device, config.externalType, handleB, flags));
   1201 		}
   1202 
   1203 		if (transference == TRANSFERENCE_COPY)
   1204 		{
   1205 			importSemaphore(vkd, *device, *semaphoreA, config.externalType, handleA, flags);
   1206 			submitDummyWait(vkd, queue, *semaphoreA);
   1207 		}
   1208 		else if (transference == TRANSFERENCE_REFERENCE)
   1209 		{
   1210 			submitDummySignal(vkd, queue, *semaphoreA);
   1211 			submitDummyWait(vkd, queue, *semaphoreA);
   1212 		}
   1213 		else
   1214 			DE_FATAL("Unknown transference.");
   1215 
   1216 		VK_CHECK(vkd.queueWaitIdle(queue));
   1217 	}
   1218 
   1219 	return tcu::TestStatus::pass("Pass");
   1220 }
   1221 
   1222 tcu::TestStatus testSemaphoreTransference (Context&						context,
   1223 										   const SemaphoreTestConfig	config)
   1224 {
   1225 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1226 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1227 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
   1228 	const vk::InstanceDriver			vki					(vkp, *instance);
   1229 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1230 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1231 
   1232 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
   1233 
   1234 	{
   1235 		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
   1236 		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
   1237 		const vk::DeviceDriver				vkd			(vki, *device);
   1238 		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));
   1239 
   1240 		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
   1241 		NativeHandle						handle;
   1242 
   1243 		submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, handle);
   1244 
   1245 		{
   1246 			const vk::Unique<vk::VkSemaphore>	semaphoreB			(createAndImportSemaphore(vkd, *device, config.externalType, handle, flags));
   1247 
   1248 			if (config.permanence == PERMANENCE_PERMANENT)
   1249 			{
   1250 				if (transference == TRANSFERENCE_COPY)
   1251 				{
   1252 					submitDummySignal(vkd, queue, *semaphoreA);
   1253 					submitDummyWait(vkd, queue, *semaphoreB);
   1254 					VK_CHECK(vkd.queueWaitIdle(queue));
   1255 
   1256 					submitDummySignal(vkd, queue, *semaphoreB);
   1257 
   1258 					submitDummyWait(vkd, queue, *semaphoreA);
   1259 					submitDummyWait(vkd, queue, *semaphoreB);
   1260 					VK_CHECK(vkd.queueWaitIdle(queue));
   1261 				}
   1262 				else if (transference== TRANSFERENCE_REFERENCE)
   1263 				{
   1264 					submitDummyWait(vkd, queue, *semaphoreB);
   1265 					VK_CHECK(vkd.queueWaitIdle(queue));
   1266 
   1267 					submitDummySignal(vkd, queue, *semaphoreA);
   1268 					submitDummyWait(vkd, queue, *semaphoreB);
   1269 
   1270 					submitDummySignal(vkd, queue, *semaphoreB);
   1271 					submitDummyWait(vkd, queue, *semaphoreA);
   1272 					VK_CHECK(vkd.queueWaitIdle(queue));
   1273 				}
   1274 				else
   1275 					DE_FATAL("Unknown transference.");
   1276 			}
   1277 			else if (config.permanence == PERMANENCE_TEMPORARY)
   1278 			{
   1279 				if (transference == TRANSFERENCE_COPY)
   1280 				{
   1281 					submitDummySignal(vkd, queue, *semaphoreA);
   1282 					submitDummyWait(vkd, queue, *semaphoreB);
   1283 					VK_CHECK(vkd.queueWaitIdle(queue));
   1284 
   1285 					submitDummySignal(vkd, queue, *semaphoreB);
   1286 
   1287 					submitDummyWait(vkd, queue, *semaphoreA);
   1288 					submitDummyWait(vkd, queue, *semaphoreB);
   1289 					VK_CHECK(vkd.queueWaitIdle(queue));
   1290 				}
   1291 				else if (transference== TRANSFERENCE_REFERENCE)
   1292 				{
   1293 					submitDummyWait(vkd, queue, *semaphoreB);
   1294 					VK_CHECK(vkd.queueWaitIdle(queue));
   1295 
   1296 					submitDummySignal(vkd, queue, *semaphoreA);
   1297 					submitDummySignal(vkd, queue, *semaphoreB);
   1298 
   1299 					submitDummyWait(vkd, queue, *semaphoreB);
   1300 					submitDummyWait(vkd, queue, *semaphoreA);
   1301 					VK_CHECK(vkd.queueWaitIdle(queue));
   1302 				}
   1303 				else
   1304 					DE_FATAL("Unknown transference.");
   1305 			}
   1306 			else
   1307 				DE_FATAL("Unknown permanence.");
   1308 		}
   1309 
   1310 		return tcu::TestStatus::pass("Pass");
   1311 	}
   1312 }
   1313 
   1314 tcu::TestStatus testSemaphoreFdDup (Context&					context,
   1315 									const SemaphoreTestConfig	config)
   1316 {
   1317 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
   1318 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1319 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1320 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
   1321 	const vk::InstanceDriver			vki					(vkp, *instance);
   1322 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1323 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1324 
   1325 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
   1326 
   1327 	{
   1328 		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
   1329 		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
   1330 		const vk::DeviceDriver				vkd			(vki, *device);
   1331 		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));
   1332 
   1333 		TestLog&							log			= context.getTestContext().getLog();
   1334 		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
   1335 
   1336 		{
   1337 			NativeHandle		fd;
   1338 
   1339 			if (transference == TRANSFERENCE_COPY)
   1340 				submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, fd);
   1341 			else
   1342 				getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, fd);
   1343 
   1344 			NativeHandle		newFd	(dup(fd.getFd()));
   1345 
   1346 			if (newFd.getFd() < 0)
   1347 				log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
   1348 
   1349 			TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for semaphores fd");
   1350 
   1351 			{
   1352 				const vk::Unique<vk::VkSemaphore> semaphoreB (createAndImportSemaphore(vkd, *device, config.externalType, newFd, flags));
   1353 
   1354 				if (transference == TRANSFERENCE_COPY)
   1355 					submitDummyWait(vkd, queue, *semaphoreB);
   1356 				else if (transference == TRANSFERENCE_REFERENCE)
   1357 				{
   1358 					submitDummySignal(vkd, queue, *semaphoreA);
   1359 					submitDummyWait(vkd, queue, *semaphoreB);
   1360 				}
   1361 				else
   1362 					DE_FATAL("Unknown permanence.");
   1363 			}
   1364 		}
   1365 
   1366 		VK_CHECK(vkd.queueWaitIdle(queue));
   1367 
   1368 		return tcu::TestStatus::pass("Pass");
   1369 	}
   1370 #else
   1371 	DE_UNREF(context);
   1372 	DE_UNREF(config);
   1373 	TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
   1374 #endif
   1375 }
   1376 
   1377 tcu::TestStatus testSemaphoreFdDup2 (Context&					context,
   1378 									 const SemaphoreTestConfig	config)
   1379 {
   1380 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
   1381 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1382 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1383 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
   1384 	const vk::InstanceDriver			vki					(vkp, *instance);
   1385 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1386 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1387 
   1388 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
   1389 
   1390 	{
   1391 		const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
   1392 		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
   1393 		const vk::DeviceDriver				vkd			(vki, *device);
   1394 		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));
   1395 
   1396 		TestLog&							log			= context.getTestContext().getLog();
   1397 		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
   1398 		const vk::Unique<vk::VkSemaphore>	semaphoreB	(createExportableSemaphore(vkd, *device, config.externalType));
   1399 
   1400 		{
   1401 			NativeHandle		fd, secondFd;
   1402 
   1403 			if (transference == TRANSFERENCE_COPY)
   1404 			{
   1405 				submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, fd);
   1406 				submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreB, config.externalType, secondFd);
   1407 			}
   1408 			else
   1409 			{
   1410 				getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, fd);
   1411 				getSemaphoreNative(vkd, *device, *semaphoreB, config.externalType, secondFd);
   1412 			}
   1413 
   1414 			int					newFd		(dup2(fd.getFd(), secondFd.getFd()));
   1415 
   1416 			if (newFd < 0)
   1417 				log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
   1418 
   1419 			TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for fences fd");
   1420 
   1421 			{
   1422 				const vk::Unique<vk::VkSemaphore> semaphoreC (createAndImportSemaphore(vkd, *device, config.externalType, secondFd, flags));
   1423 
   1424 				if (transference == TRANSFERENCE_COPY)
   1425 					submitDummyWait(vkd, queue, *semaphoreC);
   1426 				else if (transference == TRANSFERENCE_REFERENCE)
   1427 				{
   1428 					submitDummySignal(vkd, queue, *semaphoreA);
   1429 					submitDummyWait(vkd, queue, *semaphoreC);
   1430 				}
   1431 				else
   1432 					DE_FATAL("Unknown permanence.");
   1433 			}
   1434 		}
   1435 
   1436 		VK_CHECK(vkd.queueWaitIdle(queue));
   1437 
   1438 		return tcu::TestStatus::pass("Pass");
   1439 	}
   1440 #else
   1441 	DE_UNREF(context);
   1442 	DE_UNREF(config);
   1443 	TCU_THROW(NotSupportedError, "Platform doesn't support dup2()");
   1444 #endif
   1445 }
   1446 
   1447 tcu::TestStatus testSemaphoreFdDup3 (Context&					context,
   1448 									 const SemaphoreTestConfig	config)
   1449 {
   1450 #if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
   1451 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1452 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1453 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
   1454 	const vk::InstanceDriver			vki					(vkp, *instance);
   1455 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1456 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1457 
   1458 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
   1459 
   1460 	{
   1461 		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
   1462 		const vk::DeviceDriver				vkd			(vki, *device);
   1463 		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));
   1464 
   1465 		TestLog&							log			= context.getTestContext().getLog();
   1466 		const vk::Unique<vk::VkSemaphore>	semaphoreA	(createExportableSemaphore(vkd, *device, config.externalType));
   1467 		const vk::Unique<vk::VkSemaphore>	semaphoreB	(createExportableSemaphore(vkd, *device, config.externalType));
   1468 
   1469 		{
   1470 			NativeHandle						fd, secondFd;
   1471 
   1472 			if (transference == TRANSFERENCE_COPY)
   1473 			{
   1474 				submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreA, config.externalType, fd);
   1475 				submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphoreB, config.externalType, secondFd);
   1476 			}
   1477 			else
   1478 			{
   1479 				getSemaphoreNative(vkd, *device, *semaphoreA, config.externalType, fd);
   1480 				getSemaphoreNative(vkd, *device, *semaphoreB, config.externalType, secondFd);
   1481 			}
   1482 
   1483 			const vk::VkSemaphoreImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
   1484 			const int							newFd		(dup3(fd.getFd(), secondFd.getFd(), 0));
   1485 
   1486 			if (newFd < 0)
   1487 				log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
   1488 
   1489 			TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for fences fd");
   1490 
   1491 			{
   1492 				const vk::Unique<vk::VkSemaphore> semaphoreC (createAndImportSemaphore(vkd, *device, config.externalType, secondFd, flags));
   1493 
   1494 				if (transference == TRANSFERENCE_COPY)
   1495 					submitDummyWait(vkd, queue, *semaphoreC);
   1496 				else if (transference == TRANSFERENCE_REFERENCE)
   1497 				{
   1498 					submitDummySignal(vkd, queue, *semaphoreA);
   1499 					submitDummyWait(vkd, queue, *semaphoreC);
   1500 				}
   1501 				else
   1502 					DE_FATAL("Unknown permanence.");
   1503 			}
   1504 		}
   1505 
   1506 		VK_CHECK(vkd.queueWaitIdle(queue));
   1507 
   1508 		return tcu::TestStatus::pass("Pass");
   1509 	}
   1510 #else
   1511 	DE_UNREF(context);
   1512 	DE_UNREF(config);
   1513 	TCU_THROW(NotSupportedError, "Platform doesn't support dup3()");
   1514 #endif
   1515 }
   1516 
   1517 tcu::TestStatus testSemaphoreFdSendOverSocket (Context&						context,
   1518 											   const SemaphoreTestConfig	config)
   1519 {
   1520 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
   1521 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1522 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1523 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), config.externalType, 0u, 0u));
   1524 	const vk::InstanceDriver			vki					(vkp, *instance);
   1525 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1526 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1527 
   1528 	checkSemaphoreSupport(vki, physicalDevice, config.externalType);
   1529 
   1530 	{
   1531 		const vk::Unique<vk::VkDevice>		device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, config.externalType, 0u, 0u, queueFamilyIndex));
   1532 		const vk::DeviceDriver				vkd			(vki, *device);
   1533 		const vk::VkQueue					queue		(getQueue(vkd, *device, queueFamilyIndex));
   1534 
   1535 		TestLog&							log			= context.getTestContext().getLog();
   1536 		const vk::Unique<vk::VkSemaphore>	semaphore	(createExportableSemaphore(vkd, *device, config.externalType));
   1537 		NativeHandle						fd;
   1538 
   1539 		if (transference == TRANSFERENCE_COPY)
   1540 			submitDummySignalAndGetSemaphoreNative(vkd, *device, queue, queueFamilyIndex, *semaphore, config.externalType, fd);
   1541 		else
   1542 			getSemaphoreNative(vkd, *device, *semaphore, config.externalType, fd);
   1543 
   1544 		{
   1545 			int sv[2];
   1546 
   1547 			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
   1548 			{
   1549 				log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
   1550 				TCU_FAIL("Failed to create socket pair");
   1551 			}
   1552 
   1553 			{
   1554 				const NativeHandle	srcSocket	(sv[0]);
   1555 				const NativeHandle	dstSocket	(sv[1]);
   1556 				std::string			sendData	("deqp");
   1557 
   1558 				// Send FD
   1559 				{
   1560 					const int			fdRaw	(fd.getFd());
   1561 					msghdr				msg;
   1562 					cmsghdr*			cmsg;
   1563 					char				buffer[CMSG_SPACE(sizeof(int))];
   1564 					iovec				iov		= { &sendData[0], sendData.length()};
   1565 
   1566 					deMemset(&msg, 0, sizeof(msg));
   1567 
   1568 					msg.msg_control		= buffer;
   1569 					msg.msg_controllen	= sizeof(buffer);
   1570 					msg.msg_iovlen		= 1;
   1571 					msg.msg_iov			= &iov;
   1572 
   1573 					cmsg				= CMSG_FIRSTHDR(&msg);
   1574 					cmsg->cmsg_level	= SOL_SOCKET;
   1575 					cmsg->cmsg_type		= SCM_RIGHTS;
   1576 					cmsg->cmsg_len		= CMSG_LEN(sizeof(int));
   1577 
   1578 					deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
   1579 					msg.msg_controllen = cmsg->cmsg_len;
   1580 
   1581 					if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
   1582 					{
   1583 						log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
   1584 						TCU_FAIL("Failed to send fd over socket");
   1585 					}
   1586 				}
   1587 
   1588 				// Recv FD
   1589 				{
   1590 					msghdr			msg;
   1591 					char			buffer[CMSG_SPACE(sizeof(int))];
   1592 					std::string		recvData	(4, '\0');
   1593 					iovec			iov			= { &recvData[0], recvData.length() };
   1594 
   1595 					deMemset(&msg, 0, sizeof(msg));
   1596 
   1597 					msg.msg_control		= buffer;
   1598 					msg.msg_controllen	= sizeof(buffer);
   1599 					msg.msg_iovlen		= 1;
   1600 					msg.msg_iov			= &iov;
   1601 
   1602 					const ssize_t	bytes = recvmsg(dstSocket.getFd(), &msg, 0);
   1603 
   1604 					if (bytes < 0)
   1605 					{
   1606 						log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
   1607 						TCU_FAIL("Failed to recv fd over socket");
   1608 
   1609 					}
   1610 					else if (bytes != (ssize_t)sendData.length())
   1611 					{
   1612 						TCU_FAIL("recvmsg() returned unpexpected number of bytes");
   1613 					}
   1614 					else
   1615 					{
   1616 						const vk::VkSemaphoreImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_SEMAPHORE_IMPORT_TEMPORARY_BIT : (vk::VkSemaphoreImportFlagBits)0u;
   1617 						const cmsghdr* const				cmsg	= CMSG_FIRSTHDR(&msg);
   1618 						int									newFd_;
   1619 						deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
   1620 						NativeHandle						newFd	(newFd_);
   1621 
   1622 						TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
   1623 						TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
   1624 						TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
   1625 						TCU_CHECK(recvData == sendData);
   1626 						TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");
   1627 
   1628 						{
   1629 							const vk::Unique<vk::VkSemaphore> newSemaphore (createAndImportSemaphore(vkd, *device, config.externalType, newFd, flags));
   1630 
   1631 							if (transference == TRANSFERENCE_COPY)
   1632 								submitDummyWait(vkd, queue, *newSemaphore);
   1633 							else if (transference == TRANSFERENCE_REFERENCE)
   1634 							{
   1635 								submitDummySignal(vkd, queue, *newSemaphore);
   1636 								submitDummyWait(vkd, queue, *newSemaphore);
   1637 							}
   1638 							else
   1639 								DE_FATAL("Unknown permanence.");
   1640 
   1641 							VK_CHECK(vkd.queueWaitIdle(queue));
   1642 						}
   1643 					}
   1644 				}
   1645 			}
   1646 		}
   1647 	}
   1648 
   1649 	return tcu::TestStatus::pass("Pass");
   1650 #else
   1651 	DE_UNREF(context);
   1652 	DE_UNREF(config);
   1653 	TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
   1654 #endif
   1655 }
   1656 
   1657 tcu::TestStatus testFenceQueries (Context& context, vk::VkExternalFenceHandleTypeFlagBits externalType)
   1658 {
   1659 	const vk::PlatformInterface&					vkp			(context.getPlatformInterface());
   1660 	const vk::Unique<vk::VkInstance>				instance	(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, externalType));
   1661 	const vk::InstanceDriver						vki			(vkp, *instance);
   1662 	const vk::VkPhysicalDevice						device		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1663 
   1664 	TestLog&										log			= context.getTestContext().getLog();
   1665 
   1666 	const vk::VkPhysicalDeviceExternalFenceInfo		info		=
   1667 	{
   1668 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
   1669 		DE_NULL,
   1670 		externalType
   1671 	};
   1672 	vk::VkExternalFenceProperties					properties	=
   1673 	{
   1674 		vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
   1675 		DE_NULL,
   1676 		0u,
   1677 		0u,
   1678 		0u
   1679 	};
   1680 
   1681 	vki.getPhysicalDeviceExternalFenceProperties(device, &info, &properties);
   1682 	log << TestLog::Message << properties << TestLog::EndMessage;
   1683 
   1684 	TCU_CHECK(properties.pNext == DE_NULL);
   1685 	TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES);
   1686 
   1687 	return tcu::TestStatus::pass("Pass");
   1688 }
   1689 
   1690 struct FenceTestConfig
   1691 {
   1692 												FenceTestConfig	(vk::VkExternalFenceHandleTypeFlagBits	externalType_,
   1693 																 Permanence									permanence_)
   1694 		: externalType		(externalType_)
   1695 		, permanence		(permanence_)
   1696 	{
   1697 	}
   1698 
   1699 	vk::VkExternalFenceHandleTypeFlagBits	externalType;
   1700 	Permanence								permanence;
   1701 };
   1702 
   1703 
   1704 tcu::TestStatus testFenceWin32Create (Context&				context,
   1705 									  const FenceTestConfig	config)
   1706 {
   1707 #if (DE_OS == DE_OS_WIN32)
   1708 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1709 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1710 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   1711 	const vk::InstanceDriver			vki					(vkp, *instance);
   1712 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1713 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1714 
   1715 	checkFenceSupport(vki, physicalDevice, config.externalType);
   1716 
   1717 	{
   1718 		const vk::Unique<vk::VkDevice>				device			(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   1719 		const vk::DeviceDriver						vkd				(vki, *device);
   1720 		const vk::VkQueue							queue			(getQueue(vkd, *device, queueFamilyIndex));
   1721 		const vk::VkExportFenceWin32HandleInfoKHR	win32ExportInfo	=
   1722 		{
   1723 			vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR,
   1724 			DE_NULL,
   1725 
   1726 			(vk::pt::Win32SecurityAttributesPtr)DE_NULL,
   1727 			DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
   1728 			DE_NULL
   1729 		};
   1730 		const vk::VkExportFenceCreateInfo			exportCreateInfo=
   1731 		{
   1732 			vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
   1733 			&win32ExportInfo,
   1734 			(vk::VkExternalFenceHandleTypeFlags)config.externalType
   1735 		};
   1736 		const vk::VkFenceCreateInfo					createInfo		=
   1737 		{
   1738 			vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
   1739 			&exportCreateInfo,
   1740 			0u
   1741 		};
   1742 		const vk::Unique<vk::VkFence>				fence			(vk::createFence(vkd, *device, &createInfo));
   1743 
   1744 		if (transference == TRANSFERENCE_COPY)
   1745 			submitDummySignal(vkd, queue, *fence);
   1746 
   1747 		NativeHandle								handleA;
   1748 		getFenceNative(vkd, *device, *fence, config.externalType, handleA);
   1749 
   1750 		{
   1751 			const vk::VkFenceImportFlags			flags			= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   1752 			const vk::Unique<vk::VkFence>			fenceA			(createAndImportFence(vkd, *device, config.externalType, handleA, flags));
   1753 
   1754 			if (transference == TRANSFERENCE_COPY)
   1755 				VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
   1756 			else if (transference == TRANSFERENCE_REFERENCE)
   1757 			{
   1758 				submitDummySignal(vkd, queue, *fence);
   1759 				VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
   1760 			}
   1761 			else
   1762 				DE_FATAL("Unknown transference.");
   1763 
   1764 			VK_CHECK(vkd.queueWaitIdle(queue));
   1765 		}
   1766 
   1767 		return tcu::TestStatus::pass("Pass");
   1768 	}
   1769 #else
   1770 	DE_UNREF(context);
   1771 	DE_UNREF(config);
   1772 	TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
   1773 #endif
   1774 }
   1775 
   1776 tcu::TestStatus testFenceImportTwice (Context&				context,
   1777 									  const FenceTestConfig	config)
   1778 {
   1779 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1780 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1781 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   1782 	const vk::InstanceDriver			vki					(vkp, *instance);
   1783 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1784 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1785 
   1786 	checkFenceSupport(vki, physicalDevice, config.externalType);
   1787 
   1788 	{
   1789 		const vk::Unique<vk::VkDevice>	device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   1790 		const vk::DeviceDriver			vkd			(vki, *device);
   1791 		const vk::VkQueue				queue		(getQueue(vkd, *device, queueFamilyIndex));
   1792 		const vk::Unique<vk::VkFence>	fence		(createExportableFence(vkd, *device, config.externalType));
   1793 		NativeHandle					handleA;
   1794 
   1795 		if (transference == TRANSFERENCE_COPY)
   1796 			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fence, config.externalType, handleA);
   1797 		else
   1798 			getFenceNative(vkd, *device, *fence, config.externalType, handleA);
   1799 
   1800 		{
   1801 			NativeHandle					handleB	(handleA);
   1802 			const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   1803 			const vk::Unique<vk::VkFence>	fenceA	(createAndImportFence(vkd, *device, config.externalType, handleA, flags));
   1804 			const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handleB, flags));
   1805 
   1806 			if (transference == TRANSFERENCE_COPY)
   1807 				VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
   1808 			else if (transference == TRANSFERENCE_REFERENCE)
   1809 			{
   1810 				submitDummySignal(vkd, queue, *fenceA);
   1811 				VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   1812 			}
   1813 			else
   1814 				DE_FATAL("Unknown transference.");
   1815 
   1816 			VK_CHECK(vkd.queueWaitIdle(queue));
   1817 		}
   1818 
   1819 		return tcu::TestStatus::pass("Pass");
   1820 	}
   1821 }
   1822 
   1823 tcu::TestStatus testFenceImportReimport (Context&				context,
   1824 										 const FenceTestConfig	config)
   1825 {
   1826 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1827 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1828 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   1829 	const vk::InstanceDriver			vki					(vkp, *instance);
   1830 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1831 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1832 
   1833 	checkFenceSupport(vki, physicalDevice, config.externalType);
   1834 
   1835 	{
   1836 		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   1837 		const vk::DeviceDriver			vkd		(vki, *device);
   1838 		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
   1839 
   1840 		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
   1841 		NativeHandle					handleA;
   1842 
   1843 		if (transference == TRANSFERENCE_COPY)
   1844 			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handleA);
   1845 		else
   1846 			getFenceNative(vkd, *device, *fenceA, config.externalType, handleA);
   1847 
   1848 		NativeHandle					handleB	(handleA);
   1849 		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   1850 		const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handleA, flags));
   1851 
   1852 		importFence(vkd, *device, *fenceB, config.externalType, handleB, flags);
   1853 
   1854 		if (transference == TRANSFERENCE_COPY)
   1855 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   1856 		else if (transference == TRANSFERENCE_REFERENCE)
   1857 		{
   1858 			submitDummySignal(vkd, queue, *fenceA);
   1859 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   1860 		}
   1861 		else
   1862 			DE_FATAL("Unknown transference.");
   1863 
   1864 		VK_CHECK(vkd.queueWaitIdle(queue));
   1865 
   1866 		return tcu::TestStatus::pass("Pass");
   1867 	}
   1868 }
   1869 
   1870 tcu::TestStatus testFenceSignalExportImportWait (Context&				context,
   1871 												 const FenceTestConfig	config)
   1872 {
   1873 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1874 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   1875 	const vk::InstanceDriver			vki					(vkp, *instance);
   1876 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1877 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1878 
   1879 	checkFenceSupport(vki, physicalDevice, config.externalType);
   1880 
   1881 	{
   1882 		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   1883 		const vk::DeviceDriver			vkd		(vki, *device);
   1884 		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
   1885 		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
   1886 
   1887 		{
   1888 			NativeHandle	handle;
   1889 
   1890 			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle);
   1891 
   1892 			{
   1893 				const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   1894 				const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handle, flags));
   1895 				VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   1896 
   1897 				VK_CHECK(vkd.queueWaitIdle(queue));
   1898 			}
   1899 		}
   1900 
   1901 		return tcu::TestStatus::pass("Pass");
   1902 	}
   1903 }
   1904 
   1905 tcu::TestStatus testFenceExportSignalImportWait (Context&				context,
   1906 												 const FenceTestConfig	config)
   1907 {
   1908 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1909 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   1910 	const vk::InstanceDriver			vki					(vkp, *instance);
   1911 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1912 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1913 	const vk::VkFenceImportFlags		flags				= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   1914 
   1915 	DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
   1916 	checkFenceSupport(vki, physicalDevice, config.externalType);
   1917 
   1918 	{
   1919 		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   1920 		const vk::DeviceDriver			vkd		(vki, *device);
   1921 		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
   1922 
   1923 		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
   1924 		NativeHandle					handle;
   1925 
   1926 		getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
   1927 
   1928 		submitDummySignal(vkd, queue, *fenceA);
   1929 		{
   1930 			{
   1931 				const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handle, flags));
   1932 
   1933 				VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   1934 				VK_CHECK(vkd.queueWaitIdle(queue));
   1935 			}
   1936 		}
   1937 
   1938 		return tcu::TestStatus::pass("Pass");
   1939 	}
   1940 }
   1941 
   1942 tcu::TestStatus testFenceExportImportSignalWait (Context&				context,
   1943 												 const FenceTestConfig	config)
   1944 {
   1945 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1946 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   1947 	const vk::InstanceDriver			vki					(vkp, *instance);
   1948 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1949 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1950 
   1951 	DE_ASSERT(getHandelTypeTransferences(config.externalType) == TRANSFERENCE_REFERENCE);
   1952 	checkFenceSupport(vki, physicalDevice, config.externalType);
   1953 
   1954 	{
   1955 		const vk::VkFenceImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   1956 		const vk::Unique<vk::VkDevice>	device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   1957 		const vk::DeviceDriver			vkd			(vki, *device);
   1958 		const vk::VkQueue				queue		(getQueue(vkd, *device, queueFamilyIndex));
   1959 
   1960 		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
   1961 		NativeHandle					handle;
   1962 
   1963 		getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
   1964 
   1965 		const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handle, flags));
   1966 
   1967 		submitDummySignal(vkd, queue, *fenceA);
   1968 		VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   1969 
   1970 		VK_CHECK(vkd.queueWaitIdle(queue));
   1971 
   1972 		return tcu::TestStatus::pass("Pass");
   1973 	}
   1974 }
   1975 
   1976 tcu::TestStatus testFenceSignalImport (Context&					context,
   1977 									   const FenceTestConfig	config)
   1978 {
   1979 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   1980 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   1981 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   1982 	const vk::InstanceDriver			vki					(vkp, *instance);
   1983 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   1984 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   1985 
   1986 	checkFenceSupport(vki, physicalDevice, config.externalType);
   1987 
   1988 	{
   1989 		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   1990 		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   1991 		const vk::DeviceDriver			vkd		(vki, *device);
   1992 		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
   1993 
   1994 		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
   1995 		const vk::Unique<vk::VkFence>	fenceB	(createFence(vkd, *device));
   1996 		NativeHandle					handle;
   1997 
   1998 		submitDummySignal(vkd, queue, *fenceB);
   1999 		VK_CHECK(vkd.queueWaitIdle(queue));
   2000 
   2001 		if (transference == TRANSFERENCE_COPY)
   2002 			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle);
   2003 		else
   2004 			getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
   2005 
   2006 		importFence(vkd, *device, *fenceB, config.externalType, handle, flags);
   2007 
   2008 		if (transference == TRANSFERENCE_COPY)
   2009 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2010 		else if (transference == TRANSFERENCE_REFERENCE)
   2011 		{
   2012 			submitDummySignal(vkd, queue, *fenceA);
   2013 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2014 		}
   2015 		else
   2016 			DE_FATAL("Unknown transference.");
   2017 
   2018 		VK_CHECK(vkd.queueWaitIdle(queue));
   2019 
   2020 		return tcu::TestStatus::pass("Pass");
   2021 	}
   2022 }
   2023 
   2024 tcu::TestStatus testFenceReset (Context&				context,
   2025 								const FenceTestConfig	config)
   2026 {
   2027 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   2028 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   2029 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   2030 	const vk::InstanceDriver			vki					(vkp, *instance);
   2031 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2032 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2033 
   2034 	checkFenceSupport(vki, physicalDevice, config.externalType);
   2035 
   2036 	{
   2037 		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   2038 		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   2039 		const vk::DeviceDriver			vkd		(vki, *device);
   2040 		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
   2041 
   2042 		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
   2043 		const vk::Unique<vk::VkFence>	fenceB	(createFence(vkd, *device));
   2044 		const vk::Unique<vk::VkFence>	fenceC	(createFence(vkd, *device));
   2045 		NativeHandle					handle;
   2046 
   2047 		submitDummySignal(vkd, queue, *fenceB);
   2048 		VK_CHECK(vkd.queueWaitIdle(queue));
   2049 
   2050 		submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle);
   2051 		{
   2052 			NativeHandle					handleB	(handle);
   2053 			importFence(vkd, *device, *fenceB, config.externalType, handleB, flags);
   2054 		}
   2055 		importFence(vkd, *device, *fenceC, config.externalType, handle, flags);
   2056 
   2057 		VK_CHECK(vkd.queueWaitIdle(queue));
   2058 		VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
   2059 
   2060 		if (config.permanence == PERMANENCE_TEMPORARY || transference == TRANSFERENCE_COPY)
   2061 		{
   2062 			// vkResetFences() should restore fenceBs prior payload and reset that no affecting fenceCs payload
   2063 			// or fenceB should be separate copy of the payload and not affect fenceC
   2064 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
   2065 
   2066 			// vkResetFences() should have restored fenceBs prior state and should be now reset
   2067 			// or fenceB should have it's separate payload
   2068 			submitDummySignal(vkd, queue, *fenceB);
   2069 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2070 		}
   2071 		else if (config.permanence == PERMANENCE_PERMANENT)
   2072 		{
   2073 			DE_ASSERT(transference == TRANSFERENCE_REFERENCE);
   2074 
   2075 			// Reset fences should have reset all of the fences
   2076 			submitDummySignal(vkd, queue, *fenceC);
   2077 
   2078 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
   2079 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2080 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
   2081 		}
   2082 		else
   2083 			DE_FATAL("Unknown permanence");
   2084 
   2085 		VK_CHECK(vkd.queueWaitIdle(queue));
   2086 
   2087 		return tcu::TestStatus::pass("Pass");
   2088 	}
   2089 }
   2090 
   2091 tcu::TestStatus testFenceSignalWaitImport (Context&					context,
   2092 										   const FenceTestConfig	config)
   2093 {
   2094 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   2095 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   2096 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   2097 	const vk::InstanceDriver			vki					(vkp, *instance);
   2098 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2099 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2100 
   2101 	checkFenceSupport(vki, physicalDevice, config.externalType);
   2102 
   2103 	{
   2104 		const vk::VkFenceImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   2105 		const vk::Unique<vk::VkDevice>	device		(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   2106 		const vk::DeviceDriver			vkd			(vki, *device);
   2107 		const vk::VkQueue				queue		(getQueue(vkd, *device, queueFamilyIndex));
   2108 
   2109 		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
   2110 		const vk::Unique<vk::VkFence>	fenceB	(createFence(vkd, *device));
   2111 		NativeHandle					handle;
   2112 
   2113 		if (transference == TRANSFERENCE_COPY)
   2114 			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle);
   2115 		else
   2116 			getFenceNative(vkd, *device, *fenceA, config.externalType, handle);
   2117 
   2118 		submitDummySignal(vkd, queue, *fenceB);
   2119 		VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2120 
   2121 		VK_CHECK(vkd.queueWaitIdle(queue));
   2122 
   2123 		importFence(vkd, *device, *fenceB, config.externalType, handle, flags);
   2124 
   2125 		if (transference == TRANSFERENCE_COPY)
   2126 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2127 		else if (transference == TRANSFERENCE_REFERENCE)
   2128 		{
   2129 			submitDummySignal(vkd, queue, *fenceA);
   2130 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2131 		}
   2132 		else
   2133 			DE_FATAL("Unknown transference.");
   2134 
   2135 		VK_CHECK(vkd.queueWaitIdle(queue));
   2136 
   2137 		return tcu::TestStatus::pass("Pass");
   2138 	}
   2139 }
   2140 
   2141 tcu::TestStatus testFenceMultipleExports (Context&				context,
   2142 										  const FenceTestConfig	config)
   2143 {
   2144 	const size_t						exportCount			= 4 * 1024;
   2145 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   2146 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   2147 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   2148 	const vk::InstanceDriver			vki					(vkp, *instance);
   2149 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2150 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2151 
   2152 	checkFenceSupport(vki, physicalDevice, config.externalType);
   2153 
   2154 	{
   2155 		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   2156 		const vk::DeviceDriver			vkd		(vki, *device);
   2157 		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
   2158 		const vk::Unique<vk::VkFence>	fence	(createExportableFence(vkd, *device, config.externalType));
   2159 
   2160 		for (size_t exportNdx = 0; exportNdx < exportCount; exportNdx++)
   2161 		{
   2162 			NativeHandle handle;
   2163 
   2164 			if (transference == TRANSFERENCE_COPY)
   2165 				submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fence, config.externalType, handle);
   2166 			else
   2167 				getFenceNative(vkd, *device, *fence, config.externalType, handle);
   2168 		}
   2169 
   2170 		submitDummySignal(vkd, queue, *fence);
   2171 		VK_CHECK(vkd.waitForFences(*device, 1u, &*fence, VK_TRUE, ~0ull));
   2172 
   2173 		VK_CHECK(vkd.queueWaitIdle(queue));
   2174 	}
   2175 
   2176 	return tcu::TestStatus::pass("Pass");
   2177 }
   2178 
   2179 tcu::TestStatus testFenceMultipleImports (Context&				context,
   2180 										  const FenceTestConfig	config)
   2181 {
   2182 	const size_t						importCount			= 4 * 1024;
   2183 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   2184 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   2185 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   2186 	const vk::InstanceDriver			vki					(vkp, *instance);
   2187 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2188 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2189 
   2190 	checkFenceSupport(vki, physicalDevice, config.externalType);
   2191 
   2192 	{
   2193 		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   2194 		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   2195 		const vk::DeviceDriver			vkd		(vki, *device);
   2196 		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
   2197 		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
   2198 		NativeHandle					handleA;
   2199 
   2200 		if (transference == TRANSFERENCE_COPY)
   2201 			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handleA);
   2202 		else
   2203 			getFenceNative(vkd, *device, *fenceA, config.externalType, handleA);
   2204 
   2205 		for (size_t importNdx = 0; importNdx < importCount; importNdx++)
   2206 		{
   2207 			NativeHandle					handleB		(handleA);
   2208 			const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handleB, flags));
   2209 		}
   2210 
   2211 		if (transference == TRANSFERENCE_COPY)
   2212 		{
   2213 			importFence(vkd, *device, *fenceA, config.externalType, handleA, flags);
   2214 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
   2215 		}
   2216 		else if (transference == TRANSFERENCE_REFERENCE)
   2217 		{
   2218 			submitDummySignal(vkd, queue, *fenceA);
   2219 			VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
   2220 		}
   2221 		else
   2222 			DE_FATAL("Unknown transference.");
   2223 
   2224 		VK_CHECK(vkd.queueWaitIdle(queue));
   2225 	}
   2226 
   2227 	return tcu::TestStatus::pass("Pass");
   2228 }
   2229 
   2230 tcu::TestStatus testFenceTransference (Context&					context,
   2231 									   const FenceTestConfig	config)
   2232 {
   2233 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   2234 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   2235 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   2236 	const vk::InstanceDriver			vki					(vkp, *instance);
   2237 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2238 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2239 
   2240 	checkFenceSupport(vki, physicalDevice, config.externalType);
   2241 
   2242 	{
   2243 		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   2244 		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   2245 		const vk::DeviceDriver			vkd		(vki, *device);
   2246 		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
   2247 
   2248 		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
   2249 		NativeHandle					handle;
   2250 
   2251 		submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, handle);
   2252 
   2253 		{
   2254 			const vk::Unique<vk::VkFence>	fenceB	(createAndImportFence(vkd, *device, config.externalType, handle, flags));
   2255 
   2256 			if (config.permanence == PERMANENCE_PERMANENT)
   2257 			{
   2258 				if (transference == TRANSFERENCE_COPY)
   2259 				{
   2260 					submitDummySignal(vkd, queue, *fenceA);
   2261 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2262 					VK_CHECK(vkd.queueWaitIdle(queue));
   2263 
   2264 					VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
   2265 					submitDummySignal(vkd, queue, *fenceB);
   2266 
   2267 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
   2268 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2269 					VK_CHECK(vkd.queueWaitIdle(queue));
   2270 				}
   2271 				else if (transference== TRANSFERENCE_REFERENCE)
   2272 				{
   2273 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2274 					VK_CHECK(vkd.queueWaitIdle(queue));
   2275 
   2276 					VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
   2277 					submitDummySignal(vkd, queue, *fenceA);
   2278 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2279 
   2280 					VK_CHECK(vkd.resetFences(*device, 1u, &*fenceA));
   2281 					submitDummySignal(vkd, queue, *fenceB);
   2282 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
   2283 					VK_CHECK(vkd.queueWaitIdle(queue));
   2284 				}
   2285 				else
   2286 					DE_FATAL("Unknown transference.");
   2287 			}
   2288 			else if (config.permanence == PERMANENCE_TEMPORARY)
   2289 			{
   2290 				if (transference == TRANSFERENCE_COPY)
   2291 				{
   2292 					submitDummySignal(vkd, queue, *fenceA);
   2293 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2294 					VK_CHECK(vkd.queueWaitIdle(queue));
   2295 
   2296 					VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
   2297 					submitDummySignal(vkd, queue, *fenceB);
   2298 
   2299 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
   2300 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2301 					VK_CHECK(vkd.queueWaitIdle(queue));
   2302 				}
   2303 				else if (transference == TRANSFERENCE_REFERENCE)
   2304 				{
   2305 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2306 					VK_CHECK(vkd.queueWaitIdle(queue));
   2307 
   2308 					VK_CHECK(vkd.resetFences(*device, 1u, &*fenceA));
   2309 					VK_CHECK(vkd.resetFences(*device, 1u, &*fenceB));
   2310 					submitDummySignal(vkd, queue, *fenceA);
   2311 					submitDummySignal(vkd, queue, *fenceB);
   2312 
   2313 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2314 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceA, VK_TRUE, ~0ull));
   2315 					VK_CHECK(vkd.queueWaitIdle(queue));
   2316 				}
   2317 				else
   2318 					DE_FATAL("Unknown transference.");
   2319 			}
   2320 			else
   2321 				DE_FATAL("Unknown permanence.");
   2322 		}
   2323 
   2324 		return tcu::TestStatus::pass("Pass");
   2325 	}
   2326 }
   2327 
   2328 tcu::TestStatus testFenceFdDup (Context&				context,
   2329 								const FenceTestConfig	config)
   2330 {
   2331 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
   2332 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   2333 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   2334 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   2335 	const vk::InstanceDriver			vki					(vkp, *instance);
   2336 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2337 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2338 
   2339 	checkFenceSupport(vki, physicalDevice, config.externalType);
   2340 
   2341 	{
   2342 		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   2343 		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   2344 		const vk::DeviceDriver			vkd		(vki, *device);
   2345 		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
   2346 
   2347 		TestLog&						log		= context.getTestContext().getLog();
   2348 		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
   2349 
   2350 		{
   2351 			NativeHandle		fd;
   2352 
   2353 			if (transference == TRANSFERENCE_COPY)
   2354 				submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, fd);
   2355 			else
   2356 				getFenceNative(vkd, *device, *fenceA, config.externalType, fd);
   2357 
   2358 			NativeHandle		newFd	(dup(fd.getFd()));
   2359 
   2360 			if (newFd.getFd() < 0)
   2361 				log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
   2362 
   2363 			TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for fences fd");
   2364 
   2365 			{
   2366 				const vk::Unique<vk::VkFence> fenceB (createAndImportFence(vkd, *device, config.externalType, newFd, flags));
   2367 
   2368 				if (transference == TRANSFERENCE_COPY)
   2369 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2370 				else if (transference == TRANSFERENCE_REFERENCE)
   2371 				{
   2372 					submitDummySignal(vkd, queue, *fenceA);
   2373 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceB, VK_TRUE, ~0ull));
   2374 				}
   2375 				else
   2376 					DE_FATAL("Unknown permanence.");
   2377 			}
   2378 		}
   2379 
   2380 		VK_CHECK(vkd.queueWaitIdle(queue));
   2381 
   2382 		return tcu::TestStatus::pass("Pass");
   2383 	}
   2384 #else
   2385 	DE_UNREF(context);
   2386 	DE_UNREF(config);
   2387 	TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
   2388 #endif
   2389 }
   2390 
   2391 tcu::TestStatus testFenceFdDup2 (Context&				context,
   2392 								 const FenceTestConfig	config)
   2393 {
   2394 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
   2395 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   2396 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   2397 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   2398 	const vk::InstanceDriver			vki					(vkp, *instance);
   2399 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2400 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2401 
   2402 	checkFenceSupport(vki, physicalDevice, config.externalType);
   2403 
   2404 	{
   2405 		const vk::VkFenceImportFlags	flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   2406 		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   2407 		const vk::DeviceDriver			vkd		(vki, *device);
   2408 		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
   2409 
   2410 		TestLog&						log		= context.getTestContext().getLog();
   2411 		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
   2412 		const vk::Unique<vk::VkFence>	fenceB	(createExportableFence(vkd, *device, config.externalType));
   2413 
   2414 		{
   2415 			NativeHandle		fd, secondFd;
   2416 
   2417 			if (transference == TRANSFERENCE_COPY)
   2418 			{
   2419 				submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, fd);
   2420 				submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceB, config.externalType, secondFd);
   2421 			}
   2422 			else
   2423 			{
   2424 				getFenceNative(vkd, *device, *fenceA, config.externalType, fd);
   2425 				getFenceNative(vkd, *device, *fenceB, config.externalType, secondFd);
   2426 			}
   2427 
   2428 			int					newFd		(dup2(fd.getFd(), secondFd.getFd()));
   2429 
   2430 			if (newFd < 0)
   2431 				log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
   2432 
   2433 			TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for fences fd");
   2434 
   2435 			{
   2436 				const vk::Unique<vk::VkFence> fenceC (createAndImportFence(vkd, *device, config.externalType, secondFd, flags));
   2437 
   2438 				if (transference == TRANSFERENCE_COPY)
   2439 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
   2440 				else if (transference == TRANSFERENCE_REFERENCE)
   2441 				{
   2442 					submitDummySignal(vkd, queue, *fenceA);
   2443 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
   2444 				}
   2445 				else
   2446 					DE_FATAL("Unknown permanence.");
   2447 			}
   2448 		}
   2449 
   2450 		VK_CHECK(vkd.queueWaitIdle(queue));
   2451 
   2452 		return tcu::TestStatus::pass("Pass");
   2453 	}
   2454 #else
   2455 	DE_UNREF(context);
   2456 	DE_UNREF(config);
   2457 	TCU_THROW(NotSupportedError, "Platform doesn't support dup2()");
   2458 #endif
   2459 }
   2460 
   2461 tcu::TestStatus testFenceFdDup3 (Context&				context,
   2462 								 const FenceTestConfig	config)
   2463 {
   2464 #if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
   2465 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   2466 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   2467 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   2468 	const vk::InstanceDriver			vki					(vkp, *instance);
   2469 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2470 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2471 
   2472 	checkFenceSupport(vki, physicalDevice, config.externalType);
   2473 
   2474 	{
   2475 		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   2476 		const vk::DeviceDriver			vkd		(vki, *device);
   2477 		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
   2478 
   2479 		TestLog&						log		= context.getTestContext().getLog();
   2480 		const vk::Unique<vk::VkFence>	fenceA	(createExportableFence(vkd, *device, config.externalType));
   2481 		const vk::Unique<vk::VkFence>	fenceB	(createExportableFence(vkd, *device, config.externalType));
   2482 
   2483 		{
   2484 			NativeHandle					fd, secondFd;
   2485 
   2486 			if (transference == TRANSFERENCE_COPY)
   2487 			{
   2488 				submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceA, config.externalType, fd);
   2489 				submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fenceB, config.externalType, secondFd);
   2490 			}
   2491 			else
   2492 			{
   2493 				getFenceNative(vkd, *device, *fenceA, config.externalType, fd);
   2494 				getFenceNative(vkd, *device, *fenceB, config.externalType, secondFd);
   2495 			}
   2496 
   2497 			const vk::VkFenceImportFlags	flags		= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   2498 			const int						newFd		(dup3(fd.getFd(), secondFd.getFd(), 0));
   2499 
   2500 			if (newFd < 0)
   2501 				log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
   2502 
   2503 			TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for fences fd");
   2504 
   2505 			{
   2506 				const vk::Unique<vk::VkFence> fenceC (createAndImportFence(vkd, *device, config.externalType, secondFd, flags));
   2507 
   2508 				if (transference == TRANSFERENCE_COPY)
   2509 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
   2510 				else if (transference == TRANSFERENCE_REFERENCE)
   2511 				{
   2512 					submitDummySignal(vkd, queue, *fenceA);
   2513 					VK_CHECK(vkd.waitForFences(*device, 1u, &*fenceC, VK_TRUE, ~0ull));
   2514 				}
   2515 				else
   2516 					DE_FATAL("Unknown permanence.");
   2517 			}
   2518 		}
   2519 
   2520 		VK_CHECK(vkd.queueWaitIdle(queue));
   2521 
   2522 		return tcu::TestStatus::pass("Pass");
   2523 	}
   2524 #else
   2525 	DE_UNREF(context);
   2526 	DE_UNREF(config);
   2527 	TCU_THROW(NotSupportedError, "Platform doesn't support dup3()");
   2528 #endif
   2529 }
   2530 
   2531 tcu::TestStatus testFenceFdSendOverSocket (Context&					context,
   2532 										   const FenceTestConfig	config)
   2533 {
   2534 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
   2535 	const Transference					transference		(getHandelTypeTransferences(config.externalType));
   2536 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   2537 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, 0u, config.externalType));
   2538 	const vk::InstanceDriver			vki					(vkp, *instance);
   2539 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2540 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2541 
   2542 	checkFenceSupport(vki, physicalDevice, config.externalType);
   2543 
   2544 	{
   2545 		const vk::Unique<vk::VkDevice>	device	(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, 0u, config.externalType, queueFamilyIndex));
   2546 		const vk::DeviceDriver			vkd		(vki, *device);
   2547 		const vk::VkQueue				queue	(getQueue(vkd, *device, queueFamilyIndex));
   2548 
   2549 		TestLog&						log		= context.getTestContext().getLog();
   2550 		const vk::Unique<vk::VkFence>	fence	(createExportableFence(vkd, *device, config.externalType));
   2551 		NativeHandle					fd;
   2552 
   2553 		if (transference == TRANSFERENCE_COPY)
   2554 			submitDummySignalAndGetFenceNative(vkd, *device, queue, queueFamilyIndex, *fence, config.externalType, fd);
   2555 		else
   2556 			getFenceNative(vkd, *device, *fence, config.externalType, fd);
   2557 
   2558 		{
   2559 			int sv[2];
   2560 
   2561 			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
   2562 			{
   2563 				log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
   2564 				TCU_FAIL("Failed to create socket pair");
   2565 			}
   2566 
   2567 			{
   2568 				const NativeHandle	srcSocket	(sv[0]);
   2569 				const NativeHandle	dstSocket	(sv[1]);
   2570 				std::string			sendData	("deqp");
   2571 
   2572 				// Send FD
   2573 				{
   2574 					const int			fdRaw	(fd.getFd());
   2575 					msghdr				msg;
   2576 					cmsghdr*			cmsg;
   2577 					char				buffer[CMSG_SPACE(sizeof(int))];
   2578 					iovec				iov		= { &sendData[0], sendData.length()};
   2579 
   2580 					deMemset(&msg, 0, sizeof(msg));
   2581 
   2582 					msg.msg_control		= buffer;
   2583 					msg.msg_controllen	= sizeof(buffer);
   2584 					msg.msg_iovlen		= 1;
   2585 					msg.msg_iov			= &iov;
   2586 
   2587 					cmsg				= CMSG_FIRSTHDR(&msg);
   2588 					cmsg->cmsg_level	= SOL_SOCKET;
   2589 					cmsg->cmsg_type		= SCM_RIGHTS;
   2590 					cmsg->cmsg_len		= CMSG_LEN(sizeof(int));
   2591 
   2592 					deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
   2593 					msg.msg_controllen = cmsg->cmsg_len;
   2594 
   2595 					if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
   2596 					{
   2597 						log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
   2598 						TCU_FAIL("Failed to send fd over socket");
   2599 					}
   2600 				}
   2601 
   2602 				// Recv FD
   2603 				{
   2604 					msghdr			msg;
   2605 					char			buffer[CMSG_SPACE(sizeof(int))];
   2606 					std::string		recvData	(4, '\0');
   2607 					iovec			iov			= { &recvData[0], recvData.length() };
   2608 
   2609 					deMemset(&msg, 0, sizeof(msg));
   2610 
   2611 					msg.msg_control		= buffer;
   2612 					msg.msg_controllen	= sizeof(buffer);
   2613 					msg.msg_iovlen		= 1;
   2614 					msg.msg_iov			= &iov;
   2615 
   2616 					const ssize_t	bytes = recvmsg(dstSocket.getFd(), &msg, 0);
   2617 
   2618 					if (bytes < 0)
   2619 					{
   2620 						log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
   2621 						TCU_FAIL("Failed to recv fd over socket");
   2622 
   2623 					}
   2624 					else if (bytes != (ssize_t)sendData.length())
   2625 					{
   2626 						TCU_FAIL("recvmsg() returned unpexpected number of bytes");
   2627 					}
   2628 					else
   2629 					{
   2630 						const vk::VkFenceImportFlags		flags	= config.permanence == PERMANENCE_TEMPORARY ? vk::VK_FENCE_IMPORT_TEMPORARY_BIT : (vk::VkFenceImportFlagBits)0u;
   2631 						const cmsghdr* const				cmsg	= CMSG_FIRSTHDR(&msg);
   2632 						int									newFd_;
   2633 						deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
   2634 						NativeHandle						newFd	(newFd_);
   2635 
   2636 						TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
   2637 						TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
   2638 						TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
   2639 						TCU_CHECK(recvData == sendData);
   2640 						TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");
   2641 
   2642 						{
   2643 							const vk::Unique<vk::VkFence> newFence (createAndImportFence(vkd, *device, config.externalType, newFd, flags));
   2644 
   2645 							if (transference == TRANSFERENCE_COPY)
   2646 								VK_CHECK(vkd.waitForFences(*device, 1u, &*newFence, VK_TRUE, ~0ull));
   2647 							else if (transference == TRANSFERENCE_REFERENCE)
   2648 							{
   2649 								submitDummySignal(vkd, queue, *newFence);
   2650 								VK_CHECK(vkd.waitForFences(*device, 1u, &*newFence, VK_TRUE, ~0ull));
   2651 							}
   2652 							else
   2653 								DE_FATAL("Unknown permanence.");
   2654 
   2655 							VK_CHECK(vkd.queueWaitIdle(queue));
   2656 						}
   2657 					}
   2658 				}
   2659 			}
   2660 		}
   2661 	}
   2662 
   2663 	return tcu::TestStatus::pass("Pass");
   2664 #else
   2665 	DE_UNREF(context);
   2666 	DE_UNREF(config);
   2667 	TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
   2668 #endif
   2669 }
   2670 
   2671 tcu::TestStatus testBufferQueries (Context& context, vk::VkExternalMemoryHandleTypeFlagBits externalType)
   2672 {
   2673 	const vk::VkBufferCreateFlags		createFlags[]		=
   2674 	{
   2675 		0u,
   2676 		vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT,
   2677 		vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT|vk::VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,
   2678 		vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT|vk::VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
   2679 	};
   2680 	const vk::VkBufferUsageFlags		usageFlags[]		=
   2681 	{
   2682 		vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
   2683 		vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,
   2684 		vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
   2685 		vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
   2686 		vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
   2687 		vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
   2688 		vk::VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
   2689 		vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
   2690 		vk::VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
   2691 	};
   2692 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   2693 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, externalType, 0u));
   2694 	const vk::InstanceDriver			vki					(vkp, *instance);
   2695 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2696 	const vk::VkPhysicalDeviceFeatures	deviceFeatures		(vk::getPhysicalDeviceFeatures(vki, physicalDevice));
   2697 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2698 
   2699 	// VkDevice is only created if physical device claims to support any of these types.
   2700 	vk::Move<vk::VkDevice>				device;
   2701 	de::MovePtr<vk::DeviceDriver>		vkd;
   2702 	bool								deviceHasDedicated	= false;
   2703 
   2704 	TestLog&							log					= context.getTestContext().getLog();
   2705 
   2706 	for (size_t createFlagNdx = 0; createFlagNdx < DE_LENGTH_OF_ARRAY(createFlags); createFlagNdx++)
   2707 	for (size_t usageFlagNdx = 0; usageFlagNdx < DE_LENGTH_OF_ARRAY(usageFlags); usageFlagNdx++)
   2708 	{
   2709 		const vk::VkBufferViewCreateFlags				createFlag		= createFlags[createFlagNdx];
   2710 		const vk::VkBufferUsageFlags					usageFlag		= usageFlags[usageFlagNdx];
   2711 		const vk::VkPhysicalDeviceExternalBufferInfo	info			=
   2712 		{
   2713 			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
   2714 			DE_NULL,
   2715 			createFlag,
   2716 			usageFlag,
   2717 			externalType
   2718 		};
   2719 		vk::VkExternalBufferProperties					properties		=
   2720 		{
   2721 			vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
   2722 			DE_NULL,
   2723 			{ 0u, 0u, 0u }
   2724 		};
   2725 
   2726 		if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_BINDING_BIT) != 0) &&
   2727 			(deviceFeatures.sparseBinding == VK_FALSE))
   2728 			continue;
   2729 
   2730 		if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) != 0) &&
   2731 			(deviceFeatures.sparseResidencyAliased == VK_FALSE))
   2732 			continue;
   2733 
   2734 		if (((createFlag & vk::VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) != 0) &&
   2735 			(deviceFeatures.sparseResidencyBuffer == VK_FALSE))
   2736 			continue;
   2737 
   2738 		vki.getPhysicalDeviceExternalBufferProperties(physicalDevice, &info, &properties);
   2739 
   2740 		log << TestLog::Message << properties << TestLog::EndMessage;
   2741 
   2742 		TCU_CHECK(properties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES);
   2743 		TCU_CHECK(properties.pNext == DE_NULL);
   2744 		// \todo [2017-06-06 pyry] Can we validate anything else? Compatible types?
   2745 
   2746 		if ((properties.externalMemoryProperties.externalMemoryFeatures & (vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT|vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT)) != 0)
   2747 		{
   2748 			const bool	requiresDedicated	= (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0;
   2749 
   2750 			if (!device || (requiresDedicated && !deviceHasDedicated))
   2751 			{
   2752 				// \note We need to re-create with dedicated mem extensions if previous device instance didn't have them
   2753 				try
   2754 				{
   2755 					device				= createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, externalType, 0u, queueFamilyIndex, requiresDedicated);
   2756 					vkd					= de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vki, *device));
   2757 					deviceHasDedicated	= requiresDedicated;
   2758 				}
   2759 				catch (const tcu::NotSupportedError& e)
   2760 				{
   2761 					log << e;
   2762 					TCU_FAIL("Physical device claims to support handle type but required extensions are not supported");
   2763 				}
   2764 			}
   2765 		}
   2766 
   2767 		if ((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) != 0)
   2768 		{
   2769 			DE_ASSERT(!!device);
   2770 			DE_ASSERT(vkd);
   2771 
   2772 			if (deviceHasDedicated)
   2773 			{
   2774 				const vk::Unique<vk::VkBuffer>				buffer						(createExternalBuffer(*vkd, *device, queueFamilyIndex, externalType, 1024u, createFlag, usageFlag));
   2775 				const vk::VkMemoryDedicatedRequirements		reqs						(getMemoryDedicatedRequirements(*vkd, *device, *buffer));
   2776 				const bool									propertiesRequiresDedicated	= (properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0;
   2777 				const bool									objectRequiresDedicated		= (reqs.requiresDedicatedAllocation != VK_FALSE);
   2778 
   2779 				if (propertiesRequiresDedicated != objectRequiresDedicated)
   2780 					TCU_FAIL("vkGetPhysicalDeviceExternalBufferProperties and vkGetBufferMemoryRequirements2 report different dedicated requirements");
   2781 			}
   2782 			else
   2783 			{
   2784 				// We can't query whether dedicated memory is required or not on per-object basis.
   2785 				// This check should be redundant as the code above tries to create device with
   2786 				// VK_KHR_dedicated_allocation & VK_KHR_get_memory_requirements2 if dedicated memory
   2787 				// is required. However, checking again doesn't hurt.
   2788 				TCU_CHECK((properties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) == 0);
   2789 			}
   2790 		}
   2791 	}
   2792 
   2793 	return tcu::TestStatus::pass("Pass");
   2794 }
   2795 
   2796 struct MemoryTestConfig
   2797 {
   2798 												MemoryTestConfig	(vk::VkExternalMemoryHandleTypeFlagBits	externalType_,
   2799 																	 bool										hostVisible_,
   2800 																	 bool										dedicated_)
   2801 		: externalType	(externalType_)
   2802 		, hostVisible	(hostVisible_)
   2803 		, dedicated		(dedicated_)
   2804 	{
   2805 	}
   2806 
   2807 	vk::VkExternalMemoryHandleTypeFlagBits	externalType;
   2808 	bool									hostVisible;
   2809 	bool									dedicated;
   2810 };
   2811 
   2812 #if (DE_OS == DE_OS_WIN32)
   2813 deUint32 chooseMemoryType (deUint32 bits)
   2814 {
   2815 	if (bits == 0)
   2816 		TCU_THROW(NotSupportedError, "No compatible memory type found");
   2817 
   2818 	return deCtz32(bits);
   2819 }
   2820 #endif
   2821 
   2822 tcu::TestStatus testMemoryWin32Create (Context& context, MemoryTestConfig config)
   2823 {
   2824 #if (DE_OS == DE_OS_WIN32)
   2825 	const vk::PlatformInterface&				vkp					(context.getPlatformInterface());
   2826 	const vk::Unique<vk::VkInstance>			instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   2827 	const vk::InstanceDriver					vki					(vkp, *instance);
   2828 	const vk::VkPhysicalDevice					physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2829 	const deUint32								queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2830 	const vk::Unique<vk::VkDevice>				device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
   2831 	const vk::DeviceDriver						vkd					(vki, *device);
   2832 	const vk::VkBufferUsageFlags				usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   2833 	const deUint32								seed				= 1261033864u;
   2834 	const vk::VkDeviceSize						bufferSize			= 1024;
   2835 	const std::vector<deUint8>					testData			(genTestData(seed, (size_t)bufferSize));
   2836 
   2837 	const vk::VkPhysicalDeviceMemoryProperties	memoryProps			= vk::getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice());
   2838 	const deUint32								compatibleMemTypes	= vk::getCompatibleMemoryTypes(memoryProps, config.hostVisible ? vk::MemoryRequirement::HostVisible : vk::MemoryRequirement::Any);
   2839 
   2840 	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
   2841 
   2842 	// \note Buffer is only allocated to get memory requirements
   2843 	deUint32									exportedMemoryTypeIndex	= ~0U;
   2844 	const vk::Unique<vk::VkBuffer>				buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   2845 	const vk::VkMemoryRequirements				requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
   2846 	const vk::VkExportMemoryWin32HandleInfoKHR	win32Info				=
   2847 	{
   2848 		vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
   2849 		DE_NULL,
   2850 
   2851 		(vk::pt::Win32SecurityAttributesPtr)DE_NULL,
   2852 		DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE,
   2853 		DE_NULL
   2854 	};
   2855 	const vk::VkExportMemoryAllocateInfo		exportInfo			=
   2856 	{
   2857 		vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
   2858 		&win32Info,
   2859 		(vk::VkExternalMemoryHandleTypeFlags)config.externalType
   2860 	};
   2861 
   2862 	exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits & compatibleMemTypes);
   2863 	const vk::VkMemoryAllocateInfo				info				=
   2864 	{
   2865 		vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
   2866 		&exportInfo,
   2867 		requirements.size,
   2868 		exportedMemoryTypeIndex
   2869 	};
   2870 	const vk::Unique<vk::VkDeviceMemory>		memory				(vk::allocateMemory(vkd, *device, &info));
   2871 	NativeHandle								handleA;
   2872 
   2873 	if (config.hostVisible)
   2874 		writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
   2875 
   2876 	getMemoryNative(vkd, *device, *memory, config.externalType, handleA);
   2877 
   2878 	{
   2879 		const vk::Unique<vk::VkDeviceMemory>	memoryA	(importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleA));
   2880 
   2881 		if (config.hostVisible)
   2882 		{
   2883 			const std::vector<deUint8>		testDataA		(genTestData(seed ^ 124798807u, (size_t)bufferSize));
   2884 			const std::vector<deUint8>		testDataB		(genTestData(seed ^ 970834278u, (size_t)bufferSize));
   2885 
   2886 			checkHostMemory(vkd, *device, *memoryA, testData.size(), &testData[0]);
   2887 			checkHostMemory(vkd, *device, *memory,  testData.size(), &testData[0]);
   2888 
   2889 			writeHostMemory(vkd, *device, *memoryA, testDataA.size(), &testDataA[0]);
   2890 			writeHostMemory(vkd, *device, *memory,  testDataA.size(), &testDataB[0]);
   2891 
   2892 			checkHostMemory(vkd, *device, *memoryA, testData.size(), &testDataB[0]);
   2893 			checkHostMemory(vkd, *device, *memory,  testData.size(), &testDataB[0]);
   2894 		}
   2895 	}
   2896 
   2897 	return tcu::TestStatus::pass("Pass");
   2898 #else
   2899 	DE_UNREF(context);
   2900 	DE_UNREF(config);
   2901 	TCU_THROW(NotSupportedError, "Platform doesn't support win32 handles");
   2902 #endif
   2903 }
   2904 
   2905 tcu::TestStatus testMemoryImportTwice (Context& context, MemoryTestConfig config)
   2906 {
   2907 	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
   2908 	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   2909 	const vk::InstanceDriver				vki					(vkp, *instance);
   2910 	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2911 	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2912 	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
   2913 	const vk::DeviceDriver					vkd					(vki, *device);
   2914 	const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   2915 	const deUint32							seed				= 1261033864u;
   2916 	const vk::VkDeviceSize					bufferSize			= 1024;
   2917 	const std::vector<deUint8>				testData			(genTestData(seed, (size_t)bufferSize));
   2918 
   2919 	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
   2920 
   2921 	deUint32								exportedMemoryTypeIndex	= ~0U;
   2922 	// \note Buffer is only allocated to get memory requirements
   2923 	const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   2924 	const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
   2925 	const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
   2926 	NativeHandle							handleA;
   2927 
   2928 	if (config.hostVisible)
   2929 		writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
   2930 
   2931 	getMemoryNative(vkd, *device, *memory, config.externalType, handleA);
   2932 
   2933 	{
   2934 		NativeHandle							handleB	(handleA);
   2935 		const vk::Unique<vk::VkDeviceMemory>	memoryA	(importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleA));
   2936 		const vk::Unique<vk::VkDeviceMemory>	memoryB	(importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleB));
   2937 
   2938 		if (config.hostVisible)
   2939 		{
   2940 			const std::vector<deUint8>		testDataA		(genTestData(seed ^ 124798807u, (size_t)bufferSize));
   2941 			const std::vector<deUint8>		testDataB		(genTestData(seed ^ 970834278u, (size_t)bufferSize));
   2942 
   2943 			checkHostMemory(vkd, *device, *memoryA, testData.size(), &testData[0]);
   2944 			checkHostMemory(vkd, *device, *memoryB, testData.size(), &testData[0]);
   2945 
   2946 			writeHostMemory(vkd, *device, *memoryA, testData.size(), &testDataA[0]);
   2947 			writeHostMemory(vkd, *device, *memoryB, testData.size(), &testDataB[0]);
   2948 
   2949 			checkHostMemory(vkd, *device, *memoryA, testData.size(), &testDataB[0]);
   2950 			checkHostMemory(vkd, *device, *memory, testData.size(), &testDataB[0]);
   2951 		}
   2952 	}
   2953 
   2954 	return tcu::TestStatus::pass("Pass");
   2955 }
   2956 
   2957 tcu::TestStatus testMemoryMultimpleImports (Context& context, MemoryTestConfig config)
   2958 {
   2959 	const size_t							count				= 4 * 1024;
   2960 	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
   2961 	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   2962 	const vk::InstanceDriver				vki					(vkp, *instance);
   2963 	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2964 	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2965 	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
   2966 	const vk::DeviceDriver					vkd					(vki, *device);
   2967 	const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   2968 	const vk::VkDeviceSize					bufferSize			= 1024;
   2969 
   2970 	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
   2971 
   2972 	deUint32								exportedMemoryTypeIndex	= ~0U;
   2973 	// \note Buffer is only allocated to get memory requirements
   2974 	const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   2975 	const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
   2976 	const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
   2977 	NativeHandle							handleA;
   2978 
   2979 	getMemoryNative(vkd, *device, *memory, config.externalType, handleA);
   2980 
   2981 	for (size_t ndx = 0; ndx < count; ndx++)
   2982 	{
   2983 		NativeHandle							handleB	(handleA);
   2984 		const vk::Unique<vk::VkDeviceMemory>	memoryB	(importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handleB));
   2985 	}
   2986 
   2987 	return tcu::TestStatus::pass("Pass");
   2988 }
   2989 
   2990 tcu::TestStatus testMemoryMultimpleExports (Context& context, MemoryTestConfig config)
   2991 {
   2992 	const size_t							count				= 4 * 1024;
   2993 	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
   2994 	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   2995 	const vk::InstanceDriver				vki					(vkp, *instance);
   2996 	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   2997 	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   2998 	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
   2999 	const vk::DeviceDriver					vkd					(vki, *device);
   3000 	const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   3001 	const vk::VkDeviceSize					bufferSize			= 1024;
   3002 
   3003 	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
   3004 
   3005 	deUint32								exportedMemoryTypeIndex	= ~0U;
   3006 	// \note Buffer is only allocated to get memory requirements
   3007 	const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   3008 	const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
   3009 	const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
   3010 
   3011 	for (size_t ndx = 0; ndx < count; ndx++)
   3012 	{
   3013 		NativeHandle	handle;
   3014 		getMemoryNative(vkd, *device, *memory, config.externalType, handle);
   3015 	}
   3016 
   3017 	return tcu::TestStatus::pass("Pass");
   3018 }
   3019 
   3020 tcu::TestStatus testMemoryFdDup (Context& context, MemoryTestConfig config)
   3021 {
   3022 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
   3023 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   3024 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   3025 	const vk::InstanceDriver			vki					(vkp, *instance);
   3026 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   3027 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   3028 
   3029 	{
   3030 		const vk::Unique<vk::VkDevice>			device			(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
   3031 		const vk::DeviceDriver					vkd				(vki, *device);
   3032 
   3033 		TestLog&								log				= context.getTestContext().getLog();
   3034 		const vk::VkBufferUsageFlags			usage			= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   3035 		const vk::VkDeviceSize					bufferSize		= 1024;
   3036 		const deUint32							seed			= 851493858u;
   3037 		const std::vector<deUint8>				testData		(genTestData(seed, (size_t)bufferSize));
   3038 
   3039 		checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
   3040 
   3041 		deUint32								exportedMemoryTypeIndex	= ~0U;
   3042 		// \note Buffer is only allocated to get memory requirements
   3043 		const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   3044 		const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
   3045 		const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
   3046 
   3047 		if (config.hostVisible)
   3048 			writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
   3049 
   3050 		const NativeHandle						fd				(getMemoryFd(vkd, *device, *memory, config.externalType));
   3051 		NativeHandle							newFd			(dup(fd.getFd()));
   3052 
   3053 		if (newFd.getFd() < 0)
   3054 			log << TestLog::Message << "dup() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
   3055 
   3056 		TCU_CHECK_MSG(newFd.getFd() >= 0, "Failed to call dup() for memorys fd");
   3057 
   3058 		{
   3059 			const vk::Unique<vk::VkDeviceMemory>	newMemory	(importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, newFd));
   3060 
   3061 			if (config.hostVisible)
   3062 			{
   3063 				const std::vector<deUint8>	testDataA	(genTestData(seed ^ 672929437u, (size_t)bufferSize));
   3064 
   3065 				checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
   3066 
   3067 				writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
   3068 				checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
   3069 			}
   3070 		}
   3071 
   3072 		return tcu::TestStatus::pass("Pass");
   3073 	}
   3074 #else
   3075 	DE_UNREF(context);
   3076 	DE_UNREF(config);
   3077 	TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
   3078 #endif
   3079 }
   3080 
   3081 tcu::TestStatus testMemoryFdDup2 (Context& context, MemoryTestConfig config)
   3082 {
   3083 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
   3084 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   3085 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   3086 	const vk::InstanceDriver			vki					(vkp, *instance);
   3087 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   3088 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   3089 
   3090 	{
   3091 		const vk::Unique<vk::VkDevice>			device			(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
   3092 		const vk::DeviceDriver					vkd				(vki, *device);
   3093 
   3094 		TestLog&								log				= context.getTestContext().getLog();
   3095 		const vk::VkBufferUsageFlags			usage			= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   3096 		const vk::VkDeviceSize					bufferSize		= 1024;
   3097 		const deUint32							seed			= 224466865u;
   3098 		const std::vector<deUint8>				testData		(genTestData(seed, (size_t)bufferSize));
   3099 
   3100 		checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
   3101 
   3102 		deUint32								exportedMemoryTypeIndex	= ~0U;
   3103 		// \note Buffer is only allocated to get memory requirements
   3104 		const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   3105 		const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
   3106 		const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
   3107 
   3108 		if (config.hostVisible)
   3109 			writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
   3110 
   3111 		const NativeHandle						fd				(getMemoryFd(vkd, *device, *memory, config.externalType));
   3112 		NativeHandle							secondFd		(getMemoryFd(vkd, *device, *memory, config.externalType));
   3113 		const int								newFd			(dup2(fd.getFd(), secondFd.getFd()));
   3114 
   3115 		if (newFd < 0)
   3116 			log << TestLog::Message << "dup2() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
   3117 
   3118 		TCU_CHECK_MSG(newFd >= 0, "Failed to call dup2() for memorys fd");
   3119 
   3120 		{
   3121 			const vk::Unique<vk::VkDeviceMemory>	newMemory	(importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, secondFd));
   3122 
   3123 			if (config.hostVisible)
   3124 			{
   3125 				const std::vector<deUint8>	testDataA	(genTestData(seed ^ 99012346u, (size_t)bufferSize));
   3126 
   3127 				checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
   3128 
   3129 				writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
   3130 				checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
   3131 			}
   3132 		}
   3133 
   3134 		return tcu::TestStatus::pass("Pass");
   3135 	}
   3136 #else
   3137 	DE_UNREF(context);
   3138 	DE_UNREF(config);
   3139 	TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
   3140 #endif
   3141 }
   3142 
   3143 tcu::TestStatus testMemoryFdDup3 (Context& context, MemoryTestConfig config)
   3144 {
   3145 #if (DE_OS == DE_OS_UNIX) && defined(_GNU_SOURCE)
   3146 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   3147 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   3148 	const vk::InstanceDriver			vki					(vkp, *instance);
   3149 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   3150 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   3151 
   3152 	{
   3153 		const vk::Unique<vk::VkDevice>			device			(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
   3154 		const vk::DeviceDriver					vkd				(vki, *device);
   3155 
   3156 		TestLog&								log				= context.getTestContext().getLog();
   3157 		const vk::VkBufferUsageFlags			usage			= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   3158 		const vk::VkDeviceSize					bufferSize		= 1024;
   3159 		const deUint32							seed			= 2554088961u;
   3160 		const std::vector<deUint8>				testData		(genTestData(seed, (size_t)bufferSize));
   3161 
   3162 		checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
   3163 
   3164 		deUint32								exportedMemoryTypeIndex	= ~0U;
   3165 		// \note Buffer is only allocated to get memory requirements
   3166 		const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   3167 		const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
   3168 		const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
   3169 
   3170 		if (config.hostVisible)
   3171 			writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
   3172 
   3173 		const NativeHandle						fd				(getMemoryFd(vkd, *device, *memory, config.externalType));
   3174 		NativeHandle							secondFd		(getMemoryFd(vkd, *device, *memory, config.externalType));
   3175 		const int								newFd			(dup3(fd.getFd(), secondFd.getFd(), 0));
   3176 
   3177 		if (newFd < 0)
   3178 			log << TestLog::Message << "dup3() failed: '" << strerror(errno) << "'" << TestLog::EndMessage;
   3179 
   3180 		TCU_CHECK_MSG(newFd >= 0, "Failed to call dup3() for memorys fd");
   3181 
   3182 		{
   3183 			const vk::Unique<vk::VkDeviceMemory>	newMemory	(importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, secondFd));
   3184 
   3185 			if (config.hostVisible)
   3186 			{
   3187 				const std::vector<deUint8>	testDataA	(genTestData(seed ^ 4210342378u, (size_t)bufferSize));
   3188 
   3189 				checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
   3190 
   3191 				writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
   3192 				checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
   3193 			}
   3194 		}
   3195 
   3196 		return tcu::TestStatus::pass("Pass");
   3197 	}
   3198 #else
   3199 	DE_UNREF(context);
   3200 	DE_UNREF(config);
   3201 	TCU_THROW(NotSupportedError, "Platform doesn't support dup()");
   3202 #endif
   3203 }
   3204 
   3205 tcu::TestStatus testMemoryFdSendOverSocket (Context& context, MemoryTestConfig config)
   3206 {
   3207 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
   3208 	const vk::PlatformInterface&				vkp					(context.getPlatformInterface());
   3209 	const vk::Unique<vk::VkInstance>			instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   3210 	const vk::InstanceDriver					vki					(vkp, *instance);
   3211 	const vk::VkPhysicalDevice					physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   3212 	const deUint32								queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   3213 
   3214 	{
   3215 		const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex));
   3216 		const vk::DeviceDriver					vkd					(vki, *device);
   3217 
   3218 		TestLog&								log					= context.getTestContext().getLog();
   3219 		const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   3220 		const vk::VkDeviceSize					bufferSize			= 1024;
   3221 		const deUint32							seed				= 3403586456u;
   3222 		const std::vector<deUint8>				testData			(genTestData(seed, (size_t)bufferSize));
   3223 
   3224 		checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
   3225 
   3226 		deUint32								exportedMemoryTypeIndex	= ~0U;
   3227 		// \note Buffer is only allocated to get memory requirements
   3228 		const vk::Unique<vk::VkBuffer>			buffer					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   3229 		const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *buffer));
   3230 		const vk::Unique<vk::VkDeviceMemory>	memory					(allocateExportableMemory(vki, physicalDevice, vkd, *device, requirements, config.externalType, config.hostVisible, config.dedicated ? *buffer : (vk::VkBuffer)0, exportedMemoryTypeIndex));
   3231 
   3232 		if (config.hostVisible)
   3233 			writeHostMemory(vkd, *device, *memory, testData.size(), &testData[0]);
   3234 
   3235 		const NativeHandle						fd					(getMemoryFd(vkd, *device, *memory, config.externalType));
   3236 
   3237 		{
   3238 			int sv[2];
   3239 
   3240 			if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0)
   3241 			{
   3242 				log << TestLog::Message << "Failed to create socket pair: '" << strerror(errno) << "'" << TestLog::EndMessage;
   3243 				TCU_FAIL("Failed to create socket pair");
   3244 			}
   3245 
   3246 			{
   3247 				const NativeHandle	srcSocket	(sv[0]);
   3248 				const NativeHandle	dstSocket	(sv[1]);
   3249 				std::string			sendData	("deqp");
   3250 
   3251 				// Send FD
   3252 				{
   3253 					const int			fdRaw	(fd.getFd());
   3254 					msghdr				msg;
   3255 					cmsghdr*			cmsg;
   3256 					char				tmpBuffer[CMSG_SPACE(sizeof(int))];
   3257 					iovec				iov		= { &sendData[0], sendData.length()};
   3258 
   3259 					deMemset(&msg, 0, sizeof(msg));
   3260 
   3261 					msg.msg_control		= tmpBuffer;
   3262 					msg.msg_controllen	= sizeof(tmpBuffer);
   3263 					msg.msg_iovlen		= 1;
   3264 					msg.msg_iov			= &iov;
   3265 
   3266 					cmsg				= CMSG_FIRSTHDR(&msg);
   3267 					cmsg->cmsg_level	= SOL_SOCKET;
   3268 					cmsg->cmsg_type		= SCM_RIGHTS;
   3269 					cmsg->cmsg_len		= CMSG_LEN(sizeof(int));
   3270 
   3271 					deMemcpy(CMSG_DATA(cmsg), &fdRaw, sizeof(int));
   3272 					msg.msg_controllen = cmsg->cmsg_len;
   3273 
   3274 					if (sendmsg(srcSocket.getFd(), &msg, 0) < 0)
   3275 					{
   3276 						log << TestLog::Message << "Failed to send fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
   3277 						TCU_FAIL("Failed to send fd over socket");
   3278 					}
   3279 				}
   3280 
   3281 				// Recv FD
   3282 				{
   3283 					msghdr			msg;
   3284 					char			tmpBuffer[CMSG_SPACE(sizeof(int))];
   3285 					std::string		recvData	(4, '\0');
   3286 					iovec			iov			= { &recvData[0], recvData.length() };
   3287 
   3288 					deMemset(&msg, 0, sizeof(msg));
   3289 
   3290 					msg.msg_control		= tmpBuffer;
   3291 					msg.msg_controllen	= sizeof(tmpBuffer);
   3292 					msg.msg_iovlen		= 1;
   3293 					msg.msg_iov			= &iov;
   3294 
   3295 					const ssize_t	bytes = recvmsg(dstSocket.getFd(), &msg, 0);
   3296 
   3297 					if (bytes < 0)
   3298 					{
   3299 						log << TestLog::Message << "Failed to recv fd over socket: '" << strerror(errno) << "'" << TestLog::EndMessage;
   3300 						TCU_FAIL("Failed to recv fd over socket");
   3301 
   3302 					}
   3303 					else if (bytes != (ssize_t)sendData.length())
   3304 					{
   3305 						TCU_FAIL("recvmsg() returned unpexpected number of bytes");
   3306 					}
   3307 					else
   3308 					{
   3309 						const cmsghdr* const	cmsg	= CMSG_FIRSTHDR(&msg);
   3310 						int						newFd_;
   3311 						deMemcpy(&newFd_, CMSG_DATA(cmsg), sizeof(int));
   3312 						NativeHandle			newFd	(newFd_);
   3313 
   3314 						TCU_CHECK(cmsg->cmsg_level == SOL_SOCKET);
   3315 						TCU_CHECK(cmsg->cmsg_type == SCM_RIGHTS);
   3316 						TCU_CHECK(cmsg->cmsg_len == CMSG_LEN(sizeof(int)));
   3317 						TCU_CHECK(recvData == sendData);
   3318 						TCU_CHECK_MSG(newFd.getFd() >= 0, "Didn't receive valid fd from socket");
   3319 
   3320 						{
   3321 							const vk::Unique<vk::VkDeviceMemory> newMemory (importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, newFd));
   3322 
   3323 							if (config.hostVisible)
   3324 							{
   3325 								const std::vector<deUint8>	testDataA	(genTestData(seed ^ 23478978u, (size_t)bufferSize));
   3326 
   3327 								checkHostMemory(vkd, *device, *newMemory, testData.size(), &testData[0]);
   3328 
   3329 								writeHostMemory(vkd, *device, *newMemory, testDataA.size(), &testDataA[0]);
   3330 								checkHostMemory(vkd, *device, *memory, testDataA.size(), &testDataA[0]);
   3331 							}
   3332 						}
   3333 					}
   3334 				}
   3335 			}
   3336 		}
   3337 	}
   3338 
   3339 	return tcu::TestStatus::pass("Pass");
   3340 #else
   3341 	DE_UNREF(context);
   3342 	DE_UNREF(config);
   3343 	TCU_THROW(NotSupportedError, "Platform doesn't support sending file descriptors over socket");
   3344 #endif
   3345 }
   3346 
   3347 struct BufferTestConfig
   3348 {
   3349 											BufferTestConfig	(vk::VkExternalMemoryHandleTypeFlagBits		externalType_,
   3350 																 bool										dedicated_)
   3351 		: externalType	(externalType_)
   3352 		, dedicated		(dedicated_)
   3353 	{
   3354 	}
   3355 
   3356 	vk::VkExternalMemoryHandleTypeFlagBits	externalType;
   3357 	bool									dedicated;
   3358 };
   3359 
   3360 tcu::TestStatus testBufferBindExportImportBind (Context&				context,
   3361 												const BufferTestConfig	config)
   3362 {
   3363 	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
   3364 	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   3365 	const vk::InstanceDriver				vki					(vkp, *instance);
   3366 	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   3367 	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   3368 	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
   3369 	const vk::DeviceDriver					vkd					(vki, *device);
   3370 	const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   3371 	const vk::VkDeviceSize					bufferSize			= 1024;
   3372 
   3373 	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
   3374 
   3375 	deUint32								exportedMemoryTypeIndex	= ~0U;
   3376 	// \note Buffer is only allocated to get memory requirements
   3377 	const vk::Unique<vk::VkBuffer>			bufferA					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   3378 	const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *bufferA));
   3379 	const vk::Unique<vk::VkDeviceMemory>	memoryA					(allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0, exportedMemoryTypeIndex));
   3380 	NativeHandle							handle;
   3381 
   3382 	VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
   3383 
   3384 	getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
   3385 
   3386 	{
   3387 		const vk::Unique<vk::VkDeviceMemory>	memoryB	(importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
   3388 		const vk::Unique<vk::VkBuffer>			bufferB	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   3389 
   3390 		VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
   3391 	}
   3392 
   3393 	return tcu::TestStatus::pass("Pass");
   3394 }
   3395 
   3396 tcu::TestStatus testBufferExportBindImportBind (Context&				context,
   3397 												const BufferTestConfig	config)
   3398 {
   3399 	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
   3400 	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   3401 	const vk::InstanceDriver				vki					(vkp, *instance);
   3402 	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   3403 	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   3404 	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
   3405 	const vk::DeviceDriver					vkd					(vki, *device);
   3406 	const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   3407 	const vk::VkDeviceSize					bufferSize			= 1024;
   3408 
   3409 	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
   3410 
   3411 	deUint32								exportedMemoryTypeIndex	= ~0U;
   3412 	// \note Buffer is only allocated to get memory requirements
   3413 	const vk::Unique<vk::VkBuffer>			bufferA					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   3414 	const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *bufferA));
   3415 	const vk::Unique<vk::VkDeviceMemory>	memoryA					(allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0, exportedMemoryTypeIndex));
   3416 	NativeHandle							handle;
   3417 
   3418 	getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
   3419 	VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
   3420 
   3421 	{
   3422 		const vk::Unique<vk::VkDeviceMemory>	memoryB	(importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
   3423 		const vk::Unique<vk::VkBuffer>			bufferB	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   3424 
   3425 		VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
   3426 	}
   3427 
   3428 	return tcu::TestStatus::pass("Pass");
   3429 }
   3430 
   3431 tcu::TestStatus testBufferExportImportBindBind (Context&				context,
   3432 												const BufferTestConfig	config)
   3433 {
   3434 	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
   3435 	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   3436 	const vk::InstanceDriver				vki					(vkp, *instance);
   3437 	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   3438 	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   3439 	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
   3440 	const vk::DeviceDriver					vkd					(vki, *device);
   3441 	const vk::VkBufferUsageFlags			usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   3442 	const vk::VkDeviceSize					bufferSize			= 1024;
   3443 
   3444 	checkBufferSupport(vki, physicalDevice, config.externalType, 0u, usage, config.dedicated);
   3445 
   3446 	deUint32								exportedMemoryTypeIndex	= ~0U;
   3447 	// \note Buffer is only allocated to get memory requirements
   3448 	const vk::Unique<vk::VkBuffer>			bufferA					(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   3449 	const vk::VkMemoryRequirements			requirements			(getBufferMemoryRequirements(vkd, *device, *bufferA));
   3450 	const vk::Unique<vk::VkDeviceMemory>	memoryA					(allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *bufferA : (vk::VkBuffer)0, exportedMemoryTypeIndex));
   3451 	NativeHandle							handle;
   3452 
   3453 	getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
   3454 
   3455 	{
   3456 		const vk::Unique<vk::VkDeviceMemory>	memoryB	(importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
   3457 		const vk::Unique<vk::VkBuffer>			bufferB	(createExternalBuffer(vkd, *device, queueFamilyIndex, config.externalType, bufferSize, 0u, usage));
   3458 
   3459 		VK_CHECK(vkd.bindBufferMemory(*device, *bufferA, *memoryA, 0u));
   3460 		VK_CHECK(vkd.bindBufferMemory(*device, *bufferB, *memoryB, 0u));
   3461 	}
   3462 
   3463 	return tcu::TestStatus::pass("Pass");
   3464 }
   3465 
   3466 tcu::TestStatus testImageQueries (Context& context, vk::VkExternalMemoryHandleTypeFlagBits externalType)
   3467 {
   3468 	const vk::VkImageCreateFlags		createFlags[]		=
   3469 	{
   3470 		0u,
   3471 		vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT,
   3472 		vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT|vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,
   3473 		vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT|vk::VK_IMAGE_CREATE_SPARSE_ALIASED_BIT,
   3474 		vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
   3475 		vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,
   3476 		vk::VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT
   3477 	};
   3478 	const vk::VkImageUsageFlags			usageFlags[]		=
   3479 	{
   3480 		vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   3481 		vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   3482 		vk::VK_IMAGE_USAGE_SAMPLED_BIT,
   3483 		vk::VK_IMAGE_USAGE_STORAGE_BIT,
   3484 		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
   3485 		vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
   3486 		vk::VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT,
   3487 		vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
   3488 	};
   3489 	const vk::PlatformInterface&		vkp					(context.getPlatformInterface());
   3490 	const vk::Unique<vk::VkInstance>	instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, externalType, 0u));
   3491 	const vk::InstanceDriver			vki					(vkp, *instance);
   3492 	const vk::VkPhysicalDevice			physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   3493 	const vk::VkPhysicalDeviceFeatures	deviceFeatures		(vk::getPhysicalDeviceFeatures(vki, physicalDevice));
   3494 	const deUint32						queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   3495 
   3496 	// VkDevice is only created if physical device claims to support any of these types.
   3497 	vk::Move<vk::VkDevice>				device;
   3498 	de::MovePtr<vk::DeviceDriver>		vkd;
   3499 	bool								deviceHasDedicated	= false;
   3500 
   3501 	TestLog&							log					= context.getTestContext().getLog();
   3502 
   3503 	for (size_t createFlagNdx = 0; createFlagNdx < DE_LENGTH_OF_ARRAY(createFlags); createFlagNdx++)
   3504 	for (size_t usageFlagNdx = 0; usageFlagNdx < DE_LENGTH_OF_ARRAY(usageFlags); usageFlagNdx++)
   3505 	{
   3506 		const vk::VkImageViewCreateFlags						createFlag		= createFlags[createFlagNdx];
   3507 		const vk::VkImageUsageFlags								usageFlag		= usageFlags[usageFlagNdx];
   3508 		const vk::VkFormat										format			= vk::VK_FORMAT_R8G8B8A8_UNORM;
   3509 		const vk::VkImageType									type			= vk::VK_IMAGE_TYPE_2D;
   3510 		const vk::VkImageTiling									tiling			= vk::VK_IMAGE_TILING_OPTIMAL;
   3511 		const vk::VkPhysicalDeviceExternalImageFormatInfo		externalInfo	=
   3512 		{
   3513 			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
   3514 			DE_NULL,
   3515 			externalType
   3516 		};
   3517 		const vk::VkPhysicalDeviceImageFormatInfo2				info			=
   3518 		{
   3519 			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
   3520 			&externalInfo,
   3521 
   3522 			format,
   3523 			type,
   3524 			tiling,
   3525 			usageFlag,
   3526 			createFlag,
   3527 		};
   3528 		vk::VkExternalImageFormatProperties						externalProperties	=
   3529 		{
   3530 			vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
   3531 			DE_NULL,
   3532 			{ 0u, 0u, 0u }
   3533 		};
   3534 		vk::VkImageFormatProperties2							properties			=
   3535 		{
   3536 			vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
   3537 			&externalProperties,
   3538 			{
   3539 				{ 0u, 0u, 0u },
   3540 				0u,
   3541 				0u,
   3542 				0u,
   3543 				0u
   3544 			}
   3545 		};
   3546 
   3547 		if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != 0) &&
   3548 			(deviceFeatures.sparseBinding == VK_FALSE))
   3549 			continue;
   3550 
   3551 		if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) != 0) &&
   3552 			(deviceFeatures.sparseResidencyImage2D == VK_FALSE))
   3553 			continue;
   3554 
   3555 		if (((createFlag & vk::VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) != 0) &&
   3556 			(deviceFeatures.sparseResidencyAliased == VK_FALSE))
   3557 			continue;
   3558 
   3559 		vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &info, &properties);
   3560 
   3561 		log << TestLog::Message << externalProperties << TestLog::EndMessage;
   3562 		TCU_CHECK(externalProperties.sType == vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES);
   3563 		TCU_CHECK(externalProperties.pNext == DE_NULL);
   3564 		// \todo [2017-06-06 pyry] Can we validate anything else? Compatible types?
   3565 
   3566 		if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & (vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT|vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT)) != 0)
   3567 		{
   3568 			const bool	requiresDedicated	= (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0;
   3569 
   3570 			if (!device || (requiresDedicated && !deviceHasDedicated))
   3571 			{
   3572 				// \note We need to re-create with dedicated mem extensions if previous device instance didn't have them
   3573 				try
   3574 				{
   3575 					device				= createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, externalType, 0u, queueFamilyIndex, requiresDedicated);
   3576 					vkd					= de::MovePtr<vk::DeviceDriver>(new vk::DeviceDriver(vki, *device));
   3577 					deviceHasDedicated	= requiresDedicated;
   3578 				}
   3579 				catch (const tcu::NotSupportedError& e)
   3580 				{
   3581 					log << e;
   3582 					TCU_FAIL("Physical device claims to support handle type but required extensions are not supported");
   3583 				}
   3584 			}
   3585 		}
   3586 
   3587 		if ((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) != 0)
   3588 		{
   3589 			DE_ASSERT(!!device);
   3590 			DE_ASSERT(vkd);
   3591 
   3592 			if (deviceHasDedicated)
   3593 			{
   3594 				const vk::Unique<vk::VkImage>				image						(createExternalImage(*vkd, *device, queueFamilyIndex, externalType, format, 16u, 16u, tiling, createFlag, usageFlag));
   3595 				const vk::VkMemoryDedicatedRequirements		reqs						(getMemoryDedicatedRequirements(*vkd, *device, *image));
   3596 				const bool									propertiesRequiresDedicated	= (externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0;
   3597 				const bool									objectRequiresDedicated		= (reqs.requiresDedicatedAllocation != VK_FALSE);
   3598 
   3599 				if (propertiesRequiresDedicated != objectRequiresDedicated)
   3600 					TCU_FAIL("vkGetPhysicalDeviceExternalBufferProperties and vkGetBufferMemoryRequirements2 report different dedicated requirements");
   3601 			}
   3602 			else
   3603 			{
   3604 				// We can't query whether dedicated memory is required or not on per-object basis.
   3605 				// This check should be redundant as the code above tries to create device with
   3606 				// VK_KHR_dedicated_allocation & VK_KHR_get_memory_requirements2 if dedicated memory
   3607 				// is required. However, checking again doesn't hurt.
   3608 				TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) == 0);
   3609 			}
   3610 		}
   3611 	}
   3612 
   3613 	return tcu::TestStatus::pass("Pass");
   3614 }
   3615 
   3616 struct ImageTestConfig
   3617 {
   3618 											ImageTestConfig	(vk::VkExternalMemoryHandleTypeFlagBits		externalType_,
   3619 															 bool										dedicated_)
   3620 		: externalType	(externalType_)
   3621 		, dedicated		(dedicated_)
   3622 	{
   3623 	}
   3624 
   3625 	vk::VkExternalMemoryHandleTypeFlagBits	externalType;
   3626 	bool									dedicated;
   3627 };
   3628 
   3629 tcu::TestStatus testImageBindExportImportBind (Context&					context,
   3630 											   const ImageTestConfig	config)
   3631 {
   3632 	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
   3633 	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   3634 	const vk::InstanceDriver				vki					(vkp, *instance);
   3635 	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   3636 	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   3637 	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
   3638 	const vk::DeviceDriver					vkd					(vki, *device);
   3639 	const vk::VkImageUsageFlags				usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   3640 	const vk::VkFormat						format				= vk::VK_FORMAT_R8G8B8A8_UNORM;
   3641 	const deUint32							width				= 64u;
   3642 	const deUint32							height				= 64u;
   3643 	const vk::VkImageTiling					tiling				= vk::VK_IMAGE_TILING_OPTIMAL;
   3644 
   3645 	checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);
   3646 
   3647 	deUint32								exportedMemoryTypeIndex	= ~0U;
   3648 	const vk::Unique<vk::VkImage>			imageA					(createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
   3649 	const vk::VkMemoryRequirements			requirements			(getImageMemoryRequirements(vkd, *device, *imageA));
   3650 	const vk::Unique<vk::VkDeviceMemory>	memoryA					(allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0, exportedMemoryTypeIndex));
   3651 	NativeHandle							handle;
   3652 
   3653 	VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
   3654 
   3655 	getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
   3656 
   3657 	{
   3658 		const vk::Unique<vk::VkImage>			imageB	(createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
   3659 		const vk::Unique<vk::VkDeviceMemory>	memoryB	(config.dedicated
   3660 														 ? importDedicatedMemory(vkd, *device, *imageB, requirements, config.externalType, exportedMemoryTypeIndex, handle)
   3661 														 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
   3662 
   3663 		VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
   3664 	}
   3665 
   3666 	return tcu::TestStatus::pass("Pass");
   3667 }
   3668 
   3669 tcu::TestStatus testImageExportBindImportBind (Context&					context,
   3670 											   const ImageTestConfig	config)
   3671 {
   3672 	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
   3673 	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   3674 	const vk::InstanceDriver				vki					(vkp, *instance);
   3675 	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   3676 	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   3677 	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
   3678 	const vk::DeviceDriver					vkd					(vki, *device);
   3679 	const vk::VkImageUsageFlags				usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   3680 	const vk::VkFormat						format				= vk::VK_FORMAT_R8G8B8A8_UNORM;
   3681 	const deUint32							width				= 64u;
   3682 	const deUint32							height				= 64u;
   3683 	const vk::VkImageTiling					tiling				= vk::VK_IMAGE_TILING_OPTIMAL;
   3684 
   3685 	checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);
   3686 
   3687 	deUint32								exportedMemoryTypeIndex	= ~0U;
   3688 	const vk::Unique<vk::VkImage>			imageA					(createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
   3689 	const vk::VkMemoryRequirements			requirements			(getImageMemoryRequirements(vkd, *device, *imageA));
   3690 	const vk::Unique<vk::VkDeviceMemory>	memoryA					(allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0, exportedMemoryTypeIndex));
   3691 	NativeHandle							handle;
   3692 
   3693 	getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
   3694 	VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
   3695 
   3696 	{
   3697 		const vk::Unique<vk::VkImage>			imageB	(createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
   3698 		const vk::Unique<vk::VkDeviceMemory>	memoryB	(config.dedicated
   3699 														 ? importDedicatedMemory(vkd, *device, *imageB, requirements, config.externalType, exportedMemoryTypeIndex, handle)
   3700 														 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
   3701 
   3702 		VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
   3703 	}
   3704 
   3705 	return tcu::TestStatus::pass("Pass");
   3706 }
   3707 
   3708 tcu::TestStatus testImageExportImportBindBind (Context&					context,
   3709 											   const ImageTestConfig	config)
   3710 {
   3711 	const vk::PlatformInterface&			vkp					(context.getPlatformInterface());
   3712 	const vk::Unique<vk::VkInstance>		instance			(createInstance(vkp, context.getUsedApiVersion(), 0u, config.externalType, 0u));
   3713 	const vk::InstanceDriver				vki					(vkp, *instance);
   3714 	const vk::VkPhysicalDevice				physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   3715 	const deUint32							queueFamilyIndex	(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   3716 	const vk::Unique<vk::VkDevice>			device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, config.externalType, 0u, queueFamilyIndex, config.dedicated));
   3717 	const vk::DeviceDriver					vkd					(vki, *device);
   3718 	const vk::VkImageUsageFlags				usage				= vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT|vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT;
   3719 	const vk::VkFormat						format				= vk::VK_FORMAT_R8G8B8A8_UNORM;
   3720 	const deUint32							width				= 64u;
   3721 	const deUint32							height				= 64u;
   3722 	const vk::VkImageTiling					tiling				= vk::VK_IMAGE_TILING_OPTIMAL;
   3723 
   3724 	checkImageSupport(vki, physicalDevice, config.externalType, 0u, usage, format, tiling, config.dedicated);
   3725 
   3726 	deUint32								exportedMemoryTypeIndex	= ~0U;
   3727 	// \note Image is only allocated to get memory requirements
   3728 	const vk::Unique<vk::VkImage>			imageA					(createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
   3729 	const vk::VkMemoryRequirements			requirements			(getImageMemoryRequirements(vkd, *device, *imageA));
   3730 	const vk::Unique<vk::VkDeviceMemory>	memoryA					(allocateExportableMemory(vkd, *device, requirements, config.externalType, config.dedicated ? *imageA : (vk::VkImage)0, exportedMemoryTypeIndex));
   3731 	NativeHandle							handle;
   3732 
   3733 	getMemoryNative(vkd, *device, *memoryA, config.externalType, handle);
   3734 
   3735 	{
   3736 		const vk::Unique<vk::VkImage>			imageB	(createExternalImage(vkd, *device, queueFamilyIndex, config.externalType, format, width, height, tiling, 0u, usage));
   3737 		const vk::Unique<vk::VkDeviceMemory>	memoryB	(config.dedicated
   3738 														 ? importDedicatedMemory(vkd, *device, *imageB, requirements, config.externalType, exportedMemoryTypeIndex, handle)
   3739 														 : importMemory(vkd, *device, requirements, config.externalType, exportedMemoryTypeIndex, handle));
   3740 
   3741 		VK_CHECK(vkd.bindImageMemory(*device, *imageA, *memoryA, 0u));
   3742 		VK_CHECK(vkd.bindImageMemory(*device, *imageB, *memoryB, 0u));
   3743 	}
   3744 
   3745 	return tcu::TestStatus::pass("Pass");
   3746 }
   3747 de::MovePtr<tcu::TestCaseGroup> createFenceTests (tcu::TestContext& testCtx, vk::VkExternalFenceHandleTypeFlagBits externalType)
   3748 {
   3749 	const struct
   3750 	{
   3751 		const char* const	name;
   3752 		const Permanence	permanence;
   3753 	} permanences[] =
   3754 	{
   3755 		{ "temporary", PERMANENCE_TEMPORARY	},
   3756 		{ "permanent", PERMANENCE_PERMANENT	}
   3757 	};
   3758 
   3759 	de::MovePtr<tcu::TestCaseGroup> fenceGroup (new tcu::TestCaseGroup(testCtx, externalFenceTypeToName(externalType), externalFenceTypeToName(externalType)));
   3760 
   3761 	addFunctionCase(fenceGroup.get(), "info",	"Test external fence queries.",	testFenceQueries,	externalType);
   3762 
   3763 	for (size_t permanenceNdx = 0; permanenceNdx < DE_LENGTH_OF_ARRAY(permanences); permanenceNdx++)
   3764 	{
   3765 		const Permanence		permanence		(permanences[permanenceNdx].permanence);
   3766 		const char* const		permanenceName	(permanences[permanenceNdx].name);
   3767 		const FenceTestConfig	config			(externalType, permanence);
   3768 
   3769 		if (!isSupportedPermanence(externalType, permanence))
   3770 			continue;
   3771 
   3772 		if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
   3773 			|| externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
   3774 		{
   3775 			addFunctionCase(fenceGroup.get(), std::string("create_win32_") + permanenceName,	"Test creating fence with win32 properties.",	testFenceWin32Create,	config);
   3776 		}
   3777 
   3778 		addFunctionCase(fenceGroup.get(), std::string("import_twice_") + permanenceName,				"Test importing fence twice.",											testFenceImportTwice,				config);
   3779 		addFunctionCase(fenceGroup.get(), std::string("reimport_") + permanenceName,					"Test importing again over previously imported fence.",					testFenceImportReimport,			config);
   3780 		addFunctionCase(fenceGroup.get(), std::string("import_multiple_times_") + permanenceName,		"Test importing fence multiple times.",									testFenceMultipleImports,			config);
   3781 		addFunctionCase(fenceGroup.get(), std::string("signal_export_import_wait_") + permanenceName,	"Test signaling, exporting, importing and waiting for the sempahore.",	testFenceSignalExportImportWait,	config);
   3782 		addFunctionCase(fenceGroup.get(), std::string("signal_import_") + permanenceName,				"Test signaling and importing the fence.",								testFenceSignalImport,				config);
   3783 		addFunctionCase(fenceGroup.get(), std::string("reset_") + permanenceName,						"Test resetting the fence.",											testFenceReset,						config);
   3784 		addFunctionCase(fenceGroup.get(), std::string("transference_") + permanenceName,				"Test fences transference.",											testFenceTransference,				config);
   3785 
   3786 		if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
   3787 			|| externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
   3788 		{
   3789 			// \note Not supported on WIN32 handles
   3790 			addFunctionCase(fenceGroup.get(), std::string("export_multiple_times_") + permanenceName,	"Test exporting fence multiple times.",		testFenceMultipleExports,	config);
   3791 
   3792 			addFunctionCase(fenceGroup.get(), std::string("dup_") + permanenceName,						"Test calling dup() on exported fence.",	testFenceFdDup,				config);
   3793 			addFunctionCase(fenceGroup.get(), std::string("dup2_") + permanenceName,					"Test calling dup2() on exported fence.",	testFenceFdDup2,			config);
   3794 			addFunctionCase(fenceGroup.get(), std::string("dup3_") + permanenceName,					"Test calling dup3() on exported fence.",	testFenceFdDup3,			config);
   3795 			addFunctionCase(fenceGroup.get(), std::string("send_over_socket_") + permanenceName,		"Test sending fence fd over socket.",		testFenceFdSendOverSocket,	config);
   3796 		}
   3797 
   3798 		if (getHandelTypeTransferences(externalType) == TRANSFERENCE_REFERENCE)
   3799 		{
   3800 			addFunctionCase(fenceGroup.get(), std::string("signal_wait_import_") + permanenceName,			"Test signaling and then waiting for the the sepmahore.",			testFenceSignalWaitImport,			config);
   3801 			addFunctionCase(fenceGroup.get(), std::string("export_signal_import_wait_") + permanenceName,	"Test exporting, signaling, importing and waiting for the fence.",	testFenceExportSignalImportWait,	config);
   3802 			addFunctionCase(fenceGroup.get(), std::string("export_import_signal_wait_") + permanenceName,	"Test exporting, importing, signaling and waiting for the fence.",	testFenceExportImportSignalWait,	config);
   3803 		}
   3804 	}
   3805 
   3806 	return fenceGroup;
   3807 }
   3808 
   3809 #if defined(USE_ANDROID_O_HARDWARE_BUFFER)
   3810 deUint32 vkUsageToAhbUsage(deUint64 vkFlag) {
   3811 	switch(vkFlag) {
   3812 		case vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT:
   3813 		case vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT:
   3814 			// No AHB equivalent.
   3815 			return 0u;
   3816 		case vk::VK_IMAGE_USAGE_SAMPLED_BIT:
   3817 			return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
   3818 		case vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT:
   3819 			return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
   3820 		case vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT:
   3821 			return AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
   3822 	}
   3823 	return 0u;
   3824 }
   3825 
   3826 deUint32 vkCreateToAhbUsage(deUint64 vkFlag) {
   3827 	switch(vkFlag) {
   3828 		case vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT:
   3829 		case vk::VK_IMAGE_CREATE_EXTENDED_USAGE_BIT:
   3830 			// No AHB equivalent.
   3831 			return 0u;
   3832 		case vk::VK_IMAGE_CREATE_PROTECTED_BIT:
   3833 			return AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
   3834 #if defined(USE_ANDROID_P_HARDWARE_BUFFER)
   3835 		case vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT:
   3836 			return AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
   3837 #endif
   3838 	}
   3839 	return 0u;
   3840 }
   3841 
   3842 deUint32 vkFormatToAhbFormat(deUint64 vkFormat) {
   3843 	switch(vkFormat) {
   3844 		case vk::VK_FORMAT_R8G8B8A8_UNORM:
   3845 			return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
   3846 		case vk::VK_FORMAT_R8G8B8_UNORM:
   3847 			return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
   3848 		case vk::VK_FORMAT_R5G6B5_UNORM_PACK16:
   3849 			return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
   3850 		case vk::VK_FORMAT_R16G16B16A16_SFLOAT:
   3851 			return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
   3852 		case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32:
   3853 			return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
   3854 	}
   3855 	return 0u;
   3856 }
   3857 
   3858 bool ValidateAHardwareBuffer(vk::VkFormat format, deUint32 requiredAhbUsage, const vk::DeviceDriver& vkd, const vk::VkDevice& device) {
   3859 	AHardwareBuffer_Desc    hbufferdesc =
   3860 	{
   3861 		64u,
   3862 		64u,
   3863 		1u,
   3864 		vkFormatToAhbFormat(format),
   3865 		requiredAhbUsage,
   3866 		0u,
   3867 		0u,
   3868 		0u
   3869 	};
   3870 	AHardwareBuffer* hbuffer      = DE_NULL;
   3871 	AHardwareBuffer_allocate(&hbufferdesc, &hbuffer);
   3872 	if (!hbuffer)
   3873 		return false;
   3874 
   3875 	NativeHandle nativeHandle;
   3876 	nativeHandle = vk::pt::AndroidHardwareBufferPtr(hbuffer);
   3877 
   3878 	vk::VkAndroidHardwareBufferFormatPropertiesANDROID formatProperties =
   3879 	{
   3880 		vk::VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID,
   3881 		DE_NULL,
   3882 		vk::VK_FORMAT_UNDEFINED,
   3883 		0u,
   3884 		0u,
   3885 		vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
   3886 		vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
   3887 		vk::VK_CHROMA_LOCATION_COSITED_EVEN,
   3888 		vk::VK_CHROMA_LOCATION_COSITED_EVEN
   3889 	};
   3890 	vk::VkAndroidHardwareBufferPropertiesANDROID bufferProperties = {
   3891 		vk::VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID,
   3892 		&formatProperties,
   3893 		0u,
   3894 		0u
   3895 	};
   3896 
   3897 	VK_CHECK(vkd.getAndroidHardwareBufferPropertiesANDROID(device, vk::pt::AndroidHardwareBufferPtr(hbuffer), &bufferProperties));
   3898 	TCU_CHECK(formatProperties.format != vk::VK_FORMAT_UNDEFINED);
   3899 	TCU_CHECK(formatProperties.format == format);
   3900 	TCU_CHECK(formatProperties.externalFormat != 0u);
   3901 	TCU_CHECK((formatProperties.formatFeatures & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0u);
   3902 	TCU_CHECK((formatProperties.formatFeatures & (vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT | vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) != 0u);
   3903 	return true;
   3904 }
   3905 #endif
   3906 
   3907 tcu::TestStatus testAndroidHardwareBufferImageFormat(Context& context, vk::VkFormat format)
   3908 {
   3909 #if defined(USE_ANDROID_O_HARDWARE_BUFFER)
   3910 	const vk::VkExternalMemoryHandleTypeFlagBits  externalMemoryType  =	vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
   3911 	const vk::PlatformInterface&				  vkp					(context.getPlatformInterface());
   3912 	const vk::Unique<vk::VkInstance>			  instance				(createInstance(vkp, context.getUsedApiVersion(), externalMemoryType, 0u, 0u));
   3913 	const vk::InstanceDriver					  vki					(vkp, *instance);
   3914 	const vk::VkPhysicalDevice					  physicalDevice		(vk::chooseDevice(vki, *instance, context.getTestContext().getCommandLine()));
   3915 	const deUint32								  queueFamilyIndex		(chooseQueueFamilyIndex(vki, physicalDevice, 0u));
   3916 	const vk::VkImageTiling						  tiling			  =	vk::VK_IMAGE_TILING_OPTIMAL;
   3917 	const vk::Unique<vk::VkDevice>				  device				(createDevice(context.getUsedApiVersion(), vki, physicalDevice, 0u, externalMemoryType, 0u, queueFamilyIndex, true));
   3918 	const vk::DeviceDriver						  vkd					(vki, *device);
   3919 
   3920 	const vk::VkImageUsageFlagBits				  usageFlags[]		  =
   3921 	{
   3922 		vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
   3923 		vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
   3924 		vk::VK_IMAGE_USAGE_SAMPLED_BIT,
   3925 		vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
   3926 		vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
   3927 	};
   3928 	const vk::VkImageCreateFlagBits				  createFlags[]		  =
   3929 	{
   3930 		vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT,
   3931 		vk::VK_IMAGE_CREATE_EXTENDED_USAGE_BIT,
   3932 		vk::VK_IMAGE_CREATE_PROTECTED_BIT,
   3933 		vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT,
   3934 	};
   3935 	deUint32 mustSupportAhbUsageFlags =
   3936 			AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
   3937 			AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
   3938 #if defined(USE_ANDROID_P_HARDWARE_BUFFER)
   3939 	mustSupportAhbUsageFlags |=
   3940 			AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP |
   3941 			AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
   3942 #endif
   3943 	const size_t	numOfUsageFlags				= DE_LENGTH_OF_ARRAY(usageFlags);
   3944 	const size_t	numOfCreateFlags			= DE_LENGTH_OF_ARRAY(createFlags);
   3945 	const size_t	numOfFlagCombos				= 1u << (numOfUsageFlags + numOfCreateFlags);
   3946 
   3947 	for (size_t combo = 0; combo < numOfFlagCombos; combo++)
   3948 	{
   3949 		vk::VkImageUsageFlags	usage				= 0;
   3950 		vk::VkImageCreateFlags	createFlag			= 0;
   3951 		deUint32				requiredAhbUsage	= 0;
   3952 		for (size_t usageNdx = 0; usageNdx < numOfUsageFlags; usageNdx++)
   3953 		{
   3954 			if ((combo & (1u << usageNdx)) == 0)
   3955 				continue;
   3956 			usage |= usageFlags[usageNdx];
   3957 			requiredAhbUsage |= vkUsageToAhbUsage(usageFlags[usageNdx]);
   3958 		}
   3959 		for (size_t createFlagNdx = 0; createFlagNdx < numOfCreateFlags; createFlagNdx++)
   3960 		{
   3961 			const size_t	bit	= numOfUsageFlags + createFlagNdx;
   3962 			if ((combo & (1u << bit)) == 0)
   3963 				continue;
   3964 			createFlag |= createFlags[createFlagNdx];
   3965 			requiredAhbUsage |= vkCreateToAhbUsage(createFlags[createFlagNdx]);
   3966 		}
   3967 
   3968 		// Only test a combination if the usage flags include at least one of the AHARDWAREBUFFER_USAGE_GPU_* flag.
   3969 		if ((requiredAhbUsage & mustSupportAhbUsageFlags) == 0u)
   3970 			continue;
   3971 
   3972 		// Only test a combination if AHardwareBuffer can be successfully allocated for it.
   3973 		if (!ValidateAHardwareBuffer(format, requiredAhbUsage, vkd, *device))
   3974 			continue;
   3975 
   3976 		const vk::VkPhysicalDeviceExternalImageFormatInfo	externalInfo		=
   3977 		{
   3978 			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
   3979 			DE_NULL,
   3980 			vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID
   3981 		};
   3982 		const vk::VkPhysicalDeviceImageFormatInfo2			info		=
   3983 		{
   3984 			vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
   3985 			&externalInfo,
   3986 			format,
   3987 			vk::VK_IMAGE_TYPE_2D,
   3988 			vk::VK_IMAGE_TILING_OPTIMAL,
   3989 			usage,
   3990 			createFlag,
   3991 		};
   3992 
   3993 		vk::VkAndroidHardwareBufferUsageANDROID				ahbUsageProperties	=
   3994 		{
   3995 			vk::VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID,
   3996 			DE_NULL,
   3997 			0u
   3998 		};
   3999 		vk::VkExternalImageFormatProperties					externalProperties	=
   4000 		{
   4001 			vk::VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
   4002 			&ahbUsageProperties,
   4003 			{ 0u, 0u, 0u }
   4004 		};
   4005 		vk::VkImageFormatProperties2						properties			=
   4006 		{
   4007 			vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
   4008 			&externalProperties,
   4009 			{
   4010 				{ 0u, 0u, 0u },
   4011 				0u,
   4012 				0u,
   4013 				0u,
   4014 				0u
   4015 			}
   4016 		};
   4017 
   4018 		vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &info, &properties);
   4019 		TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) != 0);
   4020 		TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) != 0);
   4021 		TCU_CHECK((externalProperties.externalMemoryProperties.externalMemoryFeatures & vk::VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT) != 0);
   4022 		deUint32 maxWidth   = properties.imageFormatProperties.maxExtent.width;
   4023 		deUint32 maxHeight  = properties.imageFormatProperties.maxExtent.height;
   4024 		TCU_CHECK(maxWidth >= 4096);
   4025 		TCU_CHECK(maxHeight >= 4096);
   4026 		// Even if not requested, at least one of GPU_* usage flags must be present.
   4027 		TCU_CHECK((ahbUsageProperties.androidHardwareBufferUsage & mustSupportAhbUsageFlags) != 0u);
   4028 		// The AHB usage flags corresponding to the create and usage flags used in info must be present.
   4029 		TCU_CHECK((ahbUsageProperties.androidHardwareBufferUsage & requiredAhbUsage) == requiredAhbUsage);
   4030 
   4031 		struct ImageSize {
   4032 			deUint32 width;
   4033 			deUint32 height;
   4034 		};
   4035 		ImageSize sizes[] = {
   4036 			{64u, 64u},
   4037 			{1024u, 2096u},
   4038 		};
   4039 		deUint32					exportedMemoryTypeIndex = ~0U;
   4040 		for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(sizes); i++) {
   4041 			const vk::Unique<vk::VkImage>		  image			(createExternalImage(vkd, *device, queueFamilyIndex, externalMemoryType, format, sizes[i].width, sizes[i].height, tiling, createFlag, usage));
   4042 			const vk::VkMemoryRequirements		  requirements	(getImageMemoryRequirements(vkd, *device, *image));
   4043 			const vk::Unique<vk::VkDeviceMemory>  memory		(allocateExportableMemory(vkd, *device, requirements, externalMemoryType, *image, exportedMemoryTypeIndex));
   4044 			NativeHandle						  handle;
   4045 
   4046 			VK_CHECK(vkd.bindImageMemory(*device, *image, *memory, 0u));
   4047 			getMemoryNative(vkd, *device, *memory, externalMemoryType, handle);
   4048 
   4049 			AHardwareBuffer_Desc desc;
   4050 			AHardwareBuffer_describe(static_cast<const AHardwareBuffer*>(handle.getAndroidHardwareBuffer().internal), &desc);
   4051 			TCU_CHECK(desc.format == vkFormatToAhbFormat(format));
   4052 			TCU_CHECK((desc.usage & requiredAhbUsage) == requiredAhbUsage);
   4053 		}
   4054 
   4055 		if (properties.imageFormatProperties.maxMipLevels > 1u) {
   4056 			const vk::Unique<vk::VkImage>			image			(createExternalImage(vkd, *device, queueFamilyIndex, externalMemoryType, format, 64u, 64u, tiling, createFlag, usage,
   4057 																						 properties.imageFormatProperties.maxMipLevels));
   4058 	        const vk::VkMemoryRequirements			requirements	(getImageMemoryRequirements(vkd, *device, *image));
   4059 	        const vk::Unique<vk::VkDeviceMemory>	memory			(allocateExportableMemory(vkd, *device, requirements, externalMemoryType, *image, exportedMemoryTypeIndex));
   4060 	        NativeHandle							handle;
   4061 
   4062 			VK_CHECK(vkd.bindImageMemory(*device, *image, *memory, 0u));
   4063 			getMemoryNative(vkd, *device, *memory, externalMemoryType, handle);
   4064 
   4065 			AHardwareBuffer_Desc desc;
   4066 			AHardwareBuffer_describe(static_cast<const AHardwareBuffer*>(handle.getAndroidHardwareBuffer().internal), &desc);
   4067 			TCU_CHECK(desc.format == vkFormatToAhbFormat(format));
   4068 			TCU_CHECK((desc.usage & requiredAhbUsage) == requiredAhbUsage);
   4069 		}
   4070 
   4071 		if (properties.imageFormatProperties.maxArrayLayers > 1u) {
   4072 			const vk::Unique<vk::VkImage>		  image		  (createExternalImage(vkd, *device, queueFamilyIndex, externalMemoryType, format, 64u, 64u, tiling, createFlag, usage,
   4073                                                                                                                      1u, properties.imageFormatProperties.maxArrayLayers));
   4074 			const vk::VkMemoryRequirements		  requirements(getImageMemoryRequirements(vkd, *device, *image));
   4075 			const vk::Unique<vk::VkDeviceMemory>  memory	  (allocateExportableMemory(vkd, *device, requirements, externalMemoryType, *image, exportedMemoryTypeIndex));
   4076 			NativeHandle						  handle;
   4077 
   4078 			VK_CHECK(vkd.bindImageMemory(*device, *image, *memory, 0u));
   4079 			getMemoryNative(vkd, *device, *memory, externalMemoryType, handle);
   4080 
   4081 			AHardwareBuffer_Desc desc;
   4082 			AHardwareBuffer_describe(static_cast<const AHardwareBuffer*>(handle.getAndroidHardwareBuffer().internal), &desc);
   4083 			TCU_CHECK(desc.format == vkFormatToAhbFormat(format));
   4084 			TCU_CHECK((desc.usage & requiredAhbUsage) == requiredAhbUsage);
   4085 		}
   4086 	}
   4087 	return tcu::TestStatus::pass("Pass");
   4088 #else
   4089 	DE_UNREF(context);
   4090 	DE_UNREF(format);
   4091 	TCU_THROW(NotSupportedError, "Platform doesn't support AHardwareBuffers");
   4092 #endif
   4093 }
   4094 
   4095 de::MovePtr<tcu::TestCaseGroup> createFenceTests (tcu::TestContext& testCtx)
   4096 {
   4097 	de::MovePtr<tcu::TestCaseGroup> fenceGroup (new tcu::TestCaseGroup(testCtx, "fence", "Tests for external fences."));
   4098 
   4099 	fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT).release());
   4100 	fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT).release());
   4101 	fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT).release());
   4102 	fenceGroup->addChild(createFenceTests(testCtx, vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT).release());
   4103 
   4104 	return fenceGroup;
   4105 }
   4106 
   4107 de::MovePtr<tcu::TestCaseGroup> createSemaphoreTests (tcu::TestContext& testCtx, vk::VkExternalSemaphoreHandleTypeFlagBits externalType)
   4108 {
   4109 	const struct
   4110 	{
   4111 		const char* const	name;
   4112 		const Permanence	permanence;
   4113 	} permanences[] =
   4114 	{
   4115 		{ "temporary", PERMANENCE_TEMPORARY	},
   4116 		{ "permanent", PERMANENCE_PERMANENT	}
   4117 	};
   4118 
   4119 	de::MovePtr<tcu::TestCaseGroup> semaphoreGroup (new tcu::TestCaseGroup(testCtx, externalSemaphoreTypeToName(externalType), externalSemaphoreTypeToName(externalType)));
   4120 
   4121 	addFunctionCase(semaphoreGroup.get(), "info",	"Test external semaphore queries.",	testSemaphoreQueries,	externalType);
   4122 
   4123 	for (size_t permanenceNdx = 0; permanenceNdx < DE_LENGTH_OF_ARRAY(permanences); permanenceNdx++)
   4124 	{
   4125 		const Permanence			permanence		(permanences[permanenceNdx].permanence);
   4126 		const char* const			permanenceName	(permanences[permanenceNdx].name);
   4127 		const SemaphoreTestConfig	config			(externalType, permanence);
   4128 
   4129 		if (!isSupportedPermanence(externalType, permanence))
   4130 			continue;
   4131 
   4132 		if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
   4133 			|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
   4134 		{
   4135 			addFunctionCase(semaphoreGroup.get(), std::string("create_win32_") + permanenceName,	"Test creating semaphore with win32 properties.",	testSemaphoreWin32Create,	config);
   4136 		}
   4137 
   4138 		addFunctionCase(semaphoreGroup.get(), std::string("import_twice_") + permanenceName,				"Test importing semaphore twice.",										testSemaphoreImportTwice,				config);
   4139 		addFunctionCase(semaphoreGroup.get(), std::string("reimport_") + permanenceName,					"Test importing again over previously imported semaphore.",				testSemaphoreImportReimport,			config);
   4140 		addFunctionCase(semaphoreGroup.get(), std::string("import_multiple_times_") + permanenceName,		"Test importing semaphore multiple times.",								testSemaphoreMultipleImports,			config);
   4141 		addFunctionCase(semaphoreGroup.get(), std::string("signal_export_import_wait_") + permanenceName,	"Test signaling, exporting, importing and waiting for the sempahore.",	testSemaphoreSignalExportImportWait,	config);
   4142 		addFunctionCase(semaphoreGroup.get(), std::string("signal_import_") + permanenceName,				"Test signaling and importing the semaphore.",							testSemaphoreSignalImport,				config);
   4143 		addFunctionCase(semaphoreGroup.get(), std::string("transference_") + permanenceName,				"Test semaphores transference.",										testSemaphoreTransference,				config);
   4144 
   4145 		if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
   4146 			|| externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
   4147 		{
   4148 			// \note Not supported on WIN32 handles
   4149 			addFunctionCase(semaphoreGroup.get(), std::string("export_multiple_times_") + permanenceName,	"Test exporting semaphore multiple times.",		testSemaphoreMultipleExports,	config);
   4150 
   4151 			addFunctionCase(semaphoreGroup.get(), std::string("dup_") + permanenceName,						"Test calling dup() on exported semaphore.",	testSemaphoreFdDup,				config);
   4152 			addFunctionCase(semaphoreGroup.get(), std::string("dup2_") + permanenceName,					"Test calling dup2() on exported semaphore.",	testSemaphoreFdDup2,			config);
   4153 			addFunctionCase(semaphoreGroup.get(), std::string("dup3_") + permanenceName,					"Test calling dup3() on exported semaphore.",	testSemaphoreFdDup3,			config);
   4154 			addFunctionCase(semaphoreGroup.get(), std::string("send_over_socket_") + permanenceName,		"Test sending semaphore fd over socket.",		testSemaphoreFdSendOverSocket,	config);
   4155 		}
   4156 
   4157 		if (getHandelTypeTransferences(externalType) == TRANSFERENCE_REFERENCE)
   4158 		{
   4159 			addFunctionCase(semaphoreGroup.get(), std::string("signal_wait_import_") + permanenceName,			"Test signaling and then waiting for the the sepmahore.",				testSemaphoreSignalWaitImport,			config);
   4160 			addFunctionCase(semaphoreGroup.get(), std::string("export_signal_import_wait_") + permanenceName,	"Test exporting, signaling, importing and waiting for the semaphore.",	testSemaphoreExportSignalImportWait,	config);
   4161 			addFunctionCase(semaphoreGroup.get(), std::string("export_import_signal_wait_") + permanenceName,	"Test exporting, importing, signaling and waiting for the semaphore.",	testSemaphoreExportImportSignalWait,	config);
   4162 		}
   4163 	}
   4164 
   4165 	return semaphoreGroup;
   4166 }
   4167 
   4168 de::MovePtr<tcu::TestCaseGroup> createSemaphoreTests (tcu::TestContext& testCtx)
   4169 {
   4170 	de::MovePtr<tcu::TestCaseGroup> semaphoreGroup (new tcu::TestCaseGroup(testCtx, "semaphore", "Tests for external semaphores."));
   4171 
   4172 	semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT).release());
   4173 	semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT).release());
   4174 	semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT).release());
   4175 	semaphoreGroup->addChild(createSemaphoreTests(testCtx, vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT).release());
   4176 
   4177 	return semaphoreGroup;
   4178 }
   4179 
   4180 de::MovePtr<tcu::TestCaseGroup> createMemoryTests (tcu::TestContext& testCtx, vk::VkExternalMemoryHandleTypeFlagBits externalType)
   4181 {
   4182 	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, externalMemoryTypeToName(externalType), "Tests for external memory"));
   4183 
   4184 	for (size_t dedicatedNdx = 0; dedicatedNdx < 2; dedicatedNdx++)
   4185 	{
   4186 		const bool						dedicated		(dedicatedNdx == 1);
   4187 		de::MovePtr<tcu::TestCaseGroup>	dedicatedGroup	(new tcu::TestCaseGroup(testCtx, dedicated ? "dedicated" : "suballocated", ""));
   4188 
   4189 		for (size_t hostVisibleNdx = 0; hostVisibleNdx < 2; hostVisibleNdx++)
   4190 		{
   4191 			const bool						hostVisible			(hostVisibleNdx == 1);
   4192 			de::MovePtr<tcu::TestCaseGroup>	hostVisibleGroup	(new tcu::TestCaseGroup(testCtx, hostVisible ? "host_visible" : "device_only", ""));
   4193 			const MemoryTestConfig			memoryConfig		(externalType, hostVisible, dedicated);
   4194 
   4195 			if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
   4196 				|| externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
   4197 			{
   4198 				addFunctionCase(hostVisibleGroup.get(), "create_win32",	"Test creating memory with win32 properties .",		testMemoryWin32Create,	memoryConfig);
   4199 			}
   4200 
   4201 			addFunctionCase(hostVisibleGroup.get(), "import_twice",				"Test importing memory object twice.",			testMemoryImportTwice,		memoryConfig);
   4202 			addFunctionCase(hostVisibleGroup.get(), "import_multiple_times",	"Test importing memory object multiple times.",	testMemoryMultimpleImports,	memoryConfig);
   4203 
   4204 			if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
   4205 			{
   4206 				addFunctionCase(hostVisibleGroup.get(), "dup",									"Test calling dup() on exported memory.",	testMemoryFdDup,			memoryConfig);
   4207 				addFunctionCase(hostVisibleGroup.get(), "dup2",									"Test calling dup2() on exported memory.",	testMemoryFdDup2,			memoryConfig);
   4208 				addFunctionCase(hostVisibleGroup.get(), "dup3",									"Test calling dup3() on exported memory.",	testMemoryFdDup3,			memoryConfig);
   4209 				addFunctionCase(hostVisibleGroup.get(), "send_over_socket",						"Test sending memory fd over socket.",		testMemoryFdSendOverSocket,	memoryConfig);
   4210 				// \note Not supported on WIN32 handles
   4211 				addFunctionCase(hostVisibleGroup.get(), "export_multiple_times",				"Test exporting memory multiple times.",	testMemoryMultimpleExports,	memoryConfig);
   4212 			}
   4213 
   4214 			dedicatedGroup->addChild(hostVisibleGroup.release());
   4215 		}
   4216 
   4217 		{
   4218 			de::MovePtr<tcu::TestCaseGroup>	bufferGroup		(new tcu::TestCaseGroup(testCtx, "buffer", ""));
   4219 			const BufferTestConfig			bufferConfig	(externalType, dedicated);
   4220 
   4221 			addFunctionCase(bufferGroup.get(), "info",						"External buffer memory info query.",						testBufferQueries,				externalType);
   4222 			addFunctionCase(bufferGroup.get(), "bind_export_import_bind",	"Test binding, exporting, importing and binding buffer.",	testBufferBindExportImportBind,	bufferConfig);
   4223 			addFunctionCase(bufferGroup.get(), "export_bind_import_bind",	"Test exporting, binding, importing and binding buffer.",	testBufferExportBindImportBind,	bufferConfig);
   4224 			addFunctionCase(bufferGroup.get(), "export_import_bind_bind",	"Test exporting, importind and binding buffer.",			testBufferExportImportBindBind,	bufferConfig);
   4225 
   4226 			dedicatedGroup->addChild(bufferGroup.release());
   4227 		}
   4228 
   4229 		{
   4230 			de::MovePtr<tcu::TestCaseGroup> imageGroup	(new tcu::TestCaseGroup(testCtx, "image", ""));
   4231 			const ImageTestConfig			imageConfig	(externalType, dedicated);
   4232 
   4233 			addFunctionCase(imageGroup.get(), "info",						"External image memory info query.",						testImageQueries,				externalType);
   4234 			addFunctionCase(imageGroup.get(), "bind_export_import_bind",	"Test binding, exporting, importing and binding image.",	testImageBindExportImportBind,	imageConfig);
   4235 			addFunctionCase(imageGroup.get(), "export_bind_import_bind",	"Test exporting, binding, importing and binding image.",	testImageExportBindImportBind,	imageConfig);
   4236 			addFunctionCase(imageGroup.get(), "export_import_bind_bind",	"Test exporting, importind and binding image.",				testImageExportImportBindBind,	imageConfig);
   4237 
   4238 			dedicatedGroup->addChild(imageGroup.release());
   4239 		}
   4240 
   4241 		group->addChild(dedicatedGroup.release());
   4242 	}
   4243 
   4244 	if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
   4245 	{
   4246 		de::MovePtr<tcu::TestCaseGroup>	formatGroup	(new tcu::TestCaseGroup(testCtx, "image_formats", "Test minimum image format support"));
   4247 
   4248 		const vk::VkFormat	ahbFormats[]	=
   4249 		{
   4250 			vk::VK_FORMAT_R8G8B8_UNORM,
   4251 			vk::VK_FORMAT_R8G8B8A8_UNORM,
   4252 			vk::VK_FORMAT_R5G6B5_UNORM_PACK16,
   4253 			vk::VK_FORMAT_R16G16B16A16_SFLOAT,
   4254 			vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32,
   4255 		};
   4256 		const size_t		numOfAhbFormats	= DE_LENGTH_OF_ARRAY(ahbFormats);
   4257 
   4258 		for (size_t ahbFormatNdx = 0; ahbFormatNdx < numOfAhbFormats; ahbFormatNdx++)
   4259 		{
   4260 			const vk::VkFormat	format			= ahbFormats[ahbFormatNdx];
   4261 			const std::string	testCaseName	= getFormatCaseName(format);
   4262 			addFunctionCase(formatGroup.get(), testCaseName, "", testAndroidHardwareBufferImageFormat, format);
   4263 		}
   4264 
   4265 		group->addChild(formatGroup.release());
   4266 	}
   4267 
   4268 	return group;
   4269 }
   4270 
   4271 de::MovePtr<tcu::TestCaseGroup> createMemoryTests (tcu::TestContext& testCtx)
   4272 {
   4273 	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "memory", "Tests for external memory"));
   4274 
   4275 	group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT).release());
   4276 	group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT).release());
   4277 	group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT).release());
   4278 	group->addChild(createMemoryTests(testCtx, vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID).release());
   4279 
   4280 	return group;
   4281 }
   4282 
   4283 } // anonymous
   4284 
   4285 tcu::TestCaseGroup* createExternalMemoryTests (tcu::TestContext& testCtx)
   4286 {
   4287 	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "external", "Tests for external Vulkan objects"));
   4288 
   4289 	group->addChild(createSemaphoreTests(testCtx).release());
   4290 	group->addChild(createMemoryTests(testCtx).release());
   4291 	group->addChild(createFenceTests(testCtx).release());
   4292 
   4293 	return group.release();
   4294 }
   4295 
   4296 } // api
   4297 } // vkt
   4298