nouveau: workaround linear/z rendering interaction

nvidia hardware can't render to linear surfaces except under some
very limited circumstances, one of those is if Z is enabled.

However there appears to be some combination of gnome-shell, and
prime (with 2 nouveau cards) where we end up getting through the
GL API to the situation where we try this. This in a production
build causes the kernel to crash with a GR error.

However there existed a period of time where the hw/kernel due to
some other random hw misconfiguration didn't crash when this happened
and doing this was prefect fine. (linear + tiled Z).

This restores the userspace code to do this and just ignores the
Z buffers if we are asked for linear rendering, and seems sufficient
to fix the problem.

I do understand this is a workaround, but I think it's reasonable to
add to the nouveau GL driver at this time since we don't want to
maintain if for ever and it probably should fix a bunch of wierd
user problems with multi gpu and nouveau.

Cc: mesa-stable
Reviewed-by: Karol Herbst <kherbst@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35221>
(cherry picked from commit 06e8db646a)
This commit is contained in:
Dave Airlie 2025-05-29 11:24:21 +10:00 committed by Eric Engestrom
parent 78dbc63715
commit 0124b9a342
2 changed files with 4 additions and 3 deletions

View file

@ -1574,7 +1574,7 @@
"description": "nouveau: workaround linear/z rendering interaction",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null,
"notes": null

View file

@ -149,6 +149,7 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
unsigned ms_mode = NVC0_3D_MULTISAMPLE_MODE_MS1;
unsigned nr_cbufs = fb->nr_cbufs;
bool serialize = false;
bool cbuf_is_linear = false;
nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_FB);
@ -204,7 +205,7 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
nvc0_resource_fence(nvc0, res, NOUVEAU_BO_WR);
assert(!fb->zsbuf);
cbuf_is_linear = true;
}
if (res->status & NOUVEAU_BUFFER_STATUS_GPU_READING)
@ -216,7 +217,7 @@ nvc0_validate_fb(struct nvc0_context *nvc0)
BCTX_REFN(nvc0->bufctx_3d, 3D_FB, res, WR);
}
if (fb->zsbuf) {
if (fb->zsbuf && !cbuf_is_linear) {
struct nv50_miptree *mt = nv50_miptree(fb->zsbuf->texture);
struct nv50_surface *sf = nv50_surface(fb->zsbuf);
int unk = mt->base.base.target == PIPE_TEXTURE_2D;