Ruban4Axis
Ruban4Axis

Reputation: 841

Off screen Rendering With Multisampling

I am drawing a quad and adding texture to it and drawing small quad and adding textures. When the sample count is 4 I got following error when small quad is added. when the sample count is one is it is working fine.

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

How can i use sample count 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()

Upvotes: 3

Views: 2134

Answers (1)

Ivan Tkachenko
Ivan Tkachenko

Reputation: 506

That's my setup for offscreen rendering with multisampling. I use also depth texture. Here is written small description about multisampling 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

Upvotes: 4

Related Questions