From 3a894d2b2f6483e5a2a5ab66485062612eeff224 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 18 Oct 2021 12:05:51 -0400 Subject: [PATCH] zink: split out descriptor pool sizing into separate struct this migrates existing uses of zink_descriptor_layout_key to use zink_descriptor_pool_key instead, which ends up being more helpful overall since it puts all the pool-related data into a single struct this also has a(n incredibly small) benefit of removing VkDescriptorPoolSize[6] from every program data struct and deduplicating it into the descriptor pool key set Reviewed-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_context.h | 1 + src/gallium/drivers/zink/zink_descriptors.c | 175 +++++++++--------- src/gallium/drivers/zink/zink_descriptors.h | 14 +- .../drivers/zink/zink_descriptors_lazy.c | 69 ++++--- 4 files changed, 141 insertions(+), 118 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 2a83c6f1335..a0ed22a1f58 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -224,6 +224,7 @@ struct zink_context { struct zink_depth_stencil_alpha_state *dsa_state; struct hash_table desc_set_layouts[ZINK_DESCRIPTOR_TYPES]; + struct set desc_pool_keys[ZINK_DESCRIPTOR_TYPES]; bool pipeline_changed[2]; //gfx, compute struct zink_shader *gfx_stages[ZINK_SHADER_COUNT]; diff --git a/src/gallium/drivers/zink/zink_descriptors.c b/src/gallium/drivers/zink/zink_descriptors.c index 4d946e7d1a3..2a9c770da96 100644 --- a/src/gallium/drivers/zink/zink_descriptors.c +++ b/src/gallium/drivers/zink/zink_descriptors.c @@ -44,8 +44,8 @@ struct zink_descriptor_pool { struct hash_table *desc_sets; struct hash_table *free_desc_sets; struct util_dynarray alloc_desc_sets; + const struct zink_descriptor_pool_key *key; VkDescriptorPool descpool; - struct zink_descriptor_pool_key key; unsigned num_resources; unsigned num_sets_allocated; simple_mtx_t mtx; @@ -213,7 +213,7 @@ static void descriptor_set_invalidate(struct zink_descriptor_set *zds) { zds->invalid = true; - for (unsigned i = 0; i < zds->pool->key.layout->num_bindings; i++) { + for (unsigned i = 0; i < zds->pool->key->layout->num_bindings; i++) { switch (zds->pool->type) { case ZINK_DESCRIPTOR_TYPE_UBO: case ZINK_DESCRIPTOR_TYPE_SSBO: @@ -291,31 +291,23 @@ descriptor_pool_delete(struct zink_context *ctx, struct zink_descriptor_pool *po struct zink_screen *screen = zink_screen(ctx->base.screen); if (!pool) return; - _mesa_hash_table_remove_key(ctx->dd->descriptor_pools[pool->type], &pool->key); + _mesa_hash_table_remove_key(ctx->dd->descriptor_pools[pool->type], pool->key); descriptor_pool_free(screen, pool); } static struct zink_descriptor_pool * descriptor_pool_create(struct zink_screen *screen, enum zink_descriptor_type type, - struct zink_descriptor_layout_key *layout_key, VkDescriptorPoolSize *sizes, unsigned num_type_sizes) + const struct zink_descriptor_pool_key *pool_key) { struct zink_descriptor_pool *pool = rzalloc(NULL, struct zink_descriptor_pool); if (!pool) return NULL; pipe_reference_init(&pool->reference, 1); pool->type = type; - pool->key.layout = layout_key; - pool->key.num_type_sizes = num_type_sizes; - size_t types_size = num_type_sizes * sizeof(VkDescriptorPoolSize); - pool->key.sizes = ralloc_size(pool, types_size); - if (!pool->key.sizes) { - ralloc_free(pool); - return NULL; - } - memcpy(pool->key.sizes, sizes, types_size); + pool->key = pool_key; simple_mtx_init(&pool->mtx, mtx_plain); - for (unsigned i = 0; i < layout_key->num_bindings; i++) { - pool->num_resources += layout_key->bindings[i].descriptorCount; + for (unsigned i = 0; i < pool_key->layout->num_bindings; i++) { + pool->num_resources += pool_key->layout->bindings[i].descriptorCount; } pool->desc_sets = _mesa_hash_table_create(NULL, desc_state_hash, desc_state_equal); if (!pool->desc_sets) @@ -329,8 +321,8 @@ descriptor_pool_create(struct zink_screen *screen, enum zink_descriptor_type typ VkDescriptorPoolCreateInfo dpci = {0}; dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - dpci.pPoolSizes = sizes; - dpci.poolSizeCount = num_type_sizes; + dpci.pPoolSizes = pool_key->sizes; + dpci.poolSizeCount = pool_key->sizes[1].descriptorCount ? 2 : 1; dpci.flags = 0; dpci.maxSets = ZINK_DEFAULT_MAX_DESCS; if (VKSCR(CreateDescriptorPool)(screen->dev, &dpci, 0, &pool->descpool) != VK_SUCCESS) { @@ -415,7 +407,6 @@ create_layout(struct zink_context *ctx, enum zink_descriptor_type type, return NULL; struct zink_descriptor_layout_key *k = ralloc(ctx, struct zink_descriptor_layout_key); - k->use_count = 0; k->num_bindings = num_bindings; size_t bindings_size = MAX2(num_bindings, 1) * sizeof(VkDescriptorSetLayoutBinding); k->bindings = ralloc_size(k, bindings_size); @@ -471,6 +462,57 @@ zink_descriptor_util_layout_get(struct zink_context *ctx, enum zink_descriptor_t return layout; } + +static uint32_t +hash_descriptor_pool_key(const void *key) +{ + uint32_t hash = 0; + const struct zink_descriptor_pool_key *k = key; + hash = XXH32(&k->layout, sizeof(void*), hash); + const unsigned num_type_sizes = k->sizes[1].descriptorCount ? 2 : 1; + for (unsigned i = 0; i < num_type_sizes; i++) + hash = XXH32(&k->sizes[i], sizeof(VkDescriptorPoolSize), hash); + + return hash; +} + +static bool +equals_descriptor_pool_key(const void *a, const void *b) +{ + const struct zink_descriptor_pool_key *a_k = a; + const struct zink_descriptor_pool_key *b_k = b; + const unsigned a_num_type_sizes = a_k->sizes[1].descriptorCount ? 2 : 1; + const unsigned b_num_type_sizes = b_k->sizes[1].descriptorCount ? 2 : 1; + return a_k->layout == b_k->layout && + a_num_type_sizes == b_num_type_sizes && + !memcmp(a_k->sizes, b_k->sizes, b_num_type_sizes * sizeof(VkDescriptorPoolSize)); +} + +struct zink_descriptor_pool_key * +zink_descriptor_util_pool_key_get(struct zink_context *ctx, enum zink_descriptor_type type, + struct zink_descriptor_layout_key *layout_key, + VkDescriptorPoolSize *sizes, unsigned num_type_sizes) +{ + uint32_t hash = 0; + struct zink_descriptor_pool_key key; + if (type != ZINK_DESCRIPTOR_TYPES) { + key.layout = layout_key; + key.sizes[1].descriptorCount = 0; + memcpy(key.sizes, sizes, num_type_sizes * sizeof(VkDescriptorPoolSize)); + hash = hash_descriptor_pool_key(&key); + struct set_entry *he = _mesa_set_search_pre_hashed(&ctx->desc_pool_keys[type], hash, &key); + if (he) + return (void*)he->key; + } + + struct zink_descriptor_pool_key *pool_key = rzalloc(ctx, struct zink_descriptor_pool_key); + pool_key->layout = layout_key; + memcpy(pool_key->sizes, sizes, num_type_sizes * sizeof(VkDescriptorPoolSize)); + if (type != ZINK_DESCRIPTOR_TYPES) + _mesa_set_add_pre_hashed(&ctx->desc_pool_keys[type], hash, pool_key); + return pool_key; +} + static void init_push_binding(VkDescriptorSetLayoutBinding *binding, unsigned i, VkDescriptorType type) { @@ -564,51 +606,23 @@ zink_descriptor_util_image_layout_eval(const struct zink_resource *res, bool is_ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } -static uint32_t -hash_descriptor_pool(const void *key) -{ - uint32_t hash = 0; - const struct zink_descriptor_pool_key *k = key; - hash = XXH32(&k->num_type_sizes, sizeof(unsigned), hash); - hash = XXH32(&k->layout, sizeof(k->layout), hash); - hash = XXH32(k->sizes, k->num_type_sizes * sizeof(VkDescriptorPoolSize), hash); - - return hash; -} - -static bool -equals_descriptor_pool(const void *a, const void *b) -{ - const struct zink_descriptor_pool_key *a_k = a; - const struct zink_descriptor_pool_key *b_k = b; - return a_k->num_type_sizes == b_k->num_type_sizes && - a_k->layout == b_k->layout && - !memcmp(a_k->sizes, b_k->sizes, a_k->num_type_sizes * sizeof(VkDescriptorPoolSize)); -} - static struct zink_descriptor_pool * descriptor_pool_get(struct zink_context *ctx, enum zink_descriptor_type type, - struct zink_descriptor_layout_key *layout_key, VkDescriptorPoolSize *sizes, unsigned num_type_sizes) + const struct zink_descriptor_pool_key *pool_key) { uint32_t hash = 0; if (type != ZINK_DESCRIPTOR_TYPES) { - struct zink_descriptor_pool_key key = { - .layout = layout_key, - .num_type_sizes = num_type_sizes, - .sizes = sizes, - }; - - hash = hash_descriptor_pool(&key); - struct hash_entry *he = _mesa_hash_table_search_pre_hashed(ctx->dd->descriptor_pools[type], hash, &key); + hash = hash_descriptor_pool_key(pool_key); + struct hash_entry *he = _mesa_hash_table_search_pre_hashed(ctx->dd->descriptor_pools[type], hash, pool_key); if (he) { struct zink_descriptor_pool *pool = he->data; pipe_reference(NULL, &pool->reference); return pool; } } - struct zink_descriptor_pool *pool = descriptor_pool_create(zink_screen(ctx->base.screen), type, layout_key, sizes, num_type_sizes); + struct zink_descriptor_pool *pool = descriptor_pool_create(zink_screen(ctx->base.screen), type, pool_key); if (type != ZINK_DESCRIPTOR_TYPES) - _mesa_hash_table_insert_pre_hashed(ctx->dd->descriptor_pools[type], hash, &pool->key, pool); + _mesa_hash_table_insert_pre_hashed(ctx->dd->descriptor_pools[type], hash, pool_key, pool); return pool; } @@ -641,25 +655,6 @@ zink_descriptor_util_alloc_sets(struct zink_screen *screen, VkDescriptorSetLayou return true; } -unsigned -zink_descriptor_program_num_sizes(struct zink_program *pg, enum zink_descriptor_type type) -{ - switch (type) { - case ZINK_DESCRIPTOR_TYPE_UBO: - return 1; - case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: - return !!pg->dd->sizes[ZDS_INDEX_COMBINED_SAMPLER].descriptorCount + - !!pg->dd->sizes[ZDS_INDEX_UNIFORM_TEXELS].descriptorCount; - case ZINK_DESCRIPTOR_TYPE_SSBO: - return 1; - case ZINK_DESCRIPTOR_TYPE_IMAGE: - return !!pg->dd->sizes[ZDS_INDEX_STORAGE_IMAGE].descriptorCount + - !!pg->dd->sizes[ZDS_INDEX_STORAGE_TEXELS].descriptorCount; - default: break; - } - unreachable("unknown type"); -} - static struct zink_descriptor_set * allocate_desc_set(struct zink_context *ctx, struct zink_program *pg, enum zink_descriptor_type type, unsigned descs_used, bool is_compute) { @@ -667,8 +662,8 @@ allocate_desc_set(struct zink_context *ctx, struct zink_program *pg, enum zink_d bool push_set = type == ZINK_DESCRIPTOR_TYPES; struct zink_descriptor_pool *pool = push_set ? ctx->dd->push_pool[is_compute] : pdd_cached(pg)->pool[type]; #define DESC_BUCKET_FACTOR 10 - unsigned bucket_size = pool->key.layout->num_bindings ? DESC_BUCKET_FACTOR : 1; - if (pool->key.layout->num_bindings) { + unsigned bucket_size = pool->key->layout->num_bindings ? DESC_BUCKET_FACTOR : 1; + if (pool->key->layout->num_bindings) { for (unsigned desc_factor = DESC_BUCKET_FACTOR; desc_factor < descs_used; desc_factor *= DESC_BUCKET_FACTOR) bucket_size = desc_factor; } @@ -711,13 +706,13 @@ allocate_desc_set(struct zink_context *ctx, struct zink_program *pg, enum zink_d #endif switch (type) { case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: - zds->sampler_states = (struct zink_sampler_state**)&samplers[i * pool->key.layout->num_bindings]; + zds->sampler_states = (struct zink_sampler_state**)&samplers[i * pool->key->layout->num_bindings]; FALLTHROUGH; case ZINK_DESCRIPTOR_TYPE_IMAGE: - zds->surfaces = &surfaces[i * pool->key.layout->num_bindings]; + zds->surfaces = &surfaces[i * pool->key->layout->num_bindings]; break; default: - zds->res_objs = (struct zink_resource_object**)&res_objs[i * pool->key.layout->num_bindings]; + zds->res_objs = (struct zink_resource_object**)&res_objs[i * pool->key->layout->num_bindings]; break; } zds->desc_set = desc_set[i]; @@ -785,7 +780,7 @@ zink_descriptor_set_get(struct zink_context *ctx, unsigned descs_used = 1; assert(type <= ZINK_DESCRIPTOR_TYPES); - assert(pool->key.layout->num_bindings); + assert(pool->key->layout->num_bindings); uint32_t hash = push_set ? ctx->dd->push_state[is_compute] : ctx->dd->descriptor_states[is_compute].state[type]; @@ -903,7 +898,7 @@ zink_descriptor_set_recycle(struct zink_descriptor_set *zds) if (refcount != 1) return; /* this is a null set */ - if (!pool->key.layout->num_bindings) + if (!pool->key->layout->num_bindings) return; simple_mtx_lock(&pool->mtx); if (zds->punted) @@ -1079,16 +1074,11 @@ zink_descriptor_program_init(struct zink_context *ctx, struct zink_program *pg) return true; for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) { - if (!pg->dd->layout_key[i]) + if (!pg->dd->pool_key[i]) continue; - unsigned idx = zink_descriptor_type_to_size_idx(i); - VkDescriptorPoolSize *size = &pg->dd->sizes[idx]; - /* this is a sampler/image set with no images only texels */ - if (!size->descriptorCount) - size++; - unsigned num_sizes = zink_descriptor_program_num_sizes(pg, i); - struct zink_descriptor_pool *pool = descriptor_pool_get(ctx, i, pg->dd->layout_key[i], size, num_sizes); + const struct zink_descriptor_pool_key *pool_key = pg->dd->pool_key[i]; + struct zink_descriptor_pool *pool = descriptor_pool_get(ctx, i, pool_key); if (!pool) return false; pdd_cached(pg)->pool[i] = pool; @@ -1125,7 +1115,7 @@ static bool zink_descriptor_pool_init(struct zink_context *ctx) { for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) { - ctx->dd->descriptor_pools[i] = _mesa_hash_table_create(ctx, hash_descriptor_pool, equals_descriptor_pool); + ctx->dd->descriptor_pools[i] = _mesa_hash_table_create(ctx, hash_descriptor_pool_key, equals_descriptor_pool_key); if (!ctx->dd->descriptor_pools[i]) return false; } @@ -1135,9 +1125,13 @@ zink_descriptor_pool_init(struct zink_context *ctx) sizes[0].descriptorCount = ZINK_SHADER_COUNT * ZINK_DEFAULT_MAX_DESCS; sizes[1].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; sizes[1].descriptorCount = ZINK_DEFAULT_MAX_DESCS; - ctx->dd->push_pool[0] = descriptor_pool_get(ctx, 0, ctx->dd->push_layout_keys[0], sizes, ctx->dd->has_fbfetch ? 2 : 1); + /* these are freed by ralloc */ + struct zink_descriptor_pool_key *pool_key; + pool_key = zink_descriptor_util_pool_key_get(ctx, ZINK_DESCRIPTOR_TYPES, ctx->dd->push_layout_keys[0], sizes, ctx->dd->has_fbfetch ? 2 : 1); + ctx->dd->push_pool[0] = descriptor_pool_get(ctx, 0, pool_key); sizes[0].descriptorCount = ZINK_DEFAULT_MAX_DESCS; - ctx->dd->push_pool[1] = descriptor_pool_get(ctx, 0, ctx->dd->push_layout_keys[1], sizes, 1); + pool_key = zink_descriptor_util_pool_key_get(ctx, ZINK_DESCRIPTOR_TYPES, ctx->dd->push_layout_keys[1], sizes, 1); + ctx->dd->push_pool[1] = descriptor_pool_get(ctx, 0, pool_key); return ctx->dd->push_pool[0] && ctx->dd->push_pool[1]; } @@ -1746,9 +1740,12 @@ zink_descriptors_deinit(struct zink_context *ctx) bool zink_descriptor_layouts_init(struct zink_context *ctx) { - for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) + for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) { if (!_mesa_hash_table_init(&ctx->desc_set_layouts[i], ctx, hash_descriptor_layout, equals_descriptor_layout)) return false; + if (!_mesa_set_init(&ctx->desc_pool_keys[i], ctx, hash_descriptor_pool_key, equals_descriptor_pool_key)) + return false; + } return true; } diff --git a/src/gallium/drivers/zink/zink_descriptors.h b/src/gallium/drivers/zink/zink_descriptors.h index 89fffc07978..91fcf3a6d73 100644 --- a/src/gallium/drivers/zink/zink_descriptors.h +++ b/src/gallium/drivers/zink/zink_descriptors.h @@ -92,7 +92,6 @@ struct zink_descriptor_state_key { struct zink_descriptor_layout_key { unsigned num_bindings; - unsigned use_count; VkDescriptorSetLayoutBinding *bindings; }; @@ -102,9 +101,9 @@ struct zink_descriptor_layout { }; struct zink_descriptor_pool_key { + unsigned use_count; struct zink_descriptor_layout_key *layout; - unsigned num_type_sizes; - VkDescriptorPoolSize *sizes; + VkDescriptorPoolSize sizes[2]; }; struct zink_descriptor_reference { @@ -144,9 +143,8 @@ struct zink_descriptor_data { struct zink_program_descriptor_data { uint8_t push_usage; bool bindless; - VkDescriptorPoolSize sizes[6]; //zink_descriptor_size_index - struct zink_descriptor_layout_key *layout_key[ZINK_DESCRIPTOR_TYPES]; //push set doesn't need one uint8_t binding_usage; + struct zink_descriptor_pool_key *pool_key[ZINK_DESCRIPTOR_TYPES]; //push set doesn't need one struct zink_descriptor_layout *layouts[ZINK_DESCRIPTOR_TYPES + 1]; VkDescriptorUpdateTemplateKHR push_template; }; @@ -193,8 +191,6 @@ zink_descriptor_type_to_size_idx(enum zink_descriptor_type type) } unreachable("unknown type"); } -unsigned -zink_descriptor_program_num_sizes(struct zink_program *pg, enum zink_descriptor_type type); bool zink_descriptor_layouts_init(struct zink_context *ctx); @@ -211,6 +207,10 @@ struct zink_descriptor_layout * zink_descriptor_util_layout_get(struct zink_context *ctx, enum zink_descriptor_type type, VkDescriptorSetLayoutBinding *bindings, unsigned num_bindings, struct zink_descriptor_layout_key **layout_key); +struct zink_descriptor_pool_key * +zink_descriptor_util_pool_key_get(struct zink_context *ctx, enum zink_descriptor_type type, + struct zink_descriptor_layout_key *layout_key, + VkDescriptorPoolSize *sizes, unsigned num_type_sizes); void zink_descriptor_util_init_fbfetch(struct zink_context *ctx); bool diff --git a/src/gallium/drivers/zink/zink_descriptors_lazy.c b/src/gallium/drivers/zink/zink_descriptors_lazy.c index efa046d746b..dd0b29f9085 100644 --- a/src/gallium/drivers/zink/zink_descriptors_lazy.c +++ b/src/gallium/drivers/zink/zink_descriptors_lazy.c @@ -127,6 +127,25 @@ init_template_entry(struct zink_shader *shader, enum zink_descriptor_type type, (*entry_idx)++; } +static uint16_t +descriptor_program_num_sizes(VkDescriptorPoolSize *sizes, enum zink_descriptor_type type) +{ + switch (type) { + case ZINK_DESCRIPTOR_TYPE_UBO: + return 1; + case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: + return !!sizes[ZDS_INDEX_COMBINED_SAMPLER].descriptorCount + + !!sizes[ZDS_INDEX_UNIFORM_TEXELS].descriptorCount; + case ZINK_DESCRIPTOR_TYPE_SSBO: + return 1; + case ZINK_DESCRIPTOR_TYPE_IMAGE: + return !!sizes[ZDS_INDEX_STORAGE_IMAGE].descriptorCount + + !!sizes[ZDS_INDEX_STORAGE_TEXELS].descriptorCount; + default: break; + } + unreachable("unknown type"); +} + bool zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program *pg) { @@ -136,6 +155,8 @@ zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program unsigned num_bindings[ZINK_DESCRIPTOR_TYPES] = {0}; uint8_t has_bindings = 0; unsigned push_count = 0; + uint16_t num_type_sizes[ZINK_DESCRIPTOR_TYPES]; + VkDescriptorPoolSize sizes[6] = {0}; //zink_descriptor_size_index struct zink_shader **stages; if (pg->is_compute) @@ -183,8 +204,8 @@ zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program binding->pImmutableSamplers = NULL; enum zink_descriptor_size_index idx = zink_vktype_to_size_idx(shader->bindings[j][k].type); - pg->dd->sizes[idx].descriptorCount += shader->bindings[j][k].size; - pg->dd->sizes[idx].type = shader->bindings[j][k].type; + sizes[idx].descriptorCount += shader->bindings[j][k].size; + sizes[idx].type = shader->bindings[j][k].type; switch (shader->bindings[j][k].type) { case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: @@ -203,6 +224,7 @@ zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program num_bindings[j]++; has_bindings |= BITFIELD_BIT(j); } + num_type_sizes[j] = descriptor_program_num_sizes(sizes, j); } pg->dd->bindless |= shader->bindless; } @@ -219,6 +241,8 @@ zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program pg->dsl[pg->num_dsl++] = push_count ? ctx->dd->push_dsl[pg->is_compute]->layout : ctx->dd->dummy_dsl->layout; if (has_bindings) { + for (unsigned i = 0; i < ARRAY_SIZE(sizes); i++) + sizes[i].descriptorCount *= screen->descriptor_mode == ZINK_DESCRIPTOR_MODE_LAZY ? MAX_LAZY_DESCRIPTORS : ZINK_DEFAULT_MAX_DESCS; u_foreach_bit(type, has_bindings) { for (unsigned i = 0; i < type; i++) { /* push set is always 0 */ @@ -228,13 +252,17 @@ zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program pg->dd->binding_usage |= BITFIELD_BIT(i); } } - pg->dd->layouts[pg->num_dsl] = zink_descriptor_util_layout_get(ctx, type, bindings[type], num_bindings[type], &pg->dd->layout_key[type]); - pg->dd->layout_key[type]->use_count++; + struct zink_descriptor_layout_key *key; + pg->dd->layouts[pg->num_dsl] = zink_descriptor_util_layout_get(ctx, type, bindings[type], num_bindings[type], &key); + enum zink_descriptor_size_index idx = zink_descriptor_type_to_size_idx(type); + VkDescriptorPoolSize *sz = &sizes[idx]; + if (!sz->descriptorCount) + sz++; + pg->dd->pool_key[type] = zink_descriptor_util_pool_key_get(ctx, type, key, sz, num_type_sizes[type]); + pg->dd->pool_key[type]->use_count++; pg->dsl[pg->num_dsl] = pg->dd->layouts[pg->num_dsl]->layout; pg->num_dsl++; } - for (unsigned i = 0; i < ARRAY_SIZE(pg->dd->sizes); i++) - pg->dd->sizes[i].descriptorCount *= screen->descriptor_mode == ZINK_DESCRIPTOR_MODE_LAZY ? MAX_LAZY_DESCRIPTORS : ZINK_DEFAULT_MAX_DESCS; } /* TODO: make this dynamic? */ if (pg->dd->bindless) { @@ -267,7 +295,7 @@ zink_descriptor_program_init_lazy(struct zink_context *ctx, struct zink_program if (push_count) wd_count[0] = pg->is_compute ? 1 : (ZINK_SHADER_COUNT + !!ctx->dd->has_fbfetch); for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) - wd_count[i + 1] = pg->dd->layout_key[i] ? pg->dd->layout_key[i]->num_bindings : 0; + wd_count[i + 1] = pg->dd->pool_key[i] ? pg->dd->pool_key[i]->layout->num_bindings : 0; VkDescriptorUpdateTemplateEntry *push_entries[2] = { dd_lazy(ctx)->push_entries, @@ -308,8 +336,8 @@ zink_descriptor_program_deinit_lazy(struct zink_context *ctx, struct zink_progra { struct zink_screen *screen = zink_screen(ctx->base.screen); for (unsigned i = 0; pg->num_dsl && i < ZINK_DESCRIPTOR_TYPES; i++) { - if (pg->dd->layout_key[i]) - pg->dd->layout_key[i]->use_count--; + if (pg->dd->pool_key[i]) + pg->dd->pool_key[i]->use_count--; } if (pg->dd && pg->dd->push_template) VKSCR(DestroyDescriptorUpdateTemplate)(screen->dev, pg->dd->push_template, NULL); @@ -317,7 +345,7 @@ zink_descriptor_program_deinit_lazy(struct zink_context *ctx, struct zink_progra } static VkDescriptorPool -create_pool(struct zink_screen *screen, unsigned num_type_sizes, VkDescriptorPoolSize *sizes, unsigned flags) +create_pool(struct zink_screen *screen, unsigned num_type_sizes, const VkDescriptorPoolSize *sizes, unsigned flags) { VkDescriptorPool pool; VkDescriptorPoolCreateInfo dpci = {0}; @@ -400,7 +428,8 @@ 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_descriptor_data_lazy *bdd, bool is_compute) { struct zink_screen *screen = zink_screen(ctx->base.screen); - struct hash_entry *he = _mesa_hash_table_search(&bdd->pools[type], pg->dd->layout_key[type]); + const struct zink_descriptor_pool_key *pool_key = pg->dd->pool_key[type]; + struct hash_entry *he = _mesa_hash_table_search(&bdd->pools[type], pool_key); struct zink_descriptor_pool *pool; if (he) { pool = he->data; @@ -409,17 +438,13 @@ get_descriptor_pool_lazy(struct zink_context *ctx, struct zink_program *pg, enum pool = rzalloc(bdd, struct zink_descriptor_pool); if (!pool) return NULL; - unsigned idx = zink_descriptor_type_to_size_idx(type); - VkDescriptorPoolSize *size = &pg->dd->sizes[idx]; - /* this is a sampler/image set with no images only texels */ - if (!size->descriptorCount) - size++; - pool->pool = create_pool(screen, zink_descriptor_program_num_sizes(pg, type), size, 0); + const unsigned num_type_sizes = pool_key->sizes[1].descriptorCount ? 2 : 1; + pool->pool = create_pool(screen, num_type_sizes, pool_key->sizes, 0); if (!pool->pool) { ralloc_free(pool); return NULL; } - _mesa_hash_table_insert(&bdd->pools[type], pg->dd->layout_key[type], pool); + _mesa_hash_table_insert(&bdd->pools[type], pool_key, pool); return check_pool_alloc(ctx, pool, he, pg, type, bdd, is_compute); } @@ -438,7 +463,7 @@ populate_sets(struct zink_context *ctx, struct zink_batch_descriptor_data_lazy * struct zink_program *pg, uint8_t *changed_sets, VkDescriptorSet *sets) { u_foreach_bit(type, *changed_sets) { - if (pg->dd->layout_key[type]) { + if (pg->dd->pool_key[type]) { struct zink_descriptor_pool *pool = get_descriptor_pool_lazy(ctx, pg, type, bdd, pg->is_compute); sets[type] = get_descriptor_set_lazy(pool); } else @@ -476,7 +501,7 @@ zink_descriptors_update_lazy_masked(struct zink_context *ctx, bool is_compute, u u_foreach_bit(type, changed_sets) { assert(type + 1 < pg->num_dsl); - if (pg->dd->layout_key[type]) { + if (pg->dd->pool_key[type]) { VKSCR(UpdateDescriptorSetWithTemplate)(screen->dev, desc_sets[type], pg->dd->layouts[type + 1]->desc_template, ctx); VKSCR(CmdBindDescriptorSets)(bs->cmdbuf, is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS, @@ -487,7 +512,7 @@ zink_descriptors_update_lazy_masked(struct zink_context *ctx, bool is_compute, u } } u_foreach_bit(type, bind_sets & ~changed_sets) { - if (!pg->dd->layout_key[type]) + if (!pg->dd->pool_key[type]) bdd->sets[is_compute][type + 1] = ctx->dd->dummy_set; assert(bdd->sets[is_compute][type + 1]); VKSCR(CmdBindDescriptorSets)(bs->cmdbuf, @@ -631,7 +656,7 @@ zink_batch_descriptor_reset_lazy(struct zink_screen *screen, struct zink_batch_s struct zink_batch_descriptor_data_lazy *bdd = bdd_lazy(bs); for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) { hash_table_foreach(&bdd->pools[i], entry) { - const struct zink_descriptor_layout_key *key = entry->key; + const struct zink_descriptor_pool_key *key = entry->key; struct zink_descriptor_pool *pool = (void*)entry->data; if (key->use_count) pool->set_idx = 0;