Mesa (main): zink: split out descriptor pool sizing into separate struct

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Oct 26 14:39:12 UTC 2021


Module: Mesa
Branch: main
Commit: 3a894d2b2f6483e5a2a5ab66485062612eeff224
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3a894d2b2f6483e5a2a5ab66485062612eeff224

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Mon Oct 18 12:05:51 2021 -0400

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 <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13483>

---

 src/gallium/drivers/zink/zink_context.h          |   1 +
 src/gallium/drivers/zink/zink_descriptors.c      | 175 +++++++++++------------
 src/gallium/drivers/zink/zink_descriptors.h      |  14 +-
 src/gallium/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;



More information about the mesa-commit mailing list