From patchwork Sun Sep 29 09:42:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lynne X-Patchwork-Id: 51924 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:d8ca:0:b0:48e:c0f8:d0de with SMTP id dy10csp1341198vqb; Sun, 29 Sep 2024 02:43:52 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCX3lQbVuEkzYJf1eug9BKBBnMGXZcS9VveCz2u1LZVtSgWwnXoNP3wl4voOM7TMu8h4zeqK/1HDUl/vyfEuQYdJ@gmail.com X-Google-Smtp-Source: AGHT+IG/E5/2NsfAS9eyM/ZtQgwAOFZQW/nlm0VGE4f348dQxscp44XJffIsFzLy5Jrj+37JT1Lx X-Received: by 2002:a17:907:31ce:b0:a72:7a71:7f4f with SMTP id a640c23a62f3a-a93c3094b53mr1008764366b.7.1727603032266; Sun, 29 Sep 2024 02:43:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1727603032; cv=none; d=google.com; s=arc-20240605; b=Bm4ftb04dnbxvWCkLyDx5jWiz+W3o/n7xjVzJw6m5Ng+JtAI/kvypKafAP1MLJwOpW fd6iFe6D7EDeGL3lLFeIyr24MzvGhRB2bThb0y7yvjWue4Yb2xyQZyoBUriDDlE1jNYD dvkAXPM0tgy32vbGpmCGnSxSZaX+q41evjezgLA83xM6DTXGvnBXj2Pc3kBilNwJP1oZ 568ksjCjVQLpdSpjFIIqIee4TU97Q+dwfElZRKv4rtH3sEaA3jQfsXiibfyQVt6MBWW2 sRrdoEKws8I6pC44NlORBlh9cURZMZdmRBXPQktOE5Z4acNa+3GdEkb7zjzooGZP9n9J MdKg== 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:message-id:date:to :delivered-to; bh=ackCg3k68p7rW2218Ovi9+kA81prbLS8ex6GT//9Y1o=; fh=nenT92/WZoU6unXd3J6UhGUdod4piddKfVtctNBOh6k=; b=A5pCGRSuXjjCxi1S1AGAJQ6K+wTBwFxXkEQ7PV6odB+X4ABockboXLx1pgDmPw7hv1 OtpgzQKSdpykYP8Vmqgx1Lq8BJVCXWgHAIhXi9ZDgKd7d92U5i6N15eBH5BDF7cgvl5o MYmkJwdYrfk/BTfW/4nNtvABbA0NrLVgKabGy+iNYVHdKaZqmtoVs6NyV8G5vNh81hAp 5NB7flYOptAb9WC/eVAQrbvijLQndghpYpcJ1P/8gbFjmfLHPWy75hm4dGkY1vD1sdPO zmOJgI/qqYbLEahxfu0nRstrI9ySGYznZNSO8SFJZwoP7Dhr8fy71o8HesNRdG0RHtG7 RGUQ==; 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 a640c23a62f3a-a93c29e70d4si452326666b.576.2024.09.29.02.43.51; Sun, 29 Sep 2024 02:43:52 -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 4E76768DA96; Sun, 29 Sep 2024 12:43:12 +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 9528F68D9FF for ; Sun, 29 Sep 2024 12:43:00 +0300 (EEST) To: ffmpeg-devel@ffmpeg.org Date: Sun, 29 Sep 2024 11:42:48 +0200 Message-ID: <20240929094256.396352-1-dev@lynne.ee> X-Mailer: git-send-email 2.45.2.753.g447d99e1c3b MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/5] vulkan: merge FFVkSPIRVShader and FFVkPipeline into FFVkShader 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: Nf4JJoty/OxZ Pipelines are just shaders. There's no reason to treat them differently. This also lets us implement shader objects and is an overall cleanup. --- libavfilter/vf_avgblur_vulkan.c | 28 +- libavfilter/vf_blend_vulkan.c | 24 +- libavfilter/vf_bwdif_vulkan.c | 29 +- libavfilter/vf_chromaber_vulkan.c | 28 +- libavfilter/vf_flip_vulkan.c | 24 +- libavfilter/vf_gblur_vulkan.c | 54 ++- libavfilter/vf_nlmeans_vulkan.c | 135 +++---- libavfilter/vf_overlay_vulkan.c | 28 +- libavfilter/vf_scale_vulkan.c | 28 +- libavfilter/vf_transpose_vulkan.c | 24 +- libavfilter/vf_xfade_vulkan.c | 28 +- libavfilter/vsrc_testsrc_vulkan.c | 30 +- libavfilter/vulkan_filter.c | 78 ++-- libavfilter/vulkan_filter.h | 6 +- libavfilter/vulkan_glslang.c | 4 +- libavfilter/vulkan_shaderc.c | 4 +- libavfilter/vulkan_spirv.h | 2 +- libavutil/vulkan.c | 633 ++++++++++++++++-------------- libavutil/vulkan.h | 146 ++++--- 19 files changed, 707 insertions(+), 626 deletions(-) diff --git a/libavfilter/vf_avgblur_vulkan.c b/libavfilter/vf_avgblur_vulkan.c index 439766968e..3972ea0cbb 100644 --- a/libavfilter/vf_avgblur_vulkan.c +++ b/libavfilter/vf_avgblur_vulkan.c @@ -33,8 +33,7 @@ typedef struct AvgBlurVulkanContext { FFVkExecPool e; FFVkQueueFamilyCtx qf; VkSampler sampler; - FFVulkanPipeline pl; - FFVkSPIRVShader shd; + FFVulkanShader shd; /* Push constants / options */ struct { @@ -68,7 +67,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) AvgBlurVulkanContext *s = ctx->priv; FFVulkanContext *vkctx = &s->vkctx; const int planes = av_pix_fmt_count_planes(s->vkctx.output_format); - FFVkSPIRVShader *shd; + FFVulkanShader *shd; FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc; @@ -81,12 +80,13 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT); RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL)); RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_LINEAR)); - RET(ff_vk_shader_init(&s->pl, &s->shd, "avgblur_compute", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); + RET(ff_vk_shader_init(vkctx, &s->shd, "avgblur", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 32, 1, 1, + 0)); shd = &s->shd; - ff_vk_shader_set_compute_sizes(shd, 32, 1, 1); - desc = (FFVulkanDescriptorSetBinding []) { { .name = "input_img", @@ -107,7 +107,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 2, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc, 2, 0, 0)); GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); GLSLC(1, vec4 filter_norm; ); @@ -115,8 +115,8 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) GLSLC(0, }; ); GLSLC(0, ); - ff_vk_add_push_constant(&s->pl, 0, sizeof(s->opts), - VK_SHADER_STAGE_COMPUTE_BIT); + ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts), + VK_SHADER_STAGE_COMPUTE_BIT); GLSLD( blur_kernel ); GLSLC(0, void main() ); @@ -139,10 +139,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) RET(spv->compile_shader(spv, ctx, &s->shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(vkctx, &s->shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(vkctx, &s->shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, &s->shd)); - RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl)); + RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd)); s->initialized = 1; s->opts.filter_len[0] = s->size_x - 1; @@ -180,7 +179,7 @@ static int avgblur_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) if (!s->initialized) RET(init_filter(ctx, in)); - RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, + RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in, s->sampler, &s->opts, sizeof(s->opts))); err = av_frame_copy_props(out, in); @@ -204,7 +203,6 @@ static void avgblur_vulkan_uninit(AVFilterContext *avctx) FFVulkanFunctions *vk = &vkctx->vkfn; ff_vk_exec_pool_free(vkctx, &s->e); - ff_vk_pipeline_free(vkctx, &s->pl); ff_vk_shader_free(vkctx, &s->shd); if (s->sampler) diff --git a/libavfilter/vf_blend_vulkan.c b/libavfilter/vf_blend_vulkan.c index f3eb5355f1..ccc025fe6b 100644 --- a/libavfilter/vf_blend_vulkan.c +++ b/libavfilter/vf_blend_vulkan.c @@ -46,10 +46,9 @@ typedef struct BlendVulkanContext { FFFrameSync fs; int initialized; - FFVulkanPipeline pl; FFVkExecPool e; FFVkQueueFamilyCtx qf; - FFVkSPIRVShader shd; + FFVulkanShader shd; VkSampler sampler; FilterParamsVulkan params[4]; @@ -132,7 +131,7 @@ static av_cold int init_filter(AVFilterContext *avctx) BlendVulkanContext *s = avctx->priv; FFVulkanContext *vkctx = &s->vkctx; const int planes = av_pix_fmt_count_planes(s->vkctx.output_format); - FFVkSPIRVShader *shd = &s->shd; + FFVulkanShader *shd = &s->shd; FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc; @@ -145,10 +144,11 @@ static av_cold int init_filter(AVFilterContext *avctx) ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT); RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL)); RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST)); - RET(ff_vk_shader_init(&s->pl, &s->shd, "blend_compute", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); - - ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1); + RET(ff_vk_shader_init(vkctx, &s->shd, "blend", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 32, 32, 1, + 0)); desc = (FFVulkanDescriptorSetBinding []) { { @@ -178,7 +178,7 @@ static av_cold int init_filter(AVFilterContext *avctx) }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 3, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 3, 0, 0)); for (int i = 0, j = 0; i < planes; i++) { for (j = 0; j < i; j++) @@ -210,10 +210,9 @@ static av_cold int init_filter(AVFilterContext *avctx) RET(spv->compile_shader(spv, avctx, shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd)); - RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl)); + RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd)); s->initialized = 1; @@ -257,7 +256,7 @@ static int blend_frame(FFFrameSync *fs) RET(init_filter(avctx)); } - RET(ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->pl, + RET(ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->shd, out, (AVFrame *[]){ top, bottom }, 2, s->sampler, NULL, 0)); @@ -284,7 +283,6 @@ static av_cold void uninit(AVFilterContext *avctx) FFVulkanFunctions *vk = &vkctx->vkfn; ff_vk_exec_pool_free(vkctx, &s->e); - ff_vk_pipeline_free(vkctx, &s->pl); ff_vk_shader_free(vkctx, &s->shd); if (s->sampler) diff --git a/libavfilter/vf_bwdif_vulkan.c b/libavfilter/vf_bwdif_vulkan.c index 4e43ade1c2..3164eb3395 100644 --- a/libavfilter/vf_bwdif_vulkan.c +++ b/libavfilter/vf_bwdif_vulkan.c @@ -35,8 +35,7 @@ typedef struct BWDIFVulkanContext { FFVkExecPool e; FFVkQueueFamilyCtx qf; VkSampler sampler; - FFVulkanPipeline pl; - FFVkSPIRVShader shd; + FFVulkanShader shd; } BWDIFVulkanContext; typedef struct BWDIFParameters { @@ -100,7 +99,7 @@ static av_cold int init_filter(AVFilterContext *ctx) BWDIFVulkanContext *s = ctx->priv; FFVulkanContext *vkctx = &s->vkctx; const int planes = av_pix_fmt_count_planes(s->vkctx.output_format); - FFVkSPIRVShader *shd; + FFVulkanShader *shd; FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc; @@ -113,11 +112,13 @@ static av_cold int init_filter(AVFilterContext *ctx) ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT); RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL)); RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST)); - RET(ff_vk_shader_init(&s->pl, &s->shd, "bwdif_compute", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); - shd = &s->shd; - ff_vk_shader_set_compute_sizes(shd, 1, 64, 1); + RET(ff_vk_shader_init(vkctx, &s->shd, "bwdif", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 1, 64, 1, + 0)); + shd = &s->shd; desc = (FFVulkanDescriptorSetBinding []) { { @@ -155,7 +156,7 @@ static av_cold int init_filter(AVFilterContext *ctx) }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 4, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 4, 0, 0)); GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); GLSLC(1, int parity; ); @@ -163,8 +164,8 @@ static av_cold int init_filter(AVFilterContext *ctx) GLSLC(1, int current_field; ); GLSLC(0, }; ); - ff_vk_add_push_constant(&s->pl, 0, sizeof(BWDIFParameters), - VK_SHADER_STAGE_COMPUTE_BIT); + ff_vk_shader_add_push_const(&s->shd, 0, sizeof(BWDIFParameters), + VK_SHADER_STAGE_COMPUTE_BIT); GLSLD( filter_fn ); GLSLC(0, void main() ); @@ -245,10 +246,9 @@ static av_cold int init_filter(AVFilterContext *ctx) RET(spv->compile_shader(spv, ctx, &s->shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(vkctx, &s->shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(vkctx, &s->shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, &s->shd)); - RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl)); + RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd)); s->initialized = 1; @@ -272,7 +272,7 @@ static void bwdif_vulkan_filter_frame(AVFilterContext *ctx, AVFrame *dst, .current_field = y->current_field, }; - ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->pl, dst, + ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->shd, dst, (AVFrame *[]){ y->prev, y->cur, y->next }, 3, s->sampler, ¶ms, sizeof(params)); @@ -287,7 +287,6 @@ static void bwdif_vulkan_uninit(AVFilterContext *avctx) FFVulkanFunctions *vk = &vkctx->vkfn; ff_vk_exec_pool_free(vkctx, &s->e); - ff_vk_pipeline_free(vkctx, &s->pl); ff_vk_shader_free(vkctx, &s->shd); if (s->sampler) diff --git a/libavfilter/vf_chromaber_vulkan.c b/libavfilter/vf_chromaber_vulkan.c index 60c8378b11..450715b36c 100644 --- a/libavfilter/vf_chromaber_vulkan.c +++ b/libavfilter/vf_chromaber_vulkan.c @@ -30,10 +30,9 @@ typedef struct ChromaticAberrationVulkanContext { FFVulkanContext vkctx; int initialized; - FFVulkanPipeline pl; FFVkExecPool e; FFVkQueueFamilyCtx qf; - FFVkSPIRVShader shd; + FFVulkanShader shd; VkSampler sampler; /* Push constants / options */ @@ -75,7 +74,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) ChromaticAberrationVulkanContext *s = ctx->priv; FFVulkanContext *vkctx = &s->vkctx; const int planes = av_pix_fmt_count_planes(s->vkctx.output_format); - FFVkSPIRVShader *shd = &s->shd; + FFVulkanShader *shd = &s->shd; FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc; @@ -92,18 +91,19 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT); RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL)); RET(ff_vk_init_sampler(vkctx, &s->sampler, 0, VK_FILTER_LINEAR)); - RET(ff_vk_shader_init(&s->pl, &s->shd, "chromaber_compute", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); - - ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1); + RET(ff_vk_shader_init(vkctx, &s->shd, "chromatic_abberation", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 32, 32, 1, + 0)); GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); GLSLC(1, vec2 dist; ); GLSLC(0, }; ); GLSLC(0, ); - ff_vk_add_push_constant(&s->pl, 0, sizeof(s->opts), - VK_SHADER_STAGE_COMPUTE_BIT); + ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts), + VK_SHADER_STAGE_COMPUTE_BIT); desc = (FFVulkanDescriptorSetBinding []) { { @@ -125,7 +125,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 2, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0)); GLSLD( distort_chroma_kernel ); GLSLC(0, void main() ); @@ -150,10 +150,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd)); - RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl)); + RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd)); s->initialized = 1; @@ -182,7 +181,7 @@ static int chromaber_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) if (!s->initialized) RET(init_filter(ctx, in)); - RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, out, in, + RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in, s->sampler, &s->opts, sizeof(s->opts))); err = av_frame_copy_props(out, in); @@ -206,7 +205,6 @@ static void chromaber_vulkan_uninit(AVFilterContext *avctx) FFVulkanFunctions *vk = &vkctx->vkfn; ff_vk_exec_pool_free(vkctx, &s->e); - ff_vk_pipeline_free(vkctx, &s->pl); ff_vk_shader_free(vkctx, &s->shd); if (s->sampler) diff --git a/libavfilter/vf_flip_vulkan.c b/libavfilter/vf_flip_vulkan.c index 1271396803..2b89a9a6a3 100644 --- a/libavfilter/vf_flip_vulkan.c +++ b/libavfilter/vf_flip_vulkan.c @@ -37,10 +37,9 @@ typedef struct FlipVulkanContext { FFVulkanContext vkctx; int initialized; - FFVulkanPipeline pl; FFVkExecPool e; FFVkQueueFamilyCtx qf; - FFVkSPIRVShader shd; + FFVulkanShader shd; VkSampler sampler; } FlipVulkanContext; @@ -53,7 +52,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in, enum FlipType FlipVulkanContext *s = ctx->priv; FFVulkanContext *vkctx = &s->vkctx; const int planes = av_pix_fmt_count_planes(s->vkctx.output_format); - FFVkSPIRVShader *shd = &s->shd; + FFVulkanShader *shd = &s->shd; FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc; @@ -66,10 +65,11 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in, enum FlipType ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT); RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL)); RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_LINEAR)); - RET(ff_vk_shader_init(&s->pl, &s->shd, "flip_compute", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); - - ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1); + RET(ff_vk_shader_init(vkctx, &s->shd, "flip", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 32, 32, 1, + 0)); desc = (FFVulkanDescriptorSetBinding []) { { @@ -91,7 +91,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in, enum FlipType }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 2, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0)); GLSLC(0, void main() ); GLSLC(0, { ); @@ -123,10 +123,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in, enum FlipType RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd)); - RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl)); + RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd)); s->initialized = 1; @@ -147,7 +146,6 @@ static av_cold void flip_vulkan_uninit(AVFilterContext *avctx) FFVulkanFunctions *vk = &vkctx->vkfn; ff_vk_exec_pool_free(vkctx, &s->e); - ff_vk_pipeline_free(vkctx, &s->pl); ff_vk_shader_free(vkctx, &s->shd); if (s->sampler) @@ -176,7 +174,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in, enum FlipType type) if (!s->initialized) RET(init_filter(ctx, in, type)); - RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, out, in, + RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in, s->sampler, NULL, 0)); RET(av_frame_copy_props(out, in)); diff --git a/libavfilter/vf_gblur_vulkan.c b/libavfilter/vf_gblur_vulkan.c index d0fb6c9940..a56a6ece00 100644 --- a/libavfilter/vf_gblur_vulkan.c +++ b/libavfilter/vf_gblur_vulkan.c @@ -38,11 +38,9 @@ typedef struct GBlurVulkanContext { FFVkExecPool e; FFVkQueueFamilyCtx qf; VkSampler sampler; - FFVulkanPipeline pl_hor; - FFVkSPIRVShader shd_hor; + FFVulkanShader shd_hor; FFVkBuffer params_hor; - FFVulkanPipeline pl_ver; - FFVkSPIRVShader shd_ver; + FFVulkanShader shd_ver; FFVkBuffer params_ver; int size; @@ -123,8 +121,8 @@ static av_cold void init_gaussian_params(GBlurVulkanContext *s) init_kernel_size(s, &s->sizeV); } -static int init_gblur_pipeline(GBlurVulkanContext *s, FFVulkanPipeline *pl, - FFVkSPIRVShader *shd, FFVkBuffer *params_buf, +static int init_gblur_pipeline(GBlurVulkanContext *s, + FFVulkanShader *shd, FFVkBuffer *params_buf, int ksize, float sigma, FFVkSPIRVCompiler *spv) { int err = 0; @@ -150,7 +148,7 @@ static int init_gblur_pipeline(GBlurVulkanContext *s, FFVulkanPipeline *pl, buf_desc.buf_content = kernel_def; - RET(ff_vk_pipeline_descriptor_set_add(&s->vkctx, pl, shd, &buf_desc, 1, 1, 0)); + RET(ff_vk_shader_add_descriptor_set(&s->vkctx, shd, &buf_desc, 1, 1, 0)); GLSLD( gblur_func ); GLSLC(0, void main() ); @@ -173,10 +171,9 @@ static int init_gblur_pipeline(GBlurVulkanContext *s, FFVulkanPipeline *pl, RET(spv->compile_shader(spv, s, shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(&s->vkctx, shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(&s->vkctx, shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(&s->vkctx, pl, shd)); - RET(ff_vk_exec_pipeline_register(&s->vkctx, &s->e, pl)); + RET(ff_vk_shader_register_exec(&s->vkctx, &s->e, shd)); RET(ff_vk_create_buf(&s->vkctx, params_buf, sizeof(float) * ksize, NULL, NULL, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | @@ -187,10 +184,9 @@ static int init_gblur_pipeline(GBlurVulkanContext *s, FFVulkanPipeline *pl, init_gaussian_kernel((float *)kernel_mapped, sigma, ksize); 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, 0, params_buf->size, - VK_FORMAT_UNDEFINED)); + RET(ff_vk_shader_update_desc_buffer(&s->vkctx, &s->e.contexts[0], shd, 1, 0, 0, + params_buf, 0, params_buf->size, + VK_FORMAT_UNDEFINED)); fail: av_free(kernel_def); @@ -206,7 +202,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) FFVulkanContext *vkctx = &s->vkctx; const int planes = av_pix_fmt_count_planes(s->vkctx.output_format); - FFVkSPIRVShader *shd; + FFVulkanShader *shd; FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc; @@ -219,10 +215,6 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT); RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL)); RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_LINEAR)); - RET(ff_vk_shader_init(&s->pl_hor, &s->shd_hor, "gblur_hor_compute", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); - RET(ff_vk_shader_init(&s->pl_ver, &s->shd_ver, "gblur_ver_compute", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); desc = (FFVulkanDescriptorSetBinding []) { { @@ -248,22 +240,30 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) { shd = &s->shd_hor; - ff_vk_shader_set_compute_sizes(shd, 32, 1, 1); + RET(ff_vk_shader_init(vkctx, shd, "gblur_hor", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 32, 1, 1, + 0)); - RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl_hor, shd, desc, 2, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc, 2, 0, 0)); GLSLC(0, #define OFFSET (vec2(i, 0.0))); - RET(init_gblur_pipeline(s, &s->pl_hor, shd, &s->params_hor, s->size, s->sigma, spv)); + RET(init_gblur_pipeline(s, shd, &s->params_hor, s->size, s->sigma, spv)); } { shd = &s->shd_ver; - ff_vk_shader_set_compute_sizes(shd, 1, 32, 1); + RET(ff_vk_shader_init(vkctx, shd, "gblur_hor", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 1, 32, 1, + 0)); - RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl_ver, shd, desc, 2, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc, 2, 0, 0)); GLSLC(0, #define OFFSET (vec2(0.0, i))); - RET(init_gblur_pipeline(s, &s->pl_ver, shd, &s->params_ver, s->sizeV, s->sigmaV, spv)); + RET(init_gblur_pipeline(s, shd, &s->params_ver, s->sizeV, s->sigmaV, spv)); } s->initialized = 1; @@ -282,8 +282,6 @@ static av_cold void gblur_vulkan_uninit(AVFilterContext *avctx) FFVulkanFunctions *vk = &vkctx->vkfn; ff_vk_exec_pool_free(vkctx, &s->e); - ff_vk_pipeline_free(vkctx, &s->pl_hor); - ff_vk_pipeline_free(vkctx, &s->pl_ver); ff_vk_shader_free(vkctx, &s->shd_hor); ff_vk_shader_free(vkctx, &s->shd_ver); ff_vk_free_buf(vkctx, &s->params_hor); @@ -322,7 +320,7 @@ static int gblur_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) RET(init_filter(ctx, in)); RET(ff_vk_filter_process_2pass(&s->vkctx, &s->e, - (FFVulkanPipeline *[2]){ &s->pl_hor, &s->pl_ver }, + (FFVulkanShader *[2]){ &s->shd_hor, &s->shd_ver }, out, tmp, in, s->sampler, NULL, 0)); err = av_frame_copy_props(out, in); diff --git a/libavfilter/vf_nlmeans_vulkan.c b/libavfilter/vf_nlmeans_vulkan.c index fc9b522c80..05c752925e 100644 --- a/libavfilter/vf_nlmeans_vulkan.c +++ b/libavfilter/vf_nlmeans_vulkan.c @@ -45,11 +45,8 @@ typedef struct NLMeansVulkanContext { FFVkBuffer xyoffsets_buf; int pl_weights_rows; - FFVulkanPipeline pl_weights; - FFVkSPIRVShader shd_weights; - - FFVulkanPipeline pl_denoise; - FFVkSPIRVShader shd_denoise; + FFVulkanShader shd_weights; + FFVulkanShader shd_denoise; int *xoffsets; int *yoffsets; @@ -69,7 +66,7 @@ typedef struct NLMeansVulkanContext { extern const char *ff_source_prefix_sum_comp; -static void insert_first(FFVkSPIRVShader *shd, int r, const char *off, int horiz, int plane, int comp) +static void insert_first(FFVulkanShader *shd, int r, const char *off, int horiz, int plane, int comp) { GLSLF(4, s1 = texture(input_img[%i], pos + ivec2(%i + %s, %i + %s))[%i]; ,plane, horiz ? r : 0, horiz ? off : "0", !horiz ? r : 0, !horiz ? off : "0", comp); @@ -86,7 +83,7 @@ static void insert_first(FFVkSPIRVShader *shd, int r, const char *off, int horiz GLSLC(4, s2 = (s1 - s2) * (s1 - s2); ); } -static void insert_horizontal_pass(FFVkSPIRVShader *shd, int nb_rows, int first, int plane, int comp) +static void insert_horizontal_pass(FFVulkanShader *shd, int nb_rows, int first, int plane, int comp) { GLSLF(1, pos.y = int(gl_GlobalInvocationID.x) * %i; ,nb_rows); if (!first) @@ -112,7 +109,7 @@ static void insert_horizontal_pass(FFVkSPIRVShader *shd, int nb_rows, int first, GLSLC(0, ); } -static void insert_vertical_pass(FFVkSPIRVShader *shd, int nb_rows, int first, int plane, int comp) +static void insert_vertical_pass(FFVulkanShader *shd, int nb_rows, int first, int plane, int comp) { GLSLF(1, pos.x = int(gl_GlobalInvocationID.x) * %i; ,nb_rows); GLSLC(1, #pragma unroll(1) ); @@ -141,7 +138,7 @@ static void insert_vertical_pass(FFVkSPIRVShader *shd, int nb_rows, int first, i GLSLC(0, ); } -static void insert_weights_pass(FFVkSPIRVShader *shd, int nb_rows, int vert, +static void insert_weights_pass(FFVulkanShader *shd, int nb_rows, int vert, int t, int dst_comp, int plane, int comp) { GLSLF(1, p = patch_size[%i]; ,dst_comp); @@ -214,7 +211,7 @@ typedef struct HorizontalPushData { } HorizontalPushData; static av_cold int init_weights_pipeline(FFVulkanContext *vkctx, FFVkExecPool *exec, - FFVulkanPipeline *pl, FFVkSPIRVShader *shd, + FFVulkanShader *shd, VkSampler sampler, FFVkSPIRVCompiler *spv, int width, int height, int t, const AVPixFmtDescriptor *desc, @@ -241,8 +238,12 @@ static av_cold int init_weights_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e wg_rows++; } - RET(ff_vk_shader_init(pl, shd, "nlmeans_weights", VK_SHADER_STAGE_COMPUTE_BIT, 0)); - ff_vk_shader_set_compute_sizes(shd, wg_size, 1, 1); + RET(ff_vk_shader_init(vkctx, shd, "nlmeans_weights", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + wg_size, 1, 1, + 0)); + *nb_rows = wg_rows; if (t > 1) @@ -269,7 +270,8 @@ static av_cold int init_weights_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e GLSLC(0, }; ); GLSLC(0, ); - ff_vk_add_push_constant(pl, 0, sizeof(HorizontalPushData), VK_SHADER_STAGE_COMPUTE_BIT); + ff_vk_shader_add_push_const(shd, 0, sizeof(HorizontalPushData), + VK_SHADER_STAGE_COMPUTE_BIT); desc_set = (FFVulkanDescriptorSetBinding []) { { @@ -329,7 +331,7 @@ static av_cold int init_weights_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e .buf_content = "float sums_3[];", }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, pl, shd, desc_set, 1 + 2*desc->nb_components, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc_set, 1 + 2*desc->nb_components, 0, 0)); desc_set = (FFVulkanDescriptorSetBinding []) { { @@ -340,7 +342,7 @@ static av_cold int init_weights_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e .buf_content = "ivec2 xyoffsets[];", }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, pl, shd, desc_set, 1, 1, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc_set, 1, 1, 0)); GLSLC(0, ); GLSLC(0, void main() ); @@ -401,10 +403,9 @@ static av_cold int init_weights_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e GLSLC(0, } ); RET(spv->compile_shader(spv, vkctx, shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(vkctx, pl, shd)); - RET(ff_vk_exec_pipeline_register(vkctx, exec, pl)); + RET(ff_vk_shader_register_exec(vkctx, exec, shd)); fail: if (spv_opaque) @@ -418,7 +419,7 @@ typedef struct DenoisePushData { } DenoisePushData; static av_cold int init_denoise_pipeline(FFVulkanContext *vkctx, FFVkExecPool *exec, - FFVulkanPipeline *pl, FFVkSPIRVShader *shd, + FFVulkanShader *shd, VkSampler sampler, FFVkSPIRVCompiler *spv, const AVPixFmtDescriptor *desc, int planes) { @@ -428,16 +429,18 @@ static av_cold int init_denoise_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e void *spv_opaque = NULL; FFVulkanDescriptorSetBinding *desc_set; - RET(ff_vk_shader_init(pl, shd, "nlmeans_denoise", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); - - ff_vk_shader_set_compute_sizes(shd, 32, 32, 1); + RET(ff_vk_shader_init(vkctx, shd, "nlmeans_denoise", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 32, 32, 1, + 0)); GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); GLSLC(1, uvec4 ws_stride; ); GLSLC(0, }; ); - ff_vk_add_push_constant(pl, 0, sizeof(DenoisePushData), VK_SHADER_STAGE_COMPUTE_BIT); + ff_vk_shader_add_push_const(shd, 0, sizeof(DenoisePushData), + VK_SHADER_STAGE_COMPUTE_BIT); desc_set = (FFVulkanDescriptorSetBinding []) { { @@ -458,7 +461,7 @@ static av_cold int init_denoise_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e .stages = VK_SHADER_STAGE_COMPUTE_BIT, }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, pl, shd, desc_set, 2, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc_set, 2, 0, 0)); desc_set = (FFVulkanDescriptorSetBinding []) { { @@ -519,7 +522,7 @@ static av_cold int init_denoise_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, pl, shd, desc_set, 2*desc->nb_components, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc_set, 2*desc->nb_components, 0, 0)); GLSLC(0, void main() ); GLSLC(0, { ); @@ -551,10 +554,9 @@ static av_cold int init_denoise_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e GLSLC(0, } ); RET(spv->compile_shader(spv, vkctx, shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(vkctx, pl, shd)); - RET(ff_vk_exec_pipeline_register(vkctx, exec, pl)); + RET(ff_vk_shader_register_exec(vkctx, exec, shd)); fail: if (spv_opaque) @@ -654,14 +656,15 @@ static av_cold int init_filter(AVFilterContext *ctx) RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, 1, 0, 0, 0, NULL)); RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST)); - RET(init_weights_pipeline(vkctx, &s->e, &s->pl_weights, &s->shd_weights, s->sampler, + RET(init_weights_pipeline(vkctx, &s->e, &s->shd_weights, s->sampler, spv, s->vkctx.output_width, s->vkctx.output_height, s->opts.t, desc, planes, &s->pl_weights_rows)); - RET(init_denoise_pipeline(vkctx, &s->e, &s->pl_denoise, &s->shd_denoise, s->sampler, + RET(init_denoise_pipeline(vkctx, &s->e, &s->shd_denoise, s->sampler, spv, desc, planes)); - RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_weights, NULL, 1, 0, 0, + RET(ff_vk_shader_update_desc_buffer(vkctx, &s->e.contexts[0], &s->shd_weights, + 1, 0, 0, &s->xyoffsets_buf, 0, s->xyoffsets_buf.size, VK_FORMAT_UNDEFINED)); @@ -697,11 +700,12 @@ static int denoise_pass(NLMeansVulkanContext *s, FFVkExecContext *exec, }; /* Denoise pass pipeline */ - ff_vk_exec_bind_pipeline(vkctx, exec, &s->pl_denoise); + ff_vk_exec_bind_shader(vkctx, exec, &s->shd_denoise); /* Push data */ - ff_vk_update_push_exec(vkctx, exec, &s->pl_denoise, VK_SHADER_STAGE_COMPUTE_BIT, - 0, sizeof(pd), &pd); + ff_vk_shader_update_push_const(vkctx, exec, &s->shd_denoise, + VK_SHADER_STAGE_COMPUTE_BIT, + 0, sizeof(pd), &pd); buf_bar[nb_buf_bar++] = (VkBufferMemoryBarrier2) { .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2, @@ -726,8 +730,8 @@ static int denoise_pass(NLMeansVulkanContext *s, FFVkExecContext *exec, /* End of denoise pass */ vk->CmdDispatch(exec->buf, - FFALIGN(vkctx->output_width, s->pl_denoise.wg_size[0])/s->pl_denoise.wg_size[0], - FFALIGN(vkctx->output_height, s->pl_denoise.wg_size[1])/s->pl_denoise.wg_size[1], + FFALIGN(vkctx->output_width, s->shd_denoise.lg_size[0])/s->shd_denoise.lg_size[0], + FFALIGN(vkctx->output_height, s->shd_denoise.lg_size[1])/s->shd_denoise.lg_size[1], av_pix_fmt_count_planes(s->vkctx.output_format)); return 0; @@ -780,15 +784,15 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) return AVERROR(EINVAL); /* Integral image */ - int_stride = s->pl_weights.wg_size[0]*s->pl_weights_rows*TYPE_SIZE; - int_size = s->pl_weights.wg_size[0]*s->pl_weights_rows*int_stride; + int_stride = s->shd_weights.lg_size[0]*s->pl_weights_rows*TYPE_SIZE; + int_size = s->shd_weights.lg_size[0]*s->pl_weights_rows*int_stride; /* Plane dimensions */ for (int i = 0; i < desc->nb_components; i++) { plane_widths[i] = !i || (i == 3) ? vkctx->output_width : AV_CEIL_RSHIFT(vkctx->output_width, desc->log2_chroma_w); plane_heights[i] = !i || (i == 3) ? vkctx->output_height : AV_CEIL_RSHIFT(vkctx->output_height, desc->log2_chroma_w); - plane_widths[i] = FFALIGN(plane_widths[i], s->pl_denoise.wg_size[0]); - plane_heights[i] = FFALIGN(plane_heights[i], s->pl_denoise.wg_size[1]); + plane_widths[i] = FFALIGN(plane_widths[i], s->shd_denoise.lg_size[0]); + plane_heights[i] = FFALIGN(plane_heights[i], s->shd_denoise.lg_size[1]); ws_stride[i] = plane_widths[i]; ws_size[i] = ws_stride[i] * plane_heights[i] * sizeof(float); @@ -933,35 +937,35 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) ws_vk->access = buf_bar[0].dstAccessMask; /* Update weights descriptors */ - 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_shader_update_img_array(vkctx, exec, &s->shd_weights, in, in_views, 0, 0, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + 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, - ws_vk, weights_offs[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, - ws_vk, sums_offs[i], ws_size[i], - VK_FORMAT_UNDEFINED)); + RET(ff_vk_shader_update_desc_buffer(&s->vkctx, exec, &s->shd_weights, 0, 1 + i*2 + 0, 0, + ws_vk, weights_offs[i], ws_size[i], + VK_FORMAT_UNDEFINED)); + RET(ff_vk_shader_update_desc_buffer(&s->vkctx, exec, &s->shd_weights, 0, 1 + i*2 + 1, 0, + ws_vk, sums_offs[i], ws_size[i], + VK_FORMAT_UNDEFINED)); } /* Update denoise descriptors */ - ff_vk_update_descriptor_img_array(vkctx, &s->pl_denoise, exec, in, in_views, 0, 0, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - s->sampler); - ff_vk_update_descriptor_img_array(vkctx, &s->pl_denoise, exec, out, out_views, 0, 1, - VK_IMAGE_LAYOUT_GENERAL, s->sampler); + ff_vk_shader_update_img_array(vkctx, exec, &s->shd_denoise, in, in_views, 0, 0, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + s->sampler); + ff_vk_shader_update_img_array(vkctx, exec, &s->shd_denoise, out, out_views, 0, 1, + 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, 1, i*2 + 0, 0, - ws_vk, weights_offs[i], ws_size[i], - VK_FORMAT_UNDEFINED)); - RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_denoise, exec, 1, i*2 + 1, 0, - ws_vk, sums_offs[i], ws_size[i], - VK_FORMAT_UNDEFINED)); + RET(ff_vk_shader_update_desc_buffer(&s->vkctx, exec, &s->shd_denoise, 1, i*2 + 0, 0, + ws_vk, weights_offs[i], ws_size[i], + VK_FORMAT_UNDEFINED)); + RET(ff_vk_shader_update_desc_buffer(&s->vkctx, exec, &s->shd_denoise, 1, i*2 + 1, 0, + ws_vk, sums_offs[i], ws_size[i], + VK_FORMAT_UNDEFINED)); } /* Weights pipeline */ - ff_vk_exec_bind_pipeline(vkctx, exec, &s->pl_weights); + ff_vk_exec_bind_shader(vkctx, exec, &s->shd_weights); do { int wg_invoc; @@ -978,8 +982,9 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) }; /* Push data */ - ff_vk_update_push_exec(vkctx, exec, &s->pl_weights, VK_SHADER_STAGE_COMPUTE_BIT, - 0, sizeof(pd), &pd); + ff_vk_shader_update_push_const(vkctx, exec, &s->shd_weights, + VK_SHADER_STAGE_COMPUTE_BIT, + 0, sizeof(pd), &pd); if (offsets_dispatched) { nb_buf_bar = 0; @@ -1044,9 +1049,7 @@ static void nlmeans_vulkan_uninit(AVFilterContext *avctx) FFVulkanFunctions *vk = &vkctx->vkfn; ff_vk_exec_pool_free(vkctx, &s->e); - ff_vk_pipeline_free(vkctx, &s->pl_weights); ff_vk_shader_free(vkctx, &s->shd_weights); - ff_vk_pipeline_free(vkctx, &s->pl_denoise); ff_vk_shader_free(vkctx, &s->shd_denoise); av_buffer_pool_uninit(&s->integral_buf_pool); diff --git a/libavfilter/vf_overlay_vulkan.c b/libavfilter/vf_overlay_vulkan.c index 09444067af..f1ad27167e 100644 --- a/libavfilter/vf_overlay_vulkan.c +++ b/libavfilter/vf_overlay_vulkan.c @@ -32,10 +32,9 @@ typedef struct OverlayVulkanContext { FFFrameSync fs; int initialized; - FFVulkanPipeline pl; FFVkExecPool e; FFVkQueueFamilyCtx qf; - FFVkSPIRVShader shd; + FFVulkanShader shd; VkSampler sampler; /* Push constants / options */ @@ -92,7 +91,7 @@ static av_cold int init_filter(AVFilterContext *ctx) const int planes = av_pix_fmt_count_planes(s->vkctx.output_format); const int ialpha = av_pix_fmt_desc_get(s->vkctx.input_format)->flags & AV_PIX_FMT_FLAG_ALPHA; const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(s->vkctx.output_format); - FFVkSPIRVShader *shd = &s->shd; + FFVulkanShader *shd = &s->shd; FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc; @@ -105,10 +104,11 @@ static av_cold int init_filter(AVFilterContext *ctx) ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT); RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL)); RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST)); - RET(ff_vk_shader_init(&s->pl, &s->shd, "overlay_compute", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); - - ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1); + RET(ff_vk_shader_init(vkctx, &s->shd, "overlay", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 32, 32, 1, + 0)); GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); GLSLC(1, ivec2 o_offset[3]; ); @@ -116,8 +116,8 @@ static av_cold int init_filter(AVFilterContext *ctx) GLSLC(0, }; ); GLSLC(0, ); - ff_vk_add_push_constant(&s->pl, 0, sizeof(s->opts), - VK_SHADER_STAGE_COMPUTE_BIT); + ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts), + VK_SHADER_STAGE_COMPUTE_BIT); desc = (FFVulkanDescriptorSetBinding []) { { @@ -147,7 +147,7 @@ static av_cold int init_filter(AVFilterContext *ctx) }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 3, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 3, 0, 0)); GLSLD( overlay_noalpha ); GLSLD( overlay_alpha ); @@ -165,10 +165,9 @@ static av_cold int init_filter(AVFilterContext *ctx) RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd)); - RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl)); + RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd)); s->opts.o_offset[0] = s->overlay_x; s->opts.o_offset[1] = s->overlay_y; @@ -233,7 +232,7 @@ static int overlay_vulkan_blend(FFFrameSync *fs) goto fail; } - RET(ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->pl, + RET(ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->shd, out, (AVFrame *[]){ input_main, input_overlay }, 2, s->sampler, &s->opts, sizeof(s->opts))); @@ -288,7 +287,6 @@ static void overlay_vulkan_uninit(AVFilterContext *avctx) FFVulkanFunctions *vk = &vkctx->vkfn; ff_vk_exec_pool_free(vkctx, &s->e); - ff_vk_pipeline_free(vkctx, &s->pl); ff_vk_shader_free(vkctx, &s->shd); if (s->sampler) diff --git a/libavfilter/vf_scale_vulkan.c b/libavfilter/vf_scale_vulkan.c index 6a32ebbd5e..e39bc62aa8 100644 --- a/libavfilter/vf_scale_vulkan.c +++ b/libavfilter/vf_scale_vulkan.c @@ -38,10 +38,9 @@ typedef struct ScaleVulkanContext { FFVulkanContext vkctx; int initialized; - FFVulkanPipeline pl; FFVkExecPool e; FFVkQueueFamilyCtx qf; - FFVkSPIRVShader shd; + FFVulkanShader shd; VkSampler sampler; /* Push constants / options */ @@ -118,7 +117,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) VkFilter sampler_mode; ScaleVulkanContext *s = ctx->priv; FFVulkanContext *vkctx = &s->vkctx; - FFVkSPIRVShader *shd = &s->shd; + FFVulkanShader *shd = &s->shd; FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc; @@ -146,18 +145,19 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT); RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL)); RET(ff_vk_init_sampler(vkctx, &s->sampler, 0, sampler_mode)); - RET(ff_vk_shader_init(&s->pl, &s->shd, "scale_compute", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); - - ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1); + RET(ff_vk_shader_init(vkctx, &s->shd, "scale", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 32, 32, 1, + 0)); GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); GLSLC(1, mat4 yuv_matrix; ); GLSLC(0, }; ); GLSLC(0, ); - ff_vk_add_push_constant(&s->pl, 0, sizeof(s->opts), - VK_SHADER_STAGE_COMPUTE_BIT); + ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts), + VK_SHADER_STAGE_COMPUTE_BIT); desc = (FFVulkanDescriptorSetBinding []) { { @@ -179,7 +179,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 2, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0)); GLSLD( scale_bilinear ); @@ -249,10 +249,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd)); - RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl)); + RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd)); s->initialized = 1; @@ -281,7 +280,7 @@ static int scale_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) if (!s->initialized) RET(init_filter(ctx, in)); - RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, out, in, + RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in, s->sampler, &s->opts, sizeof(s->opts))); err = av_frame_copy_props(out, in); @@ -353,7 +352,6 @@ static void scale_vulkan_uninit(AVFilterContext *avctx) FFVulkanFunctions *vk = &vkctx->vkfn; ff_vk_exec_pool_free(vkctx, &s->e); - ff_vk_pipeline_free(vkctx, &s->pl); ff_vk_shader_free(vkctx, &s->shd); if (s->sampler) diff --git a/libavfilter/vf_transpose_vulkan.c b/libavfilter/vf_transpose_vulkan.c index 72ea142e52..c3282339af 100644 --- a/libavfilter/vf_transpose_vulkan.c +++ b/libavfilter/vf_transpose_vulkan.c @@ -32,10 +32,9 @@ typedef struct TransposeVulkanContext { FFVulkanContext vkctx; int initialized; - FFVulkanPipeline pl; FFVkExecPool e; FFVkQueueFamilyCtx qf; - FFVkSPIRVShader shd; + FFVulkanShader shd; VkSampler sampler; int dir; @@ -52,7 +51,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) FFVulkanContext *vkctx = &s->vkctx; const int planes = av_pix_fmt_count_planes(s->vkctx.output_format); - FFVkSPIRVShader *shd = &s->shd; + FFVulkanShader *shd = &s->shd; FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc; @@ -65,10 +64,11 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT); RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL)); RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_LINEAR)); - RET(ff_vk_shader_init(&s->pl, &s->shd, "transpose_compute", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); - - ff_vk_shader_set_compute_sizes(&s->shd, 32, 1, 1); + RET(ff_vk_shader_init(vkctx, &s->shd, "transpose", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 32, 1, 1, + 0)); desc = (FFVulkanDescriptorSetBinding []) { { @@ -90,7 +90,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 2, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0)); GLSLC(0, void main() ); GLSLC(0, { ); @@ -115,10 +115,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in) RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd)); - RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl)); + RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd)); s->initialized = 1; @@ -151,7 +150,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) if (!s->initialized) RET(init_filter(ctx, in)); - RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, out, in, + RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in, s->sampler, NULL, 0)); RET(av_frame_copy_props(out, in)); @@ -180,7 +179,6 @@ static av_cold void transpose_vulkan_uninit(AVFilterContext *avctx) FFVulkanFunctions *vk = &vkctx->vkfn; ff_vk_exec_pool_free(vkctx, &s->e); - ff_vk_pipeline_free(vkctx, &s->pl); ff_vk_shader_free(vkctx, &s->shd); if (s->sampler) diff --git a/libavfilter/vf_xfade_vulkan.c b/libavfilter/vf_xfade_vulkan.c index 94acc5258f..c230f5d833 100644 --- a/libavfilter/vf_xfade_vulkan.c +++ b/libavfilter/vf_xfade_vulkan.c @@ -40,10 +40,9 @@ typedef struct XFadeVulkanContext { int64_t offset; int initialized; - FFVulkanPipeline pl; FFVkExecPool e; FFVkQueueFamilyCtx qf; - FFVkSPIRVShader shd; + FFVulkanShader shd; VkSampler sampler; // PTS when the fade should start (in IN_A timebase) @@ -326,7 +325,7 @@ static av_cold int init_vulkan(AVFilterContext *avctx) XFadeVulkanContext *s = avctx->priv; FFVulkanContext *vkctx = &s->vkctx; const int planes = av_pix_fmt_count_planes(s->vkctx.output_format); - FFVkSPIRVShader *shd = &s->shd; + FFVulkanShader *shd = &s->shd; FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc; @@ -339,10 +338,11 @@ static av_cold int init_vulkan(AVFilterContext *avctx) ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT); RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL)); RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST)); - RET(ff_vk_shader_init(&s->pl, &s->shd, "xfade_compute", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); - - ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1); + RET(ff_vk_shader_init(vkctx, &s->shd, "xfade", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 32, 32, 1, + 0)); desc = (FFVulkanDescriptorSetBinding []) { { @@ -372,14 +372,14 @@ static av_cold int init_vulkan(AVFilterContext *avctx) }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 3, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 3, 0, 0)); GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); GLSLC(1, float progress; ); GLSLC(0, }; ); - ff_vk_add_push_constant(&s->pl, 0, sizeof(XFadeParameters), - VK_SHADER_STAGE_COMPUTE_BIT); + ff_vk_shader_add_push_const(&s->shd, 0, sizeof(XFadeParameters), + VK_SHADER_STAGE_COMPUTE_BIT); // Add the right transition type function to the shader GLSLD(transitions_map[s->transition]); @@ -395,10 +395,9 @@ static av_cold int init_vulkan(AVFilterContext *avctx) RET(spv->compile_shader(spv, avctx, shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd)); - RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl)); + RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd)); s->initialized = 1; @@ -441,7 +440,7 @@ static int xfade_frame(AVFilterContext *avctx, AVFrame *frame_a, AVFrame *frame_ progress = av_clipf((float)(s->pts - s->start_pts) / s->duration_pts, 0.f, 1.f); - RET(ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->pl, output, + RET(ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->shd, output, (AVFrame *[]){ frame_a, frame_b }, 2, s->sampler, &(XFadeParameters){ progress }, sizeof(XFadeParameters))); @@ -632,7 +631,6 @@ static av_cold void uninit(AVFilterContext *avctx) FFVulkanFunctions *vk = &vkctx->vkfn; ff_vk_exec_pool_free(vkctx, &s->e); - ff_vk_pipeline_free(vkctx, &s->pl); ff_vk_shader_free(vkctx, &s->shd); if (s->sampler) diff --git a/libavfilter/vsrc_testsrc_vulkan.c b/libavfilter/vsrc_testsrc_vulkan.c index 77fa9a0ba1..bfef38ce51 100644 --- a/libavfilter/vsrc_testsrc_vulkan.c +++ b/libavfilter/vsrc_testsrc_vulkan.c @@ -39,10 +39,9 @@ typedef struct TestSrcVulkanContext { FFVulkanContext vkctx; int initialized; - FFVulkanPipeline pl; FFVkExecPool e; FFVkQueueFamilyCtx qf; - FFVkSPIRVShader shd; + FFVulkanShader shd; /* Only used by color_vulkan */ uint8_t color_rgba[4]; @@ -72,7 +71,7 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode TestSrcVulkanContext *s = ctx->priv; FFVulkanContext *vkctx = &s->vkctx; const int planes = av_pix_fmt_count_planes(s->vkctx.output_format); - FFVkSPIRVShader *shd = &s->shd; + FFVulkanShader *shd = &s->shd; FFVkSPIRVCompiler *spv; FFVulkanDescriptorSetBinding *desc_set; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->vkctx.output_format); @@ -85,18 +84,19 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT); RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL)); - RET(ff_vk_shader_init(&s->pl, &s->shd, "testsrc_compute", - VK_SHADER_STAGE_COMPUTE_BIT, 0)); - - ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1); + RET(ff_vk_shader_init(vkctx, &s->shd, "scale", + VK_SHADER_STAGE_COMPUTE_BIT, + NULL, 0, + 32, 32, 1, + 0)); GLSLC(0, layout(push_constant, std430) uniform pushConstants { ); GLSLC(1, vec4 color_comp; ); GLSLC(0, }; ); GLSLC(0, ); - ff_vk_add_push_constant(&s->pl, 0, sizeof(s->opts), - VK_SHADER_STAGE_COMPUTE_BIT); + ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts), + VK_SHADER_STAGE_COMPUTE_BIT); desc_set = (FFVulkanDescriptorSetBinding []) { { @@ -110,7 +110,7 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode }, }; - RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc_set, 1, 0, 0)); + RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc_set, 1, 0, 0)); GLSLC(0, void main() ); GLSLC(0, { ); @@ -181,10 +181,9 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main", &spv_opaque)); - RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main")); + RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main")); - RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd)); - RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl)); + RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd)); s->initialized = 1; @@ -229,7 +228,7 @@ static int testsrc_vulkan_activate(AVFilterContext *ctx) if (!s->picref) return AVERROR(ENOMEM); - err = ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, s->picref, NULL, + err = ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, s->picref, NULL, VK_NULL_HANDLE, &s->opts, sizeof(s->opts)); if (err < 0) return err; @@ -248,7 +247,7 @@ static int testsrc_vulkan_activate(AVFilterContext *ctx) frame->pict_type = AV_PICTURE_TYPE_I; frame->sample_aspect_ratio = s->sar; if (!s->draw_once) { - err = ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, frame, NULL, + err = ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, frame, NULL, VK_NULL_HANDLE, &s->opts, sizeof(s->opts)); if (err < 0) { av_frame_free(&frame); @@ -311,7 +310,6 @@ static void testsrc_vulkan_uninit(AVFilterContext *avctx) av_frame_free(&s->picref); ff_vk_exec_pool_free(vkctx, &s->e); - ff_vk_pipeline_free(vkctx, &s->pl); ff_vk_shader_free(vkctx, &s->shd); ff_vk_uninit(&s->vkctx); diff --git a/libavfilter/vulkan_filter.c b/libavfilter/vulkan_filter.c index 2c6ab72849..5cee4572e6 100644 --- a/libavfilter/vulkan_filter.c +++ b/libavfilter/vulkan_filter.c @@ -238,7 +238,7 @@ int ff_vk_filter_init(AVFilterContext *avctx) } int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e, - FFVulkanPipeline *pl, AVFrame *out_f, AVFrame *in_f, + FFVulkanShader *shd, AVFrame *out_f, AVFrame *in_f, VkSampler sampler, void *push_src, size_t push_size) { int err = 0; @@ -256,24 +256,24 @@ int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e, 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); + ff_vk_shader_update_img_array(vkctx, exec, shd, 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, VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT)); RET(ff_vk_create_imageviews(vkctx, exec, in_views, in_f)); - ff_vk_update_descriptor_img_array(vkctx, pl, exec, in_f, in_views, 0, 0, + ff_vk_shader_update_img_array(vkctx, exec, shd, in_f, in_views, 0, 0, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, sampler); } /* Bind pipeline, update push data */ - ff_vk_exec_bind_pipeline(vkctx, exec, pl); + ff_vk_exec_bind_shader(vkctx, exec, shd); if (push_src) - ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT, - 0, push_size, push_src); + ff_vk_shader_update_push_const(vkctx, exec, shd, 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, @@ -297,9 +297,9 @@ int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e, }); 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], - pl->wg_size[2]); + FFALIGN(vkctx->output_width, shd->lg_size[0])/shd->lg_size[0], + FFALIGN(vkctx->output_height, shd->lg_size[1])/shd->lg_size[1], + shd->lg_size[2]); return ff_vk_exec_submit(vkctx, exec); fail: @@ -308,7 +308,7 @@ fail: } int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e, - FFVulkanPipeline *pls[2], + FFVulkanShader *shd_list[2], AVFrame *out, AVFrame *tmp, AVFrame *in, VkSampler sampler, void *push_src, size_t push_size) { @@ -364,30 +364,30 @@ int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e, }); for (int i = 0; i < 2; i++) { - FFVulkanPipeline *pl = pls[i]; + FFVulkanShader *shd = shd_list[i]; AVFrame *src_f = !i ? in : tmp; AVFrame *dst_f = !i ? tmp : out; VkImageView *src_views = !i ? in_views : tmp_views; VkImageView *dst_views = !i ? tmp_views : out_views; - 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, - sampler); - ff_vk_update_descriptor_img_array(vkctx, pl, exec, dst_f, dst_views, 0, 1, - VK_IMAGE_LAYOUT_GENERAL, - VK_NULL_HANDLE); + ff_vk_shader_update_img_array(vkctx, exec, shd, src_f, src_views, 0, 0, + !i ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : + VK_IMAGE_LAYOUT_GENERAL, + sampler); + ff_vk_shader_update_img_array(vkctx, exec, shd, dst_f, dst_views, 0, 1, + VK_IMAGE_LAYOUT_GENERAL, + VK_NULL_HANDLE); /* Bind pipeline, update push data */ - ff_vk_exec_bind_pipeline(vkctx, exec, pl); + ff_vk_exec_bind_shader(vkctx, exec, shd); if (push_src) - ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT, - 0, push_size, push_src); + ff_vk_shader_update_push_const(vkctx, exec, shd, 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], - pl->wg_size[2]); + FFALIGN(vkctx->output_width, shd->lg_size[0])/shd->lg_size[0], + FFALIGN(vkctx->output_height, shd->lg_size[1])/shd->lg_size[1], + shd->lg_size[2]); } return ff_vk_exec_submit(vkctx, exec); @@ -397,7 +397,7 @@ fail: } int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e, - FFVulkanPipeline *pl, + FFVulkanShader *shd, AVFrame *out, AVFrame *in[], int nb_in, VkSampler sampler, void *push_src, size_t push_size) { @@ -425,19 +425,19 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e, } /* 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); + ff_vk_shader_update_img_array(vkctx, exec, shd, 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); + ff_vk_shader_update_img_array(vkctx, exec, shd, 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); + ff_vk_exec_bind_shader(vkctx, exec, shd); if (push_src) - ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT, - 0, push_size, push_src); + ff_vk_shader_update_push_const(vkctx, exec, shd, 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, @@ -461,9 +461,9 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e, }); 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], - pl->wg_size[2]); + FFALIGN(vkctx->output_width, shd->lg_size[0])/shd->lg_size[0], + FFALIGN(vkctx->output_height, shd->lg_size[1])/shd->lg_size[1], + shd->lg_size[2]); return ff_vk_exec_submit(vkctx, exec); fail: diff --git a/libavfilter/vulkan_filter.h b/libavfilter/vulkan_filter.h index d2c14601d9..9f1297e0d2 100644 --- a/libavfilter/vulkan_filter.h +++ b/libavfilter/vulkan_filter.h @@ -43,14 +43,14 @@ int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s, * Submit a compute shader with a zero/one input and single out for execution. */ int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e, - FFVulkanPipeline *pl, AVFrame *out_f, AVFrame *in_f, + FFVulkanShader *shd, AVFrame *out_f, AVFrame *in_f, VkSampler sampler, void *push_src, size_t push_size); /** * Submit a compute shader with a single in and single out with 2 stages. */ int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e, - FFVulkanPipeline *pls[2], + FFVulkanShader *shd_list[2], AVFrame *out, AVFrame *tmp, AVFrame *in, VkSampler sampler, void *push_src, size_t push_size); @@ -58,7 +58,7 @@ int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e, * Up to 16 inputs, one output */ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e, - FFVulkanPipeline *pl, + FFVulkanShader *shd, AVFrame *out, AVFrame *in[], int nb_in, VkSampler sampler, void *push_src, size_t push_size); diff --git a/libavfilter/vulkan_glslang.c b/libavfilter/vulkan_glslang.c index 845a530ee0..3c1b0a8fe6 100644 --- a/libavfilter/vulkan_glslang.c +++ b/libavfilter/vulkan_glslang.c @@ -137,7 +137,7 @@ static const glslang_resource_t glslc_resource_limits = { }; static int glslc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx, - FFVkSPIRVShader *shd, uint8_t **data, + FFVulkanShader *shd, uint8_t **data, size_t *size, const char *entrypoint, void **opaque) { @@ -153,7 +153,7 @@ static int glslc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx, const glslang_input_t glslc_input = { .language = GLSLANG_SOURCE_GLSL, - .stage = glslc_stage[shd->shader.stage], + .stage = glslc_stage[shd->stage], .client = GLSLANG_CLIENT_VULKAN, /* GLSLANG_TARGET_VULKAN_1_2 before 11.6 resulted in targeting 1.0 */ #if (((GLSLANG_VERSION_MAJOR) > 11) || ((GLSLANG_VERSION_MAJOR) == 11 && \ diff --git a/libavfilter/vulkan_shaderc.c b/libavfilter/vulkan_shaderc.c index 9e8a3d17ac..d2bd60e7ef 100644 --- a/libavfilter/vulkan_shaderc.c +++ b/libavfilter/vulkan_shaderc.c @@ -22,7 +22,7 @@ #include "vulkan_spirv.h" static int shdc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx, - FFVkSPIRVShader *shd, uint8_t **data, + FFVulkanShader *shd, uint8_t **data, size_t *size, const char *entrypoint, void **opaque) { @@ -57,7 +57,7 @@ static int shdc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx, res = shaderc_compile_into_spv((shaderc_compiler_t)ctx->priv, shd->src.str, strlen(shd->src.str), - shdc_kind[shd->shader.stage], + shdc_kind[shd->stage], shd->name, entrypoint, opts); shaderc_compile_options_release(opts); diff --git a/libavfilter/vulkan_spirv.h b/libavfilter/vulkan_spirv.h index 5638cd9696..c46c9e52da 100644 --- a/libavfilter/vulkan_spirv.h +++ b/libavfilter/vulkan_spirv.h @@ -27,7 +27,7 @@ typedef struct FFVkSPIRVCompiler { void *priv; int (*compile_shader)(struct FFVkSPIRVCompiler *ctx, void *avctx, - struct FFVkSPIRVShader *shd, uint8_t **data, + struct FFVulkanShader *shd, uint8_t **data, size_t *size, const char *entrypoint, void **opaque); void (*free_shader)(struct FFVkSPIRVCompiler *ctx, void **opaque); void (*uninit)(struct FFVkSPIRVCompiler **ctx); diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c index 046ac5d67e..9ea9e478df 100644 --- a/libavutil/vulkan.c +++ b/libavutil/vulkan.c @@ -1191,17 +1191,18 @@ int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVBufferPool **buf_pool, return 0; } -int ff_vk_add_push_constant(FFVulkanPipeline *pl, int offset, int size, - VkShaderStageFlagBits stage) +int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, + VkShaderStageFlagBits stage) { VkPushConstantRange *pc; - pl->push_consts = av_realloc_array(pl->push_consts, sizeof(*pl->push_consts), - pl->push_consts_num + 1); - if (!pl->push_consts) + shd->push_consts = av_realloc_array(shd->push_consts, + sizeof(*shd->push_consts), + shd->push_consts_num + 1); + if (!shd->push_consts) return AVERROR(ENOMEM); - pc = &pl->push_consts[pl->push_consts_num++]; + pc = &shd->push_consts[shd->push_consts_num++]; memset(pc, 0, sizeof(*pc)); pc->stageFlags = stage; @@ -1397,44 +1398,79 @@ void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, ff_vk_exec_update_frame(s, e, pic, &bar[*nb_bar - nb_images], NULL); } -int ff_vk_shader_init(FFVulkanPipeline *pl, FFVkSPIRVShader *shd, const char *name, - VkShaderStageFlags stage, uint32_t required_subgroup_size) +int ff_vk_shader_init(FFVulkanContext *s, FFVulkanShader *shd, const char *name, + VkPipelineStageFlags stage, + const char *extensions[], int nb_extensions, + int lg_x, int lg_y, int lg_z, + uint32_t required_subgroup_size) { av_bprint_init(&shd->src, 0, AV_BPRINT_SIZE_UNLIMITED); - shd->shader.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; - shd->shader.stage = stage; + shd->name = name; + shd->stage = stage; + shd->lg_size[0] = lg_x; + shd->lg_size[1] = lg_y; + shd->lg_size[2] = lg_z; + + switch (shd->stage) { + case VK_SHADER_STAGE_ANY_HIT_BIT_KHR: + case VK_SHADER_STAGE_CALLABLE_BIT_KHR: + case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR: + case VK_SHADER_STAGE_INTERSECTION_BIT_KHR: + case VK_SHADER_STAGE_MISS_BIT_KHR: + case VK_SHADER_STAGE_RAYGEN_BIT_KHR: + shd->bind_point = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR; + break; + case VK_SHADER_STAGE_COMPUTE_BIT: + shd->bind_point = VK_PIPELINE_BIND_POINT_COMPUTE; + break; + default: + shd->bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS; + break; + }; if (required_subgroup_size) { - shd->shader.flags |= VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT; - shd->shader.pNext = &shd->subgroup_info; shd->subgroup_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO; shd->subgroup_info.requiredSubgroupSize = required_subgroup_size; } - shd->name = name; - + av_bprintf(&shd->src, "/* %s shader: %s */\n", + (stage == VK_SHADER_STAGE_TASK_BIT_EXT || + stage == VK_SHADER_STAGE_MESH_BIT_EXT) ? + "Mesh" : + (shd->bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR) ? + "Raytrace" : + (shd->bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) ? + "Compute" : "Graphics", + name); GLSLF(0, #version %i ,460); + GLSLC(0, ); + + /* Common utilities */ GLSLC(0, #define IS_WITHIN(v1, v2) ((v1.x < v2.x) && (v1.y < v2.y)) ); GLSLC(0, ); - GLSLC(0, #extension GL_EXT_buffer_reference : require ); - GLSLC(0, #extension GL_EXT_buffer_reference2 : require ); - return 0; -} + if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) { + GLSLC(0, #extension GL_EXT_buffer_reference : require ); + GLSLC(0, #extension GL_EXT_buffer_reference2 : require ); + } -void ff_vk_shader_set_compute_sizes(FFVkSPIRVShader *shd, int x, int y, int z) -{ - shd->local_size[0] = x; - shd->local_size[1] = y; - shd->local_size[2] = z; + if (stage == VK_SHADER_STAGE_TASK_BIT_EXT || + stage == VK_SHADER_STAGE_MESH_BIT_EXT) + GLSLC(0, #extension GL_EXT_mesh_shader : require ); - av_bprintf(&shd->src, "layout (local_size_x = %i, " - "local_size_y = %i, local_size_z = %i) in;\n\n", - shd->local_size[0], shd->local_size[1], shd->local_size[2]); + for (int i = 0; i < nb_extensions; i++) + GLSLF(0, #extension %s : %s ,extensions[i], "require"); + GLSLC(0, ); + + GLSLF(0, layout (local_size_x = %i, local_size_y = %i, local_size_z = %i) in; + , shd->lg_size[0], shd->lg_size[1], shd->lg_size[2]); + GLSLC(0, ); + + return 0; } -void ff_vk_shader_print(void *ctx, FFVkSPIRVShader *shd, int prio) +void ff_vk_shader_print(void *ctx, FFVulkanShader *shd, int prio) { int line = 0; const char *p = shd->src.str; @@ -1456,37 +1492,86 @@ void ff_vk_shader_print(void *ctx, FFVkSPIRVShader *shd, int prio) av_bprint_finalize(&buf, NULL); } -void ff_vk_shader_free(FFVulkanContext *s, FFVkSPIRVShader *shd) +static int init_pipeline_layout(FFVulkanContext *s, FFVulkanShader *shd) { + VkResult ret; FFVulkanFunctions *vk = &s->vkfn; - av_bprint_finalize(&shd->src, NULL); + VkPipelineLayoutCreateInfo pipeline_layout_info; - if (shd->shader.module) - vk->DestroyShaderModule(s->hwctx->act_dev, shd->shader.module, s->hwctx->alloc); + /* Finally create the pipeline layout */ + pipeline_layout_info = (VkPipelineLayoutCreateInfo) { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pSetLayouts = shd->desc_layout, + .setLayoutCount = shd->nb_descriptor_sets, + .pushConstantRangeCount = shd->push_consts_num, + .pPushConstantRanges = shd->push_consts, + }; + + ret = vk->CreatePipelineLayout(s->hwctx->act_dev, &pipeline_layout_info, + s->hwctx->alloc, &shd->pipeline_layout); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to init pipeline layout: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + return 0; } -int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd, - uint8_t *spirv, size_t spirv_size, const char *entrypoint) +static int create_shader_module(FFVulkanContext *s, FFVulkanShader *shd, + VkShaderModule *mod, + uint8_t *spirv, size_t spirv_len) { VkResult ret; FFVulkanFunctions *vk = &s->vkfn; - VkShaderModuleCreateInfo shader_create; - shd->shader.pName = entrypoint; + VkShaderModuleCreateInfo shader_module_info = { + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .pNext = NULL, + .flags = 0x0, + .pCode = (void *)spirv, + .codeSize = spirv_len, + }; - av_log(s, AV_LOG_VERBOSE, "Shader %s compiled! Size: %zu bytes\n", - shd->name, spirv_size); + ret = vk->CreateShaderModule(s->hwctx->act_dev, &shader_module_info, + s->hwctx->alloc, mod); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_VERBOSE, "Error creating shader module: %s\n", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } - shader_create.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - shader_create.pNext = NULL; - shader_create.codeSize = spirv_size; - shader_create.flags = 0; - shader_create.pCode = (void *)spirv; + return 0; +} - ret = vk->CreateShaderModule(s->hwctx->act_dev, &shader_create, NULL, - &shd->shader.module); +static int init_compute_pipeline(FFVulkanContext *s, FFVulkanShader *shd, + VkShaderModule mod, const char *entrypoint) +{ + VkResult ret; + FFVulkanFunctions *vk = &s->vkfn; + + VkComputePipelineCreateInfo pipeline_create_info = { + .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + .flags = (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) ? + VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT : 0x0, + .layout = shd->pipeline_layout, + .stage = (VkPipelineShaderStageCreateInfo) { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = shd->subgroup_info.requiredSubgroupSize ? + &shd->subgroup_info : NULL, + .pName = entrypoint, + .flags = shd->subgroup_info.requiredSubgroupSize ? + VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT : 0x0, + .stage = shd->stage, + .module = mod, + }, + }; + + ret = vk->CreateComputePipelines(s->hwctx->act_dev, VK_NULL_HANDLE, 1, + &pipeline_create_info, + s->hwctx->alloc, &shd->pipeline); if (ret != VK_SUCCESS) { - av_log(s, AV_LOG_VERBOSE, "Error creating shader module: %s\n", + av_log(s, AV_LOG_ERROR, "Unable to init compute pipeline: %s\n", ff_vk_ret2str(ret)); return AVERROR_EXTERNAL; } @@ -1494,6 +1579,110 @@ int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd, return 0; } +static int init_descriptors(FFVulkanContext *s, FFVulkanShader *shd) +{ + VkResult ret; + FFVulkanFunctions *vk = &s->vkfn; + + shd->desc_layout = av_malloc_array(shd->nb_descriptor_sets, + sizeof(*shd->desc_layout)); + if (!shd->desc_layout) + return AVERROR(ENOMEM); + + if (!(s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER)) { + int has_singular = 0; + for (int i = 0; i < shd->nb_descriptor_sets; i++) { + if (shd->desc_set[i].singular) { + has_singular = 1; + break; + } + } + shd->use_push = (s->extensions & FF_VK_EXT_PUSH_DESCRIPTOR) && + (shd->nb_descriptor_sets == 1) && + !has_singular; + } + + for (int i = 0; i < shd->nb_descriptor_sets; i++) { + FFVulkanDescriptorSet *set = &shd->desc_set[i]; + VkDescriptorSetLayoutCreateInfo desc_layout_create = { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .bindingCount = set->nb_bindings, + .pBindings = set->binding, + .flags = (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) ? + VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT : + (shd->use_push) ? + VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR : + 0x0, + }; + + ret = vk->CreateDescriptorSetLayout(s->hwctx->act_dev, + &desc_layout_create, + s->hwctx->alloc, + &shd->desc_layout[i]); + if (ret != VK_SUCCESS) { + av_log(s, AV_LOG_ERROR, "Unable to create descriptor set layout: %s", + ff_vk_ret2str(ret)); + return AVERROR_EXTERNAL; + } + + if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) { + vk->GetDescriptorSetLayoutSizeEXT(s->hwctx->act_dev, shd->desc_layout[i], + &set->layout_size); + + set->aligned_size = FFALIGN(set->layout_size, + s->desc_buf_props.descriptorBufferOffsetAlignment); + + for (int j = 0; j < set->nb_bindings; j++) + vk->GetDescriptorSetLayoutBindingOffsetEXT(s->hwctx->act_dev, + shd->desc_layout[i], + j, + &set->binding_offset[j]); + } + } + + return 0; +} + +int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, + uint8_t *spirv, size_t spirv_len, + const char *entrypoint) +{ + int err; + FFVulkanFunctions *vk = &s->vkfn; + + err = init_descriptors(s, shd); + if (err < 0) + return err; + + err = init_pipeline_layout(s, shd); + if (err < 0) + return err; + + { + VkShaderModule mod; + err = create_shader_module(s, shd, &mod, spirv, spirv_len); + if (err < 0) + return err; + + switch (shd->bind_point) { + case VK_PIPELINE_BIND_POINT_COMPUTE: + err = init_compute_pipeline(s, shd, mod, entrypoint); + break; + default: + av_log(s, AV_LOG_ERROR, "Unsupported shader type: %i\n", + shd->bind_point); + err = AVERROR(EINVAL); + break; + }; + + vk->DestroyShaderModule(s->hwctx->act_dev, mod, s->hwctx->alloc); + if (err < 0) + return err; + } + + return 0; +} + static const struct descriptor_props { size_t struct_size; /* Size of the opaque which updates the descriptor */ const char *type; @@ -1515,10 +1704,9 @@ static const struct descriptor_props { [VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER] = { sizeof(VkBufferView), "imageBuffer", 1, 0, 0, 0, }, }; -int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl, - FFVkSPIRVShader *shd, - FFVulkanDescriptorSetBinding *desc, int nb, - int singular, int print_to_shader_only) +int ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, + FFVulkanDescriptorSetBinding *desc, int nb, + int singular, int print_to_shader_only) { int has_sampler = 0; FFVulkanDescriptorSet *set; @@ -1527,13 +1715,14 @@ int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl, goto print; /* Actual layout allocated for the pipeline */ - set = av_realloc_array(pl->desc_set, sizeof(*pl->desc_set), - pl->nb_descriptor_sets + 1); + set = av_realloc_array(shd->desc_set, + sizeof(*shd->desc_set), + shd->nb_descriptor_sets + 1); if (!set) return AVERROR(ENOMEM); - pl->desc_set = set; + shd->desc_set = set; - set = &set[pl->nb_descriptor_sets]; + set = &set[shd->nb_descriptor_sets]; memset(set, 0, sizeof(*set)); set->binding = av_calloc(nb, sizeof(*set->binding)); @@ -1567,34 +1756,34 @@ int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl, 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) + for (j = 0; j < shd->nb_desc_pool_size; j++) + if (shd->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, + if (j >= shd->nb_desc_pool_size) { + desc_pool_size = av_realloc_array(shd->desc_pool_size, sizeof(*desc_pool_size), - pl->nb_desc_pool_size + 1); + shd->nb_desc_pool_size + 1); if (!desc_pool_size) return AVERROR(ENOMEM); - pl->desc_pool_size = desc_pool_size; - pl->nb_desc_pool_size++; + shd->desc_pool_size = desc_pool_size; + shd->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); + shd->desc_pool_size[j].type = desc[i].type; + shd->desc_pool_size[j].descriptorCount += FFMAX(desc[i].elems, 1); } } set->singular = singular; set->nb_bindings = nb; - pl->nb_descriptor_sets++; + shd->nb_descriptor_sets++; print: /* Write shader info */ for (int i = 0; i < nb; i++) { const struct descriptor_props *prop = &descriptor_props[desc[i].type]; - GLSLA("layout (set = %i, binding = %i", pl->nb_descriptor_sets - 1, i); + GLSLA("layout (set = %i, binding = %i", shd->nb_descriptor_sets - 1, i); if (desc[i].mem_layout) GLSLA(", %s", desc[i].mem_layout); @@ -1627,26 +1816,26 @@ print: return 0; } -int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool, - FFVulkanPipeline *pl) +int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, + FFVulkanShader *shd) { int err; - if (!pl->nb_descriptor_sets) + if (!shd->nb_descriptor_sets) return 0; 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) + shd->desc_bind = av_calloc(shd->nb_descriptor_sets, sizeof(*shd->desc_bind)); + if (!shd->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) + shd->bound_buffer_indices = av_calloc(shd->nb_descriptor_sets, + sizeof(*shd->bound_buffer_indices)); + if (!shd->bound_buffer_indices) return AVERROR(ENOMEM); - for (int i = 0; i < pl->nb_descriptor_sets; i++) { - FFVulkanDescriptorSet *set = &pl->desc_set[i]; + for (int i = 0; i < shd->nb_descriptor_sets; i++) { + FFVulkanDescriptorSet *set = &shd->desc_set[i]; int nb = set->singular ? 1 : pool->pool_size; err = ff_vk_create_buf(s, &set->buf, set->aligned_size*nb, @@ -1661,34 +1850,34 @@ int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool, if (err < 0) return err; - pl->desc_bind[i] = (VkDescriptorBufferBindingInfoEXT) { + shd->desc_bind[i] = (VkDescriptorBufferBindingInfoEXT) { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT, .usage = set->usage, .address = set->buf.address, }; - pl->bound_buffer_indices[i] = i; + shd->bound_buffer_indices[i] = i; } - } else if (!pl->use_push) { + } else if (!shd->use_push) { 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; + for (int i = 0; i < shd->nb_desc_pool_size; i++) + shd->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, + .pPoolSizes = shd->desc_pool_size, + .poolSizeCount = shd->nb_desc_pool_size, + .maxSets = shd->nb_descriptor_sets*pool->pool_size, }; ret = vk->CreateDescriptorPool(s->hwctx->act_dev, &pool_create_info, - s->hwctx->alloc, &pl->desc_pool); + s->hwctx->alloc, &shd->desc_pool); if (ret != VK_SUCCESS) { av_log(s, AV_LOG_ERROR, "Unable to create descriptor pool: %s\n", ff_vk_ret2str(ret)); @@ -1701,33 +1890,33 @@ int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool, /* 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]; + for (int j = 0; j < shd->nb_descriptor_sets; j++) + tmp_layouts[i*shd->nb_descriptor_sets + j] = shd->desc_layout[j]; set_alloc_info = (VkDescriptorSetAllocateInfo) { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .descriptorPool = pl->desc_pool, + .descriptorPool = shd->desc_pool, .pSetLayouts = tmp_layouts, .descriptorSetCount = pool_create_info.maxSets, }; - pl->desc_sets = av_malloc_array(pool_create_info.maxSets, + shd->desc_sets = av_malloc_array(pool_create_info.maxSets, sizeof(*tmp_layouts)); - if (!pl->desc_sets) { + if (!shd->desc_sets) { av_free(tmp_layouts); return AVERROR(ENOMEM); } ret = vk->AllocateDescriptorSets(s->hwctx->act_dev, &set_alloc_info, - pl->desc_sets); + shd->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); + av_freep(&shd->desc_sets); return AVERROR_EXTERNAL; } - pl->assoc_pool = pool; + shd->assoc_pool = pool; } return 0; @@ -1749,38 +1938,37 @@ 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, +static inline void update_set_pool_write(FFVulkanContext *s, FFVulkanShader *shd, 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]; + for (int i = 0; i < shd->assoc_pool->pool_size; i++) { + write_info->dstSet = shd->desc_sets[i*shd->nb_descriptor_sets + set]; vk->UpdateDescriptorSets(s->hwctx->act_dev, 1, write_info, 0, NULL); } } else { - if (pl->use_push) { + if (shd->use_push) { vk->CmdPushDescriptorSetKHR(e->buf, - pl->bind_point, - pl->pipeline_layout, + shd->bind_point, + shd->pipeline_layout, set, 1, write_info); } else { - write_info->dstSet = pl->desc_sets[e->idx*pl->nb_descriptor_sets + set]; + write_info->dstSet = shd->desc_sets[e->idx*shd->nb_descriptor_sets + set]; vk->UpdateDescriptorSets(s->hwctx->act_dev, 1, write_info, 0, NULL); } } } -static int vk_set_descriptor_image(FFVulkanContext *s, FFVulkanPipeline *pl, +static int vk_set_descriptor_image(FFVulkanContext *s, FFVulkanShader *shd, FFVkExecContext *e, int set, int bind, int offs, VkImageView view, VkImageLayout layout, VkSampler sampler) { - FFVulkanDescriptorSet *desc_set = &pl->desc_set[set]; + FFVulkanDescriptorSet *desc_set = &shd->desc_set[set]; if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) { VkDescriptorGetInfoEXT desc_get_info = { @@ -1834,18 +2022,19 @@ static int vk_set_descriptor_image(FFVulkanContext *s, FFVulkanPipeline *pl, .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); + update_set_pool_write(s, shd, 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 elem, - FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, - VkFormat fmt) +int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e, + FFVulkanShader *shd, + int set, int bind, int elem, + FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, + VkFormat fmt) { - FFVulkanDescriptorSet *desc_set = &pl->desc_set[set]; + FFVulkanDescriptorSet *desc_set = &shd->desc_set[set]; if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) { VkDescriptorGetInfoEXT desc_get_info = { @@ -1899,208 +2088,84 @@ int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl, .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); + update_set_pool_write(s, shd, e, desc_set, set, &desc_pool_write_info); } return 0; } -void ff_vk_update_descriptor_img_array(FFVulkanContext *s, FFVulkanPipeline *pl, - FFVkExecContext *e, AVFrame *f, - VkImageView *views, int set, int binding, - VkImageLayout layout, VkSampler sampler) +void ff_vk_shader_update_img_array(FFVulkanContext *s, FFVkExecContext *e, + FFVulkanShader *shd, AVFrame *f, + VkImageView *views, int set, int binding, + VkImageLayout layout, VkSampler sampler) { AVHWFramesContext *hwfc = (AVHWFramesContext *)f->hw_frames_ctx->data; const int nb_planes = av_pix_fmt_count_planes(hwfc->sw_format); for (int i = 0; i < nb_planes; i++) - vk_set_descriptor_image(s, pl, e, set, binding, i, + vk_set_descriptor_image(s, shd, e, set, binding, i, views[i], layout, sampler); } -void ff_vk_update_push_exec(FFVulkanContext *s, FFVkExecContext *e, - FFVulkanPipeline *pl, - VkShaderStageFlagBits stage, - int offset, size_t size, void *src) +void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e, + FFVulkanShader *shd, + VkShaderStageFlagBits stage, + int offset, size_t size, void *src) { FFVulkanFunctions *vk = &s->vkfn; - vk->CmdPushConstants(e->buf, pl->pipeline_layout, + vk->CmdPushConstants(e->buf, shd->pipeline_layout, stage, offset, size, src); } -static int init_descriptors(FFVulkanContext *s, FFVulkanPipeline *pl) -{ - VkResult ret; - FFVulkanFunctions *vk = &s->vkfn; - - pl->desc_layout = av_malloc_array(pl->nb_descriptor_sets, - sizeof(*pl->desc_layout)); - if (!pl->desc_layout) - return AVERROR(ENOMEM); - - if (!(s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER)) { - int has_singular = 0; - for (int i = 0; i < pl->nb_descriptor_sets; i++) { - if (pl->desc_set[i].singular) { - has_singular = 1; - break; - } - } - pl->use_push = (s->extensions & FF_VK_EXT_PUSH_DESCRIPTOR) && - (pl->nb_descriptor_sets == 1) && - !has_singular; - } - - for (int i = 0; i < pl->nb_descriptor_sets; i++) { - FFVulkanDescriptorSet *set = &pl->desc_set[i]; - VkDescriptorSetLayoutCreateInfo desc_layout_create = { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .bindingCount = set->nb_bindings, - .pBindings = set->binding, - .flags = (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) ? - VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT : - (pl->use_push) ? - VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR : - 0x0, - }; - - ret = vk->CreateDescriptorSetLayout(s->hwctx->act_dev, - &desc_layout_create, - s->hwctx->alloc, - &pl->desc_layout[i]); - if (ret != VK_SUCCESS) { - av_log(s, AV_LOG_ERROR, "Unable to create descriptor set layout: %s", - ff_vk_ret2str(ret)); - return AVERROR_EXTERNAL; - } - - if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) { - vk->GetDescriptorSetLayoutSizeEXT(s->hwctx->act_dev, pl->desc_layout[i], - &set->layout_size); - - set->aligned_size = FFALIGN(set->layout_size, - s->desc_buf_props.descriptorBufferOffsetAlignment); - - for (int j = 0; j < set->nb_bindings; j++) - vk->GetDescriptorSetLayoutBindingOffsetEXT(s->hwctx->act_dev, - pl->desc_layout[i], - j, - &set->binding_offset[j]); - } - } - - return 0; -} - -static int init_pipeline_layout(FFVulkanContext *s, FFVulkanPipeline *pl) -{ - VkResult ret; - FFVulkanFunctions *vk = &s->vkfn; - VkPipelineLayoutCreateInfo pipeline_layout_info; - - /* Finally create the pipeline layout */ - pipeline_layout_info = (VkPipelineLayoutCreateInfo) { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .pSetLayouts = pl->desc_layout, - .setLayoutCount = pl->nb_descriptor_sets, - .pushConstantRangeCount = pl->push_consts_num, - .pPushConstantRanges = pl->push_consts, - }; - - ret = vk->CreatePipelineLayout(s->hwctx->act_dev, &pipeline_layout_info, - s->hwctx->alloc, &pl->pipeline_layout); - if (ret != VK_SUCCESS) { - av_log(s, AV_LOG_ERROR, "Unable to init pipeline layout: %s\n", - ff_vk_ret2str(ret)); - return AVERROR_EXTERNAL; - } - - return 0; -} - -int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl, - FFVkSPIRVShader *shd) -{ - int err; - VkResult ret; - FFVulkanFunctions *vk = &s->vkfn; - - VkComputePipelineCreateInfo pipeline_create_info; - - err = init_descriptors(s, pl); - if (err < 0) - return err; - - err = init_pipeline_layout(s, pl); - if (err < 0) - return err; - - pipeline_create_info = (VkComputePipelineCreateInfo) { - .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, - .flags = (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) ? - VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT : 0x0, - .layout = pl->pipeline_layout, - .stage = shd->shader, - }; - - ret = vk->CreateComputePipelines(s->hwctx->act_dev, VK_NULL_HANDLE, 1, - &pipeline_create_info, - s->hwctx->alloc, &pl->pipeline); - if (ret != VK_SUCCESS) { - av_log(s, AV_LOG_ERROR, "Unable to init compute pipeline: %s\n", - ff_vk_ret2str(ret)); - return AVERROR_EXTERNAL; - } - - pl->bind_point = VK_PIPELINE_BIND_POINT_COMPUTE; - pl->wg_size[0] = shd->local_size[0]; - pl->wg_size[1] = shd->local_size[1]; - pl->wg_size[2] = shd->local_size[2]; - - return 0; -} - -void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e, - FFVulkanPipeline *pl) +void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, + FFVulkanShader *shd) { FFVulkanFunctions *vk = &s->vkfn; VkDeviceSize offsets[1024]; /* Bind pipeline */ - vk->CmdBindPipeline(e->buf, pl->bind_point, pl->pipeline); + vk->CmdBindPipeline(e->buf, shd->bind_point, shd->pipeline); - if (pl->nb_descriptor_sets) { + if (shd->nb_descriptor_sets) { 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; + for (int i = 0; i < shd->nb_descriptor_sets; i++) + offsets[i] = shd->desc_set[i].singular ? 0 : shd->desc_set[i].aligned_size*e->idx; /* Bind descriptor buffers */ - vk->CmdBindDescriptorBuffersEXT(e->buf, pl->nb_descriptor_sets, pl->desc_bind); + vk->CmdBindDescriptorBuffersEXT(e->buf, shd->nb_descriptor_sets, shd->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 if (!pl->use_push) { - vk->CmdBindDescriptorSets(e->buf, pl->bind_point, pl->pipeline_layout, - 0, pl->nb_descriptor_sets, - &pl->desc_sets[e->idx*pl->nb_descriptor_sets], + vk->CmdSetDescriptorBufferOffsetsEXT(e->buf, shd->bind_point, shd->pipeline_layout, + 0, shd->nb_descriptor_sets, + shd->bound_buffer_indices, offsets); + } else if (!shd->use_push) { + vk->CmdBindDescriptorSets(e->buf, shd->bind_point, shd->pipeline_layout, + 0, shd->nb_descriptor_sets, + &shd->desc_sets[e->idx*shd->nb_descriptor_sets], 0, NULL); } } } -void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl) +void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd) { FFVulkanFunctions *vk = &s->vkfn; - if (pl->pipeline) - vk->DestroyPipeline(s->hwctx->act_dev, pl->pipeline, s->hwctx->alloc); - if (pl->pipeline_layout) - vk->DestroyPipelineLayout(s->hwctx->act_dev, pl->pipeline_layout, + av_bprint_finalize(&shd->src, NULL); + +#if 0 + if (shd->shader.module) + vk->DestroyShaderModule(s->hwctx->act_dev, shd->shader.module, + s->hwctx->alloc); +#endif + + if (shd->pipeline) + vk->DestroyPipeline(s->hwctx->act_dev, shd->pipeline, s->hwctx->alloc); + if (shd->pipeline_layout) + vk->DestroyPipelineLayout(s->hwctx->act_dev, shd->pipeline_layout, s->hwctx->alloc); - for (int i = 0; i < pl->nb_descriptor_sets; i++) { - FFVulkanDescriptorSet *set = &pl->desc_set[i]; + for (int i = 0; i < shd->nb_descriptor_sets; i++) { + FFVulkanDescriptorSet *set = &shd->desc_set[i]; if (set->buf.mem) ff_vk_unmap_buffer(s, &set->buf, 0); ff_vk_free_buf(s, &set->buf); @@ -2108,23 +2173,23 @@ void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl) 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], + for (int i = 0; i < shd->nb_descriptor_sets; i++) + if (shd->desc_layout[i]) + vk->DestroyDescriptorSetLayout(s->hwctx->act_dev, shd->desc_layout[i], s->hwctx->alloc); - if (pl->desc_pool) - vk->DestroyDescriptorPool(s->hwctx->act_dev, pl->desc_pool, + if (shd->desc_pool) + vk->DestroyDescriptorPool(s->hwctx->act_dev, shd->desc_pool, s->hwctx->alloc); - av_freep(&pl->desc_pool_size); - av_freep(&pl->desc_layout); - av_freep(&pl->desc_sets); - av_freep(&pl->desc_set); - av_freep(&pl->desc_bind); - av_freep(&pl->bound_buffer_indices); - av_freep(&pl->push_consts); - pl->push_consts_num = 0; + av_freep(&shd->desc_pool_size); + av_freep(&shd->desc_layout); + av_freep(&shd->desc_sets); + av_freep(&shd->desc_set); + av_freep(&shd->desc_bind); + av_freep(&shd->bound_buffer_indices); + av_freep(&shd->push_consts); + shd->push_consts_num = 0; } void ff_vk_uninit(FFVulkanContext *s) diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h index e03fd702ca..9c87dd29cf 100644 --- a/libavutil/vulkan.h +++ b/libavutil/vulkan.h @@ -72,14 +72,6 @@ #define DUP_SAMPLER(x) { x, x, x, x } -typedef struct FFVkSPIRVShader { - const char *name; /* Name for id/debugging purposes */ - AVBPrint src; - int local_size[3]; /* Compute shader workgroup sizes */ - VkPipelineShaderStageCreateInfo shader; - VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_info; -} FFVkSPIRVShader; - typedef struct FFVulkanDescriptorSetBinding { const char *name; VkDescriptorType type; @@ -204,20 +196,35 @@ typedef struct FFVulkanDescriptorSet { int singular; } FFVulkanDescriptorSet; -typedef struct FFVulkanPipeline { +typedef struct FFVulkanShader { + /* Name for id/debugging purposes */ + const char *name; + + /* Shader text */ + AVBPrint src; + + /* Compute shader local group sizes */ + int lg_size[3]; + + /* Shader bind point/type */ + VkPipelineStageFlags stage; VkPipelineBindPoint bind_point; - /* Contexts */ + /* Creation info */ + VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_info; + + /* Base shader object */ + union { + VkPipeline pipeline; + }; + + /* Pipeline layout */ 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; @@ -233,7 +240,7 @@ typedef struct FFVulkanPipeline { int nb_desc_pool_size; int total_desc_sets; FFVkExecPool *assoc_pool; -} FFVulkanPipeline; +} FFVulkanShader; typedef struct FFVulkanContext { const AVClass *class; @@ -472,59 +479,86 @@ int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler, int unnorm_coords, VkFilter filt); /** - * Shader management. + * Initialize a shader object, with a specific set of extensions, type+bind, + * local group size, and subgroup requirements. */ -int ff_vk_shader_init(FFVulkanPipeline *pl, FFVkSPIRVShader *shd, const char *name, - VkShaderStageFlags stage, uint32_t required_subgroup_size); -void ff_vk_shader_set_compute_sizes(FFVkSPIRVShader *shd, int x, int y, int z); -void ff_vk_shader_print(void *ctx, FFVkSPIRVShader *shd, int prio); -int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd, - uint8_t *spirv, size_t spirv_size, const char *entrypoint); -void ff_vk_shader_free(FFVulkanContext *s, FFVkSPIRVShader *shd); +int ff_vk_shader_init(FFVulkanContext *s, FFVulkanShader *shd, const char *name, + VkPipelineStageFlags stage, + const char *extensions[], int nb_extensions, + int lg_x, int lg_y, int lg_z, + uint32_t required_subgroup_size); /** - * Add/update push constants for execution. + * Output the shader code as logging data, with a specific + * priority. */ -int ff_vk_add_push_constant(FFVulkanPipeline *pl, int offset, int size, - VkShaderStageFlagBits stage); -void ff_vk_update_push_exec(FFVulkanContext *s, FFVkExecContext *e, - FFVulkanPipeline *pl, - VkShaderStageFlagBits stage, - int offset, size_t size, void *src); +void ff_vk_shader_print(void *ctx, FFVulkanShader *shd, int prio); /** - * Add descriptor to a pipeline. Must be called before pipeline init. + * Link a shader into an executable. */ -int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl, - FFVkSPIRVShader *shd, - FFVulkanDescriptorSetBinding *desc, int nb, - int singular, int print_to_shader_only); +int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, + uint8_t *spirv, size_t spirv_len, + const char *entrypoint); -/* Initialize/free a pipeline. */ -int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl, - FFVkSPIRVShader *shd); -void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl); +/** + * Add/update push constants for execution. + */ +int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, + VkShaderStageFlagBits stage); /** - * Register a pipeline with an exec pool. + * Add descriptor to a shader. Must be called before shader init. + */ +int ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, + FFVulkanDescriptorSetBinding *desc, int nb, + int singular, int print_to_shader_only); + +/** + * Register a shader with an exec pool. * Pool may be NULL if all descriptor sets are read-only. */ -int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool, - FFVulkanPipeline *pl); - -/* Bind pipeline */ -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 elem, - FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, - VkFormat fmt); - -void ff_vk_update_descriptor_img_array(FFVulkanContext *s, FFVulkanPipeline *pl, - FFVkExecContext *e, AVFrame *f, - VkImageView *views, int set, int binding, - VkImageLayout layout, VkSampler sampler); +int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, + FFVulkanShader *shd); + +/** + * Bind a shader. + */ +void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, + FFVulkanShader *shd); + +/** + * Update push constant in a shader. + * Must be called before binding the shader. + */ +void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e, + FFVulkanShader *shd, + VkShaderStageFlagBits stage, + int offset, size_t size, void *src); + +/** + * Update a descriptor in a buffer with a buffer. + * Must be called before binding the shader. + */ +int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e, + FFVulkanShader *shd, + int set, int bind, int elem, + FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, + VkFormat fmt); + +/** + * Update a descriptor in a buffer with an image array.. + * Must be called before binding the shader. + */ +void ff_vk_shader_update_img_array(FFVulkanContext *s, FFVkExecContext *e, + FFVulkanShader *shd, AVFrame *f, + VkImageView *views, int set, int binding, + VkImageLayout layout, VkSampler sampler); + +/** + * Free a shader. + */ +void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd); /** * Frees main context.