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,
761 deUint32& exportedMemoryTypeIndex)
763 exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits);
764 const vk::VkMemoryDedicatedAllocateInfoKHR dedicatedInfo =
766 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
772 const vk::VkExportMemoryAllocateInfoKHR exportInfo =
774 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
775 !!buffer ? &dedicatedInfo : DE_NULL,
776 (vk::VkExternalMemoryHandleTypeFlagsKHR)externalType
778 const vk::VkMemoryAllocateInfo info =
780 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
783 exportedMemoryTypeIndex
785 return vk::allocateMemory(vkd, device, &info);
788 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::DeviceInterface& vkd,
790 const vk::VkMemoryRequirements& requirements,
791 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
793 deUint32& exportedMemoryTypeIndex)
795 exportedMemoryTypeIndex = chooseMemoryType(requirements.memoryTypeBits);
796 const vk::VkMemoryDedicatedAllocateInfoKHR dedicatedInfo =
798 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
804 const vk::VkExportMemoryAllocateInfoKHR exportInfo =
806 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
807 !!image ? &dedicatedInfo : DE_NULL,
808 (vk::VkExternalMemoryHandleTypeFlagsKHR)externalType
810 const vk::VkMemoryAllocateInfo info =
812 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
815 exportedMemoryTypeIndex
817 return vk::allocateMemory(vkd, device, &info);
820 vk::Move<vk::VkDeviceMemory> allocateExportableMemory (const vk::InstanceInterface& vki,
821 vk::VkPhysicalDevice physicalDevice,
822 const vk::DeviceInterface& vkd,
824 const vk::VkMemoryRequirements& requirements,
825 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
828 deUint32& exportedMemoryTypeIndex)
830 const vk::VkPhysicalDeviceMemoryProperties properties = vk::getPhysicalDeviceMemoryProperties(vki, physicalDevice);
832 for (deUint32 memoryTypeIndex = 0; (1u << memoryTypeIndex) <= requirements.memoryTypeBits; memoryTypeIndex++)
834 if (((requirements.memoryTypeBits & (1u << memoryTypeIndex)) != 0)
835 && (((properties.memoryTypes[memoryTypeIndex].propertyFlags & vk::VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0) == hostVisible))
837 const vk::VkMemoryDedicatedAllocateInfoKHR dedicatedInfo =
839 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
845 const vk::VkExportMemoryAllocateInfoKHR exportInfo =
847 vk::VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR,
848 !!buffer ? &dedicatedInfo : DE_NULL,
849 (vk::VkExternalMemoryHandleTypeFlagsKHR)externalType
851 const vk::VkMemoryAllocateInfo info =
853 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
859 exportedMemoryTypeIndex = memoryTypeIndex;
860 return vk::allocateMemory(vkd, device, &info);
864 TCU_THROW(NotSupportedError, "No supported memory type found");
867 static vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface& vkd,
871 const vk::VkMemoryRequirements& requirements,
872 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
873 deUint32 memoryTypeIndex,
874 NativeHandle& handle)
876 const bool isDedicated = !!buffer || !!image;
878 DE_ASSERT(!buffer || !image);
880 if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR)
882 const vk::VkImportMemoryFdInfoKHR importInfo =
884 vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
889 const vk::VkMemoryDedicatedAllocateInfoKHR dedicatedInfo =
891 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
896 const vk::VkMemoryAllocateInfo info =
898 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
899 (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
901 (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex
903 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
909 else if (externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR
910 || externalType == vk::VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_KHR)
912 const vk::VkImportMemoryWin32HandleInfoKHR importInfo =
914 vk::VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
917 handle.getWin32Handle(),
920 const vk::VkMemoryDedicatedAllocateInfoKHR dedicatedInfo =
922 vk::VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,
927 const vk::VkMemoryAllocateInfo info =
929 vk::VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
930 (isDedicated ? (const void*)&dedicatedInfo : (const void*)&importInfo),
932 (memoryTypeIndex == ~0U) ? chooseMemoryType(requirements.memoryTypeBits) : memoryTypeIndex
934 vk::Move<vk::VkDeviceMemory> memory (vk::allocateMemory(vkd, device, &info));
942 DE_FATAL("Unknown external memory type");
943 return vk::Move<vk::VkDeviceMemory>();
947 vk::Move<vk::VkDeviceMemory> importMemory (const vk::DeviceInterface& vkd,
949 const vk::VkMemoryRequirements& requirements,
950 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
951 deUint32 memoryTypeIndex,
952 NativeHandle& handle)
954 return importMemory(vkd, device, (vk::VkBuffer)0, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle);
957 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface& vkd,
960 const vk::VkMemoryRequirements& requirements,
961 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
962 deUint32 memoryTypeIndex,
963 NativeHandle& handle)
965 return importMemory(vkd, device, buffer, (vk::VkImage)0, requirements, externalType, memoryTypeIndex, handle);
968 vk::Move<vk::VkDeviceMemory> importDedicatedMemory (const vk::DeviceInterface& vkd,
971 const vk::VkMemoryRequirements& requirements,
972 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
973 deUint32 memoryTypeIndex,
974 NativeHandle& handle)
976 return importMemory(vkd, device, (vk::VkBuffer)0, image, requirements, externalType, memoryTypeIndex, handle);
979 vk::Move<vk::VkBuffer> createExternalBuffer (const vk::DeviceInterface& vkd,
981 deUint32 queueFamilyIndex,
982 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
983 vk::VkDeviceSize size,
984 vk::VkBufferCreateFlags createFlags,
985 vk::VkBufferUsageFlags usageFlags)
987 const vk::VkExternalMemoryBufferCreateInfoKHR externalCreateInfo =
989 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR,
991 (vk::VkExternalMemoryHandleTypeFlagsKHR)externalType
993 const vk::VkBufferCreateInfo createInfo =
995 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1000 vk::VK_SHARING_MODE_EXCLUSIVE,
1005 return vk::createBuffer(vkd, device, &createInfo);
1008 vk::Move<vk::VkImage> createExternalImage (const vk::DeviceInterface& vkd,
1009 vk::VkDevice device,
1010 deUint32 queueFamilyIndex,
1011 vk::VkExternalMemoryHandleTypeFlagBitsKHR externalType,
1012 vk::VkFormat format,
1015 vk::VkImageTiling tiling,
1016 vk::VkImageCreateFlags createFlags,
1017 vk::VkImageUsageFlags usageFlags)
1019 const vk::VkExternalMemoryImageCreateInfoKHR externalCreateInfo =
1021 vk::VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR,
1023 (vk::VkExternalMemoryHandleTypeFlagsKHR)externalType
1025 const vk::VkImageCreateInfo createInfo =
1027 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1028 &externalCreateInfo,
1030 vk::VK_IMAGE_TYPE_2D,
1032 { width, height, 1u, },
1035 vk::VK_SAMPLE_COUNT_1_BIT,
1038 vk::VK_SHARING_MODE_EXCLUSIVE,
1041 vk::VK_IMAGE_LAYOUT_UNDEFINED
1044 return vk::createImage(vkd, device, &createInfo);
1047 } // ExternalMemoryUtil