Skip to content

Commit c5b346e

Browse files
benfacenot-fl3
authored andcommitted
metal: match pipeline attachment formats to the view
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 (the backend has no MRT path) and mirror the view's `depthStencilPixelFormat` onto the pipeline's depth + stencil formats — but only when the view actually has one. When MTKView reports `Invalid`, skip the `set*AttachmentPixelFormat:` calls so the descriptor keeps its `Invalid` defaults instead of having that sentinel passed in explicitly. Adds `MTLPixelFormat::Invalid = 0` to the binding (Apple's `MTLPixelFormatInvalid`).
1 parent df7d8ed commit c5b346e

2 files changed

Lines changed: 22 additions & 9 deletions

File tree

src/graphics/metal.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -988,8 +988,11 @@ impl RenderingBackend for MetalContext {
988988
msg_send_![descriptor, setVertexFunction:shader_internal.vertex_function];
989989
msg_send_![descriptor, setFragmentFunction:shader_internal.fragment_function];
990990
msg_send_![descriptor, setVertexDescriptor: vertex_descriptor];
991+
// Only attachment 0 — the backend has no MRT path and
992+
// setting attachment 1 to a non-Invalid pixelFormat
993+
// fails Metal validation when no texture is bound.
991994
let color_attachments = msg_send_![descriptor, colorAttachments];
992-
for i in 0..2 {
995+
for i in 0..1usize {
993996
let color_attachment = msg_send_![color_attachments, objectAtIndexedSubscript: i];
994997
let view_pixel_format: MTLPixelFormat = msg_send![self.view, colorPixelFormat];
995998
msg_send_![color_attachment, setPixelFormat: view_pixel_format];
@@ -1036,14 +1039,23 @@ impl RenderingBackend for MetalContext {
10361039
];
10371040
}
10381041
}
1039-
msg_send_![
1040-
descriptor,
1041-
setDepthAttachmentPixelFormat: MTLPixelFormat::Depth32Float_Stencil8
1042-
];
1043-
msg_send_![
1044-
descriptor,
1045-
setStencilAttachmentPixelFormat: MTLPixelFormat::Depth32Float_Stencil8
1046-
];
1042+
// Pipeline depth/stencil formats must match whatever
1043+
// render pass uses this pipeline. MTKView reports
1044+
// `Invalid` when no depth/stencil is configured —
1045+
// leave the descriptor's defaults (also `Invalid`)
1046+
// alone in that case; otherwise mirror the view.
1047+
let view_depth_stencil_format: MTLPixelFormat =
1048+
msg_send![self.view, depthStencilPixelFormat];
1049+
if view_depth_stencil_format != MTLPixelFormat::Invalid {
1050+
msg_send_![
1051+
descriptor,
1052+
setDepthAttachmentPixelFormat: view_depth_stencil_format
1053+
];
1054+
msg_send_![
1055+
descriptor,
1056+
setStencilAttachmentPixelFormat: view_depth_stencil_format
1057+
];
1058+
}
10471059

10481060
let mut error: ObjcId = nil;
10491061
let pipeline_state: ObjcId = msg_send![

src/native/apple/frameworks.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ impl MTLClearColor {
632632
#[allow(non_camel_case_types)]
633633
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
634634
pub enum MTLPixelFormat {
635+
Invalid = 0,
635636
BGRA8Unorm = 80,
636637
Depth32Float = 252,
637638
Stencil8 = 253,

0 commit comments

Comments
 (0)