From 0124b9a342c43e81e5f1d45d31e9265ba4a04e3e Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 29 May 2025 11:24:21 +1000 Subject: [PATCH] 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 Part-of: (cherry picked from commit 06e8db646ac04d4c82959bdf0fdd8ee2fb9c18fa) --- .pick_status.json | 2 +- src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 0f2305a69be..e0c3a51cf59 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -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 diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c index 0c567966a0b..f09db273ede 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state_validate.c @@ -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;