使用MPSImageScale和MTLBlitCommandEncoder

时间:2018-11-08 18:55:57

标签: objective-c macos metal metalkit

TL; DR:从我的MTKView的委托drawInMTKView:方法中,部分渲染过程包括添加一个MPSImageBilinearScale性能着色器和零个或多个MTLBlitCommandEncoder请求generateMipmapsForTexture。在主线程上发生的drawInMTKView:中这是一件聪明的事情吗?它们中的一个在运行时是否阻塞了主线程,或者它们只是被编码然后在以后完全在GPU上执行?

长版:

在成像应用程序的背景下,我正在玩Metal。我使用Core Image加载图像并应用滤镜。输出图像在具有单个纹理的金属视图中显示为2D平面。这可行,但是为了提高性能,我想尝试使用Core Image一次渲染较小的图块的功能。每个图块都呈现为自己的IOSurface

在每个渲染过程中,我检查是否有最近渲染的图块。对于每个渲染的图块(现在为IOSurface),我从CVMetalTextureCache创建一个由表面支持的Metal纹理。

我认为使用缩放比例MPS从图块纹理复制到“主”纹理中。如果将图块复制过来,那么我将发出blit命令以在主纹理上生成mipmap。

我看到的是,如果我的主纹理很大,则生成mipmap可能会花费“一些时间”。如果我有很多瓷砖,也是如此。 似乎这正在阻塞主线程,因为我的FPS显着下降。 (MTKView以标准的60fps运行。)

如果我试着使用磁贴大小,则可以提高某些区域的性能,但可以降低某些区域的性能。例如,增加Core Image渲染的磁贴大小可创建更少的磁贴,从而减少生成mipmap和blit的调用,但要以Core Image花费更长的时间渲染一个区域为代价。

如果我减小“主”纹理的大小,则mipmap的生成会更快,因为仅更新了脏纹理,但是如果我制作主纹理,则应该缩小的范围似乎较小太小,则需要将大量纹理传递给片段着色器。 (看起来这个限制可能是128?)

我尚不清楚的是,在仍然使用MTKView的情况下,我可以从主线程中移出多少。如果渲染通道的一部分将阻塞主线程,则我希望将其移至后台,以便UI元素(如滑块和复选框)保持完全响应。

也许这不是一开始就正确的策略?除了平铺以外,还有其他更好的方法可以在Metal中显示真正的大图像吗? (即:图片是否超过了Metal的纹理大小限制16384?)

0 个答案:

没有答案