From 7f63d2ebdbc4c29a58c768787e0551e8a6bd411b Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Tue, 15 Aug 2023 17:12:01 +0200 Subject: [PATCH] nv50: fix code uploads bigger than 0x10000 bytes The hardware has a max limit on how much data we can upload in one go via the 2D engine. Just split the uploads up. Cc: mesa-stable Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9571 Acked-by: M Henning Signed-off-by: Karol Herbst Part-of: --- .../drivers/nouveau/nv50/nv50_transfer.c | 75 +++++++++++-------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c index 4c73695a28d..5a9a5bacaae 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_transfer.c @@ -279,47 +279,56 @@ nv50_sifc_linear_u8(struct nouveau_context *nv, struct nv50_context *nv50 = nv50_context(&nv->pipe); struct nouveau_pushbuf *push = nv50->base.pushbuf; uint32_t *src = (uint32_t *)data; - unsigned count = (size + 3) / 4; - unsigned xcoord = offset & 0xff; + unsigned count = DIV_ROUND_UP(size, 4); + unsigned max_size = 0x10000; nouveau_bufctx_refn(nv50->bufctx, 0, dst, domain | NOUVEAU_BO_WR); nouveau_pushbuf_bufctx(push, nv50->bufctx); + PUSH_VAL(push); - offset &= ~0xff; - - BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2); - PUSH_DATA (push, G80_SURFACE_FORMAT_R8_UNORM); - PUSH_DATA (push, 1); - BEGIN_NV04(push, NV50_2D(DST_PITCH), 5); - PUSH_DATA (push, 262144); - PUSH_DATA (push, 65536); - PUSH_DATA (push, 1); - PUSH_DATAh(push, dst->offset + offset); - PUSH_DATA (push, dst->offset + offset); - BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2); - PUSH_DATA (push, 0); - PUSH_DATA (push, G80_SURFACE_FORMAT_R8_UNORM); - BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10); - PUSH_DATA (push, size); - PUSH_DATA (push, 1); - PUSH_DATA (push, 0); - PUSH_DATA (push, 1); - PUSH_DATA (push, 0); - PUSH_DATA (push, 1); - PUSH_DATA (push, 0); - PUSH_DATA (push, xcoord); - PUSH_DATA (push, 0); - PUSH_DATA (push, 0); - while (count) { - unsigned nr = MIN2(count, NV04_PFIFO_MAX_PACKET_LEN); + unsigned xcoord = offset & 0xff; + offset &= ~0xff; - BEGIN_NI04(push, NV50_2D(SIFC_DATA), nr); - PUSH_DATAp(push, src, nr); + BEGIN_NV04(push, NV50_2D(DST_FORMAT), 2); + PUSH_DATA (push, G80_SURFACE_FORMAT_R8_UNORM); + PUSH_DATA (push, 1); + BEGIN_NV04(push, NV50_2D(DST_PITCH), 5); + PUSH_DATA (push, 262144); + PUSH_DATA (push, 65536); + PUSH_DATA (push, 1); + PUSH_DATAh(push, dst->offset + offset); + PUSH_DATA (push, dst->offset + offset); + BEGIN_NV04(push, NV50_2D(SIFC_BITMAP_ENABLE), 2); + PUSH_DATA (push, 0); + PUSH_DATA (push, G80_SURFACE_FORMAT_R8_UNORM); + BEGIN_NV04(push, NV50_2D(SIFC_WIDTH), 10); + PUSH_DATA (push, MIN2(size, max_size)); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, 1); + PUSH_DATA (push, 0); + PUSH_DATA (push, xcoord); + PUSH_DATA (push, 0); + PUSH_DATA (push, 0); - src += nr; - count -= nr; + unsigned iter_count = MIN2(count, max_size / 4); + count -= iter_count; + offset += max_size; + size -= max_size; + + while (iter_count) { + unsigned nr = MIN2(iter_count, NV04_PFIFO_MAX_PACKET_LEN); + + BEGIN_NI04(push, NV50_2D(SIFC_DATA), nr); + PUSH_DATAp(push, src, nr); + + src += nr; + iter_count -= nr; + } } nouveau_bufctx_reset(nv50->bufctx, 0);