/* * Copyright © 2021 Collabora Ltd. * * Derived from: * Copyright © 2016 Red Hat. * Copyright © 2016 Bas Nieuwenhuizen * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "genxml/gen_macros.h" #include "panvk_private.h" #include <assert.h> #include <fcntl.h> #include <stdbool.h> #include <string.h> #include <unistd.h> #include "util/mesa-sha1.h" #include "vk_descriptors.h" #include "vk_util.h" #include "pan_bo.h" #include "panvk_cs.h" #define PANVK_DESCRIPTOR_ALIGN 8 struct panvk_bview_desc { uint32_t elems; }; static void panvk_fill_bview_desc(struct panvk_bview_desc *desc, struct panvk_buffer_view *view) { desc->elems = view->elems; } struct panvk_image_desc { uint16_t width; uint16_t height; uint16_t depth; uint8_t levels; uint8_t samples; }; static void panvk_fill_image_desc(struct panvk_image_desc *desc, struct panvk_image_view *view) { desc->width = view->vk.extent.width - 1; desc->height = view->vk.extent.height - 1; desc->depth = view->vk.extent.depth - 1; desc->levels = view->vk.level_count; desc->samples = view->vk.image->samples; /* Stick array layer count after the last valid size component */ if (view->vk.image->image_type == VK_IMAGE_TYPE_1D) desc->height = view->vk.layer_count - 1; else if (view->vk.image->image_type == VK_IMAGE_TYPE_2D) desc->depth = view->vk.layer_count - 1; } VkResult panvk_per_arch(CreateDescriptorSetLayout)(VkDevice _device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDescriptorSetLayout *pSetLayout) { VK_FROM_HANDLE(panvk_device, device, _device); struct panvk_descriptor_set_layout *set_layout; VkDescriptorSetLayoutBinding *bindings = NULL; unsigned num_bindings = 0; VkResult result; if (pCreateInfo->bindingCount) { result = vk_create_sorted_bindings(pCreateInfo->pBindings, pCreateInfo->bindingCount, &bindings); if (result != VK_SUCCESS) return vk_error(device, result); num_bindings = bindings[pCreateInfo->bindingCount - 1].binding + 1; } unsigned num_immutable_samplers = 0; for (unsigned i = 0; i < pCreateInfo->bindingCount; i++) { if (bindings[i].pImmutableSamplers) num_immutable_samplers += bindings[i].descriptorCount; } size_t size = sizeof(*set_layout) + (sizeof(struct panvk_descriptor_set_binding_layout) * num_bindings) + (sizeof(struct panvk_sampler *) * num_immutable_samplers); set_layout = vk_descriptor_set_layout_zalloc(&device->vk, size); if (!set_layout) { result = VK_ERROR_OUT_OF_HOST_MEMORY; goto err_free_bindings; } struct panvk_sampler **immutable_samplers = (struct panvk_sampler **)((uint8_t *)set_layout + sizeof(*set_layout) + (sizeof(struct panvk_descriptor_set_binding_layout) * num_bindings)); set_layout->binding_count = num_bindings; unsigned sampler_idx = 0, tex_idx = 0, ubo_idx = 0; unsigned dyn_ubo_idx = 0, dyn_ssbo_idx = 0, img_idx = 0; uint32_t desc_ubo_size = 0; for (unsigned i = 0; i < pCreateInfo->bindingCount; i++) { const VkDescriptorSetLayoutBinding *binding = &bindings[i]; struct panvk_descriptor_set_binding_layout *binding_layout = &set_layout->bindings[binding->binding]; binding_layout->type = binding->descriptorType; binding_layout->array_size = binding->descriptorCount; binding_layout->shader_stages = binding->stageFlags; binding_layout->desc_ubo_stride = 0; if (binding->pImmutableSamplers) { binding_layout->immutable_samplers = immutable_samplers; immutable_samplers += binding_layout->array_size; for (unsigned j = 0; j < binding_layout->array_size; j++) { VK_FROM_HANDLE(panvk_sampler, sampler, binding->pImmutableSamplers[j]); binding_layout->immutable_samplers[j] = sampler; } } switch (binding_layout->type) { case VK_DESCRIPTOR_TYPE_SAMPLER: binding_layout->sampler_idx = sampler_idx; sampler_idx += binding_layout->array_size; break; case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: binding_layout->sampler_idx = sampler_idx; binding_layout->tex_idx = tex_idx; sampler_idx += binding_layout->array_size; tex_idx += binding_layout->array_size; binding_layout->desc_ubo_stride = sizeof(struct panvk_image_desc); break; case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: binding_layout->tex_idx = tex_idx; tex_idx += binding_layout->array_size; binding_layout->desc_ubo_stride = sizeof(struct panvk_image_desc); break; case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: binding_layout->tex_idx = tex_idx; tex_idx += binding_layout->array_size; binding_layout->desc_ubo_stride = sizeof(struct panvk_bview_desc); break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: binding_layout->dyn_ubo_idx = dyn_ubo_idx; dyn_ubo_idx += binding_layout->array_size; break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: binding_layout->ubo_idx = ubo_idx; ubo_idx += binding_layout->array_size; break; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: binding_layout->dyn_ssbo_idx = dyn_ssbo_idx; dyn_ssbo_idx += binding_layout->array_size; break; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: binding_layout->desc_ubo_stride = sizeof(struct panvk_ssbo_addr); break; case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: binding_layout->img_idx = img_idx; img_idx += binding_layout->array_size; binding_layout->desc_ubo_stride = sizeof(struct panvk_image_desc); break; case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: binding_layout->img_idx = img_idx; img_idx += binding_layout->array_size; binding_layout->desc_ubo_stride = sizeof(struct panvk_bview_desc); break; default: unreachable("Invalid descriptor type"); } desc_ubo_size = ALIGN_POT(desc_ubo_size, PANVK_DESCRIPTOR_ALIGN); binding_layout->desc_ubo_offset = desc_ubo_size; desc_ubo_size += binding_layout->desc_ubo_stride * binding_layout->array_size; } set_layout->desc_ubo_size = desc_ubo_size; if (desc_ubo_size > 0) set_layout->desc_ubo_index = ubo_idx++; set_layout->num_samplers = sampler_idx; set_layout->num_textures = tex_idx; set_layout->num_ubos = ubo_idx; set_layout->num_dyn_ubos = dyn_ubo_idx; set_layout->num_dyn_ssbos = dyn_ssbo_idx; set_layout->num_imgs = img_idx; free(bindings); *pSetLayout = panvk_descriptor_set_layout_to_handle(set_layout); return VK_SUCCESS; err_free_bindings: free(bindings); return vk_error(device, result); } static void panvk_write_sampler_desc_raw(struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem, struct panvk_sampler *sampler); static VkResult panvk_per_arch(descriptor_set_create)(struct panvk_device *device, struct panvk_descriptor_pool *pool, const struct panvk_descriptor_set_layout *layout, struct panvk_descriptor_set **out_set) { struct panvk_descriptor_set *set; /* TODO: Allocate from the pool! */ set = vk_object_zalloc(&device->vk, NULL, sizeof(struct panvk_descriptor_set), VK_OBJECT_TYPE_DESCRIPTOR_SET); if (!set) return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); set->layout = layout; if (layout->num_ubos) { set->ubos = vk_zalloc(&device->vk.alloc, pan_size(UNIFORM_BUFFER) * layout->num_ubos, 8, VK_OBJECT_TYPE_DESCRIPTOR_SET); if (!set->ubos) goto err_free_set; } if (layout->num_dyn_ubos) { set->dyn_ubos = vk_zalloc(&device->vk.alloc, sizeof(*set->dyn_ubos) * layout->num_dyn_ubos, 8, VK_OBJECT_TYPE_DESCRIPTOR_SET); if (!set->dyn_ubos) goto err_free_set; } if (layout->num_dyn_ssbos) { set->dyn_ssbos = vk_zalloc(&device->vk.alloc, sizeof(*set->dyn_ssbos) * layout->num_dyn_ssbos, 8, VK_OBJECT_TYPE_DESCRIPTOR_SET); if (!set->dyn_ssbos) goto err_free_set; } if (layout->num_samplers) { set->samplers = vk_zalloc(&device->vk.alloc, pan_size(SAMPLER) * layout->num_samplers, 8, VK_OBJECT_TYPE_DESCRIPTOR_SET); if (!set->samplers) goto err_free_set; } if (layout->num_textures) { set->textures = vk_zalloc(&device->vk.alloc, pan_size(TEXTURE) * layout->num_textures, 8, VK_OBJECT_TYPE_DESCRIPTOR_SET); if (!set->textures) goto err_free_set; } if (layout->num_imgs) { set->img_fmts = vk_zalloc(&device->vk.alloc, sizeof(*set->img_fmts) * layout->num_imgs, 8, VK_OBJECT_TYPE_DESCRIPTOR_SET); if (!set->img_fmts) goto err_free_set; set->img_attrib_bufs = vk_zalloc(&device->vk.alloc, pan_size(ATTRIBUTE_BUFFER) * 2 * layout->num_imgs, 8, VK_OBJECT_TYPE_DESCRIPTOR_SET); if (!set->img_attrib_bufs) goto err_free_set; } if (layout->desc_ubo_size) { set->desc_bo = panfrost_bo_create(&device->physical_device->pdev, layout->desc_ubo_size, 0, "Descriptor set"); if (!set->desc_bo) goto err_free_set; struct mali_uniform_buffer_packed *ubos = set->ubos; panvk_per_arch(emit_ubo)(set->desc_bo->ptr.gpu, layout->desc_ubo_size, &ubos[layout->desc_ubo_index]); } for (unsigned i = 0; i < layout->binding_count; i++) { if (!layout->bindings[i].immutable_samplers) continue; for (unsigned j = 0; j < layout->bindings[i].array_size; j++) { struct panvk_sampler *sampler = layout->bindings[i].immutable_samplers[j]; panvk_write_sampler_desc_raw(set, i, j, sampler); } } *out_set = set; return VK_SUCCESS; err_free_set: vk_free(&device->vk.alloc, set->textures); vk_free(&device->vk.alloc, set->samplers); vk_free(&device->vk.alloc, set->ubos); vk_free(&device->vk.alloc, set->dyn_ubos); vk_free(&device->vk.alloc, set->dyn_ssbos); vk_free(&device->vk.alloc, set->img_fmts); vk_free(&device->vk.alloc, set->img_attrib_bufs); if (set->desc_bo) panfrost_bo_unreference(set->desc_bo); vk_object_free(&device->vk, NULL, set); return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); } VkResult panvk_per_arch(AllocateDescriptorSets)(VkDevice _device, const VkDescriptorSetAllocateInfo *pAllocateInfo, VkDescriptorSet *pDescriptorSets) { VK_FROM_HANDLE(panvk_device, device, _device); VK_FROM_HANDLE(panvk_descriptor_pool, pool, pAllocateInfo->descriptorPool); VkResult result; unsigned i; for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) { VK_FROM_HANDLE(panvk_descriptor_set_layout, layout, pAllocateInfo->pSetLayouts[i]); struct panvk_descriptor_set *set = NULL; result = panvk_per_arch(descriptor_set_create)(device, pool, layout, &set); if (result != VK_SUCCESS) goto err_free_sets; pDescriptorSets[i] = panvk_descriptor_set_to_handle(set); } return VK_SUCCESS; err_free_sets: panvk_FreeDescriptorSets(_device, pAllocateInfo->descriptorPool, i, pDescriptorSets); for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) pDescriptorSets[i] = VK_NULL_HANDLE; return result; } static void * panvk_desc_ubo_data(struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem) { const struct panvk_descriptor_set_binding_layout *binding_layout = &set->layout->bindings[binding]; return (char *)set->desc_bo->ptr.cpu + binding_layout->desc_ubo_offset + elem * binding_layout->desc_ubo_stride; } static struct mali_sampler_packed * panvk_sampler_desc(struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem) { const struct panvk_descriptor_set_binding_layout *binding_layout = &set->layout->bindings[binding]; uint32_t sampler_idx = binding_layout->sampler_idx + elem; return &((struct mali_sampler_packed *)set->samplers)[sampler_idx]; } static void panvk_write_sampler_desc_raw(struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem, struct panvk_sampler *sampler) { memcpy(panvk_sampler_desc(set, binding, elem), &sampler->desc, sizeof(sampler->desc)); } static void panvk_write_sampler_desc(UNUSED struct panvk_device *dev, struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem, const VkDescriptorImageInfo * const pImageInfo) { const struct panvk_descriptor_set_binding_layout *binding_layout = &set->layout->bindings[binding]; if (binding_layout->immutable_samplers) return; VK_FROM_HANDLE(panvk_sampler, sampler, pImageInfo->sampler); panvk_write_sampler_desc_raw(set, binding, elem, sampler); } static void panvk_copy_sampler_desc(struct panvk_descriptor_set *dst_set, uint32_t dst_binding, uint32_t dst_elem, struct panvk_descriptor_set *src_set, uint32_t src_binding, uint32_t src_elem) { const struct panvk_descriptor_set_binding_layout *dst_binding_layout = &dst_set->layout->bindings[dst_binding]; if (dst_binding_layout->immutable_samplers) return; memcpy(panvk_sampler_desc(dst_set, dst_binding, dst_elem), panvk_sampler_desc(src_set, src_binding, src_elem), sizeof(struct mali_sampler_packed)); } static struct mali_texture_packed * panvk_tex_desc(struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem) { const struct panvk_descriptor_set_binding_layout *binding_layout = &set->layout->bindings[binding]; unsigned tex_idx = binding_layout->tex_idx + elem; return &((struct mali_texture_packed *)set->textures)[tex_idx]; } static void panvk_write_tex_desc(UNUSED struct panvk_device *dev, struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem, const VkDescriptorImageInfo * const pImageInfo) { VK_FROM_HANDLE(panvk_image_view, view, pImageInfo->imageView); memcpy(panvk_tex_desc(set, binding, elem), view->descs.tex, pan_size(TEXTURE)); panvk_fill_image_desc(panvk_desc_ubo_data(set, binding, elem), view); } static void panvk_copy_tex_desc(struct panvk_descriptor_set *dst_set, uint32_t dst_binding, uint32_t dst_elem, struct panvk_descriptor_set *src_set, uint32_t src_binding, uint32_t src_elem) { *panvk_tex_desc(dst_set, dst_binding, dst_elem) = *panvk_tex_desc(src_set, src_binding, src_elem); /* Descriptor UBO data gets copied automatically */ } static void panvk_write_tex_buf_desc(UNUSED struct panvk_device *dev, struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem, const VkBufferView bufferView) { VK_FROM_HANDLE(panvk_buffer_view, view, bufferView); memcpy(panvk_tex_desc(set, binding, elem), view->descs.tex, pan_size(TEXTURE)); panvk_fill_bview_desc(panvk_desc_ubo_data(set, binding, elem), view); } static uint32_t panvk_img_idx(struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem) { const struct panvk_descriptor_set_binding_layout *binding_layout = &set->layout->bindings[binding]; return binding_layout->img_idx + elem; } static void panvk_write_img_desc(struct panvk_device *dev, struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem, const VkDescriptorImageInfo *pImageInfo) { const struct panfrost_device *pdev = &dev->physical_device->pdev; VK_FROM_HANDLE(panvk_image_view, view, pImageInfo->imageView); unsigned img_idx = panvk_img_idx(set, binding, elem); void *attrib_buf = (uint8_t *)set->img_attrib_bufs + (pan_size(ATTRIBUTE_BUFFER) * 2 * img_idx); set->img_fmts[img_idx] = pdev->formats[view->pview.format].hw; memcpy(attrib_buf, view->descs.img_attrib_buf, pan_size(ATTRIBUTE_BUFFER) * 2); panvk_fill_image_desc(panvk_desc_ubo_data(set, binding, elem), view); } static void panvk_copy_img_desc(struct panvk_descriptor_set *dst_set, uint32_t dst_binding, uint32_t dst_elem, struct panvk_descriptor_set *src_set, uint32_t src_binding, uint32_t src_elem) { unsigned dst_img_idx = panvk_img_idx(dst_set, dst_binding, dst_elem); unsigned src_img_idx = panvk_img_idx(src_set, src_binding, src_elem); void *dst_attrib_buf = (uint8_t *)dst_set->img_attrib_bufs + (pan_size(ATTRIBUTE_BUFFER) * 2 * dst_img_idx); void *src_attrib_buf = (uint8_t *)src_set->img_attrib_bufs + (pan_size(ATTRIBUTE_BUFFER) * 2 * src_img_idx); dst_set->img_fmts[dst_img_idx] = src_set->img_fmts[src_img_idx]; memcpy(dst_attrib_buf, src_attrib_buf, pan_size(ATTRIBUTE_BUFFER) * 2); /* Descriptor UBO data gets copied automatically */ } static void panvk_write_img_buf_desc(struct panvk_device *dev, struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem, const VkBufferView bufferView) { const struct panfrost_device *pdev = &dev->physical_device->pdev; VK_FROM_HANDLE(panvk_buffer_view, view, bufferView); unsigned img_idx = panvk_img_idx(set, binding, elem); void *attrib_buf = (uint8_t *)set->img_attrib_bufs + (pan_size(ATTRIBUTE_BUFFER) * 2 * img_idx); set->img_fmts[img_idx] = pdev->formats[view->fmt].hw; memcpy(attrib_buf, view->descs.img_attrib_buf, pan_size(ATTRIBUTE_BUFFER) * 2); panvk_fill_bview_desc(panvk_desc_ubo_data(set, binding, elem), view); } static struct mali_uniform_buffer_packed * panvk_ubo_desc(struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem) { const struct panvk_descriptor_set_binding_layout *binding_layout = &set->layout->bindings[binding]; unsigned ubo_idx = binding_layout->ubo_idx + elem; return &((struct mali_uniform_buffer_packed *)set->ubos)[ubo_idx]; } static void panvk_write_ubo_desc(UNUSED struct panvk_device *dev, struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem, const VkDescriptorBufferInfo *pBufferInfo) { VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer); mali_ptr ptr = panvk_buffer_gpu_ptr(buffer, pBufferInfo->offset); size_t size = panvk_buffer_range(buffer, pBufferInfo->offset, pBufferInfo->range); panvk_per_arch(emit_ubo)(ptr, size, panvk_ubo_desc(set, binding, elem)); } static void panvk_copy_ubo_desc(struct panvk_descriptor_set *dst_set, uint32_t dst_binding, uint32_t dst_elem, struct panvk_descriptor_set *src_set, uint32_t src_binding, uint32_t src_elem) { *panvk_ubo_desc(dst_set, dst_binding, dst_elem) = *panvk_ubo_desc(src_set, src_binding, src_elem); } static struct panvk_buffer_desc * panvk_dyn_ubo_desc(struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem) { const struct panvk_descriptor_set_binding_layout *binding_layout = &set->layout->bindings[binding]; return &set->dyn_ubos[binding_layout->dyn_ubo_idx + elem]; } static void panvk_write_dyn_ubo_desc(UNUSED struct panvk_device *dev, struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem, const VkDescriptorBufferInfo *pBufferInfo) { VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer); *panvk_dyn_ubo_desc(set, binding, elem) = (struct panvk_buffer_desc) { .buffer = buffer, .offset = pBufferInfo->offset, .size = pBufferInfo->range, }; } static void panvk_copy_dyn_ubo_desc(struct panvk_descriptor_set *dst_set, uint32_t dst_binding, uint32_t dst_elem, struct panvk_descriptor_set *src_set, uint32_t src_binding, uint32_t src_elem) { *panvk_dyn_ubo_desc(dst_set, dst_binding, dst_elem) = *panvk_dyn_ubo_desc(src_set, src_binding, src_elem); } static void panvk_write_ssbo_desc(UNUSED struct panvk_device *dev, struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem, const VkDescriptorBufferInfo *pBufferInfo) { VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer); struct panvk_ssbo_addr *desc = panvk_desc_ubo_data(set, binding, elem); *desc = (struct panvk_ssbo_addr) { .base_addr = panvk_buffer_gpu_ptr(buffer, pBufferInfo->offset), .size = panvk_buffer_range(buffer, pBufferInfo->offset, pBufferInfo->range), }; } static void panvk_copy_ssbo_desc(struct panvk_descriptor_set *dst_set, uint32_t dst_binding, uint32_t dst_elem, struct panvk_descriptor_set *src_set, uint32_t src_binding, uint32_t src_elem) { /* Descriptor UBO data gets copied automatically */ } static struct panvk_buffer_desc * panvk_dyn_ssbo_desc(struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem) { const struct panvk_descriptor_set_binding_layout *binding_layout = &set->layout->bindings[binding]; return &set->dyn_ssbos[binding_layout->dyn_ssbo_idx + elem]; } static void panvk_write_dyn_ssbo_desc(UNUSED struct panvk_device *dev, struct panvk_descriptor_set *set, uint32_t binding, uint32_t elem, const VkDescriptorBufferInfo *pBufferInfo) { VK_FROM_HANDLE(panvk_buffer, buffer, pBufferInfo->buffer); *panvk_dyn_ssbo_desc(set, binding, elem) = (struct panvk_buffer_desc) { .buffer = buffer, .offset = pBufferInfo->offset, .size = pBufferInfo->range, }; } static void panvk_copy_dyn_ssbo_desc(struct panvk_descriptor_set *dst_set, uint32_t dst_binding, uint32_t dst_elem, struct panvk_descriptor_set *src_set, uint32_t src_binding, uint32_t src_elem) { *panvk_dyn_ssbo_desc(dst_set, dst_binding, dst_elem) = *panvk_dyn_ssbo_desc(src_set, src_binding, src_elem); } void panvk_per_arch(UpdateDescriptorSets)(VkDevice _device, uint32_t descriptorWriteCount, const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount, const VkCopyDescriptorSet *pDescriptorCopies) { VK_FROM_HANDLE(panvk_device, dev, _device); for (unsigned i = 0; i < descriptorWriteCount; i++) { const VkWriteDescriptorSet *write = &pDescriptorWrites[i]; VK_FROM_HANDLE(panvk_descriptor_set, set, write->dstSet); switch (write->descriptorType) { case VK_DESCRIPTOR_TYPE_SAMPLER: for (uint32_t j = 0; j < write->descriptorCount; j++) { panvk_write_sampler_desc(dev, set, write->dstBinding, write->dstArrayElement + j, &write->pImageInfo[j]); } break; case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: for (uint32_t j = 0; j < write->descriptorCount; j++) { panvk_write_sampler_desc(dev, set, write->dstBinding, write->dstArrayElement + j, &write->pImageInfo[j]); panvk_write_tex_desc(dev, set, write->dstBinding, write->dstArrayElement + j, &write->pImageInfo[j]); } break; case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: for (uint32_t j = 0; j < write->descriptorCount; j++) { panvk_write_tex_desc(dev, set, write->dstBinding, write->dstArrayElement + j, &write->pImageInfo[j]); } break; case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: for (uint32_t j = 0; j < write->descriptorCount; j++) { panvk_write_img_desc(dev, set, write->dstBinding, write->dstArrayElement + j, &write->pImageInfo[j]); } break; case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: for (uint32_t j = 0; j < write->descriptorCount; j++) { panvk_write_tex_buf_desc(dev, set, write->dstBinding, write->dstArrayElement + j, write->pTexelBufferView[j]); } break; case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: for (uint32_t j = 0; j < write->descriptorCount; j++) { panvk_write_img_buf_desc(dev, set, write->dstBinding, write->dstArrayElement + j, write->pTexelBufferView[j]); } break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: for (uint32_t j = 0; j < write->descriptorCount; j++) { panvk_write_ubo_desc(dev, set, write->dstBinding, write->dstArrayElement + j, &write->pBufferInfo[j]); } break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: for (uint32_t j = 0; j < write->descriptorCount; j++) { panvk_write_dyn_ubo_desc(dev, set, write->dstBinding, write->dstArrayElement + j, &write->pBufferInfo[j]); } break; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: for (uint32_t j = 0; j < write->descriptorCount; j++) { panvk_write_ssbo_desc(dev, set, write->dstBinding, write->dstArrayElement + j, &write->pBufferInfo[j]); } break; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: for (uint32_t j = 0; j < write->descriptorCount; j++) { panvk_write_dyn_ssbo_desc(dev, set, write->dstBinding, write->dstArrayElement + j, &write->pBufferInfo[j]); } break; default: unreachable("Unsupported descriptor type"); } } for (unsigned i = 0; i < descriptorCopyCount; i++) { const VkCopyDescriptorSet *copy = &pDescriptorCopies[i]; VK_FROM_HANDLE(panvk_descriptor_set, src_set, copy->srcSet); VK_FROM_HANDLE(panvk_descriptor_set, dst_set, copy->dstSet); const struct panvk_descriptor_set_binding_layout *dst_binding_layout = &dst_set->layout->bindings[copy->dstBinding]; const struct panvk_descriptor_set_binding_layout *src_binding_layout = &src_set->layout->bindings[copy->srcBinding]; assert(dst_binding_layout->type == src_binding_layout->type); if (dst_binding_layout->desc_ubo_stride > 0 && src_binding_layout->desc_ubo_stride > 0) { for (uint32_t j = 0; j < copy->descriptorCount; j++) { memcpy(panvk_desc_ubo_data(dst_set, copy->dstBinding, copy->dstArrayElement + j), panvk_desc_ubo_data(src_set, copy->srcBinding, copy->srcArrayElement + j), MIN2(dst_binding_layout->desc_ubo_stride, src_binding_layout->desc_ubo_stride)); } } switch (src_binding_layout->type) { case VK_DESCRIPTOR_TYPE_SAMPLER: for (uint32_t j = 0; j < copy->descriptorCount; j++) { panvk_copy_sampler_desc(dst_set, copy->dstBinding, copy->dstArrayElement + j, src_set, copy->srcBinding, copy->srcArrayElement + j); } break; case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: for (uint32_t j = 0; j < copy->descriptorCount; j++) { panvk_copy_sampler_desc(dst_set, copy->dstBinding, copy->dstArrayElement + j, src_set, copy->srcBinding, copy->srcArrayElement + j); panvk_copy_tex_desc(dst_set, copy->dstBinding, copy->dstArrayElement + j, src_set, copy->srcBinding, copy->srcArrayElement + j); } break; case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: for (uint32_t j = 0; j < copy->descriptorCount; j++) { panvk_copy_tex_desc(dst_set, copy->dstBinding, copy->dstArrayElement + j, src_set, copy->srcBinding, copy->srcArrayElement + j); } break; case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: for (uint32_t j = 0; j < copy->descriptorCount; j++) { panvk_copy_img_desc(dst_set, copy->dstBinding, copy->dstArrayElement + j, src_set, copy->srcBinding, copy->srcArrayElement + j); } break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: for (uint32_t j = 0; j < copy->descriptorCount; j++) { panvk_copy_ubo_desc(dst_set, copy->dstBinding, copy->dstArrayElement + j, src_set, copy->srcBinding, copy->srcArrayElement + j); } break; case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: for (uint32_t j = 0; j < copy->descriptorCount; j++) { panvk_copy_dyn_ubo_desc(dst_set, copy->dstBinding, copy->dstArrayElement + j, src_set, copy->srcBinding, copy->srcArrayElement + j); } break; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: for (uint32_t j = 0; j < copy->descriptorCount; j++) { panvk_copy_ssbo_desc(dst_set, copy->dstBinding, copy->dstArrayElement + j, src_set, copy->srcBinding, copy->srcArrayElement + j); } break; case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: for (uint32_t j = 0; j < copy->descriptorCount; j++) { panvk_copy_dyn_ssbo_desc(dst_set, copy->dstBinding, copy->dstArrayElement + j, src_set, copy->srcBinding, copy->srcArrayElement + j); } break; default: unreachable("Unsupported descriptor type"); } } }