Vulkan 统一着色器数据
Vulkan uniform shader data
我从 opengl 习惯的是命令缓冲区内的资源绑定到着色器,如 glUniformMatrix4fv
。
现在据我所知,唯一的等价物是 vkCmdPushConstants
.
但也可以选择用所有对象的数据创建一个大缓冲区。然后使用 vkCmdBindDescriptorSets
更改偏移量,以便着色器使用相应对象的数据(纠正我这里有问题,这就是我想它可以完成的方式)。
但是现在 "right" 将每个对象的数据获取到着色器的方法是什么?它以何种方式取决于着色器需要为每个对象更改的数据量。
我的另一个问题与同步 gpu 和 cpu 有关。
在将下一帧的数据复制到 gpu 之前,您需要等待一帧准备就绪。
那么如何让缓冲区复制发生在命令缓冲区中呢?像 vkFlushMappedMemoryRanges
这样的东西需要一个命令缓冲区然后你可以设置信号量并等待数据的使用完成,然后用来自 RAM 的下一帧的新数据覆盖 gpu 上的旧数据。在 RAM 中,为交换链中的每个图像使用一个单独的缓冲区,这样您就可以开始为下一帧写入数据(直到交换链图像计数)。
如果您无法同步该缓冲区副本,在我看来您需要在 gpu 上有一个缓冲区,其中包含每个 swpachain 图像的每个对象数据。这对我来说似乎是在浪费 space。
我看到的问题有点解释,如果在 GPU 内存上的 RAM 中只有 1 个包含着色器数据的缓冲区,并且如果你不希望 gpu 在每帧之后空闲(我想你如果您已经为适合交换链的所有帧提交了命令缓冲区,则只想等待)
- cpu 将第 0 帧的对象位置推送到 gpu
- cpu 提交第 1 帧的命令缓冲区
- GPU 开始渲染第 0 帧
- cpu 将第 1 帧的对象位置推送到 gpu
- cpu 提交第 1 帧的命令缓冲区
- GPU 完成第 0 帧
- GPU 开始第 1 帧
- GPU 完成第 1 帧
在示例中,第 1 帧的数据已经推送到 gpu,而它仍在渲染第 0 帧,这会破坏第 0 帧。
对不起,如果我的post有点语无伦次或含糊不清,但很难解释一个你不完全理解的问题。
编辑:
每个顶点应该是每个对象。
我要寻找的功能是:
VkCmdFillGpuMemory(VkCommandBuffer 命令缓冲区,VkDeviceMemory myMemory,void* ramData)。
最好还有一个范围选项来仅复制一部分数据(因此可以选择仅复制数据已更改的对象的数据)
统一数据现在都必须通过 pushbuffers 或类似 UBO 的缓冲区。
每个顶点状态(顶点属性)在 VkGraphicsPipelineCreateInfo
中使用 VkPipelineVertexInputStateCreateInfo
设置,您设置要与 vkCmdBindVertexBuffers
一起使用的缓冲区。
有一个 vkCmdCopyBuffer 可以在缓冲区之间复制数据。
我从 opengl 习惯的是命令缓冲区内的资源绑定到着色器,如 glUniformMatrix4fv
。
现在据我所知,唯一的等价物是 vkCmdPushConstants
.
但也可以选择用所有对象的数据创建一个大缓冲区。然后使用 vkCmdBindDescriptorSets
更改偏移量,以便着色器使用相应对象的数据(纠正我这里有问题,这就是我想它可以完成的方式)。
但是现在 "right" 将每个对象的数据获取到着色器的方法是什么?它以何种方式取决于着色器需要为每个对象更改的数据量。
我的另一个问题与同步 gpu 和 cpu 有关。
在将下一帧的数据复制到 gpu 之前,您需要等待一帧准备就绪。
那么如何让缓冲区复制发生在命令缓冲区中呢?像 vkFlushMappedMemoryRanges
这样的东西需要一个命令缓冲区然后你可以设置信号量并等待数据的使用完成,然后用来自 RAM 的下一帧的新数据覆盖 gpu 上的旧数据。在 RAM 中,为交换链中的每个图像使用一个单独的缓冲区,这样您就可以开始为下一帧写入数据(直到交换链图像计数)。
如果您无法同步该缓冲区副本,在我看来您需要在 gpu 上有一个缓冲区,其中包含每个 swpachain 图像的每个对象数据。这对我来说似乎是在浪费 space。
我看到的问题有点解释,如果在 GPU 内存上的 RAM 中只有 1 个包含着色器数据的缓冲区,并且如果你不希望 gpu 在每帧之后空闲(我想你如果您已经为适合交换链的所有帧提交了命令缓冲区,则只想等待)
- cpu 将第 0 帧的对象位置推送到 gpu
- cpu 提交第 1 帧的命令缓冲区
- GPU 开始渲染第 0 帧
- cpu 将第 1 帧的对象位置推送到 gpu
- cpu 提交第 1 帧的命令缓冲区
- GPU 完成第 0 帧
- GPU 开始第 1 帧
- GPU 完成第 1 帧
在示例中,第 1 帧的数据已经推送到 gpu,而它仍在渲染第 0 帧,这会破坏第 0 帧。
对不起,如果我的post有点语无伦次或含糊不清,但很难解释一个你不完全理解的问题。
编辑: 每个顶点应该是每个对象。
我要寻找的功能是: VkCmdFillGpuMemory(VkCommandBuffer 命令缓冲区,VkDeviceMemory myMemory,void* ramData)。 最好还有一个范围选项来仅复制一部分数据(因此可以选择仅复制数据已更改的对象的数据)
统一数据现在都必须通过 pushbuffers 或类似 UBO 的缓冲区。
每个顶点状态(顶点属性)在 VkGraphicsPipelineCreateInfo
中使用 VkPipelineVertexInputStateCreateInfo
设置,您设置要与 vkCmdBindVertexBuffers
一起使用的缓冲区。
有一个 vkCmdCopyBuffer 可以在缓冲区之间复制数据。