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