[vlc-commits] [Git][videolan/vlc][master] 13 commits: vulkan: remove obsolete import

Hugo Beauzée-Luyssen gitlab at videolan.org
Sun May 9 12:36:18 UTC 2021



Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC


Commits:
d8f89d45 by Niklas Haas at 2021-05-09T11:53:37+00:00
vulkan: remove obsolete import

This is no longer used by anything, as the vulkan code no longer depends
directly on libplacebo.

- - - - -
47353b65 by Niklas Haas at 2021-05-09T11:53:37+00:00
libplacebo: move utils to new library

This will be reused by the other libplacebo components, and in
particular is required to avoid symbol collisions.

- - - - -
5b3a7163 by Niklas Haas at 2021-05-09T11:53:37+00:00
libplacebo: add new libplacebo abstraction interface

This will help disentangle the libplacebo-based vout from the individual
pl_gpu providers (vulkan, opengl, etc.)

Rename the existing vlc_placebo_Create helper to
vlc_placebo_CreateContext to avoid symbol collision.

- - - - -
f5295572 by Niklas Haas at 2021-05-09T11:53:37+00:00
libplacebo: bump minimum dependency to v1.7.0

This lifts the v1.7.0 dependency from the vulkan-specific check out into
the general libplacebo pkgconfig check, a change which is required for
the following refactor of vulkan/display.c into libplacebo/display.c.

A separate dependency for v0.5 is no longer needed, since it's very old
and no longer shipping anywhere (including debian stable). Therefore,
simplify the logic rather than recreating it exactly.

- - - - -
03b3360d by Niklas Haas at 2021-05-09T11:53:37+00:00
libplacebo: move vout to API-agnostic module

Rebases vulkan/display.c ontop of the new API-agnostic libplacebo GPU
abstraction module. This opens up libplacebo/display.c to work with API
backends other than Vulkan.

Note: this has the side effect of bumping up the minimum libplacebo
dependency, because now the libplacebo vout is always compiled when
libplacebo is available. On the plus side, however, it simplifies the
configure check. That said, 1.7.0 is from 2018, and packaged everywhere
(including debian stable). so this should be fine.

- - - - -
6d49f176 by Niklas Haas at 2021-05-09T11:53:37+00:00
libplacebo: namespace all settings behind pl- prefix

The old settings names were not properly namespaced. Since this is
technically a new vout, use the opportunity to break existing
configurations in order to namespace all of the settings.

- - - - -
7c340cd3 by Niklas Haas at 2021-05-09T11:53:37+00:00
libplacebo: add libplacebo<->vulkan wrapper module

- - - - -
4b89ec42 by Niklas Haas at 2021-05-09T11:53:37+00:00
libplacebo: add MakeCurrent/ReleaseCurrent wrappers

Needed for OpenGL API support, at least on versions of libplacebo prior
to v3.128. It's worth pointing out that this logic is therefore only
temporary - once the libplacebo version is bumped past v3.128, this can
be removed again.

This commit only adds the API, with the OpenGL implementation coming in
a following commit.

- - - - -
9ae6b001 by Niklas Haas at 2021-05-09T11:53:37+00:00
libplacebo: add libplacebo<->OpenGL wrapper module

Supports both GL and GLES2, configurably.

- - - - -
51cdf229 by Niklas Haas at 2021-05-09T11:53:37+00:00
libplacebo: correctly handle overlays on flipped framebuffers

This affects OpenGL.

- - - - -
f6e9e324 by Niklas Haas at 2021-05-09T11:53:37+00:00
vulkan: rename instance.h to platform.h

With the removal of the actual vulkan instance from this abstraction in
883a865a, calling this "instance" is confusing and misleading. It should
be called "platform", because the only thing the abstraction is designed
to contain is platform-specific state and operations.

Rename it, and the associated type, for clarity. This frees up the name
`vlc_vk_t` to be used for an actual Vulkan instance, if we ever decide
we need one in the future. (e.g. for GPU filters)

- - - - -
36884525 by Niklas Haas at 2021-05-09T11:53:37+00:00
vulkan: remove refcount from vlc_vk_platform_t

I can't think of a use case for this ever being refcounted. It made more
sense back when it held the actual instance, but the platform/surface is
only ever going to be used by whatever also owns the vout_window_t.

- - - - -
ac14138a by Niklas Haas at 2021-05-09T11:53:37+00:00
vulkan: minor cosmetic cleanups

Tidy up the struct and comments, and also remove redundant forward
declarations.

- - - - -


22 changed files:

- configure.ac
- modules/video_output/Makefile.am
- + modules/video_output/libplacebo/Makefile.am
- modules/video_output/vulkan/display.c → modules/video_output/libplacebo/display.c
- + modules/video_output/libplacebo/instance.c
- + modules/video_output/libplacebo/instance.h
- + modules/video_output/libplacebo/instance_opengl.c
- + modules/video_output/libplacebo/instance_vulkan.c
- modules/video_output/placebo_utils.c → modules/video_output/libplacebo/utils.c
- modules/video_output/placebo_utils.h → modules/video_output/libplacebo/utils.h
- modules/video_output/opengl/Makefile.am
- modules/video_output/opengl/sampler.c
- modules/video_output/opengl/vout_helper.h
- modules/video_output/vulkan/Makefile.am
- modules/video_output/vulkan/instance.c → modules/video_output/vulkan/platform.c
- modules/video_output/vulkan/instance.h → modules/video_output/vulkan/platform.h
- modules/video_output/vulkan/platform_android.c
- modules/video_output/vulkan/platform_win32.c
- modules/video_output/vulkan/platform_xcb.c
- modules/video_output/wayland/Makefile.am
- modules/video_output/wayland/vulkan.c
- po/POTFILES.in


Changes:

