【发布时间】:2021-11-03 08:32:14
【问题描述】:
我正在尝试将 3 个单独的东西渲染到 Metal 中的一个纹理。 我有一个 MTLTexture 用作 3 个不同 MTLCommandBuffers 中的目的地。我一个接一个地提交它们。每个 MTLCommandBuffer 渲染到纹理的一个单独部分 - 首先绘制 0 - 1/3 部分,第二个绘制中间 1/3 - 2/3,最后一个绘制 2/3 - 1。
id<MTLTexture> dst_texture = ...;
id<MTLCommandBuffer> buffer1 = [self drawToTexture:dst_texture];
[buffer1 commit];
id<MTLCommandBuffer> buffer2 = [self drawToTexture:dst_texture];
[buffer2 commit];
id<MTLCommandBuffer> buffer3 = [self drawToTexture:dst_texture];
[buffer3 commit];
问题在于,我似乎无法在不同的命令缓冲区中共享目标纹理 - 我出现故障,有时我只能看到目标纹理的部分结果...
在drawToTexture 里面我是这样使用 dst_texture 的:
_renderPassDescriptor.colorAttachments[0].texture = dst_texture;
_renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionLoad;
当我在每次单独提交后调用 [buffer waitUntilCompleted] 时问题得到解决,但我认为它会影响性能,我希望它没有阻塞/等待。
这行得通:
id<MTLTexture> dst_texture = ...;
id<MTLCommandBuffer> buffer1 = [self drawToTexture:dst_texture];
[buffer1 commit];
[buffer1 waitUntilCompleted];
id<MTLCommandBuffer> buffer2 = [self drawToTexture:dst_texture];
[buffer2 commit];
[buffer2 waitUntilCompleted];
id<MTLCommandBuffer> buffer3 = [self drawToTexture:dst_texture];
[buffer3 commit];
[buffer3 waitUntilCompleted];
我还能做些什么来避免waitUntilCompleted 来电?
【问题讨论】:
-
您是否使用相同的
MTLCommandQueue创建命令缓冲区? -
@FrankSchlegel - 是的,所有 3 个命令缓冲区都相同
-
您使用单独的命令缓冲区有什么原因吗?你能不能不使用一个命令缓冲区和 3 个编码器或一个编码器和 3 个绘制调用.. 不知道 drawToTexture 做了什么,但听起来它可能只是一个绘制调用,所以你只需要一个命令缓冲区和一个编码器..
-
@Gary 也许我应该研究一下。我正在做的是使用相同的着色器渲染相同的几何图形,但为每个命令缓冲区使用一组不同的制服。
-
在这种情况下,您绝对应该使用一个命令缓冲区和一个编码器,因此从 commandBuffer 创建您的 renderPassDescriptor 附加您的纹理,创建您的编码器对第一次绘制进行编码(设置缓冲区进行绘制调用),然后不要调用 endEncoding,重置统一缓冲区然后再次绘制,然后再次绘制 endEncoding。然后一切都会如你所愿,这是多次绘制一个纹理的标准方式。
标签: objective-c macos metal render-to-texture