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