如何将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模式的深度纹理,匹配原有的像素格式、视图尺寸和使用方式
- 在渲染流程中手动关联自定义深度纹理到渲染命令编码器
代码示例
- 声明自定义深度纹理属性:
private var customDepthTexture: MTLTexture?
- 实现纹理创建/更新逻辑(可在视图初始化、尺寸变化时调用):
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) }
- 在
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() }
- 监听视图尺寸变化,更新纹理:
func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) { updateCustomDepthTexture(for: view) }
注意事项
- 确保自定义纹理的像素格式、尺寸与MTKView保持一致,避免渲染异常
- 根据实际业务需求调整纹理的
usage参数,确保和原depthStencilAttachmentTextureUsage匹配
内容的提问来源于stack exchange,提问作者Roman Gaditskii
相关产品推荐
相关产品推荐

