@@ -189,7 +189,7 @@ static int init_gblur_pipeline(GBlurVulkanContext *s, FFVulkanPipeline *pl,
RET(ff_vk_unmap_buffer(&s->vkctx, params_buf, 1));
RET(ff_vk_set_descriptor_buffer(&s->vkctx, pl, NULL, 1, 0, 0,
- params_buf->address, params_buf->size,
+ params_buf, 0, params_buf->size,
VK_FORMAT_UNDEFINED));
fail:
@@ -657,7 +657,7 @@ static av_cold int init_filter(AVFilterContext *ctx)
spv, desc, planes));
RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_weights, NULL, 1, 0, 0,
- s->xyoffsets_buf.address, s->xyoffsets_buf.size,
+ &s->xyoffsets_buf, 0, s->xyoffsets_buf.size,
VK_FORMAT_UNDEFINED));
do {
@@ -751,8 +751,8 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
/* Weights/sums */
AVBufferRef *ws_buf = NULL;
FFVkBuffer *ws_vk;
- VkDeviceAddress weights_addr[4];
- VkDeviceAddress sums_addr[4];
+ VkDeviceSize weights_addr[4];
+ VkDeviceSize sums_addr[4];
uint32_t ws_stride[4];
size_t ws_size[4];
size_t ws_total_size = 0;
@@ -810,8 +810,8 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
return err;
ws_vk = (FFVkBuffer *)ws_buf->data;
- weights_addr[0] = ws_vk->address;
- sums_addr[0] = ws_vk->address + ws_total_size;
+ weights_addr[0] = 0;
+ sums_addr[0] = ws_total_size;
for (int i = 1; i < desc->nb_components; i++) {
weights_addr[i] = weights_addr[i - 1] + ws_size[i - 1];
sums_addr[i] = sums_addr[i - 1] + ws_size[i - 1];
@@ -844,9 +844,6 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
/* Input frame prep */
RET(ff_vk_create_imageviews(vkctx, exec, in_views, in));
- ff_vk_update_descriptor_img_array(vkctx, &s->pl_weights, exec, in, in_views, 0, 0,
- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
- s->sampler);
ff_vk_frame_barrier(vkctx, exec, in, img_bar, &nb_img_bar,
VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
@@ -934,10 +931,10 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
s->sampler);
for (int i = 0; i < desc->nb_components; i++) {
RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_weights, exec, 0, 1 + i*2 + 0, 0,
- weights_addr[i], ws_size[i],
+ ws_vk, weights_addr[i], ws_size[i],
VK_FORMAT_UNDEFINED));
RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_weights, exec, 0, 1 + i*2 + 1, 0,
- sums_addr[i], ws_size[i],
+ ws_vk, sums_addr[i], ws_size[i],
VK_FORMAT_UNDEFINED));
}
@@ -949,10 +946,10 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
VK_IMAGE_LAYOUT_GENERAL, s->sampler);
for (int i = 0; i < desc->nb_components; i++) {
RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_denoise, exec, 0, 2 + i*2 + 0, 0,
- weights_addr[i], ws_size[i],
+ ws_vk, weights_addr[i], ws_size[i],
VK_FORMAT_UNDEFINED));
RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_denoise, exec, 0, 2 + i*2 + 1, 0,
- sums_addr[i], ws_size[i],
+ ws_vk, sums_addr[i], ws_size[i],
VK_FORMAT_UNDEFINED));
}
@@ -152,18 +152,6 @@ skip:
s->extensions = ff_vk_extensions_to_mask(vk_dev->enabled_dev_extensions,
vk_dev->nb_enabled_dev_extensions);
- /**
- * libplacebo does not use descriptor buffers.
- */
- if (!(s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) &&
- strcmp(avctx->filter->name, "libplacebo")) {
- av_log(avctx, AV_LOG_ERROR, "Vulkan filtering requires that "
- "the %s extension is supported!\n",
- VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME);
- av_buffer_unref(&frames_ref);
- return AVERROR(EINVAL);
- }
-
err = ff_vk_load_functions(device_ctx, &s->vkfn, s->extensions, 1, 1);
if (err < 0) {
av_buffer_unref(&frames_ref);
@@ -264,12 +252,13 @@ int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e,
FFVkExecContext *exec = ff_vk_exec_get(e);
ff_vk_exec_start(vkctx, exec);
- ff_vk_exec_bind_pipeline(vkctx, exec, pl);
-
- if (push_src)
- ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT,
- 0, push_size, push_src);
-
+ RET(ff_vk_exec_add_dep_frame(vkctx, exec, out_f,
+ VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
+ VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
+ RET(ff_vk_create_imageviews(vkctx, exec, out_views, out_f));
+ ff_vk_update_descriptor_img_array(vkctx, pl, exec, out_f, out_views, 0, !!in_f,
+ VK_IMAGE_LAYOUT_GENERAL,
+ VK_NULL_HANDLE);
if (in_f) {
RET(ff_vk_exec_add_dep_frame(vkctx, exec, in_f,
VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
@@ -278,27 +267,28 @@ int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e,
ff_vk_update_descriptor_img_array(vkctx, pl, exec, in_f, in_views, 0, 0,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
sampler);
- ff_vk_frame_barrier(vkctx, exec, in_f, img_bar, &nb_img_bar,
- VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
- VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
- VK_ACCESS_SHADER_READ_BIT,
- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
- VK_QUEUE_FAMILY_IGNORED);
}
- RET(ff_vk_exec_add_dep_frame(vkctx, exec, out_f,
- VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
- VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
- RET(ff_vk_create_imageviews(vkctx, exec, out_views, out_f));
- ff_vk_update_descriptor_img_array(vkctx, pl, exec, out_f, out_views, 0, !!in_f,
- VK_IMAGE_LAYOUT_GENERAL,
- VK_NULL_HANDLE);
+ /* Bind pipeline, update push data */
+ ff_vk_exec_bind_pipeline(vkctx, exec, pl);
+ if (push_src)
+ ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT,
+ 0, push_size, push_src);
+
+ /* Add data sync barriers */
ff_vk_frame_barrier(vkctx, exec, out_f, img_bar, &nb_img_bar,
VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_ACCESS_SHADER_WRITE_BIT,
VK_IMAGE_LAYOUT_GENERAL,
VK_QUEUE_FAMILY_IGNORED);
+ if (in_f)
+ ff_vk_frame_barrier(vkctx, exec, in_f, img_bar, &nb_img_bar,
+ VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
+ VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
+ VK_ACCESS_SHADER_READ_BIT,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ VK_QUEUE_FAMILY_IGNORED);
vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
@@ -380,12 +370,6 @@ int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e,
VkImageView *src_views = !i ? in_views : tmp_views;
VkImageView *dst_views = !i ? tmp_views : out_views;
- ff_vk_exec_bind_pipeline(vkctx, exec, pl);
-
- if (push_src)
- ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT,
- 0, push_size, push_src);
-
ff_vk_update_descriptor_img_array(vkctx, pl, exec, src_f, src_views, 0, 0,
!i ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL :
VK_IMAGE_LAYOUT_GENERAL,
@@ -394,6 +378,12 @@ int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e,
VK_IMAGE_LAYOUT_GENERAL,
VK_NULL_HANDLE);
+ /* Bind pipeline, update push data */
+ ff_vk_exec_bind_pipeline(vkctx, exec, pl);
+ if (push_src)
+ ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT,
+ 0, push_size, push_src);
+
vk->CmdDispatch(exec->buf,
FFALIGN(vkctx->output_width, pl->wg_size[0])/pl->wg_size[0],
FFALIGN(vkctx->output_height, pl->wg_size[1])/pl->wg_size[1],
@@ -422,32 +412,47 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e,
FFVkExecContext *exec = ff_vk_exec_get(e);
ff_vk_exec_start(vkctx, exec);
- /* Inputs */
+ /* Add deps and create temporary imageviews */
+ RET(ff_vk_exec_add_dep_frame(vkctx, exec, out,
+ VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
+ VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
+ RET(ff_vk_create_imageviews(vkctx, exec, out_views, out));
for (int i = 0; i < nb_in; i++) {
RET(ff_vk_exec_add_dep_frame(vkctx, exec, in[i],
VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
RET(ff_vk_create_imageviews(vkctx, exec, in_views[i], in[i]));
-
- ff_vk_frame_barrier(vkctx, exec, in[i], img_bar, &nb_img_bar,
- VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
- VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
- VK_ACCESS_SHADER_READ_BIT,
- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
- VK_QUEUE_FAMILY_IGNORED);
}
- /* Output */
- RET(ff_vk_exec_add_dep_frame(vkctx, exec, out,
- VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
- VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
- RET(ff_vk_create_imageviews(vkctx, exec, out_views, out));
+ /* Update descriptor sets */
+ ff_vk_update_descriptor_img_array(vkctx, pl, exec, out, out_views, 0, nb_in,
+ VK_IMAGE_LAYOUT_GENERAL,
+ VK_NULL_HANDLE);
+ for (int i = 0; i < nb_in; i++)
+ ff_vk_update_descriptor_img_array(vkctx, pl, exec, in[i], in_views[i], 0, i,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ sampler);
+
+ /* Bind pipeline, update push data */
+ ff_vk_exec_bind_pipeline(vkctx, exec, pl);
+ if (push_src)
+ ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT,
+ 0, push_size, push_src);
+
+ /* Add data sync barriers */
ff_vk_frame_barrier(vkctx, exec, out, img_bar, &nb_img_bar,
VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
VK_ACCESS_SHADER_WRITE_BIT,
VK_IMAGE_LAYOUT_GENERAL,
VK_QUEUE_FAMILY_IGNORED);
+ for (int i = 0; i < nb_in; i++)
+ ff_vk_frame_barrier(vkctx, exec, in[i], img_bar, &nb_img_bar,
+ VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
+ VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
+ VK_ACCESS_SHADER_READ_BIT,
+ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
+ VK_QUEUE_FAMILY_IGNORED);
vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
@@ -455,21 +460,6 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e,
.imageMemoryBarrierCount = nb_img_bar,
});
- ff_vk_exec_bind_pipeline(vkctx, exec, pl);
-
- if (push_src)
- ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT,
- 0, push_size, push_src);
-
- for (int i = 0; i < nb_in; i++)
- ff_vk_update_descriptor_img_array(vkctx, pl, exec, in[i], in_views[i], 0, i,
- VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
- sampler);
-
- ff_vk_update_descriptor_img_array(vkctx, pl, exec, out, out_views, 0, nb_in,
- VK_IMAGE_LAYOUT_GENERAL,
- VK_NULL_HANDLE);
-
vk->CmdDispatch(exec->buf,
FFALIGN(vkctx->output_width, pl->wg_size[0])/pl->wg_size[0],
FFALIGN(vkctx->output_height, pl->wg_size[1])/pl->wg_size[1],
@@ -578,6 +578,12 @@ static int check_extensions(AVHWDeviceContext *ctx, int dev, AVDictionary *opts,
for (int i = 0; i < optional_exts_num; i++) {
tstr = optional_exts[i].name;
found = 0;
+
+ if (dev && debug_mode &&
+ !strcmp(tstr, VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME)) {
+ continue;
+ }
+
for (int j = 0; j < sup_ext_count; j++) {
if (!strcmp(tstr, sup_ext[j].extensionName)) {
found = 1;
@@ -1561,7 +1561,8 @@ int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = nb,
.pBindings = set->binding,
- .flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT,
+ .flags = (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) ?
+ VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT : 0x0,
};
for (int i = 0; i < nb; i++) {
@@ -1589,13 +1590,35 @@ int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
return AVERROR_EXTERNAL;
}
- vk->GetDescriptorSetLayoutSizeEXT(s->hwctx->act_dev, *layout, &set->layout_size);
+ if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) {
+ 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++)
- vk->GetDescriptorSetLayoutBindingOffsetEXT(s->hwctx->act_dev, *layout,
- i, &set->binding_offset[i]);
+ for (int i = 0; i < nb; i++)
+ vk->GetDescriptorSetLayoutBindingOffsetEXT(s->hwctx->act_dev, *layout,
+ i, &set->binding_offset[i]);
+ } else {
+ for (int i = 0; i < nb; i++) {
+ int j;
+ VkDescriptorPoolSize *desc_pool_size;
+ for (j = 0; j < pl->nb_desc_pool_size; j++)
+ if (pl->desc_pool_size[j].type == desc[i].type)
+ break;
+ if (j >= pl->nb_desc_pool_size) {
+ desc_pool_size = av_realloc_array(pl->desc_pool_size,
+ sizeof(*desc_pool_size),
+ pl->nb_desc_pool_size + 1);
+ if (!desc_pool_size)
+ return AVERROR(ENOMEM);
+
+ pl->desc_pool_size = desc_pool_size;
+ pl->nb_desc_pool_size++;
+ memset(&desc_pool_size[j], 0, sizeof(VkDescriptorPoolSize));
+ }
+ pl->desc_pool_size[j].type = desc[i].type;
+ pl->desc_pool_size[j].descriptorCount += FFMAX(desc[i].elems, 1);
+ }
+ }
set->singular = singular;
set->nb_bindings = nb;
@@ -1643,38 +1666,99 @@ int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool,
{
int err;
- pl->desc_bind = av_calloc(pl->nb_descriptor_sets, sizeof(*pl->desc_bind));
- if (!pl->desc_bind)
- return AVERROR(ENOMEM);
+ if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) {
+ pl->desc_bind = av_calloc(pl->nb_descriptor_sets, sizeof(*pl->desc_bind));
+ if (!pl->desc_bind)
+ return AVERROR(ENOMEM);
- pl->bound_buffer_indices = av_calloc(pl->nb_descriptor_sets,
- sizeof(*pl->bound_buffer_indices));
- if (!pl->bound_buffer_indices)
- return AVERROR(ENOMEM);
+ pl->bound_buffer_indices = av_calloc(pl->nb_descriptor_sets,
+ sizeof(*pl->bound_buffer_indices));
+ if (!pl->bound_buffer_indices)
+ return AVERROR(ENOMEM);
- for (int i = 0; i < pl->nb_descriptor_sets; i++) {
- FFVulkanDescriptorSet *set = &pl->desc_set[i];
- int nb = set->singular ? 1 : pool->pool_size;
-
- err = ff_vk_create_buf(s, &set->buf, set->aligned_size*nb,
- NULL, NULL, set->usage,
- VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
- VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
- if (err < 0)
- return err;
+ for (int i = 0; i < pl->nb_descriptor_sets; i++) {
+ FFVulkanDescriptorSet *set = &pl->desc_set[i];
+ int nb = set->singular ? 1 : pool->pool_size;
+
+ err = ff_vk_create_buf(s, &set->buf, set->aligned_size*nb,
+ NULL, NULL, set->usage,
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
+ VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+ if (err < 0)
+ return err;
+
+ err = ff_vk_map_buffer(s, &set->buf, &set->desc_mem, 0);
+ if (err < 0)
+ return err;
+
+ pl->desc_bind[i] = (VkDescriptorBufferBindingInfoEXT) {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT,
+ .usage = set->usage,
+ .address = set->buf.address,
+ };
- err = ff_vk_map_buffer(s, &set->buf, &set->desc_mem, 0);
- if (err < 0)
- return err;
+ pl->bound_buffer_indices[i] = i;
+ }
+ } else {
+ VkResult ret;
+ FFVulkanFunctions *vk = &s->vkfn;
+ VkDescriptorSetLayout *tmp_layouts;
+ VkDescriptorSetAllocateInfo set_alloc_info;
+ VkDescriptorPoolCreateInfo pool_create_info;
+
+ for (int i = 0; i < pl->nb_desc_pool_size; i++)
+ pl->desc_pool_size[i].descriptorCount *= pool->pool_size;
+
+ pool_create_info = (VkDescriptorPoolCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
+ .flags = 0,
+ .pPoolSizes = pl->desc_pool_size,
+ .poolSizeCount = pl->nb_desc_pool_size,
+ .maxSets = pl->nb_descriptor_sets*pool->pool_size,
+ };
+
+ ret = vk->CreateDescriptorPool(s->hwctx->act_dev, &pool_create_info,
+ s->hwctx->alloc, &pl->desc_pool);
+ if (ret != VK_SUCCESS) {
+ av_log(s, AV_LOG_ERROR, "Unable to create descriptor pool: %s\n",
+ ff_vk_ret2str(ret));
+ return AVERROR_EXTERNAL;
+ }
- pl->desc_bind[i] = (VkDescriptorBufferBindingInfoEXT) {
- .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT,
- .usage = set->usage,
- .address = set->buf.address,
+ tmp_layouts = av_malloc_array(pool_create_info.maxSets, sizeof(*tmp_layouts));
+ if (!tmp_layouts)
+ return AVERROR(ENOMEM);
+
+ /* Colate each execution context's descriptor set layouts */
+ for (int i = 0; i < pool->pool_size; i++)
+ for (int j = 0; j < pl->nb_descriptor_sets; j++)
+ tmp_layouts[i*pl->nb_descriptor_sets + j] = pl->desc_layout[j];
+
+ set_alloc_info = (VkDescriptorSetAllocateInfo) {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
+ .descriptorPool = pl->desc_pool,
+ .pSetLayouts = tmp_layouts,
+ .descriptorSetCount = pool_create_info.maxSets,
};
- pl->bound_buffer_indices[i] = i;
+ pl->desc_sets = av_malloc_array(pool_create_info.maxSets,
+ sizeof(*tmp_layouts));
+ if (!pl->desc_sets) {
+ av_free(tmp_layouts);
+ return AVERROR(ENOMEM);
+ }
+ ret = vk->AllocateDescriptorSets(s->hwctx->act_dev, &set_alloc_info,
+ pl->desc_sets);
+ av_free(tmp_layouts);
+ if (ret != VK_SUCCESS) {
+ av_log(s, AV_LOG_ERROR, "Unable to allocate descriptor set: %s\n",
+ ff_vk_ret2str(ret));
+ av_freep(&pl->desc_sets);
+ return AVERROR_EXTERNAL;
+ }
+
+ pl->assoc_pool = pool;
}
return 0;
@@ -1696,94 +1780,150 @@ static inline void update_set_descriptor(FFVulkanContext *s, FFVkExecContext *e,
vk->GetDescriptorEXT(s->hwctx->act_dev, desc_get_info, desc_size, desc);
}
+static inline void update_set_pool_write(FFVulkanContext *s,
+ FFVulkanPipeline *pl,
+ FFVkExecContext *e,
+ FFVulkanDescriptorSet *desc_set, int set,
+ VkWriteDescriptorSet *write_info)
+{
+ FFVulkanFunctions *vk = &s->vkfn;
+ if (desc_set->singular) {
+ for (int i = 0; i < pl->assoc_pool->pool_size; i++) {
+ write_info->dstSet = pl->desc_sets[i*pl->nb_descriptor_sets + set];
+ vk->UpdateDescriptorSets(s->hwctx->act_dev, 1, write_info, 0, NULL);
+ }
+ } else {
+ write_info->dstSet = pl->desc_sets[e->idx + set];
+ vk->UpdateDescriptorSets(s->hwctx->act_dev, 1, write_info, 0, NULL);
+ }
+}
+
static int vk_set_descriptor_image(FFVulkanContext *s, FFVulkanPipeline *pl,
FFVkExecContext *e, int set, int bind, int offs,
VkImageView view, VkImageLayout layout,
VkSampler sampler)
{
FFVulkanDescriptorSet *desc_set = &pl->desc_set[set];
- VkDescriptorGetInfoEXT desc_get_info = {
- .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT,
- .type = desc_set->binding[bind].descriptorType,
- };
- VkDescriptorImageInfo desc_img_info = {
- .imageView = view,
- .sampler = sampler,
- .imageLayout = layout,
- };
- size_t desc_size;
- switch (desc_get_info.type) {
- case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
- desc_get_info.data.pSampledImage = &desc_img_info;
- desc_size = s->desc_buf_props.sampledImageDescriptorSize;
- break;
- case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
- desc_get_info.data.pStorageImage = &desc_img_info;
- desc_size = s->desc_buf_props.storageImageDescriptorSize;
- break;
- case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
- desc_get_info.data.pInputAttachmentImage = &desc_img_info;
- desc_size = s->desc_buf_props.inputAttachmentDescriptorSize;
- break;
- case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
- desc_get_info.data.pCombinedImageSampler = &desc_img_info;
- desc_size = s->desc_buf_props.combinedImageSamplerDescriptorSize;
- break;
- default:
- av_log(s, AV_LOG_ERROR, "Invalid descriptor type at set %i binding %i: %i!\n",
- set, bind, desc_get_info.type);
- return AVERROR(EINVAL);
- break;
- };
+ if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) {
+ VkDescriptorGetInfoEXT desc_get_info = {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT,
+ .type = desc_set->binding[bind].descriptorType,
+ };
+ VkDescriptorImageInfo desc_img_info = {
+ .imageView = view,
+ .sampler = sampler,
+ .imageLayout = layout,
+ };
+ size_t desc_size;
+
+ switch (desc_get_info.type) {
+ case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+ desc_get_info.data.pSampledImage = &desc_img_info;
+ desc_size = s->desc_buf_props.sampledImageDescriptorSize;
+ break;
+ case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+ desc_get_info.data.pStorageImage = &desc_img_info;
+ desc_size = s->desc_buf_props.storageImageDescriptorSize;
+ break;
+ case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+ desc_get_info.data.pInputAttachmentImage = &desc_img_info;
+ desc_size = s->desc_buf_props.inputAttachmentDescriptorSize;
+ break;
+ case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+ desc_get_info.data.pCombinedImageSampler = &desc_img_info;
+ desc_size = s->desc_buf_props.combinedImageSamplerDescriptorSize;
+ break;
+ default:
+ av_log(s, AV_LOG_ERROR, "Invalid descriptor type at set %i binding %i: %i!\n",
+ set, bind, desc_get_info.type);
+ return AVERROR(EINVAL);
+ break;
+ };
- update_set_descriptor(s, e, desc_set, bind, offs, &desc_get_info, desc_size);
+ update_set_descriptor(s, e, desc_set, bind, offs,
+ &desc_get_info, desc_size);
+ } else {
+ VkDescriptorImageInfo desc_pool_write_info_img = {
+ .sampler = sampler,
+ .imageView = view,
+ .imageLayout = layout,
+ };
+ VkWriteDescriptorSet desc_pool_write_info = {
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .dstBinding = bind,
+ .descriptorCount = 1,
+ .dstArrayElement = offs,
+ .descriptorType = desc_set->binding[bind].descriptorType,
+ .pImageInfo = &desc_pool_write_info_img,
+ };
+ update_set_pool_write(s, pl, e, desc_set, set, &desc_pool_write_info);
+ }
return 0;
}
int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl,
- FFVkExecContext *e, int set, int bind, int offs,
- VkDeviceAddress addr, VkDeviceSize len, VkFormat fmt)
+ FFVkExecContext *e, int set, int bind, int elem,
+ FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len,
+ VkFormat fmt)
{
FFVulkanDescriptorSet *desc_set = &pl->desc_set[set];
- VkDescriptorGetInfoEXT desc_get_info = {
- .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT,
- .type = desc_set->binding[bind].descriptorType,
- };
- VkDescriptorAddressInfoEXT desc_buf_info = {
- .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT,
- .address = addr,
- .range = len,
- .format = fmt,
- };
- size_t desc_size;
- switch (desc_get_info.type) {
- case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
- desc_get_info.data.pUniformBuffer = &desc_buf_info;
- desc_size = s->desc_buf_props.uniformBufferDescriptorSize;
- break;
- case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
- desc_get_info.data.pStorageBuffer = &desc_buf_info;
- desc_size = s->desc_buf_props.storageBufferDescriptorSize;
- break;
- case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
- desc_get_info.data.pUniformTexelBuffer = &desc_buf_info;
- desc_size = s->desc_buf_props.uniformTexelBufferDescriptorSize;
- break;
- case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
- desc_get_info.data.pStorageTexelBuffer = &desc_buf_info;
- desc_size = s->desc_buf_props.storageTexelBufferDescriptorSize;
- break;
- default:
- av_log(s, AV_LOG_ERROR, "Invalid descriptor type at set %i binding %i: %i!\n",
- set, bind, desc_get_info.type);
- return AVERROR(EINVAL);
- break;
- };
+ if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) {
+ VkDescriptorGetInfoEXT desc_get_info = {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_GET_INFO_EXT,
+ .type = desc_set->binding[bind].descriptorType,
+ };
+ VkDescriptorAddressInfoEXT desc_buf_info = {
+ .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_ADDRESS_INFO_EXT,
+ .address = buf->address + offset,
+ .range = len,
+ .format = fmt,
+ };
+ size_t desc_size;
- update_set_descriptor(s, e, desc_set, bind, offs, &desc_get_info, desc_size);
+ switch (desc_get_info.type) {
+ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+ desc_get_info.data.pUniformBuffer = &desc_buf_info;
+ desc_size = s->desc_buf_props.uniformBufferDescriptorSize;
+ break;
+ case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+ desc_get_info.data.pStorageBuffer = &desc_buf_info;
+ desc_size = s->desc_buf_props.storageBufferDescriptorSize;
+ break;
+ case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+ desc_get_info.data.pUniformTexelBuffer = &desc_buf_info;
+ desc_size = s->desc_buf_props.uniformTexelBufferDescriptorSize;
+ break;
+ case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+ desc_get_info.data.pStorageTexelBuffer = &desc_buf_info;
+ desc_size = s->desc_buf_props.storageTexelBufferDescriptorSize;
+ break;
+ default:
+ av_log(s, AV_LOG_ERROR, "Invalid descriptor type at set %i binding %i: %i!\n",
+ set, bind, desc_get_info.type);
+ return AVERROR(EINVAL);
+ break;
+ };
+
+ update_set_descriptor(s, e, desc_set, bind, elem, &desc_get_info, desc_size);
+ } else {
+ VkDescriptorBufferInfo desc_pool_write_info_buf = {
+ .buffer = buf->buf,
+ .offset = offset,
+ .range = len,
+ };
+ VkWriteDescriptorSet desc_pool_write_info = {
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .dstBinding = bind,
+ .descriptorCount = 1,
+ .dstArrayElement = elem,
+ .descriptorType = desc_set->binding[bind].descriptorType,
+ .pBufferInfo = &desc_pool_write_info_buf,
+ };
+ update_set_pool_write(s, pl, e, desc_set, set, &desc_pool_write_info);
+ }
return 0;
}
@@ -1852,7 +1992,8 @@ int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl,
pipeline_create_info = (VkComputePipelineCreateInfo) {
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
- .flags = VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT,
+ .flags = (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) ?
+ VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT : 0x0,
.layout = pl->pipeline_layout,
.stage = shd->shader,
};
@@ -1884,15 +2025,22 @@ void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e,
vk->CmdBindPipeline(e->buf, pl->bind_point, pl->pipeline);
if (pl->nb_descriptor_sets) {
- for (int i = 0; i < pl->nb_descriptor_sets; i++)
- offsets[i] = pl->desc_set[i].singular ? 0 : pl->desc_set[i].aligned_size*e->idx;
-
- /* Bind descriptor buffers */
- vk->CmdBindDescriptorBuffersEXT(e->buf, pl->nb_descriptor_sets, pl->desc_bind);
- /* Binding offsets */
- vk->CmdSetDescriptorBufferOffsetsEXT(e->buf, pl->bind_point, pl->pipeline_layout,
- 0, pl->nb_descriptor_sets,
- pl->bound_buffer_indices, offsets);
+ if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) {
+ for (int i = 0; i < pl->nb_descriptor_sets; i++)
+ offsets[i] = pl->desc_set[i].singular ? 0 : pl->desc_set[i].aligned_size*e->idx;
+
+ /* Bind descriptor buffers */
+ vk->CmdBindDescriptorBuffersEXT(e->buf, pl->nb_descriptor_sets, pl->desc_bind);
+ /* Binding offsets */
+ vk->CmdSetDescriptorBufferOffsetsEXT(e->buf, pl->bind_point, pl->pipeline_layout,
+ 0, pl->nb_descriptor_sets,
+ pl->bound_buffer_indices, offsets);
+ } else {
+ vk->CmdBindDescriptorSets(e->buf, pl->bind_point, pl->pipeline_layout,
+ 0, pl->nb_descriptor_sets,
+ &pl->desc_sets[e->idx*pl->nb_descriptor_sets],
+ 0, NULL);
+ }
}
}
@@ -1920,6 +2068,11 @@ void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl)
vk->DestroyDescriptorSetLayout(s->hwctx->act_dev, pl->desc_layout[i],
s->hwctx->alloc);
+ if (pl->desc_pool)
+ vk->DestroyDescriptorPool(s->hwctx->act_dev, pl->desc_pool,
+ s->hwctx->alloc);
+
+ av_freep(&pl->desc_pool_size);
av_freep(&pl->desc_layout);
av_freep(&pl->desc_set);
av_freep(&pl->desc_bind);
@@ -112,44 +112,6 @@ typedef struct FFVkQueueFamilyCtx {
int nb_queues;
} FFVkQueueFamilyCtx;
-typedef struct FFVulkanDescriptorSet {
- FFVkBuffer buf;
- uint8_t *desc_mem;
- VkDeviceSize layout_size;
- VkDeviceSize aligned_size; /* descriptorBufferOffsetAlignment */
- VkDeviceSize total_size; /* Once registered to an exec context */
- VkBufferUsageFlags usage;
-
- VkDescriptorSetLayoutBinding *binding;
- VkDeviceSize *binding_offset;
- int nb_bindings;
-
- /* Descriptor set is shared between all submissions */
- int singular;
-} FFVulkanDescriptorSet;
-
-typedef struct FFVulkanPipeline {
- VkPipelineBindPoint bind_point;
-
- /* Contexts */
- VkPipelineLayout pipeline_layout;
- VkPipeline pipeline;
-
- /* Push consts */
- VkPushConstantRange *push_consts;
- int push_consts_num;
-
- /* Workgroup */
- int wg_size[3];
-
- /* Descriptor buffer */
- VkDescriptorSetLayout *desc_layout;
- FFVulkanDescriptorSet *desc_set;
- VkDescriptorBufferBindingInfoEXT *desc_bind;
- uint32_t *bound_buffer_indices;
- int nb_descriptor_sets;
-} FFVulkanPipeline;
-
typedef struct FFVkExecContext {
uint32_t idx;
const struct FFVkExecPool *parent;
@@ -226,6 +188,52 @@ typedef struct FFVkExecPool {
size_t qd_size;
} FFVkExecPool;
+typedef struct FFVulkanDescriptorSet {
+ FFVkBuffer buf;
+ uint8_t *desc_mem;
+ VkDeviceSize layout_size;
+ VkDeviceSize aligned_size; /* descriptorBufferOffsetAlignment */
+ VkDeviceSize total_size; /* Once registered to an exec context */
+ VkBufferUsageFlags usage;
+
+ VkDescriptorSetLayoutBinding *binding;
+ VkDeviceSize *binding_offset;
+ int nb_bindings;
+
+ /* Descriptor set is shared between all submissions */
+ int singular;
+} FFVulkanDescriptorSet;
+
+typedef struct FFVulkanPipeline {
+ VkPipelineBindPoint bind_point;
+
+ /* Contexts */
+ VkPipelineLayout pipeline_layout;
+ VkPipeline pipeline;
+
+ /* Push consts */
+ VkPushConstantRange *push_consts;
+ int push_consts_num;
+
+ /* Workgroup */
+ int wg_size[3];
+
+ /* Descriptor buffer */
+ VkDescriptorSetLayout *desc_layout;
+ FFVulkanDescriptorSet *desc_set;
+ VkDescriptorBufferBindingInfoEXT *desc_bind;
+ uint32_t *bound_buffer_indices;
+ int nb_descriptor_sets;
+
+ /* Descriptor pool */
+ VkDescriptorSet *desc_sets;
+ VkDescriptorPool desc_pool;
+ VkDescriptorPoolSize *desc_pool_size;
+ int nb_desc_pool_size;
+ int total_desc_sets;
+ FFVkExecPool *assoc_pool;
+} FFVulkanPipeline;
+
typedef struct FFVulkanContext {
const AVClass *class;
void *log_parent;
@@ -508,8 +516,9 @@ void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e,
FFVulkanPipeline *pl);
int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl,
- FFVkExecContext *e, int set, int bind, int offs,
- VkDeviceAddress addr, VkDeviceSize len, VkFormat fmt);
+ FFVkExecContext *e, int set, int bind, int elem,
+ FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len,
+ VkFormat fmt);
void ff_vk_update_descriptor_img_array(FFVulkanContext *s, FFVulkanPipeline *pl,
FFVkExecContext *e, AVFrame *f,
@@ -176,6 +176,9 @@ typedef enum FFVulkanExtensions {
MACRO(1, 1, FF_VK_EXT_NO_FLAG, UpdateDescriptorSetWithTemplate) \
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateDescriptorUpdateTemplate) \
MACRO(1, 1, FF_VK_EXT_NO_FLAG, DestroyDescriptorUpdateTemplate) \
+ \
+ /* Descriptors */ \
+ MACRO(1, 1, FF_VK_EXT_NO_FLAG, UpdateDescriptorSets) \
\
/* Queries */ \
MACRO(1, 1, FF_VK_EXT_NO_FLAG, CreateQueryPool) \