1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * \brief Vulkan external memory utilities
20 *//*--------------------------------------------------------------------*/
22 #include "vktExternalMemoryUtil.hpp"
24 #include "vkQueryUtil.hpp"
26 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
30 # include <sys/types.h>
31 # include <sys/socket.h>
34 #if (DE_OS == DE_OS_WIN32)
35 # define WIN32_LEAN_AND_MEAN
41 namespace ExternalMemoryUtil
45 deUint32 chooseMemoryType (deUint32 bits)
49 for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= bits; memoryTypeIndex++)
51 if ((bits & (1u << memoryTypeIndex)) != 0)
52 return memoryTypeIndex;
55 DE_FATAL("No supported memory types");
61 NativeHandle::NativeHandle (void)
63 , m_win32HandleType (WIN32HANDLETYPE_LAST)
64 , m_win32Handle (DE_NULL)
68 NativeHandle::NativeHandle (const NativeHandle& other)
70 , m_win32HandleType (WIN32HANDLETYPE_LAST)
71 , m_win32Handle (DE_NULL)
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);
80 DE_FATAL("Platform doesn't support file descriptors");
83 else if (other.m_win32Handle.internal)
85 #if (DE_OS == DE_OS_WIN32)
86 m_win32HandleType = other.m_win32HandleType;
88 switch (other.m_win32HandleType)
90 case WIN32HANDLETYPE_NT:
92 DE_ASSERT(other.m_fd == -1);
94 const HANDLE process = ::GetCurrentProcess();
95 ::DuplicateHandle(process, other.m_win32Handle.internal, process, &m_win32Handle.internal, 0, TRUE, DUPLICATE_SAME_ACCESS);
100 case WIN32HANDLETYPE_KMT:
102 m_win32Handle = other.m_win32Handle;
107 DE_FATAL("Unknown win32 handle type");
110 DE_FATAL("Platform doesn't support win32 handles");
114 DE_FATAL("Native handle can't be duplicated");
117 NativeHandle::NativeHandle (int fd)
119 , m_win32HandleType (WIN32HANDLETYPE_LAST)
120 , m_win32Handle (DE_NULL)
124 NativeHandle::NativeHandle (Win32HandleType handleType, vk::pt::Win32Handle handle)
126 , m_win32HandleType (handleType)
127 , m_win32Handle (handle)
131 NativeHandle::~NativeHandle (void)
136 void NativeHandle::reset (void)
140 #if (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_UNIX)
141 DE_ASSERT(!m_win32Handle.internal);
144 DE_FATAL("Platform doesn't support file descriptors");
148 if (m_win32Handle.internal)
150 #if (DE_OS == DE_OS_WIN32)
151 switch (m_win32HandleType)
153 case WIN32HANDLETYPE_NT:
154 DE_ASSERT(m_fd == -1);
155 ::CloseHandle((HANDLE)m_win32Handle.internal);
158 case WIN32HANDLETYPE_KMT:
162 DE_FATAL("Unknown win32 handle type");
165 DE_FATAL("Platform doesn't support win32 handles");
170 m_win32Handle = vk::pt::Win32Handle(DE_NULL);
171 m_win32HandleType = WIN32HANDLETYPE_LAST;
174 NativeHandle& NativeHandle::operator= (int fd)
183 void NativeHandle::setWin32Handle (Win32HandleType type, vk::pt::Win32Handle handle)
187 m_win32HandleType = type;
188 m_win32Handle = handle;
191 void NativeHandle::disown (void)
194 m_win32Handle = vk::pt::Win32Handle(DE_NULL);
197 vk::pt::Win32Handle NativeHandle::getWin32Handle (void) const
199 DE_ASSERT(m_fd == -1);
200 return m_win32Handle;
203 int NativeHandle::getFd (void) const
205 DE_ASSERT(!m_win32Handle.internal);
210 const char* externalSemaphoreTypeToName (vk::VkExternalSemaphoreHandleTypeFlagBitsKHR type)
214 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
217 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR:
218 return "opaque_win32";
220 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR:
221 return "opaque_win32_kmt";
223 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT_KHR:
226 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
230 DE_FATAL("Unknown external semaphore type");
235 const char* externalFenceTypeToName (vk::VkExternalFenceHandleTypeFlagBitsKHR type)
239 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
242 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR:
243 return "opaque_win32";
245 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR:
246 return "opaque_win32_kmt";
248 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
252 DE_FATAL("Unknown external fence type");
257 const char* externalMemoryTypeToName (vk::VkExternalMemoryHandleTypeFlagBitsKHR type)
261 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
264 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR:
265 return "opaque_win32";
267 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR:
268 return "opaque_win32_kmt";
270 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT_KHR:
271 return "d3d11_texture";
273 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT_KHR:
274 return "d3d11_texture_kmt";
276 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT_KHR:
279 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT_KHR:
280 return "d3d12_resource";
283 DE_FATAL("Unknown external memory type");
288 bool isSupportedPermanence (vk::VkExternalSemaphoreHandleTypeFlagBitsKHR type,
289 Permanence permanence)
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;
297 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
298 return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
300 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
301 return permanence == PERMANENCE_TEMPORARY;
304 DE_FATAL("Unknown external semaphore type");
309 Transference getHandelTypeTransferences (vk::VkExternalSemaphoreHandleTypeFlagBitsKHR type)
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;
317 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
318 return TRANSFERENCE_REFERENCE;
320 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
321 return TRANSFERENCE_COPY;
324 DE_FATAL("Unknown external semaphore type");
325 return TRANSFERENCE_REFERENCE;
329 bool isSupportedPermanence (vk::VkExternalFenceHandleTypeFlagBitsKHR type,
330 Permanence permanence)
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;
338 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
339 return permanence == PERMANENCE_PERMANENT || permanence == PERMANENCE_TEMPORARY;
341 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
342 return permanence == PERMANENCE_TEMPORARY;
345 DE_FATAL("Unknown external fence type");
350 Transference getHandelTypeTransferences (vk::VkExternalFenceHandleTypeFlagBitsKHR type)
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;
358 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
359 return TRANSFERENCE_REFERENCE;
361 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
362 return TRANSFERENCE_COPY;
365 DE_FATAL("Unknown external fence type");
366 return TRANSFERENCE_REFERENCE;
370 int getMemoryFd (const vk::DeviceInterface& vkd,
372 vk::VkDeviceMemory memory,
373 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType)
375 const vk::VkMemoryGetFdInfoKHR info =
377 vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
385 VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd));
391 void getMemoryNative (const vk::DeviceInterface& vkd,
393 vk::VkDeviceMemory memory,
394 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
395 NativeHandle& nativeHandle)
397 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
399 const vk::VkMemoryGetFdInfoKHR info =
401 vk::VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
409 VK_CHECK(vkd.getMemoryFdKHR(device, &info, &fd));
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)
416 const vk::VkMemoryGetWin32HandleInfoKHR info =
418 vk::VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
424 vk::pt::Win32Handle handle (DE_NULL);
426 VK_CHECK(vkd.getMemoryWin32HandleKHR(device, &info, &handle));
428 switch (externalType)
430 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR:
431 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
434 case vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR:
435 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
439 DE_FATAL("Unknow external memory handle type");
443 DE_FATAL("Unknow external memory handle type");
446 vk::Move<vk::VkFence> createExportableFence (const vk::DeviceInterface& vkd,
448 vk::VkExternalFenceHandleTypeFlagBitsKHR externalType)
450 const vk::VkExportFenceCreateInfoKHR exportCreateInfo =
452 vk::VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR,
454 (vk::VkExternalFenceHandleTypeFlagsKHR)externalType
456 const vk::VkFenceCreateInfo createInfo =
458 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
463 return vk::createFence(vkd, device, &createInfo);
466 int getFenceFd (const vk::DeviceInterface& vkd,
469 vk::VkExternalFenceHandleTypeFlagBitsKHR externalType)
471 const vk::VkFenceGetFdInfoKHR info =
473 vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
481 VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd));
487 void getFenceNative (const vk::DeviceInterface& vkd,
490 vk::VkExternalFenceHandleTypeFlagBitsKHR externalType,
491 NativeHandle& nativeHandle)
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)
496 const vk::VkFenceGetFdInfoKHR info =
498 vk::VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
506 VK_CHECK(vkd.getFenceFdKHR(device, &info, &fd));
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)
513 const vk::VkFenceGetWin32HandleInfoKHR info =
515 vk::VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR,
521 vk::pt::Win32Handle handle (DE_NULL);
523 VK_CHECK(vkd.getFenceWin32HandleKHR(device, &info, &handle));
525 switch (externalType)
527 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR:
528 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
531 case vk::VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR:
532 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
536 DE_FATAL("Unknow external memory handle type");
540 DE_FATAL("Unknow external fence handle type");
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)
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)
553 const vk::VkImportFenceFdInfoKHR importInfo =
555 vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
563 VK_CHECK(vkd.importFenceFdKHR(device, &importInfo));
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)
569 const vk::VkImportFenceWin32HandleInfoKHR importInfo =
571 vk::VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR,
576 handle.getWin32Handle(),
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
585 DE_FATAL("Unknown fence external handle type");
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)
594 vk::Move<vk::VkFence> fence (createFence(vkd, device));
596 importFence(vkd, device, *fence, externalType, handle, flags);
601 vk::Move<vk::VkSemaphore> createExportableSemaphore (const vk::DeviceInterface& vkd,
603 vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType)
605 const vk::VkExportSemaphoreCreateInfoKHR exportCreateInfo =
607 vk::VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR,
609 (vk::VkExternalSemaphoreHandleTypeFlagsKHR)externalType
611 const vk::VkSemaphoreCreateInfo createInfo =
613 vk::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
618 return vk::createSemaphore(vkd, device, &createInfo);
621 int getSemaphoreFd (const vk::DeviceInterface& vkd,
623 vk::VkSemaphore semaphore,
624 vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType)
626 const vk::VkSemaphoreGetFdInfoKHR info =
628 vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
636 VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
642 void getSemaphoreNative (const vk::DeviceInterface& vkd,
644 vk::VkSemaphore semaphore,
645 vk::VkExternalSemaphoreHandleTypeFlagBitsKHR externalType,
646 NativeHandle& nativeHandle)
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)
651 const vk::VkSemaphoreGetFdInfoKHR info =
653 vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
661 VK_CHECK(vkd.getSemaphoreFdKHR(device, &info, &fd));
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)
668 const vk::VkSemaphoreGetWin32HandleInfoKHR info =
670 vk::VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR,
676 vk::pt::Win32Handle handle (DE_NULL);
678 VK_CHECK(vkd.getSemaphoreWin32HandleKHR(device, &info, &handle));
680 switch (externalType)
682 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR:
683 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_NT, handle);
686 case vk::VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR:
687 nativeHandle.setWin32Handle(NativeHandle::WIN32HANDLETYPE_KMT, handle);
691 DE_FATAL("Unknow external memory handle type");
695 DE_FATAL("Unknow external semaphore handle type");
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)
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)
708 const vk::VkImportSemaphoreFdInfoKHR importInfo =
710 vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
718 VK_CHECK(vkd.importSemaphoreFdKHR(device, &importInfo));
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)
724 const vk::VkImportSemaphoreWin32HandleInfoKHR importInfo =
726 vk::VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
731 handle.getWin32Handle(),
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
740 DE_FATAL("Unknown semaphore external handle type");
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)
749 vk::Move<vk::VkSemaphore> semaphore (createSemaphore(vkd, device));
751 importSemaphore(vkd, device, *semaphore, externalType, handle, flags);
756 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface& vkd,
758 const vk::VkMemoryRequirements& requirements,
759 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
762 const vk::VkMemoryDedicatedAllocateInfoKHR dedicatedInfo =
764 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
770 const vk::VkExportMemoryAllocateInfoKHR exportInfo =
772 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
773 !!buffer ? &dedicatedInfo : DE_NULL,
774 (vk::VkExternalMemoryHandleTypeFlagsKHR)externalType
776 const vk::VkMemoryAllocateInfo info =
778 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
781 chooseMemoryType(requirements.memoryTypeBits)
783 return vk::allocateMemory(vkd, device, &info);
786 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface& vkd,
788 const vk::VkMemoryRequirements& requirements,
789 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
792 const vk::VkMemoryDedicatedAllocateInfoKHR dedicatedInfo =
794 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
800 const vk::VkExportMemoryAllocateInfoKHR exportInfo =
802 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
803 !!image ? &dedicatedInfo : DE_NULL,
804 (vk::VkExternalMemoryHandleTypeFlagsKHR)externalType
806 const vk::VkMemoryAllocateInfo info =
808 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
811 chooseMemoryType(requirements.memoryTypeBits)
813 return vk::allocateMemory(vkd, device, &info);
816 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::InstanceInterface& vki,
817 vk::VkPhysicalDevice physicalDevice,
818 const vk::DeviceInterface& vkd,
820 const vk::VkMemoryRequirements& requirements,
821 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
825 const vk::VkPhysicalDeviceMemoryProperties properties = vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
827 for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= requirements.memoryTypeBits; memoryTypeIndex++)
829 if (((requirements.memoryTypeBits & (1u << memoryTypeIndex)) != 0)
830 && (((properties.memoryTypes[memoryTypeIndex].propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) == hostVisible))
832 const vk::VkMemoryDedicatedAllocateInfoKHR dedicatedInfo =
834 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
840 const vk::VkExportMemoryAllocateInfoKHR exportInfo =
842 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
843 !!buffer ? &dedicatedInfo : DE_NULL,
844 (vk::VkExternalMemoryHandleTypeFlagsKHR)externalType
846 const vk::VkMemoryAllocateInfo info =
848 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
853 return vk::allocateMemory(vkd, device, &info);
857 TCU_THROW(NotSupportedError, "No supported memory type found");
860 static vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface& vkd,
864 const vk::VkMemoryRequirements& requirements,
865 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
866 NativeHandle& handle)
868 const bool isDedicated = !!buffer || !!image;
870 DE_ASSERT(!buffer || !image);
872 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
874 const vk::VkImportMemoryFdInfoKHR importInfo =
876 vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
881 const vk::VkMemoryDedicatedAllocateInfoKHR dedicatedInfo =
883 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
888 const vk::VkMemoryAllocateInfo info =
890 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
891 (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
893 chooseMemoryType(requirements.memoryTypeBits)
895 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
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)
904 const vk::VkImportMemoryWin32HandleInfoKHR importInfo =
906 vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
909 handle.getWin32Handle(),
912 const vk::VkMemoryDedicatedAllocateInfoKHR dedicatedInfo =
914 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
919 const vk::VkMemoryAllocateInfo info =
921 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
922 (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
924 chooseMemoryType(requirements.memoryTypeBits)
926 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
934 DE_FATAL("Unknown external memory type");
935 return vk::Move<vk::VkDeviceMemory>();
939 vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface& vkd,
941 const vk::VkMemoryRequirements& requirements,
942 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
943 NativeHandle& handle)
945 return importMemory(vkd, device, (vk::VkBuffer)0, (vk::VkImage)0, requirements, externalType, handle);
948 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface& vkd,
951 const vk::VkMemoryRequirements& requirements,
952 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
953 NativeHandle& handle)
955 return importMemory(vkd, device, buffer, (vk::VkImage)0, requirements, externalType, handle);
958 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface& vkd,
961 const vk::VkMemoryRequirements& requirements,
962 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
963 NativeHandle& handle)
965 return importMemory(vkd, device, (vk::VkBuffer)0, image, requirements, externalType, handle);
968 vk::Move<vk::VkBuffer> createExternalBuffer (const vk::DeviceInterface& vkd,
970 deUint32 queueFamilyIndex,
971 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
972 vk::VkDeviceSize size,
973 vk::VkBufferCreateFlags createFlags,
974 vk::VkBufferUsageFlags usageFlags)
976 const vk::VkExternalMemoryBufferCreateInfoKHR externalCreateInfo =
978 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
980 (vk::VkExternalMemoryHandleTypeFlagsKHR)externalType
982 const vk::VkBufferCreateInfo createInfo =
984 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
989 vk::VK_SHARING_MODE_EXCLUSIVE,
994 return vk::createBuffer(vkd, device, &createInfo);
997 vk::Move<vk::VkImage> createExternalImage (const vk::DeviceInterface& vkd,
999 deUint32 queueFamilyIndex,
1000 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
1001 vk::VkFormat format,
1004 vk::VkImageTiling tiling,
1005 vk::VkImageCreateFlags createFlags,
1006 vk::VkImageUsageFlags usageFlags)
1008 const vk::VkExternalMemoryImageCreateInfoKHR externalCreateInfo =
1010 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR,
1012 (vk::VkExternalMemoryHandleTypeFlagsKHR)externalType
1014 const vk::VkImageCreateInfo createInfo =
1016 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1017 &externalCreateInfo,
1019 vk::VK_IMAGE_TYPE_2D,
1021 { width, height, 1u, },
1024 vk::VK_SAMPLE_COUNT_1_BIT,
1027 vk::VK_SHARING_MODE_EXCLUSIVE,
1030 vk::VK_IMAGE_LAYOUT_UNDEFINED
1033 return vk::createImage(vkd, device, &createInfo);
1036 } // ExternalMemoryUtil