Mesa (main): zink: improve lazy descriptor pool handling

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jul 22 01:42:17 UTC 2021


Module: Mesa
Branch: main
Commit: 8db2d53418c3c0eb627763e5ce756ca83c79efa7
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8db2d53418c3c0eb627763e5ce756ca83c79efa7

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Fri May 21 17:17:09 2021 -0400

zink: improve lazy descriptor pool handling

do set allocation when getting pool, queue filled pools for delete

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11690>

---

 src/gallium/drivers/zink/zink_descriptors_lazy.c | 122 +++++++++++++++++------
 1 file changed, 90 insertions(+), 32 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_descriptors_lazy.c b/src/gallium/drivers/zink/zink_descriptors_lazy.c
index 1caeadab462..00d0429cc80 100644
--- a/src/gallium/drivers/zink/zink_descriptors_lazy.c
+++ b/src/gallium/drivers/zink/zink_descriptors_lazy.c
@@ -50,6 +50,7 @@ struct zink_descriptor_pool {
 
 struct zink_batch_descriptor_data_lazy {
    struct zink_batch_descriptor_data base;
+   struct util_dynarray overflowed_pools;
    struct hash_table pools[ZINK_DESCRIPTOR_TYPES];
    struct zink_descriptor_pool *push_pool[2];
    struct zink_program *pg[2]; //gfx, compute
@@ -304,13 +305,78 @@ create_pool(struct zink_screen *screen, unsigned num_type_sizes, VkDescriptorPoo
 }
 
 static struct zink_descriptor_pool *
-get_descriptor_pool_lazy(struct zink_context *ctx, struct zink_program *pg, enum zink_descriptor_type type, struct zink_batch_state *bs)
+get_descriptor_pool_lazy(struct zink_context *ctx, struct zink_program *pg, enum zink_descriptor_type type, struct zink_batch_state *bs, bool is_compute);
+
+static struct zink_descriptor_pool *
+check_pool_alloc(struct zink_context *ctx, struct zink_descriptor_pool *pool, struct hash_entry *he, struct zink_program *pg,
+                 enum zink_descriptor_type type, struct zink_batch_state *bs, bool is_compute)
 {
    struct zink_screen *screen = zink_screen(ctx->base.screen);
-   struct hash_entry *he = _mesa_hash_table_search(&bdd_lazy(bs)->pools[type], pg->dd->layout_key[type]);
-   if (he)
-      return he->data;
+   /* allocate up to $current * 10, e.g., 10 -> 100 or 100 -> 1000 */
+   if (pool->set_idx == pool->sets_alloc) {
+      unsigned sets_to_alloc = MIN2(MAX2(pool->sets_alloc * 10, 10), ZINK_DEFAULT_MAX_DESCS) - pool->sets_alloc;
+      if (!sets_to_alloc) {
+         /* overflowed pool: queue for deletion on next reset */
+         util_dynarray_append(&bdd_lazy(bs)->overflowed_pools, struct zink_descriptor_pool*, pool);
+         _mesa_hash_table_remove(&bdd_lazy(bs)->pools[type], he);
+         ctx->oom_flush = true;
+         return get_descriptor_pool_lazy(ctx, pg, type, bs, is_compute);
+      }
+      if (!zink_descriptor_util_alloc_sets(screen, pg->dsl[type + 1],
+                                           pool->pool, &pool->sets[pool->sets_alloc], sets_to_alloc))
+         return NULL;
+      pool->sets_alloc += sets_to_alloc;
+   }
+   return pool;
+}
+
+static struct zink_descriptor_pool *
+create_push_pool(struct zink_screen *screen, struct zink_batch_state *bs, bool is_compute)
+{
    struct zink_descriptor_pool *pool = rzalloc(bs, struct zink_descriptor_pool);
+   VkDescriptorPoolSize sizes;
+   sizes.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+   if (is_compute)
+      sizes.descriptorCount = ZINK_DEFAULT_MAX_DESCS;
+   else
+      sizes.descriptorCount = ZINK_SHADER_COUNT * ZINK_DEFAULT_MAX_DESCS;
+   pool->pool = create_pool(screen, 1, &sizes, 0);
+   return pool;
+}
+
+static struct zink_descriptor_pool *
+check_push_pool_alloc(struct zink_context *ctx, struct zink_descriptor_pool *pool, struct zink_batch_state *bs, bool is_compute)
+{
+   struct zink_screen *screen = zink_screen(ctx->base.screen);
+   /* allocate up to $current * 10, e.g., 10 -> 100 or 100 -> 1000 */
+   if (pool->set_idx == pool->sets_alloc) {
+      unsigned sets_to_alloc = MIN2(MAX2(pool->sets_alloc * 10, 10), ZINK_DEFAULT_MAX_DESCS) - pool->sets_alloc;
+      if (!sets_to_alloc) {
+         /* overflowed pool: queue for deletion on next reset */
+         util_dynarray_append(&bdd_lazy(bs)->overflowed_pools, struct zink_descriptor_pool*, pool);
+         bdd_lazy(bs)->push_pool[is_compute] = create_push_pool(screen, bs, is_compute);
+         ctx->oom_flush = true;
+         return check_push_pool_alloc(ctx, bdd_lazy(bs)->push_pool[is_compute], bs, is_compute);
+      }
+      if (!zink_descriptor_util_alloc_sets(screen, ctx->dd->push_dsl[is_compute]->layout,
+                                           pool->pool, &pool->sets[pool->sets_alloc], sets_to_alloc))
+         return NULL;
+      pool->sets_alloc += sets_to_alloc;
+   }
+   return pool;
+}
+
+static struct zink_descriptor_pool *
+get_descriptor_pool_lazy(struct zink_context *ctx, struct zink_program *pg, enum zink_descriptor_type type, struct zink_batch_state *bs, bool is_compute)
+{
+   struct zink_screen *screen = zink_screen(ctx->base.screen);
+   struct hash_entry *he = _mesa_hash_table_search(&bdd_lazy(bs)->pools[type], pg->dd->layout_key[type]);
+   struct zink_descriptor_pool *pool;
+   if (he) {
+      pool = he->data;
+      return check_pool_alloc(ctx, pool, he, pg, type, bs, is_compute);
+   }
+   pool = rzalloc(bs, struct zink_descriptor_pool);
    if (!pool)
       return NULL;
    unsigned idx = zink_descriptor_type_to_size_idx(type);
@@ -324,29 +390,16 @@ get_descriptor_pool_lazy(struct zink_context *ctx, struct zink_program *pg, enum
       return NULL;
    }
    _mesa_hash_table_insert(&bdd_lazy(bs)->pools[type], pg->dd->layout_key[type], pool);
-   return pool;
+   return check_pool_alloc(ctx, pool, he, pg, type, bs, is_compute);
 }
 
-static VkDescriptorSet
+ALWAYS_INLINE static VkDescriptorSet
 get_descriptor_set_lazy(struct zink_context *ctx, struct zink_program *pg, enum zink_descriptor_type type, struct zink_descriptor_pool *pool, bool is_compute)
 {
-   struct zink_screen *screen = zink_screen(ctx->base.screen);
    if (!pool)
       return VK_NULL_HANDLE;
 
-   if (pool->set_idx < pool->sets_alloc)
-      return pool->sets[pool->set_idx++];
-
-   /* allocate up to $current * 10, e.g., 10 -> 100 or 100 -> 1000 */
-   unsigned sets_to_alloc = MIN2(MAX2(pool->sets_alloc * 10, 10), ZINK_DEFAULT_MAX_DESCS) - pool->sets_alloc;
-   if (!sets_to_alloc) {//pool full
-      zink_fence_wait(&ctx->base);
-      return get_descriptor_set_lazy(ctx, pg, type, pool, is_compute);
-   }
-   if (!zink_descriptor_util_alloc_sets(screen, pg ? pg->dsl[type + 1] : ctx->dd->push_dsl[is_compute]->layout,
-                                        pool->pool, &pool->sets[pool->sets_alloc], sets_to_alloc))
-      return VK_NULL_HANDLE;
-   pool->sets_alloc += sets_to_alloc;
+   assert(pool->set_idx < pool->sets_alloc);
    return pool->sets[pool->set_idx++];
 }
 
@@ -355,7 +408,7 @@ populate_sets(struct zink_context *ctx, struct zink_program *pg, uint8_t *change
 {
    struct zink_batch_state *bs = ctx->batch.state;
    if (need_push && !zink_screen(ctx->base.screen)->info.have_KHR_push_descriptor) {
-         struct zink_descriptor_pool *pool = bdd_lazy(bs)->push_pool[pg->is_compute];
+         struct zink_descriptor_pool *pool = check_push_pool_alloc(ctx, bdd_lazy(bs)->push_pool[pg->is_compute], bs, pg->is_compute);
          sets[0] = get_descriptor_set_lazy(ctx, NULL, 0, pool, pg->is_compute);
          if (!sets[0])
             return false;
@@ -367,7 +420,7 @@ populate_sets(struct zink_context *ctx, struct zink_program *pg, uint8_t *change
    bs = ctx->batch.state;
    u_foreach_bit(type, *changed_sets) {
       if (pg->dd->layout_key[type]) {
-         struct zink_descriptor_pool *pool = get_descriptor_pool_lazy(ctx, pg, type, bs);
+         struct zink_descriptor_pool *pool = get_descriptor_pool_lazy(ctx, pg, type, bs, pg->is_compute);
          sets[type + 1] = get_descriptor_set_lazy(ctx, pg, type, pool, pg->is_compute);
          if (ctx->batch.state != bs && (sets[0] || type != ffs(*changed_sets))) {
                /* sets are allocated by batch state, so if flush occurs on anything
@@ -513,6 +566,13 @@ zink_batch_descriptor_deinit_lazy(struct zink_screen *screen, struct zink_batch_
    ralloc_free(bs->dd);
 }
 
+static void
+pool_destroy(struct zink_screen *screen, struct zink_descriptor_pool *pool)
+{
+   vkDestroyDescriptorPool(screen->dev, pool->pool, NULL);
+   ralloc_free(pool);
+}
+
 void
 zink_batch_descriptor_reset_lazy(struct zink_screen *screen, struct zink_batch_state *bs)
 {
@@ -525,8 +585,7 @@ zink_batch_descriptor_reset_lazy(struct zink_screen *screen, struct zink_batch_s
          if (key->use_count)
             pool->set_idx = 0;
          else {
-            vkDestroyDescriptorPool(screen->dev, pool->pool, NULL);
-            ralloc_free(pool);
+            pool_destroy(screen, pool);
             _mesa_hash_table_remove(&bdd_lazy(bs)->pools[i], entry);
          }
       }
@@ -536,6 +595,10 @@ zink_batch_descriptor_reset_lazy(struct zink_screen *screen, struct zink_batch_s
       if (bdd_lazy(bs)->push_pool[i])
          bdd_lazy(bs)->push_pool[i]->set_idx = 0;
    }
+   while (util_dynarray_num_elements(&bdd_lazy(bs)->overflowed_pools, struct zink_descriptor_pool*)) {
+      struct zink_descriptor_pool *pool = util_dynarray_pop(&bdd_lazy(bs)->overflowed_pools, struct zink_descriptor_pool*);
+      pool_destroy(screen, pool);
+   }
 }
 
 bool
@@ -550,15 +613,10 @@ zink_batch_descriptor_init_lazy(struct zink_screen *screen, struct zink_batch_st
       if (!_mesa_hash_table_init(&bdd_lazy(bs)->pools[i], bs->dd, _mesa_hash_pointer, _mesa_key_pointer_equal))
          return false;
    }
+   util_dynarray_init(&bdd_lazy(bs)->overflowed_pools, bs->dd);
    if (!screen->info.have_KHR_push_descriptor) {
-      VkDescriptorPoolSize sizes;
-      sizes.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
-      sizes.descriptorCount = ZINK_SHADER_COUNT * ZINK_DEFAULT_MAX_DESCS;
-      bdd_lazy(bs)->push_pool[0] = rzalloc(bs, struct zink_descriptor_pool);
-      bdd_lazy(bs)->push_pool[0]->pool = create_pool(screen, 1, &sizes, 0);
-      sizes.descriptorCount  = ZINK_DEFAULT_MAX_DESCS;
-      bdd_lazy(bs)->push_pool[1] = rzalloc(bs, struct zink_descriptor_pool);
-      bdd_lazy(bs)->push_pool[1]->pool = create_pool(screen, 1, &sizes, 0);
+      bdd_lazy(bs)->push_pool[0] = create_push_pool(screen, bs, false);
+      bdd_lazy(bs)->push_pool[1] = create_push_pool(screen, bs, true);
    }
    return true;
 }



More information about the mesa-commit mailing list