From d87649d8be754dc45bfa505c3c89adb96bc793b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Ondra=C4=8Dka?= Date: Wed, 22 Apr 2026 10:02:07 +0200 Subject: [PATCH] r300: fix MSAA resolve COLORPITCH tiling after pipe_surface de-pointerization r300_simple_msaa_resolve used to patch srcsurf->pitch with the resolve destination's tiling bits before passing the surface to the blitter. That worked when set_framebuffer_state kept the same pipe_surface pointer, so r300_get_nonnull_cb returned the patched object. After the de-pointerization, r300_framebuffer_init creates a fresh r300_surface from the pipe_surface template, discarding the pitch modification. The hardware then uses the MSAA source tiling for R300_RB3D_COLORPITCH0, leading to corruption. Move the tiling override into r300_emit_fb_state and override the tiling bits of COLORPITCH from the destination surface at emit time. Fixes: 2eb45daa9c86 ("gallium: de-pointerize pipe_surface") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/15303 (cherry picked from commit 416da54cce8782227d44d6dffbb0f99860f9725f) Part-of: --- .pick_status.json | 2 +- src/gallium/drivers/r300/r300_blit.c | 5 ----- src/gallium/drivers/r300/r300_emit.c | 10 +++++++++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 1bebb7da3b1..e02a6a74726 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1204,7 +1204,7 @@ "description": "r300: fix MSAA resolve COLORPITCH tiling after pipe_surface de-pointerization", "nominated": true, "nomination_type": 2, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "2eb45daa9c86f4b8bd602ddef7a67233f56f1edf", "notes": null diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index c6bc653ec4c..50e97e2d68e 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -755,11 +755,6 @@ static void r300_simple_msaa_resolve(struct pipe_context *pipe, surf_tmpl.last_layer = dst_layer; dstsurf = r300_surface(pipe->create_surface(pipe, dst, &surf_tmpl)); - /* COLORPITCH should contain the tiling info of the resolve buffer. - * The tiling of the AA buffer isn't programmable anyway. */ - srcsurf->pitch &= ~(R300_COLOR_TILE(1) | R300_COLOR_MICROTILE(3)); - srcsurf->pitch |= dstsurf->pitch & (R300_COLOR_TILE(1) | R300_COLOR_MICROTILE(3)); - /* Enable AA resolve. */ aa->dest = dstsurf; r300->aa_state.size = 8; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 2e0f633b77a..c4cd25982b5 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -392,6 +392,7 @@ void r300_emit_aa_state(struct r300_context *r300, unsigned size, void *state) void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) { struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; + struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state; struct r300_surface* surf; unsigned i; uint32_t rb3d_cctl = 0; @@ -421,7 +422,14 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG(R300_RB3D_COLOROFFSET0 + (4 * i), surf->offset); OUT_CS_RELOC(surf); - OUT_CS_REG(R300_RB3D_COLORPITCH0 + (4 * i), surf->pitch); + /* COLORPITCH should contain the tiling info of the resolve buffer. + * The tiling of the AA buffer isn't programmable anyway. */ + uint32_t pitch = surf->pitch; + if (aa->dest) { + pitch &= ~(R300_COLOR_TILE(1) | R300_COLOR_MICROTILE(3)); + pitch |= aa->dest->pitch & (R300_COLOR_TILE(1) | R300_COLOR_MICROTILE(3)); + } + OUT_CS_REG(R300_RB3D_COLORPITCH0 + (4 * i), pitch); OUT_CS_RELOC(surf); if (r300->cmask_in_use && i == 0) {