From: Samuel Pitoiset Date: Wed, 31 Aug 2016 20:52:43 +0000 (+0200) Subject: nvc0: re-upload currently bound shaders after code eviction X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3d928d9082cab625ea4189b2bba96648f712ef3d;p=mesa.git nvc0: re-upload currently bound shaders after code eviction This fixes a very old issue which happens when the code segment size is full. A bunch of real applications like Tomb Raider, F1 2015, Elemental, hit that issue because they use a ton of shaders. In this case, all shaders are evicted (for freeing space) but all currently bound shaders also need to be re-uploaded and SP_START_ID have to be updated accordingly. Signed-off-by: Samuel Pitoiset Reviewed-by: Ilia Mirkin --- diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c index 0e0d436a7cf..66640eacbe8 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_program.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_program.c @@ -774,6 +774,10 @@ nvc0_program_upload(struct nvc0_context *nvc0, struct nvc0_program *prog) ret = nvc0_program_alloc_code(nvc0, prog); if (ret) { struct nouveau_heap *heap = screen->text_heap; + struct nvc0_program *progs[] = { /* Sorted accordingly to SP_START_ID */ + nvc0->compprog, nvc0->vertprog, nvc0->tctlprog, + nvc0->tevlprog, nvc0->gmtyprog, nvc0->fragprog + }; /* Note that the code library, which is allocated before anything else, * does not have a priv pointer. We can stop once we hit it. @@ -790,6 +794,29 @@ nvc0_program_upload(struct nvc0_context *nvc0, struct nvc0_program *prog) return false; } IMMED_NVC0(nvc0->base.pushbuf, NVC0_3D(SERIALIZE), 0); + + /* All currently bound shaders have to be reuploaded. */ + for (int i = 0; i < ARRAY_SIZE(progs); i++) { + if (!progs[i] || progs[i] == prog) + continue; + + ret = nvc0_program_alloc_code(nvc0, progs[i]); + if (ret) { + NOUVEAU_ERR("failed to re-upload a shader after code eviction.\n"); + return false; + } + nvc0_program_upload_code(nvc0, progs[i]); + + if (progs[i]->type == PIPE_SHADER_COMPUTE) { + /* Caches have to be invalidated but the CP_START_ID will be + * updated in the launch_grid functions. */ + BEGIN_NVC0(nvc0->base.pushbuf, NVC0_CP(FLUSH), 1); + PUSH_DATA (nvc0->base.pushbuf, NVC0_COMPUTE_FLUSH_CODE); + } else { + BEGIN_NVC0(nvc0->base.pushbuf, NVC0_3D(SP_START_ID(i)), 1); + PUSH_DATA (nvc0->base.pushbuf, progs[i]->code_base); + } + } } nvc0_program_upload_code(nvc0, prog);