You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 22:07:28