=====================================
configure.ac
=====================================
@@ -3288,10 +3288,13 @@ AC_ARG_ENABLE([libplacebo],
       [disable libplacebo support (default auto)]))
 
 AS_IF([test "$enable_libplacebo" != "no"], [
-  PKG_CHECK_MODULES([LIBPLACEBO], [libplacebo >= 0.5], [
+  PKG_CHECK_MODULES([LIBPLACEBO], [libplacebo >= 1.7], [
     AC_DEFINE([HAVE_LIBPLACEBO], [1], [Define to 1 if libplacebo is enabled.])
-    PKG_CHECK_MODULES([LIBPLACEBO], [libplacebo >= 1.7],
-      [have_libplacebo_vk="yes"], [have_libplacebo_vk="no"])
+    AC_CHECK_HEADER([libplacebo/vulkan.h], [VLC_ADD_PLUGIN([placebo_vk])])
+    AC_CHECK_HEADER([libplacebo/opengl.h], [
+        VLC_ADD_PLUGIN([placebo_gl])
+        VLC_ADD_PLUGIN([placebo_gles2])
+    ])
   ], [
     AS_IF([test -n "${enable_libplacebo}"], [
       AC_MSG_ERROR([${LIBPLACEBO_PKG_ERRORS}.])
@@ -3357,18 +3360,11 @@ AC_ARG_ENABLE(vulkan,
       [disable Vulkan support (default auto)])])
 
 AS_IF([test "$enable_vulkan" != "no"], [
-  AS_IF([test "$have_libplacebo_vk" = "yes"], [
-    PKG_CHECK_MODULES([VULKAN], [vulkan >= 1.0.26], [
-      AC_DEFINE([HAVE_VULKAN], [1], [Define to 1 if vulkan is enabled.])
-    ], [
-      AS_IF([test -n "${enable_vulkan}"], [
-        AC_MSG_ERROR([${VULKAN_PKG_ERRORS}.])
-      ])
-      enable_vulkan="no"
-    ])
+  PKG_CHECK_MODULES([VULKAN], [vulkan >= 1.0.26], [
+    AC_DEFINE([HAVE_VULKAN], [1], [Define to 1 if vulkan is enabled.])
   ], [
     AS_IF([test -n "${enable_vulkan}"], [
-      AC_MSG_ERROR([Vulkan support requires libplacebo 1.7 as well. Do not use --disable-libplacebo.])
+      AC_MSG_ERROR([${VULKAN_PKG_ERRORS}.])
     ])
     enable_vulkan="no"
   ])


=====================================
modules/video_output/Makefile.am
=====================================
@@ -3,6 +3,12 @@ vout_LTLIBRARIES =
 
 EXTRA_DIST += video_output/README
 
+### libplacebo ###
+if HAVE_LIBPLACEBO
+include video_output/libplacebo/Makefile.am
+endif
+
+### OpenGL ###
 include video_output/opengl/Makefile.am
 
 if HAVE_DECKLINK


=====================================
modules/video_output/libplacebo/Makefile.am
=====================================
@@ -0,0 +1,60 @@
+### libplacebo ###
+
+LIBPLACEBO_COMMONSOURCES = video_output/libplacebo/utils.h \
+	video_output/libplacebo/instance.h
+
+# Trigger the c++ linker because of glslang dependency of libplacebo
+LIBPLACEBO_COMMONSOURCES += dummy.cpp
+
+libplacebo_utils_la_SOURCES = $(LIBPLACEBO_COMMONSOURCES) \
+			      video_output/libplacebo/utils.c
+libplacebo_utils_la_CFLAGS = $(AM_CFLAGS) $(LIBPLACEBO_CFLAGS)
+libplacebo_utils_la_LIBADD = $(LIBPLACEBO_LIBS)
+libplacebo_utils_la_LDFLAGS = -static -undefined
+
+noinst_LTLIBRARIES += libplacebo_utils.la
+
+libplacebo_plugin_la_SOURCES = $(LIBPLACEBO_COMMONSOURCES) \
+			  video_output/libplacebo/instance.c \
+			  video_output/libplacebo/display.c
+libplacebo_plugin_la_CFLAGS = $(AM_CFLAGS) $(LIBPLACEBO_CFLAGS)
+libplacebo_plugin_la_LIBADD = $(LIBPLACEBO_LIBS) libplacebo_utils.la
+
+vout_LTLIBRARIES += libplacebo_plugin.la
+
+### Vulkan ###
+libplacebo_vk_plugin_la_SOURCES = $(LIBPLACEBO_COMMONSOURCES) \
+				  video_output/vulkan/platform.h \
+				  video_output/vulkan/platform.c \
+				  video_output/libplacebo/instance_vulkan.c
+libplacebo_vk_plugin_la_CFLAGS = $(AM_CFLAGS) $(LIBPLACEBO_CFLAGS) $(VULKAN_CFLAGS)
+libplacebo_vk_plugin_la_LIBADD = $(LIBPLACEBO_LIBS) $(VULKAN_LIBS)
+libplacebo_vk_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)'
+
+if HAVE_VULKAN
+vout_LTLIBRARIES += $(LTLIBplacebo_vk)
+EXTRA_LTLIBRARIES += libplacebo_vk_plugin.la
+endif
+
+### OpenGL ###
+libplacebo_gl_plugin_la_SOURCES = $(LIBPLACEBO_COMMONSOURCES) \
+				  video_output/libplacebo/instance_opengl.c
+libplacebo_gl_plugin_la_CFLAGS = $(AM_CFLAGS) $(LIBPLACEBO_CFLAGS)
+libplacebo_gl_plugin_la_LIBADD = $(LIBPLACEBO_LIBS) libvlc_opengl.la
+libplacebo_gl_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)'
+
+libplacebo_gles2_plugin_la_SOURCES = $(LIBPLACEBO_COMMONSOURCES) \
+				     video_output/libplacebo/instance_opengl.c
+libplacebo_gles2_plugin_la_CFLAGS = $(AM_CFLAGS) $(LIBPLACEBO_CFLAGS) -DUSE_OPENGL_ES2
+libplacebo_gles2_plugin_la_LIBADD = $(LIBPLACEBO_LIBS) libvlc_opengles.la
+libplacebo_gles2_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)'
+
+if HAVE_GL
+vout_LTLIBRARIES += $(LTLIBplacebo_gl)
+EXTRA_LTLIBRARIES += libplacebo_gl_plugin.la
+endif
+
+if HAVE_GLES2
+vout_LTLIBRARIES += $(LTLIBplacebo_gles2)
+EXTRA_LTLIBRARIES += libplacebo_gles2_plugin.la
+endif


=====================================
modules/video_output/vulkan/display.c → modules/video_output/libplacebo/display.c
=====================================
@@ -1,9 +1,9 @@
 /**
  * @file display.c
- * @brief Vulkan video output module
+ * @brief libplacebo video output module
  */
 /*****************************************************************************
- * Copyright © 2018 Niklas Haas
+ * Copyright © 2021 Niklas Haas
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -31,26 +31,19 @@
 #include <vlc_plugin.h>
 #include <vlc_vout_display.h>
 
-#include "../placebo_utils.h"
+#include "utils.h"
 #include "instance.h"
 
 #include <libplacebo/renderer.h>
 #include <libplacebo/utils/upload.h>
 #include <libplacebo/swapchain.h>
-#include <libplacebo/vulkan.h>
 
 struct vout_display_sys_t
 {
-    vlc_vk_t *vk;
+    vlc_placebo_t *pl;
     const struct pl_tex *plane_tex[4];
-    struct pl_context *ctx;
-    const struct pl_vk_inst *instance;
-    const struct pl_vulkan *vulkan;
-    const struct pl_swapchain *swapchain;
     struct pl_renderer *renderer;
 
-    VkSurfaceKHR surface;
-
     // Pool of textures for the subpictures
     struct pl_overlay *overlays;
     const struct pl_tex **overlay_tex;
@@ -87,7 +80,6 @@ static const struct vlc_display_operations ops = {
     Close, PictureRender, PictureDisplay, Control, NULL, NULL,
 };
 
-// Allocates a Vulkan surface and instance for video output.
 static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
                 video_format_t *fmt, vlc_video_context *context)
 {
@@ -96,67 +88,28 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
     if (unlikely(sys == NULL))
         return VLC_ENOMEM;
 
-    vout_window_t *window = vd->cfg->window;
-    if (window == NULL)
+    if (vd->cfg->window == NULL)
     {
         msg_Err(vd, "parent window not available");
         goto error;
     }
 
-    sys->vk = vlc_vk_Create(window, NULL);
-    if (sys->vk == NULL)
-        goto error;
-
-    sys->ctx = vlc_placebo_Create(VLC_OBJECT(sys->vk));
-    if (!sys->ctx)
-        goto error;
-
-    sys->instance = pl_vk_inst_create(sys->ctx, &(struct pl_vk_inst_params) {
-        .debug = var_InheritBool(sys->vk, "vk-debug"),
-        .extensions = (const char *[]) {
-            VK_KHR_SURFACE_EXTENSION_NAME,
-            sys->vk->platform_ext,
-        },
-        .num_extensions = 2,
-    });
-    if (!sys->instance)
+    char *name = var_InheritString(vd, "pl-gpu");
+    sys->pl = vlc_placebo_Create(cfg, name);
+    free(name);
+    if (sys->pl == NULL)
         goto error;
 
-    // Create the platform-specific surface object
-    if (vlc_vk_CreateSurface(sys->vk, sys->instance->instance, &sys->surface) != VLC_SUCCESS)
+    if (vlc_placebo_MakeCurrent(sys->pl) != VLC_SUCCESS)
         goto error;
 
-    // Create vulkan device
-    char *device_name = var_InheritString(sys->vk, "vk-device");
-    sys->vulkan = pl_vulkan_create(sys->ctx, &(struct pl_vulkan_params) {
-        .instance = sys->instance->instance,
-        .surface = sys->surface,
-        .device_name = device_name,
-        .allow_software = var_InheritBool(vd, "allow-sw"),
-        .async_transfer = var_InheritBool(vd, "async-xfer"),
-        .async_compute = var_InheritBool(vd, "async-comp"),
-        .queue_count = var_InheritInteger(vd, "queue-count"),
-    });
-    free(device_name);
-    if (!sys->vulkan)
-        goto error;
-
-    // Create swapchain for this surface
-    struct pl_vulkan_swapchain_params swap_params = {
-        .surface = sys->surface,
-        .present_mode = var_InheritInteger(vd, "present-mode"),
-        .swapchain_depth = var_InheritInteger(vd, "queue-depth"),
-    };
-
-    sys->swapchain = pl_vulkan_create_swapchain(sys->vulkan, &swap_params);
-    if (!sys->swapchain)
-        goto error;
-
-    const struct pl_gpu *gpu = sys->vulkan->gpu;
-    sys->renderer = pl_renderer_create(sys->ctx, gpu);
+    const struct pl_gpu *gpu = sys->pl->gpu;
+    sys->renderer = pl_renderer_create(sys->pl->ctx, gpu);
     if (!sys->renderer)
         goto error;
 
+    vlc_placebo_ReleaseCurrent(sys->pl);
+
     // Attempt using the input format as the display format
     if (vlc_placebo_FormatSupported(gpu, vd->fmt->i_chroma)) {
         fmt->i_chroma = vd->fmt->i_chroma;
@@ -202,34 +155,31 @@ static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
 
 error:
     pl_renderer_destroy(&sys->renderer);
-    pl_swapchain_destroy(&sys->swapchain);
-    pl_vulkan_destroy(&sys->vulkan);
-    pl_vk_inst_destroy(&sys->instance);
-    pl_context_destroy(&sys->ctx);
-
-    if (sys->vk != NULL)
-        vlc_vk_Release(sys->vk);
+    if (sys->pl != NULL)
+        vlc_placebo_Release(sys->pl);
     return VLC_EGENERIC;
 }
 
 static void Close(vout_display_t *vd)
 {
     vout_display_sys_t *sys = vd->sys;
-    const struct pl_gpu *gpu = sys->vulkan->gpu;
-
-    for (int i = 0; i < 4; i++)
-        pl_tex_destroy(gpu, &sys->plane_tex[i]);
-    for (int i = 0; i < sys->num_overlays; i++)
-        pl_tex_destroy(gpu, &sys->overlay_tex[i]);
+    const struct pl_gpu *gpu = sys->pl->gpu;
+
+    if (vlc_placebo_MakeCurrent(sys->pl) == VLC_SUCCESS) {
+        for (int i = 0; i < 4; i++)
+            pl_tex_destroy(gpu, &sys->plane_tex[i]);
+        for (int i = 0; i < sys->num_overlays; i++)
+            pl_tex_destroy(gpu, &sys->overlay_tex[i]);
+        pl_renderer_destroy(&sys->renderer);
+        vlc_placebo_ReleaseCurrent(sys->pl);
+    }
 
     if (sys->overlays) {
         free(sys->overlays);
         free(sys->overlay_tex);
     }
 
-    pl_renderer_destroy(&sys->renderer);
-
-    vlc_vk_Release(sys->vk);
+    vlc_placebo_Release(sys->pl);
 }
 
 static void PictureRender(vout_display_t *vd, picture_t *pic,
@@ -237,12 +187,17 @@ static void PictureRender(vout_display_t *vd, picture_t *pic,
 {
     VLC_UNUSED(date);
     vout_display_sys_t *sys = vd->sys;
-    const struct pl_gpu *gpu = sys->vulkan->gpu;
+    const struct pl_gpu *gpu = sys->pl->gpu;
     bool failed = false;
 
+    if (vlc_placebo_MakeCurrent(sys->pl) != VLC_SUCCESS)
+        return;
+
     struct pl_swapchain_frame frame;
-    if (!pl_swapchain_start_frame(sys->swapchain, &frame))
+    if (!pl_swapchain_start_frame(sys->pl->swapchain, &frame)) {
+        vlc_placebo_ReleaseCurrent(sys->pl);
         return; // Probably benign error, ignore it
+    }
 
     struct pl_image img = {
         .signature  = sys->counter++,
@@ -346,6 +301,11 @@ static void PictureRender(vout_display_t *vd, picture_t *pic,
                 .repr  = vlc_placebo_ColorRepr(&r->fmt),
             };
 
+            if (frame.flipped) {
+                overlay->rect.y0 = frame.fbo->params.h - overlay->rect.y0;
+                overlay->rect.y1 = frame.fbo->params.h - overlay->rect.y1;
+            }
+
             if (!pl_upload_plane(gpu, &overlay->plane, &sys->overlay_tex[i], &subdata)) {
                 msg_Err(vd, "Failed uploading subpicture region!");
                 num_regions = i; // stop here
@@ -377,17 +337,20 @@ done:
     if (failed)
         pl_tex_clear(gpu, frame.fbo, (float[4]){ 1.0, 0.0, 0.0, 1.0 });
 
-    if (!pl_swapchain_submit_frame(sys->swapchain)) {
+    if (!pl_swapchain_submit_frame(sys->pl->swapchain))
         msg_Err(vd, "Failed rendering frame!");
-        return;
-    }
+
+    vlc_placebo_ReleaseCurrent(sys->pl);
 }
 
 static void PictureDisplay(vout_display_t *vd, picture_t *pic)
 {
     VLC_UNUSED(pic);
     vout_display_sys_t *sys = vd->sys;
-    pl_swapchain_swap_buffers(sys->swapchain);
+    if (vlc_placebo_MakeCurrent(sys->pl) == VLC_SUCCESS) {
+        pl_swapchain_swap_buffers(sys->pl->swapchain);
+        vlc_placebo_ReleaseCurrent(sys->pl);
+    }
 }
 
 static int Control(vout_display_t *vd, int query)
@@ -415,7 +378,11 @@ static int Control(vout_display_t *vd, int query)
         {
             int width = (int) vd->cfg->display.width;
             int height = (int) vd->cfg->display.height;
-            pl_swapchain_resize(sys->swapchain, &width, &height);
+            if (vlc_placebo_MakeCurrent(sys->pl) != VLC_SUCCESS)
+                return VLC_SUCCESS; // ignore errors
+
+            pl_swapchain_resize(sys->pl->swapchain, &width, &height);
+            vlc_placebo_ReleaseCurrent(sys->pl);
 
             /* NOTE: We currently ignore resizing failures that are transient
              * on X11. Maybe improving resizing might fix that, but we don't
@@ -438,211 +405,152 @@ static int Control(vout_display_t *vd, int query)
 
 // Options
 
-#define VK_TEXT N_("Vulkan surface extension")
+#define PROVIDER_TEXT N_("GPU instance provider")
 #define PROVIDER_LONGTEXT N_( \
-    "Extension which provides the Vulkan surface to use.")
-
-#define DISABLE_DR_TEXT "Disable direct rendering / zero-copy upload"
-#define DISABLE_DR_LONGTEXT "Direct rendering is a technique where image data is uploaded via a mapped buffer instead of via memcpy. On some platforms this might be very slow (due to poor readback performance from mapped memory), in which cases this flag would help."
-
-#define DEBUG_TEXT "Enable API debugging"
-#define DEBUG_LONGTEXT "This loads the vulkan standard validation layers, which can help catch API usage errors. Comes at a small performance penalty."
-
-#define DEVICE_TEXT "Device name override"
-#define DEVICE_LONGTEXT "If set to something non-empty, only a device with this exact name will be used. To see a list of devices and their names, run vlc -v with this module active."
-
-#define ALLOWSW_TEXT "Allow software devices"
-#define ALLOWSW_LONGTEXT "If enabled, allow the use of software emulation devices, which are not real devices and therefore typically very slow. (This option has no effect if forcing a specific device name)"
-
-#define ASYNC_XFER_TEXT "Allow asynchronous transfer"
-#define ASYNC_XFER_LONGTEXT "Allows the use of an asynchronous transfer queue if the device has one. Typically this maps to a DMA engine, which can perform texture uploads/downloads without blocking the GPU's compute units. Highly recommended for 4K and above."
-
-#define ASYNC_COMP_TEXT "Allow asynchronous compute"
-#define ASYNC_COMP_LONGTEXT "Allows the use of dedicated compute queue families if the device has one. Sometimes these will schedule concurrent compute work better than the main graphics queue. Turn this off if you have any issues."
-
-#define QUEUE_COUNT_TEXT "Queue count"
-#define QUEUE_COUNT_LONGTEXT "How many queues to use on the device. Increasing this might improve rendering throughput for GPUs capable of concurrent scheduling. Increasing this past the driver's limit has no effect."
-
-#define QUEUE_DEPTH_TEXT "Maximum frame latency"
-#define QUEUE_DEPTH_LONGTEXT "Affects how many frames to render/present in advance. Increasing this can improve performance at the cost of latency, by allowing better pipelining between frames. May have no effect, depending on the VLC clock settings."
-
-static const int present_values[] = {
-    VK_PRESENT_MODE_IMMEDIATE_KHR,
-    VK_PRESENT_MODE_MAILBOX_KHR,
-    VK_PRESENT_MODE_FIFO_KHR,
-    VK_PRESENT_MODE_FIFO_RELAXED_KHR,
-};
-
-static const char * const present_text[] = {
-    "Immediate (non-blocking, tearing)",
-    "Mailbox (non-blocking, non-tearing)",
-    "FIFO (blocking, non-tearing)",
-    "Relaxed FIFO (blocking, tearing)",
-};
-
-#define PRESENT_MODE_TEXT "Preferred present mode"
-#define PRESENT_MODE_LONGTEXT "Which present mode to use when creating the swapchain. If the chosen mode is not supported, VLC will fall back to using FIFO."
+    "Extension which provides the GPU instance to use.")
 
 vlc_module_begin ()
-    set_shortname ("Vulkan")
-    set_description (N_("Vulkan video output"))
+    set_shortname ("libplacebo")
+    set_description (N_("libplacebo video output"))
     set_category (CAT_VIDEO)
     set_subcategory (SUBCAT_VIDEO_VOUT)
     set_callback_display(Open, 0)
-    add_shortcut ("vulkan", "vk")
-    add_module ("vk", "", NULL, VK_TEXT, PROVIDER_LONGTEXT)
+    add_shortcut ("libplacebo", "pl")
+    add_module ("pl-gpu", "libplacebo gpu", NULL, PROVIDER_TEXT, PROVIDER_LONGTEXT)
 
     set_section("Scaling", NULL)
-    add_integer("upscaler-preset", SCALE_BUILTIN,
+    add_integer("pl-upscaler-preset", SCALE_BUILTIN,
             UPSCALER_PRESET_TEXT, SCALER_PRESET_LONGTEXT, false)
             change_integer_list(scale_values, scale_text)
-    add_integer("downscaler-preset", SCALE_BUILTIN,
+    add_integer("pl-downscaler-preset", SCALE_BUILTIN,
             DOWNSCALER_PRESET_TEXT, SCALER_PRESET_LONGTEXT, false)
             change_integer_list(scale_values, scale_text)
-    add_integer_with_range("lut-entries", 64, 16, 256,
+    add_integer_with_range("pl-lut-entries", 64, 16, 256,
             LUT_ENTRIES_TEXT, LUT_ENTRIES_LONGTEXT, false)
-    add_float_with_range("antiringing", 0.0,
+    add_float_with_range("pl-antiringing", 0.0,
             0.0, 1.0, ANTIRING_TEXT, ANTIRING_LONGTEXT, false)
-    add_bool("sigmoid", !!pl_render_default_params.sigmoid_params,
+    add_bool("pl-sigmoid", !!pl_render_default_params.sigmoid_params,
             SIGMOID_TEXT, SIGMOID_LONGTEXT, true)
-    add_float_with_range("sigmoid-center", pl_sigmoid_default_params.center,
+    add_float_with_range("pl-sigmoid-center", pl_sigmoid_default_params.center,
             0., 1., SIGMOID_CENTER_TEXT, SIGMOID_CENTER_LONGTEXT, true)
-    add_float_with_range("sigmoid-slope", pl_sigmoid_default_params.slope,
+    add_float_with_range("pl-sigmoid-slope", pl_sigmoid_default_params.slope,
             1., 20., SIGMOID_SLOPE_TEXT, SIGMOID_SLOPE_LONGTEXT, true)
 
     set_section("Debanding", NULL)
-    add_bool("debanding", false, DEBAND_TEXT, DEBAND_LONGTEXT, false)
-    add_integer("iterations", pl_deband_default_params.iterations,
+    add_bool("pl-debanding", false, DEBAND_TEXT, DEBAND_LONGTEXT, false)
+    add_integer("pl-iterations", pl_deband_default_params.iterations,
             DEBAND_ITER_TEXT, DEBAND_ITER_LONGTEXT, false)
-    add_float("threshold", pl_deband_default_params.threshold,
+    add_float("pl-threshold", pl_deband_default_params.threshold,
             DEBAND_THRESH_TEXT, DEBAND_THRESH_LONGTEXT, false)
-    add_float("radius", pl_deband_default_params.radius,
+    add_float("pl-radius", pl_deband_default_params.radius,
             DEBAND_RADIUS_TEXT, DEBAND_RADIUS_LONGTEXT, false)
-    add_float("grain", pl_deband_default_params.grain,
+    add_float("pl-grain", pl_deband_default_params.grain,
             DEBAND_GRAIN_TEXT, DEBAND_GRAIN_LONGTEXT, false)
 
     set_section("Colorspace conversion", NULL)
-    add_integer("intent", pl_color_map_default_params.intent,
+    add_integer("pl-intent", pl_color_map_default_params.intent,
             RENDER_INTENT_TEXT, RENDER_INTENT_LONGTEXT, false)
             change_integer_list(intent_values, intent_text)
-    add_integer("target-prim", PL_COLOR_PRIM_UNKNOWN, PRIM_TEXT, PRIM_LONGTEXT, false) \
+    add_integer("pl-target-prim", PL_COLOR_PRIM_UNKNOWN, PRIM_TEXT, PRIM_LONGTEXT, false) \
             change_integer_list(prim_values, prim_text) \
-    add_integer("target-trc", PL_COLOR_TRC_UNKNOWN, TRC_TEXT, TRC_LONGTEXT, false) \
+    add_integer("pl-target-trc", PL_COLOR_TRC_UNKNOWN, TRC_TEXT, TRC_LONGTEXT, false) \
             change_integer_list(trc_values, trc_text) \
 
     // TODO: support for ICC profiles / 3DLUTs.. we will need some way of loading
     // this from the operating system / user
 
     set_section("Tone mapping", NULL)
-    add_integer("tone-mapping", pl_color_map_default_params.tone_mapping_algo,
+    add_integer("pl-tone-mapping", pl_color_map_default_params.tone_mapping_algo,
             TONEMAPPING_TEXT, TONEMAPPING_LONGTEXT, false)
             change_integer_list(tone_values, tone_text)
-    add_float("tone-mapping-param", pl_color_map_default_params.tone_mapping_param,
+    add_float("pl-tone-mapping-param", pl_color_map_default_params.tone_mapping_param,
             TONEMAP_PARAM_TEXT, TONEMAP_PARAM_LONGTEXT, true)
 #if PL_API_VER >= 10
-    add_float("desat-strength", pl_color_map_default_params.desaturation_strength,
+    add_float("pl-desat-strength", pl_color_map_default_params.desaturation_strength,
             DESAT_STRENGTH_TEXT, DESAT_STRENGTH_LONGTEXT, false)
-    add_float("desat-exponent", pl_color_map_default_params.desaturation_exponent,
+    add_float("pl-desat-exponent", pl_color_map_default_params.desaturation_exponent,
             DESAT_EXPONENT_TEXT, DESAT_EXPONENT_LONGTEXT, false)
-    add_float("desat-base", pl_color_map_default_params.desaturation_base,
+    add_float("pl-desat-base", pl_color_map_default_params.desaturation_base,
             DESAT_BASE_TEXT, DESAT_BASE_LONGTEXT, false)
-    add_float("max-boost", pl_color_map_default_params.max_boost,
+    add_float("pl-max-boost", pl_color_map_default_params.max_boost,
             MAX_BOOST_TEXT, MAX_BOOST_LONGTEXT, false)
 #else
-    add_float("tone-mapping-desat", pl_color_map_default_params.tone_mapping_desaturate,
+    add_float("pl-tone-mapping-desat", pl_color_map_default_params.tone_mapping_desaturate,
             TONEMAP_DESAT_TEXT, TONEMAP_DESAT_LONGTEXT, false)
 #endif
-    add_bool("gamut-warning", false, GAMUT_WARN_TEXT, GAMUT_WARN_LONGTEXT, true)
+    add_bool("pl-gamut-warning", false, GAMUT_WARN_TEXT, GAMUT_WARN_LONGTEXT, true)
 
 #if PL_API_VER < 12
-    add_integer_with_range("peak-frames", pl_color_map_default_params.peak_detect_frames,
+    add_integer_with_range("pl-peak-frames", pl_color_map_default_params.peak_detect_frames,
             0, 255, PEAK_FRAMES_TEXT, PEAK_FRAMES_LONGTEXT, false)
-    add_float_with_range("scene-threshold", pl_color_map_default_params.scene_threshold,
+    add_float_with_range("pl-scene-threshold", pl_color_map_default_params.scene_threshold,
             0., 10., SCENE_THRESHOLD_TEXT, SCENE_THRESHOLD_LONGTEXT, false)
 #endif
 
 #if PL_API_VER >= 13
-    add_float_with_range("peak-period", pl_peak_detect_default_params.smoothing_period,
+    add_float_with_range("pl-peak-period", pl_peak_detect_default_params.smoothing_period,
             0., 1000., PEAK_PERIOD_TEXT, PEAK_PERIOD_LONGTEXT, false)
-    add_float("scene-threshold-low", pl_peak_detect_default_params.scene_threshold_low,
+    add_float("pl-scene-threshold-low", pl_peak_detect_default_params.scene_threshold_low,
             SCENE_THRESHOLD_LOW_TEXT, SCENE_THRESHOLD_LOW_LONGTEXT, false)
-    add_float("scene-threshold-high", pl_peak_detect_default_params.scene_threshold_high,
+    add_float("pl-scene-threshold-high", pl_peak_detect_default_params.scene_threshold_high,
             SCENE_THRESHOLD_HIGH_TEXT, SCENE_THRESHOLD_HIGH_LONGTEXT, false)
 #endif
 
-    add_float_with_range("target-avg", 0.25,
+    add_float_with_range("pl-target-avg", 0.25,
             0.0, 1.0, TARGET_AVG_TEXT, TARGET_AVG_LONGTEXT, false)
 
     set_section("Dithering", NULL)
-    add_integer("dither", -1,
+    add_integer("pl-dither", -1,
             DITHER_TEXT, DITHER_LONGTEXT, false)
             change_integer_list(dither_values, dither_text)
-    add_integer_with_range("dither-size", pl_dither_default_params.lut_size,
+    add_integer_with_range("pl-dither-size", pl_dither_default_params.lut_size,
             1, 8, DITHER_SIZE_TEXT, DITHER_SIZE_LONGTEXT, false)
-    add_bool("temporal-dither", pl_dither_default_params.temporal,
+    add_bool("pl-temporal-dither", pl_dither_default_params.temporal,
             TEMPORAL_DITHER_TEXT, TEMPORAL_DITHER_LONGTEXT, false)
-    add_integer_with_range("dither-depth", 0,
+    add_integer_with_range("pl-dither-depth", 0,
             0, 16, DITHER_DEPTH_TEXT, DITHER_DEPTH_LONGTEXT, false)
 
     set_section("Custom upscaler (when preset = custom)", NULL)
-    add_integer("upscaler-kernel", FILTER_BOX,
+    add_integer("pl-upscaler-kernel", FILTER_BOX,
             KERNEL_TEXT, KERNEL_LONGTEXT, true)
             change_integer_list(filter_values, filter_text)
-    add_integer("upscaler-window", FILTER_NONE,
+    add_integer("pl-upscaler-window", FILTER_NONE,
             WINDOW_TEXT, WINDOW_LONGTEXT, true)
             change_integer_list(filter_values, filter_text)
-    add_bool("upscaler-polar", false, POLAR_TEXT, POLAR_LONGTEXT, true)
-    add_float_with_range("upscaler-clamp", 0.0,
+    add_bool("pl-upscaler-polar", false, POLAR_TEXT, POLAR_LONGTEXT, true)
+    add_float_with_range("pl-upscaler-clamp", 0.0,
             0.0, 1.0, CLAMP_TEXT, CLAMP_LONGTEXT, true)
-    add_float_with_range("upscaler-blur", 1.0,
+    add_float_with_range("pl-upscaler-blur", 1.0,
             0.0, 100.0, BLUR_TEXT, BLUR_LONGTEXT, true)
-    add_float_with_range("upscaler-taper", 0.0,
+    add_float_with_range("pl-upscaler-taper", 0.0,
             0.0, 10.0, TAPER_TEXT, TAPER_LONGTEXT, true)
 
     set_section("Custom downscaler (when preset = custom)", NULL)
-    add_integer("downscaler-kernel", FILTER_BOX,
+    add_integer("pl-downscaler-kernel", FILTER_BOX,
             KERNEL_TEXT, KERNEL_LONGTEXT, true)
             change_integer_list(filter_values, filter_text)
-    add_integer("downscaler-window", FILTER_NONE,
+    add_integer("pl-downscaler-window", FILTER_NONE,
             WINDOW_TEXT, WINDOW_LONGTEXT, true)
             change_integer_list(filter_values, filter_text)
-    add_bool("downscaler-polar", false, POLAR_TEXT, POLAR_LONGTEXT, true)
-    add_float_with_range("downscaler-clamp", 0.0,
+    add_bool("pl-downscaler-polar", false, POLAR_TEXT, POLAR_LONGTEXT, true)
+    add_float_with_range("pl-downscaler-clamp", 0.0,
             0.0, 1.0, CLAMP_TEXT, CLAMP_LONGTEXT, true)
-    add_float_with_range("downscaler-blur", 1.0,
+    add_float_with_range("pl-downscaler-blur", 1.0,
             0.0, 100.0, BLUR_TEXT, BLUR_LONGTEXT, true)
-    add_float_with_range("downscaler-taper", 0.0,
+    add_float_with_range("pl-downscaler-taper", 0.0,
             0.0, 10.0, TAPER_TEXT, TAPER_LONGTEXT, true)
 
     set_section("Performance tweaks / debugging", NULL)
-    add_bool("skip-aa", false, SKIP_AA_TEXT, SKIP_AA_LONGTEXT, false)
-    add_float_with_range("polar-cutoff", 0.001,
+    add_bool("pl-skip-aa", false, SKIP_AA_TEXT, SKIP_AA_LONGTEXT, false)
+    add_float_with_range("pl-polar-cutoff", 0.001,
             0., 1., POLAR_CUTOFF_TEXT, POLAR_CUTOFF_LONGTEXT, false)
-    add_bool("overlay-direct", false, OVERLAY_DIRECT_TEXT, OVERLAY_DIRECT_LONGTEXT, false)
-    add_bool("disable-linear", false, DISABLE_LINEAR_TEXT, DISABLE_LINEAR_LONGTEXT, false)
-    add_bool("force-general", false, FORCE_GENERAL_TEXT, FORCE_GENERAL_LONGTEXT, false)
+    add_bool("pl-overlay-direct", false, OVERLAY_DIRECT_TEXT, OVERLAY_DIRECT_LONGTEXT, false)
+    add_bool("pl-disable-linear", false, DISABLE_LINEAR_TEXT, DISABLE_LINEAR_LONGTEXT, false)
+    add_bool("pl-force-general", false, FORCE_GENERAL_TEXT, FORCE_GENERAL_LONGTEXT, false)
 #if PL_API_VER >= 13
-    add_bool("delayed-peak", false, DELAYED_PEAK_TEXT, DELAYED_PEAK_LONGTEXT, false)
+    add_bool("pl-delayed-peak", false, DELAYED_PEAK_TEXT, DELAYED_PEAK_LONGTEXT, false)
 #endif
 
-    set_section("Device selection", NULL)
-    add_bool("vk-debug", false, DEBUG_TEXT, DEBUG_LONGTEXT, false)
-    add_string("vk-device", "", DEVICE_TEXT, DEVICE_LONGTEXT, false)
-    add_bool("allow-sw", pl_vulkan_default_params.allow_software,
-            ALLOWSW_TEXT, ALLOWSW_LONGTEXT, false)
-
-    set_section("Performance tuning", NULL)
-    add_bool("async-xfer", pl_vulkan_default_params.async_transfer,
-            ASYNC_XFER_TEXT, ASYNC_XFER_LONGTEXT, false)
-    add_bool("async-comp", pl_vulkan_default_params.async_compute,
-            ASYNC_COMP_TEXT, ASYNC_COMP_LONGTEXT, false)
-    add_integer_with_range("queue-count", pl_vulkan_default_params.queue_count,
-            1, 8, QUEUE_COUNT_TEXT, QUEUE_COUNT_LONGTEXT, false)
-    add_integer_with_range("queue-depth", 3,
-            1, 8, QUEUE_DEPTH_TEXT, QUEUE_DEPTH_LONGTEXT, false)
-    add_integer("present-mode", VK_PRESENT_MODE_FIFO_KHR,
-            PRESENT_MODE_TEXT, PRESENT_MODE_LONGTEXT, false)
-            change_integer_list(present_values, present_text)
 vlc_module_end ()
 
 // Update the renderer settings based on the current configuration.
@@ -655,77 +563,77 @@ static void UpdateParams(vout_display_t *vd)
     vout_display_sys_t *sys = vd->sys;
 
     sys->deband = pl_deband_default_params;
-    sys->deband.iterations = var_InheritInteger(vd, "iterations");
-    sys->deband.threshold = var_InheritFloat(vd, "threshold");
-    sys->deband.radius = var_InheritFloat(vd, "radius");
-    sys->deband.grain = var_InheritFloat(vd, "grain");
+    sys->deband.iterations = var_InheritInteger(vd, "pl-iterations");
+    sys->deband.threshold = var_InheritFloat(vd, "pl-threshold");
+    sys->deband.radius = var_InheritFloat(vd, "pl-radius");
+    sys->deband.grain = var_InheritFloat(vd, "pl-grain");
     bool use_deband = sys->deband.iterations > 0 || sys->deband.grain > 0;
-    use_deband &= var_InheritBool(vd, "debanding");
+    use_deband &= var_InheritBool(vd, "pl-debanding");
 
     sys->sigmoid = pl_sigmoid_default_params;
-    sys->sigmoid.center = var_InheritFloat(vd, "sigmoid-center");
-    sys->sigmoid.slope = var_InheritFloat(vd, "sigmoid-slope");
-    bool use_sigmoid = var_InheritBool(vd, "sigmoid");
+    sys->sigmoid.center = var_InheritFloat(vd, "pl-sigmoid-center");
+    sys->sigmoid.slope = var_InheritFloat(vd, "pl-sigmoid-slope");
+    bool use_sigmoid = var_InheritBool(vd, "pl-sigmoid");
 
     sys->color_map = pl_color_map_default_params;
-    sys->color_map.intent = var_InheritInteger(vd, "intent");
-    sys->color_map.tone_mapping_algo = var_InheritInteger(vd, "tone-mapping");
-    sys->color_map.tone_mapping_param = var_InheritFloat(vd, "tone-mapping-param");
+    sys->color_map.intent = var_InheritInteger(vd, "pl-intent");
+    sys->color_map.tone_mapping_algo = var_InheritInteger(vd, "pl-tone-mapping");
+    sys->color_map.tone_mapping_param = var_InheritFloat(vd, "pl-tone-mapping-param");
 #if PL_API_VER >= 10
-    sys->color_map.desaturation_strength = var_InheritFloat(vd, "desat-strength");
-    sys->color_map.desaturation_exponent = var_InheritFloat(vd, "desat-exponent");
-    sys->color_map.desaturation_base = var_InheritFloat(vd, "desat-base");
-    sys->color_map.max_boost = var_InheritFloat(vd, "max-boost");
+    sys->color_map.desaturation_strength = var_InheritFloat(vd, "pl-desat-strength");
+    sys->color_map.desaturation_exponent = var_InheritFloat(vd, "pl-desat-exponent");
+    sys->color_map.desaturation_base = var_InheritFloat(vd, "pl-desat-base");
+    sys->color_map.max_boost = var_InheritFloat(vd, "pl-max-boost");
 #else
-    sys->color_map.tone_mapping_desaturate = var_InheritFloat(vd, "tone-mapping-desat");
+    sys->color_map.tone_mapping_desaturate = var_InheritFloat(vd, "pl-tone-mapping-desat");
 #endif
-    sys->color_map.gamut_warning = var_InheritBool(vd, "gamut-warning");
+    sys->color_map.gamut_warning = var_InheritBool(vd, "pl-gamut-warning");
 #if PL_API_VER < 12
-    sys->color_map.peak_detect_frames = var_InheritInteger(vd, "peak-frames");
-    sys->color_map.scene_threshold = var_InheritFloat(vd, "scene-threshold");
+    sys->color_map.peak_detect_frames = var_InheritInteger(vd, "pl-peak-frames");
+    sys->color_map.scene_threshold = var_InheritFloat(vd, "pl-scene-threshold");
 #endif
 
     sys->dither = pl_dither_default_params;
-    int method = var_InheritInteger(vd, "dither");
+    int method = var_InheritInteger(vd, "pl-dither");
     bool use_dither = method >= 0;
     sys->dither.method = use_dither ? method : 0;
-    sys->dither.lut_size = var_InheritInteger(vd, "dither-size");
-    sys->dither.temporal = var_InheritBool(vd, "temporal-dither");
+    sys->dither.lut_size = var_InheritInteger(vd, "pl-dither-size");
+    sys->dither.temporal = var_InheritBool(vd, "pl-temporal-dither");
 
     sys->params = pl_render_default_params;
     sys->params.deband_params = use_deband ? &sys->deband : NULL;
     sys->params.sigmoid_params = use_sigmoid ? &sys->sigmoid : NULL;
     sys->params.color_map_params = &sys->color_map;
     sys->params.dither_params = use_dither ? &sys->dither : NULL;
-    sys->params.lut_entries = var_InheritInteger(vd, "lut-entries");
-    sys->params.antiringing_strength = var_InheritFloat(vd, "antiringing");
-    sys->params.skip_anti_aliasing = var_InheritBool(vd, "skip-aa");
-    sys->params.polar_cutoff = var_InheritFloat(vd, "polar-cutoff");
-    sys->params.disable_overlay_sampling = var_InheritBool(vd, "overlay-direct");
-    sys->params.disable_linear_scaling = var_InheritBool(vd, "disable-linear");
-    sys->params.disable_builtin_scalers = var_InheritBool(vd, "force-general");
+    sys->params.lut_entries = var_InheritInteger(vd, "pl-lut-entries");
+    sys->params.antiringing_strength = var_InheritFloat(vd, "pl-antiringing");
+    sys->params.skip_anti_aliasing = var_InheritBool(vd, "pl-skip-aa");
+    sys->params.polar_cutoff = var_InheritFloat(vd, "pl-polar-cutoff");
+    sys->params.disable_overlay_sampling = var_InheritBool(vd, "pl-overlay-direct");
+    sys->params.disable_linear_scaling = var_InheritBool(vd, "pl-disable-linear");
+    sys->params.disable_builtin_scalers = var_InheritBool(vd, "pl-force-general");
 
 #if PL_API_VER >= 13
-    sys->peak_detect.smoothing_period = var_InheritFloat(vd, "peak-period");
-    sys->peak_detect.scene_threshold_low = var_InheritFloat(vd, "scene-threshold-low");
-    sys->peak_detect.scene_threshold_high = var_InheritFloat(vd, "scene-threshold-high");
+    sys->peak_detect.smoothing_period = var_InheritFloat(vd, "pl-peak-period");
+    sys->peak_detect.scene_threshold_low = var_InheritFloat(vd, "pl-scene-threshold-low");
+    sys->peak_detect.scene_threshold_high = var_InheritFloat(vd, "pl-scene-threshold-high");
     if (sys->peak_detect.smoothing_period > 0.0) {
         sys->params.peak_detect_params = &sys->peak_detect;
-        sys->params.allow_delayed_peak_detect = var_InheritBool(vd, "delayed-peak");
+        sys->params.allow_delayed_peak_detect = var_InheritBool(vd, "pl-delayed-peak");
     }
 #endif
 
-    int preset = var_InheritInteger(vd, "upscaler-preset");
+    int preset = var_InheritInteger(vd, "pl-upscaler-preset");
     sys->params.upscaler = scale_config[preset];
     if (preset == SCALE_CUSTOM) {
         sys->params.upscaler = &sys->upscaler;
         sys->upscaler = (struct pl_filter_config) {
-            .kernel = filter_fun[var_InheritInteger(vd, "upscaler-kernel")],
-            .window = filter_fun[var_InheritInteger(vd, "upscaler-window")],
-            .clamp  = var_InheritFloat(vd, "upscaler-clamp"),
-            .blur   = var_InheritFloat(vd, "upscaler-blur"),
-            .taper  = var_InheritFloat(vd, "upscaler-taper"),
-            .polar  = var_InheritBool(vd, "upscaler-polar"),
+            .kernel = filter_fun[var_InheritInteger(vd, "pl-upscaler-kernel")],
+            .window = filter_fun[var_InheritInteger(vd, "pl-upscaler-window")],
+            .clamp  = var_InheritFloat(vd, "pl-upscaler-clamp"),
+            .blur   = var_InheritFloat(vd, "pl-upscaler-blur"),
+            .taper  = var_InheritFloat(vd, "pl-upscaler-taper"),
+            .polar  = var_InheritBool(vd, "pl-upscaler-polar"),
         };
 
         if (!sys->upscaler.kernel) {
@@ -734,17 +642,17 @@ static void UpdateParams(vout_display_t *vd)
         }
     };
 
-    preset = var_InheritInteger(vd, "downscaler-preset");
+    preset = var_InheritInteger(vd, "pl-downscaler-preset");
     sys->params.downscaler = scale_config[preset];
     if (preset == SCALE_CUSTOM) {
         sys->params.downscaler = &sys->downscaler;
         sys->downscaler = (struct pl_filter_config) {
-            .kernel = filter_fun[var_InheritInteger(vd, "downscaler-kernel")],
-            .window = filter_fun[var_InheritInteger(vd, "downscaler-window")],
-            .clamp  = var_InheritFloat(vd, "downscaler-clamp"),
-            .blur   = var_InheritFloat(vd, "downscaler-blur"),
-            .taper  = var_InheritFloat(vd, "downscaler-taper"),
-            .polar  = var_InheritBool(vd, "downscaler-polar"),
+            .kernel = filter_fun[var_InheritInteger(vd, "pl-downscaler-kernel")],
+            .window = filter_fun[var_InheritInteger(vd, "pl-downscaler-window")],
+            .clamp  = var_InheritFloat(vd, "pl-downscaler-clamp"),
+            .blur   = var_InheritFloat(vd, "pl-downscaler-blur"),
+            .taper  = var_InheritFloat(vd, "pl-downscaler-taper"),
+            .polar  = var_InheritBool(vd, "pl-downscaler-polar"),
         };
 
         if (!sys->downscaler.kernel) {
@@ -753,10 +661,10 @@ static void UpdateParams(vout_display_t *vd)
         }
     };
 
-    sys->dither_depth = var_InheritInteger(vd, "dither-depth");
+    sys->dither_depth = var_InheritInteger(vd, "pl-dither-depth");
     sys->target = (struct pl_color_space) {
-        .primaries = var_InheritInteger(vd, "target-prim"),
-        .transfer = var_InheritInteger(vd, "target-trc"),
-        .sig_avg = var_InheritFloat(vd, "target-avg"),
+        .primaries = var_InheritInteger(vd, "pl-target-prim"),
+        .transfer = var_InheritInteger(vd, "pl-target-trc"),
+        .sig_avg = var_InheritFloat(vd, "pl-target-avg"),
     };
 }


=====================================
modules/video_output/libplacebo/instance.c
=====================================
@@ -0,0 +1,96 @@
+/*****************************************************************************
+ * instance.c: libplacebo instance abstraction
+ *****************************************************************************
+ * Copyright (C) 2021 Niklas Haas
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_modules.h>
+
+#include "instance.h"
+#include "utils.h"
+
+static int vlc_placebo_start(void *func, bool forced, va_list ap)
+{
+    int (*activate)(vlc_placebo_t *, const vout_display_cfg_t *) = func;
+    vlc_placebo_t *pl = va_arg(ap, vlc_placebo_t *);
+    const vout_display_cfg_t *cfg = va_arg(ap, const vout_display_cfg_t *);
+
+    int ret = activate(pl, cfg);
+    /* TODO: vlc_objres_clear, which is not in the public API. */
+    (void)forced;
+    return ret;
+}
+
+/**
+ * Creates a libplacebo context, and swapchain, tied to a window
+ *
+ * @param cfg vout display cfg to use as the swapchain source
+ * @param name module name for libplacebo GPU provider (or NULL for auto)
+ * @return a new context, or NULL on failure
+ */
+vlc_placebo_t *vlc_placebo_Create(const vout_display_cfg_t *cfg, const char *name)
+{
+    vlc_object_t *parent = VLC_OBJECT(cfg->window);
+    vlc_placebo_t *pl = vlc_object_create(parent, sizeof (*pl));
+    if (unlikely(pl == NULL))
+        return NULL;
+
+    pl->sys = NULL;
+    pl->ops = NULL;
+    pl->ctx = vlc_placebo_CreateContext(VLC_OBJECT(pl));
+    pl->module = vlc_module_load(parent, "libplacebo gpu", name, false,
+                                 vlc_placebo_start, pl, cfg);
+
+    if (pl->module == NULL)
+    {
+        vlc_object_delete(pl);
+        return NULL;
+    }
+
+    return pl;
+}
+
+void vlc_placebo_Release(vlc_placebo_t *pl)
+{
+    if (pl->ops)
+        pl->ops->close(pl);
+
+    pl_swapchain_destroy(&pl->swapchain);
+    pl_context_destroy(&pl->ctx);
+
+    /* TODO: use vlc_objres_clear */
+    vlc_object_delete(pl);
+}
+
+int vlc_placebo_MakeCurrent(vlc_placebo_t * pl)
+{
+    if (pl->ops->make_current)
+        return pl->ops->make_current(pl);
+
+    return VLC_SUCCESS;
+}
+
+void vlc_placebo_ReleaseCurrent(vlc_placebo_t *pl)
+{
+    if (pl->ops->release_current)
+        pl->ops->release_current(pl);
+}


=====================================
modules/video_output/libplacebo/instance.h
=====================================
@@ -0,0 +1,65 @@
+/*****************************************************************************
+ * instance.h: libplacebo instance abstraction
+ *****************************************************************************
+ * Copyright (C) 2021 Niklas Haas
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_LIBPLACEBO_INSTANCE_H
+#define VLC_LIBPLACEBO_INSTANCE_H
+
+#include <vlc_common.h>
+#include <vlc_vout_display.h>
+
+#include <libplacebo/context.h>
+#include <libplacebo/swapchain.h>
+#include <libplacebo/gpu.h>
+
+struct vlc_placebo_t;
+struct vlc_placebo_operations
+{
+    void (*close)(struct vlc_placebo_t *);
+
+    // For acquiring/releasing the context on the current thread. (Optional)
+    int (*make_current)(struct vlc_placebo_t *);
+    void (*release_current)(struct vlc_placebo_t *);
+};
+
+typedef struct vlc_placebo_system_t vlc_placebo_system_t;
+
+// Shared struct for libplacebo context / gpu / swapchain
+typedef struct vlc_placebo_t
+{
+    // fields internal to instance.c, should not be touched
+    struct vlc_object_t obj;
+    module_t *module;
+    vlc_placebo_system_t *sys;
+
+    struct pl_context *ctx;
+    const struct pl_gpu *gpu;
+    const struct pl_swapchain *swapchain;
+
+    const struct vlc_placebo_operations *ops;
+} vlc_placebo_t;
+
+vlc_placebo_t *vlc_placebo_Create(const vout_display_cfg_t *, const char*) VLC_USED;
+void vlc_placebo_Release(vlc_placebo_t *);
+
+// Needed around every `pl_gpu` / `pl_swapchain` operation
+int vlc_placebo_MakeCurrent(vlc_placebo_t *);
+void vlc_placebo_ReleaseCurrent(vlc_placebo_t *);
+
+#endif // VLC_LIBPLACEBO_INSTANCE_H


=====================================
modules/video_output/libplacebo/instance_opengl.c
=====================================
@@ -0,0 +1,173 @@
+/**
+ * @file instance_opengl.c
+ * @brief OpenGL specific libplacebo GPU wrapper
+ */
+/*****************************************************************************
+ * Copyright © 2021 Niklas Haas
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_opengl.h>
+
+#include <libplacebo/opengl.h>
+
+#include "instance.h"
+#include "utils.h"
+
+static int InitInstance(vlc_placebo_t *pl, const vout_display_cfg_t *cfg);
+static void CloseInstance(vlc_placebo_t *pl);
+static int MakeCurrent(vlc_placebo_t *pl);
+static void ReleaseCurrent(vlc_placebo_t *pl);
+
+#define GL_TEXT N_("OpenGL extension")
+#define GLES2_TEXT N_("OpenGL ES 2 extension")
+#define PROVIDER_LONGTEXT N_( \
+    "Extension through which to use the Open Graphics Library (OpenGL).")
+
+#define ALLOWSW_TEXT "Allow software rasterizers"
+#define ALLOWSW_LONGTEXT "If enabled, allow the use of OpenGL contexts detected as software rasterizers (e.g. llvmpipe, swrast)."
+
+#define SWAP_DEPTH_TEXT "Maximum frame latency"
+#define SWAP_DEPTH_LONGTEXT "Attempt limiting the maximum frame latency. The true frame latency may be lower than this setting, depending on OpenGL driver internals and the VLC clock settings."
+
+vlc_module_begin()
+    set_category(CAT_VIDEO)
+    set_subcategory(SUBCAT_VIDEO_VOUT)
+    set_capability("libplacebo gpu", 40)
+    set_callback(InitInstance)
+#ifdef USE_OPENGL_ES2
+# define API VLC_OPENGL_ES2
+# define MODULE_VARNAME "pl-gles2"
+    set_shortname("libplacebo OpenGL ES2")
+    set_description(N_("OpenGL ES2 based GPU instance"))
+    add_shortcut("pl_opengles2", "pl_gles2")
+    add_module(MODULE_VARNAME, "opengl es2", NULL, GLES2_TEXT, PROVIDER_LONGTEXT);
+#else // !USE_OPENGL_ES2
+# define API VLC_OPENGL
+# define MODULE_VARNAME "pl-gl"
+    set_shortname("libplacebo OpenGL")
+    set_description(N_("OpenGL based GPU instance"))
+    add_shortcut("pl_opengl", "pl_gl")
+    add_module(MODULE_VARNAME, "opengl", NULL, GL_TEXT, PROVIDER_LONGTEXT);
+#endif
+
+    set_section("Context settings", NULL)
+#if PL_API_VER >= 90
+    add_bool("gl-allow-sw", false, ALLOWSW_TEXT, ALLOWSW_LONGTEXT, false)
+#endif
+    add_integer_with_range("gl-swap-depth", 0,
+            0, 4, SWAP_DEPTH_TEXT, SWAP_DEPTH_LONGTEXT, false)
+vlc_module_end()
+
+struct vlc_placebo_system_t {
+    vlc_gl_t *gl;
+    const struct pl_opengl *opengl;
+};
+
+static const struct vlc_placebo_operations instance_opts =
+{
+    .close = CloseInstance,
+    .make_current = MakeCurrent,
+    .release_current = ReleaseCurrent,
+};
+
+static int InitInstance(vlc_placebo_t *pl, const vout_display_cfg_t *cfg)
+{
+    vlc_placebo_system_t *sys = pl->sys =
+        vlc_obj_calloc(VLC_OBJECT(pl), 1, sizeof (*sys));
+    if (unlikely(sys == NULL))
+        return VLC_ENOMEM;
+
+    bool current = false;
+
+    char *name = var_InheritString(pl, MODULE_VARNAME);
+    sys->gl = vlc_gl_Create(cfg, API, name);
+    free(name);
+    if (!sys->gl || vlc_gl_MakeCurrent(sys->gl) != VLC_SUCCESS)
+        goto error;
+
+    current = true;
+
+    // Create OpenGL wrapper
+    sys->opengl = pl_opengl_create(pl->ctx, &(struct pl_opengl_params) {
+#if PL_API_VER >= 90
+        .allow_software = var_InheritBool(pl, "gl-allow-sw"),
+#endif
+        .debug = true, // this only sets up the debug report callback
+    });
+    vlc_gl_ReleaseCurrent (sys->gl);
+    if (!sys->opengl)
+        goto error;
+
+
+    // Create swapchain for this surface
+    struct pl_opengl_swapchain_params swap_params = {
+        .swap_buffers = (void (*)(void *)) vlc_gl_Swap,
+        .max_swapchain_depth = var_InheritInteger(pl, "gl-swap-depth"),
+        .priv = sys->gl,
+    };
+
+    pl->swapchain = pl_opengl_create_swapchain(sys->opengl, &swap_params);
+    if (!pl->swapchain)
+        goto error;
+
+    vlc_gl_ReleaseCurrent(sys->gl);
+
+    pl->gpu = sys->opengl->gpu;
+    pl->ops = &instance_opts;
+    return VLC_SUCCESS;
+
+error:
+    if (current)
+        vlc_gl_ReleaseCurrent(sys->gl);
+    CloseInstance(pl);
+    return VLC_EGENERIC;
+}
+
+static void CloseInstance(vlc_placebo_t *pl)
+{
+    vlc_placebo_system_t *sys = pl->sys;
+
+    if (sys->gl != NULL) {
+        if (vlc_gl_MakeCurrent(sys->gl) == VLC_SUCCESS) {
+            pl_opengl_destroy(&sys->opengl);
+            vlc_gl_ReleaseCurrent(sys->gl);
+        }
+
+        vlc_gl_Release(sys->gl);
+    }
+
+    vlc_obj_free(VLC_OBJECT(pl), sys);
+    pl->sys = NULL;
+}
+
+static int MakeCurrent(vlc_placebo_t *pl)
+{
+    vlc_placebo_system_t *sys = pl->sys;
+    return vlc_gl_MakeCurrent(sys->gl);
+}
+
+static void ReleaseCurrent(vlc_placebo_t *pl)
+{
+    vlc_placebo_system_t *sys = pl->sys;
+    vlc_gl_ReleaseCurrent(sys->gl);
+}


=====================================
modules/video_output/libplacebo/instance_vulkan.c
=====================================
@@ -0,0 +1,196 @@
+/**
+ * @file instance_vulkan.c
+ * @brief Vulkan specific libplacebo GPU wrapper
+ */
+/*****************************************************************************
+ * Copyright © 2021 Niklas Haas
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+
+#include <libplacebo/vulkan.h>
+
+#include "../vulkan/platform.h"
+#include "instance.h"
+#include "utils.h"
+
+struct vlc_placebo_system_t {
+    vlc_vk_platform_t *platform;
+    const struct pl_vk_inst *instance;
+    const struct pl_vulkan *vulkan;
+};
+
+static void CloseInstance(vlc_placebo_t *pl);
+static const struct vlc_placebo_operations instance_opts =
+{
+    .close = CloseInstance,
+};
+
+static int InitInstance(vlc_placebo_t *pl, const vout_display_cfg_t *cfg)
+{
+    vlc_placebo_system_t *sys = pl->sys =
+        vlc_obj_calloc(VLC_OBJECT(pl), 1, sizeof (*sys));
+    if (unlikely(sys == NULL))
+        return VLC_ENOMEM;
+
+    char *platform_name = var_InheritString(pl, "vk-platform");
+    sys->platform = vlc_vk_platform_Create(cfg->window, platform_name);
+    free(platform_name);
+    if (!sys->platform)
+        goto error;
+
+    sys->instance = pl_vk_inst_create(pl->ctx, &(struct pl_vk_inst_params) {
+        .debug = var_InheritBool(pl, "vk-debug"),
+        .extensions = (const char *[]) {
+            VK_KHR_SURFACE_EXTENSION_NAME,
+            sys->platform->platform_ext,
+        },
+        .num_extensions = 2,
+    });
+    if (!sys->instance)
+        goto error;
+
+    // Create the platform-specific surface object
+    VkSurfaceKHR surface;
+    if (vlc_vk_CreateSurface(sys->platform, sys->instance->instance, &surface) != VLC_SUCCESS)
+        goto error;
+
+    // Create vulkan device
+    char *device_name = var_InheritString(pl, "vk-device");
+    sys->vulkan = pl_vulkan_create(pl->ctx, &(struct pl_vulkan_params) {
+        .instance = sys->instance->instance,
+        .surface = surface,
+        .device_name = device_name,
+        .allow_software = var_InheritBool(pl, "vk-allow-sw"),
+        .async_transfer = var_InheritBool(pl, "vk-async-xfer"),
+        .async_compute = var_InheritBool(pl, "vk-async-comp"),
+        .queue_count = var_InheritInteger(pl, "vk-queue-count"),
+    });
+    free(device_name);
+    if (!sys->vulkan)
+        goto error;
+
+    // Create swapchain for this surface
+    struct pl_vulkan_swapchain_params swap_params = {
+        .surface = surface,
+        .present_mode = var_InheritInteger(pl, "vk-present-mode"),
+        .swapchain_depth = var_InheritInteger(pl, "vk-queue-depth"),
+    };
+
+    pl->swapchain = pl_vulkan_create_swapchain(sys->vulkan, &swap_params);
+    if (!pl->swapchain)
+        goto error;
+
+    pl->gpu = sys->vulkan->gpu;
+    pl->ops = &instance_opts;
+    return VLC_SUCCESS;
+
+error:
+    CloseInstance(pl);
+    return VLC_EGENERIC;
+}
+
+static void CloseInstance(vlc_placebo_t *pl)
+{
+    vlc_placebo_system_t *sys = pl->sys;
+
+    pl_vulkan_destroy(&sys->vulkan);
+    pl_vk_inst_destroy(&sys->instance);
+
+    if (sys->platform != NULL)
+        vlc_vk_platform_Release(sys->platform);
+
+    vlc_obj_free(VLC_OBJECT(pl), sys);
+    pl->sys = NULL;
+}
+
+#define PROVIDER_TEXT N_("Vulkan platform module")
+#define PROVIDER_LONGTEXT N_( \
+    "Which platform-specific Vulkan surface module to load.")
+
+#define DEBUG_TEXT "Enable API debugging"
+#define DEBUG_LONGTEXT "This loads the vulkan standard validation layers, which can help catch API usage errors. Comes at a small performance penalty."
+
+#define DEVICE_TEXT "Device name override"
+#define DEVICE_LONGTEXT "If set to something non-empty, only a device with this exact name will be used. To see a list of devices and their names, run vlc -v with this module active."
+
+#define ALLOWSW_TEXT "Allow software devices"
+#define ALLOWSW_LONGTEXT "If enabled, allow the use of software emulation devices, which are not real devices and therefore typically very slow. (This option has no effect if forcing a specific device name)"
+
+#define ASYNC_XFER_TEXT "Allow asynchronous transfer"
+#define ASYNC_XFER_LONGTEXT "Allows the use of an asynchronous transfer queue if the device has one. Typically this maps to a DMA engine, which can perform texture uploads/downloads without blocking the GPU's compute units. Highly recommended for 4K and above."
+
+#define ASYNC_COMP_TEXT "Allow asynchronous compute"
+#define ASYNC_COMP_LONGTEXT "Allows the use of dedicated compute queue families if the device has one. Sometimes these will schedule concurrent compute work better than the main graphics queue. Turn this off if you have any issues."
+
+#define QUEUE_COUNT_TEXT "Queue count"
+#define QUEUE_COUNT_LONGTEXT "How many queues to use on the device. Increasing this might improve rendering throughput for GPUs capable of concurrent scheduling. Increasing this past the driver's limit has no effect."
+
+#define QUEUE_DEPTH_TEXT "Maximum frame latency"
+#define QUEUE_DEPTH_LONGTEXT "Affects how many frames to render/present in advance. Increasing this can improve performance at the cost of latency, by allowing better pipelining between frames. May have no effect, depending on the VLC clock settings."
+
+static const int present_values[] = {
+    VK_PRESENT_MODE_IMMEDIATE_KHR,
+    VK_PRESENT_MODE_MAILBOX_KHR,
+    VK_PRESENT_MODE_FIFO_KHR,
+    VK_PRESENT_MODE_FIFO_RELAXED_KHR,
+};
+
+static const char * const present_text[] = {
+    "Immediate (non-blocking, tearing)",
+    "Mailbox (non-blocking, non-tearing)",
+    "FIFO (blocking, non-tearing)",
+    "Relaxed FIFO (blocking, tearing)",
+};
+
+#define PRESENT_MODE_TEXT "Preferred present mode"
+#define PRESENT_MODE_LONGTEXT "Which present mode to use when creating the swapchain. If the chosen mode is not supported, VLC will fall back to using FIFO."
+
+vlc_module_begin()
+    set_shortname("libplacebo Vulkan")
+    set_description(N_("Vulkan-based GPU instance"))
+    set_category(CAT_VIDEO)
+    set_subcategory(SUBCAT_VIDEO_VOUT)
+    set_capability("libplacebo gpu", 50)
+    set_callback(InitInstance)
+    add_shortcut("pl_vulkan")
+    add_module ("vk-platform", "vulkan platform", NULL, PROVIDER_TEXT, PROVIDER_LONGTEXT)
+
+    set_section("Device selection", NULL)
+    add_bool("vk-debug", false, DEBUG_TEXT, DEBUG_LONGTEXT, false)
+    add_string("vk-device", "", DEVICE_TEXT, DEVICE_LONGTEXT, false)
+    add_bool("vk-allow-sw", pl_vulkan_default_params.allow_software,
+            ALLOWSW_TEXT, ALLOWSW_LONGTEXT, false)
+
+    set_section("Performance tuning", NULL)
+    add_bool("vk-async-xfer", pl_vulkan_default_params.async_transfer,
+            ASYNC_XFER_TEXT, ASYNC_XFER_LONGTEXT, false)
+    add_bool("vk-async-comp", pl_vulkan_default_params.async_compute,
+            ASYNC_COMP_TEXT, ASYNC_COMP_LONGTEXT, false)
+    add_integer_with_range("vk-queue-count", pl_vulkan_default_params.queue_count,
+            1, 8, QUEUE_COUNT_TEXT, QUEUE_COUNT_LONGTEXT, false)
+    add_integer_with_range("vk-queue-depth", 3,
+            1, 8, QUEUE_DEPTH_TEXT, QUEUE_DEPTH_LONGTEXT, false)
+    add_integer("vk-present-mode", VK_PRESENT_MODE_FIFO_KHR,
+            PRESENT_MODE_TEXT, PRESENT_MODE_LONGTEXT, false)
+            change_integer_list(present_values, present_text)
+vlc_module_end()


=====================================
modules/video_output/placebo_utils.c → modules/video_output/libplacebo/utils.c
=====================================
@@ -27,7 +27,7 @@
 #include <stdlib.h>
 
 #include <vlc_common.h>
-#include "placebo_utils.h"
+#include "utils.h"
 
 static void Log(void *priv, enum pl_log_level level, const char *msg)
 {
@@ -43,7 +43,7 @@ static void Log(void *priv, enum pl_log_level level, const char *msg)
     }
 }
 
-struct pl_context *vlc_placebo_Create(vlc_object_t *obj)
+struct pl_context *vlc_placebo_CreateContext(vlc_object_t *obj)
 {
     return pl_context_create(PL_API_VER, &(struct pl_context_params) {
         .log_level = PL_LOG_DEBUG,


=====================================
modules/video_output/placebo_utils.h → modules/video_output/libplacebo/utils.h
=====================================
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * placebo_utils.h: Definition of various libplacebo helpers
+ * utils.h: Definition of various libplacebo helpers
  *****************************************************************************
  * Copyright (C) 2018 Niklas Haas
  *
@@ -29,7 +29,7 @@
 #include <libplacebo/utils/upload.h>
 
 // Create a libplacebo context, hooked up to the log system; or NULL on OOM
-struct pl_context *vlc_placebo_Create(vlc_object_t *);
+struct pl_context *vlc_placebo_CreateContext(vlc_object_t *);
 
 // Turn a video_format_t into the equivalent libplacebo values
 struct pl_color_space vlc_placebo_ColorSpace(const video_format_t *);


=====================================
modules/video_output/opengl/Makefile.am
=====================================
@@ -23,13 +23,14 @@ OPENGL_COMMONSOURCES = video_output/opengl/vout_helper.c \
        video_output/opengl/sampler_priv.h \
        video_output/opengl/sub_renderer.c \
        video_output/opengl/sub_renderer.h
-if HAVE_LIBPLACEBO
-OPENGL_COMMONSOURCES += video_output/placebo_utils.c video_output/placebo_utils.h
-endif
 
 OPENGL_COMMONCFLAGS = $(LIBPLACEBO_CFLAGS)
 OPENGL_COMMONLIBS = $(LIBPLACEBO_LIBS)
 
+if HAVE_LIBPLACEBO
+OPENGL_COMMONLIBS += libplacebo_utils.la
+endif
+
 # Convenience library for OpenGL components -- OpenGL only
 libvlc_opengl_la_SOURCES = $(OPENGL_COMMONSOURCES)
 libvlc_opengl_la_CFLAGS = $(OPENGL_COMMONCFLAGS)


=====================================
modules/video_output/opengl/sampler.c
=====================================
@@ -31,7 +31,7 @@
 #ifdef HAVE_LIBPLACEBO
 #include <libplacebo/shaders.h>
 #include <libplacebo/shaders/colorspace.h>
-#include "../placebo_utils.h"
+#include "../libplacebo/utils.h"
 #endif
 
 #include "gl_api.h"
@@ -1140,7 +1140,7 @@ CreateSampler(struct vlc_gl_interop *interop, struct vlc_gl_t *gl,
 
 #ifdef HAVE_LIBPLACEBO
     // Create the main libplacebo context
-    priv->pl_ctx = vlc_placebo_Create(VLC_OBJECT(gl));
+    priv->pl_ctx = vlc_placebo_CreateContext(VLC_OBJECT(gl));
     if (priv->pl_ctx) {
 #   if PL_API_VER >= 20
         priv->pl_sh = pl_shader_alloc(priv->pl_ctx, &(struct pl_shader_params) {


=====================================
modules/video_output/opengl/vout_helper.h
=====================================
@@ -32,7 +32,7 @@
 #include "gl_common.h"
 
 #ifdef HAVE_LIBPLACEBO
-#include "../placebo_utils.h"
+#include "../libplacebo/utils.h"
 
 
 #if PL_API_VER >= 10


=====================================
modules/video_output/vulkan/Makefile.am
=====================================
@@ -1,10 +1,8 @@
 
 ### Vulkan ###
 
-VULKAN_COMMONSOURCES = video_output/vulkan/instance.c \
-	video_output/vulkan/instance.h \
-	video_output/placebo_utils.c \
-	video_output/placebo_utils.h
+VULKAN_COMMONSOURCES = video_output/vulkan/platform.c \
+	video_output/vulkan/platform.h
 
 # Trigger the c++ linker because of glslang dependency of libplacebo
 VULKAN_COMMONSOURCES += dummy.cpp
@@ -12,10 +10,6 @@ VULKAN_COMMONSOURCES += dummy.cpp
 VULKAN_COMMONCFLAGS = $(VULKAN_CFLAGS) $(LIBPLACEBO_CFLAGS)
 VULKAN_COMMONLIBS = $(VULKAN_LIBS) $(LIBPLACEBO_LIBS)
 
-libvk_plugin_la_SOURCES = $(VULKAN_COMMONSOURCES) video_output/vulkan/display.c
-libvk_plugin_la_CFLAGS = $(AM_CFLAGS) $(VULKAN_COMMONCFLAGS)
-libvk_plugin_la_LIBADD = $(VULKAN_COMMONLIBS)
-
 libvk_win32_plugin_la_SOURCES = $(VULKAN_COMMONSOURCES) \
 				video_output/vulkan/platform_win32.c
 libvk_win32_plugin_la_CFLAGS = $(AM_CFLAGS) $(VULKAN_COMMONCFLAGS) \
@@ -29,8 +23,6 @@ libvk_android_plugin_la_CFLAGS = $(AM_CFLAGS) $(VULKAN_COMMONCFLAGS) \
 libvk_android_plugin_la_LIBADD = $(VULKAN_COMMONLIBS)
 
 if HAVE_VULKAN
-vout_LTLIBRARIES += libvk_plugin.la
-
 if HAVE_WIN32_DESKTOP
 vout_LTLIBRARIES += libvk_win32_plugin.la
 endif


=====================================
modules/video_output/vulkan/instance.c → modules/video_output/vulkan/platform.c
=====================================
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * instance.c: Vulkan instance abstraction
+ * platform.c: Vulkan platform abstraction
  *****************************************************************************
  * Copyright (C) 2018 Niklas Haas
  *
@@ -27,14 +27,13 @@
 
 #include <vlc_common.h>
 #include <vlc_modules.h>
-#include <vlc_atomic.h>
 
-#include "instance.h"
+#include "platform.h"
 
 static int vlc_vk_start(void *func, bool forced, va_list ap)
 {
-    int (*activate)(vlc_vk_t *vk) = func;
-    vlc_vk_t *vk = va_arg(ap, vlc_vk_t *);
+    int (*activate)(vlc_vk_platform_t *vk) = func;
+    vlc_vk_platform_t *vk = va_arg(ap, vlc_vk_platform_t *);
 
     int ret = activate(vk);
     /* TODO: vlc_objres_clear, which is not in the public API. */
@@ -43,16 +42,16 @@ static int vlc_vk_start(void *func, bool forced, va_list ap)
 }
 
 /**
- * Creates a Vulkan surface (and its underlying instance).
+ * Initializes a Vulkan platform module for a given window
  *
  * @param wnd window to use as Vulkan surface
  * @param name module name (or NULL for auto)
- * @return a new context, or NULL on failure
+ * @return a new platform object, or NULL on failure
  */
-vlc_vk_t *vlc_vk_Create(struct vout_window_t *wnd, const char *name)
+vlc_vk_platform_t *vlc_vk_platform_Create(struct vout_window_t *wnd, const char *name)
 {
     vlc_object_t *parent = (vlc_object_t *) wnd;
-    struct vlc_vk_t *vk;
+    struct vlc_vk_platform_t *vk;
 
     vk = vlc_object_create(parent, sizeof (*vk));
     if (unlikely(vk == NULL))
@@ -70,21 +69,12 @@ vlc_vk_t *vlc_vk_Create(struct vout_window_t *wnd, const char *name)
         vlc_object_delete(vk);
         return NULL;
     }
-    vlc_atomic_rc_init(&vk->ref_count);
 
     return vk;
 }
 
-void vlc_vk_Hold(vlc_vk_t *vk)
+void vlc_vk_platform_Release(vlc_vk_platform_t *vk)
 {
-    vlc_atomic_rc_inc(&vk->ref_count);
-}
-
-void vlc_vk_Release(vlc_vk_t *vk)
-{
-    if (!vlc_atomic_rc_dec(&vk->ref_count))
-        return;
-
     if (vk->ops)
         vk->ops->close(vk);
 


=====================================
modules/video_output/vulkan/instance.h → modules/video_output/vulkan/platform.h
=====================================
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * instance.h: Vulkan instance abstraction
+ * platform.h: Vulkan platform abstraction
  *****************************************************************************
  * Copyright (C) 2018 Niklas Haas
  *
@@ -18,50 +18,44 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-#ifndef VLC_VULKAN_INSTANCE_H
-#define VLC_VULKAN_INSTANCE_H
+#ifndef VLC_VULKAN_PLATFORM_H
+#define VLC_VULKAN_PLATFORM_H
 
 #include <vlc_common.h>
-#include <vlc_atomic.h>
 #include <vlc_vout_window.h>
 
 #include <vulkan/vulkan.h>
-#include <libplacebo/vulkan.h>
 
-struct vout_window_t;
-struct vout_window_cfg_t;
-
-struct vlc_vk_t;
-struct vlc_vk_operations
+struct vlc_vk_platform_t;
+struct vlc_vk_platform_operations
 {
-    void (*close)(struct vlc_vk_t *);
-    int (*create_surface)(struct vlc_vk_t *, VkInstance, VkSurfaceKHR *);
+    void (*close)(struct vlc_vk_platform_t *);
+    int (*create_surface)(struct vlc_vk_platform_t *, VkInstance, VkSurfaceKHR *);
 };
 
 
-// Shared struct for vulkan instance / surface / device state
-typedef struct vlc_vk_t
+// Struct for platform-specific Vulkan state
+typedef struct vlc_vk_platform_t
 {
-    // fields internal to instance.c, should not be touched
+    // set by platform.c
     struct vlc_object_t obj;
+    struct vout_window_t *window;
     module_t *module;
-    vlc_atomic_rc_t ref_count;
+
+    // set by the platform
     void *platform_sys;
     const char *platform_ext;
+    const struct vlc_vk_platform_operations *ops;
+} vlc_vk_platform_t;
 
-    struct vout_window_t *window;
-
-    const struct vlc_vk_operations *ops;
-} vlc_vk_t;
-
-vlc_vk_t *vlc_vk_Create(struct vout_window_t *, const char *) VLC_USED;
-void vlc_vk_Release(vlc_vk_t *);
-void vlc_vk_Hold(vlc_vk_t *);
+vlc_vk_platform_t *vlc_vk_platform_Create(struct vout_window_t *, const char *) VLC_USED;
+void vlc_vk_platform_Release(vlc_vk_platform_t *);
 
-// Create a vulkan surface to vk->surface
-static inline int vlc_vk_CreateSurface(vlc_vk_t * vk, VkInstance instance, VkSurfaceKHR *surface_out)
+// Create a vulkan surface and store it to `surface_out`
+static inline int vlc_vk_CreateSurface(vlc_vk_platform_t * vk, VkInstance instance,
+                                       VkSurfaceKHR *surface_out)
 {
     return vk->ops->create_surface(vk, instance, surface_out);
 }
 
-#endif // VLC_VULKAN_INSTANCE_H
+#endif // VLC_VULKAN_PLATFORM_H


=====================================
modules/video_output/vulkan/platform_android.c
=====================================
@@ -27,18 +27,18 @@
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 
-#include "instance.h"
+#include "platform.h"
 #include "../android/utils.h"
 
-static void ClosePlatform(vlc_vk_t *vk);
-static int CreateSurface(vlc_vk_t *vk);
-static const struct vlc_vk_operations platform_ops =
+static void ClosePlatform(vlc_vk_platform_t *vk);
+static int CreateSurface(vlc_vk_platform_t *vk);
+static const struct vlc_vk_platform_operations platform_ops =
 {
     .close = ClosePlatform,
     .create_surface = CreateSurface,
 };
 
-static int InitPlatform(vlc_vk_t *vk)
+static int InitPlatform(vlc_vk_platform_t *vk)
 {
     if (vk->window->type != VOUT_WINDOW_TYPE_ANDROID_NATIVE)
         return VLC_EGENERIC;
@@ -48,13 +48,13 @@ static int InitPlatform(vlc_vk_t *vk)
     return VLC_SUCCESS;
 }
 
-static void ClosePlatform(vlc_vk_t *vk)
+static void ClosePlatform(vlc_vk_platform_t *vk)
 {
     AWindowHandler_releaseANativeWindow(vk->window->handle.anativewindow,
                                         AWindow_Video);
 }
 
-static int CreateSurface(vlc_vk_t *vk, VkInstance vkinst)
+static int CreateSurface(vlc_vk_platform_t *vk, VkInstance vkinst)
 {
     ANativeWindow *anw =
         AWindowHandler_getANativeWindow(vk->window->handle.anativewindow,


=====================================
modules/video_output/vulkan/platform_win32.c
=====================================
@@ -26,17 +26,17 @@
 
 #include <vlc_common.h>
 #include <vlc_plugin.h>
-#include "instance.h"
+#include "platform.h"
 
-static void ClosePlatform(vlc_vk_t *vk);
-static int CreateSurface(vlc_vk_t *vk);
-static const struct vlc_vk_operations platform_ops =
+static void ClosePlatform(vlc_vk_platform_t *vk);
+static int CreateSurface(vlc_vk_platform_t *vk);
+static const struct vlc_vk_platform_operations platform_ops =
 {
     .close = ClosePlatform,
     .create_surface = CreateSurface,
 };
 
-static int InitPlatform(vlc_vk_t *vk)
+static int InitPlatform(vlc_vk_platform_t *vk)
 {
     if (vk->window->type != VOUT_WINDOW_TYPE_HWND)
         return VLC_EGENERIC;
@@ -46,12 +46,12 @@ static int InitPlatform(vlc_vk_t *vk)
     return VLC_SUCCESS;
 }
 
-static void ClosePlatform(vlc_vk_t *vk)
+static void ClosePlatform(vlc_vk_platform_t *vk)
 {
     VLC_UNUSED(vk);
 }
 
-static int CreateSurface(vlc_vk_t *vk, VkInstance vkinst)
+static int CreateSurface(vlc_vk_platform_t *vk, VkInstance vkinst)
 {
     // Get current win32 HINSTANCE
     HINSTANCE hInst = GetModuleHandle(NULL);


=====================================
modules/video_output/vulkan/platform_xcb.c
=====================================
@@ -27,18 +27,18 @@
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 
-#include "instance.h"
+#include "platform.h"
 
-static void ClosePlatform(vlc_vk_t *vk);
-static int CreateSurface(vlc_vk_t *vk, VkInstance instance, VkSurfaceKHR *surface_out);
+static void ClosePlatform(vlc_vk_platform_t *vk);
+static int CreateSurface(vlc_vk_platform_t *vk, VkInstance instance, VkSurfaceKHR *surface_out);
 
-static const struct vlc_vk_operations platform_ops =
+static const struct vlc_vk_platform_operations platform_ops =
 {
     .close = ClosePlatform,
     .create_surface = CreateSurface,
 };
 
-static int InitPlatform(vlc_vk_t *vk)
+static int InitPlatform(vlc_vk_platform_t *vk)
 {
     if (vk->window->type != VOUT_WINDOW_TYPE_XID)
         return VLC_EGENERIC;
@@ -60,13 +60,13 @@ static int InitPlatform(vlc_vk_t *vk)
     return VLC_SUCCESS;
 }
 
-static void ClosePlatform(vlc_vk_t *vk)
+static void ClosePlatform(vlc_vk_platform_t *vk)
 {
     xcb_connection_t *conn = vk->platform_sys;
     xcb_disconnect(conn);
 }
 
-static int CreateSurface(vlc_vk_t *vk, VkInstance vkinst, VkSurfaceKHR *surface_out)
+static int CreateSurface(vlc_vk_platform_t *vk, VkInstance vkinst, VkSurfaceKHR *surface_out)
 {
     xcb_connection_t *conn = vk->platform_sys;
 


=====================================
modules/video_output/wayland/Makefile.am
=====================================
@@ -74,7 +74,7 @@ libegl_wl_plugin_la_CFLAGS = $(AM_CFLAGS) $(EGL_CFLAGS) $(WAYLAND_EGL_CFLAGS)
 libegl_wl_plugin_la_LIBADD = $(EGL_LIBS) $(WAYLAND_EGL_LIBS)
 
 libvk_wl_plugin_la_SOURCES = \
-	video_output/vulkan/instance.h \
+	video_output/vulkan/platform.h \
 	video_output/wayland/vulkan.c
 libvk_wl_plugin_la_CFLAGS = $(AM_CFLAGS) \
 	$(WAYLAND_CLIENT_CFLAGS) $(VULKAN_COMMONCFLAGS) \


=====================================
modules/video_output/wayland/vulkan.c
=====================================
@@ -27,12 +27,12 @@
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 
-#include "../vulkan/instance.h"
+#include "../vulkan/platform.h"
 
-static void ClosePlatform(vlc_vk_t *vk)
+static void ClosePlatform(vlc_vk_platform_t *vk)
     { (void)vk; }
 
-static int CreateSurface(vlc_vk_t *vk, VkInstance vkinst, VkSurfaceKHR *surface_out)
+static int CreateSurface(vlc_vk_platform_t *vk, VkInstance vkinst, VkSurfaceKHR *surface_out)
 {
     VkWaylandSurfaceCreateInfoKHR surface_info = {
         .sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR,
@@ -49,13 +49,13 @@ static int CreateSurface(vlc_vk_t *vk, VkInstance vkinst, VkSurfaceKHR *surface_
     return VLC_SUCCESS;
 }
 
-static const struct vlc_vk_operations platform_ops =
+static const struct vlc_vk_platform_operations platform_ops =
 {
     .close = ClosePlatform,
     .create_surface = CreateSurface,
 };
 
-static int InitPlatform(vlc_vk_t *vk)
+static int InitPlatform(vlc_vk_platform_t *vk)
 {
     if (vk->window->type != VOUT_WINDOW_TYPE_WAYLAND)
         return VLC_EGENERIC;


=====================================
po/POTFILES.in
=====================================
@@ -1299,11 +1299,13 @@ modules/video_output/decklink.cpp
 modules/video_output/fb.c
 modules/video_output/glx.c
 modules/video_output/kva.c
+modules/video_output/libplacebo/display.c
+modules/video_output/libplacebo/instance_opengl.c
+modules/video_output/libplacebo/instance_vulkan.c
 modules/video_output/macosx.m
 modules/video_output/opengl/display.c
 modules/video_output/opengl/egl.c
 modules/video_output/opengl/vout_helper.h
-modules/video_output/vulkan/display.c
 modules/video_output/win32/direct3d9.c
 modules/video_output/win32/direct3d11.c
 modules/video_output/win32/drawable.c



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/75c26d8b449723db56ff56fd786247db071e692a...ac14138ad213979186e742fe7dc4342569a9ecfd

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/75c26d8b449723db56ff56fd786247db071e692a...ac14138ad213979186e742fe7dc4342569a9ecfd
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list