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