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 <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9348>
This commit is contained in:
Mike Blumenkrantz 2020-10-01 16:29:09 -04:00 committed by Marge Bot
parent 8c908ee6a4
commit 40be7f6353
2 changed files with 32 additions and 15 deletions

View file

@ -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

View file

@ -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 {