From 7908cb895e2dea8cff91cecb53457a099dc96b07 Mon Sep 17 00:00:00 2001 From: Glenn Kennard Date: Fri, 30 Jul 2021 18:44:54 +0200 Subject: [PATCH] nv30: Fix non-scissored clears after a scissor has been set Additionally add support for PIPE_CAP_CLEAR_SCISSORED since we are already touching the scissor state. Fixes various gnome-shell rendering artifacts. v2: Remove NEW_SCISSOR as clear now updates scissor registers explicitly v3: Reset scissor_off state since its not off now after clear Cc: mesa-stable Reviewed-by: Ilia Mirkin Reviewed-by: Karol Herbst Part-of: --- src/gallium/drivers/nouveau/nv30/nv30_clear.c | 24 ++++++++++++++++++- .../drivers/nouveau/nv30/nv30_screen.c | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/nouveau/nv30/nv30_clear.c b/src/gallium/drivers/nouveau/nv30/nv30_clear.c index b307b679564..1d5727a413d 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_clear.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_clear.c @@ -58,9 +58,25 @@ nv30_clear(struct pipe_context *pipe, unsigned buffers, const struct pipe_scisso struct pipe_framebuffer_state *fb = &nv30->framebuffer; uint32_t colr = 0, zeta = 0, mode = 0; - if (!nv30_state_validate(nv30, NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR, true)) + if (!nv30_state_validate(nv30, NV30_NEW_FRAMEBUFFER, true)) return; + if (scissor_state) { + uint32_t minx = scissor_state->minx; + uint32_t maxx = MIN2(fb->width, scissor_state->maxx); + uint32_t miny = scissor_state->miny; + uint32_t maxy = MIN2(fb->height, scissor_state->maxy); + + BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2); + PUSH_DATA (push, minx | (maxx - minx) << 16); + PUSH_DATA (push, miny | (maxy - miny) << 16); + } + else { + BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2); + PUSH_DATA (push, 0x10000000); + PUSH_DATA (push, 0x10000000); + } + if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) { colr = pack_rgba(fb->cbufs[0]->format, color->f); mode |= NV30_3D_CLEAR_BUFFERS_COLOR_R | @@ -96,6 +112,10 @@ nv30_clear(struct pipe_context *pipe, unsigned buffers, const struct pipe_scisso PUSH_DATA (push, mode); nv30_state_release(nv30); + + /* Make sure regular draw commands will get their scissor state set */ + nv30->dirty |= NV30_NEW_SCISSOR; + nv30->state.scissor_off = 0; } static void @@ -156,6 +176,7 @@ nv30_clear_render_target(struct pipe_context *pipe, struct pipe_surface *ps, NV30_3D_CLEAR_BUFFERS_COLOR_A); nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR; + nv30->state.scissor_off = 0; } static void @@ -222,6 +243,7 @@ nv30_clear_depth_stencil(struct pipe_context *pipe, struct pipe_surface *ps, PUSH_DATA (push, mode); nv30->dirty |= NV30_NEW_FRAMEBUFFER | NV30_NEW_SCISSOR; + nv30->state.scissor_off = 0; } void diff --git a/src/gallium/drivers/nouveau/nv30/nv30_screen.c b/src/gallium/drivers/nouveau/nv30/nv30_screen.c index 914d62ea0b9..687c7c49ba1 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_screen.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_screen.c @@ -96,6 +96,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_FS_COORD_PIXEL_CENTER_INTEGER: case PIPE_CAP_TGSI_TEXCOORD: case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: + case PIPE_CAP_CLEAR_SCISSORED: case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: