首页 > 解决方案 > 使用多重采样进行离屏渲染

问题描述

我正在绘制一个四边形并为其添加纹理并绘制小四边形并添加纹理。当样本数为 4 时,添加小四边形时出现以下错误。当样本数为 1 时,它工作正常。

Execution of the command buffer was aborted due to an error during execution. Ignored (for causing prior/excessive GPU errors) (IOAF code 4)

我如何使用样本计数 4

guard let drawable = view.currentDrawable else { return }

let textureDescriptor = MTLTextureDescriptor()

textureDescriptor.textureType = MTLTextureType.type2DMultisample
textureDescriptor.width = drawable.texture.width
textureDescriptor.height = drawable.texture.height
textureDescriptor.pixelFormat = .bgra8Unorm
textureDescriptor.storageMode = .shared
 textureDescriptor.sampleCount = 4

textureDescriptor.usage = [.renderTarget, .shaderRead]
let sampleTexture = device.makeTexture(descriptor: textureDescriptor)


let renderPass = MTLRenderPassDescriptor()
renderPass.colorAttachments[0].texture = sampleTexture
renderPass.colorAttachments[0].resolveTexture = outTexture
renderPass.colorAttachments[0].loadAction = .clear
renderPass.colorAttachments[0].clearColor =
    MTLClearColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
 renderPass.colorAttachments[0].storeAction = .multisampleResolve

let commandBuffer = commandQueue.makeCommandBuffer()

let semaphore = inFlightSemaphore

commandBuffer?.addCompletedHandler { (_ commandBuffer)-> Swift.Void in
        semaphore.signal()
}

var commandEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: renderPass)

for scene in scenes {
    scene.render(commandEncoder: commandEncoder!)
}

commandEncoder?.endEncoding()


let descriptor = view.currentRenderPassDescriptor
commandEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: descriptor!)



for x in canvasScenes{
    x.updateCanvas(texture: sampleTexture!)
    x.render(commandEncoder: commandEncoder!)
}

commandEncoder?.endEncoding()


commandBuffer?.present(drawable)
commandBuffer?.commit()
commandBuffer?.waitUntilCompleted()

标签: iosswiftmetalmetalkit

解决方案


这是我使用多重采样进行离屏渲染的设置。我也使用深度纹理。这是关于多重采样的书面小描述https://developer.apple.com/documentation/metal/mtlrenderpassattachmentdescriptor?language=objc

    let offscreenTextureDescriptor = MTLTextureDescriptor()
    offscreenTextureDescriptor.width = size.width
    offscreenTextureDescriptor.height = size.height
    offscreenTextureDescriptor.depth = size.depth
    offscreenTextureDescriptor.pixelFormat = RenderPixelFormat.offscreen.rawValue.mtlPixelFormat()
    offscreenTextureDescriptor.textureType = .type2DMultisample
    offscreenTextureDescriptor.storageMode = .shared
    offscreenTextureDescriptor.usage = [.renderTarget, .shaderRead, .shaderWrite, .pixelFormatView]
    offscreenTextureDescriptor.sampleCount = 4

    self.offScreenTexture = device.makeTexture(descriptor: offscreenTextureDescriptor)

    offscreenTextureDescriptor.textureType = .type2D
    offscreenTextureDescriptor.sampleCount = 1
    offscreenTextureDescriptor.usage = [.shaderWrite]

    self.resolveOffScreenTexture = device.makeTexture(descriptor: offscreenTextureDescriptor)

    let depthTextureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .depth32Float, width: self.offScreenTexture.width, height: self.offScreenTexture.height, mipmapped: false)
    depthTextureDescriptor.usage = [.renderTarget, .shaderRead, .shaderWrite, .pixelFormatView]
    depthTextureDescriptor.textureType = .type2DMultisample
    depthTextureDescriptor.storageMode = .private
    depthTextureDescriptor.resourceOptions = [.storageModePrivate]
    depthTextureDescriptor.sampleCount = 4

    let depthAttachementTexureDescriptor = MTLRenderPassDepthAttachmentDescriptor()
    depthAttachementTexureDescriptor.clearDepth = 1.0
    depthAttachementTexureDescriptor.loadAction = .clear
    depthAttachementTexureDescriptor.storeAction = .store
    depthAttachementTexureDescriptor.texture = device.makeTexture(descriptor: depthTextureDescriptor)

    let renderPassDescriptor = MTLRenderPassDescriptor()
    renderPassDescriptor.colorAttachments[0].texture = self.offScreenTexture
    renderPassDescriptor.colorAttachments[0].resolveTexture = self.resolveOffScreenTexture
    renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 1)
    renderPassDescriptor.colorAttachments[0].loadAction = .clear
    renderPassDescriptor.colorAttachments[0].storeAction = .multisampleResolve
    renderPassDescriptor.depthAttachment = depthAttachementTexureDescriptor
    self.renderPassDescriptor = renderPassDescriptor

推荐阅读