1/*
2 * Copyright © 2020 Mike Blumenkrantz
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 * Authors:
24 *    Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
25 */
26
27#include "tgsi/tgsi_from_mesa.h"
28
29
30
31#include "zink_context.h"
32#include "zink_descriptors.h"
33#include "zink_program.h"
34#include "zink_render_pass.h"
35#include "zink_resource.h"
36#include "zink_screen.h"
37
38#define XXH_INLINE_ALL
39#include "util/xxhash.h"
40
41
42struct zink_descriptor_pool {
43   struct pipe_reference reference;
44   enum zink_descriptor_type type;
45   struct hash_table *desc_sets;
46   struct hash_table *free_desc_sets;
47   struct util_dynarray alloc_desc_sets;
48   const struct zink_descriptor_pool_key *key;
49   VkDescriptorPool descpool;
50   unsigned num_resources;
51   unsigned num_sets_allocated;
52   simple_mtx_t mtx;
53};
54
55struct zink_descriptor_set {
56   struct zink_descriptor_pool *pool;
57   struct pipe_reference reference; //incremented for batch usage
58   VkDescriptorSet desc_set;
59   uint32_t hash;
60   bool invalid;
61   bool punted;
62   bool recycled;
63   uint8_t compacted; //bitmask of zink_descriptor_type
64   struct zink_descriptor_state_key key;
65   struct zink_batch_usage *batch_uses;
66#ifndef NDEBUG
67   /* for extra debug asserts */
68   unsigned num_resources;
69#endif
70   union {
71      struct zink_resource_object **res_objs;
72      struct {
73         struct zink_descriptor_surface *surfaces;
74         struct zink_sampler_state **sampler_states;
75      };
76   };
77};
78
79union zink_program_descriptor_refs {
80   struct zink_resource **res;
81   struct zink_descriptor_surface *dsurf;
82   struct {
83      struct zink_descriptor_surface *dsurf;
84      struct zink_sampler_state **sampler_state;
85   } sampler;
86};
87
88struct zink_program_descriptor_data_cached {
89   struct zink_program_descriptor_data base;
90   struct zink_descriptor_pool *pool[ZINK_DESCRIPTOR_TYPES];
91   struct zink_descriptor_set *last_set[ZINK_DESCRIPTOR_TYPES];
92   unsigned num_refs[ZINK_DESCRIPTOR_TYPES];
93   union zink_program_descriptor_refs *refs[ZINK_DESCRIPTOR_TYPES];
94   unsigned cache_misses[ZINK_DESCRIPTOR_TYPES];
95};
96
97
98static inline struct zink_program_descriptor_data_cached *
99pdd_cached(struct zink_program *pg)
100{
101   return (struct zink_program_descriptor_data_cached*)pg->dd;
102}
103
104static bool
105batch_add_desc_set(struct zink_batch *batch, struct zink_descriptor_set *zds)
106{
107   if (zink_batch_usage_matches(zds->batch_uses, batch->state) ||
108       !batch_ptr_add_usage(batch, batch->state->dd->desc_sets, zds))
109      return false;
110   pipe_reference(NULL, &zds->reference);
111   pipe_reference(NULL, &zds->pool->reference);
112   zink_batch_usage_set(&zds->batch_uses, batch->state);
113   return true;
114}
115
116static void
117debug_describe_zink_descriptor_pool(char *buf, const struct zink_descriptor_pool *ptr)
118{
119   sprintf(buf, "zink_descriptor_pool");
120}
121
122static inline uint32_t
123get_sampler_view_hash(const struct zink_sampler_view *sampler_view)
124{
125   if (!sampler_view)
126      return 0;
127   return sampler_view->base.target == PIPE_BUFFER ?
128          sampler_view->buffer_view->hash : sampler_view->image_view->hash;
129}
130
131static inline uint32_t
132get_image_view_hash(const struct zink_image_view *image_view)
133{
134   if (!image_view || !image_view->base.resource)
135      return 0;
136   return image_view->base.resource->target == PIPE_BUFFER ?
137          image_view->buffer_view->hash : image_view->surface->hash;
138}
139
140uint32_t
141zink_get_sampler_view_hash(struct zink_context *ctx, struct zink_sampler_view *sampler_view, bool is_buffer)
142{
143   return get_sampler_view_hash(sampler_view) ? get_sampler_view_hash(sampler_view) :
144          (is_buffer ? zink_screen(ctx->base.screen)->null_descriptor_hashes.buffer_view :
145                       zink_screen(ctx->base.screen)->null_descriptor_hashes.image_view);
146}
147
148uint32_t
149zink_get_image_view_hash(struct zink_context *ctx, struct zink_image_view *image_view, bool is_buffer)
150{
151   return get_image_view_hash(image_view) ? get_image_view_hash(image_view) :
152          (is_buffer ? zink_screen(ctx->base.screen)->null_descriptor_hashes.buffer_view :
153                       zink_screen(ctx->base.screen)->null_descriptor_hashes.image_view);
154}
155
156#ifndef NDEBUG
157static uint32_t
158get_descriptor_surface_hash(struct zink_context *ctx, struct zink_descriptor_surface *dsurf)
159{
160   return dsurf->is_buffer ? (dsurf->bufferview ? dsurf->bufferview->hash : zink_screen(ctx->base.screen)->null_descriptor_hashes.buffer_view) :
161                             (dsurf->surface ? dsurf->surface->hash : zink_screen(ctx->base.screen)->null_descriptor_hashes.image_view);
162}
163#endif
164
165static bool
166desc_state_equal(const void *a, const void *b)
167{
168   const struct zink_descriptor_state_key *a_k = (void*)a;
169   const struct zink_descriptor_state_key *b_k = (void*)b;
170
171   for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) {
172      if (a_k->exists[i] != b_k->exists[i])
173         return false;
174      if (a_k->exists[i] && b_k->exists[i] &&
175          a_k->state[i] != b_k->state[i])
176         return false;
177   }
178   return true;
179}
180
181static uint32_t
182desc_state_hash(const void *key)
183{
184   const struct zink_descriptor_state_key *d_key = (void*)key;
185   uint32_t hash = 0;
186   bool first = true;
187   for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) {
188      if (d_key->exists[i]) {
189         if (!first)
190            hash ^= d_key->state[i];
191         else
192            hash = d_key->state[i];
193         first = false;
194      }
195   }
196   return hash;
197}
198
199static void
200pop_desc_set_ref(struct zink_descriptor_set *zds, struct util_dynarray *refs)
201{
202   size_t size = sizeof(struct zink_descriptor_reference);
203   unsigned num_elements = refs->size / size;
204   for (unsigned i = 0; i < num_elements; i++) {
205      struct zink_descriptor_reference *ref = util_dynarray_element(refs, struct zink_descriptor_reference, i);
206      if (&zds->invalid == ref->invalid) {
207         memcpy(util_dynarray_element(refs, struct zink_descriptor_reference, i),
208                util_dynarray_pop_ptr(refs, struct zink_descriptor_reference), size);
209         break;
210      }
211   }
212}
213
214static void
215descriptor_set_invalidate(struct zink_descriptor_set *zds)
216{
217   zds->invalid = true;
218   unsigned idx = 0;
219   for (unsigned i = 0; i < zds->pool->key->layout->num_bindings; i++) {
220      for (unsigned j = 0; j < zds->pool->key->layout->bindings[i].descriptorCount; j++) {
221         switch (zds->pool->type) {
222         case ZINK_DESCRIPTOR_TYPE_UBO:
223         case ZINK_DESCRIPTOR_TYPE_SSBO:
224            if (zds->res_objs[idx])
225               pop_desc_set_ref(zds, &zds->res_objs[idx]->desc_set_refs.refs);
226            zds->res_objs[idx] = NULL;
227            break;
228         case ZINK_DESCRIPTOR_TYPE_IMAGE:
229            if (zds->surfaces[idx].is_buffer) {
230               if (zds->surfaces[idx].bufferview)
231                  pop_desc_set_ref(zds, &zds->surfaces[idx].bufferview->desc_set_refs.refs);
232               zds->surfaces[idx].bufferview = NULL;
233            } else {
234               if (zds->surfaces[idx].surface)
235                  pop_desc_set_ref(zds, &zds->surfaces[idx].surface->desc_set_refs.refs);
236               zds->surfaces[idx].surface = NULL;
237            }
238            break;
239         case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
240            if (zds->surfaces[idx].is_buffer) {
241               if (zds->surfaces[idx].bufferview)
242                  pop_desc_set_ref(zds, &zds->surfaces[idx].bufferview->desc_set_refs.refs);
243               zds->surfaces[idx].bufferview = NULL;
244            } else {
245               if (zds->surfaces[idx].surface)
246                  pop_desc_set_ref(zds, &zds->surfaces[idx].surface->desc_set_refs.refs);
247               zds->surfaces[idx].surface = NULL;
248            }
249            if (zds->sampler_states[idx])
250               pop_desc_set_ref(zds, &zds->sampler_states[idx]->desc_set_refs.refs);
251            zds->sampler_states[idx] = NULL;
252            break;
253         default:
254            break;
255         }
256         idx++;
257      }
258   }
259}
260
261static void
262descriptor_pool_clear(struct hash_table *ht)
263{
264   hash_table_foreach(ht, entry) {
265      struct zink_descriptor_set *zds = entry->data;
266      descriptor_set_invalidate(zds);
267   }
268}
269
270static void
271descriptor_pool_free(struct zink_screen *screen, struct zink_descriptor_pool *pool)
272{
273   if (!pool)
274      return;
275   if (pool->descpool)
276      VKSCR(DestroyDescriptorPool)(screen->dev, pool->descpool, NULL);
277
278   simple_mtx_lock(&pool->mtx);
279   if (pool->desc_sets)
280      descriptor_pool_clear(pool->desc_sets);
281   if (pool->free_desc_sets)
282      descriptor_pool_clear(pool->free_desc_sets);
283   if (pool->desc_sets)
284      _mesa_hash_table_destroy(pool->desc_sets, NULL);
285   if (pool->free_desc_sets)
286      _mesa_hash_table_destroy(pool->free_desc_sets, NULL);
287
288   simple_mtx_unlock(&pool->mtx);
289   util_dynarray_fini(&pool->alloc_desc_sets);
290   simple_mtx_destroy(&pool->mtx);
291   ralloc_free(pool);
292}
293
294static void
295descriptor_pool_delete(struct zink_context *ctx, struct zink_descriptor_pool *pool)
296{
297   struct zink_screen *screen = zink_screen(ctx->base.screen);
298   if (!pool)
299      return;
300   _mesa_hash_table_remove_key(ctx->dd->descriptor_pools[pool->type], pool->key);
301   descriptor_pool_free(screen, pool);
302}
303
304static struct zink_descriptor_pool *
305descriptor_pool_create(struct zink_screen *screen, enum zink_descriptor_type type,
306                       const struct zink_descriptor_pool_key *pool_key)
307{
308   struct zink_descriptor_pool *pool = rzalloc(NULL, struct zink_descriptor_pool);
309   if (!pool)
310      return NULL;
311   pipe_reference_init(&pool->reference, 1);
312   pool->type = type;
313   pool->key = pool_key;
314   simple_mtx_init(&pool->mtx, mtx_plain);
315   for (unsigned i = 0; i < pool_key->layout->num_bindings; i++) {
316       pool->num_resources += pool_key->layout->bindings[i].descriptorCount;
317   }
318   pool->desc_sets = _mesa_hash_table_create(NULL, desc_state_hash, desc_state_equal);
319   if (!pool->desc_sets)
320      goto fail;
321
322   pool->free_desc_sets = _mesa_hash_table_create(NULL, desc_state_hash, desc_state_equal);
323   if (!pool->free_desc_sets)
324      goto fail;
325
326   util_dynarray_init(&pool->alloc_desc_sets, NULL);
327
328   VkDescriptorPoolCreateInfo dpci = {0};
329   dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
330   dpci.pPoolSizes = pool_key->sizes;
331   dpci.poolSizeCount = pool_key->num_type_sizes;
332   dpci.flags = 0;
333   dpci.maxSets = ZINK_DEFAULT_MAX_DESCS;
334   assert(pool_key->num_type_sizes);
335   VkResult result = VKSCR(CreateDescriptorPool)(screen->dev, &dpci, 0, &pool->descpool);
336   if (result != VK_SUCCESS) {
337      mesa_loge("ZINK: vkCreateDescriptorPool failed (%s)", vk_Result_to_str(result));
338      goto fail;
339   }
340
341   return pool;
342fail:
343   descriptor_pool_free(screen, pool);
344   return NULL;
345}
346
347static VkDescriptorSetLayout
348descriptor_layout_create(struct zink_screen *screen, enum zink_descriptor_type t, VkDescriptorSetLayoutBinding *bindings, unsigned num_bindings)
349{
350   VkDescriptorSetLayout dsl;
351   VkDescriptorSetLayoutCreateInfo dcslci = {0};
352   dcslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
353   dcslci.pNext = NULL;
354   VkDescriptorSetLayoutBindingFlagsCreateInfo fci = {0};
355   VkDescriptorBindingFlags flags[ZINK_MAX_DESCRIPTORS_PER_TYPE];
356   if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_LAZY) {
357      dcslci.pNext = &fci;
358      if (t == ZINK_DESCRIPTOR_TYPES)
359         dcslci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
360      fci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
361      fci.bindingCount = num_bindings;
362      fci.pBindingFlags = flags;
363      for (unsigned i = 0; i < num_bindings; i++) {
364         flags[i] = 0;
365      }
366   }
367   dcslci.bindingCount = num_bindings;
368   dcslci.pBindings = bindings;
369   VkDescriptorSetLayoutSupport supp;
370   supp.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT;
371   supp.pNext = NULL;
372   supp.supported = VK_FALSE;
373   if (VKSCR(GetDescriptorSetLayoutSupport)) {
374      VKSCR(GetDescriptorSetLayoutSupport)(screen->dev, &dcslci, &supp);
375      if (supp.supported == VK_FALSE) {
376         debug_printf("vkGetDescriptorSetLayoutSupport claims layout is unsupported\n");
377         return VK_NULL_HANDLE;
378      }
379   }
380   VkResult result = VKSCR(CreateDescriptorSetLayout)(screen->dev, &dcslci, 0, &dsl);
381   if (result != VK_SUCCESS)
382      mesa_loge("ZINK: vkCreateDescriptorSetLayout failed (%s)", vk_Result_to_str(result));
383   return dsl;
384}
385
386static uint32_t
387hash_descriptor_layout(const void *key)
388{
389   uint32_t hash = 0;
390   const struct zink_descriptor_layout_key *k = key;
391   hash = XXH32(&k->num_bindings, sizeof(unsigned), hash);
392   /* only hash first 3 members: no holes and the rest are always constant */
393   for (unsigned i = 0; i < k->num_bindings; i++)
394      hash = XXH32(&k->bindings[i], offsetof(VkDescriptorSetLayoutBinding, stageFlags), hash);
395
396   return hash;
397}
398
399static bool
400equals_descriptor_layout(const void *a, const void *b)
401{
402   const struct zink_descriptor_layout_key *a_k = a;
403   const struct zink_descriptor_layout_key *b_k = b;
404   return a_k->num_bindings == b_k->num_bindings &&
405          !memcmp(a_k->bindings, b_k->bindings, a_k->num_bindings * sizeof(VkDescriptorSetLayoutBinding));
406}
407
408static struct zink_descriptor_layout *
409create_layout(struct zink_context *ctx, enum zink_descriptor_type type,
410              VkDescriptorSetLayoutBinding *bindings, unsigned num_bindings,
411              struct zink_descriptor_layout_key **layout_key)
412{
413   struct zink_screen *screen = zink_screen(ctx->base.screen);
414   VkDescriptorSetLayout dsl = descriptor_layout_create(screen, type, bindings, num_bindings);
415   if (!dsl)
416      return NULL;
417
418   struct zink_descriptor_layout_key *k = ralloc(ctx, struct zink_descriptor_layout_key);
419   k->num_bindings = num_bindings;
420   if (num_bindings) {
421      size_t bindings_size = num_bindings * sizeof(VkDescriptorSetLayoutBinding);
422      k->bindings = ralloc_size(k, bindings_size);
423      if (!k->bindings) {
424         ralloc_free(k);
425         VKSCR(DestroyDescriptorSetLayout)(screen->dev, dsl, NULL);
426         return NULL;
427      }
428      memcpy(k->bindings, bindings, bindings_size);
429   }
430
431   struct zink_descriptor_layout *layout = rzalloc(ctx, struct zink_descriptor_layout);
432   layout->layout = dsl;
433   *layout_key = k;
434   return layout;
435}
436
437struct zink_descriptor_layout *
438zink_descriptor_util_layout_get(struct zink_context *ctx, enum zink_descriptor_type type,
439                      VkDescriptorSetLayoutBinding *bindings, unsigned num_bindings,
440                      struct zink_descriptor_layout_key **layout_key)
441{
442   uint32_t hash = 0;
443   struct zink_descriptor_layout_key key = {
444      .num_bindings = num_bindings,
445      .bindings = bindings,
446   };
447
448   if (type != ZINK_DESCRIPTOR_TYPES) {
449      hash = hash_descriptor_layout(&key);
450      struct hash_entry *he = _mesa_hash_table_search_pre_hashed(&ctx->desc_set_layouts[type], hash, &key);
451      if (he) {
452         *layout_key = (void*)he->key;
453         return he->data;
454      }
455   }
456
457   struct zink_descriptor_layout *layout = create_layout(ctx, type, bindings, num_bindings, layout_key);
458   if (layout && type != ZINK_DESCRIPTOR_TYPES) {
459      _mesa_hash_table_insert_pre_hashed(&ctx->desc_set_layouts[type], hash, *layout_key, layout);
460   }
461   return layout;
462}
463
464
465static uint32_t
466hash_descriptor_pool_key(const void *key)
467{
468   uint32_t hash = 0;
469   const struct zink_descriptor_pool_key *k = key;
470   hash = XXH32(&k->layout, sizeof(void*), hash);
471   for (unsigned i = 0; i < k->num_type_sizes; i++)
472      hash = XXH32(&k->sizes[i], sizeof(VkDescriptorPoolSize), hash);
473
474   return hash;
475}
476
477static bool
478equals_descriptor_pool_key(const void *a, const void *b)
479{
480   const struct zink_descriptor_pool_key *a_k = a;
481   const struct zink_descriptor_pool_key *b_k = b;
482   const unsigned a_num_type_sizes = a_k->num_type_sizes;
483   const unsigned b_num_type_sizes = b_k->num_type_sizes;
484   return a_k->layout == b_k->layout &&
485          a_num_type_sizes == b_num_type_sizes &&
486          !memcmp(a_k->sizes, b_k->sizes, b_num_type_sizes * sizeof(VkDescriptorPoolSize));
487}
488
489struct zink_descriptor_pool_key *
490zink_descriptor_util_pool_key_get(struct zink_context *ctx, enum zink_descriptor_type type,
491                                  struct zink_descriptor_layout_key *layout_key,
492                                  VkDescriptorPoolSize *sizes, unsigned num_type_sizes)
493{
494   uint32_t hash = 0;
495   struct zink_descriptor_pool_key key;
496   key.num_type_sizes = num_type_sizes;
497   if (type != ZINK_DESCRIPTOR_TYPES) {
498      key.layout = layout_key;
499      memcpy(key.sizes, sizes, num_type_sizes * sizeof(VkDescriptorPoolSize));
500      hash = hash_descriptor_pool_key(&key);
501      struct set_entry *he = _mesa_set_search_pre_hashed(&ctx->desc_pool_keys[type], hash, &key);
502      if (he)
503         return (void*)he->key;
504   }
505
506   struct zink_descriptor_pool_key *pool_key = rzalloc(ctx, struct zink_descriptor_pool_key);
507   pool_key->layout = layout_key;
508   pool_key->num_type_sizes = num_type_sizes;
509   assert(pool_key->num_type_sizes);
510   memcpy(pool_key->sizes, sizes, num_type_sizes * sizeof(VkDescriptorPoolSize));
511   if (type != ZINK_DESCRIPTOR_TYPES)
512      _mesa_set_add_pre_hashed(&ctx->desc_pool_keys[type], hash, pool_key);
513   return pool_key;
514}
515
516static void
517init_push_binding(VkDescriptorSetLayoutBinding *binding, unsigned i, VkDescriptorType type)
518{
519   binding->binding = tgsi_processor_to_shader_stage(i);
520   binding->descriptorType = type;
521   binding->descriptorCount = 1;
522   binding->stageFlags = zink_shader_stage(i);
523   binding->pImmutableSamplers = NULL;
524}
525
526static VkDescriptorType
527get_push_types(struct zink_screen *screen, enum zink_descriptor_type *dsl_type)
528{
529   *dsl_type = zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_LAZY &&
530               screen->info.have_KHR_push_descriptor ? ZINK_DESCRIPTOR_TYPES : ZINK_DESCRIPTOR_TYPE_UBO;
531   return zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_LAZY ?
532          VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
533}
534
535static struct zink_descriptor_layout *
536create_gfx_layout(struct zink_context *ctx, struct zink_descriptor_layout_key **layout_key, bool fbfetch)
537{
538   struct zink_screen *screen = zink_screen(ctx->base.screen);
539   VkDescriptorSetLayoutBinding bindings[PIPE_SHADER_TYPES];
540   enum zink_descriptor_type dsl_type;
541   VkDescriptorType vktype = get_push_types(screen, &dsl_type);
542   for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++)
543      init_push_binding(&bindings[i], i, vktype);
544   if (fbfetch) {
545      bindings[ZINK_SHADER_COUNT].binding = ZINK_FBFETCH_BINDING;
546      bindings[ZINK_SHADER_COUNT].descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
547      bindings[ZINK_SHADER_COUNT].descriptorCount = 1;
548      bindings[ZINK_SHADER_COUNT].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
549      bindings[ZINK_SHADER_COUNT].pImmutableSamplers = NULL;
550   }
551   return create_layout(ctx, dsl_type, bindings, fbfetch ? ARRAY_SIZE(bindings) : ARRAY_SIZE(bindings) - 1, layout_key);
552}
553
554bool
555zink_descriptor_util_push_layouts_get(struct zink_context *ctx, struct zink_descriptor_layout **dsls, struct zink_descriptor_layout_key **layout_keys)
556{
557   struct zink_screen *screen = zink_screen(ctx->base.screen);
558   VkDescriptorSetLayoutBinding compute_binding;
559   enum zink_descriptor_type dsl_type;
560   VkDescriptorType vktype = get_push_types(screen, &dsl_type);
561   init_push_binding(&compute_binding, PIPE_SHADER_COMPUTE, vktype);
562   dsls[0] = create_gfx_layout(ctx, &layout_keys[0], false);
563   dsls[1] = create_layout(ctx, dsl_type, &compute_binding, 1, &layout_keys[1]);
564   return dsls[0] && dsls[1];
565}
566
567VkImageLayout
568zink_descriptor_util_image_layout_eval(const struct zink_context *ctx, const struct zink_resource *res, bool is_compute)
569{
570   if (res->bindless[0] || res->bindless[1]) {
571      /* bindless needs most permissive layout */
572      if (res->image_bind_count[0] || res->image_bind_count[1])
573         return VK_IMAGE_LAYOUT_GENERAL;
574      return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
575   }
576   if (res->image_bind_count[is_compute])
577      return VK_IMAGE_LAYOUT_GENERAL;
578   if (res->aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
579      if (!is_compute && res->fb_binds &&
580          ctx->gfx_pipeline_state.render_pass && ctx->gfx_pipeline_state.render_pass->state.rts[ctx->fb_state.nr_cbufs].mixed_zs)
581         return VK_IMAGE_LAYOUT_GENERAL;
582      if (res->obj->vkusage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
583         return VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
584   }
585   return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
586}
587
588static struct zink_descriptor_pool *
589descriptor_pool_get(struct zink_context *ctx, enum zink_descriptor_type type,
590                    const struct zink_descriptor_pool_key *pool_key)
591{
592   uint32_t hash = 0;
593   if (type != ZINK_DESCRIPTOR_TYPES) {
594      hash = hash_descriptor_pool_key(pool_key);
595      struct hash_entry *he = _mesa_hash_table_search_pre_hashed(ctx->dd->descriptor_pools[type], hash, pool_key);
596      if (he) {
597         struct zink_descriptor_pool *pool = he->data;
598         pipe_reference(NULL, &pool->reference);
599         return pool;
600      }
601   }
602   struct zink_descriptor_pool *pool = descriptor_pool_create(zink_screen(ctx->base.screen), type, pool_key);
603   if (type != ZINK_DESCRIPTOR_TYPES)
604      _mesa_hash_table_insert_pre_hashed(ctx->dd->descriptor_pools[type], hash, pool_key, pool);
605   return pool;
606}
607
608static bool
609get_invalidated_desc_set(struct zink_descriptor_set *zds)
610{
611   if (!zds->invalid)
612      return false;
613   return p_atomic_read(&zds->reference.count) == 1;
614}
615
616bool
617zink_descriptor_util_alloc_sets(struct zink_screen *screen, VkDescriptorSetLayout dsl, VkDescriptorPool pool, VkDescriptorSet *sets, unsigned num_sets)
618{
619   VkDescriptorSetAllocateInfo dsai;
620   VkDescriptorSetLayout *layouts = alloca(sizeof(*layouts) * num_sets);
621   memset((void *)&dsai, 0, sizeof(dsai));
622   dsai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
623   dsai.pNext = NULL;
624   dsai.descriptorPool = pool;
625   dsai.descriptorSetCount = num_sets;
626   for (unsigned i = 0; i < num_sets; i ++)
627      layouts[i] = dsl;
628   dsai.pSetLayouts = layouts;
629
630   VkResult result = VKSCR(AllocateDescriptorSets)(screen->dev, &dsai, sets);
631   if (result != VK_SUCCESS) {
632      mesa_loge("ZINK: %" PRIu64 " failed to allocate descriptor set :/ (%s)", (uint64_t)dsl, vk_Result_to_str(result));
633      return false;
634   }
635   return true;
636}
637
638static struct zink_descriptor_set *
639allocate_desc_set(struct zink_context *ctx, struct zink_program *pg, enum zink_descriptor_type type, unsigned descs_used, bool is_compute)
640{
641   struct zink_screen *screen = zink_screen(ctx->base.screen);
642   bool push_set = type == ZINK_DESCRIPTOR_TYPES;
643   struct zink_descriptor_pool *pool = push_set ? ctx->dd->push_pool[is_compute] : pdd_cached(pg)->pool[type];
644#define DESC_BUCKET_FACTOR 10
645   unsigned bucket_size = pool->key->layout->num_bindings ? DESC_BUCKET_FACTOR : 1;
646   if (pool->key->layout->num_bindings) {
647      for (unsigned desc_factor = DESC_BUCKET_FACTOR; desc_factor < descs_used; desc_factor *= DESC_BUCKET_FACTOR)
648         bucket_size = desc_factor;
649   }
650   /* never grow more than this many at a time */
651   bucket_size = MIN2(bucket_size, ZINK_DEFAULT_MAX_DESCS);
652   VkDescriptorSet *desc_set = alloca(sizeof(*desc_set) * bucket_size);
653   if (!zink_descriptor_util_alloc_sets(screen, push_set ? ctx->dd->push_dsl[is_compute]->layout : pg->dsl[type + 1], pool->descpool, desc_set, bucket_size))
654      return VK_NULL_HANDLE;
655
656   struct zink_descriptor_set *alloc = ralloc_array(pool, struct zink_descriptor_set, bucket_size);
657   assert(alloc);
658   unsigned num_resources = pool->num_resources;
659   struct zink_resource_object **res_objs = NULL;
660   void **samplers = NULL;
661   struct zink_descriptor_surface *surfaces = NULL;
662   switch (type) {
663   case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
664      samplers = rzalloc_array(pool, void*, num_resources * bucket_size);
665      assert(samplers);
666      FALLTHROUGH;
667   case ZINK_DESCRIPTOR_TYPE_IMAGE:
668      surfaces = rzalloc_array(pool, struct zink_descriptor_surface, num_resources * bucket_size);
669      assert(surfaces);
670      break;
671   default:
672      res_objs = rzalloc_array(pool, struct zink_resource_object*, num_resources * bucket_size);
673      assert(res_objs);
674      break;
675   }
676   for (unsigned i = 0; i < bucket_size; i ++) {
677      struct zink_descriptor_set *zds = &alloc[i];
678      pipe_reference_init(&zds->reference, 1);
679      zds->pool = pool;
680      zds->hash = 0;
681      zds->batch_uses = NULL;
682      zds->invalid = true;
683      zds->punted = zds->recycled = false;
684#ifndef NDEBUG
685      zds->num_resources = num_resources;
686#endif
687      switch (type) {
688      case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
689         zds->sampler_states = (struct zink_sampler_state**)&samplers[i * num_resources];
690         FALLTHROUGH;
691      case ZINK_DESCRIPTOR_TYPE_IMAGE:
692         zds->surfaces = &surfaces[i * num_resources];
693         break;
694      default:
695         zds->res_objs = (struct zink_resource_object**)&res_objs[i * num_resources];
696         break;
697      }
698      zds->desc_set = desc_set[i];
699      if (i > 0)
700         util_dynarray_append(&pool->alloc_desc_sets, struct zink_descriptor_set *, zds);
701   }
702   pool->num_sets_allocated += bucket_size;
703   return alloc;
704}
705
706static void
707populate_zds_key(struct zink_context *ctx, enum zink_descriptor_type type, bool is_compute,
708                 struct zink_descriptor_state_key *key, uint32_t push_usage)
709{
710   if (is_compute) {
711      for (unsigned i = 1; i < ZINK_SHADER_COUNT; i++)
712         key->exists[i] = false;
713      key->exists[0] = true;
714      if (type == ZINK_DESCRIPTOR_TYPES)
715         key->state[0] = ctx->dd->push_state[is_compute];
716      else {
717         assert(ctx->dd->descriptor_states[is_compute].valid[type]);
718         key->state[0] = ctx->dd->descriptor_states[is_compute].state[type];
719      }
720   } else if (type == ZINK_DESCRIPTOR_TYPES) {
721      /* gfx only */
722      for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) {
723         if (push_usage & BITFIELD_BIT(i)) {
724            key->exists[i] = true;
725            key->state[i] = ctx->dd->gfx_push_state[i];
726         } else
727            key->exists[i] = false;
728      }
729   } else {
730      for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) {
731         key->exists[i] = ctx->dd->gfx_descriptor_states[i].valid[type];
732         key->state[i] = ctx->dd->gfx_descriptor_states[i].state[type];
733      }
734   }
735}
736
737static void
738populate_zds_key_compact(struct zink_context *ctx, enum zink_descriptor_type type, bool is_compute,
739                         struct zink_descriptor_state_key *key, uint32_t push_usage)
740{
741   if (is_compute) {
742      for (unsigned i = 1; i < ZINK_SHADER_COUNT; i++)
743         key->exists[i] = false;
744      key->exists[0] = true;
745      if (type == ZINK_DESCRIPTOR_TYPES)
746         key->state[0] = ctx->dd->push_state[is_compute];
747      else {
748         assert(ctx->dd->compact_descriptor_states[is_compute].valid[type]);
749         key->state[0] = ctx->dd->compact_descriptor_states[is_compute].state[type];
750      }
751   } else if (type == ZINK_DESCRIPTOR_TYPES) {
752      /* gfx only */
753      for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) {
754         if (push_usage & BITFIELD_BIT(i)) {
755            key->exists[i] = true;
756            key->state[i] = ctx->dd->gfx_push_state[i];
757         } else
758            key->exists[i] = false;
759      }
760   } else {
761      for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) {
762         key->exists[i] = ctx->dd->compact_gfx_descriptor_states[i].valid[type];
763         key->state[i] = ctx->dd->compact_gfx_descriptor_states[i].state[type];
764      }
765   }
766}
767
768static void
769punt_invalid_set(struct zink_descriptor_set *zds, struct hash_entry *he)
770{
771   /* this is no longer usable, so we punt it for now until it gets recycled */
772   assert(!zds->recycled);
773   if (!he)
774      he = _mesa_hash_table_search_pre_hashed(zds->pool->desc_sets, zds->hash, &zds->key);
775   _mesa_hash_table_remove(zds->pool->desc_sets, he);
776   zds->punted = true;
777}
778
779static struct zink_descriptor_set *
780zink_descriptor_set_get(struct zink_context *ctx,
781                               enum zink_descriptor_type type,
782                               bool is_compute,
783                               bool *cache_hit)
784{
785   *cache_hit = false;
786   struct zink_screen *screen = zink_screen(ctx->base.screen);
787   struct zink_descriptor_set *zds;
788   struct zink_program *pg = is_compute ? (struct zink_program *)ctx->curr_compute : (struct zink_program *)ctx->curr_program;
789   struct zink_batch *batch = &ctx->batch;
790   bool push_set = type == ZINK_DESCRIPTOR_TYPES;
791   struct zink_descriptor_pool *pool = push_set ? ctx->dd->push_pool[is_compute] : pdd_cached(pg)->pool[type];
792   unsigned descs_used = 1;
793   assert(type <= ZINK_DESCRIPTOR_TYPES);
794
795   assert(pool->key->layout->num_bindings);
796   assert(!screen->compact_descriptors || (type != ZINK_DESCRIPTOR_TYPE_SSBO && type != ZINK_DESCRIPTOR_TYPE_IMAGE));
797   uint32_t hash = push_set ? ctx->dd->push_state[is_compute] :
798                              screen->compact_descriptors ?
799                              ctx->dd->compact_descriptor_states[is_compute].state[type] :
800                              ctx->dd->descriptor_states[is_compute].state[type];
801
802   struct zink_descriptor_set *last_set = push_set ? ctx->dd->last_set[is_compute] : pdd_cached(pg)->last_set[type];
803   /* if the current state hasn't changed since the last time it was used,
804    * it's impossible for this set to not be valid, which means that an
805    * early return here can be done safely and with no locking
806    */
807   if (last_set && ((push_set && !ctx->dd->changed[is_compute][ZINK_DESCRIPTOR_TYPES]) ||
808                    (!push_set && (screen->compact_descriptors ?
809                                   !ctx->dd->changed[is_compute][type] && !ctx->dd->changed[is_compute][type+ZINK_DESCRIPTOR_COMPACT] :
810                                   !ctx->dd->changed[is_compute][type])))) {
811      *cache_hit = true;
812      return last_set;
813   }
814
815   struct zink_descriptor_state_key key;
816   if (screen->compact_descriptors)
817      populate_zds_key_compact(ctx, type, is_compute, &key, pg->dd->push_usage);
818   else
819      populate_zds_key(ctx, type, is_compute, &key, pg->dd->push_usage);
820
821   simple_mtx_lock(&pool->mtx);
822   if (last_set && last_set->hash == hash && desc_state_equal(&last_set->key, &key)) {
823      bool was_recycled = false;
824      zds = last_set;
825      *cache_hit = !zds->invalid;
826      if (zds->recycled) {
827         struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pool->free_desc_sets, hash, &key);
828         if (he) {
829            was_recycled = true;
830            _mesa_hash_table_remove(pool->free_desc_sets, he);
831         }
832         zds->recycled = false;
833      }
834      if (zds->invalid) {
835          if (zink_batch_usage_exists(zds->batch_uses))
836             punt_invalid_set(zds, NULL);
837          else {
838             if (was_recycled) {
839                descriptor_set_invalidate(zds);
840                goto out;
841             }
842             /* this set is guaranteed to be in pool->alloc_desc_sets */
843             goto skip_hash_tables;
844          }
845          zds = NULL;
846      }
847      if (zds)
848         goto out;
849   }
850
851   struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pool->desc_sets, hash, &key);
852   bool recycled = false, punted = false;
853   if (he) {
854       zds = (void*)he->data;
855       if (zds->invalid && zink_batch_usage_exists(zds->batch_uses)) {
856          punt_invalid_set(zds, he);
857          zds = NULL;
858          punted = true;
859       }
860   }
861   if (!he) {
862      he = _mesa_hash_table_search_pre_hashed(pool->free_desc_sets, hash, &key);
863      recycled = true;
864   }
865   if (he && !punted) {
866      zds = (void*)he->data;
867      *cache_hit = !zds->invalid;
868      if (recycled) {
869         if (zds->invalid)
870            descriptor_set_invalidate(zds);
871         /* need to migrate this entry back to the in-use hash */
872         _mesa_hash_table_remove(pool->free_desc_sets, he);
873         goto out;
874      }
875      goto quick_out;
876   }
877skip_hash_tables:
878   if (util_dynarray_num_elements(&pool->alloc_desc_sets, struct zink_descriptor_set *)) {
879      /* grab one off the allocated array */
880      zds = util_dynarray_pop(&pool->alloc_desc_sets, struct zink_descriptor_set *);
881      goto out;
882   }
883
884   if (_mesa_hash_table_num_entries(pool->free_desc_sets)) {
885      /* try for an invalidated set first */
886      unsigned count = 0;
887      hash_table_foreach(pool->free_desc_sets, he) {
888         struct zink_descriptor_set *tmp = he->data;
889         if ((count++ >= 100 && tmp->reference.count == 1) || get_invalidated_desc_set(he->data)) {
890            zds = tmp;
891            assert(p_atomic_read(&zds->reference.count) == 1);
892            descriptor_set_invalidate(zds);
893            _mesa_hash_table_remove(pool->free_desc_sets, he);
894            goto out;
895         }
896      }
897   }
898
899   assert(pool->num_sets_allocated < ZINK_DEFAULT_MAX_DESCS);
900
901   zds = allocate_desc_set(ctx, pg, type, descs_used, is_compute);
902out:
903   if (unlikely(pool->num_sets_allocated >= ZINK_DEFAULT_DESC_CLAMP &&
904                _mesa_hash_table_num_entries(pool->free_desc_sets) < ZINK_DEFAULT_MAX_DESCS - ZINK_DEFAULT_DESC_CLAMP))
905      ctx->oom_flush = ctx->oom_stall = true;
906   zds->hash = hash;
907   if (screen->compact_descriptors)
908      populate_zds_key_compact(ctx, type, is_compute, &zds->key, pg->dd->push_usage);
909   else
910      populate_zds_key(ctx, type, is_compute, &zds->key, pg->dd->push_usage);
911   zds->recycled = false;
912   _mesa_hash_table_insert_pre_hashed(pool->desc_sets, hash, &zds->key, zds);
913quick_out:
914   if (!push_set) {
915      if (screen->compact_descriptors) {
916         if (zink_desc_type_from_vktype(pool->key->sizes[0].type) == type)
917            zds->compacted |= BITFIELD_BIT(type);
918         for (unsigned i = 0; i < pool->key->num_type_sizes; i++) {
919            if (zink_desc_type_from_vktype(pool->key->sizes[0].type) == type + ZINK_DESCRIPTOR_COMPACT) {
920               zds->compacted |= BITFIELD_BIT(type + ZINK_DESCRIPTOR_COMPACT);
921               break;
922            }
923         }
924      } else
925         zds->compacted |= BITFIELD_BIT(type);
926   }
927   zds->punted = zds->invalid = false;
928   batch_add_desc_set(batch, zds);
929   if (push_set)
930      ctx->dd->last_set[is_compute] = zds;
931   else
932      pdd_cached(pg)->last_set[type] = zds;
933   simple_mtx_unlock(&pool->mtx);
934
935   return zds;
936}
937
938void
939zink_descriptor_set_recycle(struct zink_descriptor_set *zds)
940{
941   struct zink_descriptor_pool *pool = zds->pool;
942   /* if desc set is still in use by a batch, don't recache */
943   uint32_t refcount = p_atomic_read(&zds->reference.count);
944   if (refcount != 1)
945      return;
946   /* this is a null set */
947   if (!pool->key->layout->num_bindings)
948      return;
949   simple_mtx_lock(&pool->mtx);
950   if (zds->punted)
951      zds->invalid = true;
952   else {
953      /* if we've previously punted this set, then it won't have a hash or be in either of the tables */
954      struct hash_entry *he = _mesa_hash_table_search_pre_hashed(pool->desc_sets, zds->hash, &zds->key);
955      if (!he) {
956         /* desc sets can be used multiple times in the same batch */
957         simple_mtx_unlock(&pool->mtx);
958         return;
959      }
960      _mesa_hash_table_remove(pool->desc_sets, he);
961   }
962
963   if (zds->invalid) {
964      descriptor_set_invalidate(zds);
965      util_dynarray_append(&pool->alloc_desc_sets, struct zink_descriptor_set *, zds);
966   } else {
967      zds->recycled = true;
968      _mesa_hash_table_insert_pre_hashed(pool->free_desc_sets, zds->hash, &zds->key, zds);
969   }
970   simple_mtx_unlock(&pool->mtx);
971}
972
973
974static void
975desc_set_ref_add(struct zink_descriptor_set *zds, struct zink_descriptor_refs *refs, void **ref_ptr, void *ptr)
976{
977   struct zink_descriptor_reference ref = {ref_ptr, &zds->invalid};
978   *ref_ptr = ptr;
979   if (ptr)
980      util_dynarray_append(&refs->refs, struct zink_descriptor_reference, ref);
981}
982
983static void
984zink_descriptor_surface_desc_set_add(struct zink_descriptor_surface *dsurf, struct zink_descriptor_set *zds, unsigned idx)
985{
986   assert(idx < zds->num_resources);
987   zds->surfaces[idx].is_buffer = dsurf->is_buffer;
988   if (dsurf->is_buffer)
989      desc_set_ref_add(zds, &dsurf->bufferview->desc_set_refs, (void**)&zds->surfaces[idx].bufferview, dsurf->bufferview);
990   else
991      desc_set_ref_add(zds, &dsurf->surface->desc_set_refs, (void**)&zds->surfaces[idx].surface, dsurf->surface);
992}
993
994static void
995zink_image_view_desc_set_add(struct zink_image_view *image_view, struct zink_descriptor_set *zds, unsigned idx, bool is_buffer)
996{
997   assert(idx < zds->num_resources);
998   if (is_buffer)
999      desc_set_ref_add(zds, &image_view->buffer_view->desc_set_refs, (void**)&zds->surfaces[idx].bufferview, image_view->buffer_view);
1000   else
1001      desc_set_ref_add(zds, &image_view->surface->desc_set_refs, (void**)&zds->surfaces[idx].surface, image_view->surface);
1002}
1003
1004static void
1005zink_sampler_state_desc_set_add(struct zink_sampler_state *sampler_state, struct zink_descriptor_set *zds, unsigned idx)
1006{
1007   assert(idx < zds->num_resources);
1008   if (sampler_state)
1009      desc_set_ref_add(zds, &sampler_state->desc_set_refs, (void**)&zds->sampler_states[idx], sampler_state);
1010   else
1011      zds->sampler_states[idx] = NULL;
1012}
1013
1014static void
1015zink_resource_desc_set_add(struct zink_resource *res, struct zink_descriptor_set *zds, unsigned idx)
1016{
1017   assert(idx < zds->num_resources);
1018   desc_set_ref_add(zds, res ? &res->obj->desc_set_refs : NULL, (void**)&zds->res_objs[idx], res ? res->obj : NULL);
1019}
1020
1021void
1022zink_descriptor_set_refs_clear(struct zink_descriptor_refs *refs, void *ptr)
1023{
1024   util_dynarray_foreach(&refs->refs, struct zink_descriptor_reference, ref) {
1025      if (*ref->ref == ptr) {
1026         *ref->invalid = true;
1027         *ref->ref = NULL;
1028      }
1029   }
1030   util_dynarray_fini(&refs->refs);
1031}
1032
1033static inline void
1034zink_descriptor_pool_reference(struct zink_context *ctx,
1035                               struct zink_descriptor_pool **dst,
1036                               struct zink_descriptor_pool *src)
1037{
1038   struct zink_descriptor_pool *old_dst = dst ? *dst : NULL;
1039
1040   if (pipe_reference_described(old_dst ? &old_dst->reference : NULL, &src->reference,
1041                                (debug_reference_descriptor)debug_describe_zink_descriptor_pool))
1042      descriptor_pool_delete(ctx, old_dst);
1043   if (dst) *dst = src;
1044}
1045
1046static void
1047create_descriptor_ref_template(struct zink_context *ctx, struct zink_program *pg)
1048{
1049   struct zink_shader **stages;
1050   if (pg->is_compute)
1051      stages = &((struct zink_compute_program*)pg)->shader;
1052   else
1053      stages = ((struct zink_gfx_program*)pg)->shaders;
1054   unsigned num_shaders = pg->is_compute ? 1 : ZINK_SHADER_COUNT;
1055
1056   for (unsigned type = 0; type < ZINK_DESCRIPTOR_TYPES; type++) {
1057      for (int i = 0; i < num_shaders; i++) {
1058         struct zink_shader *shader = stages[i];
1059         if (!shader)
1060            continue;
1061
1062         for (int j = 0; j < shader->num_bindings[type]; j++) {
1063             int index = shader->bindings[type][j].index;
1064             if (type == ZINK_DESCRIPTOR_TYPE_UBO && !index)
1065                continue;
1066             pdd_cached(pg)->num_refs[type] += shader->bindings[type][j].size;
1067         }
1068      }
1069
1070      if (!pdd_cached(pg)->num_refs[type])
1071         continue;
1072
1073      pdd_cached(pg)->refs[type] = ralloc_array(pg->dd, union zink_program_descriptor_refs, pdd_cached(pg)->num_refs[type]);
1074      if (!pdd_cached(pg)->refs[type])
1075         return;
1076
1077      unsigned ref_idx = 0;
1078      for (int i = 0; i < num_shaders; i++) {
1079         struct zink_shader *shader = stages[i];
1080         if (!shader)
1081            continue;
1082
1083         enum pipe_shader_type stage = pipe_shader_type_from_mesa(shader->nir->info.stage);
1084         for (int j = 0; j < shader->num_bindings[type]; j++) {
1085            int index = shader->bindings[type][j].index;
1086            for (unsigned k = 0; k < shader->bindings[type][j].size; k++) {
1087               switch (type) {
1088               case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
1089                  pdd_cached(pg)->refs[type][ref_idx].sampler.sampler_state = (struct zink_sampler_state**)&ctx->sampler_states[stage][index + k];
1090                  pdd_cached(pg)->refs[type][ref_idx].sampler.dsurf = &ctx->di.sampler_surfaces[stage][index + k];
1091                  break;
1092               case ZINK_DESCRIPTOR_TYPE_IMAGE:
1093                  pdd_cached(pg)->refs[type][ref_idx].dsurf = &ctx->di.image_surfaces[stage][index + k];
1094                  break;
1095               case ZINK_DESCRIPTOR_TYPE_UBO:
1096                  if (!index)
1097                     continue;
1098                  FALLTHROUGH;
1099               default:
1100                  pdd_cached(pg)->refs[type][ref_idx].res = &ctx->di.descriptor_res[type][stage][index + k];
1101                  break;
1102               }
1103               assert(ref_idx < pdd_cached(pg)->num_refs[type]);
1104               ref_idx++;
1105            }
1106         }
1107      }
1108   }
1109}
1110
1111bool
1112zink_descriptor_program_init(struct zink_context *ctx, struct zink_program *pg)
1113{
1114   struct zink_screen *screen = zink_screen(ctx->base.screen);
1115
1116   pg->dd = (void*)rzalloc(pg, struct zink_program_descriptor_data_cached);
1117   if (!pg->dd)
1118      return false;
1119
1120   if (!zink_descriptor_program_init_lazy(ctx, pg))
1121      return false;
1122
1123   /* no descriptors */
1124   if (!pg->dd)
1125      return true;
1126
1127   bool has_pools = false;
1128   for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) {
1129      if (!pg->dd->pool_key[i])
1130         continue;
1131
1132      const struct zink_descriptor_pool_key *pool_key = pg->dd->pool_key[i];
1133      struct zink_descriptor_pool *pool = descriptor_pool_get(ctx, i, pool_key);
1134      if (!pool)
1135         return false;
1136      pdd_cached(pg)->pool[i] = pool;
1137      has_pools = true;
1138   }
1139   if (has_pools && screen->info.have_KHR_descriptor_update_template &&
1140       zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_NOTEMPLATES)
1141      create_descriptor_ref_template(ctx, pg);
1142
1143   return true;
1144}
1145
1146void
1147zink_descriptor_program_deinit(struct zink_context *ctx, struct zink_program *pg)
1148{
1149   if (!pg->dd)
1150      return;
1151   for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++)
1152      zink_descriptor_pool_reference(ctx, &pdd_cached(pg)->pool[i], NULL);
1153
1154   zink_descriptor_program_deinit_lazy(ctx, pg);
1155}
1156
1157static void
1158zink_descriptor_pool_deinit(struct zink_context *ctx)
1159{
1160   for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) {
1161      /* do not free: programs own these pools */
1162      _mesa_hash_table_destroy(ctx->dd->descriptor_pools[i], NULL);
1163   }
1164   descriptor_pool_free(zink_screen(ctx->base.screen), ctx->dd->push_pool[0]);
1165   descriptor_pool_free(zink_screen(ctx->base.screen), ctx->dd->push_pool[1]);
1166}
1167
1168static bool
1169zink_descriptor_pool_init(struct zink_context *ctx)
1170{
1171   for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) {
1172      ctx->dd->descriptor_pools[i] = _mesa_hash_table_create(ctx, hash_descriptor_pool_key, equals_descriptor_pool_key);
1173      if (!ctx->dd->descriptor_pools[i])
1174         return false;
1175   }
1176   VkDescriptorPoolSize sizes[2];
1177   sizes[0].type = zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_LAZY ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
1178   sizes[0].descriptorCount = ZINK_SHADER_COUNT * ZINK_DEFAULT_MAX_DESCS;
1179   sizes[1].type = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
1180   sizes[1].descriptorCount = ZINK_DEFAULT_MAX_DESCS;
1181   /* these are freed by ralloc */
1182   struct zink_descriptor_pool_key *pool_key;
1183   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);
1184   ctx->dd->push_pool[0] = descriptor_pool_get(ctx, 0, pool_key);
1185   sizes[0].descriptorCount = ZINK_DEFAULT_MAX_DESCS;
1186   pool_key = zink_descriptor_util_pool_key_get(ctx, ZINK_DESCRIPTOR_TYPES, ctx->dd->push_layout_keys[1], sizes, 1);
1187   ctx->dd->push_pool[1] = descriptor_pool_get(ctx, 0, pool_key);
1188   return ctx->dd->push_pool[0] && ctx->dd->push_pool[1];
1189}
1190
1191
1192static void
1193desc_set_res_add(struct zink_descriptor_set *zds, struct zink_resource *res, unsigned int i, bool cache_hit)
1194{
1195   /* if we got a cache hit, we have to verify that the cached set is still valid;
1196    * we store the vk resource to the set here to avoid a more complex and costly mechanism of maintaining a
1197    * hash table on every resource with the associated descriptor sets that then needs to be iterated through
1198    * whenever a resource is destroyed
1199    */
1200   assert(!cache_hit || zds->res_objs[i] == (res ? res->obj : NULL));
1201   if (!cache_hit)
1202      zink_resource_desc_set_add(res, zds, i);
1203}
1204
1205static void
1206desc_set_sampler_add(struct zink_context *ctx, struct zink_descriptor_set *zds, struct zink_descriptor_surface *dsurf,
1207                     struct zink_sampler_state *state, unsigned int i, bool cache_hit)
1208{
1209   /* if we got a cache hit, we have to verify that the cached set is still valid;
1210    * we store the vk resource to the set here to avoid a more complex and costly mechanism of maintaining a
1211    * hash table on every resource with the associated descriptor sets that then needs to be iterated through
1212    * whenever a resource is destroyed
1213    */
1214#ifndef NDEBUG
1215   uint32_t cur_hash = get_descriptor_surface_hash(ctx, &zds->surfaces[i]);
1216   uint32_t new_hash = get_descriptor_surface_hash(ctx, dsurf);
1217#endif
1218   assert(!cache_hit || cur_hash == new_hash);
1219   assert(!cache_hit || zds->sampler_states[i] == state);
1220   if (!cache_hit) {
1221      zink_descriptor_surface_desc_set_add(dsurf, zds, i);
1222      zink_sampler_state_desc_set_add(state, zds, i);
1223   }
1224}
1225
1226static void
1227desc_set_image_add(struct zink_context *ctx, struct zink_descriptor_set *zds, struct zink_descriptor_surface *dsurf,
1228                   unsigned int i, bool cache_hit)
1229{
1230   /* if we got a cache hit, we have to verify that the cached set is still valid;
1231    * we store the vk resource to the set here to avoid a more complex and costly mechanism of maintaining a
1232    * hash table on every resource with the associated descriptor sets that then needs to be iterated through
1233    * whenever a resource is destroyed
1234    */
1235#ifndef NDEBUG
1236   uint32_t cur_hash = get_descriptor_surface_hash(ctx, &zds->surfaces[i]);
1237   uint32_t new_hash = get_descriptor_surface_hash(ctx, dsurf);
1238#endif
1239   assert(!cache_hit || cur_hash == new_hash);
1240   if (!cache_hit)
1241      zink_descriptor_surface_desc_set_add(dsurf, zds, i);
1242}
1243
1244static void
1245desc_set_descriptor_surface_add(struct zink_context *ctx, struct zink_descriptor_set *zds, struct zink_descriptor_surface *dsurf,
1246                   unsigned int i, bool cache_hit)
1247{
1248   /* if we got a cache hit, we have to verify that the cached set is still valid;
1249    * we store the vk resource to the set here to avoid a more complex and costly mechanism of maintaining a
1250    * hash table on every resource with the associated descriptor sets that then needs to be iterated through
1251    * whenever a resource is destroyed
1252    */
1253#ifndef NDEBUG
1254   uint32_t cur_hash = get_descriptor_surface_hash(ctx, &zds->surfaces[i]);
1255   uint32_t new_hash = get_descriptor_surface_hash(ctx, dsurf);
1256#endif
1257   assert(!cache_hit || cur_hash == new_hash);
1258   if (!cache_hit)
1259      zink_descriptor_surface_desc_set_add(dsurf, zds, i);
1260}
1261
1262static unsigned
1263init_write_descriptor(struct zink_shader *shader, VkDescriptorSet desc_set, enum zink_descriptor_type type, int idx, VkWriteDescriptorSet *wd, unsigned num_wds)
1264{
1265    wd->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1266    wd->pNext = NULL;
1267    wd->dstBinding = shader ? shader->bindings[type][idx].binding : idx;
1268    wd->dstArrayElement = 0;
1269    wd->descriptorCount = shader ? shader->bindings[type][idx].size : 1;
1270    wd->descriptorType = shader ? shader->bindings[type][idx].type :
1271                                  idx == ZINK_FBFETCH_BINDING ? VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
1272    wd->dstSet = desc_set;
1273    return num_wds + 1;
1274}
1275
1276static unsigned
1277update_push_ubo_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zds,
1278                            VkDescriptorSet desc_set,
1279                            bool is_compute, bool cache_hit, uint32_t *dynamic_offsets)
1280{
1281   struct zink_screen *screen = zink_screen(ctx->base.screen);
1282   VkWriteDescriptorSet wds[ZINK_SHADER_COUNT + 1];
1283   VkDescriptorBufferInfo buffer_infos[ZINK_SHADER_COUNT];
1284   struct zink_shader **stages;
1285   bool fbfetch = false;
1286
1287   unsigned num_stages = is_compute ? 1 : ZINK_SHADER_COUNT;
1288   struct zink_program *pg = is_compute ? &ctx->curr_compute->base : &ctx->curr_program->base;
1289   if (is_compute)
1290      stages = &ctx->curr_compute->shader;
1291   else
1292      stages = &ctx->gfx_stages[0];
1293
1294   for (int i = 0; i < num_stages; i++) {
1295      struct zink_shader *shader = stages[i];
1296      enum pipe_shader_type pstage = shader ? pipe_shader_type_from_mesa(shader->nir->info.stage) : i;
1297      VkDescriptorBufferInfo *info = &ctx->di.ubos[pstage][0];
1298      unsigned dynamic_idx = is_compute ? 0 : tgsi_processor_to_shader_stage(pstage);
1299
1300      /* Values are taken from pDynamicOffsets in an order such that all entries for set N come before set N+1;
1301       * within a set, entries are ordered by the binding numbers in the descriptor set layouts
1302       * - vkCmdBindDescriptorSets spec
1303       *
1304       * because of this, we have to populate the dynamic offsets by their shader stage to ensure they
1305       * match what the driver expects
1306       */
1307      const bool used = (pg->dd->push_usage & BITFIELD_BIT(pstage)) == BITFIELD_BIT(pstage);
1308      dynamic_offsets[dynamic_idx] = used ? info->offset : 0;
1309      if (!cache_hit) {
1310         init_write_descriptor(NULL, desc_set, ZINK_DESCRIPTOR_TYPE_UBO, tgsi_processor_to_shader_stage(pstage), &wds[i], 0);
1311         if (used) {
1312            if (zds)
1313               desc_set_res_add(zds, ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_UBO][pstage][0], i, cache_hit);
1314            buffer_infos[i].buffer = info->buffer;
1315            buffer_infos[i].range = info->range;
1316         } else {
1317            if (zds)
1318               desc_set_res_add(zds, NULL, i, cache_hit);
1319            if (unlikely(!screen->info.rb2_feats.nullDescriptor))
1320               buffer_infos[i].buffer = zink_resource(ctx->dummy_vertex_buffer)->obj->buffer;
1321            else
1322               buffer_infos[i].buffer = VK_NULL_HANDLE;
1323            buffer_infos[i].range = VK_WHOLE_SIZE;
1324         }
1325         /* these are dynamic UBO descriptors, so we have to always set 0 as the descriptor offset */
1326         buffer_infos[i].offset = 0;
1327         wds[i].pBufferInfo = &buffer_infos[i];
1328      }
1329   }
1330   if (unlikely(!cache_hit && !is_compute && ctx->dd->has_fbfetch)) {
1331      init_write_descriptor(NULL, desc_set, 0, MESA_SHADER_STAGES, &wds[ZINK_SHADER_COUNT], 0);
1332      wds[ZINK_SHADER_COUNT].pImageInfo = &ctx->di.fbfetch;
1333      fbfetch = true;
1334   }
1335
1336   if (!cache_hit)
1337      VKSCR(UpdateDescriptorSets)(screen->dev, num_stages + !!fbfetch, wds, 0, NULL);
1338   return num_stages;
1339}
1340
1341static void
1342set_descriptor_set_refs(struct zink_context *ctx, struct zink_descriptor_set *zds, struct zink_program *pg, bool cache_hit)
1343{
1344   const bool compact_descriptors = zink_screen(ctx->base.screen)->compact_descriptors;
1345   STATIC_ASSERT(ZINK_DESCRIPTOR_TYPE_UBO + ZINK_DESCRIPTOR_COMPACT == ZINK_DESCRIPTOR_TYPE_SSBO);
1346   STATIC_ASSERT(ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW + ZINK_DESCRIPTOR_COMPACT == ZINK_DESCRIPTOR_TYPE_IMAGE);
1347   const enum zink_descriptor_type types[] = {zds->pool->type, zds->pool->type + ZINK_DESCRIPTOR_COMPACT};
1348   unsigned num_types = compact_descriptors ? 2 : 1;
1349   for (unsigned n = 0; n < num_types; n++) {
1350      const enum zink_descriptor_type type = types[n];
1351      for (unsigned i = 0; i < pdd_cached(pg)->num_refs[type]; i++) {
1352         switch (type) {
1353         case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
1354            desc_set_sampler_add(ctx, zds, pdd_cached(pg)->refs[type][i].sampler.dsurf,
1355                                           *pdd_cached(pg)->refs[type][i].sampler.sampler_state, i, cache_hit);
1356            break;
1357         case ZINK_DESCRIPTOR_TYPE_IMAGE:
1358            desc_set_descriptor_surface_add(ctx, zds, pdd_cached(pg)->refs[type][i].dsurf, i, cache_hit);
1359            break;
1360         default:
1361            desc_set_res_add(zds, *pdd_cached(pg)->refs[type][i].res, i, cache_hit);
1362            break;
1363         }
1364      }
1365   }
1366}
1367
1368static void
1369update_descriptors_internal(struct zink_context *ctx, enum zink_descriptor_type type, struct zink_descriptor_set *zds, struct zink_program *pg, bool cache_hit)
1370{
1371   struct zink_screen *screen = zink_screen(ctx->base.screen);
1372   struct zink_shader **stages;
1373
1374   unsigned num_stages = pg->is_compute ? 1 : ZINK_SHADER_COUNT;
1375   if (pg->is_compute)
1376      stages = &ctx->curr_compute->shader;
1377   else
1378      stages = &ctx->gfx_stages[0];
1379
1380   if (cache_hit || !zds)
1381      return;
1382
1383   if (screen->info.have_KHR_descriptor_update_template &&
1384       zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_NOTEMPLATES) {
1385      set_descriptor_set_refs(ctx, zds, pg, cache_hit);
1386      zink_descriptor_set_update_lazy(ctx, pg, type, zds->desc_set);
1387      return;
1388   }
1389
1390   unsigned num_resources = 0;
1391   ASSERTED unsigned num_bindings = zds->pool->num_resources;
1392   VkWriteDescriptorSet wds[ZINK_MAX_DESCRIPTORS_PER_TYPE];
1393   unsigned num_wds = 0;
1394
1395   const enum zink_descriptor_type types[2] = {type, type + ZINK_DESCRIPTOR_COMPACT};
1396   for (unsigned n = 0; n < ARRAY_SIZE(types); n++) {
1397      if (!(zds->compacted & BITFIELD_BIT(types[n])))
1398         continue;
1399      type = types[n];
1400      for (int i = 0; i < num_stages; i++) {
1401         struct zink_shader *shader = stages[i];
1402         if (!shader)
1403            continue;
1404         enum pipe_shader_type stage = pipe_shader_type_from_mesa(shader->nir->info.stage);
1405         for (int j = 0; j < shader->num_bindings[type]; j++) {
1406            int index = shader->bindings[type][j].index;
1407            switch (type) {
1408            case ZINK_DESCRIPTOR_TYPE_UBO:
1409               if (!index)
1410                  continue;
1411            FALLTHROUGH;
1412            case ZINK_DESCRIPTOR_TYPE_SSBO: {
1413               VkDescriptorBufferInfo *info;
1414               struct zink_resource *res = ctx->di.descriptor_res[type][stage][index];
1415               if (type == ZINK_DESCRIPTOR_TYPE_UBO)
1416                  info = &ctx->di.ubos[stage][index];
1417               else
1418                  info = &ctx->di.ssbos[stage][index];
1419               assert(num_resources < num_bindings);
1420               desc_set_res_add(zds, res, num_resources++, cache_hit);
1421               wds[num_wds].pBufferInfo = info;
1422            }
1423            break;
1424            case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
1425            case ZINK_DESCRIPTOR_TYPE_IMAGE: {
1426               VkDescriptorImageInfo *image_info;
1427               VkBufferView *buffer_info;
1428               if (type == ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW) {
1429                  image_info = &ctx->di.textures[stage][index];
1430                  buffer_info = &ctx->di.tbos[stage][index];
1431               } else {
1432                  image_info = &ctx->di.images[stage][index];
1433                  buffer_info = &ctx->di.texel_images[stage][index];
1434               }
1435               bool is_buffer = zink_shader_descriptor_is_buffer(shader, type, j);
1436               for (unsigned k = 0; k < shader->bindings[type][j].size; k++) {
1437                  assert(num_resources < num_bindings);
1438                  if (type == ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW) {
1439                     struct zink_sampler_state *sampler = NULL;
1440                     if (!is_buffer && image_info->imageView)
1441                        sampler = ctx->sampler_states[stage][index + k];;
1442
1443                     desc_set_sampler_add(ctx, zds, &ctx->di.sampler_surfaces[stage][index + k], sampler, num_resources++, cache_hit);
1444                  } else {
1445                     desc_set_image_add(ctx, zds, &ctx->di.image_surfaces[stage][index + k], num_resources++, cache_hit);
1446                  }
1447               }
1448               if (is_buffer)
1449                  wds[num_wds].pTexelBufferView = buffer_info;
1450               else
1451                  wds[num_wds].pImageInfo = image_info;
1452            }
1453            break;
1454            default:
1455               unreachable("unknown descriptor type");
1456            }
1457            num_wds = init_write_descriptor(shader, zds->desc_set, type, j, &wds[num_wds], num_wds);
1458         }
1459      }
1460   }
1461   if (num_wds)
1462      VKSCR(UpdateDescriptorSets)(screen->dev, num_wds, wds, 0, NULL);
1463}
1464
1465static void
1466zink_context_update_descriptor_states(struct zink_context *ctx, struct zink_program *pg);
1467
1468#define MAX_CACHE_MISSES 50
1469
1470void
1471zink_descriptors_update(struct zink_context *ctx, bool is_compute)
1472{
1473   struct zink_program *pg = is_compute ? (struct zink_program *)ctx->curr_compute : (struct zink_program *)ctx->curr_program;
1474
1475   if (ctx->dd->pg[is_compute] != pg) {
1476      for (int h = 0; h < ZINK_DESCRIPTOR_TYPES; h++) {
1477         if (pg->dd->real_binding_usage & BITFIELD_BIT(h))
1478            ctx->dd->changed[is_compute][h] = true;
1479         ctx->dd->descriptor_states[is_compute].valid[h] = false;
1480         if (!is_compute) {
1481            for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++)
1482               ctx->dd->gfx_descriptor_states[i].valid[h] = false;
1483         }
1484      }
1485   }
1486   zink_context_update_descriptor_states(ctx, pg);
1487   bool cache_hit;
1488   VkDescriptorSet desc_set = VK_NULL_HANDLE;
1489   struct zink_descriptor_set *zds = NULL;
1490
1491   struct zink_batch *batch = &ctx->batch;
1492   VkPipelineBindPoint bp = is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
1493
1494   {
1495      uint32_t dynamic_offsets[PIPE_MAX_CONSTANT_BUFFERS];
1496      unsigned dynamic_offset_idx = 0;
1497
1498      /* push set is indexed in vulkan as 0 but isn't in the general pool array */
1499      ctx->dd->changed[is_compute][ZINK_DESCRIPTOR_TYPES] |= ctx->dd->pg[is_compute] != pg;
1500      if (pg->dd->push_usage) {
1501         if (pg->dd->fbfetch) {
1502            /* fbfetch is not cacheable: grab a lazy set because it's faster */
1503            cache_hit = false;
1504            desc_set = zink_descriptors_alloc_lazy_push(ctx);
1505         } else {
1506            zds = zink_descriptor_set_get(ctx, ZINK_DESCRIPTOR_TYPES, is_compute, &cache_hit);
1507            desc_set = zds ? zds->desc_set : VK_NULL_HANDLE;
1508         }
1509      } else {
1510         cache_hit = false;
1511      }
1512      ctx->dd->changed[is_compute][ZINK_DESCRIPTOR_TYPES] = false;
1513      if (desc_set) {
1514         if (pg->dd->push_usage) // push set
1515            dynamic_offset_idx = update_push_ubo_descriptors(ctx, zds, desc_set,
1516                                                             is_compute, cache_hit, dynamic_offsets);
1517         VKCTX(CmdBindDescriptorSets)(batch->state->cmdbuf, bp,
1518                                 pg->layout, 0, 1, &desc_set,
1519                                 dynamic_offset_idx, dynamic_offsets);
1520      }
1521   }
1522
1523   {
1524      for (int h = 0; h < ZINK_DESCRIPTOR_TYPES; h++) {
1525         if (pdd_cached(pg)->cache_misses[h] < MAX_CACHE_MISSES) {
1526            if (pg->dsl[h + 1]) {
1527               /* null set has null pool */
1528               if (pdd_cached(pg)->pool[h]) {
1529                  zds = zink_descriptor_set_get(ctx, h, is_compute, &cache_hit);
1530                  if (cache_hit) {
1531                     pdd_cached(pg)->cache_misses[h] = 0;
1532                  } else {
1533                     if (++pdd_cached(pg)->cache_misses[h] == MAX_CACHE_MISSES) {
1534#ifdef PRINT_DEBUG
1535                        const char *set_names[] = {
1536                           "UBO",
1537                           "TEXTURES",
1538                           "SSBO",
1539                           "IMAGES",
1540                        };
1541                        debug_printf("zink: descriptor cache exploded for prog %p set %s: getting lazy (not a bug, just lettin you know)\n", pg, set_names[h]);
1542#endif
1543                     }
1544                  }
1545               } else
1546                  zds = NULL;
1547               if (zds) {
1548                  desc_set = zds->desc_set;
1549                  update_descriptors_internal(ctx, h, zds, pg, cache_hit);
1550
1551                  VKCTX(CmdBindDescriptorSets)(batch->state->cmdbuf, bp,
1552                                               pg->layout, h + 1, 1, &desc_set,
1553                                               0, NULL);
1554                  if (pdd_cached(pg)->cache_misses[h] == MAX_CACHE_MISSES)
1555                     zink_descriptor_pool_reference(ctx, &pdd_cached(pg)->pool[h], NULL);
1556               }
1557            }
1558         } else {
1559            zink_descriptors_update_lazy_masked(ctx, is_compute, BITFIELD_BIT(h), 0);
1560         }
1561         ctx->dd->changed[is_compute][h] = false;
1562      }
1563   }
1564   ctx->dd->pg[is_compute] = pg;
1565
1566   if (pg->dd->bindless && unlikely(!ctx->dd->bindless_bound)) {
1567      VKCTX(CmdBindDescriptorSets)(batch->state->cmdbuf, bp,
1568                                   pg->layout, ZINK_DESCRIPTOR_BINDLESS, 1, &ctx->dd->bindless_set,
1569                                   0, NULL);
1570      ctx->dd->bindless_bound = true;
1571   }
1572}
1573
1574void
1575zink_batch_descriptor_deinit(struct zink_screen *screen, struct zink_batch_state *bs)
1576{
1577   if (!bs->dd)
1578      return;
1579   _mesa_set_destroy(bs->dd->desc_sets, NULL);
1580   zink_batch_descriptor_deinit_lazy(screen, bs);
1581}
1582
1583void
1584zink_batch_descriptor_reset(struct zink_screen *screen, struct zink_batch_state *bs)
1585{
1586   set_foreach(bs->dd->desc_sets, entry) {
1587      struct zink_descriptor_set *zds = (void*)entry->key;
1588      zink_batch_usage_unset(&zds->batch_uses, bs);
1589      /* reset descriptor pools when no bs is using this program to avoid
1590       * having some inactive program hogging a billion descriptors
1591       */
1592      pipe_reference(&zds->reference, NULL);
1593      zink_descriptor_set_recycle(zds);
1594      if (zds->reference.count == 1) {
1595         struct zink_descriptor_pool *pool = zds->pool;
1596         zink_descriptor_pool_reference(bs->ctx, &pool, NULL);
1597      }
1598      _mesa_set_remove(bs->dd->desc_sets, entry);
1599   }
1600   zink_batch_descriptor_reset_lazy(screen, bs);
1601}
1602
1603bool
1604zink_batch_descriptor_init(struct zink_screen *screen, struct zink_batch_state *bs)
1605{
1606   if (!zink_batch_descriptor_init_lazy(screen, bs))
1607      return false;
1608   bs->dd->desc_sets = _mesa_pointer_set_create(bs);
1609   return !!bs->dd->desc_sets;
1610}
1611
1612static uint32_t
1613calc_descriptor_state_hash_ubo(struct zink_context *ctx, struct zink_shader *zs, enum pipe_shader_type shader, int i, int idx, uint32_t hash, bool need_offset)
1614{
1615   for (unsigned k = 0; k < zs->bindings[ZINK_DESCRIPTOR_TYPE_UBO][i].size; k++) {
1616      struct zink_resource *res = ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_UBO][shader][idx + k];
1617      struct zink_resource_object *obj = res ? res->obj : NULL;
1618      hash = XXH32(&obj, sizeof(void*), hash);
1619      void *hash_data = &ctx->di.ubos[shader][idx + k].range;
1620      size_t data_size = sizeof(unsigned);
1621      hash = XXH32(hash_data, data_size, hash);
1622      if (need_offset)
1623         hash = XXH32(&ctx->di.ubos[shader][idx + k].offset, sizeof(unsigned), hash);
1624   }
1625   return hash;
1626}
1627
1628static uint32_t
1629calc_descriptor_state_hash_ssbo(struct zink_context *ctx, struct zink_shader *zs, enum pipe_shader_type shader, int i, int idx, uint32_t hash)
1630{
1631   for (unsigned k = 0; k < zs->bindings[ZINK_DESCRIPTOR_TYPE_SSBO][i].size; k++) {
1632      struct zink_resource *res = ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_SSBO][shader][idx + k];
1633      struct zink_resource_object *obj = res ? res->obj : NULL;
1634      hash = XXH32(&obj, sizeof(void*), hash);
1635      if (obj) {
1636         struct pipe_shader_buffer *ssbo = &ctx->ssbos[shader][idx + k];
1637         hash = XXH32(&ssbo->buffer_offset, sizeof(ssbo->buffer_offset), hash);
1638         hash = XXH32(&ssbo->buffer_size, sizeof(ssbo->buffer_size), hash);
1639         /* compacted sets need a way to differentiate between a buffer bound as a ubo vs ssbo */
1640         if (zink_screen(ctx->base.screen)->compact_descriptors) {
1641            uint32_t writable = ctx->writable_ssbos[shader] & BITFIELD_BIT(idx + k);
1642            hash = XXH32(&writable, sizeof(writable), hash);
1643         }
1644      }
1645   }
1646   return hash;
1647}
1648
1649static uint32_t
1650calc_descriptor_state_hash_sampler(struct zink_context *ctx, struct zink_shader *zs, enum pipe_shader_type shader, int i, int idx, uint32_t hash)
1651{
1652   for (unsigned k = 0; k < zs->bindings[ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW][i].size; k++) {
1653      struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[shader][idx + k]);
1654      bool is_buffer = zink_shader_descriptor_is_buffer(zs, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, i);
1655      ctx->di.sampler_surfaces[shader][idx + k].is_buffer = is_buffer;
1656      uint32_t val = zink_get_sampler_view_hash(ctx, sampler_view, is_buffer);
1657      hash = XXH32(&val, sizeof(uint32_t), hash);
1658      if (is_buffer)
1659         continue;
1660
1661      hash = XXH32(&ctx->di.textures[shader][idx + k].imageLayout, sizeof(VkImageLayout), hash);
1662
1663      struct zink_sampler_state *sampler_state = ctx->sampler_states[shader][idx + k];
1664
1665      if (sampler_state)
1666         hash = XXH32(&sampler_state->hash, sizeof(uint32_t), hash);
1667   }
1668   return hash;
1669}
1670
1671static uint32_t
1672calc_descriptor_state_hash_image(struct zink_context *ctx, struct zink_shader *zs, enum pipe_shader_type shader, int i, int idx, uint32_t hash)
1673{
1674   for (unsigned k = 0; k < zs->bindings[ZINK_DESCRIPTOR_TYPE_IMAGE][i].size; k++) {
1675      bool is_buffer = zink_shader_descriptor_is_buffer(zs, ZINK_DESCRIPTOR_TYPE_IMAGE, i);
1676      uint32_t val = zink_get_image_view_hash(ctx, &ctx->image_views[shader][idx + k], is_buffer);
1677      ctx->di.image_surfaces[shader][idx + k].is_buffer = is_buffer;
1678      hash = XXH32(&val, sizeof(uint32_t), hash);
1679   }
1680   return hash;
1681}
1682
1683static uint32_t
1684update_descriptor_stage_state(struct zink_context *ctx, enum pipe_shader_type shader, enum zink_descriptor_type type)
1685{
1686   struct zink_shader *zs = shader == PIPE_SHADER_COMPUTE ? ctx->compute_stage : ctx->gfx_stages[shader];
1687
1688   uint32_t hash = 0;
1689   for (int i = 0; i < zs->num_bindings[type]; i++) {
1690      /* skip push set members */
1691      if (zs->bindings[type][i].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
1692         continue;
1693
1694      int idx = zs->bindings[type][i].index;
1695      switch (type) {
1696      case ZINK_DESCRIPTOR_TYPE_UBO:
1697         hash = calc_descriptor_state_hash_ubo(ctx, zs, shader, i, idx, hash, true);
1698         break;
1699      case ZINK_DESCRIPTOR_TYPE_SSBO:
1700         hash = calc_descriptor_state_hash_ssbo(ctx, zs, shader, i, idx, hash);
1701         break;
1702      case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW:
1703         hash = calc_descriptor_state_hash_sampler(ctx, zs, shader, i, idx, hash);
1704         break;
1705      case ZINK_DESCRIPTOR_TYPE_IMAGE:
1706         hash = calc_descriptor_state_hash_image(ctx, zs, shader, i, idx, hash);
1707         break;
1708      default:
1709         unreachable("unknown descriptor type");
1710      }
1711   }
1712   return hash;
1713}
1714
1715static void
1716update_descriptor_state(struct zink_context *ctx, enum zink_descriptor_type type, bool is_compute)
1717{
1718   /* we shouldn't be calling this if we don't have to */
1719   assert(!ctx->dd->descriptor_states[is_compute].valid[type]);
1720   bool has_any_usage = false;
1721
1722   if (is_compute) {
1723      /* just update compute state */
1724      bool has_usage = zink_program_get_descriptor_usage(ctx, PIPE_SHADER_COMPUTE, type);
1725      if (has_usage)
1726         ctx->dd->descriptor_states[is_compute].state[type] = update_descriptor_stage_state(ctx, PIPE_SHADER_COMPUTE, type);
1727      else
1728         ctx->dd->descriptor_states[is_compute].state[type] = 0;
1729      has_any_usage = has_usage;
1730   } else {
1731      /* update all gfx states */
1732      bool first = true;
1733      for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) {
1734         bool has_usage = false;
1735         /* this is the incremental update for the shader stage */
1736         if (!ctx->dd->gfx_descriptor_states[i].valid[type]) {
1737            ctx->dd->gfx_descriptor_states[i].state[type] = 0;
1738            if (ctx->gfx_stages[i]) {
1739               has_usage = zink_program_get_descriptor_usage(ctx, i, type);
1740               if (has_usage)
1741                  ctx->dd->gfx_descriptor_states[i].state[type] = update_descriptor_stage_state(ctx, i, type);
1742               ctx->dd->gfx_descriptor_states[i].valid[type] = has_usage;
1743            }
1744         }
1745         if (ctx->dd->gfx_descriptor_states[i].valid[type]) {
1746            /* this is the overall state update for the descriptor set hash */
1747            if (first) {
1748               /* no need to double hash the first state */
1749               ctx->dd->descriptor_states[is_compute].state[type] = ctx->dd->gfx_descriptor_states[i].state[type];
1750               first = false;
1751            } else {
1752               ctx->dd->descriptor_states[is_compute].state[type] ^= ctx->dd->gfx_descriptor_states[i].state[type];
1753            }
1754         }
1755         has_any_usage |= has_usage;
1756      }
1757   }
1758   ctx->dd->descriptor_states[is_compute].valid[type] = has_any_usage;
1759}
1760
1761static void
1762zink_context_update_descriptor_states(struct zink_context *ctx, struct zink_program *pg)
1763{
1764   struct zink_screen *screen = zink_screen(ctx->base.screen);
1765   if (pg->dd->push_usage && (!ctx->dd->push_valid[pg->is_compute] ||
1766                                           pg->dd->push_usage != ctx->dd->last_push_usage[pg->is_compute])) {
1767      uint32_t hash = 0;
1768      if (pg->is_compute) {
1769          hash = calc_descriptor_state_hash_ubo(ctx, ctx->compute_stage, PIPE_SHADER_COMPUTE, 0, 0, 0, false);
1770      } else {
1771         bool first = true;
1772         u_foreach_bit(stage, pg->dd->push_usage) {
1773            if (!ctx->dd->gfx_push_valid[stage]) {
1774               ctx->dd->gfx_push_state[stage] = calc_descriptor_state_hash_ubo(ctx, ctx->gfx_stages[stage], stage, 0, 0, 0, false);
1775               ctx->dd->gfx_push_valid[stage] = true;
1776            }
1777            if (first)
1778               hash = ctx->dd->gfx_push_state[stage];
1779            else
1780               hash ^= ctx->dd->gfx_push_state[stage];
1781            first = false;
1782         }
1783      }
1784      ctx->dd->changed[pg->is_compute][ZINK_DESCRIPTOR_TYPES] |= ctx->dd->push_state[pg->is_compute] != hash;
1785      ctx->dd->changed[pg->is_compute][ZINK_DESCRIPTOR_TYPES] |= pg->dd->push_usage != ctx->dd->last_push_usage[pg->is_compute];
1786      ctx->dd->push_state[pg->is_compute] = hash;
1787      ctx->dd->push_valid[pg->is_compute] = true;
1788      ctx->dd->last_push_usage[pg->is_compute] = pg->dd->push_usage;
1789   }
1790   for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) {
1791      if (pdd_cached(pg)->pool[screen->desc_set_id[i] - 1] && pdd_cached(pg)->cache_misses[i] < MAX_CACHE_MISSES &&
1792          ctx->dd->changed[pg->is_compute][i] &&
1793          !ctx->dd->descriptor_states[pg->is_compute].valid[i])
1794         update_descriptor_state(ctx, i, pg->is_compute);
1795   }
1796
1797   if (!screen->compact_descriptors)
1798      return;
1799
1800   for (unsigned n = 0; n < 2; n++) {
1801      ctx->dd->compact_descriptor_states[pg->is_compute].valid[n] = ctx->dd->descriptor_states[pg->is_compute].valid[n] |
1802                                                                    ctx->dd->descriptor_states[pg->is_compute].valid[n + ZINK_DESCRIPTOR_COMPACT];
1803      if (ctx->dd->compact_descriptor_states[pg->is_compute].valid[n]) {
1804         if (pg->is_compute) {
1805            ctx->dd->compact_descriptor_states[pg->is_compute].state[n] = ctx->dd->descriptor_states[pg->is_compute].state[n] ^
1806                                                                          ctx->dd->descriptor_states[pg->is_compute].state[n + ZINK_DESCRIPTOR_COMPACT];
1807         } else {
1808            uint32_t hash = 0;
1809            bool first = true;
1810            for (unsigned i = 0; i < ZINK_SHADER_COUNT; i++) {
1811               ctx->dd->compact_gfx_descriptor_states[i].valid[n] = ctx->dd->gfx_descriptor_states[i].valid[n] |
1812                                                                    ctx->dd->gfx_descriptor_states[i].valid[n + ZINK_DESCRIPTOR_COMPACT];
1813               if (ctx->dd->compact_gfx_descriptor_states[i].valid[n]) {
1814                  ctx->dd->compact_gfx_descriptor_states[i].state[n] = ctx->dd->gfx_descriptor_states[i].state[n] ^
1815                                                                       ctx->dd->gfx_descriptor_states[i].state[n + ZINK_DESCRIPTOR_COMPACT];
1816                  if (first)
1817                     hash = ctx->dd->compact_gfx_descriptor_states[i].state[n];
1818                  else
1819                     hash ^= ctx->dd->compact_gfx_descriptor_states[i].state[n];
1820                  first = false;
1821               } else {
1822                  ctx->dd->compact_gfx_descriptor_states[i].state[n] = 0;
1823               }
1824            }
1825            ctx->dd->compact_descriptor_states[pg->is_compute].state[n] = hash;
1826         }
1827      } else {
1828         ctx->dd->compact_descriptor_states[pg->is_compute].state[n] = 0;
1829      }
1830   }
1831}
1832
1833void
1834zink_context_invalidate_descriptor_state(struct zink_context *ctx, enum pipe_shader_type shader, enum zink_descriptor_type type, unsigned start, unsigned count)
1835{
1836   zink_context_invalidate_descriptor_state_lazy(ctx, shader, type, start, count);
1837   if (type == ZINK_DESCRIPTOR_TYPE_UBO && !start) {
1838      /* ubo 0 is the push set */
1839      ctx->dd->push_state[shader == PIPE_SHADER_COMPUTE] = 0;
1840      ctx->dd->push_valid[shader == PIPE_SHADER_COMPUTE] = false;
1841      if (shader != PIPE_SHADER_COMPUTE) {
1842         ctx->dd->gfx_push_state[shader] = 0;
1843         ctx->dd->gfx_push_valid[shader] = false;
1844      }
1845      ctx->dd->changed[shader == PIPE_SHADER_COMPUTE][ZINK_DESCRIPTOR_TYPES] = true;
1846      return;
1847   }
1848   if (shader != PIPE_SHADER_COMPUTE) {
1849      ctx->dd->gfx_descriptor_states[shader].valid[type] = false;
1850      ctx->dd->gfx_descriptor_states[shader].state[type] = 0;
1851   }
1852   ctx->dd->descriptor_states[shader == PIPE_SHADER_COMPUTE].valid[type] = false;
1853   ctx->dd->descriptor_states[shader == PIPE_SHADER_COMPUTE].state[type] = 0;
1854   ctx->dd->changed[shader == PIPE_SHADER_COMPUTE][type] = true;
1855}
1856
1857bool
1858zink_descriptors_init(struct zink_context *ctx)
1859{
1860   zink_descriptors_init_lazy(ctx);
1861   if (!ctx->dd)
1862      return false;
1863   return zink_descriptor_pool_init(ctx);
1864}
1865
1866void
1867zink_descriptors_deinit(struct zink_context *ctx)
1868{
1869   zink_descriptor_pool_deinit(ctx);
1870   zink_descriptors_deinit_lazy(ctx);
1871}
1872
1873bool
1874zink_descriptor_layouts_init(struct zink_context *ctx)
1875{
1876   for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) {
1877      if (!_mesa_hash_table_init(&ctx->desc_set_layouts[i], ctx, hash_descriptor_layout, equals_descriptor_layout))
1878         return false;
1879      if (!_mesa_set_init(&ctx->desc_pool_keys[i], ctx, hash_descriptor_pool_key, equals_descriptor_pool_key))
1880         return false;
1881   }
1882   return true;
1883}
1884
1885void
1886zink_descriptor_layouts_deinit(struct zink_context *ctx)
1887{
1888   struct zink_screen *screen = zink_screen(ctx->base.screen);
1889   for (unsigned i = 0; i < ZINK_DESCRIPTOR_TYPES; i++) {
1890      hash_table_foreach(&ctx->desc_set_layouts[i], he) {
1891         struct zink_descriptor_layout *layout = he->data;
1892         VKSCR(DestroyDescriptorSetLayout)(screen->dev, layout->layout, NULL);
1893         ralloc_free(layout);
1894         _mesa_hash_table_remove(&ctx->desc_set_layouts[i], he);
1895      }
1896   }
1897}
1898
1899
1900void
1901zink_descriptor_util_init_fbfetch(struct zink_context *ctx)
1902{
1903   if (ctx->dd->has_fbfetch)
1904      return;
1905
1906   struct zink_screen *screen = zink_screen(ctx->base.screen);
1907   VKSCR(DestroyDescriptorSetLayout)(screen->dev, ctx->dd->push_dsl[0]->layout, NULL);
1908   //don't free these now, let ralloc free on teardown to avoid invalid access
1909   //ralloc_free(ctx->dd->push_dsl[0]);
1910   //ralloc_free(ctx->dd->push_layout_keys[0]);
1911   ctx->dd->push_dsl[0] = create_gfx_layout(ctx, &ctx->dd->push_layout_keys[0], true);
1912   ctx->dd->has_fbfetch = true;
1913   if (zink_descriptor_mode != ZINK_DESCRIPTOR_MODE_LAZY)
1914      zink_descriptor_pool_init(ctx);
1915}
1916
1917ALWAYS_INLINE static VkDescriptorType
1918type_from_bindless_index(unsigned idx)
1919{
1920   switch (idx) {
1921   case 0: return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
1922   case 1: return VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
1923   case 2: return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
1924   case 3: return VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
1925   default:
1926      unreachable("unknown index");
1927   }
1928}
1929
1930void
1931zink_descriptors_init_bindless(struct zink_context *ctx)
1932{
1933   if (ctx->dd->bindless_set)
1934      return;
1935
1936   struct zink_screen *screen = zink_screen(ctx->base.screen);
1937   VkDescriptorSetLayoutBinding bindings[4];
1938   const unsigned num_bindings = 4;
1939   VkDescriptorSetLayoutCreateInfo dcslci = {0};
1940   dcslci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1941   dcslci.pNext = NULL;
1942   VkDescriptorSetLayoutBindingFlagsCreateInfo fci = {0};
1943   VkDescriptorBindingFlags flags[4];
1944   dcslci.pNext = &fci;
1945   dcslci.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
1946   fci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
1947   fci.bindingCount = num_bindings;
1948   fci.pBindingFlags = flags;
1949   for (unsigned i = 0; i < num_bindings; i++) {
1950      flags[i] = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT | VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT;
1951   }
1952   for (unsigned i = 0; i < num_bindings; i++) {
1953      bindings[i].binding = i;
1954      bindings[i].descriptorType = type_from_bindless_index(i);
1955      bindings[i].descriptorCount = ZINK_MAX_BINDLESS_HANDLES;
1956      bindings[i].stageFlags = VK_SHADER_STAGE_ALL_GRAPHICS | VK_SHADER_STAGE_COMPUTE_BIT;
1957      bindings[i].pImmutableSamplers = NULL;
1958   }
1959
1960   dcslci.bindingCount = num_bindings;
1961   dcslci.pBindings = bindings;
1962   VkResult result = VKSCR(CreateDescriptorSetLayout)(screen->dev, &dcslci, 0, &ctx->dd->bindless_layout);
1963   if (result != VK_SUCCESS) {
1964      mesa_loge("ZINK: vkCreateDescriptorSetLayout failed (%s)", vk_Result_to_str(result));
1965      return;
1966   }
1967
1968   VkDescriptorPoolCreateInfo dpci = {0};
1969   VkDescriptorPoolSize sizes[4];
1970   for (unsigned i = 0; i < 4; i++) {
1971      sizes[i].type = type_from_bindless_index(i);
1972      sizes[i].descriptorCount = ZINK_MAX_BINDLESS_HANDLES;
1973   }
1974   dpci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
1975   dpci.pPoolSizes = sizes;
1976   dpci.poolSizeCount = 4;
1977   dpci.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT;
1978   dpci.maxSets = 1;
1979   result = VKSCR(CreateDescriptorPool)(screen->dev, &dpci, 0, &ctx->dd->bindless_pool);
1980   if (result != VK_SUCCESS) {
1981      mesa_loge("ZINK: vkCreateDescriptorPool failed (%s)", vk_Result_to_str(result));
1982      return;
1983   }
1984
1985   zink_descriptor_util_alloc_sets(screen, ctx->dd->bindless_layout, ctx->dd->bindless_pool, &ctx->dd->bindless_set, 1);
1986}
1987
1988void
1989zink_descriptors_deinit_bindless(struct zink_context *ctx)
1990{
1991   struct zink_screen *screen = zink_screen(ctx->base.screen);
1992   if (ctx->dd->bindless_layout)
1993      VKSCR(DestroyDescriptorSetLayout)(screen->dev, ctx->dd->bindless_layout, NULL);
1994   if (ctx->dd->bindless_pool)
1995      VKSCR(DestroyDescriptorPool)(screen->dev, ctx->dd->bindless_pool, NULL);
1996}
1997
1998void
1999zink_descriptors_update_bindless(struct zink_context *ctx)
2000{
2001   struct zink_screen *screen = zink_screen(ctx->base.screen);
2002   for (unsigned i = 0; i < 2; i++) {
2003      if (!ctx->di.bindless_dirty[i])
2004         continue;
2005      while (util_dynarray_contains(&ctx->di.bindless[i].updates, uint32_t)) {
2006         uint32_t handle = util_dynarray_pop(&ctx->di.bindless[i].updates, uint32_t);
2007         bool is_buffer = ZINK_BINDLESS_IS_BUFFER(handle);
2008         VkWriteDescriptorSet wd;
2009         wd.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
2010         wd.pNext = NULL;
2011         wd.dstSet = ctx->dd->bindless_set;
2012         wd.dstBinding = is_buffer ? i * 2 + 1: i * 2;
2013         wd.dstArrayElement = is_buffer ? handle - ZINK_MAX_BINDLESS_HANDLES : handle;
2014         wd.descriptorCount = 1;
2015         wd.descriptorType = type_from_bindless_index(wd.dstBinding);
2016         if (is_buffer)
2017            wd.pTexelBufferView = &ctx->di.bindless[i].buffer_infos[wd.dstArrayElement];
2018         else
2019            wd.pImageInfo = &ctx->di.bindless[i].img_infos[handle];
2020         VKSCR(UpdateDescriptorSets)(screen->dev, 1, &wd, 0, NULL);
2021      }
2022   }
2023   ctx->di.any_bindless_dirty = 0;
2024}
2025