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 
36 static bool
has_equal_immutable_samplers(const VkSampler * samplers,uint32_t count)37 has_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 
50 static bool
radv_mutable_descriptor_type_size_alignment(const VkMutableDescriptorTypeListVALVE * list,uint64_t * out_size,uint64_t * out_align)51 radv_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 
90 VkResult
radv_CreateDescriptorSetLayout(VkDevice _device,const VkDescriptorSetLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorSetLayout * pSetLayout)91 radv_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 
338 void
radv_DestroyDescriptorSetLayout(VkDevice _device,VkDescriptorSetLayout _set_layout,const VkAllocationCallbacks * pAllocator)339 radv_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 
352 void
radv_GetDescriptorSetLayoutSupport(VkDevice device,const VkDescriptorSetLayoutCreateInfo * pCreateInfo,VkDescriptorSetLayoutSupport * pSupport)353 radv_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 
469 VkResult
radv_CreatePipelineLayout(VkDevice _device,const VkPipelineLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipelineLayout * pPipelineLayout)470 radv_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 
533 void
radv_DestroyPipelineLayout(VkDevice _device,VkPipelineLayout _pipelineLayout,const VkAllocationCallbacks * pAllocator)534 radv_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 
547 static VkResult
radv_descriptor_set_create(struct radv_device * device,struct radv_descriptor_pool * pool,const struct radv_descriptor_set_layout * layout,const uint32_t * variable_count,struct radv_descriptor_set ** out_set)548 radv_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 
673 static void
radv_descriptor_set_destroy(struct radv_device * device,struct radv_descriptor_pool * pool,struct radv_descriptor_set * set,bool free_bo)674 radv_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 
693 static void
radv_destroy_descriptor_pool(struct radv_device * device,const VkAllocationCallbacks * pAllocator,struct radv_descriptor_pool * pool)694 radv_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 
712 VkResult
radv_CreateDescriptorPool(VkDevice _device,const VkDescriptorPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorPool * pDescriptorPool)713 radv_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 
849 void
radv_DestroyDescriptorPool(VkDevice _device,VkDescriptorPool _pool,const VkAllocationCallbacks * pAllocator)850 radv_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 
862 VkResult
radv_ResetDescriptorPool(VkDevice _device,VkDescriptorPool descriptorPool,VkDescriptorPoolResetFlags flags)863 radv_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 
882 VkResult
radv_AllocateDescriptorSets(VkDevice _device,const VkDescriptorSetAllocateInfo * pAllocateInfo,VkDescriptorSet * pDescriptorSets)883 radv_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 
927 VkResult
radv_FreeDescriptorSets(VkDevice _device,VkDescriptorPool descriptorPool,uint32_t count,const VkDescriptorSet * pDescriptorSets)928 radv_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 
943 static void
write_texel_buffer_descriptor(struct radv_device * device,struct radv_cmd_buffer * cmd_buffer,unsigned * dst,struct radeon_winsys_bo ** buffer_list,const VkBufferView _buffer_view)944 write_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 
965 static void
write_buffer_descriptor(struct radv_device * device,struct radv_cmd_buffer * cmd_buffer,unsigned * dst,struct radeon_winsys_bo ** buffer_list,const VkDescriptorBufferInfo * buffer_info)966 write_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 
1017 static void
write_block_descriptor(struct radv_device * device,struct radv_cmd_buffer * cmd_buffer,void * dst,const VkWriteDescriptorSet * writeset)1018 write_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 
1027 static void
write_dynamic_buffer_descriptor(struct radv_device * device,struct radv_descriptor_range * range,struct radeon_winsys_bo ** buffer_list,const VkDescriptorBufferInfo * buffer_info)1028 write_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 
1062 static void
write_image_descriptor(struct radv_device * device,struct radv_cmd_buffer * cmd_buffer,unsigned size,unsigned * dst,struct radeon_winsys_bo ** buffer_list,VkDescriptorType descriptor_type,const VkDescriptorImageInfo * image_info)1063 write_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 
1092 static void
write_combined_image_sampler_descriptor(struct radv_device * device,struct radv_cmd_buffer * cmd_buffer,unsigned sampler_offset,unsigned * dst,struct radeon_winsys_bo ** buffer_list,VkDescriptorType descriptor_type,const VkDescriptorImageInfo * image_info,bool has_sampler)1093 write_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 
1108 static void
write_sampler_descriptor(struct radv_device * device,unsigned * dst,const VkDescriptorImageInfo * image_info)1109 write_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 
1117 static void
write_accel_struct(void * ptr,VkAccelerationStructureKHR _accel_struct)1118 write_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 
1125 void
radv_update_descriptor_sets(struct radv_device * device,struct radv_cmd_buffer * cmd_buffer,VkDescriptorSet dstSetOverride,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)1126 radv_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 
1293 void
radv_UpdateDescriptorSets(VkDevice _device,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)1294 radv_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 
1305 VkResult
radv_CreateDescriptorUpdateTemplate(VkDevice _device,const VkDescriptorUpdateTemplateCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorUpdateTemplate * pDescriptorUpdateTemplate)1306 radv_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 
1400 void
radv_DestroyDescriptorUpdateTemplate(VkDevice _device,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const VkAllocationCallbacks * pAllocator)1401 radv_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 
1415 void
radv_update_descriptor_set_with_template(struct radv_device * device,struct radv_cmd_buffer * cmd_buffer,struct radv_descriptor_set * set,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const void * pData)1416 radv_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 
1497 void
radv_UpdateDescriptorSetWithTemplate(VkDevice _device,VkDescriptorSet descriptorSet,VkDescriptorUpdateTemplate descriptorUpdateTemplate,const void * pData)1498 radv_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 
1508 VkResult
radv_CreateSamplerYcbcrConversion(VkDevice _device,const VkSamplerYcbcrConversionCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSamplerYcbcrConversion * pYcbcrConversion)1509 radv_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 
1537 void
radv_DestroySamplerYcbcrConversion(VkDevice _device,VkSamplerYcbcrConversion ycbcrConversion,const VkAllocationCallbacks * pAllocator)1538 radv_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