gpt4 book ai didi

objective-c - 如何将 Metal Performance Shader 与 MTLBlitCommandEncoder 同步?

转载 作者:太空狗 更新时间:2023-10-30 03:52:26 26 4
gpt4 key购买 nike

我正在努力更好地理解使用 Metal Performance Shaders 时的同步要求和一个 MTLBlitCommandEncoder .

我有一个 MTLCommandBuffer设置如下:

  • 使用 MTLBlitCommandEncoder将纹理 A 的区域复制到纹理 B。纹理 A 比纹理 B 大。我正在从纹理 A 中提取“图 block ”并将其复制到纹理 B。

    <
  • 使用MPSImageBilinearScale Metal 性能着色器,纹理 B 作为源纹理,第三个纹理纹理 C 作为目标。此 Metal 性能着色器将缩放并可能将纹理 B 的内容转换为纹理 C。

在 Metal 性能着色器开始尝试缩放纹理 B 之前,如何确保 blit 编码器完全完成将数据从纹理 A 复制到纹理 B?我是否还需要为此担心,或者命令缓冲区的串行特性是否已经为我解决了这个问题?

Metal 有栅栏的概念使用 MTLFence用于同步对资源的访问,但无论如何我都看不到 Metal 性能着色器在栅栏上等待。 (而 waitForFence: 出现在编码器上。)

如果我不能使用 fences 而我确实需要同步,推荐的做法是将 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];

我认为我需要将中间副本复制到纹理 B 的原因是因为 MPSImageBilinearScale似乎缩放其整个源纹理。 clipOffset对输出很有用,但不适用于实际的缩放或变换。因此,需要将图 block 从纹理 A 提取到与图 block 本身大小相同的纹理 B 中。然后缩放和变换将“有意义”。忽略这个脚注,因为我忘记了一些基本的数学原理,并且从那以后想出了如何使缩放变换的平移属性与 clipRect 一起工作。

最佳答案

Metal 会为您处理这件事。驱动程序和 GPU 以串行方式在命令缓冲区中执行命令。 (“好像”允许并行运行或乱序运行以提高效率,但前提是结果与串行运行时相同。)

当 CPU 和 GPU 处理相同的对象时,就会出现同步问题。还可以在屏幕上呈现纹理。 (您不应该渲染到屏幕上显示的纹理。)

有一个 section of the Metal Programming Guide它处理着色器对资源的读写访问,这并不完全相同,但应该让你放心:

Memory Barriers

Between Command Encoders

All resource writes performed in a given command encoder are visible in the next command encoder. This is true for both render and compute command encoders.

Within a Render Command Encoder

For buffers, atomic writes are visible to subsequent atomic reads across multiple threads.

For textures, the textureBarrier method ensures that writes performed in a given draw call are visible to subsequent reads in the next draw call.

Within a Compute Command Encoder

All resource writes performed in a given kernel function are visible in the next kernel function.

关于objective-c - 如何将 Metal Performance Shader 与 MTLBlitCommandEncoder 同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52007588/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com