MPSImage直方图均衡抛出偏移量必须< [缓冲区长度] 的断言



我正在尝试在iOS上使用MPSImageHistogramEqualization进行直方图均衡,但它最终抛出了一个我不明白的断言。这是我的代码:

// Calculate Histogram
var histogramInfo = MPSImageHistogramInfo(
numberOfHistogramEntries: 256,
histogramForAlpha: false,
minPixelValue: vector_float4(0,0,0,0),
maxPixelValue: vector_float4(1,1,1,1))
let calculation = MPSImageHistogram(device: self.mtlDevice, histogramInfo: &histogramInfo)
let bufferLength = calculation.histogramSize(forSourceFormat: sourceTexture.pixelFormat)
let histogramInfoBuffer = self.mtlDevice.makeBuffer(length: bufferLength, options: [.storageModePrivate])!
calculation.encode(to: commandBuffer,
sourceTexture: sourceTexture,
histogram: histogramInfoBuffer,
histogramOffset: 0)
let histogramEqualization = MPSImageHistogramEqualization(device: self.mtlDevice, histogramInfo: &histogramInfo)
histogramEqualization.encodeTransform(to: commandBuffer, sourceTexture: sourceTexture, histogram: histogramInfoBuffer, histogramOffset: 0)

这是在最后一行发生的断言:

-[MTLDebugComputeCommandEncoder setBuffer:offset:atIndex:]:283: failed assertion `offset(4096) must be < [buffer length](4096).'

关于这里可能发生的事情的任何建议?

这似乎是MPSImageHistogramEqualization中专用路径中的一个错误,我鼓励您提交反馈。

numberOfHistogramEntries大于 256 时,映像内核会分配一个足够大的内部缓冲区来容纳它需要处理的数据(对于 N=512,这是 8192 字节(,再加上一个额外的空间位(32 字节(。设置内部optimized256BinsUseCase标志时,它会精确分配 4096 字节,省略最后一点的额外存储空间。我怀疑后续操作依赖于在初始数据块之后有更多的空间,并且无意中将缓冲区偏移量设置为超过内部缓冲区的长度。

您可以通过使用不同数量的直方图箱(如 512(来解决此问题。这浪费了一点空间和时间,但我认为它会产生相同的结果。

或者,您可以通过禁用 Metal 验证层来避免此崩溃,但我强烈建议不要这样做,因为您只会掩盖潜在问题,直到它得到修复。

注意:我在macOS Catalina上对MetalPerformanceShaders框架进行了逆向工程。不同的平台和不同的软件版本可能具有不同的代码路径。

最新更新