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 <samuel.pitoiset@gmail.com> Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user