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

如何将MTKView自动创建的深度纹理存储模式改为.memoryless?

如何修改MTKView自动创建的深度纹理存储模式为.memoryless?

Metal分析器给出如下提示:

"Texture:0x12880c010 "MTKView Depth"" has storage mode 'Private' but was a transient render target accessed exclusively by the GPU

Consider changing the storage mode to 'Memoryless'.

当设置depthStencilPixelFormat为有效值时,MTKView会自动创建深度纹理,我们可通过depthStencilAttachmentTextureUsage控制纹理使用方式,但MTKView并未提供直接修改该纹理存储模式的API。尽管文档说明MTKView会自动配置正确的存储模式:

...the view automatically creates those textures for you
and configures them as part of any render passes that the view creates.

但在渲染管线不读取深度纹理的场景下,MTKView不会自动切换到Memoryless模式,此时需要通过自定义深度纹理来解决:

解决方案步骤

  • 禁用MTKView自动创建深度纹理:将depthStencilPixelFormat设为.invalid
  • 手动创建Memoryless模式的深度纹理,匹配原有的像素格式、视图尺寸和使用方式
  • 在渲染流程中手动关联自定义深度纹理到渲染命令编码器

代码示例

  1. 声明自定义深度纹理属性:
private var customDepthTexture: MTLTexture?
  1. 实现纹理创建/更新逻辑(可在视图初始化、尺寸变化时调用):
func updateCustomDepthTexture(for view: MTKView) {
    guard let device = view.device, view.drawableSize.width > 0, view.drawableSize.height > 0 else {
        customDepthTexture = nil
        return
    }
    
    // 替换为你原本设置的深度模板像素格式
    let depthPixelFormat: MTLPixelFormat = .depth32Float
    let descriptor = MTLTextureDescriptor.texture2DDescriptor(
        pixelFormat: depthPixelFormat,
        width: Int(view.drawableSize.width),
        height: Int(view.drawableSize.height),
        mipmapped: false
    )
    
    descriptor.storageMode = .memoryless
    // 匹配你原本设置的depthStencilAttachmentTextureUsage
    descriptor.usage = .renderTarget
    
    customDepthTexture = device.makeTexture(descriptor: descriptor)
}
  1. 在draw(in:)方法中关联自定义纹理:
func draw(in view: MTKView) {
    guard let commandBuffer = commandQueue.makeCommandBuffer(),
          let renderPassDescriptor = view.currentRenderPassDescriptor,
          let depthTexture = customDepthTexture,
          let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else {
        return
    }
    
    // 替换自动创建的深度附件为自定义纹理
    renderEncoder.setDepthStencilTexture(depthTexture)
    
    // 执行你的渲染逻辑
    // ...
    
    renderEncoder.endEncoding()
    
    if let drawable = view.currentDrawable {
        commandBuffer.present(drawable)
    }
    commandBuffer.commit()
}
  1. 监听视图尺寸变化,更新纹理:
func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
    updateCustomDepthTexture(for: view)
}

注意事项

  • 确保自定义纹理的像素格式、尺寸与MTKView保持一致,避免渲染异常
  • 根据实际业务需求调整纹理的usage参数,确保和原depthStencilAttachmentTextureUsage匹配

内容的提问来源于stack exchange,提问作者Roman Gaditskii

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 07:52:54