在 Direct3D12 中,您可以使用“ID3D12Resource::WriteToSubresource”为 UMA 适配器启用零拷贝优化。
Vulkan 中“ID3D12Resource::WriteToSubresource”的等价物是什么?
在 Direct3D12 中,您可以使用“ID3D12Resource::WriteToSubresource”为 UMA 适配器启用零拷贝优化。
Vulkan 中“ID3D12Resource::WriteToSubresource”的等价物是什么?
似乎要做的事情WriteToSubresource
(在 Vulkan 等效术语中)是将像素数据从 CPU 内存写入图像,其存储在 CPU 可写内存中(因此需要首先映射它),无需命令即可立即执行缓冲区,并且无论线性/平铺如何都能够这样做。
Vulkan 没有办法做到这一点。您可以直接写入线性图像(在通用布局中)的后备存储,但不能写入平铺图像。您必须为此使用适当的传输命令,即使在 UMA 架构上也是如此。这意味着构建一个命令缓冲区并提交到一个支持传输的队列,因为 Vulkan 没有任何类似的立即复制命令。
执行此操作的 Vulkan 方法本质上是一个函数,该函数将数据写入到设备内存存储的映射指针,以适合VkImage
您打算存储在特定内存区域中的预初始化布局中的平铺。这样,您就可以将图像绑定到该内存位置,并且您可以将布局转换为您想要的任何内容。
但这需要添加这样的函数并允许将预初始化的布局用于平铺图像(只要数据是由该函数写入的)。
因此,从ID3D12Resource::WriteToSubresource
文档中我读到它执行了一份副本,上面撒了marketeze。
Vulkan 是一个显式 API,它完全可以让您在 UMA(或其他任何东西)上执行一个副本。如果您坚持使用线性平铺,它甚至可以让您进行真正的零拷贝。
UMA 可能看起来像这样:https ://vulkan.gpuinfo.org/displayreport.php?id=
4919#memorytypes 即只有一个堆,内存类型为两者DEVICE_LOCAL
和HOST_VISIBLE
。
因此,如果您在 VulkanvkMapMemory
的内存中创建一个线性平铺的图像\缓冲区,然后将数据直接生成到该映射指针中,那么您就有一个(真正的)零拷贝。
由于这并不总是实用的(即你不能总是选择如何分配事物,例如,如果它是从库函数返回的数据),有一个扩展VK_EXT_external_memory_host
(当然假设你的 ICD 支持它),它允许你导入你的主机数据直接,无需先制作 Vulkan 内存映射。
现在,有最佳平铺图像。最佳平铺在 Vulkan 中是不透明的(到目前为止),并且依赖于实现,因此如果没有一些逆向工程,您甚至不知道寻址方案。一般来说,您希望使用最佳平铺图像,因为据说访问它们具有更好的性能特征(至少在常见情况下)。
这就是单个副本的用武之地。您可以将线性平铺图像(或缓冲区)vkCmdCopy*
放入最佳平铺图像中。该副本由 Device\GPU 及其所有花里胡哨的功能执行,可能比 CPU 更快,即我怀疑他们称之为“接近零副本”。