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