裁剪和缩放MTLTexture

8

我能否在现有的MTLTexture区域x1/y1/w1/h1上创建一个新的尺寸为w2/h2MTLTexture

注:我考虑使用MTLTexture.buffer?.makeTexture,但偏移量需要64字节。为什么?


如果您需要缩放/重采样,您可以考虑编写自己的内核或顶点/片段函数,或者如果您的目标是iOS 9.0+,则可以使用MetalPerformanceShaders框架中的MPSImageLanczosScale内核。 - warrenm
2个回答

9
这是一个使用 MPSImageLanczosScale 的示例。请注意,sourceRegion 是以源纹理的像素坐标系表示的,而 destRegion 应该等于目标纹理的整个区域(请注意,它不特别考虑目标区域的原点):
let scaleX = Double(destRegion.size.width) / Double(sourceRegion.size.width)
let scaleY = Double(destRegion.size.height) / Double(sourceRegion.size.height)
let translateX = Double(-sourceRegion.origin.x) * scaleX
let translateY = Double(-sourceRegion.origin.y) * scaleY
let filter = MPSImageLanczosScale(device: device)
var transform = MPSScaleTransform(scaleX: scaleX, scaleY: scaleY, translateX: translateX, translateY: translateY)
let commandBuffer = commandQueue.makeCommandBuffer()
withUnsafePointer(to: &transform) { (transformPtr: UnsafePointer<MPSScaleTransform>) -> () in
    filter.scaleTransform = transformPtr
    filter.encode(commandBuffer: commandBuffer, sourceTexture: sourceTexture, destinationTexture: destTexture)
}
commandBuffer.commit()
commandBuffer.waitUntilCompleted()

如果您需要在CPU上读取目标纹理,可以等待命令缓冲完成,或者将已完成处理程序添加到命令缓冲以接收异步回调,以便在重新采样工作完成时得到通知。否则,您可以在命令缓冲中编码额外的工作,并立即使用目标纹理。如果您要重复缩放纹理,则应保留单个 MPSImageLanczosScale 实例,而不是反复创建它的实例。


虽然我本来希望只引用缓冲区而不是创建一个副本,但我猜这样也还可以,因为纹理仍然在GPU内存中。 - user187676
1
如果目标纹理与源区域具有相同的尺寸,则可以使用blit命令编码器实现所需效果。我只是假设缩放部分是必要的,如果是这样,那么您将无法在没有某种重新采样的情况下完成。 - warrenm
@warrenm,我不是要唤起死者,但你有什么想法,为什么这个方法不能与MPSImageScale一起使用,对于那些想要比Lanczos Filter更快的东西的人来说?也许我们需要自己编写一个简单的线性缩放计算内核?在我看来,这应该是MPS已经拥有的东西。 - DaveNine
我没有建议使用MPSImageScale的唯一原因是当时它还不存在。 - warrenm
这听起来很有前途,但是 withUnsafePointervalidateComputeFunctionArguments:829 处失败了,断言失败:'Compute Function(lanczosHorizontalScale):写入纹理(dest[1]),其用途(0x01)未指定MTLTextureUsageShaderWrite (0x02)'。 - JCutting8
1
为了解决上述问题,需要确保在创建目标纹理时指定 textureDescriptor.usage = [.shaderRead, .shaderWrite] - JCutting8

5

MPSImageScale 不能直接使用,因为它是一个抽象类。具体的类为 MPSImageLanczosScaleMPSImageBilinearScale


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接