nvc0: allow to resize the code segment dynamically
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Wed, 31 Aug 2016 20:52:46 +0000 (22:52 +0200)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Thu, 1 Sep 2016 19:25:35 +0000 (21:25 +0200)
When an application uses a ton of shaders, we need to evict them
when the code segment is full but this is not really a good solution
if monster shaders are used because code eviction will happen a lot.

To avoid this, it seems better to dynamically resize the code
segment area after each eviction. The maximum size is arbitrary
fixed to 8MB which should be enough.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/nvc0/nvc0_program.c

index 66640eacbe8eb5f4914dcdfdddcc7711f621ac5b..9f29b2983cc4359fbdeec835a9fb0012c021691c 100644 (file)
@@ -788,12 +788,35 @@ nvc0_program_upload(struct nvc0_context *nvc0, struct nvc0_program *prog)
       }
       debug_printf("WARNING: out of code space, evicting all shaders.\n");
 
+      /* Make sure to synchronize before deleting the code segment. */
+      IMMED_NVC0(nvc0->base.pushbuf, NVC0_3D(SERIALIZE), 0);
+
+      if ((screen->text->size << 1) <= (1 << 23)) {
+         ret = nvc0_screen_resize_text_area(screen, screen->text->size << 1);
+         if (ret) {
+            NOUVEAU_ERR("Error allocating TEXT area: %d\n", ret);
+            return false;
+         }
+         nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_3D_TEXT);
+         BCTX_REFN_bo(nvc0->bufctx_3d, 3D_TEXT,
+                      NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD,
+                      screen->text);
+         if (screen->compute) {
+            nouveau_bufctx_reset(nvc0->bufctx_cp, NVC0_BIND_CP_TEXT);
+            BCTX_REFN_bo(nvc0->bufctx_cp, CP_TEXT,
+                         NV_VRAM_DOMAIN(&screen->base) | NOUVEAU_BO_RD,
+                         screen->text);
+         }
+
+         /* Re-upload the builtin function into the new code segment. */
+         nvc0_program_library_upload(nvc0);
+      }
+
       ret = nvc0_program_alloc_code(nvc0, prog);
       if (ret) {
          NOUVEAU_ERR("shader too large (0x%x) to fit in code space ?\n", size);
          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++) {