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