From patchwork Sun Sep 22 07:22:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lynne X-Patchwork-Id: 51694 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:d154:0:b0:48e:c0f8:d0de with SMTP id bt20csp1852035vqb; Sun, 22 Sep 2024 00:23:41 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCX4tqsjP4WZgbInxX5uF0t0yEr+JjLSsDReFt8HQ5knsxGdj+Y1hK/zrgVpmH0ztjSCFITC6XMzMhWf6lyTSVZQ@gmail.com X-Google-Smtp-Source: AGHT+IEsmfe7/Pf/WM8thMLnmyh28lQ9DwwhqX2v+eFOIvb+pY3GsYf1OFLsXc8MrBr75KXsPFOQ X-Received: by 2002:a50:858b:0:b0:5c4:6307:d971 with SMTP id 4fb4d7f45d1cf-5c464a43b24mr6132561a12.18.1726989821034; Sun, 22 Sep 2024 00:23:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726989821; cv=none; d=google.com; s=arc-20240605; b=Xt213NsQWpWacPVRUIxr5HdOTRp6UNPjXhXXKZDlwfpsjVn8yNGLYiP2w1UQrRhDUJ J4j+Ca7YcAXzlBcV1ECeNta3vUABbAY4s7klE/nt1aTA+n+AhkWknxSUTizOVCP9iG4e OlTdcYdWIeHQ9prt+aBa9QywWCcNPswaOCgSj87hxs58/dUElvKeNlWg6fOR/JejRu7t 30grKvr2CzI783WIZ7QX3CsSTeTDRwwPjApnBleb80mmw7mmPpL7KSzVn2pEVAC0ypm3 cdvjU43/I7XQ7MNqJfhWnZ6wb7N73DLuOEEsNDIV28eqGB9CMz2KZWE9QTYBUw6bhb+D O/Iw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:cc:reply-to:from :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:delivered-to; bh=qnFd1u0ol2b6f53KTF81WlKAY3ExqKYjPgp5wN8OTVg=; fh=nenT92/WZoU6unXd3J6UhGUdod4piddKfVtctNBOh6k=; b=lYqAt5mfc6qSrVujtsklg4P5VlO7gjl51os+PBIqTJIYIMBhDGyyYhFkBBxXkxYgQh df+x+x8YmV/HzUZ3la5g+WDLxlFhPZHoTgPOoGx6csU/gOzOTsYb22UxzShgaT1MDf1v Y+RXJwoEdP3RyZSdm8gtSWG7oSAcgcDwrdWt1ywRC1hBCJlSQpSB8m+CIPuGsvb8M5wr dsjPcQnT8JCsbGrBkg/mY4LgPc4t+dF3ghEgJUlf2Gux2bjYesQvz96kcHmY9ba8EafT DfA9/Ix7fOGAJNQw4yIjEatx/qPe3jqQqBVqKaKL21fC6Axr+bYJrG31bNzdjgli14XQ fwJg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 4fb4d7f45d1cf-5c42bb50e41si12527495a12.117.2024.09.22.00.23.40; Sun, 22 Sep 2024 00:23:41 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9CD2668DBC7; Sun, 22 Sep 2024 10:22:59 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from vidala.lynne.ee (vidala.pars.ee [116.203.72.101]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3279868DB18 for ; Sun, 22 Sep 2024 10:22:48 +0300 (EEST) To: ffmpeg-devel@ffmpeg.org Date: Sun, 22 Sep 2024 09:22:37 +0200 Message-ID: <20240922072243.175005-4-dev@lynne.ee> X-Mailer: git-send-email 2.45.2.753.g447d99e1c3b In-Reply-To: <20240922072243.175005-1-dev@lynne.ee> References: <20240922072243.175005-1-dev@lynne.ee> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 4/4] vulkan: add support for regular descriptor pools X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Lynne via ffmpeg-devel From: Lynne Reply-To: FFmpeg development discussions and patches Cc: Lynne Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: zK0EY0kUNwAH This permits: - The use of Vulkan filtering on many more devices - Better debugging due to lack of descriptor buffer support in layers --- libavfilter/vf_gblur_vulkan.c | 2 +- libavfilter/vf_nlmeans_vulkan.c | 21 +- libavfilter/vulkan_filter.c | 120 +++++----- libavutil/hwcontext_vulkan.c | 6 + libavutil/vulkan.c | 381 ++++++++++++++++++++++---------- libavutil/vulkan.h | 89 ++++---- libavutil/vulkan_functions.h | 3 + 7 files changed, 390 insertions(+), 232 deletions(-) diff --git a/libavfilter/vf_gblur_vulkan.c b/libavfilter/vf_gblur_vulkan.c index 546e2828b0..d0fb6c9940 100644 --- a/libavfilter/vf_gblur_vulkan.c +++ b/libavfilter/vf_gblur_vulkan.c @@ -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: diff --git a/libavfilter/vf_nlmeans_vulkan.c b/libavfilter/vf_nlmeans_vulkan.c index cd44f5e4db..9d96efa27b 100644 --- a/libavfilter/vf_nlmeans_vulkan.c +++ b/libavfilter/vf_nlmeans_vulkan.c @@ -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)); } diff --git a/libavfilter/vulkan_filter.c b/libavfilter/vulkan_filter.c index c31d42b91a..2c6ab72849 100644 --- a/libavfilter/vulkan_filter.c +++ b/libavfilter/vulkan_filter.c @@ -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], diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c index 5e56a215e8..7e7d9cb70b 100644 --- a/libavutil/hwcontext_vulkan.c +++ b/libavutil/hwcontext_vulkan.c @@ -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; diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c index e3fb70da46..71f978f9d1 100644 --- a/libavutil/vulkan.c +++ b/libavutil/vulkan.c @@ -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); diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h index 35e3488690..7009104a8f 100644 --- a/libavutil/vulkan.h +++ b/libavutil/vulkan.h @@ -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, diff --git a/libavutil/vulkan_functions.h b/libavutil/vulkan_functions.h index 6aeaf4e79a..da555b37c7 100644 --- a/libavutil/vulkan_functions.h +++ b/libavutil/vulkan_functions.h @@ -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) \