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