diff --git a/src/gallium/drivers/zink/zink_descriptors.c b/src/gallium/drivers/zink/zink_descriptors.c index 32c9ad0d7ce..cae636e3a17 100644 --- a/src/gallium/drivers/zink/zink_descriptors.c +++ b/src/gallium/drivers/zink/zink_descriptors.c @@ -33,6 +33,83 @@ #include "zink_resource.h" #include "zink_screen.h" + +static bool +desc_state_equal(const void *a, const void *b) +{ + const struct zink_descriptor_state_key *a_k = (void*)a; + const struct zink_descriptor_state_key *b_k = (void*)b; + + for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) { + if (a_k->exists[i] != b_k->exists[i]) + return false; + if (a_k->exists[i] && b_k->exists[i] && + a_k->state[i] != b_k->state[i]) + return false; + } + return true; +} + +static uint32_t +desc_state_hash(const void *key) +{ + const struct zink_descriptor_state_key *d_key = (void*)key; + uint32_t hash = 0; + /* this is a compute shader */ + if (!d_key->exists[PIPE_SHADER_FRAGMENT]) + return d_key->state[0]; + for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) { + if (d_key->exists[i]) + hash = XXH32(&d_key->state[i], sizeof(uint32_t), hash); + } + return hash; +} + +static struct zink_descriptor_pool * +descriptor_pool_create(struct zink_screen *screen, VkDescriptorSetLayoutBinding *bindings, unsigned num_bindings, VkDescriptorPoolSize *sizes, unsigned num_type_sizes) +{ + struct zink_descriptor_pool *pool = rzalloc(NULL, struct zink_descriptor_pool); + if (!pool) + return NULL; + pool->num_descriptors = num_bindings; + pool->desc_sets = _mesa_hash_table_create(NULL, desc_state_hash, desc_state_equal); + if (!pool->desc_sets) + goto fail; + + pool->free_desc_sets = _mesa_hash_table_create(NULL, desc_state_hash, desc_state_equal); + if (!pool->free_desc_sets) + goto fail; + + util_dynarray_init(&pool->alloc_desc_sets, NULL); + + VkDescriptorSetLayoutCreateInfo dcslci = {}; + dcslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; + dcslci.pNext = NULL; + dcslci.flags = 0; + dcslci.bindingCount = num_bindings; + dcslci.pBindings = bindings; + if (vkCreateDescriptorSetLayout(screen->dev, &dcslci, 0, &pool->dsl) != VK_SUCCESS) { + debug_printf("vkCreateDescriptorSetLayout failed\n"); + goto fail; + } + + VkDescriptorPoolCreateInfo dpci = {}; + dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + dpci.pPoolSizes = sizes; + dpci.poolSizeCount = num_type_sizes; + dpci.flags = 0; + dpci.maxSets = ZINK_DEFAULT_MAX_DESCS; + if (vkCreateDescriptorPool(screen->dev, &dpci, 0, &pool->descpool) != VK_SUCCESS) { + debug_printf("vkCreateDescriptorPool failed\n"); + goto fail; + } + + return pool; +fail: + zink_descriptor_pool_free(screen, pool); + return NULL; +} + static bool get_invalidated_desc_set(struct zink_descriptor_set *zds) { @@ -45,9 +122,10 @@ static struct zink_descriptor_set * allocate_desc_set(struct zink_screen *screen, struct zink_program *pg, enum zink_descriptor_type type, unsigned descs_used, bool is_compute) { VkDescriptorSetAllocateInfo dsai; + struct zink_descriptor_pool *pool = pg->pool[type]; #define DESC_BUCKET_FACTOR 10 - unsigned bucket_size = pg->num_descriptors[type] ? DESC_BUCKET_FACTOR : 1; - if (pg->num_descriptors[type]) { + unsigned bucket_size = pool->num_descriptors ? DESC_BUCKET_FACTOR : 1; + if (pool->num_descriptors) { for (unsigned desc_factor = DESC_BUCKET_FACTOR; desc_factor < descs_used; desc_factor *= DESC_BUCKET_FACTOR) bucket_size = desc_factor; } @@ -55,10 +133,10 @@ allocate_desc_set(struct zink_screen *screen, struct zink_program *pg, enum zink memset((void *)&dsai, 0, sizeof(dsai)); dsai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; dsai.pNext = NULL; - dsai.descriptorPool = pg->descpool[type]; + dsai.descriptorPool = pool->descpool; dsai.descriptorSetCount = bucket_size; for (unsigned i = 0; i < bucket_size; i ++) - layouts[i] = pg->dsl[type]; + layouts[i] = pool->dsl; dsai.pSetLayouts = layouts; VkDescriptorSet desc_set[bucket_size]; @@ -67,14 +145,14 @@ allocate_desc_set(struct zink_screen *screen, struct zink_program *pg, enum zink return VK_NULL_HANDLE; } - struct zink_descriptor_set *alloc = ralloc_array(pg, struct zink_descriptor_set, bucket_size); + struct zink_descriptor_set *alloc = ralloc_array(pool, struct zink_descriptor_set, bucket_size); assert(alloc); unsigned num_resources = zink_program_num_bindings_typed(pg, type, is_compute); - struct zink_resource **resources = rzalloc_array(pg, struct zink_resource*, num_resources * bucket_size); + struct zink_resource **resources = rzalloc_array(pool, struct zink_resource*, num_resources * bucket_size); assert(resources); void **samplers = NULL; if (type == ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW) { - samplers = rzalloc_array(pg, void*, num_resources * bucket_size); + samplers = rzalloc_array(pool, void*, num_resources * bucket_size); assert(samplers); } for (unsigned i = 0; i < bucket_size; i ++) { @@ -89,13 +167,13 @@ allocate_desc_set(struct zink_screen *screen, struct zink_program *pg, enum zink zds->num_resources = num_resources; #endif if (type == ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW) { - zds->sampler_views = (struct zink_sampler_view**)&resources[i * pg->num_descriptors[type]]; - zds->sampler_states = (struct zink_sampler_state**)&samplers[i * pg->num_descriptors[type]]; + zds->sampler_views = (struct zink_sampler_view**)&resources[i * pool->num_descriptors]; + zds->sampler_states = (struct zink_sampler_state**)&samplers[i * pool->num_descriptors]; } else - zds->resources = (struct zink_resource**)&resources[i * pg->num_descriptors[type]]; + zds->resources = (struct zink_resource**)&resources[i * pool->num_descriptors]; zds->desc_set = desc_set[i]; if (i > 0) - util_dynarray_append(&pg->alloc_desc_sets[type], struct zink_descriptor_set *, zds); + util_dynarray_append(&pool->alloc_desc_sets, struct zink_descriptor_set *, zds); } return alloc; } @@ -127,25 +205,26 @@ zink_descriptor_set_get(struct zink_context *ctx, *cache_hit = false; struct zink_descriptor_set *zds; struct zink_screen *screen = zink_screen(ctx->base.screen); + struct zink_descriptor_pool *pool = pg->pool[type]; unsigned descs_used = 1; assert(type < ZINK_DESCRIPTOR_TYPES); - uint32_t hash = pg->num_descriptors[type] ? ctx->descriptor_states[is_compute].state[type] : 0; + uint32_t hash = pool->num_descriptors ? 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 && - zink_desc_state_equal(&pg->last_set[type]->key, &key)) { + desc_state_equal(&pg->last_set[type]->key, &key)) { zds = pg->last_set[type]; *cache_hit = !zds->invalid; - if (pg->num_descriptors[type] && zds->recycled) { - struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pg->free_desc_sets[type], hash, &key); + if (pool->num_descriptors && zds->recycled) { + struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pool->free_desc_sets, hash, &key); if (he) - _mesa_hash_table_remove(pg->free_desc_sets[type], he); + _mesa_hash_table_remove(pool->free_desc_sets, he); } goto out; } - if (pg->num_descriptors[type]) { - struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pg->desc_sets[type], hash, &key); + if (pool->num_descriptors) { + struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pool->desc_sets, hash, &key); bool recycled = false; if (he) { zds = (void*)he->data; @@ -155,7 +234,7 @@ zink_descriptor_set_get(struct zink_context *ctx, assert(!zds->invalid); } if (!he) { - he = _mesa_hash_table_search_pre_hashed(pg->free_desc_sets[type], hash, &key); + he = _mesa_hash_table_search_pre_hashed(pool->free_desc_sets, hash, &key); recycled = true; } if (he) { @@ -163,35 +242,35 @@ zink_descriptor_set_get(struct zink_context *ctx, *cache_hit = !zds->invalid; if (recycled) { /* need to migrate this entry back to the in-use hash */ - _mesa_hash_table_remove(pg->free_desc_sets[type], he); + _mesa_hash_table_remove(pool->free_desc_sets, he); goto out; } goto quick_out; } - if (util_dynarray_num_elements(&pg->alloc_desc_sets[type], struct zink_descriptor_set *)) { + if (util_dynarray_num_elements(&pool->alloc_desc_sets, struct zink_descriptor_set *)) { /* grab one off the allocated array */ - zds = util_dynarray_pop(&pg->alloc_desc_sets[type], struct zink_descriptor_set *); + zds = util_dynarray_pop(&pool->alloc_desc_sets, struct zink_descriptor_set *); goto out; } - if (_mesa_hash_table_num_entries(pg->free_desc_sets[type])) { + if (_mesa_hash_table_num_entries(pool->free_desc_sets)) { /* try for an invalidated set first */ unsigned count = 0; - hash_table_foreach(pg->free_desc_sets[type], he) { + hash_table_foreach(pool->free_desc_sets, he) { struct zink_descriptor_set *tmp = he->data; if ((count++ >= 100 && tmp->reference.count == 1) || get_invalidated_desc_set(he->data)) { zds = tmp; assert(p_atomic_read(&zds->reference.count) == 1); zink_descriptor_set_invalidate(zds); - _mesa_hash_table_remove(pg->free_desc_sets[type], he); + _mesa_hash_table_remove(pool->free_desc_sets, he); goto out; } } } - descs_used = _mesa_hash_table_num_entries(pg->desc_sets[type]) + _mesa_hash_table_num_entries(pg->free_desc_sets[type]); - if (descs_used + pg->num_descriptors[type] > ZINK_DEFAULT_MAX_DESCS) { + descs_used = _mesa_hash_table_num_entries(pool->desc_sets) + _mesa_hash_table_num_entries(pool->free_desc_sets); + if (descs_used + pool->num_descriptors > ZINK_DEFAULT_MAX_DESCS) { batch = zink_flush_batch(ctx, batch); zink_batch_reference_program(batch, pg); return zink_descriptor_set_get(ctx, batch, pg, type, is_compute, cache_hit); @@ -209,19 +288,19 @@ out: zds->hash = hash; populate_zds_key(ctx, type, is_compute, &zds->key); zds->recycled = false; - if (pg->num_descriptors[type]) - _mesa_hash_table_insert_pre_hashed(pg->desc_sets[type], hash, &zds->key, zds); + if (pool->num_descriptors) + _mesa_hash_table_insert_pre_hashed(pool->desc_sets, hash, &zds->key, 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]) + if (pg->pool[i] && !pg->pool[i]->num_descriptors) pg->last_set[i] = zds; } } quick_out: zds->invalid = false; if (zink_batch_add_desc_set(batch, zds)) - batch->descs_used += pg->num_descriptors[type]; + batch->descs_used += pool->num_descriptors; pg->last_set[type] = zds; return zds; } @@ -230,28 +309,29 @@ void zink_descriptor_set_recycle(struct zink_descriptor_set *zds) { struct zink_program *pg = zds->pg; + struct zink_descriptor_pool *pool = pg->pool[zds->type]; /* if desc set is still in use by a batch, don't recache */ uint32_t refcount = p_atomic_read(&zds->reference.count); if (refcount != 1) return; /* this is a null set */ - if (!zds->hash && !pg->num_descriptors[zds->type]) + if (!pool->num_descriptors) return; - struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pg->desc_sets[zds->type], zds->hash, &zds->key); + struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pool->desc_sets, 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_remove(pool->desc_sets, he); if (zds->invalid) { if (pg->last_set[zds->type] == zds) pg->last_set[zds->type] = NULL; zink_descriptor_set_invalidate(zds); - util_dynarray_append(&pg->alloc_desc_sets[zds->type], struct zink_descriptor_set *, zds); + util_dynarray_append(&pool->alloc_desc_sets, struct zink_descriptor_set *, zds); } else { zds->recycled = true; - _mesa_hash_table_insert_pre_hashed(pg->free_desc_sets[zds->type], zds->hash, &zds->key, zds); + _mesa_hash_table_insert_pre_hashed(pool->free_desc_sets, zds->hash, &zds->key, zds); } } @@ -302,7 +382,7 @@ zink_descriptor_set_refs_clear(struct zink_descriptor_refs *refs, void *ptr) } bool -zink_descriptor_program_init(VkDevice dev, +zink_descriptor_program_init(struct zink_screen *screen, struct zink_shader *stages[ZINK_SHADER_COUNT], struct zink_program *pg) { @@ -340,7 +420,6 @@ zink_descriptor_program_init(VkDevice dev, unsigned total_descs = 0; for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) { - pg->num_descriptors[i] = num_bindings[i]; total_descs += num_bindings[i];; } if (!total_descs) @@ -349,55 +428,27 @@ zink_descriptor_program_init(VkDevice dev, for (int i = 0; i < num_types; i++) sizes[i].descriptorCount *= ZINK_DEFAULT_MAX_DESCS; - VkDescriptorSetLayout null_set = VK_NULL_HANDLE; - VkDescriptorPool null_pool = VK_NULL_HANDLE; bool found_descriptors = false; for (unsigned i = ZINK_DESCRIPTOR_TYPES - 1; i < ZINK_DESCRIPTOR_TYPES; i--) { - VkDescriptorSetLayoutCreateInfo dcslci = {}; - dcslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; - dcslci.pNext = NULL; - dcslci.flags = 0; - if (!num_bindings[i]) { if (!found_descriptors) continue; - if (!null_set) { - dcslci.bindingCount = 1; - VkDescriptorSetLayoutBinding null_binding; - null_binding.binding = 1; - null_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - null_binding.descriptorCount = 1; - null_binding.pImmutableSamplers = NULL; - null_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | - VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | - VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_COMPUTE_BIT; - dcslci.pBindings = &null_binding; - if (vkCreateDescriptorSetLayout(dev, &dcslci, 0, &null_set) != VK_SUCCESS) { - debug_printf("vkCreateDescriptorSetLayout failed\n"); - return false; - } - VkDescriptorPoolCreateInfo dpci = {}; - VkDescriptorPoolSize null_size = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, ZINK_DESCRIPTOR_TYPES}; - dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - dpci.pPoolSizes = &null_size; - dpci.poolSizeCount = 1; - dpci.flags = 0; - dpci.maxSets = 1; - if (vkCreateDescriptorPool(dev, &dpci, 0, &null_pool) != VK_SUCCESS) - return false; - } - pg->dsl[i] = null_set; - pg->descpool[i] = null_pool; + VkDescriptorSetLayoutBinding null_binding; + null_binding.binding = 1; + null_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + null_binding.descriptorCount = 1; + null_binding.pImmutableSamplers = NULL; + null_binding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | + VK_SHADER_STAGE_GEOMETRY_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | + VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_COMPUTE_BIT; + VkDescriptorPoolSize null_size = {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, ZINK_DESCRIPTOR_TYPES}; + pg->pool[i] = descriptor_pool_create(screen, &null_binding, 1, &null_size, 1); + if (!pg->pool[i]) + return false; continue; } - dcslci.bindingCount = num_bindings[i]; - dcslci.pBindings = bindings[i]; found_descriptors = true; - if (vkCreateDescriptorSetLayout(dev, &dcslci, 0, &pg->dsl[i]) != VK_SUCCESS) { - debug_printf("vkCreateDescriptorSetLayout failed\n"); - return false; - } VkDescriptorPoolSize type_sizes[2] = {}; int num_type_sizes = 0; switch (i) { @@ -438,15 +489,9 @@ zink_descriptor_program_init(VkDevice dev, } break; } - VkDescriptorPoolCreateInfo dpci = {}; - dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - dpci.pPoolSizes = type_sizes; - dpci.poolSizeCount = num_type_sizes; - dpci.flags = 0; - dpci.maxSets = ZINK_DEFAULT_MAX_DESCS; - if (vkCreateDescriptorPool(dev, &dpci, 0, &pg->descpool[i]) != VK_SUCCESS) { + pg->pool[i] = descriptor_pool_create(screen, bindings[i], num_bindings[i], type_sizes, num_type_sizes); + if (!pg->pool[i]) return false; - } } return true; } @@ -456,3 +501,40 @@ zink_descriptor_set_invalidate(struct zink_descriptor_set *zds) { zds->invalid = true; } + +#ifndef NDEBUG +static void +descriptor_pool_clear(struct hash_table *ht) +{ + hash_table_foreach(ht, entry) { + struct zink_descriptor_set *zds = entry->data; + zink_descriptor_set_invalidate(zds); + } + _mesa_hash_table_clear(ht, NULL); +} +#endif + +void +zink_descriptor_pool_free(struct zink_screen *screen, struct zink_descriptor_pool *pool) +{ + if (!pool) + return; + if (pool->dsl) + vkDestroyDescriptorSetLayout(screen->dev, pool->dsl, NULL); + if (pool->descpool) + vkDestroyDescriptorPool(screen->dev, pool->descpool, NULL); + +#ifndef NDEBUG + if (pool->desc_sets) + descriptor_pool_clear(pool->desc_sets); + if (pool->free_desc_sets) + descriptor_pool_clear(pool->free_desc_sets); +#endif + if (pool->desc_sets) + _mesa_hash_table_destroy(pool->desc_sets, NULL); + if (pool->free_desc_sets) + _mesa_hash_table_destroy(pool->free_desc_sets, NULL); + + util_dynarray_fini(&pool->alloc_desc_sets); + ralloc_free(pool); +} diff --git a/src/gallium/drivers/zink/zink_descriptors.h b/src/gallium/drivers/zink/zink_descriptors.h index 73856f00859..6bd700df26a 100644 --- a/src/gallium/drivers/zink/zink_descriptors.h +++ b/src/gallium/drivers/zink/zink_descriptors.h @@ -57,21 +57,14 @@ struct zink_descriptor_state_key { uint32_t state[ZINK_SHADER_COUNT]; }; -static inline bool -zink_desc_state_equal(const void *a, const void *b) -{ - const struct zink_descriptor_state_key *a_k = (void*)a; - const struct zink_descriptor_state_key *b_k = (void*)b; - - for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) { - if (a_k->exists[i] != b_k->exists[i]) - return false; - if (a_k->exists[i] && b_k->exists[i] && - a_k->state[i] != b_k->state[i]) - return false; - } - return true; -} +struct zink_descriptor_pool { + struct hash_table *desc_sets; + struct hash_table *free_desc_sets; + struct util_dynarray alloc_desc_sets; + VkDescriptorPool descpool; + VkDescriptorSetLayout dsl; + unsigned num_descriptors; +}; struct zink_descriptor_set { struct zink_program *pg; @@ -124,10 +117,14 @@ void zink_descriptor_set_recycle(struct zink_descriptor_set *zds); bool -zink_descriptor_program_init(VkDevice dev, +zink_descriptor_program_init(struct zink_screen *screen, struct zink_shader *stages[ZINK_SHADER_COUNT], struct zink_program *pg); void zink_descriptor_set_invalidate(struct zink_descriptor_set *zds); + +void +zink_descriptor_pool_free(struct zink_screen *screen, struct zink_descriptor_pool *pool); + #endif diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index 6dee1fd4cad..e8a0b889cb4 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -398,7 +398,7 @@ update_ubo_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zds { struct zink_program *pg = zds->pg; struct zink_screen *screen = zink_screen(ctx->base.screen); - unsigned num_descriptors = pg->num_descriptors[zds->type]; + unsigned num_descriptors = pg->pool[zds->type]->num_descriptors; unsigned num_bindings = zink_program_num_bindings_typed(pg, zds->type, is_compute); VkWriteDescriptorSet wds[num_descriptors]; struct zink_descriptor_resource resources[num_bindings]; @@ -480,7 +480,7 @@ update_ssbo_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zd { struct zink_program *pg = zds->pg; ASSERTED struct zink_screen *screen = zink_screen(ctx->base.screen); - unsigned num_descriptors = pg->num_descriptors[zds->type]; + unsigned num_descriptors = pg->pool[zds->type]->num_descriptors; unsigned num_bindings = zink_program_num_bindings_typed(pg, zds->type, is_compute); VkWriteDescriptorSet wds[num_descriptors]; struct zink_descriptor_resource resources[num_bindings]; @@ -584,7 +584,7 @@ update_sampler_descriptors(struct zink_context *ctx, struct zink_descriptor_set { struct zink_program *pg = zds->pg; struct zink_screen *screen = zink_screen(ctx->base.screen); - unsigned num_descriptors = pg->num_descriptors[zds->type]; + unsigned num_descriptors = pg->pool[zds->type]->num_descriptors; unsigned num_bindings = zink_program_num_bindings(pg, is_compute); VkWriteDescriptorSet wds[num_descriptors]; struct zink_descriptor_resource resources[num_bindings]; @@ -657,7 +657,7 @@ update_image_descriptors(struct zink_context *ctx, struct zink_descriptor_set *z { struct zink_program *pg = zds->pg; struct zink_screen *screen = zink_screen(ctx->base.screen); - unsigned num_descriptors = pg->num_descriptors[zds->type]; + unsigned num_descriptors = pg->pool[zds->type]->num_descriptors; unsigned num_bindings = zink_program_num_bindings(pg, is_compute); VkWriteDescriptorSet wds[num_descriptors]; struct zink_descriptor_resource resources[num_bindings]; @@ -742,7 +742,7 @@ update_descriptors(struct zink_context *ctx, struct zink_screen *screen, bool is bool cache_hit[ZINK_DESCRIPTOR_TYPES]; struct zink_descriptor_set *zds[ZINK_DESCRIPTOR_TYPES]; for (int h = 0; h < ZINK_DESCRIPTOR_TYPES; h++) { - if (pg->dsl[h]) + if (pg->pool[h]) zds[h] = get_descriptor_set(ctx, is_compute, h, &cache_hit[h]); else zds[h] = NULL; @@ -970,7 +970,7 @@ zink_draw_vbo(struct pipe_context *pctx, } } - if (gfx_program->base.num_descriptors) + if (zink_program_num_descriptors(&gfx_program->base)) update_descriptors(ctx, screen, false); struct zink_batch *batch = zink_batch_rp(ctx); @@ -1179,7 +1179,7 @@ zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info) VkPipeline pipeline = zink_get_compute_pipeline(screen, comp_program, &ctx->compute_pipeline_state); - if (comp_program->base.num_descriptors) + if (zink_program_num_descriptors(&comp_program->base)) update_descriptors(ctx, screen, true); diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index a6ac5422417..69ce1a809e1 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -125,8 +125,10 @@ create_gfx_pipeline_layout(VkDevice dev, struct zink_gfx_program *prog) unsigned num_descriptors = zink_program_num_descriptors(&prog->base); if (num_descriptors) { for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) { - layouts[num_layouts] = prog->base.dsl[i]; - num_layouts += !!layouts[num_layouts]; + if (prog->base.pool[i]) { + layouts[num_layouts] = prog->base.pool[i]->dsl; + num_layouts++; + } } } @@ -164,8 +166,10 @@ create_compute_pipeline_layout(VkDevice dev, struct zink_compute_program *comp) unsigned num_descriptors = zink_program_num_descriptors(&comp->base); if (num_descriptors) { for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) { - layouts[num_layouts] = comp->base.dsl[i]; - num_layouts += !!layouts[num_layouts]; + if (comp->base.pool[i]) { + layouts[num_layouts] = comp->base.pool[i]->dsl; + num_layouts++; + } } } @@ -479,22 +483,6 @@ zink_update_gfx_program(struct zink_context *ctx, struct zink_gfx_program *prog) update_shader_modules(ctx, ctx->gfx_stages, prog, true); } -static uint32_t -desc_state_hash(const void *key) -{ - const struct zink_descriptor_state_key *d_key = (void*)key; - uint32_t hash = 0; - /* this is a compute shader */ - if (!d_key->exists[PIPE_SHADER_FRAGMENT]) - return d_key->state[0]; - for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) { - if (d_key->exists[i]) - hash = XXH32(&d_key->state[i], sizeof(uint32_t), hash); - } - return hash; -} - - struct zink_gfx_program * zink_create_gfx_program(struct zink_context *ctx, struct zink_shader *stages[ZINK_SHADER_COUNT]) @@ -525,27 +513,13 @@ zink_create_gfx_program(struct zink_context *ctx, } } - if (!zink_descriptor_program_init(screen->dev, stages, (struct zink_program*)prog)) + if (!zink_descriptor_program_init(screen, stages, (struct zink_program*)prog)) goto fail; prog->base.layout = create_gfx_pipeline_layout(screen->dev, prog); if (!prog->base.layout) goto fail; - for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) { - if (!prog->base.num_descriptors[i]) - continue; - prog->base.desc_sets[i] = _mesa_hash_table_create(NULL, desc_state_hash, zink_desc_state_equal); - if (!prog->base.desc_sets[i]) - goto fail; - - prog->base.free_desc_sets[i] = _mesa_hash_table_create(NULL, desc_state_hash, zink_desc_state_equal); - if (!prog->base.free_desc_sets[i]) - goto fail; - - util_dynarray_init(&prog->base.alloc_desc_sets[i], NULL); - } - return prog; fail: @@ -637,27 +611,13 @@ zink_create_compute_program(struct zink_context *ctx, struct zink_shader *shader struct zink_shader *stages[ZINK_SHADER_COUNT] = {}; stages[0] = shader; - if (!zink_descriptor_program_init(screen->dev, stages, (struct zink_program*)comp)) + if (!zink_descriptor_program_init(screen, stages, (struct zink_program*)comp)) goto fail; comp->base.layout = create_compute_pipeline_layout(screen->dev, comp); if (!comp->base.layout) goto fail; - for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) { - if (!comp->base.num_descriptors[i]) - continue; - comp->base.desc_sets[i] = _mesa_hash_table_create(NULL, desc_state_hash, zink_desc_state_equal); - if (!comp->base.desc_sets[i]) - goto fail; - - comp->base.free_desc_sets[i] = _mesa_hash_table_create(NULL, desc_state_hash, zink_desc_state_equal); - if (!comp->base.free_desc_sets[i]) - goto fail; - - util_dynarray_init(&comp->base.alloc_desc_sets[i], NULL); - } - return comp; fail: @@ -666,16 +626,6 @@ fail: return NULL; } -static void -zink_program_clear_desc_sets(struct zink_program *pg, struct hash_table *ht) -{ - hash_table_foreach(ht, entry) { - struct zink_descriptor_set *zds = entry->data; - zink_descriptor_set_invalidate(zds); - } - _mesa_hash_table_clear(ht, NULL); -} - uint32_t zink_program_get_descriptor_usage(struct zink_context *ctx, enum pipe_shader_type stage, enum zink_descriptor_type type) { @@ -753,6 +703,15 @@ zink_program_num_bindings(const struct zink_program *pg, bool is_compute) return num_bindings; } +unsigned +zink_program_num_descriptors(const struct zink_program *pg) +{ + unsigned num_descriptors = 0; + for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) + num_descriptors += pg->pool[i] ? pg->pool[i]->num_descriptors : 0; + return num_descriptors; +} + static void gfx_program_remove_shader(struct zink_gfx_program *prog, struct zink_shader *shader) { @@ -788,22 +747,8 @@ zink_destroy_gfx_program(struct zink_screen *screen, } zink_shader_cache_reference(screen, &prog->shader_cache, NULL); - bool null_destroy = false; - for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) { - - if (prog->base.num_descriptors[i] || !null_destroy) { - vkDestroyDescriptorSetLayout(screen->dev, prog->base.dsl[i], NULL); - vkDestroyDescriptorPool(screen->dev, prog->base.descpool[i], NULL); - } - null_destroy |= !prog->base.num_descriptors[i]; - - zink_program_clear_desc_sets(&prog->base, prog->base.desc_sets[i]); - _mesa_hash_table_destroy(prog->base.desc_sets[i], NULL); - zink_program_clear_desc_sets(&prog->base, prog->base.free_desc_sets[i]); - _mesa_hash_table_destroy(prog->base.free_desc_sets[i], NULL); - - util_dynarray_fini(&prog->base.alloc_desc_sets[i]); - } + for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) + zink_descriptor_pool_free(screen, prog->base.pool[i]); ralloc_free(prog); } @@ -829,22 +774,8 @@ zink_destroy_compute_program(struct zink_screen *screen, _mesa_hash_table_destroy(comp->pipelines, NULL); zink_shader_cache_reference(screen, &comp->shader_cache, NULL); - bool null_destroy = false; - for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) { - - if (comp->base.num_descriptors[i] || !null_destroy) { - vkDestroyDescriptorSetLayout(screen->dev, comp->base.dsl[i], NULL); - vkDestroyDescriptorPool(screen->dev, comp->base.descpool[i], NULL); - } - null_destroy |= !comp->base.num_descriptors[i]; - - zink_program_clear_desc_sets((struct zink_program*)comp, comp->base.desc_sets[i]); - _mesa_hash_table_destroy(comp->base.desc_sets[i], NULL); - zink_program_clear_desc_sets((struct zink_program*)comp, comp->base.free_desc_sets[i]); - _mesa_hash_table_destroy(comp->base.free_desc_sets[i], NULL); - - util_dynarray_fini(&comp->base.alloc_desc_sets[i]); - } + for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) + zink_descriptor_pool_free(screen, comp->base.pool[i]); ralloc_free(comp); } diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h index 3329cabba2a..ac56eb0eab3 100644 --- a/src/gallium/drivers/zink/zink_program.h +++ b/src/gallium/drivers/zink/zink_program.h @@ -70,12 +70,7 @@ struct zink_shader_cache { struct zink_program { struct pipe_reference reference; - struct hash_table *desc_sets[ZINK_DESCRIPTOR_TYPES]; - struct hash_table *free_desc_sets[ZINK_DESCRIPTOR_TYPES]; - struct util_dynarray alloc_desc_sets[ZINK_DESCRIPTOR_TYPES]; - VkDescriptorPool descpool[ZINK_DESCRIPTOR_TYPES]; - VkDescriptorSetLayout dsl[ZINK_DESCRIPTOR_TYPES]; - unsigned num_descriptors[ZINK_DESCRIPTOR_TYPES]; + struct zink_descriptor_pool *pool[ZINK_DESCRIPTOR_TYPES]; struct zink_descriptor_set *last_set[ZINK_DESCRIPTOR_TYPES]; VkPipelineLayout layout; @@ -123,14 +118,8 @@ zink_desc_type_from_vktype(VkDescriptorType type) } -static inline unsigned -zink_program_num_descriptors(const struct zink_program *pg) -{ - unsigned num_descriptors = 0; - for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) - num_descriptors += pg->num_descriptors[i]; - return num_descriptors; -} +unsigned +zink_program_num_descriptors(const struct zink_program *pg); unsigned zink_program_num_bindings_typed(const struct zink_program *pg, enum zink_descriptor_type type, bool is_compute);