这似乎是一个简单的Vulkan API问题,但我真的找不到搜索互联网后的答案.我注意到有一个Vulkan功能:
void vkCmdUpdateBuffer(
VkCommandBuffer commandBuffer,
VkBuffer dstBuffer,
VkDeviceSize dstOffset,
VkDeviceSize dataSize,
const void* pData);
Run Code Online (Sandbox Code Playgroud)
乍一看,我认为它可用于记录命令缓冲区,因为它vkCmd
的名称中有前缀,但文档说明了这一点
vkCmdUpdateBuffer仅允许在渲染过程之外.出于同步障碍的目的,此命令被视为"传输"操作.
所以我开始认为它是一个便利函数,它包含缓冲区数据传输操作,就像memcpy()
用来将数据从主机复制到设备一样.
然后我的问题是:为什么没有一个Vulkan样本/教程(我已经搜索了所有这些)vkCmdUpdateBuffer()
而不是手动处理数据memcpy()
.我明白了吗?
所有vkCmd*
函数都将命令生成到命令缓冲区中.这个也不例外.它是一个传输命令,和大多数传输命令一样,你不能在渲染过程中完成它们.但是有很多命令缓冲区生成命令在渲染过程中不起作用.
通常,Vulkan内存传输操作仅发生在设备内存之间.主机将某些内容放入设备内存的典型机制是写入映射指针.但根据定义,这要求目标内存可以映射.因此,如果要将内容写入不可映射的内存,则必须将其复制到可映射内存,然后通过vkCmdCopy*
函数在可映射内存和不可映射内存之间执行传输操作.
如果您同时进行一系列转移,那就没问题.您可以将一堆内容复制到映射内存中,然后提交包含所有复制操作的批处理,以将数据复制到适当的位置.
但有时候,你只是更新了一小块设备内存.如果它不可映射,那么只需要向GPU获取几千字节的数据就可以做很多工作.在这种情况下,vkCmdUpdateBuffer
可能是更好的选择,因为它可以"直接"从CPU内存复制到任何设备内存.
我说"直接",因为这显然不是它正在做的事情.除了它在命令缓冲区中执行它之外,它确实做了你应该做的事情.您可以将CPU数据复制到GPU可映射内存中,然后创建一个命令,将该可映射内存复制到不可映射的内存中.
vkCmdUpdateBuffer
做同样的事情.它将数据从您指定的指针/大小复制到可映射的内存中(由命令缓冲区本身提供.这就是它的上限为64KB的原因).这个副本会立即发生,就像你做的那样memcpy
,所以当这个函数返回时,你可以用你给它的指针做任何你想做的事情.然后,它在命令缓冲区中创建一个命令,该命令从命令缓冲区中的可映射内存复制到目标内存位置.
此函数的文档明确提供有关将其用于更大传输的警告.也就是说,它告诉你不要这样做.这是为了快速,小巧,一次性更新不可映射的内存.而已.
这就是为什么教程不讨论它的一个原因:它是一个非常特殊的功能,许多新手用户会尝试使用它,因为它比显式代码更容易.但在大多数情况下,他们不应该使用它.
归档时间: |
|
查看次数: |
234 次 |
最近记录: |