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 {