vulkan - 如何正确共享 VkDeviceMemory?VkExternalMemoryBufferCreateInfoKHR 有什么用?
问题描述
这是我上一篇文章的延续。简而言之 - 我有多个VkDevice
(和多个一切- 交换链、命令缓冲区等),我想用这些资源渲染相同的几何图形,即我不想多次上传数据。正如@Ekzuzy 指出的那样,我可以使用VK_KHR_external_memory
. 我试过了,实际上它有效,但我还有一些问题以及调试层抱怨。
这是最重要的步骤:
包括所有必需的扩展:
instanceExtensions.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME); instanceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); instanceExtensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); instanceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME); deviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); deviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME); deviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME); deviceExtensions.push_back(VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME); deviceExtensions.push_back(VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
使用数据创建设备本地内存。它打算成为共享内存:
a) create_staging_buffer_and_memory b) copy_data_to_staging_buffer c) create_device_local_buffer_and_memory d) copy_staging_buffer_to_device_local_buffer e) create_memory_handle
VkBuffer
这里的对象是临时的,复制完成后会被销毁。分期记忆也是。使用字段中的VkExportMemoryAllocateInfoKHR
结构 创建的设备本地内存。通过调用VkMemoryAllocateInfo::pNext
获得的内存句柄。vkGetMemoryFdKHR
在该步骤之后,我有一个内存,其中包含设备中的数据和指向它的句柄。创建
VkBuffer
并且VkDeviceMemory
应该参与实际渲染。VkImportMemoryFdInfoKHR
使用字段中的结构创建的内存VkMemoryAllocateInfo::pNext
,我使用之前获得的句柄。最后记录一个命令缓冲区,其中从 step 绑定一个缓冲区
3
。
正如我之前所写 - 我看到了输出,但调试层告诉我:
layer MEM: vkCmdBindVertexBuffers(): Cannot read invalid region of memory allocation 0x17 for bound Buffer object 0x16, 请在使用前填充内存。
我不确定为什么。以及层如何知道内存无效。无论如何,这对我来说是错误的,我不应该担心这个警告。还是应该?
另一个问题是关于VkExternalMemoryBufferCreateInfoKHR
哪个用于VkBufferCreateInfo::pNext
. 我不清楚文档的作用-它拥有的所有信息都是某个句柄的类型。哪个把手?并且应用程序在指定和不指定此结构的情况下都可以正常工作。
更新:似乎图层警告是一个错误。
解决方案
VkExternalMemoryBufferCreateInfoKHR
用于创建跨 API 共享的内存,或者可能跨底层物理设备相同的Vulkan 实例或设备共享的内存。
在我的示例存储库中,有一个使用外部存储器 API 在 OpenGL 和 Vulkan 之间共享纹理图像信息的示例。此示例使用 API 的 Win32 HANDLE 版本,但功能与 FD 版本相同,只是用于存储要在不同 API 之间传递的标识符的类型不同。
另一个问题是关于在 VkBufferCreateInfo::pNext 中使用的 VkExternalMemoryBufferCreateInfoKHR
此结构用于通知 vulkan 实例相关缓冲区可能是共享的,这可能会影响 Vulkan 驱动程序在内部管理它的方式。
我认为当从外部存储器创建 Vulkan 缓冲区时会使用此结构。在缓冲区(或图像)创建期间,您将使用此结构来标记图像将由外部内存支持,然后您将pNext
MemoryAllocateInfo设置为ImportMemoryHostPointerInfoEXT
包含共享句柄的实例,而不是正常分配。我怀疑它没有在我的示例中使用,因为我使用 Vulkan 仅用于导出,而 GL 端进行导入。如果您在导出和导入端都使用 Vulkan,则可能需要它。
推荐阅读
- ruby-on-rails - 尝试运行 db:migrate in rails 时出错
- project-reactor - GroupedFlux 中的 Reactor delayElements 延迟所有组中的元素
- http-headers - 通过 HTTP 标头传递 cookie?
- google-sheets - 如何使谷歌表单响应提交到电子表格底部而不忽略电子表格中手动输入的数据
- date - 按年份在同一散点图上绘制两条回归线:X 轴日期 MM/DD
- javascript - 从 3D 数组中检索值
- java - 实体管理器在尝试使用 JPA 连接到 Java 中的 Dockerised DB2 时为空,也使用 maven 和 Open Liberty
- javascript - 是否有特定的方法可以路由到 GitHub Pages 站点上的不同页面?
- linux - 在 unix 中重新编码列值
- python - 在文件中搜索特定信息