Merge vk-gl-cts/vulkan-cts-1.1.2 into vk-gl-cts/master
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / vktExternalMemoryUtil.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 utilities
20  *//*--------------------------------------------------------------------*/
21
22 #include "vktExternalMemoryUtil.hpp"
23
24 #include "vkQueryUtil.hpp"
25
26 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
27 #       include <unistd.h>
28 #       include <fcntl.h>
29 #       include <errno.h>
30 #       include <sys/types.h>
31 #       include <sys/socket.h>
32 #endif
33
34 #if (DE_OS == DE_OS_WIN32)
35 #       define WIN32_LEAN_AND_MEAN
36 #       include <windows.h>
37 #endif
38
39 #if (DE_OS == DE_OS_ANDROID)
40 #   include <sys/system_properties.h>
41 #endif
42
43 #if (DE_OS == DE_OS_ANDROID) && defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
44 #       include <android/hardware_buffer.h>
45 #       include "deDynamicLibrary.hpp"
46 #       define BUILT_WITH_ANDROID_HARDWARE_BUFFER 1
47 #endif
48
49 namespace vkt
50 {
51 namespace ExternalMemoryUtil
52 {
53 namespace
54 {
55 deUint32 chooseMemoryType (deUint32 bits)
56 {
57         DE_ASSERT(bits != 0);
58
59         for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
60         {
61                 if ((bits & (1u << memoryTypeIndex)) != 0)
62                         return memoryTypeIndex;
63         }
64
65         DE_FATAL("No supported memory types");
66         return -1;
67 }
68
69 } // anonymous
70
71 NativeHandle::NativeHandle (void)
72         : m_fd                                          (-1)
73         , m_win32HandleType                     (WIN32HANDLETYPE_LAST)
74         , m_win32Handle                         (DE_NULL)
75         , m_androidHardwareBuffer       (DE_NULL)
76 {
77 }
78
79 NativeHandle::NativeHandle (const NativeHandle& other)
80         : m_fd                                          (-1)
81         , m_win32HandleType                     (WIN32HANDLETYPE_LAST)
82         , m_win32Handle                         (DE_NULL)
83         , m_androidHardwareBuffer       (DE_NULL)
84 {
85         if (other.m_fd >= 0)
86         {
87 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
88                 DE_ASSERT(!other.m_win32Handle.internal);
89                 DE_ASSERT(!other.m_androidHardwareBuffer.internal);
90                 m_fd = dup(other.m_fd);
91                 TCU_CHECK(m_fd >= 0);
92 #else
93                 DE_FATAL("Platform doesn't support file descriptors");
94 #endif
95         }
96         else if (other.m_win32Handle.internal)
97         {
98 #if (DE_OS == DE_OS_WIN32)
99                 m_win32HandleType = other.m_win32HandleType;
100
101                 switch (other.m_win32HandleType)
102                 {
103                         case WIN32HANDLETYPE_NT:
104                         {
105                                 DE_ASSERT(other.m_fd == -1);
106                                 DE_ASSERT(!other.m_androidHardwareBuffer.internal);
107
108                                 const HANDLE process = ::GetCurrentProcess();
109                                 ::DuplicateHandle(process, other.m_win32Handle.internal, process, &m_win32Handle.internal, 0, TRUE, DUPLICATE_SAME_ACCESS);
110
111                                 break;
112                         }
113
114                         case WIN32HANDLETYPE_KMT:
115                         {
116                                 m_win32Handle = other.m_win32Handle;
117                                 break;
118                         }
119
120                         default:
121                                 DE_FATAL("Unknown win32 handle type");
122                 }
123 #else
124                 DE_FATAL("Platform doesn't support win32 handles");
125 #endif
126         }
127         else if (other.m_androidHardwareBuffer.internal)
128         {
129                 DE_ASSERT(other.m_fd == -1);
130                 DE_ASSERT(!other.m_win32Handle.internal);
131                 m_androidHardwareBuffer = other.m_androidHardwareBuffer;
132                 AndroidHardwareBufferExternalApi::getInstance()->acquire(m_androidHardwareBuffer);
133         }
134         else
135                 DE_FATAL("Native handle can't be duplicated");
136 }
137
138 NativeHandle::NativeHandle (int fd)
139         : m_fd                                          (fd)
140         , m_win32HandleType                     (WIN32HANDLETYPE_LAST)
141         , m_win32Handle                         (DE_NULL)
142         , m_androidHardwareBuffer       (DE_NULL)
143 {
144 }
145
146 NativeHandle::NativeHandle (Win32HandleType handleType, vk::pt::Win32Handle handle)
147         : m_fd                                          (-1)
148         , m_win32HandleType                     (handleType)
149         , m_win32Handle                         (handle)
150         , m_androidHardwareBuffer       (DE_NULL)
151 {
152 }
153
154 NativeHandle::NativeHandle (vk::pt::AndroidHardwareBufferPtr buffer)
155         : m_fd                                          (-1)
156         , m_win32HandleType                     (WIN32HANDLETYPE_LAST)
157         , m_win32Handle                         (DE_NULL)
158         , m_androidHardwareBuffer       (buffer)
159 {
160 }
161
162 NativeHandle::~NativeHandle (void)
163 {
164         reset();
165 }
166
167 void NativeHandle::reset (void)
168 {
169         if (m_fd >= 0)
170         {
171 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
172                 DE_ASSERT(!m_win32Handle.internal);
173                 DE_ASSERT(!m_androidHardwareBuffer.internal);
174                 ::close(m_fd);
175 #else
176                 DE_FATAL("Platform doesn't support file descriptors");
177 #endif
178         }
179
180         if (m_win32Handle.internal)
181         {
182 #if (DE_OS == DE_OS_WIN32)
183                 switch (m_win32HandleType)
184                 {
185                         case WIN32HANDLETYPE_NT:
186                                 DE_ASSERT(m_fd == -1);
187                                 DE_ASSERT(!m_androidHardwareBuffer.internal);
188                                 ::CloseHandle((HANDLE)m_win32Handle.internal);
189                                 break;
190
191                         case WIN32HANDLETYPE_KMT:
192                                 break;
193
194                         default:
195                                 DE_FATAL("Unknown win32 handle type");
196                 }
197 #else
198                 DE_FATAL("Platform doesn't support win32 handles");
199 #endif
200         }
201         if (m_androidHardwareBuffer.internal)
202         {
203                 DE_ASSERT(m_fd == -1);
204                 DE_ASSERT(!m_win32Handle.internal);
205                 AndroidHardwareBufferExternalApi::getInstance()->release(m_androidHardwareBuffer);
206         }
207         m_fd                                    = -1;
208         m_win32Handle                   = vk::pt::Win32Handle(DE_NULL);
209         m_win32HandleType               = WIN32HANDLETYPE_LAST;
210         m_androidHardwareBuffer = vk::pt::AndroidHardwareBufferPtr(DE_NULL);
211 }
212
213 NativeHandle& NativeHandle::operator= (int fd)
214 {
215         reset();
216
217         m_fd = fd;
218
219         return *this;
220 }
221
222 NativeHandle& NativeHandle::operator= (vk::pt::AndroidHardwareBufferPtr buffer)
223 {
224         reset();
225
226         m_androidHardwareBuffer = buffer;
227
228         return *this;
229 }
230
231 void NativeHandle::setWin32Handle (Win32HandleType type, vk::pt::Win32Handle handle)
232 {
233         reset();
234
235         m_win32HandleType       = type;
236         m_win32Handle           = handle;
237 }
238
239 void NativeHandle::disown (void)
240 {
241         m_fd = -1;
242         m_win32Handle = vk::pt::Win32Handle(DE_NULL);
243         m_androidHardwareBuffer = vk::pt::AndroidHardwareBufferPtr(DE_NULL);
244 }
245
246 vk::pt::Win32Handle NativeHandle::getWin32Handle (void) const
247 {
248         DE_ASSERT(m_fd == -1);
249         DE_ASSERT(!m_androidHardwareBuffer.internal);
250         return m_win32Handle;
251 }
252
253 int NativeHandle::getFd (void) const
254 {
255         DE_ASSERT(!m_win32Handle.internal);
256         DE_ASSERT(!m_androidHardwareBuffer.internal);
257         return m_fd;
258 }
259
260
261 vk::pt::AndroidHardwareBufferPtr NativeHandle::getAndroidHardwareBuffer (void) const
262 {
263         DE_ASSERT(m_fd == -1);
264         DE_ASSERT(!m_win32Handle.internal);
265         return m_androidHardwareBuffer;
266 }
267
268 const char* externalSemaphoreTypeToName (vk::VkExternalSemaphoreHandleTypeFlagBits type)
269 {
270         switch (type)
271         {
272                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
273                         return "opaque_fd";
274
275                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
276                         return "opaque_win32";
277
278                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
279                         return "opaque_win32_kmt";
280
281                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT:
282                         return "d3d12_fenc";
283
284                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
285                         return "sync_fd";
286
287                 default:
288                         DE_FATAL("Unknown external semaphore type");
289                         return DE_NULL;
290         }
291 }
292
293 const char* externalFenceTypeToName (vk::VkExternalFenceHandleTypeFlagBits type)
294 {
295         switch (type)
296         {
297                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
298                         return "opaque_fd";
299
300                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
301                         return "opaque_win32";
302
303                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
304                         return "opaque_win32_kmt";
305
306                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
307                         return "sync_fd";
308
309                 default:
310                         DE_FATAL("Unknown external fence type");
311                         return DE_NULL;
312         }
313 }
314
315 const char* externalMemoryTypeToName (vk::VkExternalMemoryHandleTypeFlagBits type)
316 {
317         switch (type)
318         {
319                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
320                         return "opaque_fd";
321
322                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:
323                         return "opaque_win32";
324
325                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
326                         return "opaque_win32_kmt";
327
328                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT:
329                         return "d3d11_texture";
330
331                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT:
332                         return "d3d11_texture_kmt";
333
334                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT:
335                         return "d3d12_heap";
336
337                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT:
338                         return "d3d12_resource";
339
340                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:
341                         return "android_hardware_buffer";
342
343                 default:
344                         DE_FATAL("Unknown external memory type");
345                         return DE_NULL;
346         }
347 }
348
349 bool isSupportedPermanence (vk::VkExternalSemaphoreHandleTypeFlagBits   type,
350                                                         Permanence                                                                              permanence)
351 {
352         switch (type)
353         {
354                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
355                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
356                         return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
357
358                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
359                         return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
360
361                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
362                         return permanence == PERMANENCE_TEMPORARY;
363
364                 default:
365                         DE_FATAL("Unknown external semaphore type");
366                         return false;
367         }
368 }
369
370 Transference getHandelTypeTransferences (vk::VkExternalSemaphoreHandleTypeFlagBits type)
371 {
372         switch (type)
373         {
374                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
375                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
376                         return TRANSFERENCE_REFERENCE;
377
378                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
379                         return TRANSFERENCE_REFERENCE;
380
381                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
382                         return TRANSFERENCE_COPY;
383
384                 default:
385                         DE_FATAL("Unknown external semaphore type");
386                         return TRANSFERENCE_REFERENCE;
387         }
388 }
389
390 bool isSupportedPermanence (vk::VkExternalFenceHandleTypeFlagBits       type,
391                                                         Permanence                                                                      permanence)
392 {
393         switch (type)
394         {
395                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
396                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
397                         return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
398
399                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
400                         return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
401
402                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
403                         return permanence == PERMANENCE_TEMPORARY;
404
405                 default:
406                         DE_FATAL("Unknown external fence type");
407                         return false;
408         }
409 }
410
411 Transference getHandelTypeTransferences (vk::VkExternalFenceHandleTypeFlagBits type)
412 {
413         switch (type)
414         {
415                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
416                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
417                         return TRANSFERENCE_REFERENCE;
418
419                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
420                         return TRANSFERENCE_REFERENCE;
421
422                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
423                         return TRANSFERENCE_COPY;
424
425                 default:
426                         DE_FATAL("Unknown external fence type");
427                         return TRANSFERENCE_REFERENCE;
428         }
429 }
430
431 int getMemoryFd (const vk::DeviceInterface&                                     vkd,
432                                  vk::VkDevice                                                           device,
433                                  vk::VkDeviceMemory                                                     memory,
434                                  vk::VkExternalMemoryHandleTypeFlagBits         externalType)
435 {
436         const vk::VkMemoryGetFdInfoKHR  info    =
437         {
438                 vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
439                 DE_NULL,
440
441                 memory,
442                 externalType
443         };
444         int                                                             fd              = -1;
445
446         VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd));
447         TCU_CHECK(fd >= 0);
448
449         return fd;
450 }
451
452 void getMemoryNative (const vk::DeviceInterface&                                        vkd,
453                                                  vk::VkDevice                                                           device,
454                                                  vk::VkDeviceMemory                                                     memory,
455                                                  vk::VkExternalMemoryHandleTypeFlagBits         externalType,
456                                                  NativeHandle&                                                          nativeHandle)
457 {
458         if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
459         {
460                 const vk::VkMemoryGetFdInfoKHR  info    =
461                 {
462                         vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
463                         DE_NULL,
464
465                         memory,
466                         externalType
467                 };
468                 int                                                             fd              = -1;
469
470                 VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd));
471                 TCU_CHECK(fd >= 0);
472                 nativeHandle = fd;
473         }
474         else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
475                 || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
476         {
477                 const vk::VkMemoryGetWin32HandleInfoKHR info    =
478                 {
479                         vk::VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
480                         DE_NULL,
481
482                         memory,
483                         externalType
484                 };
485                 vk::pt::Win32Handle                                             handle  (DE_NULL);
486
487                 VK_CHECK(vkd.getMemoryWin32HandleKHR(device, &info, &handle));
488
489                 switch (externalType)
490                 {
491                         case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:
492                                 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
493                                 break;
494
495                         case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
496                                 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
497                                 break;
498
499                         default:
500                                 DE_FATAL("Unknown external memory handle type");
501                 }
502         }
503         else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
504         {
505                 if (!AndroidHardwareBufferExternalApi::getInstance())
506                 {
507                         TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles");
508                 }
509                 const vk::VkMemoryGetAndroidHardwareBufferInfoANDROID   info    =
510                 {
511                         vk::VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
512                         DE_NULL,
513
514                         memory,
515                 };
516                 vk::pt::AndroidHardwareBufferPtr                                                ahb     (DE_NULL);
517
518                 VK_CHECK(vkd.getMemoryAndroidHardwareBufferANDROID(device, &info, &ahb));
519                 TCU_CHECK(ahb.internal);
520                 nativeHandle = ahb;
521         }
522         else
523                 DE_FATAL("Unknown external memory handle type");
524 }
525
526 vk::Move<vk::VkFence> createExportableFence (const vk::DeviceInterface&                                 vkd,
527                                                                                          vk::VkDevice                                                           device,
528                                                                                          vk::VkExternalFenceHandleTypeFlagBits          externalType)
529 {
530         const vk::VkExportFenceCreateInfo       exportCreateInfo        =
531         {
532                 vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
533                 DE_NULL,
534                 (vk::VkExternalFenceHandleTypeFlags)externalType
535         };
536         const vk::VkFenceCreateInfo                             createInfo                      =
537         {
538                 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
539                 &exportCreateInfo,
540                 0u
541         };
542
543         return vk::createFence(vkd, device, &createInfo);
544 }
545
546 int getFenceFd (const vk::DeviceInterface&                                      vkd,
547                                 vk::VkDevice                                                            device,
548                                 vk::VkFence                                                                     fence,
549                                 vk::VkExternalFenceHandleTypeFlagBits           externalType)
550 {
551         const vk::VkFenceGetFdInfoKHR   info    =
552         {
553                 vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
554                 DE_NULL,
555
556                 fence,
557                 externalType
558         };
559         int                                                             fd      = -1;
560
561         VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd));
562         TCU_CHECK(fd >= 0);
563
564         return fd;
565 }
566
567 void getFenceNative (const vk::DeviceInterface&                                 vkd,
568                                          vk::VkDevice                                                           device,
569                                          vk::VkFence                                                            fence,
570                                          vk::VkExternalFenceHandleTypeFlagBits          externalType,
571                                          NativeHandle&                                                          nativeHandle)
572 {
573         if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
574                 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
575         {
576                 const vk::VkFenceGetFdInfoKHR   info    =
577                 {
578                         vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
579                         DE_NULL,
580
581                         fence,
582                         externalType
583                 };
584                 int                                                             fd      = -1;
585
586                 VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd));
587                 TCU_CHECK(fd >= 0);
588                 nativeHandle = fd;
589         }
590         else if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
591                 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
592         {
593                 const vk::VkFenceGetWin32HandleInfoKHR  info    =
594                 {
595                         vk::VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR,
596                         DE_NULL,
597
598                         fence,
599                         externalType
600                 };
601                 vk::pt::Win32Handle                                             handle  (DE_NULL);
602
603                 VK_CHECK(vkd.getFenceWin32HandleKHR(device, &info, &handle));
604
605                 switch (externalType)
606                 {
607                         case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
608                                 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
609                                 break;
610
611                         case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
612                                 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
613                                 break;
614
615                         default:
616                                 DE_FATAL("Unknow external memory handle type");
617                 }
618         }
619         else
620                 DE_FATAL("Unknow external fence handle type");
621 }
622
623 void importFence (const vk::DeviceInterface&                            vkd,
624                                   const vk::VkDevice                                            device,
625                                   const vk::VkFence                                                     fence,
626                                   vk::VkExternalFenceHandleTypeFlagBits         externalType,
627                                   NativeHandle&                                                         handle,
628                                   vk::VkFenceImportFlags                                        flags)
629 {
630         if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
631                 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
632         {
633                 const vk::VkImportFenceFdInfoKHR        importInfo      =
634                 {
635                         vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
636                         DE_NULL,
637                         fence,
638                         flags,
639                         externalType,
640                         handle.getFd()
641                 };
642
643                 VK_CHECK(vkd.importFenceFdKHR(device, &importInfo));
644                 handle.disown();
645         }
646         else if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
647                         || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
648         {
649                 const vk::VkImportFenceWin32HandleInfoKHR       importInfo      =
650                 {
651                         vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
652                         DE_NULL,
653                         fence,
654                         flags,
655                         externalType,
656                         handle.getWin32Handle(),
657                         DE_NULL
658                 };
659
660                 VK_CHECK(vkd.importFenceWin32HandleKHR(device, &importInfo));
661                 // \note File descriptors and win32 handles behave differently, but this call wil make it seem like they would behave in same way
662                 handle.reset();
663         }
664         else
665                 DE_FATAL("Unknown fence external handle type");
666 }
667
668 vk::Move<vk::VkFence> createAndImportFence (const vk::DeviceInterface&                          vkd,
669                                                                                         const vk::VkDevice                                              device,
670                                                                                         vk::VkExternalFenceHandleTypeFlagBits   externalType,
671                                                                                         NativeHandle&                                                   handle,
672                                                                                         vk::VkFenceImportFlags                                  flags)
673 {
674         vk::Move<vk::VkFence>   fence   (createFence(vkd, device));
675
676         importFence(vkd, device, *fence, externalType, handle, flags);
677
678         return fence;
679 }
680
681 vk::Move<vk::VkSemaphore> createExportableSemaphore (const vk::DeviceInterface&                                 vkd,
682                                                                                                          vk::VkDevice                                                           device,
683                                                                                                          vk::VkExternalSemaphoreHandleTypeFlagBits      externalType)
684 {
685         const vk::VkExportSemaphoreCreateInfo   exportCreateInfo        =
686         {
687                 vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
688                 DE_NULL,
689                 (vk::VkExternalSemaphoreHandleTypeFlags)externalType
690         };
691         const vk::VkSemaphoreCreateInfo                         createInfo                      =
692         {
693                 vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
694                 &exportCreateInfo,
695                 0u
696         };
697
698         return vk::createSemaphore(vkd, device, &createInfo);
699 }
700
701 int getSemaphoreFd (const vk::DeviceInterface&                                  vkd,
702                                         vk::VkDevice                                                            device,
703                                         vk::VkSemaphore                                                         semaphore,
704                                         vk::VkExternalSemaphoreHandleTypeFlagBits       externalType)
705 {
706         const vk::VkSemaphoreGetFdInfoKHR       info    =
707         {
708                 vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
709                 DE_NULL,
710
711                 semaphore,
712                 externalType
713         };
714         int                                                                             fd      = -1;
715
716         VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
717         TCU_CHECK(fd >= 0);
718
719         return fd;
720 }
721
722 void getSemaphoreNative (const vk::DeviceInterface&                                     vkd,
723                                                  vk::VkDevice                                                           device,
724                                                  vk::VkSemaphore                                                        semaphore,
725                                                  vk::VkExternalSemaphoreHandleTypeFlagBits      externalType,
726                                                  NativeHandle&                                                          nativeHandle)
727 {
728         if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
729                 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
730         {
731                 const vk::VkSemaphoreGetFdInfoKHR       info    =
732                 {
733                         vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
734                         DE_NULL,
735
736                         semaphore,
737                         externalType
738                 };
739                 int                                                                             fd      = -1;
740
741                 VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
742                 TCU_CHECK(fd >= 0);
743                 nativeHandle = fd;
744         }
745         else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
746                 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
747         {
748                 const vk::VkSemaphoreGetWin32HandleInfoKHR      info    =
749                 {
750                         vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
751                         DE_NULL,
752
753                         semaphore,
754                         externalType
755                 };
756                 vk::pt::Win32Handle                                                     handle  (DE_NULL);
757
758                 VK_CHECK(vkd.getSemaphoreWin32HandleKHR(device, &info, &handle));
759
760                 switch (externalType)
761                 {
762                         case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
763                                 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
764                                 break;
765
766                         case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
767                                 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
768                                 break;
769
770                         default:
771                                 DE_FATAL("Unknow external memory handle type");
772                 }
773         }
774         else
775                 DE_FATAL("Unknow external semaphore handle type");
776 }
777
778 void importSemaphore (const vk::DeviceInterface&                                        vkd,
779                                           const vk::VkDevice                                                    device,
780                                           const vk::VkSemaphore                                                 semaphore,
781                                           vk::VkExternalSemaphoreHandleTypeFlagBits             externalType,
782                                           NativeHandle&                                                                 handle,
783                                           vk::VkSemaphoreImportFlags                                    flags)
784 {
785         if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
786                 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
787         {
788                 const vk::VkImportSemaphoreFdInfoKHR    importInfo      =
789                 {
790                         vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
791                         DE_NULL,
792                         semaphore,
793                         flags,
794                         externalType,
795                         handle.getFd()
796                 };
797
798                 VK_CHECK(vkd.importSemaphoreFdKHR(device, &importInfo));
799                 handle.disown();
800         }
801         else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
802                         || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
803         {
804                 const vk::VkImportSemaphoreWin32HandleInfoKHR   importInfo      =
805                 {
806                         vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
807                         DE_NULL,
808                         semaphore,
809                         flags,
810                         externalType,
811                         handle.getWin32Handle(),
812                         DE_NULL
813                 };
814
815                 VK_CHECK(vkd.importSemaphoreWin32HandleKHR(device, &importInfo));
816                 // \note File descriptors and win32 handles behave differently, but this call wil make it seem like they would behave in same way
817                 handle.reset();
818         }
819         else
820                 DE_FATAL("Unknown semaphore external handle type");
821 }
822
823 vk::Move<vk::VkSemaphore> createAndImportSemaphore (const vk::DeviceInterface&                                          vkd,
824                                                                                                         const vk::VkDevice                                                              device,
825                                                                                                         vk::VkExternalSemaphoreHandleTypeFlagBits               externalType,
826                                                                                                         NativeHandle&                                                                   handle,
827                                                                                                         vk::VkSemaphoreImportFlags                                              flags)
828 {
829         vk::Move<vk::VkSemaphore>       semaphore       (createSemaphore(vkd, device));
830
831         importSemaphore(vkd, device, *semaphore, externalType, handle, flags);
832
833         return semaphore;
834 }
835
836 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface&                                       vkd,
837                                                                                                            vk::VkDevice                                                                 device,
838                                                                                                            const vk::VkMemoryRequirements&                              requirements,
839                                                                                                            vk::VkExternalMemoryHandleTypeFlagBits               externalType,
840                                                                                                            vk::VkBuffer                                                                 buffer,
841                                                                                                            deUint32&                                                                    exportedMemoryTypeIndex)
842 {
843         exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits);
844         const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo   =
845         {
846                 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
847                 DE_NULL,
848
849                 (vk::VkImage)0,
850                 buffer
851         };
852         const vk::VkExportMemoryAllocateInfo    exportInfo      =
853         {
854                 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
855                 !!buffer ? &dedicatedInfo : DE_NULL,
856                 (vk::VkExternalMemoryHandleTypeFlags)externalType
857         };
858         const vk::VkMemoryAllocateInfo                  info            =
859         {
860                 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
861                 &exportInfo,
862                 requirements.size,
863                 exportedMemoryTypeIndex
864         };
865         return vk::allocateMemory(vkd, device, &info);
866 }
867
868 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface&                                       vkd,
869                                                                                                            vk::VkDevice                                                                 device,
870                                                                                                            const vk::VkMemoryRequirements&                              requirements,
871                                                                                                            vk::VkExternalMemoryHandleTypeFlagBits               externalType,
872                                                                                                            vk::VkImage                                                                  image,
873                                                                                                            deUint32&                                                                    exportedMemoryTypeIndex)
874 {
875         exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits);
876         const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo   =
877         {
878                 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
879                 DE_NULL,
880
881                 image,
882                 (vk::VkBuffer)0
883         };
884         const vk::VkExportMemoryAllocateInfo    exportInfo      =
885         {
886                 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
887                 !!image ? &dedicatedInfo : DE_NULL,
888                 (vk::VkExternalMemoryHandleTypeFlags)externalType
889         };
890         const vk::VkMemoryAllocateInfo                  info            =
891         {
892                 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
893                 &exportInfo,
894                 requirements.size,
895                 exportedMemoryTypeIndex
896         };
897         return vk::allocateMemory(vkd, device, &info);
898 }
899
900 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::InstanceInterface&                                     vki,
901                                                                                                            vk::VkPhysicalDevice                                                 physicalDevice,
902                                                                                                            const vk::DeviceInterface&                                   vkd,
903                                                                                                            vk::VkDevice                                                                 device,
904                                                                                                            const vk::VkMemoryRequirements&                              requirements,
905                                                                                                            vk::VkExternalMemoryHandleTypeFlagBits               externalType,
906                                                                                                            bool                                                                                 hostVisible,
907                                                                                                            vk::VkBuffer                                                                 buffer,
908                                                                                                            deUint32&                                                                    exportedMemoryTypeIndex)
909 {
910         const vk::VkPhysicalDeviceMemoryProperties properties = vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
911
912         for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= requirements.memoryTypeBits; memoryTypeIndex++)
913         {
914                 if (((requirements.memoryTypeBits & (1u << memoryTypeIndex)) != 0)
915                         && (((properties.memoryTypes[memoryTypeIndex].propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) == hostVisible))
916                 {
917                         const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo   =
918                         {
919                                 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
920                                 DE_NULL,
921
922                                 (vk::VkImage)0,
923                                 buffer
924                         };
925                         const vk::VkExportMemoryAllocateInfo    exportInfo      =
926                         {
927                                 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
928                                 !!buffer ? &dedicatedInfo : DE_NULL,
929                                 (vk::VkExternalMemoryHandleTypeFlags)externalType
930                         };
931                         const vk::VkMemoryAllocateInfo                  info            =
932                         {
933                                 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
934                                 &exportInfo,
935                                 requirements.size,
936                                 memoryTypeIndex
937                         };
938
939                         exportedMemoryTypeIndex = memoryTypeIndex;
940                         return vk::allocateMemory(vkd, device, &info);
941                 }
942         }
943
944         TCU_THROW(NotSupportedError, "No supported memory type found");
945 }
946
947 static vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface&                            vkd,
948                                                                                                   vk::VkDevice                                                          device,
949                                                                                                   vk::VkBuffer                                                          buffer,
950                                                                                                   vk::VkImage                                                           image,
951                                                                                                   const vk::VkMemoryRequirements&                       requirements,
952                                                                                                   vk::VkExternalMemoryHandleTypeFlagBits        externalType,
953                                                                                                   deUint32                                                                      memoryTypeIndex,
954                                                                                                   NativeHandle&                                                         handle)
955 {
956         const bool      isDedicated             = !!buffer || !!image;
957
958         DE_ASSERT(!buffer || !image);
959
960         if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
961         {
962                 const vk::VkImportMemoryFdInfoKHR                       importInfo              =
963                 {
964                         vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
965                         DE_NULL,
966                         externalType,
967                         handle.getFd()
968                 };
969                 const vk::VkMemoryDedicatedAllocateInfo         dedicatedInfo   =
970                 {
971                         vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
972                         &importInfo,
973                         image,
974                         buffer,
975                 };
976                 const vk::VkMemoryAllocateInfo                          info                    =
977                 {
978                         vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
979                         (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
980                         requirements.size,
981                         (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex
982                 };
983                 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
984
985                 handle.disown();
986
987                 return memory;
988         }
989         else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
990                         || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
991         {
992                 const vk::VkImportMemoryWin32HandleInfoKHR      importInfo              =
993                 {
994                         vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
995                         DE_NULL,
996                         externalType,
997                         handle.getWin32Handle(),
998                         DE_NULL
999                 };
1000                 const vk::VkMemoryDedicatedAllocateInfo         dedicatedInfo   =
1001                 {
1002                         vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1003                         &importInfo,
1004                         image,
1005                         buffer,
1006                 };
1007                 const vk::VkMemoryAllocateInfo                          info                    =
1008                 {
1009                         vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1010                         (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1011                         requirements.size,
1012                         (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits)  : memoryTypeIndex
1013                 };
1014                 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1015
1016                 // The handle's owned reference must also be released. Do not discard the handle below.
1017                 if (externalType != vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT)
1018                         handle.disown();
1019
1020                 return memory;
1021         }
1022         else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
1023         {
1024                 AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance();
1025                 if (!ahbApi)
1026                 {
1027                         TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles");
1028                 }
1029
1030                 deUint32 ahbFormat = 0;
1031                 ahbApi->describe(handle.getAndroidHardwareBuffer(), DE_NULL, DE_NULL, DE_NULL, &ahbFormat, DE_NULL, DE_NULL);
1032                 DE_ASSERT(ahbApi->ahbFormatIsBlob(ahbFormat) || image != 0);
1033
1034                 vk::VkImportAndroidHardwareBufferInfoANDROID    importInfo =
1035                 {
1036                         vk::VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
1037                         DE_NULL,
1038                         handle.getAndroidHardwareBuffer()
1039                 };
1040                 const vk::VkMemoryDedicatedAllocateInfo         dedicatedInfo =
1041                 {
1042                         vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
1043                         &importInfo,
1044                         image,
1045                         buffer,
1046                 };
1047                 const vk::VkMemoryAllocateInfo                                  info =
1048                 {
1049                         vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1050                         (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1051                         requirements.size,
1052                         (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits)  : memoryTypeIndex
1053                 };
1054                 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1055
1056                 return memory;
1057         }
1058         else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
1059         {
1060                 AndroidHardwareBufferExternalApi* ahbApi = AndroidHardwareBufferExternalApi::getInstance();
1061                 if (!ahbApi)
1062                 {
1063                         TCU_THROW(NotSupportedError, "Platform doesn't support Android Hardware Buffer handles");
1064                 }
1065
1066                 deUint32 ahbFormat = 0;
1067                 ahbApi->describe(handle.getAndroidHardwareBuffer(), DE_NULL, DE_NULL, DE_NULL, &ahbFormat, DE_NULL, DE_NULL);
1068                 DE_ASSERT(ahbApi->ahbFormatIsBlob(ahbFormat) || image != 0);
1069
1070                 vk::VkImportAndroidHardwareBufferInfoANDROID    importInfo =
1071                 {
1072                         vk::VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
1073                         DE_NULL,
1074                         handle.getAndroidHardwareBuffer()
1075                 };
1076                 const vk::VkMemoryDedicatedAllocateInfo         dedicatedInfo =
1077                 {
1078                         vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
1079                         &importInfo,
1080                         image,
1081                         buffer,
1082                 };
1083                 const vk::VkMemoryAllocateInfo                                  info =
1084                 {
1085                         vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1086                         (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1087                         requirements.size,
1088                         (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits)  : memoryTypeIndex
1089                 };
1090                 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1091
1092                 return memory;
1093         }
1094         else
1095         {
1096                 DE_FATAL("Unknown external memory type");
1097                 return vk::Move<vk::VkDeviceMemory>();
1098         }
1099 }
1100
1101 vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface&                                   vkd,
1102                                                                                    vk::VkDevice                                                                 device,
1103                                                                                    const vk::VkMemoryRequirements&                              requirements,
1104                                                                                    vk::VkExternalMemoryHandleTypeFlagBits               externalType,
1105                                                                                    deUint32                                                                             memoryTypeIndex,
1106                                                                                    NativeHandle&                                                                handle)
1107 {
1108         return importMemory(vkd, device, (vk::VkBuffer)0, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle);
1109 }
1110
1111 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface&                                  vkd,
1112                                                                                                         vk::VkDevice                                                            device,
1113                                                                                                         vk::VkBuffer                                                            buffer,
1114                                                                                                         const vk::VkMemoryRequirements&                         requirements,
1115                                                                                                         vk::VkExternalMemoryHandleTypeFlagBits          externalType,
1116                                                                                                         deUint32                                                                        memoryTypeIndex,
1117                                                                                                         NativeHandle&                                                           handle)
1118 {
1119         return importMemory(vkd, device, buffer, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle);
1120 }
1121
1122 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface&                                  vkd,
1123                                                                                                         vk::VkDevice                                                            device,
1124                                                                                                         vk::VkImage                                                                     image,
1125                                                                                                         const vk::VkMemoryRequirements&                         requirements,
1126                                                                                                         vk::VkExternalMemoryHandleTypeFlagBits          externalType,
1127                                                                                                         deUint32                                                                        memoryTypeIndex,
1128                                                                                                         NativeHandle&                                                           handle)
1129 {
1130         return importMemory(vkd, device, (vk::VkBuffer)0, image, requirements, externalType, memoryTypeIndex, handle);
1131 }
1132
1133 vk::Move<vk::VkBuffer> createExternalBuffer (const vk::DeviceInterface&                                 vkd,
1134                                                                                          vk::VkDevice                                                           device,
1135                                                                                          deUint32                                                                       queueFamilyIndex,
1136                                                                                          vk::VkExternalMemoryHandleTypeFlagBits         externalType,
1137                                                                                          vk::VkDeviceSize                                                       size,
1138                                                                                          vk::VkBufferCreateFlags                                        createFlags,
1139                                                                                          vk::VkBufferUsageFlags                                         usageFlags)
1140 {
1141         const vk::VkExternalMemoryBufferCreateInfo                      externalCreateInfo      =
1142         {
1143                 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
1144                 DE_NULL,
1145                 (vk::VkExternalMemoryHandleTypeFlags)externalType
1146         };
1147         const vk::VkBufferCreateInfo                                            createInfo                      =
1148         {
1149                 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1150                 &externalCreateInfo,
1151                 createFlags,
1152                 size,
1153                 usageFlags,
1154                 vk::VK_SHARING_MODE_EXCLUSIVE,
1155                 1u,
1156                 &queueFamilyIndex
1157         };
1158
1159         return vk::createBuffer(vkd, device, &createInfo);
1160 }
1161
1162 vk::Move<vk::VkImage> createExternalImage (const vk::DeviceInterface&                                   vkd,
1163                                                                                    vk::VkDevice                                                                 device,
1164                                                                                    deUint32                                                                             queueFamilyIndex,
1165                                                                                    vk::VkExternalMemoryHandleTypeFlagBits               externalType,
1166                                                                                    vk::VkFormat                                                                 format,
1167                                                                                    deUint32                                                                             width,
1168                                                                                    deUint32                                                                             height,
1169                                                                                    vk::VkImageTiling                                                    tiling,
1170                                                                                    vk::VkImageCreateFlags                                               createFlags,
1171                                                                                    vk::VkImageUsageFlags                                                usageFlags,
1172                                                                                    deUint32                                                                             mipLevels,
1173                                                                                    deUint32                                                                             arrayLayers)
1174 {
1175         const vk::VkExternalMemoryImageCreateInfo               externalCreateInfo      =
1176         {
1177                 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
1178                 DE_NULL,
1179                 (vk::VkExternalMemoryHandleTypeFlags)externalType
1180         };
1181         const vk::VkImageCreateInfo                                             createInfo                      =
1182         {
1183                 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1184                 &externalCreateInfo,
1185                 createFlags,
1186                 vk::VK_IMAGE_TYPE_2D,
1187                 format,
1188                 { width, height, 1u, },
1189                 mipLevels,
1190                 arrayLayers,
1191                 vk::VK_SAMPLE_COUNT_1_BIT,
1192                 tiling,
1193                 usageFlags,
1194                 vk::VK_SHARING_MODE_EXCLUSIVE,
1195                 1,
1196                 &queueFamilyIndex,
1197                 vk::VK_IMAGE_LAYOUT_UNDEFINED
1198         };
1199
1200         return vk::createImage(vkd, device, &createInfo);
1201 }
1202
1203 #if (DE_OS == DE_OS_ANDROID)
1204 #  if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__)
1205 #      define BUILT_WITH_ANDROID_P_HARDWARE_BUFFER 1
1206 #  endif
1207
1208 static deInt32 androidGetSdkVersion()
1209 {
1210         static deInt32 sdkVersion = -1;
1211         if (sdkVersion < 0)
1212         {
1213                 char value[128] = {0};
1214                 __system_property_get("ro.build.version.sdk", value);
1215                 sdkVersion = static_cast<deInt32>(strtol(value, DE_NULL, 10));
1216                 printf("SDK Version is %d\n", sdkVersion);
1217         }
1218         return sdkVersion;
1219 }
1220
1221 static deInt32 checkAnbApiBuild()
1222 {
1223         deInt32 sdkVersion = androidGetSdkVersion();
1224 #if !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1225         // When testing AHB on Android-O and newer the CTS must be compiled against API26 or newer.
1226         DE_TEST_ASSERT(!(sdkVersion >= 26)); /* __ANDROID_API_O__ */
1227 #endif // !defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1228 #if !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1229         // When testing AHB on Android-P and newer the CTS must be compiled against API28 or newer.
1230         DE_TEST_ASSERT(!(sdkVersion >= 28)); /*__ANDROID_API_P__ */
1231 #endif // !defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1232         return sdkVersion;
1233 }
1234
1235 bool AndroidHardwareBufferExternalApi::supportsAhb()
1236 {
1237         return (checkAnbApiBuild() >= __ANDROID_API_O__);
1238 }
1239
1240 AndroidHardwareBufferExternalApi::AndroidHardwareBufferExternalApi()
1241 {
1242         deInt32 sdkVersion = checkAnbApiBuild();
1243         if(sdkVersion >= __ANDROID_API_O__)
1244         {
1245 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1246                 if (!loadAhbDynamicApis(sdkVersion))
1247                 {
1248                         // Couldn't load  Android AHB system APIs.
1249                         DE_TEST_ASSERT(false);
1250                 }
1251 #else
1252                 // Invalid Android AHB APIs configuration. Please check the instructions on how to build NDK for Android.
1253                 DE_TEST_ASSERT(false);
1254 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1255         }
1256 }
1257
1258 AndroidHardwareBufferExternalApi::~AndroidHardwareBufferExternalApi()
1259 {
1260 }
1261
1262 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1263 typedef int  (*pfn_system_property_get)(const char *, char *);
1264 typedef int  (*pfnAHardwareBuffer_allocate)(const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer);
1265 typedef void (*pfnAHardwareBuffer_describe)(const AHardwareBuffer* buffer, AHardwareBuffer_Desc* outDesc);
1266 typedef void (*pfnAHardwareBuffer_acquire)(AHardwareBuffer* buffer);
1267 typedef void (*pfnAHardwareBuffer_release)(AHardwareBuffer* buffer);
1268
1269 struct AhbFunctions
1270 {
1271         pfnAHardwareBuffer_allocate allocate;
1272         pfnAHardwareBuffer_describe describe;
1273         pfnAHardwareBuffer_acquire  acquire;
1274         pfnAHardwareBuffer_release  release;
1275 };
1276
1277 static AhbFunctions ahbFunctions;
1278
1279 static bool ahbFunctionsLoaded(AhbFunctions* pAhbFunctions)
1280 {
1281         static bool ahbApiLoaded = false;
1282         if (ahbApiLoaded ||
1283             ((pAhbFunctions->allocate != DE_NULL) &&
1284                 (pAhbFunctions->describe != DE_NULL) &&
1285                 (pAhbFunctions->acquire  != DE_NULL) &&
1286                 (pAhbFunctions->release  != DE_NULL)))
1287         {
1288                 ahbApiLoaded = true;
1289                 return true;
1290         }
1291         return false;
1292 }
1293
1294 bool AndroidHardwareBufferExternalApi::loadAhbDynamicApis(deInt32 sdkVersion)
1295 {
1296         if(sdkVersion >= __ANDROID_API_O__)
1297         {
1298                 if (!ahbFunctionsLoaded(&ahbFunctions))
1299                 {
1300                         de::DynamicLibrary libnativewindow("libnativewindow.so");
1301                         ahbFunctions.allocate = reinterpret_cast<pfnAHardwareBuffer_allocate>(libnativewindow.getFunction("AHardwareBuffer_allocate"));
1302                         ahbFunctions.describe = reinterpret_cast<pfnAHardwareBuffer_describe>(libnativewindow.getFunction("AHardwareBuffer_describe"));
1303                         ahbFunctions.acquire  = reinterpret_cast<pfnAHardwareBuffer_acquire>(libnativewindow.getFunction("AHardwareBuffer_acquire"));
1304                         ahbFunctions.release  = reinterpret_cast<pfnAHardwareBuffer_release>(libnativewindow.getFunction("AHardwareBuffer_release"));
1305
1306                         return ahbFunctionsLoaded(&ahbFunctions);
1307
1308                 }
1309                 else
1310                 {
1311                         return true;
1312                 }
1313         }
1314
1315         return false;
1316 }
1317
1318 class AndroidHardwareBufferExternalApi26 : public  AndroidHardwareBufferExternalApi
1319 {
1320 public:
1321
1322         virtual vk::pt::AndroidHardwareBufferPtr allocate(deUint32 width, deUint32  height, deUint32 layers, deUint32  format, deUint64 usage);
1323         virtual void acquire(vk::pt::AndroidHardwareBufferPtr buffer);
1324         virtual void release(vk::pt::AndroidHardwareBufferPtr buffer);
1325         virtual void describe(const vk::pt::AndroidHardwareBufferPtr buffer,
1326                                   deUint32* width,
1327                                   deUint32* height,
1328                                   deUint32* layers,
1329                                   deUint32* format,
1330                                   deUint64* usage,
1331                                   deUint32* stride);
1332         virtual deUint64 vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlag);
1333         virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag);
1334         virtual deUint32 vkFormatToAhbFormat(vk::VkFormat vkFormat);
1335         virtual deUint64 mustSupportAhbUsageFlags();
1336         virtual bool     ahbFormatIsBlob(deUint32 ahbFormat) { return (ahbFormat == AHARDWAREBUFFER_FORMAT_BLOB); };
1337
1338         AndroidHardwareBufferExternalApi26() : AndroidHardwareBufferExternalApi() {};
1339         virtual ~AndroidHardwareBufferExternalApi26() {};
1340
1341 private:
1342         // Stop the compiler generating methods of copy the object
1343         AndroidHardwareBufferExternalApi26(AndroidHardwareBufferExternalApi26 const& copy);            // Not Implemented
1344         AndroidHardwareBufferExternalApi26& operator=(AndroidHardwareBufferExternalApi26 const& copy); // Not Implemented
1345 };
1346
1347 vk::pt::AndroidHardwareBufferPtr AndroidHardwareBufferExternalApi26::allocate(  deUint32 width,
1348                                                                                                                                                                 deUint32 height,
1349                                                                                                                                                                 deUint32 layers,
1350                                                                                                                                                                 deUint32 format,
1351                                                                                                                                                                 deUint64 usage)
1352 {
1353         AHardwareBuffer_Desc hbufferdesc = {
1354                 width,
1355                 height,
1356                 layers,   // number of images
1357                 format,
1358                 usage,
1359                 0u,       // Stride in pixels, ignored for AHardwareBuffer_allocate()
1360                 0u,       // Initialize to zero, reserved for future use
1361                 0u        // Initialize to zero, reserved for future use
1362         };
1363
1364         AHardwareBuffer* hbuffer  = DE_NULL;
1365         ahbFunctions.allocate(&hbufferdesc, &hbuffer);
1366
1367         return vk::pt::AndroidHardwareBufferPtr(hbuffer);
1368 }
1369
1370 void AndroidHardwareBufferExternalApi26::acquire(vk::pt::AndroidHardwareBufferPtr buffer)
1371 {
1372         ahbFunctions.acquire(static_cast<AHardwareBuffer*>(buffer.internal));
1373 }
1374
1375 void AndroidHardwareBufferExternalApi26::release(vk::pt::AndroidHardwareBufferPtr buffer)
1376 {
1377         ahbFunctions.release(static_cast<AHardwareBuffer*>(buffer.internal));
1378 }
1379
1380 void AndroidHardwareBufferExternalApi26::describe( const vk::pt::AndroidHardwareBufferPtr buffer,
1381                                                                                                         deUint32* width,
1382                                                                                                         deUint32* height,
1383                                                                                                         deUint32* layers,
1384                                                                                                         deUint32* format,
1385                                                                                                         deUint64* usage,
1386                                                                                                         deUint32* stride)
1387 {
1388         AHardwareBuffer_Desc desc;
1389         ahbFunctions.describe(static_cast<const AHardwareBuffer*>(buffer.internal), &desc);
1390         if (width)  *width  = desc.width;
1391         if (height) *height = desc.height;
1392         if (layers) *layers = desc.layers;
1393         if (format) *format = desc.format;
1394         if (usage)  *usage  = desc.usage;
1395         if (stride) *stride = desc.stride;
1396 }
1397
1398 deUint64 AndroidHardwareBufferExternalApi26::vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlags)
1399 {
1400         switch(vkFlags)
1401         {
1402           case vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT:
1403           case vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT:
1404                 // No AHB equivalent.
1405                 return 0u;
1406           case vk::VK_IMAGE_USAGE_SAMPLED_BIT:
1407                 return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1408           case vk::VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT:
1409                 return AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE;
1410           case vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT:
1411                 return AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
1412           default:
1413                   return 0u;
1414         }
1415 }
1416
1417 deUint64 AndroidHardwareBufferExternalApi26::vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)
1418 {
1419         switch(vkFlags)
1420         {
1421           case vk::VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT:
1422           case vk::VK_IMAGE_CREATE_EXTENDED_USAGE_BIT:
1423                 // No AHB equivalent.
1424                 return 0u;
1425           case vk::VK_IMAGE_CREATE_PROTECTED_BIT:
1426                 return AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
1427           default:
1428                 return 0u;
1429         }
1430 }
1431
1432 deUint32 AndroidHardwareBufferExternalApi26::vkFormatToAhbFormat(vk::VkFormat vkFormat)
1433 {
1434          switch(vkFormat)
1435          {
1436            case vk::VK_FORMAT_R8G8B8A8_UNORM:
1437                  return AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
1438            case vk::VK_FORMAT_R8G8B8_UNORM:
1439                  return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
1440            case vk::VK_FORMAT_R5G6B5_UNORM_PACK16:
1441                  return AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
1442            case vk::VK_FORMAT_R16G16B16A16_SFLOAT:
1443                  return AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
1444            case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1445                  return AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
1446            default:
1447                  return 0u;
1448          }
1449 }
1450
1451 deUint64 AndroidHardwareBufferExternalApi26::mustSupportAhbUsageFlags()
1452 {
1453         return (AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT);
1454 }
1455
1456 #if defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1457 class AndroidHardwareBufferExternalApi28 : public  AndroidHardwareBufferExternalApi26
1458 {
1459 public:
1460
1461         virtual deUint64 vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag);
1462         virtual deUint64 mustSupportAhbUsageFlags();
1463
1464         AndroidHardwareBufferExternalApi28() : AndroidHardwareBufferExternalApi26() {};
1465         virtual ~AndroidHardwareBufferExternalApi28() {};
1466
1467 private:
1468         // Stop the compiler generating methods of copy the object
1469         AndroidHardwareBufferExternalApi28(AndroidHardwareBufferExternalApi28 const& copy);            // Not Implemented
1470         AndroidHardwareBufferExternalApi28& operator=(AndroidHardwareBufferExternalApi28 const& copy); // Not Implemented
1471 };
1472
1473 deUint64 AndroidHardwareBufferExternalApi28::vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlags)
1474 {
1475         switch(vkFlags)
1476         {
1477           case vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT:
1478                 return AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
1479           default:
1480                 return AndroidHardwareBufferExternalApi26::vkCreateToAhbUsage(vkFlags);
1481         }
1482 }
1483
1484 deUint64 AndroidHardwareBufferExternalApi28::mustSupportAhbUsageFlags()
1485 {
1486         return AndroidHardwareBufferExternalApi26::mustSupportAhbUsageFlags() | AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP | AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE;
1487 }
1488
1489 #endif // defined(BUILT_WITH_ANDROID_P_HARDWARE_BUFFER)
1490 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1491 #endif // (DE_OS == DE_OS_ANDROID)
1492
1493 AndroidHardwareBufferExternalApi* AndroidHardwareBufferExternalApi::getInstance()
1494 {
1495 #if (DE_OS == DE_OS_ANDROID)
1496         deInt32 sdkVersion = checkAnbApiBuild();
1497 #if defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1498 #  if defined(__ANDROID_API_P__) && (DE_ANDROID_API >= __ANDROID_API_P__)
1499         if (sdkVersion >= __ANDROID_API_P__ )
1500         {
1501                 static AndroidHardwareBufferExternalApi28 api28Instance;
1502                 return &api28Instance;
1503         }
1504 #  endif
1505 #  if defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
1506         if (sdkVersion >= __ANDROID_API_O__ )
1507         {
1508                 static AndroidHardwareBufferExternalApi26 api26Instance;
1509                 return &api26Instance;
1510         }
1511 #  endif
1512 #endif // defined(BUILT_WITH_ANDROID_HARDWARE_BUFFER)
1513         DE_UNREF(sdkVersion);
1514 #endif // DE_OS == DE_OS_ANDROID
1515         return DE_NULL;
1516 }
1517
1518 } // ExternalMemoryUtil
1519 } // vkt