Metal API报错:GetBytes Validation rowBytes(1600)需≥(4680)求助
解决MTLTexture转CVPixelBuffer时rowBytes验证失败的问题
问题原因
错误rowBytes(1600) must be >= (4680)的核心原因:
- 传入的
bytesPerRow远小于纹理实际需要的行字节数 - 纹理获取逻辑错误,拿到的不是已渲染完成的目标纹理
修复方案
1. 修正纹理获取逻辑
在commandBuffer.addCompletedHandler中,直接取当前drawable的纹理,而非调用nextDrawable():
commandBuffer.addCompletedHandler { [weak self] _ in guard let self = self, let texture = drawable.texture else { return } self.recorder.writeFrame(forTexture: texture) }
避免强制解包
texture!,防止空值引发崩溃。
2. 对齐bytesPerRow参数
在writeFrame方法里,直接使用MTLTexture自带的bytesPerRow,不要手动计算或硬编码:
func writeFrame(forTexture texture: MTLTexture) { // ... 初始化pixelBuffer等逻辑 ... let bytesPerRow = texture.bytesPerRow texture.getBytes(pixelBufferBytes, bytesPerRow: bytesPerRow, from: region, mipmapLevel: 0) // ... 后续写入逻辑 ... }
如果是手动创建CVPixelBuffer,需保证其行字节数与纹理一致:
let bufferAttributes = [ kCVPixelBufferWidthKey: texture.width, kCVPixelBufferHeightKey: texture.height, kCVPixelBufferBytesPerRowAlignmentKey: texture.bytesPerRow, kCVPixelBufferPixelFormatTypeKey: kCVPixelFormatType_32BGRA ] as CFDictionary var pixelBuffer: CVPixelBuffer? CVPixelBufferCreate(kCFAllocatorDefault, texture.width, texture.height, kCVPixelFormatType_32BGRA, bufferAttributes, &pixelBuffer)
3. 确保纹理具备读取权限
虽然你已经设置framebufferOnly = false,需额外确认纹理的usage包含读取权限:
// 针对MTKView的设置 metalView.framebufferOnly = false // 若为自定义纹理,创建时指定usage let textureDesc = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .bgra8Unorm, width: width, height: height, mipmapped: false) textureDesc.usage = [.renderTarget, .shaderRead, .blitSource]
关于已尝试方案的说明
- 禁用Metal API Validation只是屏蔽了错误提示,并未解决根本问题;CoreTelephony相关错误与当前问题无关,可忽略。
framebufferOnly = false是必要条件,但需配合正确的纹理获取和参数对齐才能生效。
内容的提问来源于stack exchange,提问作者user10309700
相关产品推荐
相关产品推荐

