1/*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24#include <assert.h>
25#include <fcntl.h>
26#include <stdbool.h>
27#include <string.h>
28
29#include "util/mesa-sha1.h"
30#include "radv_private.h"
31#include "sid.h"
32#include "vk_descriptors.h"
33#include "vk_format.h"
34#include "vk_util.h"
35
36static bool
37has_equal_immutable_samplers(const VkSampler *samplers, uint32_t count)
38{
39   if (!samplers)
40      return false;
41   for (uint32_t i = 1; i < count; ++i) {
42      if (memcmp(radv_sampler_from_handle(samplers[0])->state,
43                 radv_sampler_from_handle(samplers[i])->state, 16)) {
44         return false;
45      }
46   }
47   return true;
48}
49
50static bool
51radv_mutable_descriptor_type_size_alignment(const VkMutableDescriptorTypeListVALVE *list,
52                                            uint64_t *out_size, uint64_t *out_align)
53{
54   uint32_t max_size = 0;
55   uint32_t max_align = 0;
56
57   for (uint32_t i = 0; i < list->descriptorTypeCount; i++) {
58      uint32_t size = 0;
59      uint32_t align = 0;
60
61      switch (list->pDescriptorTypes[i]) {
62      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
63      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
64      case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
65      case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
66         size = 16;
67         align = 16;
68         break;
69      case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
70         size = 32;
71         align = 32;
72         break;
73      case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
74         size = 64;
75         align = 32;
76         break;
77      default:
78         return false;
79      }
80
81      max_size = MAX2(max_size, size);
82      max_align = MAX2(max_align, align);
83   }
84
85   *out_size = max_size;
86   *out_align = max_align;
87   return true;
88}
89
90VkResult
91radv_CreateDescriptorSetLayout(VkDevice _device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
92                               const VkAllocationCallbacks *pAllocator,
93                               VkDescriptorSetLayout *pSetLayout)
94{
95   RADV_FROM_HANDLE(radv_device, device, _device);
96   struct radv_descriptor_set_layout *set_layout;
97
98   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
99   const VkDescriptorSetLayoutBindingFlagsCreateInfo *variable_flags =
100      vk_find_struct_const(pCreateInfo->pNext, DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO);
101   const VkMutableDescriptorTypeCreateInfoVALVE *mutable_info =
102      vk_find_struct_const(pCreateInfo->pNext, MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE);
103
104   uint32_t num_bindings = 0;
105   uint32_t immutable_sampler_count = 0;
106   uint32_t ycbcr_sampler_count = 0;
107   for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) {
108      num_bindings = MAX2(num_bindings, pCreateInfo->pBindings[j].binding + 1);
109      if ((pCreateInfo->pBindings[j].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
110           pCreateInfo->pBindings[j].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) &&
111          pCreateInfo->pBindings[j].pImmutableSamplers) {
112         immutable_sampler_count += pCreateInfo->pBindings[j].descriptorCount;
113
114         bool has_ycbcr_sampler = false;
115         for (unsigned i = 0; i < pCreateInfo->pBindings[j].descriptorCount; ++i) {
116            if (radv_sampler_from_handle(pCreateInfo->pBindings[j].pImmutableSamplers[i])
117                   ->ycbcr_sampler)
118               has_ycbcr_sampler = true;
119         }
120
121         if (has_ycbcr_sampler)
122            ycbcr_sampler_count += pCreateInfo->pBindings[j].descriptorCount;
123      }
124   }
125
126   uint32_t samplers_offset = offsetof(struct radv_descriptor_set_layout, binding[num_bindings]);
127   size_t size = samplers_offset + immutable_sampler_count * 4 * sizeof(uint32_t);
128   if (ycbcr_sampler_count > 0) {
129      /* Store block of offsets first, followed by the conversion descriptors (padded to the struct
130       * alignment) */
131      size += num_bindings * sizeof(uint32_t);
132      size = ALIGN(size, alignof(struct radv_sampler_ycbcr_conversion));
133      size += ycbcr_sampler_count * sizeof(struct radv_sampler_ycbcr_conversion);
134   }
135
136   set_layout =
137      vk_zalloc2(&device->vk.alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
138   if (!set_layout)
139      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
140
141   vk_object_base_init(&device->vk, &set_layout->base, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT);
142
143   set_layout->flags = pCreateInfo->flags;
144   set_layout->layout_size = size;
145
146   /* We just allocate all the samplers at the end of the struct */
147   uint32_t *samplers = (uint32_t *)&set_layout->binding[num_bindings];
148   struct radv_sampler_ycbcr_conversion *ycbcr_samplers = NULL;
149   uint32_t *ycbcr_sampler_offsets = NULL;
150
151   if (ycbcr_sampler_count > 0) {
152      ycbcr_sampler_offsets = samplers + 4 * immutable_sampler_count;
153      set_layout->ycbcr_sampler_offsets_offset = (char *)ycbcr_sampler_offsets - (char *)set_layout;
154
155      uintptr_t first_ycbcr_sampler_offset =
156         (uintptr_t)ycbcr_sampler_offsets + sizeof(uint32_t) * num_bindings;
157      first_ycbcr_sampler_offset =
158         ALIGN(first_ycbcr_sampler_offset, alignof(struct radv_sampler_ycbcr_conversion));
159      ycbcr_samplers = (struct radv_sampler_ycbcr_conversion *)first_ycbcr_sampler_offset;
160   } else
161      set_layout->ycbcr_sampler_offsets_offset = 0;
162
163   VkDescriptorSetLayoutBinding *bindings = NULL;
164   VkResult result =
165      vk_create_sorted_bindings(pCreateInfo->pBindings, pCreateInfo->bindingCount, &bindings);
166   if (result != VK_SUCCESS) {
167      vk_object_base_finish(&set_layout->base);
168      vk_free2(&device->vk.alloc, pAllocator, set_layout);
169      return vk_error(device, result);
170   }
171
172   set_layout->binding_count = num_bindings;
173   set_layout->shader_stages = 0;
174   set_layout->dynamic_shader_stages = 0;
175   set_layout->has_immutable_samplers = false;
176   set_layout->size = 0;
177
178   uint32_t buffer_count = 0;
179   uint32_t dynamic_offset_count = 0;
180
181   for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) {
182      const VkDescriptorSetLayoutBinding *binding = bindings + j;
183      uint32_t b = binding->binding;
184      uint32_t alignment = 0;
185      unsigned binding_buffer_count = 0;
186      uint32_t descriptor_count = binding->descriptorCount;
187      bool has_ycbcr_sampler = false;
188
189      /* main image + fmask */
190      uint32_t max_sampled_image_descriptors = 2;
191
192      if (binding->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
193          binding->pImmutableSamplers) {
194         for (unsigned i = 0; i < binding->descriptorCount; ++i) {
195            struct radv_sampler_ycbcr_conversion *conversion =
196               radv_sampler_from_handle(binding->pImmutableSamplers[i])->ycbcr_sampler;
197
198            if (conversion) {
199               has_ycbcr_sampler = true;
200               max_sampled_image_descriptors = MAX2(max_sampled_image_descriptors,
201                                                    vk_format_get_plane_count(conversion->format));
202            }
203         }
204      }
205
206      switch (binding->descriptorType) {
207      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
208      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
209         assert(!(pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
210         set_layout->binding[b].dynamic_offset_count = 1;
211         set_layout->dynamic_shader_stages |= binding->stageFlags;
212         set_layout->binding[b].size = 0;
213         binding_buffer_count = 1;
214         alignment = 1;
215         break;
216      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
217      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
218      case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
219      case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
220         set_layout->binding[b].size = 16;
221         binding_buffer_count = 1;
222         alignment = 16;
223         break;
224      case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
225         set_layout->binding[b].size = 32;
226         binding_buffer_count = 1;
227         alignment = 32;
228         break;
229      case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
230      case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
231         /* main descriptor + fmask descriptor */
232         set_layout->binding[b].size = 64;
233         binding_buffer_count = 1;
234         alignment = 32;
235         break;
236      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
237         /* main descriptor + fmask descriptor + sampler */
238         set_layout->binding[b].size = 96;
239         binding_buffer_count = 1;
240         alignment = 32;
241         break;
242      case VK_DESCRIPTOR_TYPE_SAMPLER:
243         set_layout->binding[b].size = 16;
244         alignment = 16;
245         break;
246      case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE: {
247         uint64_t mutable_size = 0, mutable_align = 0;
248         radv_mutable_descriptor_type_size_alignment(&mutable_info->pMutableDescriptorTypeLists[j],
249                                                     &mutable_size, &mutable_align);
250         assert(mutable_size && mutable_align);
251         set_layout->binding[b].size = mutable_size;
252         binding_buffer_count = 1;
253         alignment = mutable_align;
254         break;
255      }
256      case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
257         alignment = 16;
258         set_layout->binding[b].size = descriptor_count;
259         descriptor_count = 1;
260         break;
261      case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
262         set_layout->binding[b].size = 16;
263         alignment = 16;
264         break;
265      default:
266         break;
267      }
268
269      set_layout->size = align(set_layout->size, alignment);
270      set_layout->binding[b].type = binding->descriptorType;
271      set_layout->binding[b].array_size = descriptor_count;
272      set_layout->binding[b].offset = set_layout->size;
273      set_layout->binding[b].buffer_offset = buffer_count;
274      set_layout->binding[b].dynamic_offset_offset = dynamic_offset_count;
275
276      if (variable_flags && binding->binding < variable_flags->bindingCount &&
277          (variable_flags->pBindingFlags[binding->binding] &
278           VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT)) {
279         assert(
280            !binding->pImmutableSamplers); /* Terribly ill defined  how many samplers are valid */
281         assert(binding->binding == num_bindings - 1);
282
283         set_layout->has_variable_descriptors = true;
284      }
285
286      if ((binding->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
287           binding->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) &&
288          binding->pImmutableSamplers) {
289         set_layout->binding[b].immutable_samplers_offset = samplers_offset;
290         set_layout->binding[b].immutable_samplers_equal =
291            has_equal_immutable_samplers(binding->pImmutableSamplers, binding->descriptorCount);
292         set_layout->has_immutable_samplers = true;
293
294         for (uint32_t i = 0; i < binding->descriptorCount; i++)
295            memcpy(samplers + 4 * i,
296                   &radv_sampler_from_handle(binding->pImmutableSamplers[i])->state, 16);
297
298         /* Don't reserve space for the samplers if they're not accessed. */
299         if (set_layout->binding[b].immutable_samplers_equal) {
300            if (binding->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER &&
301                max_sampled_image_descriptors <= 2)
302               set_layout->binding[b].size -= 32;
303            else if (binding->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
304               set_layout->binding[b].size -= 16;
305         }
306         samplers += 4 * binding->descriptorCount;
307         samplers_offset += 4 * sizeof(uint32_t) * binding->descriptorCount;
308
309         if (has_ycbcr_sampler) {
310            ycbcr_sampler_offsets[b] = (const char *)ycbcr_samplers - (const char *)set_layout;
311            for (uint32_t i = 0; i < binding->descriptorCount; i++) {
312               if (radv_sampler_from_handle(binding->pImmutableSamplers[i])->ycbcr_sampler)
313                  ycbcr_samplers[i] =
314                     *radv_sampler_from_handle(binding->pImmutableSamplers[i])->ycbcr_sampler;
315               else
316                  ycbcr_samplers[i].format = VK_FORMAT_UNDEFINED;
317            }
318            ycbcr_samplers += binding->descriptorCount;
319         }
320      }
321
322      set_layout->size += descriptor_count * set_layout->binding[b].size;
323      buffer_count += descriptor_count * binding_buffer_count;
324      dynamic_offset_count += descriptor_count * set_layout->binding[b].dynamic_offset_count;
325      set_layout->shader_stages |= binding->stageFlags;
326   }
327
328   free(bindings);
329
330   set_layout->buffer_count = buffer_count;
331   set_layout->dynamic_offset_count = dynamic_offset_count;
332
333   *pSetLayout = radv_descriptor_set_layout_to_handle(set_layout);
334
335   return VK_SUCCESS;
336}
337
338void
339radv_DestroyDescriptorSetLayout(VkDevice _device, VkDescriptorSetLayout _set_layout,
340                                const VkAllocationCallbacks *pAllocator)
341{
342   RADV_FROM_HANDLE(radv_device, device, _device);
343   RADV_FROM_HANDLE(radv_descriptor_set_layout, set_layout, _set_layout);
344
345   if (!set_layout)
346      return;
347
348   vk_object_base_finish(&set_layout->base);
349   vk_free2(&device->vk.alloc, pAllocator, set_layout);
350}
351
352void
353radv_GetDescriptorSetLayoutSupport(VkDevice device,
354                                   const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
355                                   VkDescriptorSetLayoutSupport *pSupport)
356{
357   VkDescriptorSetLayoutBinding *bindings = NULL;
358   VkResult result =
359      vk_create_sorted_bindings(pCreateInfo->pBindings, pCreateInfo->bindingCount, &bindings);
360   if (result != VK_SUCCESS) {
361      pSupport->supported = false;
362      return;
363   }
364
365   const VkDescriptorSetLayoutBindingFlagsCreateInfo *variable_flags =
366      vk_find_struct_const(pCreateInfo->pNext, DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO);
367   VkDescriptorSetVariableDescriptorCountLayoutSupport *variable_count = vk_find_struct(
368      (void *)pCreateInfo->pNext, DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT);
369   const VkMutableDescriptorTypeCreateInfoVALVE *mutable_info =
370      vk_find_struct_const(pCreateInfo->pNext, MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE);
371   if (variable_count) {
372      variable_count->maxVariableDescriptorCount = 0;
373   }
374
375   bool supported = true;
376   uint64_t size = 0;
377   for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
378      const VkDescriptorSetLayoutBinding *binding = bindings + i;
379
380      uint64_t descriptor_size = 0;
381      uint64_t descriptor_alignment = 1;
382      uint32_t descriptor_count = binding->descriptorCount;
383      switch (binding->descriptorType) {
384      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
385      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
386         break;
387      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
388      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
389      case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
390      case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
391         descriptor_size = 16;
392         descriptor_alignment = 16;
393         break;
394      case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
395         descriptor_size = 32;
396         descriptor_alignment = 32;
397         break;
398      case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
399      case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
400         descriptor_size = 64;
401         descriptor_alignment = 32;
402         break;
403      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
404         if (!has_equal_immutable_samplers(binding->pImmutableSamplers, descriptor_count)) {
405            descriptor_size = 64;
406         } else {
407            descriptor_size = 96;
408         }
409         descriptor_alignment = 32;
410         break;
411      case VK_DESCRIPTOR_TYPE_SAMPLER:
412         if (!has_equal_immutable_samplers(binding->pImmutableSamplers, descriptor_count)) {
413            descriptor_size = 16;
414            descriptor_alignment = 16;
415         }
416         break;
417      case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
418         descriptor_alignment = 16;
419         descriptor_size = descriptor_count;
420         descriptor_count = 1;
421         break;
422      case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE:
423         if (!radv_mutable_descriptor_type_size_alignment(
424                &mutable_info->pMutableDescriptorTypeLists[i], &descriptor_size,
425                &descriptor_alignment)) {
426            supported = false;
427         }
428         break;
429      case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
430         descriptor_size = 16;
431         descriptor_alignment = 16;
432         break;
433      default:
434         break;
435      }
436
437      if (size && !align_u64(size, descriptor_alignment)) {
438         supported = false;
439      }
440      size = align_u64(size, descriptor_alignment);
441
442      uint64_t max_count = INT32_MAX;
443      if (binding->descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
444         max_count = INT32_MAX - size;
445      else if (descriptor_size)
446         max_count = (INT32_MAX - size) / descriptor_size;
447
448      if (max_count < descriptor_count) {
449         supported = false;
450      }
451      if (variable_flags && binding->binding < variable_flags->bindingCount && variable_count &&
452          (variable_flags->pBindingFlags[binding->binding] &
453           VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT)) {
454         variable_count->maxVariableDescriptorCount = MIN2(UINT32_MAX, max_count);
455      }
456      size += descriptor_count * descriptor_size;
457   }
458
459   free(bindings);
460
461   pSupport->supported = supported;
462}
463
464/*
465 * Pipeline layouts.  These have nothing to do with the pipeline.  They are
466 * just multiple descriptor set layouts pasted together.
467 */
468
469VkResult
470radv_CreatePipelineLayout(VkDevice _device, const VkPipelineLayoutCreateInfo *pCreateInfo,
471                          const VkAllocationCallbacks *pAllocator,
472                          VkPipelineLayout *pPipelineLayout)
473{
474   RADV_FROM_HANDLE(radv_device, device, _device);
475   struct radv_pipeline_layout *layout;
476   struct mesa_sha1 ctx;
477
478   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
479
480   layout = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*layout), 8,
481                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
482   if (layout == NULL)
483      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
484
485   vk_object_base_init(&device->vk, &layout->base, VK_OBJECT_TYPE_PIPELINE_LAYOUT);
486
487   layout->num_sets = pCreateInfo->setLayoutCount;
488
489   unsigned dynamic_offset_count = 0;
490   uint16_t dynamic_shader_stages = 0;
491
492   _mesa_sha1_init(&ctx);
493   for (uint32_t set = 0; set < pCreateInfo->setLayoutCount; set++) {
494      RADV_FROM_HANDLE(radv_descriptor_set_layout, set_layout, pCreateInfo->pSetLayouts[set]);
495      layout->set[set].layout = set_layout;
496
497      layout->set[set].dynamic_offset_start = dynamic_offset_count;
498      layout->set[set].dynamic_offset_count = 0;
499      layout->set[set].dynamic_offset_stages = 0;
500
501      for (uint32_t b = 0; b < set_layout->binding_count; b++) {
502         layout->set[set].dynamic_offset_count +=
503            set_layout->binding[b].array_size * set_layout->binding[b].dynamic_offset_count;
504         layout->set[set].dynamic_offset_stages |= set_layout->dynamic_shader_stages;
505      }
506      dynamic_offset_count += layout->set[set].dynamic_offset_count;
507      dynamic_shader_stages |= layout->set[set].dynamic_offset_stages;
508
509      /* Hash the entire set layout except for the vk_object_base. The
510       * rest of the set layout is carefully constructed to not have
511       * pointers so a full hash instead of a per-field hash should be ok. */
512      _mesa_sha1_update(&ctx, (const char *)set_layout + sizeof(struct vk_object_base),
513                        set_layout->layout_size - sizeof(struct vk_object_base));
514   }
515
516   layout->dynamic_offset_count = dynamic_offset_count;
517   layout->dynamic_shader_stages = dynamic_shader_stages;
518   layout->push_constant_size = 0;
519
520   for (unsigned i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
521      const VkPushConstantRange *range = pCreateInfo->pPushConstantRanges + i;
522      layout->push_constant_size = MAX2(layout->push_constant_size, range->offset + range->size);
523   }
524
525   layout->push_constant_size = align(layout->push_constant_size, 16);
526   _mesa_sha1_update(&ctx, &layout->push_constant_size, sizeof(layout->push_constant_size));
527   _mesa_sha1_final(&ctx, layout->sha1);
528   *pPipelineLayout = radv_pipeline_layout_to_handle(layout);
529
530   return VK_SUCCESS;
531}
532
533void
534radv_DestroyPipelineLayout(VkDevice _device, VkPipelineLayout _pipelineLayout,
535                           const VkAllocationCallbacks *pAllocator)
536{
537   RADV_FROM_HANDLE(radv_device, device, _device);
538   RADV_FROM_HANDLE(radv_pipeline_layout, pipeline_layout, _pipelineLayout);
539
540   if (!pipeline_layout)
541      return;
542
543   vk_object_base_finish(&pipeline_layout->base);
544   vk_free2(&device->vk.alloc, pAllocator, pipeline_layout);
545}
546
547static VkResult
548radv_descriptor_set_create(struct radv_device *device, struct radv_descriptor_pool *pool,
549                           const struct radv_descriptor_set_layout *layout,
550                           const uint32_t *variable_count, struct radv_descriptor_set **out_set)
551{
552   struct radv_descriptor_set *set;
553   uint32_t buffer_count = layout->buffer_count;
554   if (variable_count) {
555      unsigned stride = 1;
556      if (layout->binding[layout->binding_count - 1].type == VK_DESCRIPTOR_TYPE_SAMPLER ||
557          layout->binding[layout->binding_count - 1].type ==
558             VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
559         stride = 0;
560      buffer_count =
561         layout->binding[layout->binding_count - 1].buffer_offset + *variable_count * stride;
562   }
563   unsigned range_offset =
564      sizeof(struct radv_descriptor_set_header) + sizeof(struct radeon_winsys_bo *) * buffer_count;
565   const unsigned dynamic_offset_count = layout->dynamic_offset_count;
566   unsigned mem_size =
567      range_offset + sizeof(struct radv_descriptor_range) * dynamic_offset_count;
568
569   if (pool->host_memory_base) {
570      if (pool->host_memory_end - pool->host_memory_ptr < mem_size)
571         return VK_ERROR_OUT_OF_POOL_MEMORY;
572
573      set = (struct radv_descriptor_set *)pool->host_memory_ptr;
574      pool->host_memory_ptr += mem_size;
575      memset(set->descriptors, 0, sizeof(struct radeon_winsys_bo *) * buffer_count);
576   } else {
577      set = vk_alloc2(&device->vk.alloc, NULL, mem_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
578
579      if (!set)
580         return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
581   }
582
583   memset(set, 0, mem_size);
584
585   vk_object_base_init(&device->vk, &set->header.base, VK_OBJECT_TYPE_DESCRIPTOR_SET);
586
587   if (dynamic_offset_count) {
588      set->header.dynamic_descriptors =
589         (struct radv_descriptor_range *)((uint8_t *)set + range_offset);
590   }
591
592   set->header.layout = layout;
593   set->header.buffer_count = buffer_count;
594   uint32_t layout_size = layout->size;
595   if (variable_count) {
596      uint32_t stride = layout->binding[layout->binding_count - 1].size;
597      if (layout->binding[layout->binding_count - 1].type ==
598          VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
599         stride = 1;
600
601      layout_size = layout->binding[layout->binding_count - 1].offset + *variable_count * stride;
602   }
603   layout_size = align_u32(layout_size, 32);
604   set->header.size = layout_size;
605
606   if (!pool->host_memory_base && pool->entry_count == pool->max_entry_count) {
607      vk_free2(&device->vk.alloc, NULL, set);
608      return VK_ERROR_OUT_OF_POOL_MEMORY;
609   }
610
611   /* try to allocate linearly first, so that we don't spend
612    * time looking for gaps if the app only allocates &
613    * resets via the pool. */
614   if (pool->current_offset + layout_size <= pool->size) {
615      set->header.bo = pool->bo;
616      set->header.mapped_ptr = (uint32_t *)(pool->mapped_ptr + pool->current_offset);
617      set->header.va = pool->bo ? (radv_buffer_get_va(set->header.bo) + pool->current_offset) : 0;
618      if (!pool->host_memory_base) {
619         pool->entries[pool->entry_count].offset = pool->current_offset;
620         pool->entries[pool->entry_count].size = layout_size;
621         pool->entries[pool->entry_count].set = set;
622         pool->entry_count++;
623      }
624      pool->current_offset += layout_size;
625   } else if (!pool->host_memory_base) {
626      uint64_t offset = 0;
627      int index;
628
629      for (index = 0; index < pool->entry_count; ++index) {
630         if (pool->entries[index].offset - offset >= layout_size)
631            break;
632         offset = pool->entries[index].offset + pool->entries[index].size;
633      }
634
635      if (pool->size - offset < layout_size) {
636         vk_free2(&device->vk.alloc, NULL, set);
637         return VK_ERROR_OUT_OF_POOL_MEMORY;
638      }
639      set->header.bo = pool->bo;
640      set->header.mapped_ptr = (uint32_t *)(pool->mapped_ptr + offset);
641      set->header.va = pool->bo ? (radv_buffer_get_va(set->header.bo) + offset) : 0;
642      memmove(&pool->entries[index + 1], &pool->entries[index],
643              sizeof(pool->entries[0]) * (pool->entry_count - index));
644      pool->entries[index].offset = offset;
645      pool->entries[index].size = layout_size;
646      pool->entries[index].set = set;
647      pool->entry_count++;
648   } else
649      return VK_ERROR_OUT_OF_POOL_MEMORY;
650
651   if (layout->has_immutable_samplers) {
652      for (unsigned i = 0; i < layout->binding_count; ++i) {
653         if (!layout->binding[i].immutable_samplers_offset ||
654             layout->binding[i].immutable_samplers_equal)
655            continue;
656
657         unsigned offset = layout->binding[i].offset / 4;
658         if (layout->binding[i].type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
659            offset += radv_combined_image_descriptor_sampler_offset(layout->binding + i) / 4;
660
661         const uint32_t *samplers =
662            (const uint32_t *)((const char *)layout + layout->binding[i].immutable_samplers_offset);
663         for (unsigned j = 0; j < layout->binding[i].array_size; ++j) {
664            memcpy(set->header.mapped_ptr + offset, samplers + 4 * j, 16);
665            offset += layout->binding[i].size / 4;
666         }
667      }
668   }
669   *out_set = set;
670   return VK_SUCCESS;
671}
672
673static void
674radv_descriptor_set_destroy(struct radv_device *device, struct radv_descriptor_pool *pool,
675                            struct radv_descriptor_set *set, bool free_bo)
676{
677   assert(!pool->host_memory_base);
678
679   if (free_bo && !pool->host_memory_base) {
680      for (int i = 0; i < pool->entry_count; ++i) {
681         if (pool->entries[i].set == set) {
682            memmove(&pool->entries[i], &pool->entries[i + 1],
683                    sizeof(pool->entries[i]) * (pool->entry_count - i - 1));
684            --pool->entry_count;
685            break;
686         }
687      }
688   }
689   vk_object_base_finish(&set->header.base);
690   vk_free2(&device->vk.alloc, NULL, set);
691}
692
693static void
694radv_destroy_descriptor_pool(struct radv_device *device, const VkAllocationCallbacks *pAllocator,
695                             struct radv_descriptor_pool *pool)
696{
697   if (!pool->host_memory_base) {
698      for (int i = 0; i < pool->entry_count; ++i) {
699         radv_descriptor_set_destroy(device, pool, pool->entries[i].set, false);
700      }
701   }
702
703   if (pool->bo)
704      device->ws->buffer_destroy(device->ws, pool->bo);
705   if (pool->host_bo)
706      vk_free2(&device->vk.alloc, pAllocator, pool->host_bo);
707
708   vk_object_base_finish(&pool->base);
709   vk_free2(&device->vk.alloc, pAllocator, pool);
710}
711
712VkResult
713radv_CreateDescriptorPool(VkDevice _device, const VkDescriptorPoolCreateInfo *pCreateInfo,
714                          const VkAllocationCallbacks *pAllocator,
715                          VkDescriptorPool *pDescriptorPool)
716{
717   RADV_FROM_HANDLE(radv_device, device, _device);
718   struct radv_descriptor_pool *pool;
719   uint64_t size = sizeof(struct radv_descriptor_pool);
720   uint64_t bo_size = 0, bo_count = 0, range_count = 0;
721
722   const VkMutableDescriptorTypeCreateInfoVALVE *mutable_info =
723      vk_find_struct_const(pCreateInfo->pNext, MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_VALVE);
724
725   vk_foreach_struct(ext, pCreateInfo->pNext)
726   {
727      switch (ext->sType) {
728      case VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT: {
729         const struct VkDescriptorPoolInlineUniformBlockCreateInfoEXT *info =
730            (const struct VkDescriptorPoolInlineUniformBlockCreateInfoEXT *)ext;
731         /* the sizes are 4 aligned, and we need to align to at
732          * most 32, which needs at most 28 bytes extra per
733          * binding. */
734         bo_size += 28llu * info->maxInlineUniformBlockBindings;
735         break;
736      }
737      default:
738         break;
739      }
740   }
741
742   for (unsigned i = 0; i < pCreateInfo->poolSizeCount; ++i) {
743      if (pCreateInfo->pPoolSizes[i].type != VK_DESCRIPTOR_TYPE_SAMPLER)
744         bo_count += pCreateInfo->pPoolSizes[i].descriptorCount;
745
746      switch (pCreateInfo->pPoolSizes[i].type) {
747      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
748      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
749         range_count += pCreateInfo->pPoolSizes[i].descriptorCount;
750         break;
751      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
752      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
753      case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
754      case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
755      case VK_DESCRIPTOR_TYPE_SAMPLER:
756      case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
757      case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
758         /* 32 as we may need to align for images */
759         bo_size += 32 * pCreateInfo->pPoolSizes[i].descriptorCount;
760         break;
761      case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
762      case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
763         bo_size += 64 * pCreateInfo->pPoolSizes[i].descriptorCount;
764         break;
765      case VK_DESCRIPTOR_TYPE_MUTABLE_VALVE:
766         /* Per spec, if a mutable descriptor type list is provided for the pool entry, we
767          * allocate enough memory to hold any subset of that list.
768          * If there is no mutable descriptor type list available,
769          * we must allocate enough for any supported mutable descriptor type, i.e. 64 bytes. */
770         if (mutable_info && i < mutable_info->mutableDescriptorTypeListCount) {
771            uint64_t mutable_size, mutable_alignment;
772            if (radv_mutable_descriptor_type_size_alignment(
773                   &mutable_info->pMutableDescriptorTypeLists[i], &mutable_size,
774                   &mutable_alignment)) {
775               /* 32 as we may need to align for images */
776               mutable_size = align(mutable_size, 32);
777               bo_size += mutable_size * pCreateInfo->pPoolSizes[i].descriptorCount;
778            }
779         } else {
780            bo_size += 64 * pCreateInfo->pPoolSizes[i].descriptorCount;
781         }
782         break;
783      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
784         bo_size += 96 * pCreateInfo->pPoolSizes[i].descriptorCount;
785         break;
786      case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
787         bo_size += pCreateInfo->pPoolSizes[i].descriptorCount;
788         break;
789      default:
790         break;
791      }
792   }
793
794   if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT)) {
795      uint64_t host_size = pCreateInfo->maxSets * sizeof(struct radv_descriptor_set);
796      host_size += sizeof(struct radeon_winsys_bo *) * bo_count;
797      host_size += sizeof(struct radv_descriptor_range) * range_count;
798      size += host_size;
799   } else {
800      size += sizeof(struct radv_descriptor_pool_entry) * pCreateInfo->maxSets;
801   }
802
803   pool = vk_alloc2(&device->vk.alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
804   if (!pool)
805      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
806
807   memset(pool, 0, sizeof(*pool));
808
809   vk_object_base_init(&device->vk, &pool->base, VK_OBJECT_TYPE_DESCRIPTOR_POOL);
810
811   if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT)) {
812      pool->host_memory_base = (uint8_t *)pool + sizeof(struct radv_descriptor_pool);
813      pool->host_memory_ptr = pool->host_memory_base;
814      pool->host_memory_end = (uint8_t *)pool + size;
815   }
816
817   if (bo_size) {
818      if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_HOST_ONLY_BIT_VALVE)) {
819         VkResult result = device->ws->buffer_create(
820            device->ws, bo_size, 32, RADEON_DOMAIN_VRAM,
821            RADEON_FLAG_NO_INTERPROCESS_SHARING | RADEON_FLAG_READ_ONLY | RADEON_FLAG_32BIT,
822            RADV_BO_PRIORITY_DESCRIPTOR, 0, &pool->bo);
823         if (result != VK_SUCCESS) {
824            radv_destroy_descriptor_pool(device, pAllocator, pool);
825            return vk_error(device, result);
826         }
827         pool->mapped_ptr = (uint8_t *)device->ws->buffer_map(pool->bo);
828         if (!pool->mapped_ptr) {
829            radv_destroy_descriptor_pool(device, pAllocator, pool);
830            return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
831         }
832      } else {
833         pool->host_bo =
834            vk_alloc2(&device->vk.alloc, pAllocator, bo_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
835         if (!pool->host_bo) {
836            radv_destroy_descriptor_pool(device, pAllocator, pool);
837            return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
838         }
839         pool->mapped_ptr = pool->host_bo;
840      }
841   }
842   pool->size = bo_size;
843   pool->max_entry_count = pCreateInfo->maxSets;
844
845   *pDescriptorPool = radv_descriptor_pool_to_handle(pool);
846   return VK_SUCCESS;
847}
848
849void
850radv_DestroyDescriptorPool(VkDevice _device, VkDescriptorPool _pool,
851                           const VkAllocationCallbacks *pAllocator)
852{
853   RADV_FROM_HANDLE(radv_device, device, _device);
854   RADV_FROM_HANDLE(radv_descriptor_pool, pool, _pool);
855
856   if (!pool)
857      return;
858
859   radv_destroy_descriptor_pool(device, pAllocator, pool);
860}
861
862VkResult
863radv_ResetDescriptorPool(VkDevice _device, VkDescriptorPool descriptorPool,
864                         VkDescriptorPoolResetFlags flags)
865{
866   RADV_FROM_HANDLE(radv_device, device, _device);
867   RADV_FROM_HANDLE(radv_descriptor_pool, pool, descriptorPool);
868
869   if (!pool->host_memory_base) {
870      for (int i = 0; i < pool->entry_count; ++i) {
871         radv_descriptor_set_destroy(device, pool, pool->entries[i].set, false);
872      }
873      pool->entry_count = 0;
874   }
875
876   pool->current_offset = 0;
877   pool->host_memory_ptr = pool->host_memory_base;
878
879   return VK_SUCCESS;
880}
881
882VkResult
883radv_AllocateDescriptorSets(VkDevice _device, const VkDescriptorSetAllocateInfo *pAllocateInfo,
884                            VkDescriptorSet *pDescriptorSets)
885{
886   RADV_FROM_HANDLE(radv_device, device, _device);
887   RADV_FROM_HANDLE(radv_descriptor_pool, pool, pAllocateInfo->descriptorPool);
888
889   VkResult result = VK_SUCCESS;
890   uint32_t i;
891   struct radv_descriptor_set *set = NULL;
892
893   const VkDescriptorSetVariableDescriptorCountAllocateInfo *variable_counts = vk_find_struct_const(
894      pAllocateInfo->pNext, DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO);
895   const uint32_t zero = 0;
896
897   /* allocate a set of buffers for each shader to contain descriptors */
898   for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
899      RADV_FROM_HANDLE(radv_descriptor_set_layout, layout, pAllocateInfo->pSetLayouts[i]);
900
901      const uint32_t *variable_count = NULL;
902      if (layout->has_variable_descriptors && variable_counts) {
903         if (i < variable_counts->descriptorSetCount)
904            variable_count = variable_counts->pDescriptorCounts + i;
905         else
906            variable_count = &zero;
907      }
908
909      assert(!(layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
910
911      result = radv_descriptor_set_create(device, pool, layout, variable_count, &set);
912      if (result != VK_SUCCESS)
913         break;
914
915      pDescriptorSets[i] = radv_descriptor_set_to_handle(set);
916   }
917
918   if (result != VK_SUCCESS) {
919      radv_FreeDescriptorSets(_device, pAllocateInfo->descriptorPool, i, pDescriptorSets);
920      for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
921         pDescriptorSets[i] = VK_NULL_HANDLE;
922      }
923   }
924   return result;
925}
926
927VkResult
928radv_FreeDescriptorSets(VkDevice _device, VkDescriptorPool descriptorPool, uint32_t count,
929                        const VkDescriptorSet *pDescriptorSets)
930{
931   RADV_FROM_HANDLE(radv_device, device, _device);
932   RADV_FROM_HANDLE(radv_descriptor_pool, pool, descriptorPool);
933
934   for (uint32_t i = 0; i < count; i++) {
935      RADV_FROM_HANDLE(radv_descriptor_set, set, pDescriptorSets[i]);
936
937      if (set && !pool->host_memory_base)
938         radv_descriptor_set_destroy(device, pool, set, true);
939   }
940   return VK_SUCCESS;
941}
942
943static void
944write_texel_buffer_descriptor(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer,
945                              unsigned *dst, struct radeon_winsys_bo **buffer_list,
946                              const VkBufferView _buffer_view)
947{
948   RADV_FROM_HANDLE(radv_buffer_view, buffer_view, _buffer_view);
949
950   if (!buffer_view) {
951      memset(dst, 0, 4 * 4);
952      if (!cmd_buffer)
953         *buffer_list = NULL;
954      return;
955   }
956
957   memcpy(dst, buffer_view->state, 4 * 4);
958
959   if (cmd_buffer)
960      radv_cs_add_buffer(device->ws, cmd_buffer->cs, buffer_view->bo);
961   else
962      *buffer_list = buffer_view->bo;
963}
964
965static void
966write_buffer_descriptor(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer,
967                        unsigned *dst, struct radeon_winsys_bo **buffer_list,
968                        const VkDescriptorBufferInfo *buffer_info)
969{
970   RADV_FROM_HANDLE(radv_buffer, buffer, buffer_info->buffer);
971
972   if (!buffer) {
973      memset(dst, 0, 4 * 4);
974      if (!cmd_buffer)
975         *buffer_list = NULL;
976      return;
977   }
978
979   uint64_t va = radv_buffer_get_va(buffer->bo);
980   uint32_t range = buffer_info->range;
981
982   if (buffer_info->range == VK_WHOLE_SIZE)
983      range = buffer->size - buffer_info->offset;
984   assert(buffer->size > 0 && range > 0);
985
986   /* robustBufferAccess is relaxed enough to allow this (in combination
987    * with the alignment/size we return from vkGetBufferMemoryRequirements)
988    * and this allows the shader compiler to create more efficient 8/16-bit
989    * buffer accesses. */
990   range = align(range, 4);
991
992   va += buffer_info->offset + buffer->offset;
993
994   uint32_t rsrc_word3 =
995      S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) | S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
996      S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) | S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
997
998   if (device->physical_device->rad_info.chip_class >= GFX10) {
999      rsrc_word3 |= S_008F0C_FORMAT(V_008F0C_GFX10_FORMAT_32_FLOAT) |
1000                    S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_RAW) | S_008F0C_RESOURCE_LEVEL(1);
1001   } else {
1002      rsrc_word3 |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
1003                    S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
1004   }
1005
1006   dst[0] = va;
1007   dst[1] = S_008F04_BASE_ADDRESS_HI(va >> 32);
1008   dst[2] = range;
1009   dst[3] = rsrc_word3;
1010
1011   if (cmd_buffer)
1012      radv_cs_add_buffer(device->ws, cmd_buffer->cs, buffer->bo);
1013   else
1014      *buffer_list = buffer->bo;
1015}
1016
1017static void
1018write_block_descriptor(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer, void *dst,
1019                       const VkWriteDescriptorSet *writeset)
1020{
1021   const VkWriteDescriptorSetInlineUniformBlockEXT *inline_ub =
1022      vk_find_struct_const(writeset->pNext, WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT);
1023
1024   memcpy(dst, inline_ub->pData, inline_ub->dataSize);
1025}
1026
1027static void
1028write_dynamic_buffer_descriptor(struct radv_device *device, struct radv_descriptor_range *range,
1029                                struct radeon_winsys_bo **buffer_list,
1030                                const VkDescriptorBufferInfo *buffer_info)
1031{
1032   RADV_FROM_HANDLE(radv_buffer, buffer, buffer_info->buffer);
1033   uint64_t va;
1034   unsigned size;
1035
1036   if (!buffer) {
1037      range->va = 0;
1038      *buffer_list = NULL;
1039      return;
1040   }
1041
1042   va = radv_buffer_get_va(buffer->bo);
1043   size = buffer_info->range;
1044
1045   if (buffer_info->range == VK_WHOLE_SIZE)
1046      size = buffer->size - buffer_info->offset;
1047   assert(buffer->size > 0 && size > 0);
1048
1049   /* robustBufferAccess is relaxed enough to allow this (in combination
1050    * with the alignment/size we return from vkGetBufferMemoryRequirements)
1051    * and this allows the shader compiler to create more efficient 8/16-bit
1052    * buffer accesses. */
1053   size = align(size, 4);
1054
1055   va += buffer_info->offset + buffer->offset;
1056   range->va = va;
1057   range->size = size;
1058
1059   *buffer_list = buffer->bo;
1060}
1061
1062static void
1063write_image_descriptor(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer,
1064                       unsigned size, unsigned *dst, struct radeon_winsys_bo **buffer_list,
1065                       VkDescriptorType descriptor_type, const VkDescriptorImageInfo *image_info)
1066{
1067   RADV_FROM_HANDLE(radv_image_view, iview, image_info->imageView);
1068   union radv_descriptor *descriptor;
1069
1070   if (!iview) {
1071      memset(dst, 0, size);
1072      if (!cmd_buffer)
1073         *buffer_list = NULL;
1074      return;
1075   }
1076
1077   if (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) {
1078      descriptor = &iview->storage_descriptor;
1079   } else {
1080      descriptor = &iview->descriptor;
1081   }
1082   assert(size > 0);
1083
1084   memcpy(dst, descriptor, size);
1085
1086   if (cmd_buffer)
1087      radv_cs_add_buffer(device->ws, cmd_buffer->cs, iview->image->bo);
1088   else
1089      *buffer_list = iview->image->bo;
1090}
1091
1092static void
1093write_combined_image_sampler_descriptor(struct radv_device *device,
1094                                        struct radv_cmd_buffer *cmd_buffer, unsigned sampler_offset,
1095                                        unsigned *dst, struct radeon_winsys_bo **buffer_list,
1096                                        VkDescriptorType descriptor_type,
1097                                        const VkDescriptorImageInfo *image_info, bool has_sampler)
1098{
1099   write_image_descriptor(device, cmd_buffer, sampler_offset, dst, buffer_list, descriptor_type,
1100                          image_info);
1101   /* copy over sampler state */
1102   if (has_sampler) {
1103      RADV_FROM_HANDLE(radv_sampler, sampler, image_info->sampler);
1104      memcpy(dst + sampler_offset / sizeof(*dst), sampler->state, 16);
1105   }
1106}
1107
1108static void
1109write_sampler_descriptor(struct radv_device *device, unsigned *dst,
1110                         const VkDescriptorImageInfo *image_info)
1111{
1112   RADV_FROM_HANDLE(radv_sampler, sampler, image_info->sampler);
1113
1114   memcpy(dst, sampler->state, 16);
1115}
1116
1117static void
1118write_accel_struct(void *ptr, VkAccelerationStructureKHR _accel_struct)
1119{
1120   RADV_FROM_HANDLE(radv_acceleration_structure, accel_struct, _accel_struct);
1121   uint64_t va = accel_struct ? radv_accel_struct_get_va(accel_struct) : 0;
1122   memcpy(ptr, &va, sizeof(va));
1123}
1124
1125void
1126radv_update_descriptor_sets(struct radv_device *device, struct radv_cmd_buffer *cmd_buffer,
1127                            VkDescriptorSet dstSetOverride, uint32_t descriptorWriteCount,
1128                            const VkWriteDescriptorSet *pDescriptorWrites,
1129                            uint32_t descriptorCopyCount,
1130                            const VkCopyDescriptorSet *pDescriptorCopies)
1131{
1132   uint32_t i, j;
1133   for (i = 0; i < descriptorWriteCount; i++) {
1134      const VkWriteDescriptorSet *writeset = &pDescriptorWrites[i];
1135      RADV_FROM_HANDLE(radv_descriptor_set, set,
1136                       dstSetOverride ? dstSetOverride : writeset->dstSet);
1137      const struct radv_descriptor_set_binding_layout *binding_layout =
1138         set->header.layout->binding + writeset->dstBinding;
1139      uint32_t *ptr = set->header.mapped_ptr;
1140      struct radeon_winsys_bo **buffer_list = set->descriptors;
1141      /* Immutable samplers are not copied into push descriptors when they are
1142       * allocated, so if we are writing push descriptors we have to copy the
1143       * immutable samplers into them now.
1144       */
1145      const bool copy_immutable_samplers = cmd_buffer &&
1146                                           binding_layout->immutable_samplers_offset &&
1147                                           !binding_layout->immutable_samplers_equal;
1148      const uint32_t *samplers = radv_immutable_samplers(set->header.layout, binding_layout);
1149      const VkWriteDescriptorSetAccelerationStructureKHR *accel_structs = NULL;
1150
1151      ptr += binding_layout->offset / 4;
1152
1153      if (writeset->descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
1154         write_block_descriptor(device, cmd_buffer, (uint8_t *)ptr + writeset->dstArrayElement,
1155                                writeset);
1156         continue;
1157      } else if (writeset->descriptorType == VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) {
1158         accel_structs =
1159            vk_find_struct_const(writeset->pNext, WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR);
1160      }
1161
1162      ptr += binding_layout->size * writeset->dstArrayElement / 4;
1163      buffer_list += binding_layout->buffer_offset;
1164      buffer_list += writeset->dstArrayElement;
1165      for (j = 0; j < writeset->descriptorCount; ++j) {
1166         switch (writeset->descriptorType) {
1167         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1168         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
1169            unsigned idx = writeset->dstArrayElement + j;
1170            idx += binding_layout->dynamic_offset_offset;
1171            assert(!(set->header.layout->flags &
1172                     VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
1173            write_dynamic_buffer_descriptor(device, set->header.dynamic_descriptors + idx,
1174                                            buffer_list, writeset->pBufferInfo + j);
1175            break;
1176         }
1177         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1178         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1179            write_buffer_descriptor(device, cmd_buffer, ptr, buffer_list,
1180                                    writeset->pBufferInfo + j);
1181            break;
1182         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1183         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1184            write_texel_buffer_descriptor(device, cmd_buffer, ptr, buffer_list,
1185                                          writeset->pTexelBufferView[j]);
1186            break;
1187         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1188            write_image_descriptor(device, cmd_buffer, 32, ptr, buffer_list,
1189                                   writeset->descriptorType, writeset->pImageInfo + j);
1190            break;
1191         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1192         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1193            write_image_descriptor(device, cmd_buffer, 64, ptr, buffer_list,
1194                                   writeset->descriptorType, writeset->pImageInfo + j);
1195            break;
1196         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
1197            unsigned sampler_offset = radv_combined_image_descriptor_sampler_offset(binding_layout);
1198            write_combined_image_sampler_descriptor(
1199               device, cmd_buffer, sampler_offset, ptr, buffer_list, writeset->descriptorType,
1200               writeset->pImageInfo + j, !binding_layout->immutable_samplers_offset);
1201            if (copy_immutable_samplers) {
1202               const unsigned idx = writeset->dstArrayElement + j;
1203               memcpy((char *)ptr + sampler_offset, samplers + 4 * idx, 16);
1204            }
1205            break;
1206         }
1207         case VK_DESCRIPTOR_TYPE_SAMPLER:
1208            if (!binding_layout->immutable_samplers_offset) {
1209               write_sampler_descriptor(device, ptr, writeset->pImageInfo + j);
1210            } else if (copy_immutable_samplers) {
1211               unsigned idx = writeset->dstArrayElement + j;
1212               memcpy(ptr, samplers + 4 * idx, 16);
1213            }
1214            break;
1215         case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
1216            write_accel_struct(ptr, accel_structs->pAccelerationStructures[j]);
1217            break;
1218         default:
1219            break;
1220         }
1221         ptr += binding_layout->size / 4;
1222         ++buffer_list;
1223      }
1224   }
1225
1226   for (i = 0; i < descriptorCopyCount; i++) {
1227      const VkCopyDescriptorSet *copyset = &pDescriptorCopies[i];
1228      RADV_FROM_HANDLE(radv_descriptor_set, src_set, copyset->srcSet);
1229      RADV_FROM_HANDLE(radv_descriptor_set, dst_set, copyset->dstSet);
1230      const struct radv_descriptor_set_binding_layout *src_binding_layout =
1231         src_set->header.layout->binding + copyset->srcBinding;
1232      const struct radv_descriptor_set_binding_layout *dst_binding_layout =
1233         dst_set->header.layout->binding + copyset->dstBinding;
1234      uint32_t *src_ptr = src_set->header.mapped_ptr;
1235      uint32_t *dst_ptr = dst_set->header.mapped_ptr;
1236      struct radeon_winsys_bo **src_buffer_list = src_set->descriptors;
1237      struct radeon_winsys_bo **dst_buffer_list = dst_set->descriptors;
1238
1239      src_ptr += src_binding_layout->offset / 4;
1240      dst_ptr += dst_binding_layout->offset / 4;
1241
1242      if (src_binding_layout->type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
1243         src_ptr += copyset->srcArrayElement / 4;
1244         dst_ptr += copyset->dstArrayElement / 4;
1245
1246         memcpy(dst_ptr, src_ptr, copyset->descriptorCount);
1247         continue;
1248      }
1249
1250      src_ptr += src_binding_layout->size * copyset->srcArrayElement / 4;
1251      dst_ptr += dst_binding_layout->size * copyset->dstArrayElement / 4;
1252
1253      src_buffer_list += src_binding_layout->buffer_offset;
1254      src_buffer_list += copyset->srcArrayElement;
1255
1256      dst_buffer_list += dst_binding_layout->buffer_offset;
1257      dst_buffer_list += copyset->dstArrayElement;
1258
1259      /* In case of copies between mutable descriptor types
1260       * and non-mutable descriptor types. */
1261      size_t copy_size = MIN2(src_binding_layout->size, dst_binding_layout->size);
1262
1263      for (j = 0; j < copyset->descriptorCount; ++j) {
1264         switch (src_binding_layout->type) {
1265         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1266         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
1267            unsigned src_idx = copyset->srcArrayElement + j;
1268            unsigned dst_idx = copyset->dstArrayElement + j;
1269            struct radv_descriptor_range *src_range, *dst_range;
1270            src_idx += src_binding_layout->dynamic_offset_offset;
1271            dst_idx += dst_binding_layout->dynamic_offset_offset;
1272
1273            src_range = src_set->header.dynamic_descriptors + src_idx;
1274            dst_range = dst_set->header.dynamic_descriptors + dst_idx;
1275            *dst_range = *src_range;
1276            break;
1277         }
1278         default:
1279            memcpy(dst_ptr, src_ptr, copy_size);
1280         }
1281         src_ptr += src_binding_layout->size / 4;
1282         dst_ptr += dst_binding_layout->size / 4;
1283
1284         if (src_binding_layout->type != VK_DESCRIPTOR_TYPE_SAMPLER &&
1285             src_binding_layout->type != VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) {
1286            /* Sampler descriptors don't have a buffer list. */
1287            dst_buffer_list[j] = src_buffer_list[j];
1288         }
1289      }
1290   }
1291}
1292
1293void
1294radv_UpdateDescriptorSets(VkDevice _device, uint32_t descriptorWriteCount,
1295                          const VkWriteDescriptorSet *pDescriptorWrites,
1296                          uint32_t descriptorCopyCount,
1297                          const VkCopyDescriptorSet *pDescriptorCopies)
1298{
1299   RADV_FROM_HANDLE(radv_device, device, _device);
1300
1301   radv_update_descriptor_sets(device, NULL, VK_NULL_HANDLE, descriptorWriteCount,
1302                               pDescriptorWrites, descriptorCopyCount, pDescriptorCopies);
1303}
1304
1305VkResult
1306radv_CreateDescriptorUpdateTemplate(VkDevice _device,
1307                                    const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
1308                                    const VkAllocationCallbacks *pAllocator,
1309                                    VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate)
1310{
1311   RADV_FROM_HANDLE(radv_device, device, _device);
1312   RADV_FROM_HANDLE(radv_descriptor_set_layout, set_layout, pCreateInfo->descriptorSetLayout);
1313   const uint32_t entry_count = pCreateInfo->descriptorUpdateEntryCount;
1314   const size_t size = sizeof(struct radv_descriptor_update_template) +
1315                       sizeof(struct radv_descriptor_update_template_entry) * entry_count;
1316   struct radv_descriptor_update_template *templ;
1317   uint32_t i;
1318
1319   templ = vk_alloc2(&device->vk.alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1320   if (!templ)
1321      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1322
1323   vk_object_base_init(&device->vk, &templ->base, VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE);
1324
1325   templ->entry_count = entry_count;
1326
1327   if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR) {
1328      RADV_FROM_HANDLE(radv_pipeline_layout, pipeline_layout, pCreateInfo->pipelineLayout);
1329
1330      /* descriptorSetLayout should be ignored for push descriptors
1331       * and instead it refers to pipelineLayout and set.
1332       */
1333      assert(pCreateInfo->set < MAX_SETS);
1334      set_layout = pipeline_layout->set[pCreateInfo->set].layout;
1335
1336      templ->bind_point = pCreateInfo->pipelineBindPoint;
1337   }
1338
1339   for (i = 0; i < entry_count; i++) {
1340      const VkDescriptorUpdateTemplateEntry *entry = &pCreateInfo->pDescriptorUpdateEntries[i];
1341      const struct radv_descriptor_set_binding_layout *binding_layout =
1342         set_layout->binding + entry->dstBinding;
1343      const uint32_t buffer_offset = binding_layout->buffer_offset + entry->dstArrayElement;
1344      const uint32_t *immutable_samplers = NULL;
1345      uint32_t dst_offset;
1346      uint32_t dst_stride;
1347
1348      /* dst_offset is an offset into dynamic_descriptors when the descriptor
1349         is dynamic, and an offset into mapped_ptr otherwise */
1350      switch (entry->descriptorType) {
1351      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1352      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1353         assert(pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET);
1354         dst_offset = binding_layout->dynamic_offset_offset + entry->dstArrayElement;
1355         dst_stride = 0; /* Not used */
1356         break;
1357      default:
1358         switch (entry->descriptorType) {
1359         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1360         case VK_DESCRIPTOR_TYPE_SAMPLER:
1361            /* Immutable samplers are copied into push descriptors when they are pushed */
1362            if (pCreateInfo->templateType ==
1363                   VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR &&
1364                binding_layout->immutable_samplers_offset &&
1365                !binding_layout->immutable_samplers_equal) {
1366               immutable_samplers =
1367                  radv_immutable_samplers(set_layout, binding_layout) + entry->dstArrayElement * 4;
1368            }
1369            break;
1370         default:
1371            break;
1372         }
1373         dst_offset = binding_layout->offset / 4;
1374         if (entry->descriptorType == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT)
1375            dst_offset += entry->dstArrayElement / 4;
1376         else
1377            dst_offset += binding_layout->size * entry->dstArrayElement / 4;
1378
1379         dst_stride = binding_layout->size / 4;
1380         break;
1381      }
1382
1383      templ->entry[i] = (struct radv_descriptor_update_template_entry){
1384         .descriptor_type = entry->descriptorType,
1385         .descriptor_count = entry->descriptorCount,
1386         .src_offset = entry->offset,
1387         .src_stride = entry->stride,
1388         .dst_offset = dst_offset,
1389         .dst_stride = dst_stride,
1390         .buffer_offset = buffer_offset,
1391         .has_sampler = !binding_layout->immutable_samplers_offset,
1392         .sampler_offset = radv_combined_image_descriptor_sampler_offset(binding_layout),
1393         .immutable_samplers = immutable_samplers};
1394   }
1395
1396   *pDescriptorUpdateTemplate = radv_descriptor_update_template_to_handle(templ);
1397   return VK_SUCCESS;
1398}
1399
1400void
1401radv_DestroyDescriptorUpdateTemplate(VkDevice _device,
1402                                     VkDescriptorUpdateTemplate descriptorUpdateTemplate,
1403                                     const VkAllocationCallbacks *pAllocator)
1404{
1405   RADV_FROM_HANDLE(radv_device, device, _device);
1406   RADV_FROM_HANDLE(radv_descriptor_update_template, templ, descriptorUpdateTemplate);
1407
1408   if (!templ)
1409      return;
1410
1411   vk_object_base_finish(&templ->base);
1412   vk_free2(&device->vk.alloc, pAllocator, templ);
1413}
1414
1415void
1416radv_update_descriptor_set_with_template(struct radv_device *device,
1417                                         struct radv_cmd_buffer *cmd_buffer,
1418                                         struct radv_descriptor_set *set,
1419                                         VkDescriptorUpdateTemplate descriptorUpdateTemplate,
1420                                         const void *pData)
1421{
1422   RADV_FROM_HANDLE(radv_descriptor_update_template, templ, descriptorUpdateTemplate);
1423   uint32_t i;
1424
1425   for (i = 0; i < templ->entry_count; ++i) {
1426      struct radeon_winsys_bo **buffer_list = set->descriptors + templ->entry[i].buffer_offset;
1427      uint32_t *pDst = set->header.mapped_ptr + templ->entry[i].dst_offset;
1428      const uint8_t *pSrc = ((const uint8_t *)pData) + templ->entry[i].src_offset;
1429      uint32_t j;
1430
1431      if (templ->entry[i].descriptor_type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT) {
1432         memcpy((uint8_t *)pDst, pSrc, templ->entry[i].descriptor_count);
1433         continue;
1434      }
1435
1436      for (j = 0; j < templ->entry[i].descriptor_count; ++j) {
1437         switch (templ->entry[i].descriptor_type) {
1438         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1439         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
1440            const unsigned idx = templ->entry[i].dst_offset + j;
1441            assert(!(set->header.layout->flags &
1442                     VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
1443            write_dynamic_buffer_descriptor(device, set->header.dynamic_descriptors + idx,
1444                                            buffer_list, (struct VkDescriptorBufferInfo *)pSrc);
1445            break;
1446         }
1447         case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1448         case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1449            write_buffer_descriptor(device, cmd_buffer, pDst, buffer_list,
1450                                    (struct VkDescriptorBufferInfo *)pSrc);
1451            break;
1452         case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1453         case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1454            write_texel_buffer_descriptor(device, cmd_buffer, pDst, buffer_list,
1455                                          *(VkBufferView *)pSrc);
1456            break;
1457         case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1458            write_image_descriptor(device, cmd_buffer, 32, pDst, buffer_list,
1459                                   templ->entry[i].descriptor_type,
1460                                   (struct VkDescriptorImageInfo *)pSrc);
1461            break;
1462         case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1463         case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1464            write_image_descriptor(device, cmd_buffer, 64, pDst, buffer_list,
1465                                   templ->entry[i].descriptor_type,
1466                                   (struct VkDescriptorImageInfo *)pSrc);
1467            break;
1468         case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1469            write_combined_image_sampler_descriptor(
1470               device, cmd_buffer, templ->entry[i].sampler_offset, pDst, buffer_list,
1471               templ->entry[i].descriptor_type, (struct VkDescriptorImageInfo *)pSrc,
1472               templ->entry[i].has_sampler);
1473            if (templ->entry[i].immutable_samplers) {
1474               memcpy((char *)pDst + templ->entry[i].sampler_offset,
1475                      templ->entry[i].immutable_samplers + 4 * j, 16);
1476            }
1477            break;
1478         case VK_DESCRIPTOR_TYPE_SAMPLER:
1479            if (templ->entry[i].has_sampler)
1480               write_sampler_descriptor(device, pDst, (struct VkDescriptorImageInfo *)pSrc);
1481            else if (templ->entry[i].immutable_samplers)
1482               memcpy(pDst, templ->entry[i].immutable_samplers + 4 * j, 16);
1483            break;
1484         case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR:
1485            write_accel_struct(pDst, *(const VkAccelerationStructureKHR *)pSrc);
1486            break;
1487         default:
1488            break;
1489         }
1490         pSrc += templ->entry[i].src_stride;
1491         pDst += templ->entry[i].dst_stride;
1492         ++buffer_list;
1493      }
1494   }
1495}
1496
1497void
1498radv_UpdateDescriptorSetWithTemplate(VkDevice _device, VkDescriptorSet descriptorSet,
1499                                     VkDescriptorUpdateTemplate descriptorUpdateTemplate,
1500                                     const void *pData)
1501{
1502   RADV_FROM_HANDLE(radv_device, device, _device);
1503   RADV_FROM_HANDLE(radv_descriptor_set, set, descriptorSet);
1504
1505   radv_update_descriptor_set_with_template(device, NULL, set, descriptorUpdateTemplate, pData);
1506}
1507
1508VkResult
1509radv_CreateSamplerYcbcrConversion(VkDevice _device,
1510                                  const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
1511                                  const VkAllocationCallbacks *pAllocator,
1512                                  VkSamplerYcbcrConversion *pYcbcrConversion)
1513{
1514   RADV_FROM_HANDLE(radv_device, device, _device);
1515   struct radv_sampler_ycbcr_conversion *conversion = NULL;
1516
1517   conversion = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*conversion), 8,
1518                           VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1519
1520   if (conversion == NULL)
1521      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1522
1523   vk_object_base_init(&device->vk, &conversion->base, VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION);
1524
1525   conversion->format = pCreateInfo->format;
1526   conversion->ycbcr_model = pCreateInfo->ycbcrModel;
1527   conversion->ycbcr_range = pCreateInfo->ycbcrRange;
1528   conversion->components = pCreateInfo->components;
1529   conversion->chroma_offsets[0] = pCreateInfo->xChromaOffset;
1530   conversion->chroma_offsets[1] = pCreateInfo->yChromaOffset;
1531   conversion->chroma_filter = pCreateInfo->chromaFilter;
1532
1533   *pYcbcrConversion = radv_sampler_ycbcr_conversion_to_handle(conversion);
1534   return VK_SUCCESS;
1535}
1536
1537void
1538radv_DestroySamplerYcbcrConversion(VkDevice _device, VkSamplerYcbcrConversion ycbcrConversion,
1539                                   const VkAllocationCallbacks *pAllocator)
1540{
1541   RADV_FROM_HANDLE(radv_device, device, _device);
1542   RADV_FROM_HANDLE(radv_sampler_ycbcr_conversion, ycbcr_conversion, ycbcrConversion);
1543
1544   if (!ycbcr_conversion)
1545      return;
1546
1547   vk_object_base_finish(&ycbcr_conversion->base);
1548   vk_free2(&device->vk.alloc, pAllocator, ycbcr_conversion);
1549}
1550