zink: use a list for free batch states
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Fri, 5 Aug 2022 20:12:19 +0000 (16:12 -0400)
committerMarge Bot <emma+marge@anholt.net>
Sat, 20 Aug 2022 01:27:13 +0000 (01:27 +0000)
this ensures "fairer" reuse and avoids having any states sitting idle
for too long with resources attached

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18135>

src/gallium/drivers/zink/zink_batch.c
src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_types.h

index f9df891..ede5c23 100644 (file)
@@ -144,7 +144,11 @@ zink_batch_reset_all(struct zink_context *ctx)
       bs->fence.completed = true;
       pop_batch_state(ctx);
       zink_reset_batch_state(ctx, bs);
-      util_dynarray_append(&ctx->free_batch_states, struct zink_batch_state *, bs);
+      if (ctx->last_free_batch_state)
+         ctx->last_free_batch_state->next = bs;
+      else
+         ctx->free_batch_states = bs;
+      ctx->last_free_batch_state = bs;
    }
 }
 
@@ -268,8 +272,12 @@ get_batch_state(struct zink_context *ctx, struct zink_batch *batch)
    struct zink_screen *screen = zink_screen(ctx->base.screen);
    struct zink_batch_state *bs = NULL;
 
-   if (util_dynarray_num_elements(&ctx->free_batch_states, struct zink_batch_state*))
-      bs = util_dynarray_pop(&ctx->free_batch_states, struct zink_batch_state*);
+   if (ctx->free_batch_states) {
+      bs = ctx->free_batch_states;
+      ctx->free_batch_states = bs->next;
+      if (bs == ctx->last_free_batch_state)
+         ctx->last_free_batch_state = NULL;
+   }
    if (!bs && ctx->batch_states) {
       /* states are stored sequentially, so if the first one doesn't work, none of them will */
       if (zink_screen_check_last_finished(screen, ctx->batch_states->fence.batch_id) ||
@@ -285,7 +293,11 @@ get_batch_state(struct zink_context *ctx, struct zink_batch *batch)
          /* this is batch init, so create a few more states for later use */
          for (int i = 0; i < 3; i++) {
             struct zink_batch_state *state = create_batch_state(ctx);
-            util_dynarray_append(&ctx->free_batch_states, struct zink_batch_state *, state);
+            if (ctx->last_free_batch_state)
+               ctx->last_free_batch_state->next = state;
+            else
+               ctx->free_batch_states = state;
+            ctx->last_free_batch_state = state;
          }
       }
       bs = create_batch_state(ctx);
@@ -467,7 +479,11 @@ zink_end_batch(struct zink_context *ctx, struct zink_batch *batch)
 
          pop_batch_state(ctx);
          zink_reset_batch_state(ctx, bs);
-         util_dynarray_append(&ctx->free_batch_states, struct zink_batch_state *, bs);
+         if (ctx->last_free_batch_state)
+            ctx->last_free_batch_state->next = bs;
+         else
+            ctx->free_batch_states = bs;
+         ctx->last_free_batch_state = bs;
       }
       if (ctx->batch_states_count > 50)
          ctx->oom_flush = true;
index 97e74a7..520ddb4 100644 (file)
@@ -135,9 +135,12 @@ zink_context_destroy(struct pipe_context *pctx)
       zink_batch_state_destroy(screen, bs);
       bs = bs_next;
    }
-   util_dynarray_foreach(&ctx->free_batch_states, struct zink_batch_state*, bs) {
-      zink_clear_batch_state(ctx, *bs);
-      zink_batch_state_destroy(screen, *bs);
+   bs = ctx->free_batch_states;
+   while (bs) {
+      struct zink_batch_state *bs_next = bs->next;
+      zink_clear_batch_state(ctx, bs);
+      zink_batch_state_destroy(screen, bs);
+      bs = bs_next;
    }
 
    for (unsigned i = 0; i < 2; i++) {
@@ -4512,8 +4515,6 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    ctx->need_barriers[0] = &ctx->update_barriers[0][0];
    ctx->need_barriers[1] = &ctx->update_barriers[1][0];
 
-   util_dynarray_init(&ctx->free_batch_states, ctx);
-
    slab_create_child(&ctx->transfer_pool, &screen->transfer_pool);
    slab_create_child(&ctx->transfer_pool_unsync, &screen->transfer_pool);
 
index a5d37ed..d138dab 100644 (file)
@@ -1333,7 +1333,8 @@ struct zink_context {
    struct zink_fence *last_fence; //the last command buffer submitted
    struct zink_batch_state *batch_states; //list of submitted batch states: ordered by increasing timeline id
    unsigned batch_states_count; //number of states in `batch_states`
-   struct util_dynarray free_batch_states; //unused batch states
+   struct zink_batch_state *free_batch_states; //unused batch states
+   struct zink_batch_state *last_free_batch_state; //for appending
    bool oom_flush;
    bool oom_stall;
    struct zink_batch batch;