1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2019 Google LLC 3bf215546Sopenharmony_ci * SPDX-License-Identifier: MIT 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * based in part on anv and radv which are: 6bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation 7bf215546Sopenharmony_ci * Copyright © 2016 Red Hat. 8bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 9bf215546Sopenharmony_ci */ 10bf215546Sopenharmony_ci 11bf215546Sopenharmony_ci#include "vn_descriptor_set.h" 12bf215546Sopenharmony_ci 13bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_descriptor_pool.h" 14bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_descriptor_set.h" 15bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_descriptor_set_layout.h" 16bf215546Sopenharmony_ci#include "venus-protocol/vn_protocol_driver_descriptor_update_template.h" 17bf215546Sopenharmony_ci 18bf215546Sopenharmony_ci#include "vn_device.h" 19bf215546Sopenharmony_ci 20bf215546Sopenharmony_cistatic void 21bf215546Sopenharmony_civn_descriptor_set_layout_destroy(struct vn_device *dev, 22bf215546Sopenharmony_ci struct vn_descriptor_set_layout *layout) 23bf215546Sopenharmony_ci{ 24bf215546Sopenharmony_ci VkDevice dev_handle = vn_device_to_handle(dev); 25bf215546Sopenharmony_ci VkDescriptorSetLayout layout_handle = 26bf215546Sopenharmony_ci vn_descriptor_set_layout_to_handle(layout); 27bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = &dev->base.base.alloc; 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci vn_async_vkDestroyDescriptorSetLayout(dev->instance, dev_handle, 30bf215546Sopenharmony_ci layout_handle, NULL); 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci vn_object_base_fini(&layout->base); 33bf215546Sopenharmony_ci vk_free(alloc, layout); 34bf215546Sopenharmony_ci} 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_cistatic inline struct vn_descriptor_set_layout * 37bf215546Sopenharmony_civn_descriptor_set_layout_ref(struct vn_device *dev, 38bf215546Sopenharmony_ci struct vn_descriptor_set_layout *layout) 39bf215546Sopenharmony_ci{ 40bf215546Sopenharmony_ci vn_refcount_inc(&layout->refcount); 41bf215546Sopenharmony_ci return layout; 42bf215546Sopenharmony_ci} 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_cistatic inline void 45bf215546Sopenharmony_civn_descriptor_set_layout_unref(struct vn_device *dev, 46bf215546Sopenharmony_ci struct vn_descriptor_set_layout *layout) 47bf215546Sopenharmony_ci{ 48bf215546Sopenharmony_ci if (vn_refcount_dec(&layout->refcount)) 49bf215546Sopenharmony_ci vn_descriptor_set_layout_destroy(dev, layout); 50bf215546Sopenharmony_ci} 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_cistatic void 53bf215546Sopenharmony_civn_descriptor_set_destroy(struct vn_device *dev, 54bf215546Sopenharmony_ci struct vn_descriptor_set *set, 55bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc) 56bf215546Sopenharmony_ci{ 57bf215546Sopenharmony_ci list_del(&set->head); 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci vn_descriptor_set_layout_unref(dev, set->layout); 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci vn_object_base_fini(&set->base); 62bf215546Sopenharmony_ci vk_free(alloc, set); 63bf215546Sopenharmony_ci} 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci/* Mapping VkDescriptorType to array index */ 66bf215546Sopenharmony_cistatic enum vn_descriptor_type 67bf215546Sopenharmony_civn_descriptor_type_index(VkDescriptorType type) 68bf215546Sopenharmony_ci{ 69bf215546Sopenharmony_ci switch (type) { 70bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 71bf215546Sopenharmony_ci return VN_DESCRIPTOR_TYPE_SAMPLER; 72bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 73bf215546Sopenharmony_ci return VN_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 74bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 75bf215546Sopenharmony_ci return VN_DESCRIPTOR_TYPE_SAMPLED_IMAGE; 76bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 77bf215546Sopenharmony_ci return VN_DESCRIPTOR_TYPE_STORAGE_IMAGE; 78bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 79bf215546Sopenharmony_ci return VN_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; 80bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 81bf215546Sopenharmony_ci return VN_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; 82bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 83bf215546Sopenharmony_ci return VN_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 84bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 85bf215546Sopenharmony_ci return VN_DESCRIPTOR_TYPE_STORAGE_BUFFER; 86bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 87bf215546Sopenharmony_ci return VN_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; 88bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 89bf215546Sopenharmony_ci return VN_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC; 90bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 91bf215546Sopenharmony_ci return VN_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; 92bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: 93bf215546Sopenharmony_ci return VN_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK; 94bf215546Sopenharmony_ci default: 95bf215546Sopenharmony_ci break; 96bf215546Sopenharmony_ci } 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci unreachable("bad VkDescriptorType"); 99bf215546Sopenharmony_ci} 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci/* descriptor set layout commands */ 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_civoid 104bf215546Sopenharmony_civn_GetDescriptorSetLayoutSupport( 105bf215546Sopenharmony_ci VkDevice device, 106bf215546Sopenharmony_ci const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 107bf215546Sopenharmony_ci VkDescriptorSetLayoutSupport *pSupport) 108bf215546Sopenharmony_ci{ 109bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci /* TODO per-device cache */ 112bf215546Sopenharmony_ci vn_call_vkGetDescriptorSetLayoutSupport(dev->instance, device, pCreateInfo, 113bf215546Sopenharmony_ci pSupport); 114bf215546Sopenharmony_ci} 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_cistatic void 117bf215546Sopenharmony_civn_descriptor_set_layout_init( 118bf215546Sopenharmony_ci struct vn_device *dev, 119bf215546Sopenharmony_ci const VkDescriptorSetLayoutCreateInfo *create_info, 120bf215546Sopenharmony_ci uint32_t last_binding, 121bf215546Sopenharmony_ci struct vn_descriptor_set_layout *layout) 122bf215546Sopenharmony_ci{ 123bf215546Sopenharmony_ci VkDevice dev_handle = vn_device_to_handle(dev); 124bf215546Sopenharmony_ci VkDescriptorSetLayout layout_handle = 125bf215546Sopenharmony_ci vn_descriptor_set_layout_to_handle(layout); 126bf215546Sopenharmony_ci const VkDescriptorSetLayoutBindingFlagsCreateInfo *binding_flags = 127bf215546Sopenharmony_ci vk_find_struct_const(create_info->pNext, 128bf215546Sopenharmony_ci DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO); 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci /* 14.2.1. Descriptor Set Layout 131bf215546Sopenharmony_ci * 132bf215546Sopenharmony_ci * If bindingCount is zero or if this structure is not included in 133bf215546Sopenharmony_ci * the pNext chain, the VkDescriptorBindingFlags for each descriptor 134bf215546Sopenharmony_ci * set layout binding is considered to be zero. 135bf215546Sopenharmony_ci */ 136bf215546Sopenharmony_ci if (binding_flags && !binding_flags->bindingCount) 137bf215546Sopenharmony_ci binding_flags = NULL; 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci layout->refcount = VN_REFCOUNT_INIT(1); 140bf215546Sopenharmony_ci layout->last_binding = last_binding; 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci for (uint32_t i = 0; i < create_info->bindingCount; i++) { 143bf215546Sopenharmony_ci const VkDescriptorSetLayoutBinding *binding_info = 144bf215546Sopenharmony_ci &create_info->pBindings[i]; 145bf215546Sopenharmony_ci struct vn_descriptor_set_layout_binding *binding = 146bf215546Sopenharmony_ci &layout->bindings[binding_info->binding]; 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci if (binding_info->binding == last_binding) { 149bf215546Sopenharmony_ci /* 14.2.1. Descriptor Set Layout 150bf215546Sopenharmony_ci * 151bf215546Sopenharmony_ci * VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT must only be 152bf215546Sopenharmony_ci * used for the last binding in the descriptor set layout (i.e. the 153bf215546Sopenharmony_ci * binding with the largest value of binding). 154bf215546Sopenharmony_ci * 155bf215546Sopenharmony_ci * 41. Features 156bf215546Sopenharmony_ci * 157bf215546Sopenharmony_ci * descriptorBindingVariableDescriptorCount indicates whether the 158bf215546Sopenharmony_ci * implementation supports descriptor sets with a variable-sized last 159bf215546Sopenharmony_ci * binding. If this feature is not enabled, 160bf215546Sopenharmony_ci * VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT must not be 161bf215546Sopenharmony_ci * used. 162bf215546Sopenharmony_ci */ 163bf215546Sopenharmony_ci layout->has_variable_descriptor_count = 164bf215546Sopenharmony_ci binding_flags && 165bf215546Sopenharmony_ci (binding_flags->pBindingFlags[i] & 166bf215546Sopenharmony_ci VK_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT); 167bf215546Sopenharmony_ci } 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci binding->type = binding_info->descriptorType; 170bf215546Sopenharmony_ci binding->count = binding_info->descriptorCount; 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci switch (binding_info->descriptorType) { 173bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 174bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 175bf215546Sopenharmony_ci binding->has_immutable_samplers = binding_info->pImmutableSamplers; 176bf215546Sopenharmony_ci break; 177bf215546Sopenharmony_ci default: 178bf215546Sopenharmony_ci break; 179bf215546Sopenharmony_ci } 180bf215546Sopenharmony_ci } 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci vn_async_vkCreateDescriptorSetLayout(dev->instance, dev_handle, 183bf215546Sopenharmony_ci create_info, NULL, &layout_handle); 184bf215546Sopenharmony_ci} 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ciVkResult 187bf215546Sopenharmony_civn_CreateDescriptorSetLayout( 188bf215546Sopenharmony_ci VkDevice device, 189bf215546Sopenharmony_ci const VkDescriptorSetLayoutCreateInfo *pCreateInfo, 190bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 191bf215546Sopenharmony_ci VkDescriptorSetLayout *pSetLayout) 192bf215546Sopenharmony_ci{ 193bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 194bf215546Sopenharmony_ci /* ignore pAllocator as the layout is reference-counted */ 195bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = &dev->base.base.alloc; 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci uint32_t last_binding = 0; 198bf215546Sopenharmony_ci VkDescriptorSetLayoutBinding *local_bindings = NULL; 199bf215546Sopenharmony_ci VkDescriptorSetLayoutCreateInfo local_create_info; 200bf215546Sopenharmony_ci if (pCreateInfo->bindingCount) { 201bf215546Sopenharmony_ci /* the encoder does not ignore 202bf215546Sopenharmony_ci * VkDescriptorSetLayoutBinding::pImmutableSamplers when it should 203bf215546Sopenharmony_ci */ 204bf215546Sopenharmony_ci const size_t binding_size = 205bf215546Sopenharmony_ci sizeof(*pCreateInfo->pBindings) * pCreateInfo->bindingCount; 206bf215546Sopenharmony_ci local_bindings = vk_alloc(alloc, binding_size, VN_DEFAULT_ALIGN, 207bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 208bf215546Sopenharmony_ci if (!local_bindings) 209bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci memcpy(local_bindings, pCreateInfo->pBindings, binding_size); 212bf215546Sopenharmony_ci for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) { 213bf215546Sopenharmony_ci VkDescriptorSetLayoutBinding *binding = &local_bindings[i]; 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci if (last_binding < binding->binding) 216bf215546Sopenharmony_ci last_binding = binding->binding; 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci switch (binding->descriptorType) { 219bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 220bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 221bf215546Sopenharmony_ci break; 222bf215546Sopenharmony_ci default: 223bf215546Sopenharmony_ci binding->pImmutableSamplers = NULL; 224bf215546Sopenharmony_ci break; 225bf215546Sopenharmony_ci } 226bf215546Sopenharmony_ci } 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci local_create_info = *pCreateInfo; 229bf215546Sopenharmony_ci local_create_info.pBindings = local_bindings; 230bf215546Sopenharmony_ci pCreateInfo = &local_create_info; 231bf215546Sopenharmony_ci } 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci const size_t layout_size = 234bf215546Sopenharmony_ci offsetof(struct vn_descriptor_set_layout, bindings[last_binding + 1]); 235bf215546Sopenharmony_ci /* allocated with the device scope */ 236bf215546Sopenharmony_ci struct vn_descriptor_set_layout *layout = 237bf215546Sopenharmony_ci vk_zalloc(alloc, layout_size, VN_DEFAULT_ALIGN, 238bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_DEVICE); 239bf215546Sopenharmony_ci if (!layout) { 240bf215546Sopenharmony_ci vk_free(alloc, local_bindings); 241bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 242bf215546Sopenharmony_ci } 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci vn_object_base_init(&layout->base, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, 245bf215546Sopenharmony_ci &dev->base); 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci vn_descriptor_set_layout_init(dev, pCreateInfo, last_binding, layout); 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ci vk_free(alloc, local_bindings); 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci *pSetLayout = vn_descriptor_set_layout_to_handle(layout); 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci return VK_SUCCESS; 254bf215546Sopenharmony_ci} 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_civoid 257bf215546Sopenharmony_civn_DestroyDescriptorSetLayout(VkDevice device, 258bf215546Sopenharmony_ci VkDescriptorSetLayout descriptorSetLayout, 259bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 260bf215546Sopenharmony_ci{ 261bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 262bf215546Sopenharmony_ci struct vn_descriptor_set_layout *layout = 263bf215546Sopenharmony_ci vn_descriptor_set_layout_from_handle(descriptorSetLayout); 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci if (!layout) 266bf215546Sopenharmony_ci return; 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci vn_descriptor_set_layout_unref(dev, layout); 269bf215546Sopenharmony_ci} 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci/* descriptor pool commands */ 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ciVkResult 274bf215546Sopenharmony_civn_CreateDescriptorPool(VkDevice device, 275bf215546Sopenharmony_ci const VkDescriptorPoolCreateInfo *pCreateInfo, 276bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 277bf215546Sopenharmony_ci VkDescriptorPool *pDescriptorPool) 278bf215546Sopenharmony_ci{ 279bf215546Sopenharmony_ci VN_TRACE_FUNC(); 280bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 281bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 282bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci const VkDescriptorPoolInlineUniformBlockCreateInfo *iub_info = 285bf215546Sopenharmony_ci vk_find_struct_const(pCreateInfo->pNext, 286bf215546Sopenharmony_ci DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO); 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci struct vn_descriptor_pool *pool = 289bf215546Sopenharmony_ci vk_zalloc(alloc, sizeof(*pool), VN_DEFAULT_ALIGN, 290bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 291bf215546Sopenharmony_ci if (!pool) 292bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci vn_object_base_init(&pool->base, VK_OBJECT_TYPE_DESCRIPTOR_POOL, 295bf215546Sopenharmony_ci &dev->base); 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci pool->allocator = *alloc; 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci /* Without VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, the set 300bf215546Sopenharmony_ci * allocation must not fail due to a fragmented pool per spec. In this 301bf215546Sopenharmony_ci * case, set allocation can be asynchronous with pool resource tracking. 302bf215546Sopenharmony_ci */ 303bf215546Sopenharmony_ci pool->async_set_allocation = 304bf215546Sopenharmony_ci !VN_PERF(NO_ASYNC_SET_ALLOC) && 305bf215546Sopenharmony_ci !(pCreateInfo->flags & 306bf215546Sopenharmony_ci VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT); 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci pool->max.set_count = pCreateInfo->maxSets; 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci if (iub_info) 311bf215546Sopenharmony_ci pool->max.iub_binding_count = iub_info->maxInlineUniformBlockBindings; 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci for (uint32_t i = 0; i < pCreateInfo->poolSizeCount; i++) { 314bf215546Sopenharmony_ci const VkDescriptorPoolSize *pool_size = &pCreateInfo->pPoolSizes[i]; 315bf215546Sopenharmony_ci const uint32_t type_index = vn_descriptor_type_index(pool_size->type); 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci assert(type_index < VN_NUM_DESCRIPTOR_TYPES); 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci pool->max.descriptor_counts[type_index] += pool_size->descriptorCount; 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_ci assert((pCreateInfo->pPoolSizes[i].type != 322bf215546Sopenharmony_ci VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) || 323bf215546Sopenharmony_ci iub_info); 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci list_inithead(&pool->descriptor_sets); 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci VkDescriptorPool pool_handle = vn_descriptor_pool_to_handle(pool); 329bf215546Sopenharmony_ci vn_async_vkCreateDescriptorPool(dev->instance, device, pCreateInfo, NULL, 330bf215546Sopenharmony_ci &pool_handle); 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_ci *pDescriptorPool = pool_handle; 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci return VK_SUCCESS; 335bf215546Sopenharmony_ci} 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_civoid 338bf215546Sopenharmony_civn_DestroyDescriptorPool(VkDevice device, 339bf215546Sopenharmony_ci VkDescriptorPool descriptorPool, 340bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 341bf215546Sopenharmony_ci{ 342bf215546Sopenharmony_ci VN_TRACE_FUNC(); 343bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 344bf215546Sopenharmony_ci struct vn_descriptor_pool *pool = 345bf215546Sopenharmony_ci vn_descriptor_pool_from_handle(descriptorPool); 346bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc; 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ci if (!pool) 349bf215546Sopenharmony_ci return; 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci alloc = pAllocator ? pAllocator : &pool->allocator; 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci /* We must emit vkDestroyDescriptorPool before freeing the sets in 354bf215546Sopenharmony_ci * pool->descriptor_sets. Otherwise, another thread might reuse their 355bf215546Sopenharmony_ci * object ids while they still refer to the sets in the renderer. 356bf215546Sopenharmony_ci */ 357bf215546Sopenharmony_ci vn_async_vkDestroyDescriptorPool(dev->instance, device, descriptorPool, 358bf215546Sopenharmony_ci NULL); 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci list_for_each_entry_safe(struct vn_descriptor_set, set, 361bf215546Sopenharmony_ci &pool->descriptor_sets, head) 362bf215546Sopenharmony_ci vn_descriptor_set_destroy(dev, set, alloc); 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci vn_object_base_fini(&pool->base); 365bf215546Sopenharmony_ci vk_free(alloc, pool); 366bf215546Sopenharmony_ci} 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_cistatic bool 369bf215546Sopenharmony_civn_descriptor_pool_alloc_descriptors( 370bf215546Sopenharmony_ci struct vn_descriptor_pool *pool, 371bf215546Sopenharmony_ci const struct vn_descriptor_set_layout *layout, 372bf215546Sopenharmony_ci uint32_t last_binding_descriptor_count) 373bf215546Sopenharmony_ci{ 374bf215546Sopenharmony_ci struct vn_descriptor_pool_state recovery; 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci if (!pool->async_set_allocation) 377bf215546Sopenharmony_ci return true; 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci if (pool->used.set_count == pool->max.set_count) 380bf215546Sopenharmony_ci return false; 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci /* backup current pool state to recovery */ 383bf215546Sopenharmony_ci recovery = pool->used; 384bf215546Sopenharmony_ci 385bf215546Sopenharmony_ci ++pool->used.set_count; 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci for (uint32_t i = 0; i <= layout->last_binding; i++) { 388bf215546Sopenharmony_ci const VkDescriptorType type = layout->bindings[i].type; 389bf215546Sopenharmony_ci const uint32_t count = i == layout->last_binding 390bf215546Sopenharmony_ci ? last_binding_descriptor_count 391bf215546Sopenharmony_ci : layout->bindings[i].count; 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_ci /* Allocation may fail if a call to vkAllocateDescriptorSets would cause 394bf215546Sopenharmony_ci * the total number of inline uniform block bindings allocated from the 395bf215546Sopenharmony_ci * pool to exceed the value of 396bf215546Sopenharmony_ci * VkDescriptorPoolInlineUniformBlockCreateInfo::maxInlineUniformBlockBindings 397bf215546Sopenharmony_ci * used to create the descriptor pool. 398bf215546Sopenharmony_ci */ 399bf215546Sopenharmony_ci if (type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) { 400bf215546Sopenharmony_ci if (++pool->used.iub_binding_count > pool->max.iub_binding_count) { 401bf215546Sopenharmony_ci /* restore pool state before this allocation */ 402bf215546Sopenharmony_ci pool->used = recovery; 403bf215546Sopenharmony_ci return false; 404bf215546Sopenharmony_ci } 405bf215546Sopenharmony_ci } 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci const uint32_t type_index = vn_descriptor_type_index(type); 408bf215546Sopenharmony_ci pool->used.descriptor_counts[type_index] += count; 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci if (pool->used.descriptor_counts[type_index] > 411bf215546Sopenharmony_ci pool->max.descriptor_counts[type_index]) { 412bf215546Sopenharmony_ci /* restore pool state before this allocation */ 413bf215546Sopenharmony_ci pool->used = recovery; 414bf215546Sopenharmony_ci return false; 415bf215546Sopenharmony_ci } 416bf215546Sopenharmony_ci } 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci return true; 419bf215546Sopenharmony_ci} 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_cistatic void 422bf215546Sopenharmony_civn_descriptor_pool_free_descriptors( 423bf215546Sopenharmony_ci struct vn_descriptor_pool *pool, 424bf215546Sopenharmony_ci const struct vn_descriptor_set_layout *layout, 425bf215546Sopenharmony_ci uint32_t last_binding_descriptor_count) 426bf215546Sopenharmony_ci{ 427bf215546Sopenharmony_ci if (!pool->async_set_allocation) 428bf215546Sopenharmony_ci return; 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci for (uint32_t i = 0; i <= layout->last_binding; i++) { 431bf215546Sopenharmony_ci const uint32_t count = i == layout->last_binding 432bf215546Sopenharmony_ci ? last_binding_descriptor_count 433bf215546Sopenharmony_ci : layout->bindings[i].count; 434bf215546Sopenharmony_ci 435bf215546Sopenharmony_ci pool->used.descriptor_counts[vn_descriptor_type_index( 436bf215546Sopenharmony_ci layout->bindings[i].type)] -= count; 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ci if (layout->bindings[i].type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) 439bf215546Sopenharmony_ci --pool->used.iub_binding_count; 440bf215546Sopenharmony_ci } 441bf215546Sopenharmony_ci 442bf215546Sopenharmony_ci --pool->used.set_count; 443bf215546Sopenharmony_ci} 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_cistatic void 446bf215546Sopenharmony_civn_descriptor_pool_reset_descriptors(struct vn_descriptor_pool *pool) 447bf215546Sopenharmony_ci{ 448bf215546Sopenharmony_ci if (!pool->async_set_allocation) 449bf215546Sopenharmony_ci return; 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_ci memset(&pool->used, 0, sizeof(pool->used)); 452bf215546Sopenharmony_ci} 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_ciVkResult 455bf215546Sopenharmony_civn_ResetDescriptorPool(VkDevice device, 456bf215546Sopenharmony_ci VkDescriptorPool descriptorPool, 457bf215546Sopenharmony_ci VkDescriptorPoolResetFlags flags) 458bf215546Sopenharmony_ci{ 459bf215546Sopenharmony_ci VN_TRACE_FUNC(); 460bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 461bf215546Sopenharmony_ci struct vn_descriptor_pool *pool = 462bf215546Sopenharmony_ci vn_descriptor_pool_from_handle(descriptorPool); 463bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = &pool->allocator; 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_ci vn_async_vkResetDescriptorPool(dev->instance, device, descriptorPool, 466bf215546Sopenharmony_ci flags); 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci list_for_each_entry_safe(struct vn_descriptor_set, set, 469bf215546Sopenharmony_ci &pool->descriptor_sets, head) 470bf215546Sopenharmony_ci vn_descriptor_set_destroy(dev, set, alloc); 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci vn_descriptor_pool_reset_descriptors(pool); 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ci return VK_SUCCESS; 475bf215546Sopenharmony_ci} 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci/* descriptor set commands */ 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ciVkResult 480bf215546Sopenharmony_civn_AllocateDescriptorSets(VkDevice device, 481bf215546Sopenharmony_ci const VkDescriptorSetAllocateInfo *pAllocateInfo, 482bf215546Sopenharmony_ci VkDescriptorSet *pDescriptorSets) 483bf215546Sopenharmony_ci{ 484bf215546Sopenharmony_ci VN_TRACE_FUNC(); 485bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 486bf215546Sopenharmony_ci struct vn_descriptor_pool *pool = 487bf215546Sopenharmony_ci vn_descriptor_pool_from_handle(pAllocateInfo->descriptorPool); 488bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = &pool->allocator; 489bf215546Sopenharmony_ci const VkDescriptorSetVariableDescriptorCountAllocateInfo *variable_info = 490bf215546Sopenharmony_ci NULL; 491bf215546Sopenharmony_ci VkResult result; 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci /* 14.2.3. Allocation of Descriptor Sets 494bf215546Sopenharmony_ci * 495bf215546Sopenharmony_ci * If descriptorSetCount is zero or this structure is not included in 496bf215546Sopenharmony_ci * the pNext chain, then the variable lengths are considered to be zero. 497bf215546Sopenharmony_ci */ 498bf215546Sopenharmony_ci variable_info = vk_find_struct_const( 499bf215546Sopenharmony_ci pAllocateInfo->pNext, 500bf215546Sopenharmony_ci DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO); 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci if (variable_info && !variable_info->descriptorSetCount) 503bf215546Sopenharmony_ci variable_info = NULL; 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_ci for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) { 506bf215546Sopenharmony_ci struct vn_descriptor_set_layout *layout = 507bf215546Sopenharmony_ci vn_descriptor_set_layout_from_handle(pAllocateInfo->pSetLayouts[i]); 508bf215546Sopenharmony_ci uint32_t last_binding_descriptor_count = 0; 509bf215546Sopenharmony_ci struct vn_descriptor_set *set = NULL; 510bf215546Sopenharmony_ci 511bf215546Sopenharmony_ci /* 14.2.3. Allocation of Descriptor Sets 512bf215546Sopenharmony_ci * 513bf215546Sopenharmony_ci * If VkDescriptorSetAllocateInfo::pSetLayouts[i] does not include a 514bf215546Sopenharmony_ci * variable count descriptor binding, then pDescriptorCounts[i] is 515bf215546Sopenharmony_ci * ignored. 516bf215546Sopenharmony_ci */ 517bf215546Sopenharmony_ci if (!layout->has_variable_descriptor_count) { 518bf215546Sopenharmony_ci last_binding_descriptor_count = 519bf215546Sopenharmony_ci layout->bindings[layout->last_binding].count; 520bf215546Sopenharmony_ci } else if (variable_info) { 521bf215546Sopenharmony_ci last_binding_descriptor_count = variable_info->pDescriptorCounts[i]; 522bf215546Sopenharmony_ci } 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_ci if (!vn_descriptor_pool_alloc_descriptors( 525bf215546Sopenharmony_ci pool, layout, last_binding_descriptor_count)) { 526bf215546Sopenharmony_ci pDescriptorSets[i] = VK_NULL_HANDLE; 527bf215546Sopenharmony_ci result = VK_ERROR_OUT_OF_POOL_MEMORY; 528bf215546Sopenharmony_ci goto fail; 529bf215546Sopenharmony_ci } 530bf215546Sopenharmony_ci 531bf215546Sopenharmony_ci set = vk_zalloc(alloc, sizeof(*set), VN_DEFAULT_ALIGN, 532bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 533bf215546Sopenharmony_ci if (!set) { 534bf215546Sopenharmony_ci vn_descriptor_pool_free_descriptors(pool, layout, 535bf215546Sopenharmony_ci last_binding_descriptor_count); 536bf215546Sopenharmony_ci pDescriptorSets[i] = VK_NULL_HANDLE; 537bf215546Sopenharmony_ci result = VK_ERROR_OUT_OF_HOST_MEMORY; 538bf215546Sopenharmony_ci goto fail; 539bf215546Sopenharmony_ci } 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_ci vn_object_base_init(&set->base, VK_OBJECT_TYPE_DESCRIPTOR_SET, 542bf215546Sopenharmony_ci &dev->base); 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci /* We might reorder vkCmdBindDescriptorSets after 545bf215546Sopenharmony_ci * vkDestroyDescriptorSetLayout due to batching. The spec says 546bf215546Sopenharmony_ci * 547bf215546Sopenharmony_ci * VkDescriptorSetLayout objects may be accessed by commands that 548bf215546Sopenharmony_ci * operate on descriptor sets allocated using that layout, and those 549bf215546Sopenharmony_ci * descriptor sets must not be updated with vkUpdateDescriptorSets 550bf215546Sopenharmony_ci * after the descriptor set layout has been destroyed. Otherwise, a 551bf215546Sopenharmony_ci * VkDescriptorSetLayout object passed as a parameter to create 552bf215546Sopenharmony_ci * another object is not further accessed by that object after the 553bf215546Sopenharmony_ci * duration of the command it is passed into. 554bf215546Sopenharmony_ci * 555bf215546Sopenharmony_ci * It is ambiguous but the reordering is likely invalid. Let's keep the 556bf215546Sopenharmony_ci * layout alive with the set to defer vkDestroyDescriptorSetLayout. 557bf215546Sopenharmony_ci */ 558bf215546Sopenharmony_ci set->layout = vn_descriptor_set_layout_ref(dev, layout); 559bf215546Sopenharmony_ci set->last_binding_descriptor_count = last_binding_descriptor_count; 560bf215546Sopenharmony_ci list_addtail(&set->head, &pool->descriptor_sets); 561bf215546Sopenharmony_ci 562bf215546Sopenharmony_ci VkDescriptorSet set_handle = vn_descriptor_set_to_handle(set); 563bf215546Sopenharmony_ci pDescriptorSets[i] = set_handle; 564bf215546Sopenharmony_ci } 565bf215546Sopenharmony_ci 566bf215546Sopenharmony_ci if (pool->async_set_allocation) { 567bf215546Sopenharmony_ci vn_async_vkAllocateDescriptorSets(dev->instance, device, pAllocateInfo, 568bf215546Sopenharmony_ci pDescriptorSets); 569bf215546Sopenharmony_ci } else { 570bf215546Sopenharmony_ci result = vn_call_vkAllocateDescriptorSets( 571bf215546Sopenharmony_ci dev->instance, device, pAllocateInfo, pDescriptorSets); 572bf215546Sopenharmony_ci if (result != VK_SUCCESS) 573bf215546Sopenharmony_ci goto fail; 574bf215546Sopenharmony_ci } 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_ci return VK_SUCCESS; 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_cifail: 579bf215546Sopenharmony_ci for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) { 580bf215546Sopenharmony_ci struct vn_descriptor_set *set = 581bf215546Sopenharmony_ci vn_descriptor_set_from_handle(pDescriptorSets[i]); 582bf215546Sopenharmony_ci if (!set) 583bf215546Sopenharmony_ci break; 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci vn_descriptor_pool_free_descriptors(pool, set->layout, 586bf215546Sopenharmony_ci set->last_binding_descriptor_count); 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci vn_descriptor_set_destroy(dev, set, alloc); 589bf215546Sopenharmony_ci } 590bf215546Sopenharmony_ci 591bf215546Sopenharmony_ci memset(pDescriptorSets, 0, 592bf215546Sopenharmony_ci sizeof(*pDescriptorSets) * pAllocateInfo->descriptorSetCount); 593bf215546Sopenharmony_ci 594bf215546Sopenharmony_ci return vn_error(dev->instance, result); 595bf215546Sopenharmony_ci} 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_ciVkResult 598bf215546Sopenharmony_civn_FreeDescriptorSets(VkDevice device, 599bf215546Sopenharmony_ci VkDescriptorPool descriptorPool, 600bf215546Sopenharmony_ci uint32_t descriptorSetCount, 601bf215546Sopenharmony_ci const VkDescriptorSet *pDescriptorSets) 602bf215546Sopenharmony_ci{ 603bf215546Sopenharmony_ci VN_TRACE_FUNC(); 604bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 605bf215546Sopenharmony_ci struct vn_descriptor_pool *pool = 606bf215546Sopenharmony_ci vn_descriptor_pool_from_handle(descriptorPool); 607bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = &pool->allocator; 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci vn_async_vkFreeDescriptorSets(dev->instance, device, descriptorPool, 610bf215546Sopenharmony_ci descriptorSetCount, pDescriptorSets); 611bf215546Sopenharmony_ci 612bf215546Sopenharmony_ci for (uint32_t i = 0; i < descriptorSetCount; i++) { 613bf215546Sopenharmony_ci struct vn_descriptor_set *set = 614bf215546Sopenharmony_ci vn_descriptor_set_from_handle(pDescriptorSets[i]); 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci if (!set) 617bf215546Sopenharmony_ci continue; 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_ci vn_descriptor_set_destroy(dev, set, alloc); 620bf215546Sopenharmony_ci } 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci return VK_SUCCESS; 623bf215546Sopenharmony_ci} 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_cistatic struct vn_update_descriptor_sets * 626bf215546Sopenharmony_civn_update_descriptor_sets_alloc(uint32_t write_count, 627bf215546Sopenharmony_ci uint32_t image_count, 628bf215546Sopenharmony_ci uint32_t buffer_count, 629bf215546Sopenharmony_ci uint32_t view_count, 630bf215546Sopenharmony_ci uint32_t iub_count, 631bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 632bf215546Sopenharmony_ci VkSystemAllocationScope scope) 633bf215546Sopenharmony_ci{ 634bf215546Sopenharmony_ci const size_t writes_offset = sizeof(struct vn_update_descriptor_sets); 635bf215546Sopenharmony_ci const size_t images_offset = 636bf215546Sopenharmony_ci writes_offset + sizeof(VkWriteDescriptorSet) * write_count; 637bf215546Sopenharmony_ci const size_t buffers_offset = 638bf215546Sopenharmony_ci images_offset + sizeof(VkDescriptorImageInfo) * image_count; 639bf215546Sopenharmony_ci const size_t views_offset = 640bf215546Sopenharmony_ci buffers_offset + sizeof(VkDescriptorBufferInfo) * buffer_count; 641bf215546Sopenharmony_ci const size_t iubs_offset = 642bf215546Sopenharmony_ci views_offset + sizeof(VkBufferView) * view_count; 643bf215546Sopenharmony_ci const size_t alloc_size = 644bf215546Sopenharmony_ci iubs_offset + 645bf215546Sopenharmony_ci sizeof(VkWriteDescriptorSetInlineUniformBlock) * iub_count; 646bf215546Sopenharmony_ci 647bf215546Sopenharmony_ci void *storage = vk_alloc(alloc, alloc_size, VN_DEFAULT_ALIGN, scope); 648bf215546Sopenharmony_ci if (!storage) 649bf215546Sopenharmony_ci return NULL; 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci struct vn_update_descriptor_sets *update = storage; 652bf215546Sopenharmony_ci update->write_count = write_count; 653bf215546Sopenharmony_ci update->writes = storage + writes_offset; 654bf215546Sopenharmony_ci update->images = storage + images_offset; 655bf215546Sopenharmony_ci update->buffers = storage + buffers_offset; 656bf215546Sopenharmony_ci update->views = storage + views_offset; 657bf215546Sopenharmony_ci update->iubs = storage + iubs_offset; 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci return update; 660bf215546Sopenharmony_ci} 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_cistatic struct vn_update_descriptor_sets * 663bf215546Sopenharmony_civn_update_descriptor_sets_parse_writes(uint32_t write_count, 664bf215546Sopenharmony_ci const VkWriteDescriptorSet *writes, 665bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc) 666bf215546Sopenharmony_ci{ 667bf215546Sopenharmony_ci uint32_t img_count = 0; 668bf215546Sopenharmony_ci for (uint32_t i = 0; i < write_count; i++) { 669bf215546Sopenharmony_ci const VkWriteDescriptorSet *write = &writes[i]; 670bf215546Sopenharmony_ci switch (write->descriptorType) { 671bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 672bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 673bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 674bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 675bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 676bf215546Sopenharmony_ci img_count += write->descriptorCount; 677bf215546Sopenharmony_ci break; 678bf215546Sopenharmony_ci default: 679bf215546Sopenharmony_ci break; 680bf215546Sopenharmony_ci } 681bf215546Sopenharmony_ci } 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_ci struct vn_update_descriptor_sets *update = 684bf215546Sopenharmony_ci vn_update_descriptor_sets_alloc(write_count, img_count, 0, 0, 0, alloc, 685bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 686bf215546Sopenharmony_ci if (!update) 687bf215546Sopenharmony_ci return NULL; 688bf215546Sopenharmony_ci 689bf215546Sopenharmony_ci /* the encoder does not ignore 690bf215546Sopenharmony_ci * VkWriteDescriptorSet::{pImageInfo,pBufferInfo,pTexelBufferView} when it 691bf215546Sopenharmony_ci * should 692bf215546Sopenharmony_ci * 693bf215546Sopenharmony_ci * TODO make the encoder smarter 694bf215546Sopenharmony_ci */ 695bf215546Sopenharmony_ci memcpy(update->writes, writes, sizeof(*writes) * write_count); 696bf215546Sopenharmony_ci img_count = 0; 697bf215546Sopenharmony_ci for (uint32_t i = 0; i < write_count; i++) { 698bf215546Sopenharmony_ci const struct vn_descriptor_set *set = 699bf215546Sopenharmony_ci vn_descriptor_set_from_handle(writes[i].dstSet); 700bf215546Sopenharmony_ci const struct vn_descriptor_set_layout_binding *binding = 701bf215546Sopenharmony_ci &set->layout->bindings[writes[i].dstBinding]; 702bf215546Sopenharmony_ci VkWriteDescriptorSet *write = &update->writes[i]; 703bf215546Sopenharmony_ci VkDescriptorImageInfo *imgs = &update->images[img_count]; 704bf215546Sopenharmony_ci 705bf215546Sopenharmony_ci switch (write->descriptorType) { 706bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 707bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 708bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 709bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 710bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 711bf215546Sopenharmony_ci memcpy(imgs, write->pImageInfo, 712bf215546Sopenharmony_ci sizeof(*imgs) * write->descriptorCount); 713bf215546Sopenharmony_ci img_count += write->descriptorCount; 714bf215546Sopenharmony_ci 715bf215546Sopenharmony_ci for (uint32_t j = 0; j < write->descriptorCount; j++) { 716bf215546Sopenharmony_ci switch (write->descriptorType) { 717bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 718bf215546Sopenharmony_ci imgs[j].imageView = VK_NULL_HANDLE; 719bf215546Sopenharmony_ci break; 720bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 721bf215546Sopenharmony_ci if (binding->has_immutable_samplers) 722bf215546Sopenharmony_ci imgs[j].sampler = VK_NULL_HANDLE; 723bf215546Sopenharmony_ci break; 724bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 725bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 726bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 727bf215546Sopenharmony_ci imgs[j].sampler = VK_NULL_HANDLE; 728bf215546Sopenharmony_ci break; 729bf215546Sopenharmony_ci default: 730bf215546Sopenharmony_ci break; 731bf215546Sopenharmony_ci } 732bf215546Sopenharmony_ci } 733bf215546Sopenharmony_ci 734bf215546Sopenharmony_ci write->pImageInfo = imgs; 735bf215546Sopenharmony_ci write->pBufferInfo = NULL; 736bf215546Sopenharmony_ci write->pTexelBufferView = NULL; 737bf215546Sopenharmony_ci break; 738bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 739bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 740bf215546Sopenharmony_ci write->pImageInfo = NULL; 741bf215546Sopenharmony_ci write->pBufferInfo = NULL; 742bf215546Sopenharmony_ci break; 743bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 744bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 745bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 746bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 747bf215546Sopenharmony_ci write->pImageInfo = NULL; 748bf215546Sopenharmony_ci write->pTexelBufferView = NULL; 749bf215546Sopenharmony_ci break; 750bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: 751bf215546Sopenharmony_ci default: 752bf215546Sopenharmony_ci write->pImageInfo = NULL; 753bf215546Sopenharmony_ci write->pBufferInfo = NULL; 754bf215546Sopenharmony_ci write->pTexelBufferView = NULL; 755bf215546Sopenharmony_ci break; 756bf215546Sopenharmony_ci } 757bf215546Sopenharmony_ci } 758bf215546Sopenharmony_ci 759bf215546Sopenharmony_ci return update; 760bf215546Sopenharmony_ci} 761bf215546Sopenharmony_ci 762bf215546Sopenharmony_civoid 763bf215546Sopenharmony_civn_UpdateDescriptorSets(VkDevice device, 764bf215546Sopenharmony_ci uint32_t descriptorWriteCount, 765bf215546Sopenharmony_ci const VkWriteDescriptorSet *pDescriptorWrites, 766bf215546Sopenharmony_ci uint32_t descriptorCopyCount, 767bf215546Sopenharmony_ci const VkCopyDescriptorSet *pDescriptorCopies) 768bf215546Sopenharmony_ci{ 769bf215546Sopenharmony_ci VN_TRACE_FUNC(); 770bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 771bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = &dev->base.base.alloc; 772bf215546Sopenharmony_ci 773bf215546Sopenharmony_ci struct vn_update_descriptor_sets *update = 774bf215546Sopenharmony_ci vn_update_descriptor_sets_parse_writes(descriptorWriteCount, 775bf215546Sopenharmony_ci pDescriptorWrites, alloc); 776bf215546Sopenharmony_ci if (!update) { 777bf215546Sopenharmony_ci /* TODO update one-by-one? */ 778bf215546Sopenharmony_ci vn_log(dev->instance, "TODO descriptor set update ignored due to OOM"); 779bf215546Sopenharmony_ci return; 780bf215546Sopenharmony_ci } 781bf215546Sopenharmony_ci 782bf215546Sopenharmony_ci vn_async_vkUpdateDescriptorSets(dev->instance, device, update->write_count, 783bf215546Sopenharmony_ci update->writes, descriptorCopyCount, 784bf215546Sopenharmony_ci pDescriptorCopies); 785bf215546Sopenharmony_ci 786bf215546Sopenharmony_ci vk_free(alloc, update); 787bf215546Sopenharmony_ci} 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_ci/* descriptor update template commands */ 790bf215546Sopenharmony_ci 791bf215546Sopenharmony_cistatic struct vn_update_descriptor_sets * 792bf215546Sopenharmony_civn_update_descriptor_sets_parse_template( 793bf215546Sopenharmony_ci const VkDescriptorUpdateTemplateCreateInfo *create_info, 794bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 795bf215546Sopenharmony_ci struct vn_descriptor_update_template_entry *entries) 796bf215546Sopenharmony_ci{ 797bf215546Sopenharmony_ci uint32_t img_count = 0; 798bf215546Sopenharmony_ci uint32_t buf_count = 0; 799bf215546Sopenharmony_ci uint32_t view_count = 0; 800bf215546Sopenharmony_ci uint32_t iub_count = 0; 801bf215546Sopenharmony_ci for (uint32_t i = 0; i < create_info->descriptorUpdateEntryCount; i++) { 802bf215546Sopenharmony_ci const VkDescriptorUpdateTemplateEntry *entry = 803bf215546Sopenharmony_ci &create_info->pDescriptorUpdateEntries[i]; 804bf215546Sopenharmony_ci 805bf215546Sopenharmony_ci switch (entry->descriptorType) { 806bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 807bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 808bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 809bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 810bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 811bf215546Sopenharmony_ci img_count += entry->descriptorCount; 812bf215546Sopenharmony_ci break; 813bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 814bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 815bf215546Sopenharmony_ci view_count += entry->descriptorCount; 816bf215546Sopenharmony_ci break; 817bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 818bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 819bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 820bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 821bf215546Sopenharmony_ci buf_count += entry->descriptorCount; 822bf215546Sopenharmony_ci break; 823bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: 824bf215546Sopenharmony_ci iub_count += 1; 825bf215546Sopenharmony_ci break; 826bf215546Sopenharmony_ci default: 827bf215546Sopenharmony_ci unreachable("unhandled descriptor type"); 828bf215546Sopenharmony_ci break; 829bf215546Sopenharmony_ci } 830bf215546Sopenharmony_ci } 831bf215546Sopenharmony_ci 832bf215546Sopenharmony_ci struct vn_update_descriptor_sets *update = vn_update_descriptor_sets_alloc( 833bf215546Sopenharmony_ci create_info->descriptorUpdateEntryCount, img_count, buf_count, 834bf215546Sopenharmony_ci view_count, iub_count, alloc, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 835bf215546Sopenharmony_ci if (!update) 836bf215546Sopenharmony_ci return NULL; 837bf215546Sopenharmony_ci 838bf215546Sopenharmony_ci img_count = 0; 839bf215546Sopenharmony_ci buf_count = 0; 840bf215546Sopenharmony_ci view_count = 0; 841bf215546Sopenharmony_ci iub_count = 0; 842bf215546Sopenharmony_ci for (uint32_t i = 0; i < create_info->descriptorUpdateEntryCount; i++) { 843bf215546Sopenharmony_ci const VkDescriptorUpdateTemplateEntry *entry = 844bf215546Sopenharmony_ci &create_info->pDescriptorUpdateEntries[i]; 845bf215546Sopenharmony_ci VkWriteDescriptorSet *write = &update->writes[i]; 846bf215546Sopenharmony_ci 847bf215546Sopenharmony_ci write->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 848bf215546Sopenharmony_ci write->pNext = NULL; 849bf215546Sopenharmony_ci write->dstBinding = entry->dstBinding; 850bf215546Sopenharmony_ci write->dstArrayElement = entry->dstArrayElement; 851bf215546Sopenharmony_ci write->descriptorCount = entry->descriptorCount; 852bf215546Sopenharmony_ci write->descriptorType = entry->descriptorType; 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_ci entries[i].offset = entry->offset; 855bf215546Sopenharmony_ci entries[i].stride = entry->stride; 856bf215546Sopenharmony_ci 857bf215546Sopenharmony_ci switch (entry->descriptorType) { 858bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 859bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 860bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 861bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 862bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 863bf215546Sopenharmony_ci write->pImageInfo = &update->images[img_count]; 864bf215546Sopenharmony_ci write->pBufferInfo = NULL; 865bf215546Sopenharmony_ci write->pTexelBufferView = NULL; 866bf215546Sopenharmony_ci img_count += entry->descriptorCount; 867bf215546Sopenharmony_ci break; 868bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 869bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 870bf215546Sopenharmony_ci write->pImageInfo = NULL; 871bf215546Sopenharmony_ci write->pBufferInfo = NULL; 872bf215546Sopenharmony_ci write->pTexelBufferView = &update->views[view_count]; 873bf215546Sopenharmony_ci view_count += entry->descriptorCount; 874bf215546Sopenharmony_ci break; 875bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 876bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 877bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 878bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 879bf215546Sopenharmony_ci write->pImageInfo = NULL; 880bf215546Sopenharmony_ci write->pBufferInfo = &update->buffers[buf_count]; 881bf215546Sopenharmony_ci write->pTexelBufferView = NULL; 882bf215546Sopenharmony_ci buf_count += entry->descriptorCount; 883bf215546Sopenharmony_ci break; 884bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: 885bf215546Sopenharmony_ci write->pImageInfo = NULL; 886bf215546Sopenharmony_ci write->pBufferInfo = NULL; 887bf215546Sopenharmony_ci write->pTexelBufferView = NULL; 888bf215546Sopenharmony_ci VkWriteDescriptorSetInlineUniformBlock *iub_data = 889bf215546Sopenharmony_ci &update->iubs[iub_count]; 890bf215546Sopenharmony_ci iub_data->sType = 891bf215546Sopenharmony_ci VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK; 892bf215546Sopenharmony_ci iub_data->pNext = write->pNext; 893bf215546Sopenharmony_ci iub_data->dataSize = entry->descriptorCount; 894bf215546Sopenharmony_ci write->pNext = iub_data; 895bf215546Sopenharmony_ci iub_count += 1; 896bf215546Sopenharmony_ci break; 897bf215546Sopenharmony_ci default: 898bf215546Sopenharmony_ci break; 899bf215546Sopenharmony_ci } 900bf215546Sopenharmony_ci } 901bf215546Sopenharmony_ci 902bf215546Sopenharmony_ci return update; 903bf215546Sopenharmony_ci} 904bf215546Sopenharmony_ci 905bf215546Sopenharmony_ciVkResult 906bf215546Sopenharmony_civn_CreateDescriptorUpdateTemplate( 907bf215546Sopenharmony_ci VkDevice device, 908bf215546Sopenharmony_ci const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo, 909bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 910bf215546Sopenharmony_ci VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) 911bf215546Sopenharmony_ci{ 912bf215546Sopenharmony_ci VN_TRACE_FUNC(); 913bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 914bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 915bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 916bf215546Sopenharmony_ci 917bf215546Sopenharmony_ci const size_t templ_size = 918bf215546Sopenharmony_ci offsetof(struct vn_descriptor_update_template, 919bf215546Sopenharmony_ci entries[pCreateInfo->descriptorUpdateEntryCount + 1]); 920bf215546Sopenharmony_ci struct vn_descriptor_update_template *templ = vk_zalloc( 921bf215546Sopenharmony_ci alloc, templ_size, VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 922bf215546Sopenharmony_ci if (!templ) 923bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 924bf215546Sopenharmony_ci 925bf215546Sopenharmony_ci vn_object_base_init(&templ->base, 926bf215546Sopenharmony_ci VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE, &dev->base); 927bf215546Sopenharmony_ci 928bf215546Sopenharmony_ci templ->update = vn_update_descriptor_sets_parse_template( 929bf215546Sopenharmony_ci pCreateInfo, alloc, templ->entries); 930bf215546Sopenharmony_ci if (!templ->update) { 931bf215546Sopenharmony_ci vk_free(alloc, templ); 932bf215546Sopenharmony_ci return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 933bf215546Sopenharmony_ci } 934bf215546Sopenharmony_ci 935bf215546Sopenharmony_ci mtx_init(&templ->mutex, mtx_plain); 936bf215546Sopenharmony_ci 937bf215546Sopenharmony_ci /* no host object */ 938bf215546Sopenharmony_ci VkDescriptorUpdateTemplate templ_handle = 939bf215546Sopenharmony_ci vn_descriptor_update_template_to_handle(templ); 940bf215546Sopenharmony_ci *pDescriptorUpdateTemplate = templ_handle; 941bf215546Sopenharmony_ci 942bf215546Sopenharmony_ci return VK_SUCCESS; 943bf215546Sopenharmony_ci} 944bf215546Sopenharmony_ci 945bf215546Sopenharmony_civoid 946bf215546Sopenharmony_civn_DestroyDescriptorUpdateTemplate( 947bf215546Sopenharmony_ci VkDevice device, 948bf215546Sopenharmony_ci VkDescriptorUpdateTemplate descriptorUpdateTemplate, 949bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 950bf215546Sopenharmony_ci{ 951bf215546Sopenharmony_ci VN_TRACE_FUNC(); 952bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 953bf215546Sopenharmony_ci struct vn_descriptor_update_template *templ = 954bf215546Sopenharmony_ci vn_descriptor_update_template_from_handle(descriptorUpdateTemplate); 955bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc = 956bf215546Sopenharmony_ci pAllocator ? pAllocator : &dev->base.base.alloc; 957bf215546Sopenharmony_ci 958bf215546Sopenharmony_ci if (!templ) 959bf215546Sopenharmony_ci return; 960bf215546Sopenharmony_ci 961bf215546Sopenharmony_ci /* no host object */ 962bf215546Sopenharmony_ci vk_free(alloc, templ->update); 963bf215546Sopenharmony_ci mtx_destroy(&templ->mutex); 964bf215546Sopenharmony_ci 965bf215546Sopenharmony_ci vn_object_base_fini(&templ->base); 966bf215546Sopenharmony_ci vk_free(alloc, templ); 967bf215546Sopenharmony_ci} 968bf215546Sopenharmony_ci 969bf215546Sopenharmony_civoid 970bf215546Sopenharmony_civn_UpdateDescriptorSetWithTemplate( 971bf215546Sopenharmony_ci VkDevice device, 972bf215546Sopenharmony_ci VkDescriptorSet descriptorSet, 973bf215546Sopenharmony_ci VkDescriptorUpdateTemplate descriptorUpdateTemplate, 974bf215546Sopenharmony_ci const void *pData) 975bf215546Sopenharmony_ci{ 976bf215546Sopenharmony_ci VN_TRACE_FUNC(); 977bf215546Sopenharmony_ci struct vn_device *dev = vn_device_from_handle(device); 978bf215546Sopenharmony_ci struct vn_descriptor_set *set = 979bf215546Sopenharmony_ci vn_descriptor_set_from_handle(descriptorSet); 980bf215546Sopenharmony_ci struct vn_descriptor_update_template *templ = 981bf215546Sopenharmony_ci vn_descriptor_update_template_from_handle(descriptorUpdateTemplate); 982bf215546Sopenharmony_ci struct vn_update_descriptor_sets *update = templ->update; 983bf215546Sopenharmony_ci 984bf215546Sopenharmony_ci /* duplicate update instead to avoid locking? */ 985bf215546Sopenharmony_ci mtx_lock(&templ->mutex); 986bf215546Sopenharmony_ci 987bf215546Sopenharmony_ci for (uint32_t i = 0; i < update->write_count; i++) { 988bf215546Sopenharmony_ci const struct vn_descriptor_update_template_entry *entry = 989bf215546Sopenharmony_ci &templ->entries[i]; 990bf215546Sopenharmony_ci const struct vn_descriptor_set_layout_binding *binding = 991bf215546Sopenharmony_ci &set->layout->bindings[update->writes[i].dstBinding]; 992bf215546Sopenharmony_ci VkWriteDescriptorSet *write = &update->writes[i]; 993bf215546Sopenharmony_ci 994bf215546Sopenharmony_ci write->dstSet = vn_descriptor_set_to_handle(set); 995bf215546Sopenharmony_ci 996bf215546Sopenharmony_ci switch (write->descriptorType) { 997bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 998bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 999bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 1000bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 1001bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 1002bf215546Sopenharmony_ci for (uint32_t j = 0; j < write->descriptorCount; j++) { 1003bf215546Sopenharmony_ci const bool need_sampler = 1004bf215546Sopenharmony_ci (write->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER || 1005bf215546Sopenharmony_ci write->descriptorType == 1006bf215546Sopenharmony_ci VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) && 1007bf215546Sopenharmony_ci !binding->has_immutable_samplers; 1008bf215546Sopenharmony_ci const bool need_view = 1009bf215546Sopenharmony_ci write->descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER; 1010bf215546Sopenharmony_ci const VkDescriptorImageInfo *src = 1011bf215546Sopenharmony_ci pData + entry->offset + entry->stride * j; 1012bf215546Sopenharmony_ci VkDescriptorImageInfo *dst = 1013bf215546Sopenharmony_ci (VkDescriptorImageInfo *)&write->pImageInfo[j]; 1014bf215546Sopenharmony_ci 1015bf215546Sopenharmony_ci dst->sampler = need_sampler ? src->sampler : VK_NULL_HANDLE; 1016bf215546Sopenharmony_ci dst->imageView = need_view ? src->imageView : VK_NULL_HANDLE; 1017bf215546Sopenharmony_ci dst->imageLayout = src->imageLayout; 1018bf215546Sopenharmony_ci } 1019bf215546Sopenharmony_ci break; 1020bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 1021bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 1022bf215546Sopenharmony_ci for (uint32_t j = 0; j < write->descriptorCount; j++) { 1023bf215546Sopenharmony_ci const VkBufferView *src = 1024bf215546Sopenharmony_ci pData + entry->offset + entry->stride * j; 1025bf215546Sopenharmony_ci VkBufferView *dst = (VkBufferView *)&write->pTexelBufferView[j]; 1026bf215546Sopenharmony_ci *dst = *src; 1027bf215546Sopenharmony_ci } 1028bf215546Sopenharmony_ci break; 1029bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 1030bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 1031bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 1032bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 1033bf215546Sopenharmony_ci for (uint32_t j = 0; j < write->descriptorCount; j++) { 1034bf215546Sopenharmony_ci const VkDescriptorBufferInfo *src = 1035bf215546Sopenharmony_ci pData + entry->offset + entry->stride * j; 1036bf215546Sopenharmony_ci VkDescriptorBufferInfo *dst = 1037bf215546Sopenharmony_ci (VkDescriptorBufferInfo *)&write->pBufferInfo[j]; 1038bf215546Sopenharmony_ci *dst = *src; 1039bf215546Sopenharmony_ci } 1040bf215546Sopenharmony_ci break; 1041bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK:; 1042bf215546Sopenharmony_ci VkWriteDescriptorSetInlineUniformBlock *iub_data = 1043bf215546Sopenharmony_ci (VkWriteDescriptorSetInlineUniformBlock *)vk_find_struct_const( 1044bf215546Sopenharmony_ci write->pNext, WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK); 1045bf215546Sopenharmony_ci iub_data->pData = pData + entry->offset; 1046bf215546Sopenharmony_ci break; 1047bf215546Sopenharmony_ci default: 1048bf215546Sopenharmony_ci unreachable("unhandled descriptor type"); 1049bf215546Sopenharmony_ci break; 1050bf215546Sopenharmony_ci } 1051bf215546Sopenharmony_ci } 1052bf215546Sopenharmony_ci 1053bf215546Sopenharmony_ci vn_async_vkUpdateDescriptorSets(dev->instance, device, update->write_count, 1054bf215546Sopenharmony_ci update->writes, 0, NULL); 1055bf215546Sopenharmony_ci 1056bf215546Sopenharmony_ci mtx_unlock(&templ->mutex); 1057bf215546Sopenharmony_ci} 1058