vaapi: add support for vaapi-win32

Only vaapi-copy variant as nothing can map D3D12 resources currently.

And even if we would add resource sharing to D3D11 it would invoke copy
at some point, so there is no point really. Maybe in the future when
libplacebo get smarter about resource sharing on Windows, but practical
advantages are really small. I've tested it with Vulkan <-> D3D11
sharing and GPU <-> GPU copy is still invoked. Better than CPU memcpy,
something for the future.
This commit is contained in:
Kacper Michajłow 2023-11-08 00:05:40 +01:00 committed by sfan5
parent 73eecdb415
commit 67deebc5b5
4 changed files with 65 additions and 5 deletions

View File

@ -1293,7 +1293,7 @@ Video
or ``--vo=libmpv`` (iOS 9.0 and up) or ``--vo=libmpv`` (iOS 9.0 and up)
:videotoolbox-copy: copies video back into system RAM (macOS 10.8 or iOS 9.0 and up) :videotoolbox-copy: copies video back into system RAM (macOS 10.8 or iOS 9.0 and up)
:vaapi: requires ``--vo=gpu``, ``--vo=vaapi`` or ``--vo=dmabuf-wayland`` (Linux only) :vaapi: requires ``--vo=gpu``, ``--vo=vaapi`` or ``--vo=dmabuf-wayland`` (Linux only)
:vaapi-copy: copies video back into system RAM (Linux with some GPUs only) :vaapi-copy: copies video back into system RAM (Linux with some GPUs or Windows)
:nvdec: requires ``--vo=gpu`` (Any platform CUDA is available) :nvdec: requires ``--vo=gpu`` (Any platform CUDA is available)
:nvdec-copy: copies video back to system RAM (Any platform CUDA is available) :nvdec-copy: copies video back to system RAM (Any platform CUDA is available)
:drm: requires ``--vo=gpu`` (Linux only) :drm: requires ``--vo=gpu`` (Linux only)
@ -1497,10 +1497,13 @@ Video
For the Vulkan GPU backend, decoding must always happen on the display For the Vulkan GPU backend, decoding must always happen on the display
device, and this option has no effect. device, and this option has no effect.
``--vaapi-device=<device file>`` ``--vaapi-device=<device file|adapter name>``
Choose the DRM device for ``vaapi-copy``. This should be the path to a Choose the DRM device for ``vaapi-copy``. This should be the path to a
DRM device file. (Default: ``/dev/dri/renderD128``) DRM device file. (Default: ``/dev/dri/renderD128``)
On Windows this takes adapter name as an input. Will pick the default adapter
if unset. Alternatives are listed when the name "help" is given.
``--panscan=<0.0-1.0>`` ``--panscan=<0.0-1.0>``
Enables pan-and-scan functionality (cropping the sides of e.g. a 16:9 Enables pan-and-scan functionality (cropping the sides of e.g. a 16:9
video to make it fit a 4:3 display without black bands). The range video to make it fit a 4:3 display without black bands). The range

View File

@ -1401,8 +1401,15 @@ if features['vaapi-x11']
sources += files('video/out/vo_vaapi.c') sources += files('video/out/vo_vaapi.c')
endif endif
vaapi_win32 = dependency('libva-win32', required: get_option('vaapi-win32').require(libva.found()))
features += {'vaapi-win32': vaapi_win32.found()}
if features['vaapi-win32']
dependencies += vaapi_win32
endif
vaapi = get_option('vaapi').require(libva.found() and (features['vaapi-drm'] or vaapi = get_option('vaapi').require(libva.found() and (features['vaapi-drm'] or
features['vaapi-wayland'] or features['vaapi-x11'])) features['vaapi-wayland'] or features['vaapi-x11'] or
features['vaapi-win32']))
features += {'vaapi': vaapi.allowed()} features += {'vaapi': vaapi.allowed()}
if features['vaapi'] if features['vaapi']

View File

