我试图更好地理解使用时的同步要求Metal Performance Shaders
and an MTLBlitCommandEncoder
.
我有一个MTLCommandBuffer
设置如下:
如何确保 blit 编码器在金属性能着色器开始尝试缩放纹理 B 之前完全完成将数据从纹理 A 复制到纹理 B?我是否需要担心这个问题,或者命令缓冲区的串行性质是否已经为我解决了这个问题?
金属有栅栏的概念,使用MTLFence
用于同步对资源的访问,但无论如何我都不认为金属性能着色器会等待。 (然而waitForFence:
存在于编码器上。)
如果我不能使用栅栏并且确实需要同步,建议的做法是将 blit 编码器排入队列,然后调用waitUntilCompleted
在将着色器排队并调用之前在命令缓冲区上waitUntilCompleted
第二次?前任:
id<MTLCommandBuffer> commandBuffer;
// Enqueue blit encoder to copy Texture A -> Texture B
id<MTLBlitCommandEncoder> blitEncoder = [commandBuffer blitCommandEncoder];
[blitEncoder copyFromTexture:...];
[blitEncoder endEncoding];
// Wait for blit encoder to complete.
[commandBuffer commit];
[commandBuffer waitUntilCompleted];
// Scale Texture B -> Texture C
MPSImageBilinearScale *imageScaleShader = [[MPSImageBilinearScale alloc] initWithDevice:...];
[imageScaleShader encodeToCommandBuffer:commandBuffer...];
// Wait for scaling shader to complete.
[commandBuffer commit];
[commandBuffer waitUntilCompleted];
The reason I think I need to do the intermediary copy into Texture B is because MPSImageBilinearScale
appears to scale its entire source texture. The clipOffset
is useful for output, but it doesn't apply to the actual scaling or transform. So the tile needs to be extracted from Texture A into Texture B that is the same size as the tile itself. Then the scaling and transform will "make sense". Disregard this footnote because I had forgotten some basic math principles and have since figured out how to make the scale transform's translate properties work with the clipRect.
Metal 会为您解决这个问题。驱动程序和 GPU 在命令缓冲区中执行命令,就像以串行方式一样。 (“好像”允许并行运行或无序运行以提高效率,但前提是结果与串行执行时相同。)
当 CPU 和 GPU 处理相同的对象时,就会出现同步问题。还可以在屏幕上呈现纹理。 (您不应该渲染到屏幕上呈现的纹理。)
有一个Metal 编程指南部分 https://developer.apple.com/library/archive/documentation/Miscellaneous/Conceptual/MetalProgrammingGuide/WhatsNewiniOS10tvOS10andOSX1012/WhatsNewiniOS10tvOS10andOSX1012.html#//apple_ref/doc/uid/TP40014221-CH14-DontLinkElementID_73它处理着色器对资源的读写访问,这并不完全相同,但应该让您放心:
内存屏障
命令编码器之间
在给定命令编码器中执行的所有资源写入都是可见的
在下一个命令编码器中。对于渲染和计算都是如此
命令编码器。
在渲染命令编码器内
对于缓冲区,原子写入对后续原子读取可见
跨多个线程。
对于纹理,textureBarrier
方法确保写入
在给定的绘制调用中执行的操作对于后续读取是可见的
下一次抽奖电话。
在计算命令编码器内
在给定内核函数中执行的所有资源写入都是可见的
在下一个核函数中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)