Skip to content

metal: match pipeline attachment formats to the view#635

Open
benface wants to merge 1 commit into
not-fl3:masterfrom
benface:metal-pipeline-attachments
Open

metal: match pipeline attachment formats to the view#635
benface wants to merge 1 commit into
not-fl3:masterfrom
benface:metal-pipeline-attachments

Conversation

@benface

@benface benface commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Problem

The Metal backend unconditionally configures every render pipeline state for two color attachments (for i in 0..2) plus depth + stencil at Depth32Float_Stencil8. MTKView by default exposes only color attachment 0 and depthStencilPixelFormat = MTLPixelFormatInvalid. With Metal validation on, the first draw asserts:

-[MTLDebugRenderCommandEncoder setRenderPipelineState:]:1654: failed assertion `Set Render Pipeline State Validation
For color attachment 1, the renderPipelineState pixelFormat must be MTLPixelFormatInvalid, as no texture is set.
For depth attachment, the renderPipelineState pixelFormat must be MTLPixelFormatInvalid, as no texture is set.
For stencil attachment, the renderPipelineState pixelFormat must be MTLPixelFormatInvalid, as no texture is set.

Hit this trying to switch a 2D macroquad app to the Metal backend on an iPhone 17 simulator (iOS 27 beta).

Fix

Two changes in graphics/metal.rs::new_pipeline:

  1. Loop only over color attachment 0 (for i in 0..1) — miniquad's Metal backend doesn't expose multiple render targets, so attachment 1 should remain Invalid.
  2. Read the view's depthStencilPixelFormat and pass it through to the pipeline's depth + stencil attachment formats — MTLPixelFormatInvalid when MTKView has no depth/stencil, which is the default.

After this, the pipeline state's attachment formats match whatever the encoder actually has bound, and Metal validation accepts every draw.

Tested on

iPhone 17 simulator on iOS 27 beta — Metal validation crash gone, app launches and renders into the simulator.

The Metal backend unconditionally configured every render pipeline
state for two color attachments (`for i in 0..2`) plus depth and
stencil at `Depth32Float_Stencil8`, while MTKView by default exposes
only color attachment 0 and `depthStencilPixelFormat = Invalid`. Metal
validation fires on the first draw:

    failed assertion `Set Render Pipeline State Validation
    For color attachment 1, the renderPipelineState pixelFormat must
    be MTLPixelFormatInvalid, as no texture is set.
    For depth attachment, the renderPipelineState pixelFormat must be
    MTLPixelFormatInvalid, as no texture is set.
    For stencil attachment, the renderPipelineState pixelFormat must
    be MTLPixelFormatInvalid, as no texture is set.

Configure only color attachment 0 and read the view's
`depthStencilPixelFormat` for the pipeline's depth + stencil formats.
Pipelines now match whatever the encoder actually has bound, so the
validation layer accepts the draw.
@benface benface force-pushed the metal-pipeline-attachments branch from 5615845 to 7ea7ce8 Compare June 13, 2026 15:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant