Path: blob/21.2-virgl/src/virtio/vulkan/vn_descriptor_set.c
4560 views
/*1* Copyright 2019 Google LLC2* SPDX-License-Identifier: MIT3*4* based in part on anv and radv which are:5* Copyright © 2015 Intel Corporation6* Copyright © 2016 Red Hat.7* Copyright © 2016 Bas Nieuwenhuizen8*/910#include "vn_descriptor_set.h"1112#include "venus-protocol/vn_protocol_driver_descriptor_pool.h"13#include "venus-protocol/vn_protocol_driver_descriptor_set.h"14#include "venus-protocol/vn_protocol_driver_descriptor_set_layout.h"15#include "venus-protocol/vn_protocol_driver_descriptor_update_template.h"1617#include "vn_device.h"1819/* descriptor set layout commands */2021void22vn_GetDescriptorSetLayoutSupport(23VkDevice device,24const VkDescriptorSetLayoutCreateInfo *pCreateInfo,25VkDescriptorSetLayoutSupport *pSupport)26{27struct vn_device *dev = vn_device_from_handle(device);2829/* TODO per-device cache */30vn_call_vkGetDescriptorSetLayoutSupport(dev->instance, device, pCreateInfo,31pSupport);32}3334VkResult35vn_CreateDescriptorSetLayout(36VkDevice device,37const VkDescriptorSetLayoutCreateInfo *pCreateInfo,38const VkAllocationCallbacks *pAllocator,39VkDescriptorSetLayout *pSetLayout)40{41struct vn_device *dev = vn_device_from_handle(device);42const VkAllocationCallbacks *alloc =43pAllocator ? pAllocator : &dev->base.base.alloc;4445uint32_t max_binding = 0;46VkDescriptorSetLayoutBinding *local_bindings = NULL;47VkDescriptorSetLayoutCreateInfo local_create_info;48if (pCreateInfo->bindingCount) {49/* the encoder does not ignore50* VkDescriptorSetLayoutBinding::pImmutableSamplers when it should51*/52const size_t binding_size =53sizeof(*pCreateInfo->pBindings) * pCreateInfo->bindingCount;54local_bindings = vk_alloc(alloc, binding_size, VN_DEFAULT_ALIGN,55VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);56if (!local_bindings)57return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);5859memcpy(local_bindings, pCreateInfo->pBindings, binding_size);60for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {61VkDescriptorSetLayoutBinding *binding = &local_bindings[i];6263if (max_binding < binding->binding)64max_binding = binding->binding;6566switch (binding->descriptorType) {67case VK_DESCRIPTOR_TYPE_SAMPLER:68case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:69break;70default:71binding->pImmutableSamplers = NULL;72break;73}74}7576local_create_info = *pCreateInfo;77local_create_info.pBindings = local_bindings;78pCreateInfo = &local_create_info;79}8081const size_t layout_size =82offsetof(struct vn_descriptor_set_layout, bindings[max_binding + 1]);83struct vn_descriptor_set_layout *layout =84vk_zalloc(alloc, layout_size, VN_DEFAULT_ALIGN,85VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);86if (!layout) {87vk_free(alloc, local_bindings);88return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);89}9091vn_object_base_init(&layout->base, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT,92&dev->base);9394for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {95const VkDescriptorSetLayoutBinding *binding =96&pCreateInfo->pBindings[i];97struct vn_descriptor_set_layout_binding *dst =98&layout->bindings[binding->binding];99100switch (binding->descriptorType) {101case VK_DESCRIPTOR_TYPE_SAMPLER:102case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:103dst->has_immutable_samplers = binding->pImmutableSamplers;104break;105default:106break;107}108}109110VkDescriptorSetLayout layout_handle =111vn_descriptor_set_layout_to_handle(layout);112vn_async_vkCreateDescriptorSetLayout(dev->instance, device, pCreateInfo,113NULL, &layout_handle);114115vk_free(alloc, local_bindings);116117*pSetLayout = layout_handle;118119return VK_SUCCESS;120}121122void123vn_DestroyDescriptorSetLayout(VkDevice device,124VkDescriptorSetLayout descriptorSetLayout,125const VkAllocationCallbacks *pAllocator)126{127struct vn_device *dev = vn_device_from_handle(device);128struct vn_descriptor_set_layout *layout =129vn_descriptor_set_layout_from_handle(descriptorSetLayout);130const VkAllocationCallbacks *alloc =131pAllocator ? pAllocator : &dev->base.base.alloc;132133if (!layout)134return;135136vn_async_vkDestroyDescriptorSetLayout(dev->instance, device,137descriptorSetLayout, NULL);138139vn_object_base_fini(&layout->base);140vk_free(alloc, layout);141}142143/* descriptor pool commands */144145VkResult146vn_CreateDescriptorPool(VkDevice device,147const VkDescriptorPoolCreateInfo *pCreateInfo,148const VkAllocationCallbacks *pAllocator,149VkDescriptorPool *pDescriptorPool)150{151struct vn_device *dev = vn_device_from_handle(device);152const VkAllocationCallbacks *alloc =153pAllocator ? pAllocator : &dev->base.base.alloc;154155struct vn_descriptor_pool *pool =156vk_zalloc(alloc, sizeof(*pool), VN_DEFAULT_ALIGN,157VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);158if (!pool)159return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);160161vn_object_base_init(&pool->base, VK_OBJECT_TYPE_DESCRIPTOR_POOL,162&dev->base);163164pool->allocator = *alloc;165list_inithead(&pool->descriptor_sets);166167VkDescriptorPool pool_handle = vn_descriptor_pool_to_handle(pool);168vn_async_vkCreateDescriptorPool(dev->instance, device, pCreateInfo, NULL,169&pool_handle);170171*pDescriptorPool = pool_handle;172173return VK_SUCCESS;174}175176void177vn_DestroyDescriptorPool(VkDevice device,178VkDescriptorPool descriptorPool,179const VkAllocationCallbacks *pAllocator)180{181struct vn_device *dev = vn_device_from_handle(device);182struct vn_descriptor_pool *pool =183vn_descriptor_pool_from_handle(descriptorPool);184const VkAllocationCallbacks *alloc;185186if (!pool)187return;188189alloc = pAllocator ? pAllocator : &pool->allocator;190191/* We must emit vkDestroyDescriptorPool before freeing the sets in192* pool->descriptor_sets. Otherwise, another thread might reuse their193* object ids while they still refer to the sets in the renderer.194*/195vn_async_vkDestroyDescriptorPool(dev->instance, device, descriptorPool,196NULL);197198list_for_each_entry_safe(struct vn_descriptor_set, set,199&pool->descriptor_sets, head) {200list_del(&set->head);201202vn_object_base_fini(&set->base);203vk_free(alloc, set);204}205206vn_object_base_fini(&pool->base);207vk_free(alloc, pool);208}209210VkResult211vn_ResetDescriptorPool(VkDevice device,212VkDescriptorPool descriptorPool,213VkDescriptorPoolResetFlags flags)214{215struct vn_device *dev = vn_device_from_handle(device);216struct vn_descriptor_pool *pool =217vn_descriptor_pool_from_handle(descriptorPool);218const VkAllocationCallbacks *alloc = &pool->allocator;219220vn_async_vkResetDescriptorPool(dev->instance, device, descriptorPool,221flags);222223list_for_each_entry_safe(struct vn_descriptor_set, set,224&pool->descriptor_sets, head) {225list_del(&set->head);226227vn_object_base_fini(&set->base);228vk_free(alloc, set);229}230231return VK_SUCCESS;232}233234/* descriptor set commands */235236VkResult237vn_AllocateDescriptorSets(VkDevice device,238const VkDescriptorSetAllocateInfo *pAllocateInfo,239VkDescriptorSet *pDescriptorSets)240{241struct vn_device *dev = vn_device_from_handle(device);242struct vn_descriptor_pool *pool =243vn_descriptor_pool_from_handle(pAllocateInfo->descriptorPool);244const VkAllocationCallbacks *alloc = &pool->allocator;245246for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {247struct vn_descriptor_set *set =248vk_zalloc(alloc, sizeof(*set), VN_DEFAULT_ALIGN,249VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);250if (!set) {251for (uint32_t j = 0; j < i; j++) {252set = vn_descriptor_set_from_handle(pDescriptorSets[j]);253list_del(&set->head);254vk_free(alloc, set);255}256memset(pDescriptorSets, 0,257sizeof(*pDescriptorSets) * pAllocateInfo->descriptorSetCount);258return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);259}260261vn_object_base_init(&set->base, VK_OBJECT_TYPE_DESCRIPTOR_SET,262&dev->base);263set->layout =264vn_descriptor_set_layout_from_handle(pAllocateInfo->pSetLayouts[i]);265list_addtail(&set->head, &pool->descriptor_sets);266267VkDescriptorSet set_handle = vn_descriptor_set_to_handle(set);268pDescriptorSets[i] = set_handle;269}270271VkResult result = vn_call_vkAllocateDescriptorSets(272dev->instance, device, pAllocateInfo, pDescriptorSets);273if (result != VK_SUCCESS) {274for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {275struct vn_descriptor_set *set =276vn_descriptor_set_from_handle(pDescriptorSets[i]);277list_del(&set->head);278vk_free(alloc, set);279}280memset(pDescriptorSets, 0,281sizeof(*pDescriptorSets) * pAllocateInfo->descriptorSetCount);282return vn_error(dev->instance, result);283}284285return VK_SUCCESS;286}287288VkResult289vn_FreeDescriptorSets(VkDevice device,290VkDescriptorPool descriptorPool,291uint32_t descriptorSetCount,292const VkDescriptorSet *pDescriptorSets)293{294struct vn_device *dev = vn_device_from_handle(device);295struct vn_descriptor_pool *pool =296vn_descriptor_pool_from_handle(descriptorPool);297const VkAllocationCallbacks *alloc = &pool->allocator;298299vn_async_vkFreeDescriptorSets(dev->instance, device, descriptorPool,300descriptorSetCount, pDescriptorSets);301302for (uint32_t i = 0; i < descriptorSetCount; i++) {303struct vn_descriptor_set *set =304vn_descriptor_set_from_handle(pDescriptorSets[i]);305306if (!set)307continue;308309list_del(&set->head);310311vn_object_base_fini(&set->base);312vk_free(alloc, set);313}314315return VK_SUCCESS;316}317318static struct vn_update_descriptor_sets *319vn_update_descriptor_sets_alloc(uint32_t write_count,320uint32_t image_count,321uint32_t buffer_count,322uint32_t view_count,323const VkAllocationCallbacks *alloc,324VkSystemAllocationScope scope)325{326const size_t writes_offset = sizeof(struct vn_update_descriptor_sets);327const size_t images_offset =328writes_offset + sizeof(VkWriteDescriptorSet) * write_count;329const size_t buffers_offset =330images_offset + sizeof(VkDescriptorImageInfo) * image_count;331const size_t views_offset =332buffers_offset + sizeof(VkDescriptorBufferInfo) * buffer_count;333const size_t alloc_size = views_offset + sizeof(VkBufferView) * view_count;334335void *storage = vk_alloc(alloc, alloc_size, VN_DEFAULT_ALIGN, scope);336if (!storage)337return NULL;338339struct vn_update_descriptor_sets *update = storage;340update->write_count = write_count;341update->writes = storage + writes_offset;342update->images = storage + images_offset;343update->buffers = storage + buffers_offset;344update->views = storage + views_offset;345346return update;347}348349static struct vn_update_descriptor_sets *350vn_update_descriptor_sets_parse_writes(uint32_t write_count,351const VkWriteDescriptorSet *writes,352const VkAllocationCallbacks *alloc)353{354uint32_t img_count = 0;355for (uint32_t i = 0; i < write_count; i++) {356const VkWriteDescriptorSet *write = &writes[i];357switch (write->descriptorType) {358case VK_DESCRIPTOR_TYPE_SAMPLER:359case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:360case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:361case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:362case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:363img_count += write->descriptorCount;364break;365default:366break;367}368}369370struct vn_update_descriptor_sets *update =371vn_update_descriptor_sets_alloc(write_count, img_count, 0, 0, alloc,372VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);373if (!update)374return NULL;375376/* the encoder does not ignore377* VkWriteDescriptorSet::{pImageInfo,pBufferInfo,pTexelBufferView} when it378* should379*380* TODO make the encoder smarter381*/382memcpy(update->writes, writes, sizeof(*writes) * write_count);383img_count = 0;384for (uint32_t i = 0; i < write_count; i++) {385const struct vn_descriptor_set *set =386vn_descriptor_set_from_handle(writes[i].dstSet);387const struct vn_descriptor_set_layout_binding *binding =388&set->layout->bindings[writes[i].dstBinding];389VkWriteDescriptorSet *write = &update->writes[i];390VkDescriptorImageInfo *imgs = &update->images[img_count];391392switch (write->descriptorType) {393case VK_DESCRIPTOR_TYPE_SAMPLER:394case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:395case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:396case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:397case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:398memcpy(imgs, write->pImageInfo,399sizeof(*imgs) * write->descriptorCount);400img_count += write->descriptorCount;401402for (uint32_t j = 0; j < write->descriptorCount; j++) {403switch (write->descriptorType) {404case VK_DESCRIPTOR_TYPE_SAMPLER:405imgs[j].imageView = VK_NULL_HANDLE;406break;407case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:408if (binding->has_immutable_samplers)409imgs[j].sampler = VK_NULL_HANDLE;410break;411case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:412case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:413case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:414imgs[j].sampler = VK_NULL_HANDLE;415break;416default:417break;418}419}420421write->pImageInfo = imgs;422write->pBufferInfo = NULL;423write->pTexelBufferView = NULL;424break;425case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:426case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:427write->pImageInfo = NULL;428write->pBufferInfo = NULL;429break;430case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:431case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:432case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:433case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:434write->pImageInfo = NULL;435write->pTexelBufferView = NULL;436break;437default:438write->pImageInfo = NULL;439write->pBufferInfo = NULL;440write->pTexelBufferView = NULL;441break;442}443}444445return update;446}447448void449vn_UpdateDescriptorSets(VkDevice device,450uint32_t descriptorWriteCount,451const VkWriteDescriptorSet *pDescriptorWrites,452uint32_t descriptorCopyCount,453const VkCopyDescriptorSet *pDescriptorCopies)454{455struct vn_device *dev = vn_device_from_handle(device);456const VkAllocationCallbacks *alloc = &dev->base.base.alloc;457458struct vn_update_descriptor_sets *update =459vn_update_descriptor_sets_parse_writes(descriptorWriteCount,460pDescriptorWrites, alloc);461if (!update) {462/* TODO update one-by-one? */463vn_log(dev->instance, "TODO descriptor set update ignored due to OOM");464return;465}466467vn_async_vkUpdateDescriptorSets(dev->instance, device, update->write_count,468update->writes, descriptorCopyCount,469pDescriptorCopies);470471vk_free(alloc, update);472}473474/* descriptor update template commands */475476static struct vn_update_descriptor_sets *477vn_update_descriptor_sets_parse_template(478const VkDescriptorUpdateTemplateCreateInfo *create_info,479const VkAllocationCallbacks *alloc,480struct vn_descriptor_update_template_entry *entries)481{482uint32_t img_count = 0;483uint32_t buf_count = 0;484uint32_t view_count = 0;485for (uint32_t i = 0; i < create_info->descriptorUpdateEntryCount; i++) {486const VkDescriptorUpdateTemplateEntry *entry =487&create_info->pDescriptorUpdateEntries[i];488489switch (entry->descriptorType) {490case VK_DESCRIPTOR_TYPE_SAMPLER:491case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:492case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:493case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:494case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:495img_count += entry->descriptorCount;496break;497case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:498case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:499view_count += entry->descriptorCount;500break;501case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:502case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:503case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:504case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:505buf_count += entry->descriptorCount;506break;507default:508unreachable("unhandled descriptor type");509break;510}511}512513struct vn_update_descriptor_sets *update = vn_update_descriptor_sets_alloc(514create_info->descriptorUpdateEntryCount, img_count, buf_count,515view_count, alloc, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);516if (!update)517return NULL;518519img_count = 0;520buf_count = 0;521view_count = 0;522for (uint32_t i = 0; i < create_info->descriptorUpdateEntryCount; i++) {523const VkDescriptorUpdateTemplateEntry *entry =524&create_info->pDescriptorUpdateEntries[i];525VkWriteDescriptorSet *write = &update->writes[i];526527write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;528write->pNext = NULL;529write->dstBinding = entry->dstBinding;530write->dstArrayElement = entry->dstArrayElement;531write->descriptorCount = entry->descriptorCount;532write->descriptorType = entry->descriptorType;533534entries[i].offset = entry->offset;535entries[i].stride = entry->stride;536537switch (entry->descriptorType) {538case VK_DESCRIPTOR_TYPE_SAMPLER:539case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:540case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:541case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:542case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:543write->pImageInfo = &update->images[img_count];544write->pBufferInfo = NULL;545write->pTexelBufferView = NULL;546img_count += entry->descriptorCount;547break;548case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:549case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:550write->pImageInfo = NULL;551write->pBufferInfo = NULL;552write->pTexelBufferView = &update->views[view_count];553view_count += entry->descriptorCount;554break;555case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:556case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:557case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:558case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:559write->pImageInfo = NULL;560write->pBufferInfo = &update->buffers[buf_count];561write->pTexelBufferView = NULL;562buf_count += entry->descriptorCount;563break;564default:565break;566}567}568569return update;570}571572VkResult573vn_CreateDescriptorUpdateTemplate(574VkDevice device,575const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,576const VkAllocationCallbacks *pAllocator,577VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate)578{579struct vn_device *dev = vn_device_from_handle(device);580const VkAllocationCallbacks *alloc =581pAllocator ? pAllocator : &dev->base.base.alloc;582583const size_t templ_size =584offsetof(struct vn_descriptor_update_template,585entries[pCreateInfo->descriptorUpdateEntryCount + 1]);586struct vn_descriptor_update_template *templ = vk_zalloc(587alloc, templ_size, VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);588if (!templ)589return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);590591vn_object_base_init(&templ->base,592VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, &dev->base);593594templ->update = vn_update_descriptor_sets_parse_template(595pCreateInfo, alloc, templ->entries);596if (!templ->update) {597vk_free(alloc, templ);598return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);599}600601mtx_init(&templ->mutex, mtx_plain);602603/* no host object */604VkDescriptorUpdateTemplate templ_handle =605vn_descriptor_update_template_to_handle(templ);606*pDescriptorUpdateTemplate = templ_handle;607608return VK_SUCCESS;609}610611void612vn_DestroyDescriptorUpdateTemplate(613VkDevice device,614VkDescriptorUpdateTemplate descriptorUpdateTemplate,615const VkAllocationCallbacks *pAllocator)616{617struct vn_device *dev = vn_device_from_handle(device);618struct vn_descriptor_update_template *templ =619vn_descriptor_update_template_from_handle(descriptorUpdateTemplate);620const VkAllocationCallbacks *alloc =621pAllocator ? pAllocator : &dev->base.base.alloc;622623if (!templ)624return;625626/* no host object */627vk_free(alloc, templ->update);628mtx_destroy(&templ->mutex);629630vn_object_base_fini(&templ->base);631vk_free(alloc, templ);632}633634void635vn_UpdateDescriptorSetWithTemplate(636VkDevice device,637VkDescriptorSet descriptorSet,638VkDescriptorUpdateTemplate descriptorUpdateTemplate,639const void *pData)640{641struct vn_device *dev = vn_device_from_handle(device);642struct vn_descriptor_set *set =643vn_descriptor_set_from_handle(descriptorSet);644struct vn_descriptor_update_template *templ =645vn_descriptor_update_template_from_handle(descriptorUpdateTemplate);646struct vn_update_descriptor_sets *update = templ->update;647648/* duplicate update instead to avoid locking? */649mtx_lock(&templ->mutex);650651for (uint32_t i = 0; i < update->write_count; i++) {652const struct vn_descriptor_update_template_entry *entry =653&templ->entries[i];654const struct vn_descriptor_set_layout_binding *binding =655&set->layout->bindings[update->writes[i].dstBinding];656VkWriteDescriptorSet *write = &update->writes[i];657658write->dstSet = vn_descriptor_set_to_handle(set);659660switch (write->descriptorType) {661case VK_DESCRIPTOR_TYPE_SAMPLER:662case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:663case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:664case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:665case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:666for (uint32_t j = 0; j < write->descriptorCount; j++) {667const bool need_sampler =668(write->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER ||669write->descriptorType ==670VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) &&671!binding->has_immutable_samplers;672const bool need_view =673write->descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER;674const VkDescriptorImageInfo *src =675pData + entry->offset + entry->stride * j;676VkDescriptorImageInfo *dst =677(VkDescriptorImageInfo *)&write->pImageInfo[j];678679dst->sampler = need_sampler ? src->sampler : VK_NULL_HANDLE;680dst->imageView = need_view ? src->imageView : VK_NULL_HANDLE;681dst->imageLayout = src->imageLayout;682}683break;684case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:685case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:686for (uint32_t j = 0; j < write->descriptorCount; j++) {687const VkBufferView *src =688pData + entry->offset + entry->stride * j;689VkBufferView *dst = (VkBufferView *)&write->pTexelBufferView[j];690*dst = *src;691}692break;693case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:694case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:695case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:696case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:697for (uint32_t j = 0; j < write->descriptorCount; j++) {698const VkDescriptorBufferInfo *src =699pData + entry->offset + entry->stride * j;700VkDescriptorBufferInfo *dst =701(VkDescriptorBufferInfo *)&write->pBufferInfo[j];702*dst = *src;703}704break;705default:706unreachable("unhandled descriptor type");707break;708}709}710711vn_async_vkUpdateDescriptorSets(dev->instance, device, update->write_count,712update->writes, 0, NULL);713714mtx_unlock(&templ->mutex);715}716717718