@ -85,6 +85,7 @@ option('vdpau-gl-x11', type: 'feature', value: 'auto', description: 'VDPAU with
option('vaapi', type: 'feature', value: 'auto', description: 'VAAPI acceleration') option('vaapi', type: 'feature', value: 'auto', description: 'VAAPI acceleration')
option('vaapi-drm', type: 'feature', value: 'auto', description: 'VAAPI (DRM support)') option('vaapi-drm', type: 'feature', value: 'auto', description: 'VAAPI (DRM support)')
option('vaapi-wayland', type: 'feature', value: 'auto', description: 'VAAPI (Wayland support)') option('vaapi-wayland', type: 'feature', value: 'auto', description: 'VAAPI (Wayland support)')
option('vaapi-win32', type: 'feature', value: 'auto', description: 'VAAPI (Windows support)')
option('vaapi-x11', type: 'feature', value: 'auto', description: 'VAAPI (X11 support)') option('vaapi-x11', type: 'feature', value: 'auto', description: 'VAAPI (X11 support)')
option('vulkan', type: 'feature', value: 'auto', description: 'Vulkan context support') option('vulkan', type: 'feature', value: 'auto', description: 'Vulkan context support')
option('wayland', type: 'feature', value: 'auto', description: 'Wayland') option('wayland', type: 'feature', value: 'auto', description: 'Wayland')

View File

@ -29,9 +29,30 @@
#include "mp_image_pool.h" #include "mp_image_pool.h"
#include "options/m_config.h" #include "options/m_config.h"
#ifdef _WIN32
#include "osdep/windows_utils.h"
#include "out/d3d11/context.h"
#include "out/gpu/d3d11_helpers.h"
#endif
#include <libavutil/hwcontext.h> #include <libavutil/hwcontext.h>
#include <libavutil/hwcontext_vaapi.h> #include <libavutil/hwcontext_vaapi.h>
#ifdef _WIN32
#define DEV_PATH_DEFAULT NULL
#define DEV_PATH_VALIDATE mp_dxgi_validate_adapter
#else
#define DEV_PATH_DEFAULT "/dev/dri/renderD128"
#define DEV_PATH_VALIDATE validate_path
static int validate_path(struct mp_log *log,
const struct m_option *opt,
struct bstr name, const char **value)
{
return (*value && **value) ? 0 : M_OPT_INVALID;
}
#endif
struct vaapi_opts { struct vaapi_opts {
char *path; char *path;
}; };
@ -39,11 +60,11 @@ struct vaapi_opts {
#define OPT_BASE_STRUCT struct vaapi_opts #define OPT_BASE_STRUCT struct vaapi_opts
const struct m_sub_options vaapi_conf = { const struct m_sub_options vaapi_conf = {
.opts = (const struct m_option[]) { .opts = (const struct m_option[]) {
{"device", OPT_STRING(path)}, {"device", OPT_STRING_VALIDATE(path, DEV_PATH_VALIDATE)},
{0}, {0},
}, },
.defaults = &(const struct vaapi_opts) { .defaults = &(const struct vaapi_opts) {
.path = "/dev/dri/renderD128", .path = DEV_PATH_DEFAULT,
}, },
.size = sizeof(struct vaapi_opts), .size = sizeof(struct vaapi_opts),
}; };
@ -201,6 +222,31 @@ static const struct va_native_display disp_x11 = {
}; };
#endif #endif
#if HAVE_VAAPI_WIN32
#include <va/va_win32.h>
static void win32_create(struct mp_log *log, VADisplay **out_display,
void **out_native_ctx, const char *path)
{
LUID *luid = NULL;
DXGI_ADAPTER_DESC1 desc = {0};
if (path && path[0]) {
IDXGIAdapter1 *adapter = mp_get_dxgi_adapter(log, bstr0(path), NULL);
if (!adapter || FAILED(IDXGIAdapter1_GetDesc1(adapter, &desc))) {
mp_err(log, "Failed to get adapter LUID for name: %s\n", path);
} else {
luid = &desc.AdapterLuid;
}
SAFE_RELEASE(adapter);
}
*out_display = vaGetDisplayWin32(luid);
}
static const struct va_native_display disp_win32 = {
.create = win32_create,
};
#endif
#if HAVE_VAAPI_DRM #if HAVE_VAAPI_DRM
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
@ -246,6 +292,9 @@ static const struct va_native_display *const native_displays[] = {
#if HAVE_VAAPI_DRM #if HAVE_VAAPI_DRM
&disp_drm, &disp_drm,
#endif #endif
#if HAVE_VAAPI_WIN32
&disp_win32,
#endif
#if HAVE_VAAPI_X11 #if HAVE_VAAPI_X11
&disp_x11, &disp_x11,
#endif #endif