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