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