2016-12-05 59 views
3

我可以創建一個新的MTLTexture尺寸w2/h2現有的MTLTexture區域x1/y1/w1/h1作物和鱗片MTLTexture

PS:我想過使用MTLTexture.buffer?.makeTexture,但偏移量需要爲64個字節。爲什麼?

+0

如果您需要縮放/重新採樣,您可以考慮編寫自己的內核或頂點/片段函數,或者如果您的目標是iOS 9.0+,則使用MetalPerformanceShaders框架中的「MPSImageLanczosScale」內核。 – warrenm

回答

2

下面是一個示例,說明如何使用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的實例,而不是反覆創建它的實例。

+0

儘管我希望只是引用緩衝區而不是創建副本,但我認爲這仍然足以滿足GPU內存中的紋理。 –

+1

如果目標紋理具有與源區域相同的尺寸,則可以使用blit命令編碼器實現您想要的效果。我只是假定縮放部分是必不可少的,在這種情況下,如果沒有某種重新採樣,就無法獲得。 – warrenm

+0

@warrenm我並不是想要保護死者,但是對於我們這些想要比Lanczos過濾器更快一點的人來說,爲什麼這不適用於MPSImageScale?也許有必要自己編寫一個天真的線性規模計算內核?在我看來,這應該是MPS已有的東西.. –