在Metal中同步统一缓冲区更新

时间:2017-02-16 12:57:21

标签: synchronization metal

我们假设我有以下代码(简化):

id<MTLBuffer> uniforms = ...;
MTLRenderCommandEncoder encoder = ...;

[uniforms contents] = some_data;
[encoder setVertexbuffer: uniforms ...];

DrawSomethingWithShader("myshader");

[uniforms contents] = some_other_data;    // WRONG! overwrites previous draw call's uniforms
[encoder setVertexbuffer: uniforms ...];

DrawSomethingElseWithShader("myshader");

在Vulkan中,有一种称为 vkCmdPipelineBarrier()的机制。但是,我在Metal中找不到任何类似的东西( MTLFence 是候选者,但似乎它用于其他类型的东西)。

所以我的问题是如何同步这个缓冲区更新?

(ps:我目前的想法是跟踪对缓​​冲区的修改并将“第二个统一数据”复制到另一个位置,但以强大的方式实现它会相当复杂) < / p>

1 个答案:

答案 0 :(得分:2)

您需要确保编码到命令缓冲区中的每个绘制调用的统一数据不仅可以在您结束编码之前访问,而且直到命令缓冲区本身完成。

这意味着您应该向缓冲区的内容指针添加偏移量,并在缓冲区的连续部分中为连续绘制调用写入统一数据。然后,您应该不写入与此帧对应的缓冲区域,直到完成为止。

由于您可能会在编码帧完成之前获得回调以绘制下一帧,因此您应该使用缓冲池并在它们之间循环,使用计数信号量控制访问。此建议详见Metal Best Practices Guide