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: 2eb45daa9c ("gallium: de-pointerize pipe_surface")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/15303
(cherry picked from commit 416da54cce)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41269>
This commit is contained in:
Pavel Ondračka 2026-04-22 10:02:07 +02:00 committed by Eric Engestrom
parent 2aa4169765
commit d87649d8be
3 changed files with 10 additions and 7 deletions

View file

@ -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

View file

@ -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;

View file

@ -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) {