radv: Don't store buffer references in the descriptor set.
[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
34
35 static bool has_equal_immutable_samplers(const VkSampler *samplers, uint32_t count)
36 {
37 if (!samplers)
38 return false;
39 for(uint32_t i = 1; i < count; ++i) {
40 if (memcmp(radv_sampler_from_handle(samplers[0])->state,
41 radv_sampler_from_handle(samplers[i])->state, 16)) {
42 return false;
43 }
44 }
45 return true;
46 }
47
48 VkResult radv_CreateDescriptorSetLayout(
49 VkDevice _device,
50 const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
51 const VkAllocationCallbacks* pAllocator,
52 VkDescriptorSetLayout* pSetLayout)
53 {
54 RADV_FROM_HANDLE(radv_device, device, _device);
55 struct radv_descriptor_set_layout *set_layout;
56
57 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
58
59 uint32_t max_binding = 0;
60 uint32_t immutable_sampler_count = 0;
61 for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) {
62 max_binding = MAX2(max_binding, pCreateInfo->pBindings[j].binding);
63 if (pCreateInfo->pBindings[j].pImmutableSamplers)
64 immutable_sampler_count += pCreateInfo->pBindings[j].descriptorCount;
65 }
66
67 uint32_t samplers_offset = sizeof(struct radv_descriptor_set_layout) +
68 (max_binding + 1) * sizeof(set_layout->binding[0]);
69 size_t size = samplers_offset + immutable_sampler_count * 4 * sizeof(uint32_t);
70
71 set_layout = vk_alloc2(&device->alloc, pAllocator, size, 8,
72 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
73 if (!set_layout)
74 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
75
76 set_layout->flags = pCreateInfo->flags;
77
78 /* We just allocate all the samplers at the end of the struct */
79 uint32_t *samplers = (uint32_t*)&set_layout->binding[max_binding + 1];
80
81 set_layout->binding_count = max_binding + 1;
82 set_layout->shader_stages = 0;
83 set_layout->dynamic_shader_stages = 0;
84 set_layout->has_immutable_samplers = false;
85 set_layout->size = 0;
86
87 memset(set_layout->binding, 0, size - sizeof(struct radv_descriptor_set_layout));
88
89 uint32_t dynamic_offset_count = 0;
90
91 for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) {
92 const VkDescriptorSetLayoutBinding *binding = &pCreateInfo->pBindings[j];
93 uint32_t b = binding->binding;
94 uint32_t alignment;
95
96 switch (binding->descriptorType) {
97 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
98 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
99 assert(!(pCreateInfo->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
100 set_layout->binding[b].dynamic_offset_count = 1;
101 set_layout->dynamic_shader_stages |= binding->stageFlags;
102 set_layout->binding[b].size = 0;
103 alignment = 1;
104 break;
105 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
106 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
107 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
108 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
109 set_layout->binding[b].size = 16;
110 alignment = 16;
111 break;
112 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
113 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
114 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
115 /* main descriptor + fmask descriptor */
116 set_layout->binding[b].size = 64;
117 alignment = 32;
118 break;
119 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
120 /* main descriptor + fmask descriptor + sampler */
121 set_layout->binding[b].size = 96;
122 alignment = 32;
123 break;
124 case VK_DESCRIPTOR_TYPE_SAMPLER:
125 set_layout->binding[b].size = 16;
126 alignment = 16;
127 break;
128 default:
129 unreachable("unknown descriptor type\n");
130 break;
131 }
132
133 set_layout->size = align(set_layout->size, alignment);
134 set_layout->binding[b].type = binding->descriptorType;
135 set_layout->binding[b].array_size = binding->descriptorCount;
136 set_layout->binding[b].offset = set_layout->size;
137 set_layout->binding[b].dynamic_offset_offset = dynamic_offset_count;
138
139 if (binding->pImmutableSamplers) {
140 set_layout->binding[b].immutable_samplers_offset = samplers_offset;
141 set_layout->binding[b].immutable_samplers_equal =
142 has_equal_immutable_samplers(binding->pImmutableSamplers, binding->descriptorCount);
143 set_layout->has_immutable_samplers = true;
144
145
146 for (uint32_t i = 0; i < binding->descriptorCount; i++)
147 memcpy(samplers + 4 * i, &radv_sampler_from_handle(binding->pImmutableSamplers[i])->state, 16);
148
149 /* Don't reserve space for the samplers if they're not accessed. */
150 if (set_layout->binding[b].immutable_samplers_equal) {
151 if (binding->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
152 set_layout->binding[b].size -= 32;
153 else if (binding->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
154 set_layout->binding[b].size -= 16;
155 }
156 samplers += 4 * binding->descriptorCount;
157 samplers_offset += 4 * sizeof(uint32_t) * binding->descriptorCount;
158 }
159
160 set_layout->size += binding->descriptorCount * set_layout->binding[b].size;
161 dynamic_offset_count += binding->descriptorCount *
162 set_layout->binding[b].dynamic_offset_count;
163 set_layout->shader_stages |= binding->stageFlags;
164 }
165
166 set_layout->dynamic_offset_count = dynamic_offset_count;
167
168 *pSetLayout = radv_descriptor_set_layout_to_handle(set_layout);
169
170 return VK_SUCCESS;
171 }
172
173 void radv_DestroyDescriptorSetLayout(
174 VkDevice _device,
175 VkDescriptorSetLayout _set_layout,
176 const VkAllocationCallbacks* pAllocator)
177 {
178 RADV_FROM_HANDLE(radv_device, device, _device);
179 RADV_FROM_HANDLE(radv_descriptor_set_layout, set_layout, _set_layout);
180
181 if (!set_layout)
182 return;
183
184 vk_free2(&device->alloc, pAllocator, set_layout);
185 }
186
187 void radv_GetDescriptorSetLayoutSupport(VkDevice device,
188 const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
189 VkDescriptorSetLayoutSupport* pSupport)
190 {
191 bool supported = true;
192 uint64_t size = 0;
193 for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
194 const VkDescriptorSetLayoutBinding *binding = &pCreateInfo->pBindings[i];
195
196 if (binding->descriptorCount == 0)
197 continue;
198
199 uint64_t descriptor_size = 0;
200 uint64_t descriptor_alignment = 1;
201 switch (binding->descriptorType) {
202 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
203 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
204 break;
205 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
206 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
207 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
208 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
209 descriptor_size = 16;
210 descriptor_alignment = 16;
211 break;
212 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
213 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
214 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
215 descriptor_size = 64;
216 descriptor_alignment = 32;
217 break;
218 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
219 if (!has_equal_immutable_samplers(binding->pImmutableSamplers, binding->descriptorCount)) {
220 descriptor_size = 64;
221 } else {
222 descriptor_size = 96;
223 }
224 descriptor_alignment = 32;
225 break;
226 case VK_DESCRIPTOR_TYPE_SAMPLER:
227 if (!has_equal_immutable_samplers(binding->pImmutableSamplers, binding->descriptorCount)) {
228 descriptor_size = 16;
229 descriptor_alignment = 16;
230 }
231 break;
232 default:
233 unreachable("unknown descriptor type\n");
234 break;
235 }
236
237 if (size && !align_u64(size, descriptor_alignment)) {
238 supported = false;
239 }
240 size = align_u64(size, descriptor_alignment);
241 if (descriptor_size && (UINT64_MAX - size) / descriptor_size < binding->descriptorCount) {
242 supported = false;
243 }
244 size += binding->descriptorCount * descriptor_size;
245 }
246
247 pSupport->supported = supported;
248 }
249
250 /*
251 * Pipeline layouts. These have nothing to do with the pipeline. They are
252 * just muttiple descriptor set layouts pasted together
253 */
254
255 VkResult radv_CreatePipelineLayout(
256 VkDevice _device,
257 const VkPipelineLayoutCreateInfo* pCreateInfo,
258 const VkAllocationCallbacks* pAllocator,
259 VkPipelineLayout* pPipelineLayout)
260 {
261 RADV_FROM_HANDLE(radv_device, device, _device);
262 struct radv_pipeline_layout *layout;
263 struct mesa_sha1 ctx;
264
265 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
266
267 layout = vk_alloc2(&device->alloc, pAllocator, sizeof(*layout), 8,
268 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
269 if (layout == NULL)
270 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
271
272 layout->num_sets = pCreateInfo->setLayoutCount;
273
274 unsigned dynamic_offset_count = 0;
275
276
277 _mesa_sha1_init(&ctx);
278 for (uint32_t set = 0; set < pCreateInfo->setLayoutCount; set++) {
279 RADV_FROM_HANDLE(radv_descriptor_set_layout, set_layout,
280 pCreateInfo->pSetLayouts[set]);
281 layout->set[set].layout = set_layout;
282
283 layout->set[set].dynamic_offset_start = dynamic_offset_count;
284 for (uint32_t b = 0; b < set_layout->binding_count; b++) {
285 dynamic_offset_count += set_layout->binding[b].array_size * set_layout->binding[b].dynamic_offset_count;
286 if (set_layout->binding[b].immutable_samplers_offset)
287 _mesa_sha1_update(&ctx, radv_immutable_samplers(set_layout, set_layout->binding + b),
288 set_layout->binding[b].array_size * 4 * sizeof(uint32_t));
289 }
290 _mesa_sha1_update(&ctx, set_layout->binding,
291 sizeof(set_layout->binding[0]) * set_layout->binding_count);
292 }
293
294 layout->dynamic_offset_count = dynamic_offset_count;
295 layout->push_constant_size = 0;
296
297 for (unsigned i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
298 const VkPushConstantRange *range = pCreateInfo->pPushConstantRanges + i;
299 layout->push_constant_size = MAX2(layout->push_constant_size,
300 range->offset + range->size);
301 }
302
303 layout->push_constant_size = align(layout->push_constant_size, 16);
304 _mesa_sha1_update(&ctx, &layout->push_constant_size,
305 sizeof(layout->push_constant_size));
306 _mesa_sha1_final(&ctx, layout->sha1);
307 *pPipelineLayout = radv_pipeline_layout_to_handle(layout);
308
309 return VK_SUCCESS;
310 }
311
312 void radv_DestroyPipelineLayout(
313 VkDevice _device,
314 VkPipelineLayout _pipelineLayout,
315 const VkAllocationCallbacks* pAllocator)
316 {
317 RADV_FROM_HANDLE(radv_device, device, _device);
318 RADV_FROM_HANDLE(radv_pipeline_layout, pipeline_layout, _pipelineLayout);
319
320 if (!pipeline_layout)
321 return;
322 vk_free2(&device->alloc, pAllocator, pipeline_layout);
323 }
324
325 #define EMPTY 1
326
327 static VkResult
328 radv_descriptor_set_create(struct radv_device *device,
329 struct radv_descriptor_pool *pool,
330 const struct radv_descriptor_set_layout *layout,
331 struct radv_descriptor_set **out_set)
332 {
333 struct radv_descriptor_set *set;
334 unsigned range_offset = sizeof(struct radv_descriptor_set);
335 unsigned mem_size = range_offset +
336 sizeof(struct radv_descriptor_range) * layout->dynamic_offset_count;
337
338 if (pool->host_memory_base) {
339 if (pool->host_memory_end - pool->host_memory_ptr < mem_size)
340 return vk_error(VK_ERROR_OUT_OF_POOL_MEMORY_KHR);
341
342 set = (struct radv_descriptor_set*)pool->host_memory_ptr;
343 pool->host_memory_ptr += mem_size;
344 } else {
345 set = vk_alloc2(&device->alloc, NULL, mem_size, 8,
346 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
347
348 if (!set)
349 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
350 }
351
352 memset(set, 0, mem_size);
353
354 if (layout->dynamic_offset_count) {
355 set->dynamic_descriptors = (struct radv_descriptor_range*)((uint8_t*)set + range_offset);
356 }
357
358 set->layout = layout;
359 if (layout->size) {
360 uint32_t layout_size = align_u32(layout->size, 32);
361 set->size = layout->size;
362
363 if (!pool->host_memory_base && pool->entry_count == pool->max_entry_count) {
364 vk_free2(&device->alloc, NULL, set);
365 return vk_error(VK_ERROR_OUT_OF_POOL_MEMORY_KHR);
366 }
367
368 /* try to allocate linearly first, so that we don't spend
369 * time looking for gaps if the app only allocates &
370 * resets via the pool. */
371 if (pool->current_offset + layout_size <= pool->size) {
372 set->bo = pool->bo;
373 set->mapped_ptr = (uint32_t*)(pool->mapped_ptr + pool->current_offset);
374 set->va = radv_buffer_get_va(set->bo) + pool->current_offset;
375 if (!pool->host_memory_base) {
376 pool->entries[pool->entry_count].offset = pool->current_offset;
377 pool->entries[pool->entry_count].size = layout_size;
378 pool->entries[pool->entry_count].set = set;
379 pool->entry_count++;
380 }
381 pool->current_offset += layout_size;
382 } else if (!pool->host_memory_base) {
383 uint64_t offset = 0;
384 int index;
385
386 for (index = 0; index < pool->entry_count; ++index) {
387 if (pool->entries[index].offset - offset >= layout_size)
388 break;
389 offset = pool->entries[index].offset + pool->entries[index].size;
390 }
391
392 if (pool->size - offset < layout_size) {
393 vk_free2(&device->alloc, NULL, set);
394 return vk_error(VK_ERROR_OUT_OF_POOL_MEMORY_KHR);
395 }
396 set->bo = pool->bo;
397 set->mapped_ptr = (uint32_t*)(pool->mapped_ptr + offset);
398 set->va = radv_buffer_get_va(set->bo) + offset;
399 memmove(&pool->entries[index + 1], &pool->entries[index],
400 sizeof(pool->entries[0]) * (pool->entry_count - index));
401 pool->entries[index].offset = offset;
402 pool->entries[index].size = layout_size;
403 pool->entries[index].set = set;
404 pool->entry_count++;
405 } else
406 return vk_error(VK_ERROR_OUT_OF_POOL_MEMORY_KHR);
407 }
408
409 if (layout->has_immutable_samplers) {
410 for (unsigned i = 0; i < layout->binding_count; ++i) {
411 if (!layout->binding[i].immutable_samplers_offset ||
412 layout->binding[i].immutable_samplers_equal)
413 continue;
414
415 unsigned offset = layout->binding[i].offset / 4;
416 if (layout->binding[i].type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
417 offset += 16;
418
419 const uint32_t *samplers = (const uint32_t*)((const char*)layout + layout->binding[i].immutable_samplers_offset);
420 for (unsigned j = 0; j < layout->binding[i].array_size; ++j) {
421 memcpy(set->mapped_ptr + offset, samplers + 4 * j, 16);
422 offset += layout->binding[i].size / 4;
423 }
424
425 }
426 }
427 *out_set = set;
428 return VK_SUCCESS;
429 }
430
431 static void
432 radv_descriptor_set_destroy(struct radv_device *device,
433 struct radv_descriptor_pool *pool,
434 struct radv_descriptor_set *set,
435 bool free_bo)
436 {
437 assert(!pool->host_memory_base);
438
439 if (free_bo && set->size && !pool->host_memory_base) {
440 uint32_t offset = (uint8_t*)set->mapped_ptr - pool->mapped_ptr;
441 for (int i = 0; i < pool->entry_count; ++i) {
442 if (pool->entries[i].offset == offset) {
443 memmove(&pool->entries[i], &pool->entries[i+1],
444 sizeof(pool->entries[i]) * (pool->entry_count - i - 1));
445 --pool->entry_count;
446 break;
447 }
448 }
449 }
450 vk_free2(&device->alloc, NULL, set);
451 }
452
453 VkResult radv_CreateDescriptorPool(
454 VkDevice _device,
455 const VkDescriptorPoolCreateInfo* pCreateInfo,
456 const VkAllocationCallbacks* pAllocator,
457 VkDescriptorPool* pDescriptorPool)
458 {
459 RADV_FROM_HANDLE(radv_device, device, _device);
460 struct radv_descriptor_pool *pool;
461 int size = sizeof(struct radv_descriptor_pool);
462 uint64_t bo_size = 0, bo_count = 0, range_count = 0;
463
464
465 for (unsigned i = 0; i < pCreateInfo->poolSizeCount; ++i) {
466 if (pCreateInfo->pPoolSizes[i].type != VK_DESCRIPTOR_TYPE_SAMPLER)
467 bo_count += pCreateInfo->pPoolSizes[i].descriptorCount;
468
469 switch(pCreateInfo->pPoolSizes[i].type) {
470 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
471 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
472 range_count += pCreateInfo->pPoolSizes[i].descriptorCount;
473 break;
474 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
475 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
476 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
477 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
478 case VK_DESCRIPTOR_TYPE_SAMPLER:
479 /* 32 as we may need to align for images */
480 bo_size += 32 * pCreateInfo->pPoolSizes[i].descriptorCount;
481 break;
482 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
483 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
484 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
485 bo_size += 64 * pCreateInfo->pPoolSizes[i].descriptorCount;
486 break;
487 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
488 bo_size += 96 * pCreateInfo->pPoolSizes[i].descriptorCount;
489 break;
490 default:
491 unreachable("unknown descriptor type\n");
492 break;
493 }
494 }
495
496 if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT)) {
497 uint64_t host_size = pCreateInfo->maxSets * sizeof(struct radv_descriptor_set);
498 host_size += sizeof(struct radeon_winsys_bo*) * bo_count;
499 host_size += sizeof(struct radv_descriptor_range) * range_count;
500 size += host_size;
501 } else {
502 size += sizeof(struct radv_descriptor_pool_entry) * pCreateInfo->maxSets;
503 }
504
505 pool = vk_alloc2(&device->alloc, pAllocator, size, 8,
506 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
507 if (!pool)
508 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
509
510 memset(pool, 0, sizeof(*pool));
511
512 if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT)) {
513 pool->host_memory_base = (uint8_t*)pool + sizeof(struct radv_descriptor_pool);
514 pool->host_memory_ptr = pool->host_memory_base;
515 pool->host_memory_end = (uint8_t*)pool + size;
516 }
517
518 if (bo_size) {
519 pool->bo = device->ws->buffer_create(device->ws, bo_size, 32,
520 RADEON_DOMAIN_VRAM,
521 RADEON_FLAG_NO_INTERPROCESS_SHARING |
522 RADEON_FLAG_READ_ONLY);
523 pool->mapped_ptr = (uint8_t*)device->ws->buffer_map(pool->bo);
524 }
525 pool->size = bo_size;
526 pool->max_entry_count = pCreateInfo->maxSets;
527
528 *pDescriptorPool = radv_descriptor_pool_to_handle(pool);
529 return VK_SUCCESS;
530 }
531
532 void radv_DestroyDescriptorPool(
533 VkDevice _device,
534 VkDescriptorPool _pool,
535 const VkAllocationCallbacks* pAllocator)
536 {
537 RADV_FROM_HANDLE(radv_device, device, _device);
538 RADV_FROM_HANDLE(radv_descriptor_pool, pool, _pool);
539
540 if (!pool)
541 return;
542
543 if (!pool->host_memory_base) {
544 for(int i = 0; i < pool->entry_count; ++i) {
545 radv_descriptor_set_destroy(device, pool, pool->entries[i].set, false);
546 }
547 }
548
549 if (pool->bo)
550 device->ws->buffer_destroy(pool->bo);
551 vk_free2(&device->alloc, pAllocator, pool);
552 }
553
554 VkResult radv_ResetDescriptorPool(
555 VkDevice _device,
556 VkDescriptorPool descriptorPool,
557 VkDescriptorPoolResetFlags flags)
558 {
559 RADV_FROM_HANDLE(radv_device, device, _device);
560 RADV_FROM_HANDLE(radv_descriptor_pool, pool, descriptorPool);
561
562 if (!pool->host_memory_base) {
563 for(int i = 0; i < pool->entry_count; ++i) {
564 radv_descriptor_set_destroy(device, pool, pool->entries[i].set, false);
565 }
566 pool->entry_count = 0;
567 }
568
569 pool->current_offset = 0;
570 pool->host_memory_ptr = pool->host_memory_base;
571
572 return VK_SUCCESS;
573 }
574
575 VkResult radv_AllocateDescriptorSets(
576 VkDevice _device,
577 const VkDescriptorSetAllocateInfo* pAllocateInfo,
578 VkDescriptorSet* pDescriptorSets)
579 {
580 RADV_FROM_HANDLE(radv_device, device, _device);
581 RADV_FROM_HANDLE(radv_descriptor_pool, pool, pAllocateInfo->descriptorPool);
582
583 VkResult result = VK_SUCCESS;
584 uint32_t i;
585 struct radv_descriptor_set *set = NULL;
586
587 /* allocate a set of buffers for each shader to contain descriptors */
588 for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
589 RADV_FROM_HANDLE(radv_descriptor_set_layout, layout,
590 pAllocateInfo->pSetLayouts[i]);
591
592 assert(!(layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
593
594 result = radv_descriptor_set_create(device, pool, layout, &set);
595 if (result != VK_SUCCESS)
596 break;
597
598 pDescriptorSets[i] = radv_descriptor_set_to_handle(set);
599 }
600
601 if (result != VK_SUCCESS)
602 radv_FreeDescriptorSets(_device, pAllocateInfo->descriptorPool,
603 i, pDescriptorSets);
604 return result;
605 }
606
607 VkResult radv_FreeDescriptorSets(
608 VkDevice _device,
609 VkDescriptorPool descriptorPool,
610 uint32_t count,
611 const VkDescriptorSet* pDescriptorSets)
612 {
613 RADV_FROM_HANDLE(radv_device, device, _device);
614 RADV_FROM_HANDLE(radv_descriptor_pool, pool, descriptorPool);
615
616 for (uint32_t i = 0; i < count; i++) {
617 RADV_FROM_HANDLE(radv_descriptor_set, set, pDescriptorSets[i]);
618
619 if (set && !pool->host_memory_base)
620 radv_descriptor_set_destroy(device, pool, set, true);
621 }
622 return VK_SUCCESS;
623 }
624
625 static void write_texel_buffer_descriptor(struct radv_device *device,
626 unsigned *dst,
627 const VkBufferView _buffer_view)
628 {
629 RADV_FROM_HANDLE(radv_buffer_view, buffer_view, _buffer_view);
630
631 memcpy(dst, buffer_view->state, 4 * 4);
632 }
633
634 static void write_buffer_descriptor(struct radv_device *device,
635 unsigned *dst,
636 const VkDescriptorBufferInfo *buffer_info)
637 {
638 RADV_FROM_HANDLE(radv_buffer, buffer, buffer_info->buffer);
639 uint64_t va = radv_buffer_get_va(buffer->bo);
640 uint32_t range = buffer_info->range;
641
642 if (buffer_info->range == VK_WHOLE_SIZE)
643 range = buffer->size - buffer_info->offset;
644
645 va += buffer_info->offset + buffer->offset;
646 dst[0] = va;
647 dst[1] = S_008F04_BASE_ADDRESS_HI(va >> 32);
648 dst[2] = range;
649 dst[3] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
650 S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
651 S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
652 S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
653 S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
654 S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
655
656 }
657
658 static void write_dynamic_buffer_descriptor(struct radv_device *device,
659 struct radv_descriptor_range *range,
660 const VkDescriptorBufferInfo *buffer_info)
661 {
662 RADV_FROM_HANDLE(radv_buffer, buffer, buffer_info->buffer);
663 uint64_t va = radv_buffer_get_va(buffer->bo);
664 unsigned size = buffer_info->range;
665
666 if (buffer_info->range == VK_WHOLE_SIZE)
667 size = buffer->size - buffer_info->offset;
668
669 va += buffer_info->offset + buffer->offset;
670 range->va = va;
671 range->size = size;
672 }
673
674 static void
675 write_image_descriptor(struct radv_device *device,
676 unsigned *dst,
677 VkDescriptorType descriptor_type,
678 const VkDescriptorImageInfo *image_info)
679 {
680 RADV_FROM_HANDLE(radv_image_view, iview, image_info->imageView);
681 uint32_t *descriptor;
682
683 if (descriptor_type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) {
684 descriptor = iview->storage_descriptor;
685 } else {
686 descriptor = iview->descriptor;
687 }
688
689 memcpy(dst, descriptor, 16 * 4);
690 }
691
692 static void
693 write_combined_image_sampler_descriptor(struct radv_device *device,
694 unsigned *dst,
695 VkDescriptorType descriptor_type,
696 const VkDescriptorImageInfo *image_info,
697 bool has_sampler)
698 {
699 RADV_FROM_HANDLE(radv_sampler, sampler, image_info->sampler);
700
701 write_image_descriptor(device, dst, descriptor_type, image_info);
702 /* copy over sampler state */
703 if (has_sampler)
704 memcpy(dst + 16, sampler->state, 16);
705 }
706
707 static void
708 write_sampler_descriptor(struct radv_device *device,
709 unsigned *dst,
710 const VkDescriptorImageInfo *image_info)
711 {
712 RADV_FROM_HANDLE(radv_sampler, sampler, image_info->sampler);
713
714 memcpy(dst, sampler->state, 16);
715 }
716
717 void radv_update_descriptor_sets(
718 struct radv_device* device,
719 struct radv_cmd_buffer* cmd_buffer,
720 VkDescriptorSet dstSetOverride,
721 uint32_t descriptorWriteCount,
722 const VkWriteDescriptorSet* pDescriptorWrites,
723 uint32_t descriptorCopyCount,
724 const VkCopyDescriptorSet* pDescriptorCopies)
725 {
726 uint32_t i, j;
727 for (i = 0; i < descriptorWriteCount; i++) {
728 const VkWriteDescriptorSet *writeset = &pDescriptorWrites[i];
729 RADV_FROM_HANDLE(radv_descriptor_set, set,
730 dstSetOverride ? dstSetOverride : writeset->dstSet);
731 const struct radv_descriptor_set_binding_layout *binding_layout =
732 set->layout->binding + writeset->dstBinding;
733 uint32_t *ptr = set->mapped_ptr;
734
735 /* Immutable samplers are not copied into push descriptors when they are
736 * allocated, so if we are writing push descriptors we have to copy the
737 * immutable samplers into them now.
738 */
739 const bool copy_immutable_samplers = cmd_buffer &&
740 binding_layout->immutable_samplers_offset && !binding_layout->immutable_samplers_equal;
741 const uint32_t *samplers = radv_immutable_samplers(set->layout, binding_layout);
742
743 ptr += binding_layout->offset / 4;
744 ptr += binding_layout->size * writeset->dstArrayElement / 4;
745 for (j = 0; j < writeset->descriptorCount; ++j) {
746 switch(writeset->descriptorType) {
747 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
748 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
749 unsigned idx = writeset->dstArrayElement + j;
750 idx += binding_layout->dynamic_offset_offset;
751 assert(!(set->layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
752 write_dynamic_buffer_descriptor(device, set->dynamic_descriptors + idx,
753 writeset->pBufferInfo + j);
754 break;
755 }
756 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
757 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
758 write_buffer_descriptor(device, ptr, writeset->pBufferInfo + j);
759 break;
760 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
761 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
762 write_texel_buffer_descriptor(device, ptr, writeset->pTexelBufferView[j]);
763 break;
764 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
765 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
766 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
767 write_image_descriptor(device, ptr, writeset->descriptorType,
768 writeset->pImageInfo + j);
769 break;
770 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
771 write_combined_image_sampler_descriptor(device, ptr,
772 writeset->descriptorType,
773 writeset->pImageInfo + j,
774 !binding_layout->immutable_samplers_offset);
775 if (copy_immutable_samplers) {
776 const unsigned idx = writeset->dstArrayElement + j;
777 memcpy(ptr + 16, samplers + 4 * idx, 16);
778 }
779 break;
780 case VK_DESCRIPTOR_TYPE_SAMPLER:
781 if (!binding_layout->immutable_samplers_offset) {
782 write_sampler_descriptor(device, ptr,
783 writeset->pImageInfo + j);
784 } else if (copy_immutable_samplers) {
785 unsigned idx = writeset->dstArrayElement + j;
786 memcpy(ptr, samplers + 4 * idx, 16);
787 }
788 break;
789 default:
790 unreachable("unimplemented descriptor type");
791 break;
792 }
793 ptr += binding_layout->size / 4;
794 }
795
796 }
797
798 for (i = 0; i < descriptorCopyCount; i++) {
799 const VkCopyDescriptorSet *copyset = &pDescriptorCopies[i];
800 RADV_FROM_HANDLE(radv_descriptor_set, src_set,
801 copyset->srcSet);
802 RADV_FROM_HANDLE(radv_descriptor_set, dst_set,
803 copyset->dstSet);
804 const struct radv_descriptor_set_binding_layout *src_binding_layout =
805 src_set->layout->binding + copyset->srcBinding;
806 const struct radv_descriptor_set_binding_layout *dst_binding_layout =
807 dst_set->layout->binding + copyset->dstBinding;
808 uint32_t *src_ptr = src_set->mapped_ptr;
809 uint32_t *dst_ptr = dst_set->mapped_ptr;
810
811 src_ptr += src_binding_layout->offset / 4;
812 dst_ptr += dst_binding_layout->offset / 4;
813
814 src_ptr += src_binding_layout->size * copyset->srcArrayElement / 4;
815 dst_ptr += dst_binding_layout->size * copyset->dstArrayElement / 4;
816
817 for (j = 0; j < copyset->descriptorCount; ++j) {
818 switch (src_binding_layout->type) {
819 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
820 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
821 unsigned src_idx = copyset->srcArrayElement + j;
822 unsigned dst_idx = copyset->dstArrayElement + j;
823 struct radv_descriptor_range *src_range, *dst_range;
824 src_idx += src_binding_layout->dynamic_offset_offset;
825 dst_idx += dst_binding_layout->dynamic_offset_offset;
826
827 src_range = src_set->dynamic_descriptors + src_idx;
828 dst_range = dst_set->dynamic_descriptors + dst_idx;
829 *dst_range = *src_range;
830 break;
831 }
832 default:
833 memcpy(dst_ptr, src_ptr, src_binding_layout->size);
834 }
835 src_ptr += src_binding_layout->size / 4;
836 dst_ptr += dst_binding_layout->size / 4;
837 }
838 }
839 }
840
841 void radv_UpdateDescriptorSets(
842 VkDevice _device,
843 uint32_t descriptorWriteCount,
844 const VkWriteDescriptorSet* pDescriptorWrites,
845 uint32_t descriptorCopyCount,
846 const VkCopyDescriptorSet* pDescriptorCopies)
847 {
848 RADV_FROM_HANDLE(radv_device, device, _device);
849
850 radv_update_descriptor_sets(device, NULL, VK_NULL_HANDLE, descriptorWriteCount, pDescriptorWrites,
851 descriptorCopyCount, pDescriptorCopies);
852 }
853
854 VkResult radv_CreateDescriptorUpdateTemplate(VkDevice _device,
855 const VkDescriptorUpdateTemplateCreateInfoKHR *pCreateInfo,
856 const VkAllocationCallbacks *pAllocator,
857 VkDescriptorUpdateTemplateKHR *pDescriptorUpdateTemplate)
858 {
859 RADV_FROM_HANDLE(radv_device, device, _device);
860 RADV_FROM_HANDLE(radv_descriptor_set_layout, set_layout, pCreateInfo->descriptorSetLayout);
861 const uint32_t entry_count = pCreateInfo->descriptorUpdateEntryCount;
862 const size_t size = sizeof(struct radv_descriptor_update_template) +
863 sizeof(struct radv_descriptor_update_template_entry) * entry_count;
864 struct radv_descriptor_update_template *templ;
865 uint32_t i;
866
867 templ = vk_alloc2(&device->alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
868 if (!templ)
869 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
870
871 templ->entry_count = entry_count;
872 templ->bind_point = pCreateInfo->pipelineBindPoint;
873
874 for (i = 0; i < entry_count; i++) {
875 const VkDescriptorUpdateTemplateEntryKHR *entry = &pCreateInfo->pDescriptorUpdateEntries[i];
876 const struct radv_descriptor_set_binding_layout *binding_layout =
877 set_layout->binding + entry->dstBinding;
878 const uint32_t *immutable_samplers = NULL;
879 uint32_t dst_offset;
880 uint32_t dst_stride;
881
882 /* dst_offset is an offset into dynamic_descriptors when the descriptor
883 is dynamic, and an offset into mapped_ptr otherwise */
884 switch (entry->descriptorType) {
885 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
886 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
887 assert(pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR);
888 dst_offset = binding_layout->dynamic_offset_offset + entry->dstArrayElement;
889 dst_stride = 0; /* Not used */
890 break;
891 default:
892 switch (entry->descriptorType) {
893 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
894 case VK_DESCRIPTOR_TYPE_SAMPLER:
895 /* Immutable samplers are copied into push descriptors when they are pushed */
896 if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR &&
897 binding_layout->immutable_samplers_offset && !binding_layout->immutable_samplers_equal) {
898 immutable_samplers = radv_immutable_samplers(set_layout, binding_layout) + entry->dstArrayElement * 4;
899 }
900 break;
901 default:
902 break;
903 }
904 dst_offset = binding_layout->offset / 4 + binding_layout->size * entry->dstArrayElement / 4;
905 dst_stride = binding_layout->size / 4;
906 break;
907 }
908
909 templ->entry[i] = (struct radv_descriptor_update_template_entry) {
910 .descriptor_type = entry->descriptorType,
911 .descriptor_count = entry->descriptorCount,
912 .src_offset = entry->offset,
913 .src_stride = entry->stride,
914 .dst_offset = dst_offset,
915 .dst_stride = dst_stride,
916 .has_sampler = !binding_layout->immutable_samplers_offset,
917 .immutable_samplers = immutable_samplers
918 };
919 }
920
921 *pDescriptorUpdateTemplate = radv_descriptor_update_template_to_handle(templ);
922 return VK_SUCCESS;
923 }
924
925 void radv_DestroyDescriptorUpdateTemplate(VkDevice _device,
926 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
927 const VkAllocationCallbacks *pAllocator)
928 {
929 RADV_FROM_HANDLE(radv_device, device, _device);
930 RADV_FROM_HANDLE(radv_descriptor_update_template, templ, descriptorUpdateTemplate);
931
932 if (!templ)
933 return;
934
935 vk_free2(&device->alloc, pAllocator, templ);
936 }
937
938 void radv_update_descriptor_set_with_template(struct radv_device *device,
939 struct radv_cmd_buffer *cmd_buffer,
940 struct radv_descriptor_set *set,
941 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
942 const void *pData)
943 {
944 RADV_FROM_HANDLE(radv_descriptor_update_template, templ, descriptorUpdateTemplate);
945 uint32_t i;
946
947 for (i = 0; i < templ->entry_count; ++i) {
948 uint32_t *pDst = set->mapped_ptr + templ->entry[i].dst_offset;
949 const uint8_t *pSrc = ((const uint8_t *) pData) + templ->entry[i].src_offset;
950 uint32_t j;
951
952 for (j = 0; j < templ->entry[i].descriptor_count; ++j) {
953 switch (templ->entry[i].descriptor_type) {
954 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
955 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
956 const unsigned idx = templ->entry[i].dst_offset + j;
957 assert(!(set->layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
958 write_dynamic_buffer_descriptor(device, set->dynamic_descriptors + idx,
959 (struct VkDescriptorBufferInfo *) pSrc);
960 break;
961 }
962 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
963 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
964 write_buffer_descriptor(device, pDst,
965 (struct VkDescriptorBufferInfo *) pSrc);
966 break;
967 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
968 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
969 write_texel_buffer_descriptor(device, pDst,
970 *(VkBufferView *) pSrc);
971 break;
972 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
973 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
974 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
975 write_image_descriptor(device, pDst,
976 templ->entry[i].descriptor_type,
977 (struct VkDescriptorImageInfo *) pSrc);
978 break;
979 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
980 write_combined_image_sampler_descriptor(device, pDst,
981 templ->entry[i].descriptor_type,
982 (struct VkDescriptorImageInfo *) pSrc,
983 templ->entry[i].has_sampler);
984 if (templ->entry[i].immutable_samplers)
985 memcpy(pDst + 16, templ->entry[i].immutable_samplers + 4 * j, 16);
986 break;
987 case VK_DESCRIPTOR_TYPE_SAMPLER:
988 if (templ->entry[i].has_sampler)
989 write_sampler_descriptor(device, pDst,
990 (struct VkDescriptorImageInfo *) pSrc);
991 else if (templ->entry[i].immutable_samplers)
992 memcpy(pDst, templ->entry[i].immutable_samplers + 4 * j, 16);
993 break;
994 default:
995 unreachable("unimplemented descriptor type");
996 break;
997 }
998 pSrc += templ->entry[i].src_stride;
999 pDst += templ->entry[i].dst_stride;
1000 }
1001 }
1002 }
1003
1004 void radv_UpdateDescriptorSetWithTemplate(VkDevice _device,
1005 VkDescriptorSet descriptorSet,
1006 VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
1007 const void *pData)
1008 {
1009 RADV_FROM_HANDLE(radv_device, device, _device);
1010 RADV_FROM_HANDLE(radv_descriptor_set, set, descriptorSet);
1011
1012 radv_update_descriptor_set_with_template(device, NULL, set, descriptorUpdateTemplate, pData);
1013 }
1014
1015
1016 VkResult radv_CreateSamplerYcbcrConversion(VkDevice device,
1017 const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
1018 const VkAllocationCallbacks* pAllocator,
1019 VkSamplerYcbcrConversion* pYcbcrConversion)
1020 {
1021 *pYcbcrConversion = VK_NULL_HANDLE;
1022 return VK_SUCCESS;
1023 }
1024
1025
1026 void radv_DestroySamplerYcbcrConversion(VkDevice device,
1027 VkSamplerYcbcrConversion ycbcrConversion,
1028 const VkAllocationCallbacks* pAllocator)
1029 {
1030 /* Do nothing. */
1031 }