Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Niklas Haas <ffmpeg@haasn.xyz>
To: ffmpeg-devel@ffmpeg.org
Cc: Niklas Haas <git@haasn.dev>
Subject: [FFmpeg-devel] [PATCH v2] lavfi/vf_libplacebo: add vulkan device import fallback
Date: Thu, 11 May 2023 10:39:02 +0200
Message-ID: <20230511083902.7262-1-ffmpeg@haasn.xyz> (raw)
In-Reply-To: <20230511082850.5289-1-ffmpeg@haasn.xyz>

From: Niklas Haas <git@haasn.dev>

Recent versions of libplacebo have required Vulkan versions incompatible
with lavu Vulkan hwcontexts. While this is expected to change
eventually, breaking vf_libplacebo every time there is such a transition
period is obviously undesired behavior, as the following sea of bug
reports shows.

This commit adds a fallback path for pl_vulkan_import failures which
simply creates an internal device instead. Also useful when no interop
with lavu vulkan hwframes is needed or desired.

Fixes: https://github.com/haasn/libplacebo/issues/170
Fixes: https://github.com/mpv-player/mpv/issues/9589#issuecomment-1535432185
Fixes: https://code.videolan.org/videolan/libplacebo/-/issues/270
---
 libavfilter/vf_libplacebo.c | 92 +++++++++++++++++++------------------
 1 file changed, 48 insertions(+), 44 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index 6fe3e0ea88..74ea3cbcc5 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -351,58 +351,50 @@ fail:
     return err;
 }
 
-static int init_vulkan(AVFilterContext *avctx)
+static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwctx)
 {
     int err = 0;
     LibplaceboContext *s = avctx->priv;
-    const AVHWDeviceContext *avhwctx;
-    const AVVulkanDeviceContext *hwctx;
     uint8_t *buf = NULL;
     size_t buf_len;
 
-    if (!avctx->hw_device_ctx) {
-        av_log(s, AV_LOG_ERROR, "Missing vulkan hwdevice for vf_libplacebo.\n");
-        return AVERROR(EINVAL);
-    }
-
-    avhwctx = (AVHWDeviceContext *) avctx->hw_device_ctx->data;
-    if (avhwctx->type != AV_HWDEVICE_TYPE_VULKAN) {
-        av_log(s, AV_LOG_ERROR, "Expected vulkan hwdevice for vf_libplacebo, got %s.\n",
-            av_hwdevice_get_type_name(avhwctx->type));
-        return AVERROR(EINVAL);
+    if (hwctx) {
+        /* Import libavfilter vulkan context into libplacebo */
+        s->vulkan = pl_vulkan_import(s->log, pl_vulkan_import_params(
+            .instance       = hwctx->inst,
+            .get_proc_addr  = hwctx->get_proc_addr,
+            .phys_device    = hwctx->phys_dev,
+            .device         = hwctx->act_dev,
+            .extensions     = hwctx->enabled_dev_extensions,
+            .num_extensions = hwctx->nb_enabled_dev_extensions,
+            .features       = &hwctx->device_features,
+            .queue_graphics = {
+                .index = hwctx->queue_family_index,
+                .count = hwctx->nb_graphics_queues,
+            },
+            .queue_compute = {
+                .index = hwctx->queue_family_comp_index,
+                .count = hwctx->nb_comp_queues,
+            },
+            .queue_transfer = {
+                .index = hwctx->queue_family_tx_index,
+                .count = hwctx->nb_tx_queues,
+            },
+            /* This is the highest version created by hwcontext_vulkan.c */
+            .max_api_version = VK_API_VERSION_1_2,
+        ));
     }
 
-    hwctx = avhwctx->hwctx;
-
-    /* Import libavfilter vulkan context into libplacebo */
-    s->vulkan = pl_vulkan_import(s->log, pl_vulkan_import_params(
-        .instance       = hwctx->inst,
-        .get_proc_addr  = hwctx->get_proc_addr,
-        .phys_device    = hwctx->phys_dev,
-        .device         = hwctx->act_dev,
-        .extensions     = hwctx->enabled_dev_extensions,
-        .num_extensions = hwctx->nb_enabled_dev_extensions,
-        .features       = &hwctx->device_features,
-        .queue_graphics = {
-            .index = hwctx->queue_family_index,
-            .count = hwctx->nb_graphics_queues,
-        },
-        .queue_compute = {
-            .index = hwctx->queue_family_comp_index,
-            .count = hwctx->nb_comp_queues,
-        },
-        .queue_transfer = {
-            .index = hwctx->queue_family_tx_index,
-            .count = hwctx->nb_tx_queues,
-        },
-        /* This is the highest version created by hwcontext_vulkan.c */
-        .max_api_version = VK_API_VERSION_1_2,
-    ));
-
     if (!s->vulkan) {
-        av_log(s, AV_LOG_ERROR, "Failed importing vulkan device to libplacebo!\n");
-        err = AVERROR_EXTERNAL;
-        goto fail;
+        s->vulkan = pl_vulkan_create(s->log, pl_vulkan_params(
+            .get_proc_addr = hwctx ? hwctx->get_proc_addr : NULL,
+            .queue_count = 0, /* enable all queues for parallelization */
+        ));
+        if (!s->vulkan) {
+            av_log(s, AV_LOG_ERROR, "Failed creating fallback vulkan device!\n");
+            err = AVERROR_EXTERNAL;
+            goto fail;
+        }
     }
 
     /* Create the renderer */
@@ -695,10 +687,17 @@ static int libplacebo_query_format(AVFilterContext *ctx)
 {
     int err;
     LibplaceboContext *s = ctx->priv;
+    const AVVulkanDeviceContext *vkhwctx = NULL;
     const AVPixFmtDescriptor *desc = NULL;
     AVFilterFormats *infmts = NULL, *outfmts = NULL;
 
-    RET(init_vulkan(ctx));
+    if (ctx->hw_device_ctx) {
+        const AVHWDeviceContext *avhwctx = (void *) ctx->hw_device_ctx->data;
+        if (avhwctx->type == AV_HWDEVICE_TYPE_VULKAN)
+            vkhwctx = avhwctx->hwctx;
+    }
+
+    RET(init_vulkan(ctx, vkhwctx));
 
     while ((desc = av_pix_fmt_desc_next(desc))) {
         enum AVPixelFormat pixfmt = av_pix_fmt_desc_get_id(desc);
@@ -710,6 +709,11 @@ static int libplacebo_query_format(AVFilterContext *ctx)
             continue;
 #endif
 
+        if (pixfmt == AV_PIX_FMT_VULKAN) {
+            if (!vkhwctx || vkhwctx->act_dev != s->vulkan->device)
+                continue;
+        }
+
         if (!pl_test_pixfmt(s->gpu, pixfmt))
             continue;
 
-- 
2.40.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  reply	other threads:[~2023-05-11  8:39 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-11  8:28 [FFmpeg-devel] [PATCH] " Niklas Haas
2023-05-11  8:39 ` Niklas Haas [this message]
2023-05-11  9:32   ` [FFmpeg-devel] [PATCH v2] " Lynne
2023-05-11 11:21     ` Hendrik Leppkes
2023-05-11 11:57       ` Dennis Mungai
2023-05-11 12:01       ` Lynne
2023-05-11 12:10         ` Niklas Haas
2023-05-11  9:53   ` Anton Khirnov
2023-05-11 10:10     ` Niklas Haas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230511083902.7262-1-ffmpeg@haasn.xyz \
    --to=ffmpeg@haasn.xyz \
    --cc=ffmpeg-devel@ffmpeg.org \
    --cc=git@haasn.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git