Home | History | Annotate | Line # | Download | only in vulkan
      1 /*
      2  * Copyright  2019 Raspberry Pi
      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 "vk_descriptors.h"
     25 #include "vk_util.h"
     26 
     27 #include "v3dv_private.h"
     28 
     29 /*
     30  * For a given descriptor defined by the descriptor_set it belongs, its
     31  * binding layout, and array_index, it returns the map region assigned to it
     32  * from the descriptor pool bo.
     33  */
     34 static void*
     35 descriptor_bo_map(struct v3dv_device *device,
     36                   struct v3dv_descriptor_set *set,
     37                   const struct v3dv_descriptor_set_binding_layout *binding_layout,
     38                   uint32_t array_index)
     39 {
     40    assert(v3dv_X(device, descriptor_bo_size)(binding_layout->type) > 0);
     41    return set->pool->bo->map +
     42       set->base_offset + binding_layout->descriptor_offset +
     43       array_index * v3dv_X(device, descriptor_bo_size)(binding_layout->type);
     44 }
     45 
     46 static bool
     47 descriptor_type_is_dynamic(VkDescriptorType type)
     48 {
     49    switch (type) {
     50    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
     51    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
     52       return true;
     53       break;
     54    default:
     55       return false;
     56    }
     57 }
     58 
     59 /*
     60  * Tries to get a real descriptor using a descriptor map index from the
     61  * descriptor_state + pipeline_layout.
     62  */
     63 struct v3dv_descriptor *
     64 v3dv_descriptor_map_get_descriptor(struct v3dv_descriptor_state *descriptor_state,
     65                                    struct v3dv_descriptor_map *map,
     66                                    struct v3dv_pipeline_layout *pipeline_layout,
     67                                    uint32_t index,
     68                                    uint32_t *dynamic_offset)
     69 {
     70    assert(index < map->num_desc);
     71 
     72    uint32_t set_number = map->set[index];
     73    assert((descriptor_state->valid & 1 << set_number));
     74 
     75    struct v3dv_descriptor_set *set =
     76       descriptor_state->descriptor_sets[set_number];
     77    assert(set);
     78 
     79    uint32_t binding_number = map->binding[index];
     80    assert(binding_number < set->layout->binding_count);
     81 
     82    const struct v3dv_descriptor_set_binding_layout *binding_layout =
     83       &set->layout->binding[binding_number];
     84 
     85    uint32_t array_index = map->array_index[index];
     86    assert(array_index < binding_layout->array_size);
     87 
     88    if (descriptor_type_is_dynamic(binding_layout->type)) {
     89       uint32_t dynamic_offset_index =
     90          pipeline_layout->set[set_number].dynamic_offset_start +
     91          binding_layout->dynamic_offset_index + array_index;
     92 
     93       *dynamic_offset = descriptor_state->dynamic_offsets[dynamic_offset_index];
     94    }
     95 
     96    return &set->descriptors[binding_layout->descriptor_index + array_index];
     97 }
     98 
     99 /* Equivalent to map_get_descriptor but it returns a reloc with the bo
    100  * associated with that descriptor (suballocation of the descriptor pool bo)
    101  *
    102  * It also returns the descriptor type, so the caller could do extra
    103  * validation or adding extra offsets if the bo contains more that one field.
    104  */
    105 static struct v3dv_cl_reloc
    106 v3dv_descriptor_map_get_descriptor_bo(struct v3dv_device *device,
    107                                       struct v3dv_descriptor_state *descriptor_state,
    108                                       struct v3dv_descriptor_map *map,
    109                                       struct v3dv_pipeline_layout *pipeline_layout,
    110                                       uint32_t index,
    111                                       VkDescriptorType *out_type)
    112 {
    113    assert(index < map->num_desc);
    114 
    115    uint32_t set_number = map->set[index];
    116    assert(descriptor_state->valid & 1 << set_number);
    117 
    118    struct v3dv_descriptor_set *set =
    119       descriptor_state->descriptor_sets[set_number];
    120    assert(set);
    121 
    122    uint32_t binding_number = map->binding[index];
    123    assert(binding_number < set->layout->binding_count);
    124 
    125    const struct v3dv_descriptor_set_binding_layout *binding_layout =
    126       &set->layout->binding[binding_number];
    127 
    128    assert(v3dv_X(device, descriptor_bo_size)(binding_layout->type) > 0);
    129    *out_type = binding_layout->type;
    130 
    131    uint32_t array_index = map->array_index[index];
    132    assert(array_index < binding_layout->array_size);
    133 
    134    struct v3dv_cl_reloc reloc = {
    135       .bo = set->pool->bo,
    136       .offset = set->base_offset + binding_layout->descriptor_offset +
    137       array_index * v3dv_X(device, descriptor_bo_size)(binding_layout->type),
    138    };
    139 
    140    return reloc;
    141 }
    142 
    143 /*
    144  * The difference between this method and v3dv_descriptor_map_get_descriptor,
    145  * is that if the sampler are added as immutable when creating the set layout,
    146  * they are bound to the set layout, so not part of the descriptor per
    147  * se. This method return early in that case.
    148  */
    149 const struct v3dv_sampler *
    150 v3dv_descriptor_map_get_sampler(struct v3dv_descriptor_state *descriptor_state,
    151                                 struct v3dv_descriptor_map *map,
    152                                 struct v3dv_pipeline_layout *pipeline_layout,
    153                                 uint32_t index)
    154 {
    155    assert(index < map->num_desc);
    156 
    157    uint32_t set_number = map->set[index];
    158    assert(descriptor_state->valid & 1 << set_number);
    159 
    160    struct v3dv_descriptor_set *set =
    161       descriptor_state->descriptor_sets[set_number];
    162    assert(set);
    163 
    164    uint32_t binding_number = map->binding[index];
    165    assert(binding_number < set->layout->binding_count);
    166 
    167    const struct v3dv_descriptor_set_binding_layout *binding_layout =
    168       &set->layout->binding[binding_number];
    169 
    170    uint32_t array_index = map->array_index[index];
    171    assert(array_index < binding_layout->array_size);
    172 
    173    if (binding_layout->immutable_samplers_offset != 0) {
    174       assert(binding_layout->type == VK_DESCRIPTOR_TYPE_SAMPLER ||
    175              binding_layout->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
    176 
    177       const struct v3dv_sampler *immutable_samplers =
    178          v3dv_immutable_samplers(set->layout, binding_layout);
    179 
    180       assert(immutable_samplers);
    181       const struct v3dv_sampler *sampler = &immutable_samplers[array_index];
    182       assert(sampler);
    183 
    184       return sampler;
    185    }
    186 
    187    struct v3dv_descriptor *descriptor =
    188       &set->descriptors[binding_layout->descriptor_index + array_index];
    189 
    190    assert(descriptor->type == VK_DESCRIPTOR_TYPE_SAMPLER ||
    191           descriptor->type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
    192 
    193    assert(descriptor->sampler);
    194 
    195    return descriptor->sampler;
    196 }
    197 
    198 
    199 struct v3dv_cl_reloc
    200 v3dv_descriptor_map_get_sampler_state(struct v3dv_device *device,
    201                                       struct v3dv_descriptor_state *descriptor_state,
    202                                       struct v3dv_descriptor_map *map,
    203                                       struct v3dv_pipeline_layout *pipeline_layout,
    204                                       uint32_t index)
    205 {
    206    VkDescriptorType type;
    207    struct v3dv_cl_reloc reloc =
    208       v3dv_descriptor_map_get_descriptor_bo(device, descriptor_state, map,
    209                                             pipeline_layout,
    210                                             index, &type);
    211 
    212    assert(type == VK_DESCRIPTOR_TYPE_SAMPLER ||
    213           type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
    214 
    215    if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
    216       reloc.offset += v3dv_X(device, combined_image_sampler_sampler_state_offset)();
    217 
    218    return reloc;
    219 }
    220 
    221 const struct v3dv_format*
    222 v3dv_descriptor_map_get_texture_format(struct v3dv_descriptor_state *descriptor_state,
    223                                        struct v3dv_descriptor_map *map,
    224                                        struct v3dv_pipeline_layout *pipeline_layout,
    225                                        uint32_t index,
    226                                        VkFormat *out_vk_format)
    227 {
    228    struct v3dv_descriptor *descriptor =
    229       v3dv_descriptor_map_get_descriptor(descriptor_state, map,
    230                                          pipeline_layout, index, NULL);
    231 
    232    switch (descriptor->type) {
    233    case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
    234    case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
    235       assert(descriptor->buffer_view);
    236       *out_vk_format = descriptor->buffer_view->vk_format;
    237       return descriptor->buffer_view->format;
    238    case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
    239    case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
    240    case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
    241    case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
    242       assert(descriptor->image_view);
    243       *out_vk_format = descriptor->image_view->vk.format;
    244       return descriptor->image_view->format;
    245    default:
    246       unreachable("descriptor type doesn't has a texture format");
    247    }
    248 }
    249 
    250 struct v3dv_bo*
    251 v3dv_descriptor_map_get_texture_bo(struct v3dv_descriptor_state *descriptor_state,
    252                                    struct v3dv_descriptor_map *map,
    253                                    struct v3dv_pipeline_layout *pipeline_layout,
    254                                    uint32_t index)
    255 
    256 {
    257    struct v3dv_descriptor *descriptor =
    258       v3dv_descriptor_map_get_descriptor(descriptor_state, map,
    259                                          pipeline_layout, index, NULL);
    260 
    261    switch (descriptor->type) {
    262    case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
    263    case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
    264       assert(descriptor->buffer_view);
    265       return descriptor->buffer_view->buffer->mem->bo;
    266    case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
    267    case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
    268    case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
    269    case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
    270       assert(descriptor->image_view);
    271       struct v3dv_image *image =
    272          (struct v3dv_image *) descriptor->image_view->vk.image;
    273       return image->mem->bo;
    274    }
    275    default:
    276       unreachable("descriptor type doesn't has a texture bo");
    277    }
    278 }
    279 
    280 struct v3dv_cl_reloc
    281 v3dv_descriptor_map_get_texture_shader_state(struct v3dv_device *device,
    282                                              struct v3dv_descriptor_state *descriptor_state,
    283                                              struct v3dv_descriptor_map *map,
    284                                              struct v3dv_pipeline_layout *pipeline_layout,
    285                                              uint32_t index)
    286 {
    287    VkDescriptorType type;
    288    struct v3dv_cl_reloc reloc =
    289       v3dv_descriptor_map_get_descriptor_bo(device,
    290                                             descriptor_state, map,
    291                                             pipeline_layout,
    292                                             index, &type);
    293 
    294    assert(type == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ||
    295           type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
    296           type == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT ||
    297           type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ||
    298           type == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER ||
    299           type == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER);
    300 
    301    if (type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
    302       reloc.offset += v3dv_X(device, combined_image_sampler_texture_state_offset)();
    303 
    304    return reloc;
    305 }
    306 
    307 /*
    308  * As anv and tu already points:
    309  *
    310  * "Pipeline layouts.  These have nothing to do with the pipeline.  They are
    311  * just multiple descriptor set layouts pasted together."
    312  */
    313 
    314 VKAPI_ATTR VkResult VKAPI_CALL
    315 v3dv_CreatePipelineLayout(VkDevice _device,
    316                          const VkPipelineLayoutCreateInfo *pCreateInfo,
    317                          const VkAllocationCallbacks *pAllocator,
    318                          VkPipelineLayout *pPipelineLayout)
    319 {
    320    V3DV_FROM_HANDLE(v3dv_device, device, _device);
    321    struct v3dv_pipeline_layout *layout;
    322 
    323    assert(pCreateInfo->sType ==
    324           VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
    325 
    326    layout = vk_object_zalloc(&device->vk, pAllocator, sizeof(*layout),
    327                              VK_OBJECT_TYPE_PIPELINE_LAYOUT);
    328    if (layout == NULL)
    329       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
    330 
    331    layout->num_sets = pCreateInfo->setLayoutCount;
    332 
    333    uint32_t dynamic_offset_count = 0;
    334    for (uint32_t set = 0; set < pCreateInfo->setLayoutCount; set++) {
    335       V3DV_FROM_HANDLE(v3dv_descriptor_set_layout, set_layout,
    336                      pCreateInfo->pSetLayouts[set]);
    337       layout->set[set].layout = set_layout;
    338 
    339       layout->set[set].dynamic_offset_start = dynamic_offset_count;
    340       for (uint32_t b = 0; b < set_layout->binding_count; b++) {
    341          dynamic_offset_count += set_layout->binding[b].array_size *
    342             set_layout->binding[b].dynamic_offset_count;
    343       }
    344 
    345       layout->shader_stages |= set_layout->shader_stages;
    346    }
    347 
    348    layout->push_constant_size = 0;
    349    for (unsigned i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
    350       const VkPushConstantRange *range = pCreateInfo->pPushConstantRanges + i;
    351       layout->push_constant_size =
    352          MAX2(layout->push_constant_size, range->offset + range->size);
    353    }
    354 
    355    layout->push_constant_size = align(layout->push_constant_size, 4096);
    356 
    357    layout->dynamic_offset_count = dynamic_offset_count;
    358 
    359    *pPipelineLayout = v3dv_pipeline_layout_to_handle(layout);
    360 
    361    return VK_SUCCESS;
    362 }
    363 
    364 VKAPI_ATTR void VKAPI_CALL
    365 v3dv_DestroyPipelineLayout(VkDevice _device,
    366                           VkPipelineLayout _pipelineLayout,
    367                           const VkAllocationCallbacks *pAllocator)
    368 {
    369    V3DV_FROM_HANDLE(v3dv_device, device, _device);
    370    V3DV_FROM_HANDLE(v3dv_pipeline_layout, pipeline_layout, _pipelineLayout);
    371 
    372    if (!pipeline_layout)
    373       return;
    374    vk_object_free(&device->vk, pAllocator, pipeline_layout);
    375 }
    376 
    377 VKAPI_ATTR VkResult VKAPI_CALL
    378 v3dv_CreateDescriptorPool(VkDevice _device,
    379                           const VkDescriptorPoolCreateInfo *pCreateInfo,
    380                           const VkAllocationCallbacks *pAllocator,
    381                           VkDescriptorPool *pDescriptorPool)
    382 {
    383    V3DV_FROM_HANDLE(v3dv_device, device, _device);
    384    struct v3dv_descriptor_pool *pool;
    385    /* size is for the vulkan object descriptor pool. The final size would
    386     * depend on some of FREE_DESCRIPTOR flags used
    387     */
    388    uint64_t size = sizeof(struct v3dv_descriptor_pool);
    389    /* bo_size is for the descriptor related info that we need to have on a GPU
    390     * address (so on v3dv_bo_alloc allocated memory), like for example the
    391     * texture sampler state. Note that not all the descriptors use it
    392     */
    393    uint32_t bo_size = 0;
    394    uint32_t descriptor_count = 0;
    395 
    396    assert(pCreateInfo->poolSizeCount > 0);
    397    for (unsigned i = 0; i < pCreateInfo->poolSizeCount; ++i) {
    398       /* Verify supported descriptor type */
    399       switch(pCreateInfo->pPoolSizes[i].type) {
    400       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
    401       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
    402       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
    403       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
    404       case VK_DESCRIPTOR_TYPE_SAMPLER:
    405       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
    406       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
    407       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
    408       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
    409       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
    410       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
    411          break;
    412       default:
    413          unreachable("Unimplemented descriptor type");
    414          break;
    415       }
    416 
    417       assert(pCreateInfo->pPoolSizes[i].descriptorCount > 0);
    418       descriptor_count += pCreateInfo->pPoolSizes[i].descriptorCount;
    419       bo_size += v3dv_X(device, descriptor_bo_size)(pCreateInfo->pPoolSizes[i].type) *
    420          pCreateInfo->pPoolSizes[i].descriptorCount;
    421    }
    422 
    423    if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT)) {
    424       uint64_t host_size =
    425          pCreateInfo->maxSets * sizeof(struct v3dv_descriptor_set);
    426       host_size += sizeof(struct v3dv_descriptor) * descriptor_count;
    427       size += host_size;
    428    } else {
    429       size += sizeof(struct v3dv_descriptor_pool_entry) * pCreateInfo->maxSets;
    430    }
    431 
    432    pool = vk_object_zalloc(&device->vk, pAllocator, size,
    433                            VK_OBJECT_TYPE_DESCRIPTOR_POOL);
    434 
    435    if (!pool)
    436       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
    437 
    438    if (!(pCreateInfo->flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT)) {
    439       pool->host_memory_base = (uint8_t*)pool + sizeof(struct v3dv_descriptor_pool);
    440       pool->host_memory_ptr = pool->host_memory_base;
    441       pool->host_memory_end = (uint8_t*)pool + size;
    442    }
    443 
    444    pool->max_entry_count = pCreateInfo->maxSets;
    445 
    446    if (bo_size > 0) {
    447       pool->bo = v3dv_bo_alloc(device, bo_size, "descriptor pool bo", true);
    448       if (!pool->bo)
    449          goto out_of_device_memory;
    450 
    451       bool ok = v3dv_bo_map(device, pool->bo, pool->bo->size);
    452       if (!ok)
    453          goto out_of_device_memory;
    454 
    455       pool->current_offset = 0;
    456    } else {
    457       pool->bo = NULL;
    458    }
    459 
    460    *pDescriptorPool = v3dv_descriptor_pool_to_handle(pool);
    461 
    462    return VK_SUCCESS;
    463 
    464  out_of_device_memory:
    465    vk_object_free(&device->vk, pAllocator, pool);
    466    return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
    467 }
    468 
    469 static void
    470 descriptor_set_destroy(struct v3dv_device *device,
    471                        struct v3dv_descriptor_pool *pool,
    472                        struct v3dv_descriptor_set *set,
    473                        bool free_bo)
    474 {
    475    assert(!pool->host_memory_base);
    476 
    477    if (free_bo && !pool->host_memory_base) {
    478       for (uint32_t i = 0; i < pool->entry_count; i++) {
    479          if (pool->entries[i].set == set) {
    480             memmove(&pool->entries[i], &pool->entries[i+1],
    481                     sizeof(pool->entries[i]) * (pool->entry_count - i - 1));
    482             --pool->entry_count;
    483             break;
    484          }
    485       }
    486    }
    487    vk_object_free(&device->vk, NULL, set);
    488 }
    489 
    490 VKAPI_ATTR void VKAPI_CALL
    491 v3dv_DestroyDescriptorPool(VkDevice _device,
    492                            VkDescriptorPool _pool,
    493                            const VkAllocationCallbacks *pAllocator)
    494 {
    495    V3DV_FROM_HANDLE(v3dv_device, device, _device);
    496    V3DV_FROM_HANDLE(v3dv_descriptor_pool, pool, _pool);
    497 
    498    if (!pool)
    499       return;
    500 
    501    if (!pool->host_memory_base) {
    502       for(int i = 0; i < pool->entry_count; ++i) {
    503          descriptor_set_destroy(device, pool, pool->entries[i].set, false);
    504       }
    505    }
    506 
    507    if (pool->bo) {
    508       v3dv_bo_free(device, pool->bo);
    509       pool->bo = NULL;
    510    }
    511 
    512    vk_object_free(&device->vk, pAllocator, pool);
    513 }
    514 
    515 VKAPI_ATTR VkResult VKAPI_CALL
    516 v3dv_ResetDescriptorPool(VkDevice _device,
    517                          VkDescriptorPool descriptorPool,
    518                          VkDescriptorPoolResetFlags flags)
    519 {
    520    V3DV_FROM_HANDLE(v3dv_device, device, _device);
    521    V3DV_FROM_HANDLE(v3dv_descriptor_pool, pool, descriptorPool);
    522 
    523    if (!pool->host_memory_base) {
    524       for(int i = 0; i < pool->entry_count; ++i) {
    525          descriptor_set_destroy(device, pool, pool->entries[i].set, false);
    526       }
    527    } else {
    528       /* We clean-up the host memory, so when allocating a new set from the
    529        * pool, it is already 0
    530        */
    531       uint32_t host_size = pool->host_memory_end - pool->host_memory_base;
    532       memset(pool->host_memory_base, 0, host_size);
    533    }
    534 
    535    pool->entry_count = 0;
    536    pool->host_memory_ptr = pool->host_memory_base;
    537    pool->current_offset = 0;
    538 
    539    return VK_SUCCESS;
    540 }
    541 
    542 VKAPI_ATTR VkResult VKAPI_CALL
    543 v3dv_CreateDescriptorSetLayout(VkDevice _device,
    544                                const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
    545                                const VkAllocationCallbacks *pAllocator,
    546                                VkDescriptorSetLayout *pSetLayout)
    547 {
    548    V3DV_FROM_HANDLE(v3dv_device, device, _device);
    549    struct v3dv_descriptor_set_layout *set_layout;
    550 
    551    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
    552 
    553    uint32_t num_bindings = 0;
    554    uint32_t immutable_sampler_count = 0;
    555    for (uint32_t j = 0; j < pCreateInfo->bindingCount; j++) {
    556       num_bindings = MAX2(num_bindings, pCreateInfo->pBindings[j].binding + 1);
    557 
    558       /* From the Vulkan 1.1.97 spec for VkDescriptorSetLayoutBinding:
    559        *
    560        *    "If descriptorType specifies a VK_DESCRIPTOR_TYPE_SAMPLER or
    561        *    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER type descriptor, then
    562        *    pImmutableSamplers can be used to initialize a set of immutable
    563        *    samplers. [...]  If descriptorType is not one of these descriptor
    564        *    types, then pImmutableSamplers is ignored.
    565        *
    566        * We need to be careful here and only parse pImmutableSamplers if we
    567        * have one of the right descriptor types.
    568        */
    569       VkDescriptorType desc_type = pCreateInfo->pBindings[j].descriptorType;
    570       if ((desc_type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
    571            desc_type == VK_DESCRIPTOR_TYPE_SAMPLER) &&
    572            pCreateInfo->pBindings[j].pImmutableSamplers) {
    573          immutable_sampler_count += pCreateInfo->pBindings[j].descriptorCount;
    574       }
    575    }
    576 
    577    uint32_t samplers_offset = sizeof(struct v3dv_descriptor_set_layout) +
    578       num_bindings * sizeof(set_layout->binding[0]);
    579    uint32_t size = samplers_offset +
    580       immutable_sampler_count * sizeof(struct v3dv_sampler);
    581 
    582    set_layout = vk_object_zalloc(&device->vk, pAllocator, size,
    583                                  VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT);
    584 
    585    if (!set_layout)
    586       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
    587 
    588    /* We just allocate all the immutable samplers at the end of the struct */
    589    struct v3dv_sampler *samplers = (void*) &set_layout->binding[num_bindings];
    590 
    591    assert(pCreateInfo->bindingCount == 0 || num_bindings > 0);
    592 
    593    VkDescriptorSetLayoutBinding *bindings = NULL;
    594    VkResult result = vk_create_sorted_bindings(pCreateInfo->pBindings,
    595                                                pCreateInfo->bindingCount, &bindings);
    596    if (result != VK_SUCCESS) {
    597       vk_object_free(&device->vk, pAllocator, set_layout);
    598       return vk_error(device, result);
    599    }
    600 
    601    memset(set_layout->binding, 0,
    602           size - sizeof(struct v3dv_descriptor_set_layout));
    603 
    604    set_layout->binding_count = num_bindings;
    605    set_layout->flags = pCreateInfo->flags;
    606    set_layout->shader_stages = 0;
    607    set_layout->bo_size = 0;
    608 
    609    uint32_t descriptor_count = 0;
    610    uint32_t dynamic_offset_count = 0;
    611 
    612    for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
    613       const VkDescriptorSetLayoutBinding *binding = bindings + i;
    614       uint32_t binding_number = binding->binding;
    615 
    616       switch (binding->descriptorType) {
    617       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
    618       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
    619          break;
    620       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
    621       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
    622          set_layout->binding[binding_number].dynamic_offset_count = 1;
    623          break;
    624       case VK_DESCRIPTOR_TYPE_SAMPLER:
    625       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
    626       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
    627       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
    628       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
    629       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
    630       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
    631          /* Nothing here, just to keep the descriptor type filtering below */
    632          break;
    633       default:
    634          unreachable("Unknown descriptor type\n");
    635          break;
    636       }
    637 
    638       set_layout->binding[binding_number].type = binding->descriptorType;
    639       set_layout->binding[binding_number].array_size = binding->descriptorCount;
    640       set_layout->binding[binding_number].descriptor_index = descriptor_count;
    641       set_layout->binding[binding_number].dynamic_offset_index = dynamic_offset_count;
    642 
    643       if ((binding->descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||
    644            binding->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) &&
    645           binding->pImmutableSamplers) {
    646 
    647          set_layout->binding[binding_number].immutable_samplers_offset = samplers_offset;
    648 
    649          for (uint32_t i = 0; i < binding->descriptorCount; i++)
    650             samplers[i] = *v3dv_sampler_from_handle(binding->pImmutableSamplers[i]);
    651 
    652          samplers += binding->descriptorCount;
    653          samplers_offset += sizeof(struct v3dv_sampler) * binding->descriptorCount;
    654       }
    655 
    656       descriptor_count += binding->descriptorCount;
    657       dynamic_offset_count += binding->descriptorCount *
    658          set_layout->binding[binding_number].dynamic_offset_count;
    659 
    660       set_layout->shader_stages |= binding->stageFlags;
    661 
    662       set_layout->binding[binding_number].descriptor_offset = set_layout->bo_size;
    663       set_layout->bo_size +=
    664          v3dv_X(device, descriptor_bo_size)(set_layout->binding[binding_number].type) *
    665          binding->descriptorCount;
    666    }
    667 
    668    free(bindings);
    669 
    670    set_layout->descriptor_count = descriptor_count;
    671    set_layout->dynamic_offset_count = dynamic_offset_count;
    672 
    673    *pSetLayout = v3dv_descriptor_set_layout_to_handle(set_layout);
    674 
    675    return VK_SUCCESS;
    676 }
    677 
    678 VKAPI_ATTR void VKAPI_CALL
    679 v3dv_DestroyDescriptorSetLayout(VkDevice _device,
    680                                 VkDescriptorSetLayout _set_layout,
    681                                 const VkAllocationCallbacks *pAllocator)
    682 {
    683    V3DV_FROM_HANDLE(v3dv_device, device, _device);
    684    V3DV_FROM_HANDLE(v3dv_descriptor_set_layout, set_layout, _set_layout);
    685 
    686    if (!set_layout)
    687       return;
    688 
    689    vk_object_free(&device->vk, pAllocator, set_layout);
    690 }
    691 
    692 static inline VkResult
    693 out_of_pool_memory(const struct v3dv_device *device,
    694                    const struct v3dv_descriptor_pool *pool)
    695 {
    696    /* Don't log OOPM errors for internal driver pools, we handle these properly
    697     * by allocating a new pool, so they don't point to real issues.
    698     */
    699    if (!pool->is_driver_internal)
    700       return vk_error(device, VK_ERROR_OUT_OF_POOL_MEMORY);
    701    else
    702       return VK_ERROR_OUT_OF_POOL_MEMORY;
    703 }
    704 
    705 static VkResult
    706 descriptor_set_create(struct v3dv_device *device,
    707                       struct v3dv_descriptor_pool *pool,
    708                       const struct v3dv_descriptor_set_layout *layout,
    709                       struct v3dv_descriptor_set **out_set)
    710 {
    711    struct v3dv_descriptor_set *set;
    712    uint32_t descriptor_count = layout->descriptor_count;
    713    unsigned mem_size = sizeof(struct v3dv_descriptor_set) +
    714       sizeof(struct v3dv_descriptor) * descriptor_count;
    715 
    716    if (pool->host_memory_base) {
    717       if (pool->host_memory_end - pool->host_memory_ptr < mem_size)
    718          return out_of_pool_memory(device, pool);
    719 
    720       set = (struct v3dv_descriptor_set*)pool->host_memory_ptr;
    721       pool->host_memory_ptr += mem_size;
    722 
    723       vk_object_base_init(&device->vk, &set->base, VK_OBJECT_TYPE_DESCRIPTOR_SET);
    724    } else {
    725       set = vk_object_zalloc(&device->vk, NULL, mem_size,
    726                              VK_OBJECT_TYPE_DESCRIPTOR_SET);
    727 
    728       if (!set)
    729          return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
    730    }
    731 
    732    set->pool = pool;
    733 
    734    set->layout = layout;
    735 
    736    /* FIXME: VK_EXT_descriptor_indexing introduces
    737     * VARIABLE_DESCRIPTOR_LAYOUT_COUNT. That would affect the layout_size used
    738     * below for bo allocation
    739     */
    740 
    741    uint32_t offset = 0;
    742    uint32_t index = pool->entry_count;
    743 
    744    if (layout->bo_size) {
    745       if (!pool->host_memory_base && pool->entry_count == pool->max_entry_count) {
    746          vk_object_free(&device->vk, NULL, set);
    747          return out_of_pool_memory(device, pool);
    748       }
    749 
    750       /* We first try to allocate linearly fist, so that we don't spend time
    751        * looking for gaps if the app only allocates & resets via the pool.
    752        *
    753        * If that fails, we try to find a gap from previously freed subregions
    754        * iterating through the descriptor pool entries. Note that we are not
    755        * doing that if we have a pool->host_memory_base. We only have that if
    756        * VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT is not set, so in
    757        * that case the user can't free subregions, so it doesn't make sense to
    758        * even try (or track those subregions).
    759        */
    760       if (pool->current_offset + layout->bo_size <= pool->bo->size) {
    761          offset = pool->current_offset;
    762          pool->current_offset += layout->bo_size;
    763       } else if (!pool->host_memory_base) {
    764          for (index = 0; index < pool->entry_count; index++) {
    765             if (pool->entries[index].offset - offset >= layout->bo_size)
    766                break;
    767             offset = pool->entries[index].offset + pool->entries[index].size;
    768          }
    769          if (pool->bo->size - offset < layout->bo_size) {
    770             vk_object_free(&device->vk, NULL, set);
    771             return out_of_pool_memory(device, pool);
    772          }
    773          memmove(&pool->entries[index + 1], &pool->entries[index],
    774                  sizeof(pool->entries[0]) * (pool->entry_count - index));
    775       } else {
    776          assert(pool->host_memory_base);
    777          return out_of_pool_memory(device, pool);
    778       }
    779 
    780       set->base_offset = offset;
    781    }
    782 
    783    if (!pool->host_memory_base) {
    784       pool->entries[index].set = set;
    785       pool->entries[index].offset = offset;
    786       pool->entries[index].size = layout->bo_size;
    787       pool->entry_count++;
    788    }
    789 
    790    /* Go through and fill out immutable samplers if we have any */
    791    for (uint32_t b = 0; b < layout->binding_count; b++) {
    792       if (layout->binding[b].immutable_samplers_offset == 0)
    793          continue;
    794 
    795       const struct v3dv_sampler *samplers =
    796          (const struct v3dv_sampler *)((const char *)layout +
    797                                        layout->binding[b].immutable_samplers_offset);
    798 
    799       for (uint32_t i = 0; i < layout->binding[b].array_size; i++) {
    800          uint32_t combined_offset =
    801             layout->binding[b].type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ?
    802             v3dv_X(device, combined_image_sampler_sampler_state_offset)() : 0;
    803 
    804          void *desc_map = descriptor_bo_map(device, set, &layout->binding[b], i);
    805          desc_map += combined_offset;
    806 
    807          memcpy(desc_map,
    808                 samplers[i].sampler_state,
    809                 sizeof(samplers[i].sampler_state));
    810       }
    811    }
    812 
    813    *out_set = set;
    814 
    815    return VK_SUCCESS;
    816 }
    817 
    818 VKAPI_ATTR VkResult VKAPI_CALL
    819 v3dv_AllocateDescriptorSets(VkDevice _device,
    820                             const VkDescriptorSetAllocateInfo *pAllocateInfo,
    821                             VkDescriptorSet *pDescriptorSets)
    822 {
    823    V3DV_FROM_HANDLE(v3dv_device, device, _device);
    824    V3DV_FROM_HANDLE(v3dv_descriptor_pool, pool, pAllocateInfo->descriptorPool);
    825 
    826    VkResult result = VK_SUCCESS;
    827    struct v3dv_descriptor_set *set = NULL;
    828    uint32_t i = 0;
    829 
    830    for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
    831       V3DV_FROM_HANDLE(v3dv_descriptor_set_layout, layout,
    832                        pAllocateInfo->pSetLayouts[i]);
    833 
    834       result = descriptor_set_create(device, pool, layout, &set);
    835       if (result != VK_SUCCESS)
    836          break;
    837 
    838       pDescriptorSets[i] = v3dv_descriptor_set_to_handle(set);
    839    }
    840 
    841    if (result != VK_SUCCESS) {
    842       v3dv_FreeDescriptorSets(_device, pAllocateInfo->descriptorPool,
    843                               i, pDescriptorSets);
    844       for (i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
    845          pDescriptorSets[i] = VK_NULL_HANDLE;
    846       }
    847    }
    848 
    849    return result;
    850 }
    851 
    852 VKAPI_ATTR VkResult VKAPI_CALL
    853 v3dv_FreeDescriptorSets(VkDevice _device,
    854                         VkDescriptorPool descriptorPool,
    855                         uint32_t count,
    856                         const VkDescriptorSet *pDescriptorSets)
    857 {
    858    V3DV_FROM_HANDLE(v3dv_device, device, _device);
    859    V3DV_FROM_HANDLE(v3dv_descriptor_pool, pool, descriptorPool);
    860 
    861    for (uint32_t i = 0; i < count; i++) {
    862       V3DV_FROM_HANDLE(v3dv_descriptor_set, set, pDescriptorSets[i]);
    863       if (set && !pool->host_memory_base)
    864          descriptor_set_destroy(device, pool, set, true);
    865    }
    866 
    867    return VK_SUCCESS;
    868 }
    869 
    870 static void
    871 descriptor_bo_copy(struct v3dv_device *device,
    872                    struct v3dv_descriptor_set *dst_set,
    873                    const struct v3dv_descriptor_set_binding_layout *dst_binding_layout,
    874                    uint32_t dst_array_index,
    875                    struct v3dv_descriptor_set *src_set,
    876                    const struct v3dv_descriptor_set_binding_layout *src_binding_layout,
    877                    uint32_t src_array_index)
    878 {
    879    assert(dst_binding_layout->type == src_binding_layout->type);
    880 
    881    void *dst_map = descriptor_bo_map(device, dst_set, dst_binding_layout, dst_array_index);
    882    void *src_map = descriptor_bo_map(device, src_set, src_binding_layout, src_array_index);
    883 
    884    memcpy(dst_map, src_map, v3dv_X(device, descriptor_bo_size)(src_binding_layout->type));
    885 }
    886 
    887 static void
    888 write_buffer_descriptor(struct v3dv_descriptor *descriptor,
    889                         VkDescriptorType desc_type,
    890                         const VkDescriptorBufferInfo *buffer_info)
    891 {
    892    V3DV_FROM_HANDLE(v3dv_buffer, buffer, buffer_info->buffer);
    893 
    894    descriptor->type = desc_type;
    895    descriptor->buffer = buffer;
    896    descriptor->offset = buffer_info->offset;
    897    if (buffer_info->range == VK_WHOLE_SIZE) {
    898       descriptor->range = buffer->size - buffer_info->offset;
    899    } else {
    900       assert(descriptor->range <= UINT32_MAX);
    901       descriptor->range = buffer_info->range;
    902    }
    903 }
    904 
    905 static void
    906 write_image_descriptor(struct v3dv_device *device,
    907                        struct v3dv_descriptor *descriptor,
    908                        VkDescriptorType desc_type,
    909                        struct v3dv_descriptor_set *set,
    910                        const struct v3dv_descriptor_set_binding_layout *binding_layout,
    911                        struct v3dv_image_view *iview,
    912                        struct v3dv_sampler *sampler,
    913                        uint32_t array_index)
    914 {
    915    descriptor->type = desc_type;
    916    descriptor->sampler = sampler;
    917    descriptor->image_view = iview;
    918 
    919    void *desc_map = descriptor_bo_map(device, set,
    920                                       binding_layout, array_index);
    921 
    922    if (iview) {
    923       const uint32_t tex_state_index =
    924          iview->vk.view_type != VK_IMAGE_VIEW_TYPE_CUBE_ARRAY ||
    925          desc_type != VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? 0 : 1;
    926       memcpy(desc_map,
    927              iview->texture_shader_state[tex_state_index],
    928              sizeof(iview->texture_shader_state[0]));
    929       desc_map += v3dv_X(device, combined_image_sampler_sampler_state_offset)();
    930    }
    931 
    932    if (sampler && !binding_layout->immutable_samplers_offset) {
    933       /* For immutable samplers this was already done as part of the
    934        * descriptor set create, as that info can't change later
    935        */
    936       memcpy(desc_map,
    937              sampler->sampler_state,
    938              sizeof(sampler->sampler_state));
    939    }
    940 }
    941 
    942 
    943 static void
    944 write_buffer_view_descriptor(struct v3dv_device *device,
    945                              struct v3dv_descriptor *descriptor,
    946                              VkDescriptorType desc_type,
    947                              struct v3dv_descriptor_set *set,
    948                              const struct v3dv_descriptor_set_binding_layout *binding_layout,
    949                              struct v3dv_buffer_view *bview,
    950                              uint32_t array_index)
    951 {
    952    assert(bview);
    953    descriptor->type = desc_type;
    954    descriptor->buffer_view = bview;
    955 
    956    void *desc_map = descriptor_bo_map(device, set, binding_layout, array_index);
    957 
    958    memcpy(desc_map,
    959           bview->texture_shader_state,
    960           sizeof(bview->texture_shader_state));
    961 }
    962 
    963 VKAPI_ATTR void VKAPI_CALL
    964 v3dv_UpdateDescriptorSets(VkDevice  _device,
    965                           uint32_t descriptorWriteCount,
    966                           const VkWriteDescriptorSet *pDescriptorWrites,
    967                           uint32_t descriptorCopyCount,
    968                           const VkCopyDescriptorSet *pDescriptorCopies)
    969 {
    970    V3DV_FROM_HANDLE(v3dv_device, device, _device);
    971    for (uint32_t i = 0; i < descriptorWriteCount; i++) {
    972       const VkWriteDescriptorSet *writeset = &pDescriptorWrites[i];
    973       V3DV_FROM_HANDLE(v3dv_descriptor_set, set, writeset->dstSet);
    974 
    975       const struct v3dv_descriptor_set_binding_layout *binding_layout =
    976          set->layout->binding + writeset->dstBinding;
    977 
    978       struct v3dv_descriptor *descriptor = set->descriptors;
    979 
    980       descriptor += binding_layout->descriptor_index;
    981       descriptor += writeset->dstArrayElement;
    982 
    983       for (uint32_t j = 0; j < writeset->descriptorCount; ++j) {
    984          switch(writeset->descriptorType) {
    985 
    986          case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
    987          case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
    988          case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
    989          case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: {
    990             const VkDescriptorBufferInfo *buffer_info = writeset->pBufferInfo + j;
    991             write_buffer_descriptor(descriptor, writeset->descriptorType,
    992                                     buffer_info);
    993             break;
    994          }
    995          case VK_DESCRIPTOR_TYPE_SAMPLER: {
    996             /* If we are here we shouldn't be modifying a immutable sampler,
    997              * so we don't ensure that would work or not crash. But let the
    998              * validation layers check that
    999              */
   1000             const VkDescriptorImageInfo *image_info = writeset->pImageInfo + j;
   1001             V3DV_FROM_HANDLE(v3dv_sampler, sampler, image_info->sampler);
   1002             write_image_descriptor(device, descriptor, writeset->descriptorType,
   1003                                    set, binding_layout, NULL, sampler,
   1004                                    writeset->dstArrayElement + j);
   1005 
   1006             break;
   1007          }
   1008          case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
   1009          case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
   1010          case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: {
   1011             const VkDescriptorImageInfo *image_info = writeset->pImageInfo + j;
   1012             V3DV_FROM_HANDLE(v3dv_image_view, iview, image_info->imageView);
   1013             write_image_descriptor(device, descriptor, writeset->descriptorType,
   1014                                    set, binding_layout, iview, NULL,
   1015                                    writeset->dstArrayElement + j);
   1016 
   1017             break;
   1018          }
   1019          case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
   1020             const VkDescriptorImageInfo *image_info = writeset->pImageInfo + j;
   1021             V3DV_FROM_HANDLE(v3dv_image_view, iview, image_info->imageView);
   1022             V3DV_FROM_HANDLE(v3dv_sampler, sampler, image_info->sampler);
   1023             write_image_descriptor(device, descriptor, writeset->descriptorType,
   1024                                    set, binding_layout, iview, sampler,
   1025                                    writeset->dstArrayElement + j);
   1026 
   1027             break;
   1028          }
   1029          case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
   1030          case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: {
   1031             V3DV_FROM_HANDLE(v3dv_buffer_view, buffer_view,
   1032                              writeset->pTexelBufferView[j]);
   1033             write_buffer_view_descriptor(device, descriptor, writeset->descriptorType,
   1034                                          set, binding_layout, buffer_view,
   1035                                          writeset->dstArrayElement + j);
   1036             break;
   1037          }
   1038          default:
   1039             unreachable("unimplemented descriptor type");
   1040             break;
   1041          }
   1042          descriptor++;
   1043       }
   1044    }
   1045 
   1046    for (uint32_t i = 0; i < descriptorCopyCount; i++) {
   1047       const VkCopyDescriptorSet *copyset = &pDescriptorCopies[i];
   1048       V3DV_FROM_HANDLE(v3dv_descriptor_set, src_set,
   1049                        copyset->srcSet);
   1050       V3DV_FROM_HANDLE(v3dv_descriptor_set, dst_set,
   1051                        copyset->dstSet);
   1052 
   1053       const struct v3dv_descriptor_set_binding_layout *src_binding_layout =
   1054          src_set->layout->binding + copyset->srcBinding;
   1055       const struct v3dv_descriptor_set_binding_layout *dst_binding_layout =
   1056          dst_set->layout->binding + copyset->dstBinding;
   1057 
   1058       assert(src_binding_layout->type == dst_binding_layout->type);
   1059 
   1060       struct v3dv_descriptor *src_descriptor = src_set->descriptors;
   1061       struct v3dv_descriptor *dst_descriptor = dst_set->descriptors;
   1062 
   1063       src_descriptor += src_binding_layout->descriptor_index;
   1064       src_descriptor += copyset->srcArrayElement;
   1065 
   1066       dst_descriptor += dst_binding_layout->descriptor_index;
   1067       dst_descriptor += copyset->dstArrayElement;
   1068 
   1069       for (uint32_t j = 0; j < copyset->descriptorCount; j++) {
   1070          *dst_descriptor = *src_descriptor;
   1071          dst_descriptor++;
   1072          src_descriptor++;
   1073 
   1074          if (v3dv_X(device, descriptor_bo_size)(src_binding_layout->type) > 0) {
   1075             descriptor_bo_copy(device,
   1076                                dst_set, dst_binding_layout,
   1077                                j + copyset->dstArrayElement,
   1078                                src_set, src_binding_layout,
   1079                                j + copyset->srcArrayElement);
   1080          }
   1081 
   1082       }
   1083    }
   1084 }
   1085 
   1086 VKAPI_ATTR void VKAPI_CALL
   1087 v3dv_GetDescriptorSetLayoutSupport(
   1088    VkDevice _device,
   1089    const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
   1090    VkDescriptorSetLayoutSupport *pSupport)
   1091 {
   1092    V3DV_FROM_HANDLE(v3dv_device, device, _device);
   1093    VkDescriptorSetLayoutBinding *bindings = NULL;
   1094    VkResult result = vk_create_sorted_bindings(
   1095       pCreateInfo->pBindings, pCreateInfo->bindingCount, &bindings);
   1096    if (result != VK_SUCCESS) {
   1097       pSupport->supported = false;
   1098       return;
   1099    }
   1100 
   1101    bool supported = true;
   1102 
   1103    uint32_t desc_host_size = sizeof(struct v3dv_descriptor);
   1104    uint32_t host_size = sizeof(struct v3dv_descriptor_set);
   1105    uint32_t bo_size = 0;
   1106    for (uint32_t i = 0; i < pCreateInfo->bindingCount; i++) {
   1107       const VkDescriptorSetLayoutBinding *binding = bindings + i;
   1108 
   1109       if ((UINT32_MAX - host_size) / desc_host_size < binding->descriptorCount) {
   1110          supported = false;
   1111          break;
   1112       }
   1113 
   1114       uint32_t desc_bo_size = v3dv_X(device, descriptor_bo_size)(binding->descriptorType);
   1115       if (desc_bo_size > 0 &&
   1116           (UINT32_MAX - bo_size) / desc_bo_size < binding->descriptorCount) {
   1117          supported = false;
   1118          break;
   1119       }
   1120 
   1121       host_size += binding->descriptorCount * desc_host_size;
   1122       bo_size += binding->descriptorCount * desc_bo_size;
   1123    }
   1124 
   1125    free(bindings);
   1126 
   1127    pSupport->supported = supported;
   1128 }
   1129 
   1130 VkResult
   1131 v3dv_CreateDescriptorUpdateTemplate(
   1132    VkDevice _device,
   1133    const VkDescriptorUpdateTemplateCreateInfo *pCreateInfo,
   1134    const VkAllocationCallbacks *pAllocator,
   1135    VkDescriptorUpdateTemplate *pDescriptorUpdateTemplate)
   1136 {
   1137    V3DV_FROM_HANDLE(v3dv_device, device, _device);
   1138    struct v3dv_descriptor_update_template *template;
   1139 
   1140    size_t size = sizeof(*template) +
   1141       pCreateInfo->descriptorUpdateEntryCount * sizeof(template->entries[0]);
   1142    template = vk_object_alloc(&device->vk, pAllocator, size,
   1143                               VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE);
   1144    if (template == NULL)
   1145       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
   1146 
   1147    template->bind_point = pCreateInfo->pipelineBindPoint;
   1148 
   1149    assert(pCreateInfo->templateType ==
   1150           VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET);
   1151    template->set = pCreateInfo->set;
   1152 
   1153    template->entry_count = pCreateInfo->descriptorUpdateEntryCount;
   1154    for (uint32_t i = 0; i < template->entry_count; i++) {
   1155       const VkDescriptorUpdateTemplateEntry *pEntry =
   1156          &pCreateInfo->pDescriptorUpdateEntries[i];
   1157 
   1158       template->entries[i] = (struct v3dv_descriptor_template_entry) {
   1159          .type = pEntry->descriptorType,
   1160          .binding = pEntry->dstBinding,
   1161          .array_element = pEntry->dstArrayElement,
   1162          .array_count = pEntry->descriptorCount,
   1163          .offset = pEntry->offset,
   1164          .stride = pEntry->stride,
   1165       };
   1166    }
   1167 
   1168    *pDescriptorUpdateTemplate =
   1169       v3dv_descriptor_update_template_to_handle(template);
   1170 
   1171    return VK_SUCCESS;
   1172 }
   1173 
   1174 void
   1175 v3dv_DestroyDescriptorUpdateTemplate(
   1176    VkDevice _device,
   1177    VkDescriptorUpdateTemplate descriptorUpdateTemplate,
   1178    const VkAllocationCallbacks *pAllocator)
   1179 {
   1180    V3DV_FROM_HANDLE(v3dv_device, device, _device);
   1181    V3DV_FROM_HANDLE(v3dv_descriptor_update_template, template,
   1182                     descriptorUpdateTemplate);
   1183 
   1184    if (!template)
   1185       return;
   1186 
   1187    vk_object_free(&device->vk, pAllocator, template);
   1188 }
   1189 
   1190 void
   1191 v3dv_UpdateDescriptorSetWithTemplate(
   1192    VkDevice _device,
   1193    VkDescriptorSet descriptorSet,
   1194    VkDescriptorUpdateTemplate descriptorUpdateTemplate,
   1195    const void *pData)
   1196 {
   1197    V3DV_FROM_HANDLE(v3dv_device, device, _device);
   1198    V3DV_FROM_HANDLE(v3dv_descriptor_set, set, descriptorSet);
   1199    V3DV_FROM_HANDLE(v3dv_descriptor_update_template, template,
   1200                     descriptorUpdateTemplate);
   1201 
   1202    for (int i = 0; i < template->entry_count; i++) {
   1203       const struct v3dv_descriptor_template_entry *entry =
   1204          &template->entries[i];
   1205 
   1206       const struct v3dv_descriptor_set_binding_layout *binding_layout =
   1207          set->layout->binding + entry->binding;
   1208 
   1209       struct v3dv_descriptor *descriptor =
   1210          set->descriptors +
   1211          binding_layout->descriptor_index +
   1212          entry->array_element;
   1213 
   1214       switch (entry->type) {
   1215       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
   1216       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
   1217       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
   1218       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
   1219          for (uint32_t j = 0; j < entry->array_count; j++) {
   1220             const VkDescriptorBufferInfo *info =
   1221                pData + entry->offset + j * entry->stride;
   1222             write_buffer_descriptor(descriptor + j, entry->type, info);
   1223          }
   1224          break;
   1225 
   1226       case VK_DESCRIPTOR_TYPE_SAMPLER:
   1227       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
   1228       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
   1229       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
   1230       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
   1231          for (uint32_t j = 0; j < entry->array_count; j++) {
   1232             const VkDescriptorImageInfo *info =
   1233                pData + entry->offset + j * entry->stride;
   1234             V3DV_FROM_HANDLE(v3dv_image_view, iview, info->imageView);
   1235             V3DV_FROM_HANDLE(v3dv_sampler, sampler, info->sampler);
   1236             write_image_descriptor(device, descriptor + j, entry->type,
   1237                                    set, binding_layout, iview, sampler,
   1238                                    entry->array_element + j);
   1239          }
   1240          break;
   1241 
   1242       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
   1243       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
   1244          for (uint32_t j = 0; j < entry->array_count; j++) {
   1245             const VkBufferView *_bview =
   1246                pData + entry->offset + j * entry->stride;
   1247             V3DV_FROM_HANDLE(v3dv_buffer_view, bview, *_bview);
   1248             write_buffer_view_descriptor(device, descriptor + j, entry->type,
   1249                                          set, binding_layout, bview,
   1250                                          entry->array_element + j);
   1251          }
   1252          break;
   1253 
   1254       default:
   1255          unreachable("Unsupported descriptor type");
   1256       }
   1257    }
   1258 }
   1259 
   1260 VKAPI_ATTR VkResult VKAPI_CALL
   1261 v3dv_CreateSamplerYcbcrConversion(
   1262     VkDevice _device,
   1263     const VkSamplerYcbcrConversionCreateInfo *pCreateInfo,
   1264     const VkAllocationCallbacks *pAllocator,
   1265     VkSamplerYcbcrConversion *pYcbcrConversion)
   1266 {
   1267    unreachable("Ycbcr sampler conversion is not supported");
   1268    return VK_SUCCESS;
   1269 }
   1270 
   1271 VKAPI_ATTR void VKAPI_CALL
   1272 v3dv_DestroySamplerYcbcrConversion(
   1273     VkDevice _device,
   1274     VkSamplerYcbcrConversion YcbcrConversion,
   1275     const VkAllocationCallbacks *pAllocator)
   1276 {
   1277    unreachable("Ycbcr sampler conversion is not supported");
   1278 }
   1279