vulkan: separate out descriptor layouts from sets

Just avoids a single temporary allocation.
This commit is contained in:
Lynne 2024-09-22 06:02:24 +02:00
parent 2942ca802a
commit 3d75ba7495
No known key found for this signature in database
GPG Key ID: A2FEA5F03F034464
2 changed files with 21 additions and 18 deletions

View File

@ -1524,6 +1524,7 @@ int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
int has_sampler = 0; int has_sampler = 0;
FFVulkanFunctions *vk = &s->vkfn; FFVulkanFunctions *vk = &s->vkfn;
FFVulkanDescriptorSet *set; FFVulkanDescriptorSet *set;
VkDescriptorSetLayout *layout;
VkDescriptorSetLayoutCreateInfo desc_create_layout; VkDescriptorSetLayoutCreateInfo desc_create_layout;
if (print_to_shader_only) if (print_to_shader_only)
@ -1535,7 +1536,15 @@ int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
if (!set) if (!set)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
pl->desc_set = set; pl->desc_set = set;
layout = av_realloc_array(pl->desc_layout, sizeof(*pl->desc_layout),
pl->nb_descriptor_sets + 1);
if (!layout)
return AVERROR(ENOMEM);
pl->desc_layout = layout;
set = &set[pl->nb_descriptor_sets]; set = &set[pl->nb_descriptor_sets];
layout = &layout[pl->nb_descriptor_sets];
memset(set, 0, sizeof(*set)); memset(set, 0, sizeof(*set));
set->binding = av_calloc(nb, sizeof(*set->binding)); set->binding = av_calloc(nb, sizeof(*set->binding));
@ -1573,19 +1582,19 @@ int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
set->usage |= VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT; set->usage |= VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT;
ret = vk->CreateDescriptorSetLayout(s->hwctx->act_dev, &desc_create_layout, ret = vk->CreateDescriptorSetLayout(s->hwctx->act_dev, &desc_create_layout,
s->hwctx->alloc, &set->layout); s->hwctx->alloc, layout);
if (ret != VK_SUCCESS) { if (ret != VK_SUCCESS) {
av_log(s, AV_LOG_ERROR, "Unable to init descriptor set layout: %s", av_log(s, AV_LOG_ERROR, "Unable to init descriptor set layout: %s",
ff_vk_ret2str(ret)); ff_vk_ret2str(ret));
return AVERROR_EXTERNAL; return AVERROR_EXTERNAL;
} }
vk->GetDescriptorSetLayoutSizeEXT(s->hwctx->act_dev, set->layout, &set->layout_size); vk->GetDescriptorSetLayoutSizeEXT(s->hwctx->act_dev, *layout, &set->layout_size);
set->aligned_size = FFALIGN(set->layout_size, s->desc_buf_props.descriptorBufferOffsetAlignment); set->aligned_size = FFALIGN(set->layout_size, s->desc_buf_props.descriptorBufferOffsetAlignment);
for (int i = 0; i < nb; i++) for (int i = 0; i < nb; i++)
vk->GetDescriptorSetLayoutBindingOffsetEXT(s->hwctx->act_dev, set->layout, vk->GetDescriptorSetLayoutBindingOffsetEXT(s->hwctx->act_dev, *layout,
i, &set->binding_offset[i]); i, &set->binding_offset[i]);
set->singular = singular; set->singular = singular;
@ -1808,18 +1817,10 @@ static int init_pipeline_layout(FFVulkanContext *s, FFVulkanPipeline *pl)
FFVulkanFunctions *vk = &s->vkfn; FFVulkanFunctions *vk = &s->vkfn;
VkPipelineLayoutCreateInfo pipeline_layout_info; VkPipelineLayoutCreateInfo pipeline_layout_info;
VkDescriptorSetLayout *desc_layouts = av_malloc(pl->nb_descriptor_sets*
sizeof(desc_layouts));
if (!desc_layouts)
return AVERROR(ENOMEM);
for (int i = 0; i < pl->nb_descriptor_sets; i++)
desc_layouts[i] = pl->desc_set[i].layout;
/* Finally create the pipeline layout */ /* Finally create the pipeline layout */
pipeline_layout_info = (VkPipelineLayoutCreateInfo) { pipeline_layout_info = (VkPipelineLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pSetLayouts = desc_layouts, .pSetLayouts = pl->desc_layout,
.setLayoutCount = pl->nb_descriptor_sets, .setLayoutCount = pl->nb_descriptor_sets,
.pushConstantRangeCount = pl->push_consts_num, .pushConstantRangeCount = pl->push_consts_num,
.pPushConstantRanges = pl->push_consts, .pPushConstantRanges = pl->push_consts,
@ -1827,7 +1828,6 @@ static int init_pipeline_layout(FFVulkanContext *s, FFVulkanPipeline *pl)
ret = vk->CreatePipelineLayout(s->hwctx->act_dev, &pipeline_layout_info, ret = vk->CreatePipelineLayout(s->hwctx->act_dev, &pipeline_layout_info,
s->hwctx->alloc, &pl->pipeline_layout); s->hwctx->alloc, &pl->pipeline_layout);
av_free(desc_layouts);
if (ret != VK_SUCCESS) { if (ret != VK_SUCCESS) {
av_log(s, AV_LOG_ERROR, "Unable to init pipeline layout: %s\n", av_log(s, AV_LOG_ERROR, "Unable to init pipeline layout: %s\n",
ff_vk_ret2str(ret)); ff_vk_ret2str(ret));
@ -1911,13 +1911,16 @@ void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl)
if (set->buf.mem) if (set->buf.mem)
ff_vk_unmap_buffer(s, &set->buf, 0); ff_vk_unmap_buffer(s, &set->buf, 0);
ff_vk_free_buf(s, &set->buf); ff_vk_free_buf(s, &set->buf);
if (set->layout)
vk->DestroyDescriptorSetLayout(s->hwctx->act_dev, set->layout,
s->hwctx->alloc);
av_free(set->binding); av_free(set->binding);
av_free(set->binding_offset); av_free(set->binding_offset);
} }
for (int i = 0; i < pl->nb_descriptor_sets; i++)
if (pl->desc_layout[i])
vk->DestroyDescriptorSetLayout(s->hwctx->act_dev, pl->desc_layout[i],
s->hwctx->alloc);
av_freep(&pl->desc_layout);
av_freep(&pl->desc_set); av_freep(&pl->desc_set);
av_freep(&pl->desc_bind); av_freep(&pl->desc_bind);
av_freep(&pl->bound_buffer_indices); av_freep(&pl->bound_buffer_indices);

View File

@ -113,7 +113,6 @@ typedef struct FFVkQueueFamilyCtx {
} FFVkQueueFamilyCtx; } FFVkQueueFamilyCtx;
typedef struct FFVulkanDescriptorSet { typedef struct FFVulkanDescriptorSet {
VkDescriptorSetLayout layout;
FFVkBuffer buf; FFVkBuffer buf;
uint8_t *desc_mem; uint8_t *desc_mem;
VkDeviceSize layout_size; VkDeviceSize layout_size;
@ -143,7 +142,8 @@ typedef struct FFVulkanPipeline {
/* Workgroup */ /* Workgroup */
int wg_size[3]; int wg_size[3];
/* Descriptors */ /* Descriptor buffer */
VkDescriptorSetLayout *desc_layout;
FFVulkanDescriptorSet *desc_set; FFVulkanDescriptorSet *desc_set;
VkDescriptorBufferBindingInfoEXT *desc_bind; VkDescriptorBufferBindingInfoEXT *desc_bind;
uint32_t *bound_buffer_indices; uint32_t *bound_buffer_indices;