Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 使用参数缓冲区动态渲染地形:了解为什么GPU飞行中不会覆盖粒子缓冲区_Objective C_Metal_Wwdc - Fatal编程技术网

Objective c 使用参数缓冲区动态渲染地形:了解为什么GPU飞行中不会覆盖粒子缓冲区

Objective c 使用参数缓冲区动态渲染地形:了解为什么GPU飞行中不会覆盖粒子缓冲区,objective-c,metal,wwdc,Objective C,Metal,Wwdc,我正在浏览一个苹果演示项目,该项目与2017年WWDC名为“介绍金属2”的视频相关,开发者在视频中演示了参数缓冲区的使用。该项目链接在Apple开发者网站上标题为“使用参数缓冲区动态渲染地形”的页面上。在这里,它们通过调度信号量\u t同步CPU的资源写入,以防止竞争条件,当命令缓冲区在GPU上执行完毕时发出信号,如果CPU在GPU前几帧写入数据,则等待它。这与2014年WWDC上一篇“金属加工:基础”中所展示的内容一致 我注意到,applparticlerender似乎在从上一个渲染过程的片段

我正在浏览一个苹果演示项目,该项目与2017年WWDC名为“介绍金属2”的视频相关,开发者在视频中演示了参数缓冲区的使用。该项目链接在Apple开发者网站上标题为“使用参数缓冲区动态渲染地形”的页面上。在这里,它们通过
调度信号量\u t
同步CPU的资源写入,以防止竞争条件,当命令缓冲区在GPU上执行完毕时发出信号,如果CPU在GPU前几帧写入数据,则等待它。这与2014年WWDC上一篇“金属加工:基础”中所展示的内容一致

我注意到,
applparticlerender
似乎在从上一个渲染过程的片段着色器读取相同的缓冲区之前,正在发送GPU在计算过程中写入的数据。缓冲区的资源存储模式为
MTLResourceStorageModePrivate
。我的问题:Metal是否自动同步访问只能由GPU访问的私有
id
s?从new
id
调用的渲染、计算和blit过程是否只有在其他过程写入和读取缓冲区后才能访问缓冲区(独占访问)?我已经看到,在平铺着色器中有保证的屏障,平铺内存在后续片段着色器访问内存之前由内核独占访问


最后,在2016年WWDC“金属的新功能,第2部分”中,第一位演示者Charles Brissart在16:44提到,从同一缓冲区读取和写入的片段和顶点函数必须放在两个渲染命令编码器中,但对于计算内核,一个计算命令编码器就足够了。这与粒子渲染器中看到的一致。

有关此答案的简要版本,请参见我对原始问题的评论

事实证明,对于
MTLResource
类型,Metal跟踪默认情况下调度到GPU的命令之间的依赖关系。根据金属文档,
MTLResource
hazardTrackingMode
属性默认为
MTLHazardTrackingModeTracked
MTLHazardTrackingMode.tracked
,在Swift中)。这意味着Metal跟踪修改资源的命令之间的依赖关系,就像粒子内核一样,并延迟执行,直到之前访问资源的命令完成。 因此,由于
\u particibledatapool
缓冲区的存储模式为
MTLResourceStorageModePrivate
storageModePrivate
在Swift中),因此只能由GPU写入;因此,该缓冲区不需要CPU/GPU与信号量同步,因此该资源不需要多缓冲区系统。 只有当一个资源可以被CPU写入而GPU仍在读取时,我们才需要多个缓冲区,这样CPU才不会空闲

请注意,
MTLHeap
的默认危险跟踪模式为
MTLHazardTrackingModeUntracked
MTLHazardTrackingMode.untracked
在Swift中),在这种情况下,您负责同步GPU的资源写入

编辑

在阅读了Metal中的资源同步之后,我还想提出一些额外的观点,我想进一步澄清发生了什么。请注意,其余部分为Swift格式。要了解更多详细信息,我建议阅读Metal文档中的“同步”部分

MTLFence

首先,使用
MTLFence
在单个命令缓冲区内同步对未跟踪资源的访问。围栏使您能够明确控制GPU何时访问资源,并且在使用未跟踪的资源时是必需的。否则,Metal将为您处理此同步

需要注意的是,我在回答中提到的自动管理只发生在编码过程之间的单个命令缓冲区中。但这并不意味着我们需要在相同的命令队列中调度的命令缓冲区之间进行同步,因为没有立即调度命令缓冲区执行。事实上,根据
MTLCommandBuffer
协议的
addScheduledHandler(:)
方法的文档,可以找到

设备对象在识别与系统中其他命令缓冲区或其他API提交的工作任务的任何依赖关系后,对命令缓冲区进行调度

在这一点上,访问这些相同的缓冲区是安全的。请注意,在单个渲染编码过程中,需要注意的是,如果顶点着色器将同一过程中的片段着色器读取的内容写入缓冲区,则这是未定义的。我在原始问题中提到了这一点,解决方案是使用两个渲染过程编码器。我还没有确定为什么这对于计算编码器来说不是必需的,但我想这与内核与顶点和片段着色器相比的执行方式有关

MTLEvent

但是,在某些情况下,由相同的MTL设备创建的不同队列中的命令缓冲区需要访问相同的资源或以某种方式相互依赖。在这种情况下,同步是必要的,因为单独的队列在不知道其他队列的情况下调度自己的命令缓冲区,这意味着两个命令缓冲区可能同时执行

要解决此问题,请使用设备使用
makeEvent()
创建的
MTLEvent
实例,并在每个缓冲区的特定点对事件信号进行编码

MTLSharedEvent

如果(没有双关语)您