我试图通过这种方式获得MTLTexture
的像素:
let pixelCount = compareTexture.width * compareTexture.height
let region = MTLRegionMake2D(0, 0, compareTexture.width, compareTexture.height)
var textureComponentsArray = Array<float4>(repeating: float4(0), count: pixelCount)
textureComponentsArray.withUnsafeMutableBytes {
compareTexture.getBytes($0.baseAddress!, bytesPerRow: (MemoryLayout<float4>.size * compareTexture.width), from: region, mipmapLevel: 0)
}
print(textureComponentsArray.first!)
不幸的是,大多数元素都是NaN或等于我初始化textureComponentsArray的值。例如,此代码打印:
float4(nan, nan, nan, nan)
我在macOS上,我的MTLTexture有这些属性:
let textureDescriptor = MTLTextureDescriptor()
textureDescriptor.width = imageTexture.width
textureDescriptor.height = imageTexture.height
textureDescriptor.pixelFormat = imageTexture.pixelFormat
textureDescriptor.resourceOptions = .storageModeManaged
textureDescriptor.storageMode = .managed
textureDescriptor.usage = [.renderTarget, .shaderRead, .shaderWrite]
我确实使用托管存储模式,因此数据应该可供CPU使用,我不明白为什么它不起作用。
谢谢。
编辑:
我正在尝试使用:
blitCommandEncoder.synchronize(resource: compareTexture)
我确实等待命令缓冲区完成但仍有问题。
答案 0 :(得分:0)
我需要针对iOS的此问题的答案。我要把为我的需要编写的扩展名留在这里。
import Metal
extension MTLTexture {
func getPixels<T> (_ region: MTLRegion? = nil, mipmapLevel: Int = 0) -> UnsafeMutablePointer<T> {
let fromRegion = region ?? MTLRegionMake2D(0, 0, self.width, self.height)
let width = fromRegion.size.width
let height = fromRegion.size.height
let bytesPerRow = MemoryLayout<T>.stride * width
let data = UnsafeMutablePointer<T>.allocate(capacity: bytesPerRow * height)
self.getBytes(data, bytesPerRow: bytesPerRow, from: fromRegion, mipmapLevel: mipmapLevel)
return data
}
}
您可以简单地调用该函数。但是请记住,您有责任重新分配用于数据对象的内存。
如果像素也采用不同的格式,则可以读取它们。对于MTLPixelFormat.rgba32Float
纹理,我将数据检索为:
let pixels: UnsafeMutablePointer<Float32> = texture.getPixels()
defer {
pixels.deallocate()
}
let capacity = texture.width * texture.height * MemoryLayout<Float32>.stride
for i in stride(from: 0, to: capacity, by: 4) {
let l = pixels[i + 0]
let a = pixels[i + 1]
let b = pixels[i + 2]
let alpha = pixels[i + 3]
}