ios - 在 Apple Metal 上的 MPSImageLanczosScale 之后应用着色器的问题
问题描述
在应用MPSImageLanczosScale后在 MTLTexture 上应用着色器时,我得到了奇怪的结果。
即使变换为 scale = 1 和 translationX = 0 和 translationY = 0。
如果我不应用 MPSImageLanczosScale,它运行良好。您可以在下面看到不应用 MPSImageLanczosScale 和应用 MPSImageLanczosScale 的结果。
我的渲染方法如下所示:
func filter(pixelBuffer: CVPixelBuffer) -> CVPixelBuffer? {
guard let commandQueue = commandQueue, var commandBuffer = commandQueue.makeCommandBuffer() else {
print("Failed to create Metal command queue")
CVMetalTextureCacheFlush(textureCache!, 0)
return nil
}
var newPixelBuffer: CVPixelBuffer?
CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, outputPixelBufferPool!, &newPixelBuffer)
guard var outputPixelBuffer = newPixelBuffer else {
print("Allocation failure: Could not get pixel buffer from pool (\(self.description))")
return nil
}
guard let inputTexture = makeTextureFromCVPixelBuffer(pixelBuffer: pixelBuffer, textureFormat: .bgra8Unorm) else {
return nil
}
guard var intermediateTexture = makeTextureFromCVPixelBuffer(pixelBuffer: outputPixelBuffer, textureFormat: .bgra8Unorm) else {
return nil
}
let imageLanczosScale = MPSImageLanczosScale(device: metalDevice)
let transform = MPSScaleTransform(scaleX: Double(scale), scaleY: Double(scale), translateX: Double(translationX), translateY: Double(translationY))
withUnsafePointer(to: &transform) { (transformPtr: UnsafePointer<MPSScaleTransform>) -> () in
imageLanczosScale.scaleTransform = transformPtr
}
imageLanczosScale.encode(commandBuffer: commandBuffer, sourceTexture: inputTexture, destinationTexture: outputTexture)
guard let commandEncoder = commandBuffer.makeComputeCommandEncoder(),
let outputTexture = makeTextureFromCVPixelBuffer(pixelBuffer: outputPixelBuffer, textureFormat: .bgra8Unorm) else { return nil }
commandEncoder.label = "Shader"
commandEncoder.setComputePipelineState(shaderPipline)
commandEncoder.setTexture(intermediateTexture, index: 1)
commandEncoder.setTexture(outputTexture, index: 0)
let w = shaderPipline.threadExecutionWidth
let h = shaderPipline.maxTotalThreadsPerThreadgroup / w
let threadsPerThreadgroup = MTLSizeMake(w, h, 1)
let threadgroupsPerGrid = MTLSize(width: (intermediateTexture.width + w - 1) / w, height: (intermediateTexture.height + h - 1) / h, depth: 1)
commandEncoder.dispatchThreadgroups(threadgroupsPerGrid, threadsPerThreadgroup: threadsPerThreadgroup)
commandEncoder.endEncoding()
commandBuffer.commit()
return outputPixelBuffer
}
不知道我做错了什么。有任何想法吗?
解决方案
推荐阅读
- java - 如何计算给定 String[][] 和 String[][] 预期返回的平均成绩
- java - 如何使用圆点幻灯片注册活动
- python-3.x - wxPython 需要什么才能成功运行?
- python - 如何读取文件并将内容存储到二维矩阵中?
- javascript - XPath:选择包含规范化文本的节点,不包括祖先节点
- joomla - 将 Joomla 网站转移到另一台服务器
- php - 如何访问 laravel 集合中的属性
- c++ - std::stringbuf in_avail() 函数输出奇怪的数字,它比缓冲区大小小很多,即使没有对缓冲区进行读取
- python-3.x - 如何获得输出纯 HTML 的请求?
- docker - 如何由该容器的非 root 用户通过 SSH 连接到 docker 容器?