1/* 2 * Copyright © 2019 Red Hat. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include "lvp_private.h" 25#include "vk_descriptors.h" 26#include "vk_util.h" 27#include "u_math.h" 28 29VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDescriptorSetLayout( 30 VkDevice _device, 31 const VkDescriptorSetLayoutCreateInfo* pCreateInfo, 32 const VkAllocationCallbacks* pAllocator, 33 VkDescriptorSetLayout* pSetLayout) 34{ 35 LVP_FROM_HANDLE(lvp_device, device, _device); 36 struct lvp_descriptor_set_layout *set_layout; 37 38 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO); 39 uint32_t num_bindings = 0; 40 uint32_t immutable_sampler_count = 0; 41 for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) { 42 num_bindings = MAX2(num_bindings, pCreateInfo->pBindings[j].binding + 1); 43 /* From the Vulkan 1.1.97 spec for VkDescriptorSetLayoutBinding: 44 * 45 * "If descriptorType specifies a VK_DESCRIPTOR_TYPE_SAMPLER or 46 * VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER type descriptor, then 47 * pImmutableSamplers can be used to initialize a set of immutable 48 * samplers. [...] If descriptorType is not one of these descriptor 49 * types, then pImmutableSamplers is ignored. 50 * 51 * We need to be careful here and only parse pImmutableSamplers if we 52 * have one of the right descriptor types. 53 */ 54 VkDescriptorType desc_type = pCreateInfo->pBindings[j].descriptorType; 55 if ((desc_type == VK_DESCRIPTOR_TYPE_SAMPLER || 56 desc_type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) && 57 pCreateInfo->pBindings[j].pImmutableSamplers) 58 immutable_sampler_count += pCreateInfo->pBindings[j].descriptorCount; 59 } 60 61 size_t size = sizeof(struct lvp_descriptor_set_layout) + 62 num_bindings * sizeof(set_layout->binding[0]) + 63 immutable_sampler_count * sizeof(struct lvp_sampler *); 64 65 set_layout = vk_zalloc2(&device->vk.alloc, pAllocator, size, 8, 66 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 67 if (!set_layout) 68 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 69 70 vk_object_base_init(&device->vk, &set_layout->base, 71 VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT); 72 set_layout->ref_cnt = 1; 73 /* We just allocate all the samplers at the end of the struct */ 74 struct lvp_sampler **samplers = 75 (struct lvp_sampler **)&set_layout->binding[num_bindings]; 76 77 set_layout->alloc = pAllocator; 78 set_layout->binding_count = num_bindings; 79 set_layout->shader_stages = 0; 80 set_layout->size = 0; 81 82 VkDescriptorSetLayoutBinding *bindings = NULL; 83 VkResult result = vk_create_sorted_bindings(pCreateInfo->pBindings, 84 pCreateInfo->bindingCount, 85 &bindings); 86 if (result != VK_SUCCESS) { 87 vk_object_base_finish(&set_layout->base); 88 vk_free2(&device->vk.alloc, pAllocator, set_layout); 89 return vk_error(device, result); 90 } 91 92 uint32_t dynamic_offset_count = 0; 93 for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) { 94 const VkDescriptorSetLayoutBinding *binding = bindings + j; 95 uint32_t b = binding->binding; 96 97 set_layout->binding[b].array_size = binding->descriptorCount; 98 set_layout->binding[b].descriptor_index = set_layout->size; 99 set_layout->binding[b].type = binding->descriptorType; 100 set_layout->binding[b].valid = true; 101 set_layout->size += binding->descriptorCount; 102 103 for (gl_shader_stage stage = MESA_SHADER_VERTEX; stage < MESA_SHADER_STAGES; stage++) { 104 set_layout->binding[b].stage[stage].const_buffer_index = -1; 105 set_layout->binding[b].stage[stage].shader_buffer_index = -1; 106 set_layout->binding[b].stage[stage].sampler_index = -1; 107 set_layout->binding[b].stage[stage].sampler_view_index = -1; 108 set_layout->binding[b].stage[stage].image_index = -1; 109 } 110 111 if (binding->descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || 112 binding->descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC) { 113 set_layout->binding[b].dynamic_index = dynamic_offset_count; 114 dynamic_offset_count += binding->descriptorCount; 115 } 116 switch (binding->descriptorType) { 117 case VK_DESCRIPTOR_TYPE_SAMPLER: 118 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 119 lvp_foreach_stage(s, binding->stageFlags) { 120 set_layout->binding[b].stage[s].sampler_index = set_layout->stage[s].sampler_count; 121 set_layout->stage[s].sampler_count += binding->descriptorCount; 122 } 123 if (binding->pImmutableSamplers) { 124 set_layout->binding[b].immutable_samplers = samplers; 125 samplers += binding->descriptorCount; 126 127 for (uint32_t i = 0; i < binding->descriptorCount; i++) 128 set_layout->binding[b].immutable_samplers[i] = 129 lvp_sampler_from_handle(binding->pImmutableSamplers[i]); 130 } 131 break; 132 default: 133 break; 134 } 135 136 switch (binding->descriptorType) { 137 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 138 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 139 lvp_foreach_stage(s, binding->stageFlags) { 140 set_layout->binding[b].stage[s].const_buffer_index = set_layout->stage[s].const_buffer_count; 141 set_layout->stage[s].const_buffer_count += binding->descriptorCount; 142 } 143 break; 144 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 145 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 146 lvp_foreach_stage(s, binding->stageFlags) { 147 set_layout->binding[b].stage[s].shader_buffer_index = set_layout->stage[s].shader_buffer_count; 148 set_layout->stage[s].shader_buffer_count += binding->descriptorCount; 149 } 150 break; 151 152 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 153 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 154 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 155 lvp_foreach_stage(s, binding->stageFlags) { 156 set_layout->binding[b].stage[s].image_index = set_layout->stage[s].image_count; 157 set_layout->stage[s].image_count += binding->descriptorCount; 158 } 159 break; 160 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 161 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 162 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 163 lvp_foreach_stage(s, binding->stageFlags) { 164 set_layout->binding[b].stage[s].sampler_view_index = set_layout->stage[s].sampler_view_count; 165 set_layout->stage[s].sampler_view_count += binding->descriptorCount; 166 } 167 break; 168 default: 169 break; 170 } 171 172 set_layout->shader_stages |= binding->stageFlags; 173 } 174 175 free(bindings); 176 177 set_layout->dynamic_offset_count = dynamic_offset_count; 178 179 *pSetLayout = lvp_descriptor_set_layout_to_handle(set_layout); 180 181 return VK_SUCCESS; 182} 183 184void 185lvp_descriptor_set_layout_destroy(struct lvp_device *device, 186 struct lvp_descriptor_set_layout *layout) 187{ 188 assert(layout->ref_cnt == 0); 189 vk_object_base_finish(&layout->base); 190 vk_free2(&device->vk.alloc, layout->alloc, layout); 191} 192 193VKAPI_ATTR void VKAPI_CALL lvp_DestroyDescriptorSetLayout( 194 VkDevice _device, 195 VkDescriptorSetLayout _set_layout, 196 const VkAllocationCallbacks* pAllocator) 197{ 198 LVP_FROM_HANDLE(lvp_device, device, _device); 199 LVP_FROM_HANDLE(lvp_descriptor_set_layout, set_layout, _set_layout); 200 201 if (!_set_layout) 202 return; 203 204 lvp_descriptor_set_layout_unref(device, set_layout); 205} 206 207VKAPI_ATTR VkResult VKAPI_CALL lvp_CreatePipelineLayout( 208 VkDevice _device, 209 const VkPipelineLayoutCreateInfo* pCreateInfo, 210 const VkAllocationCallbacks* pAllocator, 211 VkPipelineLayout* pPipelineLayout) 212{ 213 LVP_FROM_HANDLE(lvp_device, device, _device); 214 struct lvp_pipeline_layout *layout; 215 216 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO); 217 218 layout = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*layout), 8, 219 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 220 if (layout == NULL) 221 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 222 223 vk_object_base_init(&device->vk, &layout->base, 224 VK_OBJECT_TYPE_PIPELINE_LAYOUT); 225 layout->num_sets = pCreateInfo->setLayoutCount; 226 227 for (uint32_t set = 0; set < pCreateInfo->setLayoutCount; set++) { 228 LVP_FROM_HANDLE(lvp_descriptor_set_layout, set_layout, 229 pCreateInfo->pSetLayouts[set]); 230 layout->set[set].layout = set_layout; 231 lvp_descriptor_set_layout_ref(set_layout); 232 } 233 234 layout->push_constant_size = 0; 235 for (unsigned i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) { 236 const VkPushConstantRange *range = pCreateInfo->pPushConstantRanges + i; 237 layout->push_constant_size = MAX2(layout->push_constant_size, 238 range->offset + range->size); 239 } 240 layout->push_constant_size = align(layout->push_constant_size, 16); 241 *pPipelineLayout = lvp_pipeline_layout_to_handle(layout); 242 243 return VK_SUCCESS; 244} 245 246VKAPI_ATTR void VKAPI_CALL lvp_DestroyPipelineLayout( 247 VkDevice _device, 248 VkPipelineLayout _pipelineLayout, 249 const VkAllocationCallbacks* pAllocator) 250{ 251 LVP_FROM_HANDLE(lvp_device, device, _device); 252 LVP_FROM_HANDLE(lvp_pipeline_layout, pipeline_layout, _pipelineLayout); 253 254 if (!_pipelineLayout) 255 return; 256 for (uint32_t i = 0; i < pipeline_layout->num_sets; i++) 257 lvp_descriptor_set_layout_unref(device, pipeline_layout->set[i].layout); 258 259 vk_object_base_finish(&pipeline_layout->base); 260 vk_free2(&device->vk.alloc, pAllocator, pipeline_layout); 261} 262 263VkResult 264lvp_descriptor_set_create(struct lvp_device *device, 265 struct lvp_descriptor_set_layout *layout, 266 struct lvp_descriptor_set **out_set) 267{ 268 struct lvp_descriptor_set *set; 269 size_t size = sizeof(*set) + layout->size * sizeof(set->descriptors[0]); 270 271 set = vk_alloc(&device->vk.alloc /* XXX: Use the pool */, size, 8, 272 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 273 if (!set) 274 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 275 276 /* A descriptor set may not be 100% filled. Clear the set so we can can 277 * later detect holes in it. 278 */ 279 memset(set, 0, size); 280 281 vk_object_base_init(&device->vk, &set->base, 282 VK_OBJECT_TYPE_DESCRIPTOR_SET); 283 set->layout = layout; 284 lvp_descriptor_set_layout_ref(layout); 285 286 /* Go through and fill out immutable samplers if we have any */ 287 struct lvp_descriptor *desc = set->descriptors; 288 for (uint32_t b = 0; b < layout->binding_count; b++) { 289 if (layout->binding[b].immutable_samplers) { 290 for (uint32_t i = 0; i < layout->binding[b].array_size; i++) 291 desc[i].info.sampler = layout->binding[b].immutable_samplers[i]; 292 } 293 desc += layout->binding[b].array_size; 294 } 295 296 *out_set = set; 297 298 return VK_SUCCESS; 299} 300 301void 302lvp_descriptor_set_destroy(struct lvp_device *device, 303 struct lvp_descriptor_set *set) 304{ 305 lvp_descriptor_set_layout_unref(device, set->layout); 306 vk_object_base_finish(&set->base); 307 vk_free(&device->vk.alloc, set); 308} 309 310VKAPI_ATTR VkResult VKAPI_CALL lvp_AllocateDescriptorSets( 311 VkDevice _device, 312 const VkDescriptorSetAllocateInfo* pAllocateInfo, 313 VkDescriptorSet* pDescriptorSets) 314{ 315 LVP_FROM_HANDLE(lvp_device, device, _device); 316 LVP_FROM_HANDLE(lvp_descriptor_pool, pool, pAllocateInfo->descriptorPool); 317 VkResult result = VK_SUCCESS; 318 struct lvp_descriptor_set *set; 319 uint32_t i; 320 321 for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) { 322 LVP_FROM_HANDLE(lvp_descriptor_set_layout, layout, 323 pAllocateInfo->pSetLayouts[i]); 324 325 result = lvp_descriptor_set_create(device, layout, &set); 326 if (result != VK_SUCCESS) 327 break; 328 329 list_addtail(&set->link, &pool->sets); 330 pDescriptorSets[i] = lvp_descriptor_set_to_handle(set); 331 } 332 333 if (result != VK_SUCCESS) 334 lvp_FreeDescriptorSets(_device, pAllocateInfo->descriptorPool, 335 i, pDescriptorSets); 336 337 return result; 338} 339 340VKAPI_ATTR VkResult VKAPI_CALL lvp_FreeDescriptorSets( 341 VkDevice _device, 342 VkDescriptorPool descriptorPool, 343 uint32_t count, 344 const VkDescriptorSet* pDescriptorSets) 345{ 346 LVP_FROM_HANDLE(lvp_device, device, _device); 347 for (uint32_t i = 0; i < count; i++) { 348 LVP_FROM_HANDLE(lvp_descriptor_set, set, pDescriptorSets[i]); 349 350 if (!set) 351 continue; 352 list_del(&set->link); 353 lvp_descriptor_set_destroy(device, set); 354 } 355 return VK_SUCCESS; 356} 357 358VKAPI_ATTR void VKAPI_CALL lvp_UpdateDescriptorSets( 359 VkDevice _device, 360 uint32_t descriptorWriteCount, 361 const VkWriteDescriptorSet* pDescriptorWrites, 362 uint32_t descriptorCopyCount, 363 const VkCopyDescriptorSet* pDescriptorCopies) 364{ 365 for (uint32_t i = 0; i < descriptorWriteCount; i++) { 366 const VkWriteDescriptorSet *write = &pDescriptorWrites[i]; 367 LVP_FROM_HANDLE(lvp_descriptor_set, set, write->dstSet); 368 const struct lvp_descriptor_set_binding_layout *bind_layout = 369 &set->layout->binding[write->dstBinding]; 370 struct lvp_descriptor *desc = 371 &set->descriptors[bind_layout->descriptor_index]; 372 desc += write->dstArrayElement; 373 374 switch (write->descriptorType) { 375 case VK_DESCRIPTOR_TYPE_SAMPLER: 376 for (uint32_t j = 0; j < write->descriptorCount; j++) { 377 LVP_FROM_HANDLE(lvp_sampler, sampler, 378 write->pImageInfo[j].sampler); 379 380 desc[j] = (struct lvp_descriptor) { 381 .type = VK_DESCRIPTOR_TYPE_SAMPLER, 382 .info.sampler = sampler, 383 }; 384 } 385 break; 386 387 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 388 for (uint32_t j = 0; j < write->descriptorCount; j++) { 389 LVP_FROM_HANDLE(lvp_image_view, iview, 390 write->pImageInfo[j].imageView); 391 desc[j].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 392 desc[j].info.iview = iview; 393 /* 394 * All consecutive bindings updated via a single VkWriteDescriptorSet structure, except those 395 * with a descriptorCount of zero, must all either use immutable samplers or must all not 396 * use immutable samplers 397 */ 398 if (bind_layout->immutable_samplers) { 399 desc[j].info.sampler = bind_layout->immutable_samplers[j]; 400 } else { 401 LVP_FROM_HANDLE(lvp_sampler, sampler, 402 write->pImageInfo[j].sampler); 403 404 desc[j].info.sampler = sampler; 405 } 406 } 407 break; 408 409 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 410 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 411 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 412 for (uint32_t j = 0; j < write->descriptorCount; j++) { 413 LVP_FROM_HANDLE(lvp_image_view, iview, 414 write->pImageInfo[j].imageView); 415 416 desc[j] = (struct lvp_descriptor) { 417 .type = write->descriptorType, 418 .info.iview = iview, 419 }; 420 } 421 break; 422 423 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 424 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 425 for (uint32_t j = 0; j < write->descriptorCount; j++) { 426 LVP_FROM_HANDLE(lvp_buffer_view, bview, 427 write->pTexelBufferView[j]); 428 429 desc[j] = (struct lvp_descriptor) { 430 .type = write->descriptorType, 431 .info.buffer_view = bview, 432 }; 433 } 434 break; 435 436 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 437 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 438 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 439 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 440 for (uint32_t j = 0; j < write->descriptorCount; j++) { 441 assert(write->pBufferInfo[j].buffer); 442 LVP_FROM_HANDLE(lvp_buffer, buffer, write->pBufferInfo[j].buffer); 443 assert(buffer); 444 desc[j] = (struct lvp_descriptor) { 445 .type = write->descriptorType, 446 .info.offset = write->pBufferInfo[j].offset, 447 .info.buffer = buffer, 448 .info.range = write->pBufferInfo[j].range, 449 }; 450 451 } 452 453 default: 454 break; 455 } 456 } 457 458 for (uint32_t i = 0; i < descriptorCopyCount; i++) { 459 const VkCopyDescriptorSet *copy = &pDescriptorCopies[i]; 460 LVP_FROM_HANDLE(lvp_descriptor_set, src, copy->srcSet); 461 LVP_FROM_HANDLE(lvp_descriptor_set, dst, copy->dstSet); 462 463 const struct lvp_descriptor_set_binding_layout *src_layout = 464 &src->layout->binding[copy->srcBinding]; 465 struct lvp_descriptor *src_desc = 466 &src->descriptors[src_layout->descriptor_index]; 467 src_desc += copy->srcArrayElement; 468 469 const struct lvp_descriptor_set_binding_layout *dst_layout = 470 &dst->layout->binding[copy->dstBinding]; 471 struct lvp_descriptor *dst_desc = 472 &dst->descriptors[dst_layout->descriptor_index]; 473 dst_desc += copy->dstArrayElement; 474 475 for (uint32_t j = 0; j < copy->descriptorCount; j++) 476 dst_desc[j] = src_desc[j]; 477 } 478} 479 480VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDescriptorPool( 481 VkDevice _device, 482 const VkDescriptorPoolCreateInfo* pCreateInfo, 483 const VkAllocationCallbacks* pAllocator, 484 VkDescriptorPool* pDescriptorPool) 485{ 486 LVP_FROM_HANDLE(lvp_device, device, _device); 487 struct lvp_descriptor_pool *pool; 488 size_t size = sizeof(struct lvp_descriptor_pool); 489 pool = vk_zalloc2(&device->vk.alloc, pAllocator, size, 8, 490 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 491 if (!pool) 492 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 493 494 vk_object_base_init(&device->vk, &pool->base, 495 VK_OBJECT_TYPE_DESCRIPTOR_POOL); 496 pool->flags = pCreateInfo->flags; 497 list_inithead(&pool->sets); 498 *pDescriptorPool = lvp_descriptor_pool_to_handle(pool); 499 return VK_SUCCESS; 500} 501 502static void lvp_reset_descriptor_pool(struct lvp_device *device, 503 struct lvp_descriptor_pool *pool) 504{ 505 struct lvp_descriptor_set *set, *tmp; 506 LIST_FOR_EACH_ENTRY_SAFE(set, tmp, &pool->sets, link) { 507 lvp_descriptor_set_layout_unref(device, set->layout); 508 list_del(&set->link); 509 vk_free(&device->vk.alloc, set); 510 } 511} 512 513VKAPI_ATTR void VKAPI_CALL lvp_DestroyDescriptorPool( 514 VkDevice _device, 515 VkDescriptorPool _pool, 516 const VkAllocationCallbacks* pAllocator) 517{ 518 LVP_FROM_HANDLE(lvp_device, device, _device); 519 LVP_FROM_HANDLE(lvp_descriptor_pool, pool, _pool); 520 521 if (!_pool) 522 return; 523 524 lvp_reset_descriptor_pool(device, pool); 525 vk_object_base_finish(&pool->base); 526 vk_free2(&device->vk.alloc, pAllocator, pool); 527} 528 529VKAPI_ATTR VkResult VKAPI_CALL lvp_ResetDescriptorPool( 530 VkDevice _device, 531 VkDescriptorPool _pool, 532 VkDescriptorPoolResetFlags flags) 533{ 534 LVP_FROM_HANDLE(lvp_device, device, _device); 535 LVP_FROM_HANDLE(lvp_descriptor_pool, pool, _pool); 536 537 lvp_reset_descriptor_pool(device, pool); 538 return VK_SUCCESS; 539} 540 541VKAPI_ATTR void VKAPI_CALL lvp_GetDescriptorSetLayoutSupport(VkDevice device, 542 const VkDescriptorSetLayoutCreateInfo* pCreateInfo, 543 VkDescriptorSetLayoutSupport* pSupport) 544{ 545 pSupport->supported = true; 546} 547 548VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateDescriptorUpdateTemplate(VkDevice _device, 549 const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo, 550 const VkAllocationCallbacks *pAllocator, 551 VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate) 552{ 553 LVP_FROM_HANDLE(lvp_device, device, _device); 554 const uint32_t entry_count = pCreateInfo->descriptorUpdateEntryCount; 555 const size_t size = sizeof(struct lvp_descriptor_update_template) + 556 sizeof(VkDescriptorUpdateTemplateEntry) * entry_count; 557 558 struct lvp_descriptor_update_template *templ; 559 560 templ = vk_alloc2(&device->vk.alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 561 if (!templ) 562 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 563 564 vk_object_base_init(&device->vk, &templ->base, 565 VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE); 566 567 templ->type = pCreateInfo->templateType; 568 templ->bind_point = pCreateInfo->pipelineBindPoint; 569 templ->set = pCreateInfo->set; 570 /* This parameter is ignored if templateType is not VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR */ 571 if (pCreateInfo->templateType == VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR) 572 templ->pipeline_layout = lvp_pipeline_layout_from_handle(pCreateInfo->pipelineLayout); 573 else 574 templ->pipeline_layout = NULL; 575 templ->entry_count = entry_count; 576 577 VkDescriptorUpdateTemplateEntry *entries = (VkDescriptorUpdateTemplateEntry *)(templ + 1); 578 for (unsigned i = 0; i < entry_count; i++) { 579 entries[i] = pCreateInfo->pDescriptorUpdateEntries[i]; 580 } 581 582 *pDescriptorUpdateTemplate = lvp_descriptor_update_template_to_handle(templ); 583 return VK_SUCCESS; 584} 585 586VKAPI_ATTR void VKAPI_CALL lvp_DestroyDescriptorUpdateTemplate(VkDevice _device, 587 VkDescriptorUpdateTemplate descriptorUpdateTemplate, 588 const VkAllocationCallbacks *pAllocator) 589{ 590 LVP_FROM_HANDLE(lvp_device, device, _device); 591 LVP_FROM_HANDLE(lvp_descriptor_update_template, templ, descriptorUpdateTemplate); 592 593 if (!templ) 594 return; 595 596 vk_object_base_finish(&templ->base); 597 vk_free2(&device->vk.alloc, pAllocator, templ); 598} 599 600VKAPI_ATTR void VKAPI_CALL lvp_UpdateDescriptorSetWithTemplate(VkDevice _device, 601 VkDescriptorSet descriptorSet, 602 VkDescriptorUpdateTemplate descriptorUpdateTemplate, 603 const void *pData) 604{ 605 LVP_FROM_HANDLE(lvp_descriptor_set, set, descriptorSet); 606 LVP_FROM_HANDLE(lvp_descriptor_update_template, templ, descriptorUpdateTemplate); 607 uint32_t i, j; 608 609 for (i = 0; i < templ->entry_count; ++i) { 610 VkDescriptorUpdateTemplateEntry *entry = &templ->entry[i]; 611 const uint8_t *pSrc = ((const uint8_t *) pData) + entry->offset; 612 const struct lvp_descriptor_set_binding_layout *bind_layout = 613 &set->layout->binding[entry->dstBinding]; 614 struct lvp_descriptor *desc = 615 &set->descriptors[bind_layout->descriptor_index]; 616 for (j = 0; j < entry->descriptorCount; ++j) { 617 unsigned idx = j + entry->dstArrayElement; 618 switch (entry->descriptorType) { 619 case VK_DESCRIPTOR_TYPE_SAMPLER: { 620 LVP_FROM_HANDLE(lvp_sampler, sampler, 621 *(VkSampler *)pSrc); 622 desc[idx] = (struct lvp_descriptor) { 623 .type = VK_DESCRIPTOR_TYPE_SAMPLER, 624 .info.sampler = sampler, 625 }; 626 break; 627 } 628 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: { 629 VkDescriptorImageInfo *info = (VkDescriptorImageInfo *)pSrc; 630 desc[idx] = (struct lvp_descriptor) { 631 .type = entry->descriptorType, 632 .info.iview = lvp_image_view_from_handle(info->imageView), 633 .info.sampler = lvp_sampler_from_handle(info->sampler), 634 }; 635 break; 636 } 637 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 638 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 639 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: { 640 LVP_FROM_HANDLE(lvp_image_view, iview, 641 ((VkDescriptorImageInfo *)pSrc)->imageView); 642 desc[idx] = (struct lvp_descriptor) { 643 .type = entry->descriptorType, 644 .info.iview = iview, 645 }; 646 break; 647 } 648 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 649 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: { 650 LVP_FROM_HANDLE(lvp_buffer_view, bview, 651 *(VkBufferView *)pSrc); 652 desc[idx] = (struct lvp_descriptor) { 653 .type = entry->descriptorType, 654 .info.buffer_view = bview, 655 }; 656 break; 657 } 658 659 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 660 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 661 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 662 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: { 663 VkDescriptorBufferInfo *info = (VkDescriptorBufferInfo *)pSrc; 664 desc[idx] = (struct lvp_descriptor) { 665 .type = entry->descriptorType, 666 .info.offset = info->offset, 667 .info.buffer = lvp_buffer_from_handle(info->buffer), 668 .info.range = info->range, 669 }; 670 break; 671 } 672 default: 673 break; 674 } 675 pSrc += entry->stride; 676 } 677 } 678} 679