外部内存和同步
有时,应用程序与 GPU 相关的所有操作并非都在 Vulkan 中完成。在各种情况下,内存是在 Vulkan 范围之外写入或读取的。为了支持这些用例,创建了一组外部内存和同步函数
内存 vs 同步

有一组扩展用于处理仅内存本身的导入/导出。另一组扩展用于控制内部 Vulkan 命令的同步原语 (VkFence
和 VkSemaphore
)。通常的做法是,对于每个导入/导出的内存片段,还有一个匹配的栅栏/信号量来管理内存访问。
功能
VK_KHR_external_fence_capabilities
、VK_KHR_external_semaphore_capabilities
和 VK_KHR_external_memory_capabilities
仅仅是查询有关实现提供的外部支持的信息的方法。
外部内存
VK_KHR_external_memory
扩展主要提供 VkExternalMemoryHandleTypeFlagBits
枚举,该枚举描述了外部使用的内存类型。
目前支持 3 种导入/导出内存的方式
-
VK_KHR_external_memory_fd
用于 POSIX 文件描述符中的内存 -
VK_KHR_external_memory_win32
用于 Windows 句柄中的内存 -
VK_ANDROID_external_memory_android_hardware_buffer
用于 AHardwareBuffer 中的内存
这些方法中的每一种都有关于限制、要求、所有权等的详细描述。
导入内存
要导入内存,给定外部内存扩展会提供一个 VkImport*Info
结构。将其传递给 vkAllocateMemory
,Vulkan 现在将具有映射到导入内存的 VkDeviceMemory
句柄。
// some external memory types require dedicated allocation
VkMemoryDedicatedAllocateInfo dedicated_info;
dedicated_info.buffer = buffer;
VkImportMemoryFdInfoKHR import_info;
import_info.pNext = &dedicated_info;
import_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
import_info.fd = fd;
VkMemoryAllocateInfo allocate_info;
allocate_info.pNext = &import_info
VkDeviceMemory device_memory;
vkAllocateMemory(device, &allocate_info, nullptr, device_memory);
导出内存
要导出内存,给定外部内存扩展会提供一个 VkGetMemory*
函数。此函数将接收一个 VkDeviceMemory
句柄,然后将其映射到扩展公开的对象。
VkExportMemoryAllocateInfo export_info;
export_info.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
VkMemoryAllocateInfo allocate_info;
allocate_info.pNext = &export_info
VkDeviceMemory device_memory;
vkAllocateMemory(device, &allocate_info, nullptr, device_memory);
VkMemoryGetFdInfoKHR get_handle_info;
get_handle_info.memory = device_memory;
get_handle_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
int fd;
vkGetMemoryFdKHR(device, &get_handle_info, &fd);
同步
外部同步可以在 Vulkan 中用于 VkFence
和 VkSemaphores
。两者在如何用于导入和导出方面几乎没有区别。
VK_KHR_external_fence
和 VK_KHR_external_semaphore
扩展都公开了 Vk*ImportFlagBits
枚举和 VkExport*CreateInfo
结构,以描述正在导入/导出的同步类型。
目前支持 2 种导入/导出同步的方式
-
VK_KHR_external_fence_fd
/VK_KHR_external_semaphore_fd
-
VK_KHR_external_fence_win32
/VK_KHR_external_semaphore_win32
每个扩展都解释了它如何管理同步原语的所有权。