Don't leak ref to native handle in external memory tests
[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) && defined(__ANDROID_API_O__) && (DE_ANDROID_API >= __ANDROID_API_O__)
40 #       include <android/hardware_buffer.h>
41 #       define USE_ANDROID_O_HARDWARE_BUFFER 1
42 #endif
43
44 namespace vkt
45 {
46 namespace ExternalMemoryUtil
47 {
48 namespace
49 {
50 deUint32 chooseMemoryType (deUint32 bits)
51 {
52         DE_ASSERT(bits != 0);
53
54         for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
55         {
56                 if ((bits & (1u << memoryTypeIndex)) != 0)
57                         return memoryTypeIndex;
58         }
59
60         DE_FATAL("No supported memory types");
61         return -1;
62 }
63
64 } // anonymous
65
66 NativeHandle::NativeHandle (void)
67         : m_fd                                          (-1)
68         , m_win32HandleType                     (WIN32HANDLETYPE_LAST)
69         , m_win32Handle                         (DE_NULL)
70         , m_androidHardwareBuffer       (DE_NULL)
71 {
72 }
73
74 NativeHandle::NativeHandle (const NativeHandle& other)
75         : m_fd                                          (-1)
76         , m_win32HandleType                     (WIN32HANDLETYPE_LAST)
77         , m_win32Handle                         (DE_NULL)
78         , m_androidHardwareBuffer       (DE_NULL)
79 {
80         if (other.m_fd >= 0)
81         {
82 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
83                 DE_ASSERT(!other.m_win32Handle.internal);
84                 DE_ASSERT(!other.m_androidHardwareBuffer.internal);
85                 m_fd = dup(other.m_fd);
86                 TCU_CHECK(m_fd >= 0);
87 #else
88                 DE_FATAL("Platform doesn't support file descriptors");
89 #endif
90         }
91         else if (other.m_win32Handle.internal)
92         {
93 #if (DE_OS == DE_OS_WIN32)
94                 m_win32HandleType = other.m_win32HandleType;
95
96                 switch (other.m_win32HandleType)
97                 {
98                         case WIN32HANDLETYPE_NT:
99                         {
100                                 DE_ASSERT(other.m_fd == -1);
101                                 DE_ASSERT(!other.m_androidHardwareBuffer.internal);
102
103                                 const HANDLE process = ::GetCurrentProcess();
104                                 ::DuplicateHandle(process, other.m_win32Handle.internal, process, &m_win32Handle.internal, 0, TRUE, DUPLICATE_SAME_ACCESS);
105
106                                 break;
107                         }
108
109                         case WIN32HANDLETYPE_KMT:
110                         {
111                                 m_win32Handle = other.m_win32Handle;
112                                 break;
113                         }
114
115                         default:
116                                 DE_FATAL("Unknown win32 handle type");
117                 }
118 #else
119                 DE_FATAL("Platform doesn't support win32 handles");
120 #endif
121         }
122 #if defined(USE_ANDROID_O_HARDWARE_BUFFER)
123         else if (other.m_androidHardwareBuffer.internal)
124         {
125                 DE_ASSERT(other.m_fd == -1);
126                 DE_ASSERT(!other.m_win32Handle.internal);
127                 m_androidHardwareBuffer = other.m_androidHardwareBuffer;
128                 AHardwareBuffer_acquire((AHardwareBuffer*)m_androidHardwareBuffer.internal);
129         }
130 #endif
131         else
132                 DE_FATAL("Native handle can't be duplicated");
133 }
134
135 NativeHandle::NativeHandle (int fd)
136         : m_fd                                          (fd)
137         , m_win32HandleType                     (WIN32HANDLETYPE_LAST)
138         , m_win32Handle                         (DE_NULL)
139         , m_androidHardwareBuffer       (DE_NULL)
140 {
141 }
142
143 NativeHandle::NativeHandle (Win32HandleType handleType, vk::pt::Win32Handle handle)
144         : m_fd                                          (-1)
145         , m_win32HandleType                     (handleType)
146         , m_win32Handle                         (handle)
147         , m_androidHardwareBuffer       (DE_NULL)
148 {
149 }
150
151 NativeHandle::NativeHandle (vk::pt::AndroidHardwareBufferPtr buffer)
152         : m_fd                                          (-1)
153         , m_win32HandleType                     (WIN32HANDLETYPE_LAST)
154         , m_win32Handle                         (DE_NULL)
155         , m_androidHardwareBuffer       (buffer)
156 {
157 }
158
159 NativeHandle::~NativeHandle (void)
160 {
161         reset();
162 }
163
164 void NativeHandle::reset (void)
165 {
166         if (m_fd >= 0)
167         {
168 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
169                 DE_ASSERT(!m_win32Handle.internal);
170                 DE_ASSERT(!m_androidHardwareBuffer.internal);
171                 ::close(m_fd);
172 #else
173                 DE_FATAL("Platform doesn't support file descriptors");
174 #endif
175         }
176
177         if (m_win32Handle.internal)
178         {
179 #if (DE_OS == DE_OS_WIN32)
180                 switch (m_win32HandleType)
181                 {
182                         case WIN32HANDLETYPE_NT:
183                                 DE_ASSERT(m_fd == -1);
184                                 DE_ASSERT(!m_androidHardwareBuffer.internal);
185                                 ::CloseHandle((HANDLE)m_win32Handle.internal);
186                                 break;
187
188                         case WIN32HANDLETYPE_KMT:
189                                 break;
190
191                         default:
192                                 DE_FATAL("Unknown win32 handle type");
193                 }
194 #else
195                 DE_FATAL("Platform doesn't support win32 handles");
196 #endif
197         }
198
199 #if defined(USE_ANDROID_O_HARDWARE_BUFFER)
200         if (m_androidHardwareBuffer.internal)
201         {
202                 DE_ASSERT(m_fd == -1);
203                 DE_ASSERT(!m_win32Handle.internal);
204                 AHardwareBuffer_release((AHardwareBuffer*)m_androidHardwareBuffer.internal);
205         }
206 #endif
207
208         m_fd                                    = -1;
209         m_win32Handle                   = vk::pt::Win32Handle(DE_NULL);
210         m_win32HandleType               = WIN32HANDLETYPE_LAST;
211         m_androidHardwareBuffer = vk::pt::AndroidHardwareBufferPtr(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::disown (void)
241 {
242         m_fd = -1;
243         m_win32Handle = vk::pt::Win32Handle(DE_NULL);
244         m_androidHardwareBuffer = vk::pt::AndroidHardwareBufferPtr(DE_NULL);
245 }
246
247 vk::pt::Win32Handle NativeHandle::getWin32Handle (void) const
248 {
249         DE_ASSERT(m_fd == -1);
250         DE_ASSERT(!m_androidHardwareBuffer.internal);
251         return m_win32Handle;
252 }
253
254 int NativeHandle::getFd (void) const
255 {
256         DE_ASSERT(!m_win32Handle.internal);
257         DE_ASSERT(!m_androidHardwareBuffer.internal);
258         return m_fd;
259 }
260
261
262 vk::pt::AndroidHardwareBufferPtr NativeHandle::getAndroidHardwareBuffer (void) const
263 {
264         DE_ASSERT(m_fd == -1);
265         DE_ASSERT(!m_win32Handle.internal);
266         return m_androidHardwareBuffer;
267 }
268
269 const char* externalSemaphoreTypeToName (vk::VkExternalSemaphoreHandleTypeFlagBits type)
270 {
271         switch (type)
272         {
273                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
274                         return "opaque_fd";
275
276                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
277                         return "opaque_win32";
278
279                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
280                         return "opaque_win32_kmt";
281
282                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT:
283                         return "d3d12_fenc";
284
285                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
286                         return "sync_fd";
287
288                 default:
289                         DE_FATAL("Unknown external semaphore type");
290                         return DE_NULL;
291         }
292 }
293
294 const char* externalFenceTypeToName (vk::VkExternalFenceHandleTypeFlagBits type)
295 {
296         switch (type)
297         {
298                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
299                         return "opaque_fd";
300
301                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
302                         return "opaque_win32";
303
304                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
305                         return "opaque_win32_kmt";
306
307                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
308                         return "sync_fd";
309
310                 default:
311                         DE_FATAL("Unknown external fence type");
312                         return DE_NULL;
313         }
314 }
315
316 const char* externalMemoryTypeToName (vk::VkExternalMemoryHandleTypeFlagBits type)
317 {
318         switch (type)
319         {
320                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
321                         return "opaque_fd";
322
323                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:
324                         return "opaque_win32";
325
326                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
327                         return "opaque_win32_kmt";
328
329                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT:
330                         return "d3d11_texture";
331
332                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT:
333                         return "d3d11_texture_kmt";
334
335                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT:
336                         return "d3d12_heap";
337
338                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT:
339                         return "d3d12_resource";
340
341                 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:
342                         return "android_hardware_buffer";
343
344                 default:
345                         DE_FATAL("Unknown external memory type");
346                         return DE_NULL;
347         }
348 }
349
350 bool isSupportedPermanence (vk::VkExternalSemaphoreHandleTypeFlagBits   type,
351                                                         Permanence                                                                              permanence)
352 {
353         switch (type)
354         {
355                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
356                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
357                         return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
358
359                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
360                         return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
361
362                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
363                         return permanence == PERMANENCE_TEMPORARY;
364
365                 default:
366                         DE_FATAL("Unknown external semaphore type");
367                         return false;
368         }
369 }
370
371 Transference getHandelTypeTransferences (vk::VkExternalSemaphoreHandleTypeFlagBits type)
372 {
373         switch (type)
374         {
375                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
376                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
377                         return TRANSFERENCE_REFERENCE;
378
379                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
380                         return TRANSFERENCE_REFERENCE;
381
382                 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
383                         return TRANSFERENCE_COPY;
384
385                 default:
386                         DE_FATAL("Unknown external semaphore type");
387                         return TRANSFERENCE_REFERENCE;
388         }
389 }
390
391 bool isSupportedPermanence (vk::VkExternalFenceHandleTypeFlagBits       type,
392                                                         Permanence                                                                      permanence)
393 {
394         switch (type)
395         {
396                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
397                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
398                         return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
399
400                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
401                         return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
402
403                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
404                         return permanence == PERMANENCE_TEMPORARY;
405
406                 default:
407                         DE_FATAL("Unknown external fence type");
408                         return false;
409         }
410 }
411
412 Transference getHandelTypeTransferences (vk::VkExternalFenceHandleTypeFlagBits type)
413 {
414         switch (type)
415         {
416                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
417                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
418                         return TRANSFERENCE_REFERENCE;
419
420                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
421                         return TRANSFERENCE_REFERENCE;
422
423                 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
424                         return TRANSFERENCE_COPY;
425
426                 default:
427                         DE_FATAL("Unknown external fence type");
428                         return TRANSFERENCE_REFERENCE;
429         }
430 }
431
432 int getMemoryFd (const vk::DeviceInterface&                                     vkd,
433                                  vk::VkDevice                                                           device,
434                                  vk::VkDeviceMemory                                                     memory,
435                                  vk::VkExternalMemoryHandleTypeFlagBits         externalType)
436 {
437         const vk::VkMemoryGetFdInfoKHR  info    =
438         {
439                 vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
440                 DE_NULL,
441
442                 memory,
443                 externalType
444         };
445         int                                                             fd              = -1;
446
447         VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd));
448         TCU_CHECK(fd >= 0);
449
450         return fd;
451 }
452
453 void getMemoryNative (const vk::DeviceInterface&                                        vkd,
454                                                  vk::VkDevice                                                           device,
455                                                  vk::VkDeviceMemory                                                     memory,
456                                                  vk::VkExternalMemoryHandleTypeFlagBits         externalType,
457                                                  NativeHandle&                                                          nativeHandle)
458 {
459         if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
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                 nativeHandle = fd;
474         }
475         else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
476                 || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
477         {
478                 const vk::VkMemoryGetWin32HandleInfoKHR info    =
479                 {
480                         vk::VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
481                         DE_NULL,
482
483                         memory,
484                         externalType
485                 };
486                 vk::pt::Win32Handle                                             handle  (DE_NULL);
487
488                 VK_CHECK(vkd.getMemoryWin32HandleKHR(device, &info, &handle));
489
490                 switch (externalType)
491                 {
492                         case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT:
493                                 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
494                                 break;
495
496                         case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
497                                 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
498                                 break;
499
500                         default:
501                                 DE_FATAL("Unknown external memory handle type");
502                 }
503         }
504         else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
505         {
506                 const vk::VkMemoryGetAndroidHardwareBufferInfoANDROID   info    =
507                 {
508                         vk::VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
509                         DE_NULL,
510
511                         memory,
512                 };
513                 vk::pt::AndroidHardwareBufferPtr                                                ahb     (DE_NULL);
514
515                 VK_CHECK(vkd.getMemoryAndroidHardwareBufferANDROID(device, &info, &ahb));
516                 TCU_CHECK(ahb.internal);
517                 nativeHandle = ahb;
518         }
519         else
520                 DE_FATAL("Unknown external memory handle type");
521 }
522
523 vk::Move<vk::VkFence> createExportableFence (const vk::DeviceInterface&                                 vkd,
524                                                                                          vk::VkDevice                                                           device,
525                                                                                          vk::VkExternalFenceHandleTypeFlagBits          externalType)
526 {
527         const vk::VkExportFenceCreateInfo       exportCreateInfo        =
528         {
529                 vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
530                 DE_NULL,
531                 (vk::VkExternalFenceHandleTypeFlags)externalType
532         };
533         const vk::VkFenceCreateInfo                             createInfo                      =
534         {
535                 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
536                 &exportCreateInfo,
537                 0u
538         };
539
540         return vk::createFence(vkd, device, &createInfo);
541 }
542
543 int getFenceFd (const vk::DeviceInterface&                                      vkd,
544                                 vk::VkDevice                                                            device,
545                                 vk::VkFence                                                                     fence,
546                                 vk::VkExternalFenceHandleTypeFlagBits           externalType)
547 {
548         const vk::VkFenceGetFdInfoKHR   info    =
549         {
550                 vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
551                 DE_NULL,
552
553                 fence,
554                 externalType
555         };
556         int                                                             fd      = -1;
557
558         VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd));
559         TCU_CHECK(fd >= 0);
560
561         return fd;
562 }
563
564 void getFenceNative (const vk::DeviceInterface&                                 vkd,
565                                          vk::VkDevice                                                           device,
566                                          vk::VkFence                                                            fence,
567                                          vk::VkExternalFenceHandleTypeFlagBits          externalType,
568                                          NativeHandle&                                                          nativeHandle)
569 {
570         if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
571                 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
572         {
573                 const vk::VkFenceGetFdInfoKHR   info    =
574                 {
575                         vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
576                         DE_NULL,
577
578                         fence,
579                         externalType
580                 };
581                 int                                                             fd      = -1;
582
583                 VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd));
584                 TCU_CHECK(fd >= 0);
585                 nativeHandle = fd;
586         }
587         else if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
588                 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
589         {
590                 const vk::VkFenceGetWin32HandleInfoKHR  info    =
591                 {
592                         vk::VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR,
593                         DE_NULL,
594
595                         fence,
596                         externalType
597                 };
598                 vk::pt::Win32Handle                                             handle  (DE_NULL);
599
600                 VK_CHECK(vkd.getFenceWin32HandleKHR(device, &info, &handle));
601
602                 switch (externalType)
603                 {
604                         case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
605                                 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
606                                 break;
607
608                         case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
609                                 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
610                                 break;
611
612                         default:
613                                 DE_FATAL("Unknow external memory handle type");
614                 }
615         }
616         else
617                 DE_FATAL("Unknow external fence handle type");
618 }
619
620 void importFence (const vk::DeviceInterface&                            vkd,
621                                   const vk::VkDevice                                            device,
622                                   const vk::VkFence                                                     fence,
623                                   vk::VkExternalFenceHandleTypeFlagBits         externalType,
624                                   NativeHandle&                                                         handle,
625                                   vk::VkFenceImportFlags                                        flags)
626 {
627         if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT
628                 || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT)
629         {
630                 const vk::VkImportFenceFdInfoKHR        importInfo      =
631                 {
632                         vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
633                         DE_NULL,
634                         fence,
635                         flags,
636                         externalType,
637                         handle.getFd()
638                 };
639
640                 VK_CHECK(vkd.importFenceFdKHR(device, &importInfo));
641                 handle.disown();
642         }
643         else if (externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT
644                         || externalType == vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
645         {
646                 const vk::VkImportFenceWin32HandleInfoKHR       importInfo      =
647                 {
648                         vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
649                         DE_NULL,
650                         fence,
651                         flags,
652                         externalType,
653                         handle.getWin32Handle(),
654                         DE_NULL
655                 };
656
657                 VK_CHECK(vkd.importFenceWin32HandleKHR(device, &importInfo));
658                 // \note File descriptors and win32 handles behave differently, but this call wil make it seem like they would behave in same way
659                 handle.reset();
660         }
661         else
662                 DE_FATAL("Unknown fence external handle type");
663 }
664
665 vk::Move<vk::VkFence> createAndImportFence (const vk::DeviceInterface&                          vkd,
666                                                                                         const vk::VkDevice                                              device,
667                                                                                         vk::VkExternalFenceHandleTypeFlagBits   externalType,
668                                                                                         NativeHandle&                                                   handle,
669                                                                                         vk::VkFenceImportFlags                                  flags)
670 {
671         vk::Move<vk::VkFence>   fence   (createFence(vkd, device));
672
673         importFence(vkd, device, *fence, externalType, handle, flags);
674
675         return fence;
676 }
677
678 vk::Move<vk::VkSemaphore> createExportableSemaphore (const vk::DeviceInterface&                                 vkd,
679                                                                                                          vk::VkDevice                                                           device,
680                                                                                                          vk::VkExternalSemaphoreHandleTypeFlagBits      externalType)
681 {
682         const vk::VkExportSemaphoreCreateInfo   exportCreateInfo        =
683         {
684                 vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
685                 DE_NULL,
686                 (vk::VkExternalSemaphoreHandleTypeFlags)externalType
687         };
688         const vk::VkSemaphoreCreateInfo                         createInfo                      =
689         {
690                 vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
691                 &exportCreateInfo,
692                 0u
693         };
694
695         return vk::createSemaphore(vkd, device, &createInfo);
696 }
697
698 int getSemaphoreFd (const vk::DeviceInterface&                                  vkd,
699                                         vk::VkDevice                                                            device,
700                                         vk::VkSemaphore                                                         semaphore,
701                                         vk::VkExternalSemaphoreHandleTypeFlagBits       externalType)
702 {
703         const vk::VkSemaphoreGetFdInfoKHR       info    =
704         {
705                 vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
706                 DE_NULL,
707
708                 semaphore,
709                 externalType
710         };
711         int                                                                             fd      = -1;
712
713         VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
714         TCU_CHECK(fd >= 0);
715
716         return fd;
717 }
718
719 void getSemaphoreNative (const vk::DeviceInterface&                                     vkd,
720                                                  vk::VkDevice                                                           device,
721                                                  vk::VkSemaphore                                                        semaphore,
722                                                  vk::VkExternalSemaphoreHandleTypeFlagBits      externalType,
723                                                  NativeHandle&                                                          nativeHandle)
724 {
725         if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
726                 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
727         {
728                 const vk::VkSemaphoreGetFdInfoKHR       info    =
729                 {
730                         vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
731                         DE_NULL,
732
733                         semaphore,
734                         externalType
735                 };
736                 int                                                                             fd      = -1;
737
738                 VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
739                 TCU_CHECK(fd >= 0);
740                 nativeHandle = fd;
741         }
742         else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
743                 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
744         {
745                 const vk::VkSemaphoreGetWin32HandleInfoKHR      info    =
746                 {
747                         vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
748                         DE_NULL,
749
750                         semaphore,
751                         externalType
752                 };
753                 vk::pt::Win32Handle                                                     handle  (DE_NULL);
754
755                 VK_CHECK(vkd.getSemaphoreWin32HandleKHR(device, &info, &handle));
756
757                 switch (externalType)
758                 {
759                         case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT:
760                                 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
761                                 break;
762
763                         case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT:
764                                 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
765                                 break;
766
767                         default:
768                                 DE_FATAL("Unknow external memory handle type");
769                 }
770         }
771         else
772                 DE_FATAL("Unknow external semaphore handle type");
773 }
774
775 void importSemaphore (const vk::DeviceInterface&                                        vkd,
776                                           const vk::VkDevice                                                    device,
777                                           const vk::VkSemaphore                                                 semaphore,
778                                           vk::VkExternalSemaphoreHandleTypeFlagBits             externalType,
779                                           NativeHandle&                                                                 handle,
780                                           vk::VkSemaphoreImportFlags                                    flags)
781 {
782         if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT
783                 || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT)
784         {
785                 const vk::VkImportSemaphoreFdInfoKHR    importInfo      =
786                 {
787                         vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
788                         DE_NULL,
789                         semaphore,
790                         flags,
791                         externalType,
792                         handle.getFd()
793                 };
794
795                 VK_CHECK(vkd.importSemaphoreFdKHR(device, &importInfo));
796                 handle.disown();
797         }
798         else if (externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
799                         || externalType == vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
800         {
801                 const vk::VkImportSemaphoreWin32HandleInfoKHR   importInfo      =
802                 {
803                         vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
804                         DE_NULL,
805                         semaphore,
806                         flags,
807                         externalType,
808                         handle.getWin32Handle(),
809                         DE_NULL
810                 };
811
812                 VK_CHECK(vkd.importSemaphoreWin32HandleKHR(device, &importInfo));
813                 // \note File descriptors and win32 handles behave differently, but this call wil make it seem like they would behave in same way
814                 handle.reset();
815         }
816         else
817                 DE_FATAL("Unknown semaphore external handle type");
818 }
819
820 vk::Move<vk::VkSemaphore> createAndImportSemaphore (const vk::DeviceInterface&                                          vkd,
821                                                                                                         const vk::VkDevice                                                              device,
822                                                                                                         vk::VkExternalSemaphoreHandleTypeFlagBits               externalType,
823                                                                                                         NativeHandle&                                                                   handle,
824                                                                                                         vk::VkSemaphoreImportFlags                                              flags)
825 {
826         vk::Move<vk::VkSemaphore>       semaphore       (createSemaphore(vkd, device));
827
828         importSemaphore(vkd, device, *semaphore, externalType, handle, flags);
829
830         return semaphore;
831 }
832
833 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface&                                       vkd,
834                                                                                                            vk::VkDevice                                                                 device,
835                                                                                                            const vk::VkMemoryRequirements&                              requirements,
836                                                                                                            vk::VkExternalMemoryHandleTypeFlagBits               externalType,
837                                                                                                            vk::VkBuffer                                                                 buffer,
838                                                                                                            deUint32&                                                                    exportedMemoryTypeIndex)
839 {
840         exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits);
841         const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo   =
842         {
843                 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
844                 DE_NULL,
845
846                 (vk::VkImage)0,
847                 buffer
848         };
849         const vk::VkExportMemoryAllocateInfo    exportInfo      =
850         {
851                 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
852                 !!buffer ? &dedicatedInfo : DE_NULL,
853                 (vk::VkExternalMemoryHandleTypeFlags)externalType
854         };
855         const vk::VkMemoryAllocateInfo                  info            =
856         {
857                 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
858                 &exportInfo,
859                 requirements.size,
860                 exportedMemoryTypeIndex
861         };
862         return vk::allocateMemory(vkd, device, &info);
863 }
864
865 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface&                                       vkd,
866                                                                                                            vk::VkDevice                                                                 device,
867                                                                                                            const vk::VkMemoryRequirements&                              requirements,
868                                                                                                            vk::VkExternalMemoryHandleTypeFlagBits               externalType,
869                                                                                                            vk::VkImage                                                                  image,
870                                                                                                            deUint32&                                                                    exportedMemoryTypeIndex)
871 {
872         exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits);
873         const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo   =
874         {
875                 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
876                 DE_NULL,
877
878                 image,
879                 (vk::VkBuffer)0
880         };
881         const vk::VkExportMemoryAllocateInfo    exportInfo      =
882         {
883                 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
884                 !!image ? &dedicatedInfo : DE_NULL,
885                 (vk::VkExternalMemoryHandleTypeFlags)externalType
886         };
887         const vk::VkMemoryAllocateInfo                  info            =
888         {
889                 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
890                 &exportInfo,
891                 requirements.size,
892                 exportedMemoryTypeIndex
893         };
894         return vk::allocateMemory(vkd, device, &info);
895 }
896
897 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::InstanceInterface&                                     vki,
898                                                                                                            vk::VkPhysicalDevice                                                 physicalDevice,
899                                                                                                            const vk::DeviceInterface&                                   vkd,
900                                                                                                            vk::VkDevice                                                                 device,
901                                                                                                            const vk::VkMemoryRequirements&                              requirements,
902                                                                                                            vk::VkExternalMemoryHandleTypeFlagBits               externalType,
903                                                                                                            bool                                                                                 hostVisible,
904                                                                                                            vk::VkBuffer                                                                 buffer,
905                                                                                                            deUint32&                                                                    exportedMemoryTypeIndex)
906 {
907         const vk::VkPhysicalDeviceMemoryProperties properties = vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
908
909         for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= requirements.memoryTypeBits; memoryTypeIndex++)
910         {
911                 if (((requirements.memoryTypeBits & (1u << memoryTypeIndex)) != 0)
912                         && (((properties.memoryTypes[memoryTypeIndex].propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) == hostVisible))
913                 {
914                         const vk::VkMemoryDedicatedAllocateInfo dedicatedInfo   =
915                         {
916                                 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
917                                 DE_NULL,
918
919                                 (vk::VkImage)0,
920                                 buffer
921                         };
922                         const vk::VkExportMemoryAllocateInfo    exportInfo      =
923                         {
924                                 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
925                                 !!buffer ? &dedicatedInfo : DE_NULL,
926                                 (vk::VkExternalMemoryHandleTypeFlags)externalType
927                         };
928                         const vk::VkMemoryAllocateInfo                  info            =
929                         {
930                                 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
931                                 &exportInfo,
932                                 requirements.size,
933                                 memoryTypeIndex
934                         };
935
936                         exportedMemoryTypeIndex = memoryTypeIndex;
937                         return vk::allocateMemory(vkd, device, &info);
938                 }
939         }
940
941         TCU_THROW(NotSupportedError, "No supported memory type found");
942 }
943
944 static vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface&                            vkd,
945                                                                                                   vk::VkDevice                                                          device,
946                                                                                                   vk::VkBuffer                                                          buffer,
947                                                                                                   vk::VkImage                                                           image,
948                                                                                                   const vk::VkMemoryRequirements&                       requirements,
949                                                                                                   vk::VkExternalMemoryHandleTypeFlagBits        externalType,
950                                                                                                   deUint32                                                                      memoryTypeIndex,
951                                                                                                   NativeHandle&                                                         handle)
952 {
953         const bool      isDedicated             = !!buffer || !!image;
954
955         DE_ASSERT(!buffer || !image);
956
957         if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT)
958         {
959                 const vk::VkImportMemoryFdInfoKHR                       importInfo              =
960                 {
961                         vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
962                         DE_NULL,
963                         externalType,
964                         handle.getFd()
965                 };
966                 const vk::VkMemoryDedicatedAllocateInfo         dedicatedInfo   =
967                 {
968                         vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
969                         &importInfo,
970                         image,
971                         buffer,
972                 };
973                 const vk::VkMemoryAllocateInfo                          info                    =
974                 {
975                         vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
976                         (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
977                         requirements.size,
978                         (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex
979                 };
980                 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
981
982                 handle.disown();
983
984                 return memory;
985         }
986         else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT
987                         || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT)
988         {
989                 const vk::VkImportMemoryWin32HandleInfoKHR      importInfo              =
990                 {
991                         vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
992                         DE_NULL,
993                         externalType,
994                         handle.getWin32Handle(),
995                         DE_NULL
996                 };
997                 const vk::VkMemoryDedicatedAllocateInfo         dedicatedInfo   =
998                 {
999                         vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
1000                         &importInfo,
1001                         image,
1002                         buffer,
1003                 };
1004                 const vk::VkMemoryAllocateInfo                          info                    =
1005                 {
1006                         vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1007                         (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1008                         requirements.size,
1009                         (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits)  : memoryTypeIndex
1010                 };
1011                 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1012
1013                 handle.disown();
1014
1015                 return memory;
1016         }
1017 #if defined(USE_ANDROID_O_HARDWARE_BUFFER)
1018         else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
1019         {
1020                 AHardwareBuffer_Desc desc;
1021                 AHardwareBuffer_describe(static_cast<const AHardwareBuffer*>(handle.getAndroidHardwareBuffer().internal), &desc);
1022
1023                 DE_ASSERT(desc.format == AHARDWAREBUFFER_FORMAT_BLOB || image != 0);
1024
1025                 vk::VkImportAndroidHardwareBufferInfoANDROID    importInfo =
1026                 {
1027                         vk::VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID,
1028                         DE_NULL,
1029                         handle.getAndroidHardwareBuffer()
1030                 };
1031                 const vk::VkMemoryDedicatedAllocateInfo         dedicatedInfo =
1032                 {
1033                         vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
1034                         &importInfo,
1035                         image,
1036                         buffer,
1037                 };
1038                 const vk::VkMemoryAllocateInfo                                  info =
1039                 {
1040                         vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
1041                         (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
1042                         requirements.size,
1043                         (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits)  : memoryTypeIndex
1044                 };
1045                 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
1046
1047                 return memory;
1048         }
1049 #endif // (USE_ANDROID_O_HARDWARE_BUFFER)
1050         else
1051         {
1052                 DE_FATAL("Unknown external memory type");
1053                 return vk::Move<vk::VkDeviceMemory>();
1054         }
1055 }
1056
1057 vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface&                                   vkd,
1058                                                                                    vk::VkDevice                                                                 device,
1059                                                                                    const vk::VkMemoryRequirements&                              requirements,
1060                                                                                    vk::VkExternalMemoryHandleTypeFlagBits               externalType,
1061                                                                                    deUint32                                                                             memoryTypeIndex,
1062                                                                                    NativeHandle&                                                                handle)
1063 {
1064         return importMemory(vkd, device, (vk::VkBuffer)0, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle);
1065 }
1066
1067 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface&                                  vkd,
1068                                                                                                         vk::VkDevice                                                            device,
1069                                                                                                         vk::VkBuffer                                                            buffer,
1070                                                                                                         const vk::VkMemoryRequirements&                         requirements,
1071                                                                                                         vk::VkExternalMemoryHandleTypeFlagBits          externalType,
1072                                                                                                         deUint32                                                                        memoryTypeIndex,
1073                                                                                                         NativeHandle&                                                           handle)
1074 {
1075         return importMemory(vkd, device, buffer, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle);
1076 }
1077
1078 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface&                                  vkd,
1079                                                                                                         vk::VkDevice                                                            device,
1080                                                                                                         vk::VkImage                                                                     image,
1081                                                                                                         const vk::VkMemoryRequirements&                         requirements,
1082                                                                                                         vk::VkExternalMemoryHandleTypeFlagBits          externalType,
1083                                                                                                         deUint32                                                                        memoryTypeIndex,
1084                                                                                                         NativeHandle&                                                           handle)
1085 {
1086         return importMemory(vkd, device, (vk::VkBuffer)0, image, requirements, externalType, memoryTypeIndex, handle);
1087 }
1088
1089 vk::Move<vk::VkBuffer> createExternalBuffer (const vk::DeviceInterface&                                 vkd,
1090                                                                                          vk::VkDevice                                                           device,
1091                                                                                          deUint32                                                                       queueFamilyIndex,
1092                                                                                          vk::VkExternalMemoryHandleTypeFlagBits         externalType,
1093                                                                                          vk::VkDeviceSize                                                       size,
1094                                                                                          vk::VkBufferCreateFlags                                        createFlags,
1095                                                                                          vk::VkBufferUsageFlags                                         usageFlags)
1096 {
1097         const vk::VkExternalMemoryBufferCreateInfo                      externalCreateInfo      =
1098         {
1099                 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
1100                 DE_NULL,
1101                 (vk::VkExternalMemoryHandleTypeFlags)externalType
1102         };
1103         const vk::VkBufferCreateInfo                                            createInfo                      =
1104         {
1105                 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1106                 &externalCreateInfo,
1107                 createFlags,
1108                 size,
1109                 usageFlags,
1110                 vk::VK_SHARING_MODE_EXCLUSIVE,
1111                 1u,
1112                 &queueFamilyIndex
1113         };
1114
1115         return vk::createBuffer(vkd, device, &createInfo);
1116 }
1117
1118 vk::Move<vk::VkImage> createExternalImage (const vk::DeviceInterface&                                   vkd,
1119                                                                                    vk::VkDevice                                                                 device,
1120                                                                                    deUint32                                                                             queueFamilyIndex,
1121                                                                                    vk::VkExternalMemoryHandleTypeFlagBits               externalType,
1122                                                                                    vk::VkFormat                                                                 format,
1123                                                                                    deUint32                                                                             width,
1124                                                                                    deUint32                                                                             height,
1125                                                                                    vk::VkImageTiling                                                    tiling,
1126                                                                                    vk::VkImageCreateFlags                                               createFlags,
1127                                                                                    vk::VkImageUsageFlags                                                usageFlags,
1128                                                                                    deUint32 mipLevels,
1129                                                                                    deUint32 arrayLayers)
1130 {
1131         const vk::VkExternalMemoryImageCreateInfo               externalCreateInfo      =
1132         {
1133                 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
1134                 DE_NULL,
1135                 (vk::VkExternalMemoryHandleTypeFlags)externalType
1136         };
1137         const vk::VkImageCreateInfo                                             createInfo                      =
1138         {
1139                 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1140                 &externalCreateInfo,
1141                 createFlags,
1142                 vk::VK_IMAGE_TYPE_2D,
1143                 format,
1144                 { width, height, 1u, },
1145                 mipLevels,
1146                 arrayLayers,
1147                 vk::VK_SAMPLE_COUNT_1_BIT,
1148                 tiling,
1149                 usageFlags,
1150                 vk::VK_SHARING_MODE_EXCLUSIVE,
1151                 1,
1152                 &queueFamilyIndex,
1153                 vk::VK_IMAGE_LAYOUT_UNDEFINED
1154         };
1155
1156         return vk::createImage(vkd, device, &createInfo);
1157 }
1158
1159 } // ExternalMemoryUtil
1160 } // vkt