From 40be7f6353cfd786939f49514d7c2e6c3f38f92e Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 1 Oct 2020 16:29:09 -0400 Subject: [PATCH] zink: store last-used descriptor set for each type of set for quick reuse we can avoid some hash lookups this way, and we can also avoid putting the null descriptor sets back into the array since we know they'll always be the last-used set this also helps our null set reuse be more explicit since we never have to put these sets back into an array or anything Reviewed-by: Bas Nieuwenhuizen Part-of: --- src/gallium/drivers/zink/zink_program.c | 45 +++++++++++++++++-------- src/gallium/drivers/zink/zink_program.h | 2 +- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 0d1cf322281..4c21f35d69f 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -924,6 +924,17 @@ zink_program_allocate_desc_set(struct zink_context *ctx, uint32_t hash = pg->num_descriptors[type] ? ctx->descriptor_states[is_compute].state[type] : 0; struct zink_descriptor_state_key key; populate_zds_key(ctx, type, is_compute, &key); + if (pg->last_set[type] && pg->last_set[type]->hash == hash && + desc_state_equal(&pg->last_set[type]->key, &key)) { + zds = pg->last_set[type]; + *cache_hit = true; + if (pg->num_descriptors[type]) { + struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pg->free_desc_sets[type], hash, &key); + if (he) + _mesa_hash_table_remove(pg->free_desc_sets[type], he); + } + goto out; + } if (pg->num_descriptors[type]) { struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pg->desc_sets[type], hash, &key); @@ -978,8 +989,8 @@ zink_program_allocate_desc_set(struct zink_context *ctx, return zink_program_allocate_desc_set(ctx, batch, pg, type, is_compute, cache_hit); } } else { - zds = pg->null_set; - if (zds) { + if (pg->last_set[type] && !pg->last_set[type]->hash) { + zds = pg->last_set[type]; *cache_hit = true; goto quick_out; } @@ -991,13 +1002,18 @@ out: populate_zds_key(ctx, type, is_compute, &zds->key); if (pg->num_descriptors[type]) _mesa_hash_table_insert_pre_hashed(pg->desc_sets[type], hash, &zds->key, zds); - else - pg->null_set = zds; + else { + /* we can safely apply the null set to all the slots which will need it here */ + for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) { + if (!pg->num_descriptors[i]) + pg->last_set[i] = zds; + } + } quick_out: zds->invalid = false; if (zink_batch_add_desc_set(batch, pg, zds)) batch->descs_used += pg->num_descriptors[type]; - + pg->last_set[type] = zds; return zds; } @@ -1008,16 +1024,17 @@ zink_program_recycle_desc_set(struct zink_program *pg, struct zink_descriptor_se uint32_t refcount = p_atomic_read(&zds->reference.count); if (refcount != 1) return; - if (!zds->invalid) { - struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pg->desc_sets[zds->type], zds->hash, &zds->key); - if (!he) - /* desc sets can be used multiple times in the same batch */ - return; + /* this is a null set */ + if (!zds->hash && !pg->num_descriptors[zds->type]) + return; - _mesa_hash_table_remove(pg->desc_sets[zds->type], he); - _mesa_hash_table_insert_pre_hashed(pg->free_desc_sets[zds->type], zds->hash, &zds->key, zds); - } else - util_dynarray_append(&pg->alloc_desc_sets[zds->type], struct zink_descriptor_set *, zds); + struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pg->desc_sets[zds->type], zds->hash, &zds->key); + if (!he) + /* desc sets can be used multiple times in the same batch */ + return; + + _mesa_hash_table_remove(pg->desc_sets[zds->type], he); + _mesa_hash_table_insert_pre_hashed(pg->free_desc_sets[zds->type], zds->hash, &zds->key, zds); } static void diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h index 211702e8ee6..5f3acd11e60 100644 --- a/src/gallium/drivers/zink/zink_program.h +++ b/src/gallium/drivers/zink/zink_program.h @@ -88,7 +88,7 @@ struct zink_program { VkDescriptorPool descpool[ZINK_DESCRIPTOR_TYPES]; VkDescriptorSetLayout dsl[ZINK_DESCRIPTOR_TYPES]; unsigned num_descriptors[ZINK_DESCRIPTOR_TYPES]; - struct zink_descriptor_set *null_set; + struct zink_descriptor_set *last_set[ZINK_DESCRIPTOR_TYPES]; }; struct zink_gfx_program {