通过MTLTexture

时间:2017-10-23 04:42:24

标签: metal metalkit

这是我的情景:

MTKView(以及其中的单个命令缓冲区)中,我有MTLTexture,这是MTLComputeEncoder操作的结果。

draw上的MTKView方法被称为dispatch_get_global_queue的高优先级实例。在drawRect的{​​{1}}的尾端,我“挖出”该纹理并将其设置为不同MTKView上的属性。然后我调度一个低优先级线程来调用该视图的MTKView方法,将原始纹理的一个区域复制到第二个draw,同时调用最终的MTKView调用 - 所有这些都是不同的命令缓冲区。同时,原始presentDrawable结束MTKView方法,并自行调用draw

我应该提及这些presentDrawable都配置了MTKViewsisPaused=YES

这一切都运行得相当不错,但我偶尔会遇到“enableSetNeedsDisplay=NO”警告或偶尔崩溃导致某些无法识别的线程崩溃:

[CAMetalLayerDrawable texture] should not be called after presenting the drawable

如果我删除/注释掉辅助“scoop”并重绘原始纹理,则不会发生崩溃。

有没有更可接受的方法来实现这一目标?可能使用QuartzCore`-[CAMetalDrawable present]: 0x7fff881cf471 <+0>: pushq %rbp 0x7fff881cf472 <+1>: movq %rsp, %rbp 0x7fff881cf475 <+4>: movq %rdi, %rax 0x7fff881cf478 <+7>: movq 0x15f25ce1(%rip), %rcx ; CAMetalDrawable._priv 0x7fff881cf47f <+14>: movq (%rax,%rcx), %rcx 0x7fff881cf483 <+18>: movq 0x20(%rcx), %rdi <---- crashes here 0x7fff881cf487 <+22>: xorps %xmm0, %xmm0 0x7fff881cf48a <+25>: movq %rax, %rsi 0x7fff881cf48d <+28>: popq %rbp 0x7fff881cf48e <+29>: jmp 0x7fff881cf493 ; layer_private_present(_CAMetalLayerPrivate*, CAMetalDrawable*, double, unsigned int) 显式复制提供的纹理的内容?

更新#1

更清晰的代码是一个明智的想法,可能:

这是主MTLBlitCommandEncoder的{​​{1}}方法,由drawRect驱动:

MTKView

在次要视图中:

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)

1 个答案:

答案 0 :(得分:1)

我不确定你是否意识到创建自己的纹理并渲染它是既可接受又常见的。您不必渲染视图或图层的可绘制纹理。

创建自己的纹理以进行渲染,然后,就目前的步骤而言,从纹理渲染到可绘制的纹理。

请注意,根据您正在做的事情,您可能需要旋转三个左右的纹理池。您需要关注的问题是Metal是否仍在从纹理中读取,因此在读取之前不要写入。