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

Synchronization 在Metal中同步统一缓冲区更新,synchronization,metal,Synchronization,Metal,假设我有以下代码(简化): id=。。。; MTLRenderCommandEncoder编码器=。。。; [内容]=一些_数据; [编码器setVertexbuffer:uniforms…]; 用Shader(“myshader”)画一些东西; [内容]=一些其他数据;//错了!覆盖上一次抽签呼叫的制服 [编码器setVertexbuffer:uniforms…]; 用Shader(“myshader”)画一些东西; 在Vulkan中,有一种称为vkCmdPipelineBarrier()的

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

id=。。。;
MTLRenderCommandEncoder编码器=。。。;
[内容]=一些_数据;
[编码器setVertexbuffer:uniforms…];
用Shader(“myshader”)画一些东西;
[内容]=一些其他数据;//错了!覆盖上一次抽签呼叫的制服
[编码器setVertexbuffer:uniforms…];
用Shader(“myshader”)画一些东西;
在Vulkan中,有一种称为vkCmdPipelineBarrier()的机制。然而,我在金属中找不到任何类似的东西(MTLFence是一个候选,但似乎它被用于其他种类的东西)

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


(注:我目前的想法是跟踪对缓冲区的修改,并将“第二个统一数据”复制到另一个位置,但以健壮的方式实现将相当复杂)

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

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


因为在编码的帧完成之前,您可能会得到一个回调来绘制下一帧,所以您应该使用一个缓冲池并在它们之间循环,用计数信号量控制访问。此建议在中有详细说明。

这正是我所担心的……无论如何,谢谢。(附言:我把这个问题留待几天)
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");