MPSImageHistogramEqualization 抛出偏移量必须小于 [缓冲区长度] 的断言
MPSImageHistogramEqualization throws assertion that offset must be < [buffer length]
我正在尝试在 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
中专门路径中的错误,我鼓励您 file feedback 解决它。
当numberOfHistogramEntries
大于256时,图像内核分配一个足够大的内部缓冲区来保存它需要处理的数据(对于N=512,这是8192字节),再加上一个额外的位space(32 字节)。设置内部 optimized256BinsUseCase
标志时,它会分配恰好 4096 字节,省略最后一位额外存储空间。我怀疑后续操作依赖于在初始数据块之后有更多 space,并且无意中将缓冲区偏移量设置为超过内部缓冲区的长度。
您可以通过使用不同数量的直方图 bin(例如 512)来解决此问题。这会浪费一点 space 和时间,但我认为它会产生相同的结果。
或者,您可以通过禁用 Metal 验证层来避免此崩溃,但我强烈反对这样做,因为您只会掩盖潜在的问题,直到它得到修复。
注意:我在 macOS Catalina 上对 MetalPerformanceShaders 框架进行了逆向工程。不同的平台和不同的软件版本可能有不同的代码路径。
我正在尝试在 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
中专门路径中的错误,我鼓励您 file feedback 解决它。
当numberOfHistogramEntries
大于256时,图像内核分配一个足够大的内部缓冲区来保存它需要处理的数据(对于N=512,这是8192字节),再加上一个额外的位space(32 字节)。设置内部 optimized256BinsUseCase
标志时,它会分配恰好 4096 字节,省略最后一位额外存储空间。我怀疑后续操作依赖于在初始数据块之后有更多 space,并且无意中将缓冲区偏移量设置为超过内部缓冲区的长度。
您可以通过使用不同数量的直方图 bin(例如 512)来解决此问题。这会浪费一点 space 和时间,但我认为它会产生相同的结果。
或者,您可以通过禁用 Metal 验证层来避免此崩溃,但我强烈反对这样做,因为您只会掩盖潜在的问题,直到它得到修复。
注意:我在 macOS Catalina 上对 MetalPerformanceShaders 框架进行了逆向工程。不同的平台和不同的软件版本可能有不同的代码路径。