Metal 中的高性能纹理区域副本

Performant texture region copies in Metal

我将 Metal 视为一种以 60fps 执行高性能像素复制的选项。

让我用现有技术来表述我的问题...

我有附加的 1920x1080 NSImage,我想以 "mosaic" 类型的方式将其转换为 NSView。假设此图像是一帧视频,那么它更有可能是 RGBA32 格式 CVPixelBuffer)。这 9 个彩色区域中的每一个都可能最终出现在屏幕上的随机位置。

我可以使用 NSImage API 中的 drawInRect 函数执行 9 次这样的从图像源到目标 NSView 的复制调用。这种情况下的数据模型将涉及 9 个源-目标 CGRect 对,然后 9 个这样的调用来执行复制。

我怀疑与 Metal 中可能发生的情况相比,这是一种非常缓慢的方法。如果 NSView 是金属支持的,它可能会加速。

有人能告诉我这是一个非常高效的 Metal 版本吗?

目的是按原样上传整个纹理,一次上传到 GPU,然后发出一组基于 GPU 的调用以(最终)将纹理的区域 blit 到屏幕上。假设源像素格式为 RGBA32。意图显然是仅用于一次 CPU->GPU 像素数据传输(无往返!)。

这种方法是否会首先涉及使用 copyFromBuffer to get the image on the GPU, then a set of 9 calls to copyFromTexture 来完成呈现的纹理?然后将该纹理映射到屏幕上的四边形上。只是猜测。这会是什么样子?

(Metal2 现在有一些一次性参数缓冲区这一事实对我很有吸引力,可能只是 MTLBlitCommandEncoder 中上述两个函数的较低级别实现。如果这是一个更高性能的较低级别的实现,那会是什么样子?)

如有任何相关指导,我们将不胜感激。

我认为任何不太复杂的方法都会有很好的性能。顶点很少,只涉及一个纹理。

您可以使用 MTKTextureLoader 及其方法创建初始纹理,以从 CGImage 甚至原始图像数据源(URL 或图像资源)创建纹理。或者,由于您提到了 Core Video,您可以直接从中获得 Metal 纹理。

如果您想将该纹理的不同扇区绘制到视图的不同扇区,我会绘制 9 个四边形(在单个绘制调用中)并为每个四边形使用适当的纹理坐标。无需将纹理块从一个地方复制到另一个地方。