~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/drivers/zink/zink_descriptors.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

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