hwdec/dmabuf_interop: refactor out hwdec_vaapi dependencies

With the files renamed, we can now disentangle the shared private
struct between the interops and hwdec_vaapi. We need this separation
to allow the future drmprime hwdec to use the interops.
This commit is contained in:
Philip Langdale 2022-07-31 12:14:44 -07:00 committed by Philip Langdale
parent 06900eef63
commit e9e5059589
4 changed files with 53 additions and 39 deletions

View File

@ -20,21 +20,18 @@
#include <va/va_drmcommon.h>
#include "config.h"
#include "video/vaapi.h"
#include "video/out/gpu/hwdec.h"
struct priv_owner {
struct mp_vaapi_ctx *ctx;
VADisplay *display;
int *formats;
bool probing_formats; // temporary during init
struct dmabuf_interop {
bool use_modifiers;
bool (*interop_init)(struct ra_hwdec_mapper *mapper,
const struct ra_imgfmt_desc *desc);
void (*interop_uninit)(const struct ra_hwdec_mapper *mapper);
bool (*interop_map)(struct ra_hwdec_mapper *mapper, bool probing);
bool (*interop_map)(struct ra_hwdec_mapper *mapper,
struct dmabuf_interop *dmabuf_interop,
bool probing);
void (*interop_unmap)(struct ra_hwdec_mapper *mapper);
};
@ -49,7 +46,10 @@ struct priv {
void *interop_mapper_priv;
};
typedef bool (*dmabuf_interop_init)(const struct ra_hwdec *hw);
typedef bool (*dmabuf_interop_init)(const struct ra_hwdec *hw,
struct dmabuf_interop *dmabuf_interop);
bool dmabuf_interop_gl_init(const struct ra_hwdec *hw);
bool dmabuf_interop_pl_init(const struct ra_hwdec *hw);
bool dmabuf_interop_gl_init(const struct ra_hwdec *hw,
struct dmabuf_interop *dmabuf_interop);
bool dmabuf_interop_pl_init(const struct ra_hwdec *hw,
struct dmabuf_interop *dmabuf_interop);

View File

@ -150,17 +150,18 @@ static void vaapi_gl_mapper_uninit(const struct ra_hwdec_mapper *mapper)
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _OFFSET_EXT, \
p_mapper->desc.layers[n].offset[plane]); \
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _PITCH_EXT, \
p_mapper->desc.layers[n].pitch[plane]); \
if (p_owner->use_modifiers && drm_format_modifier != DRM_FORMAT_MOD_INVALID) { \
p_mapper->desc.layers[n].planes[plane].pitch); \
if (dmabuf_interop->use_modifiers && drm_format_modifier != DRM_FORMAT_MOD_INVALID) { \
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _MODIFIER_LO_EXT, drm_format_modifier & 0xfffffffful); \
ADD_ATTRIB(EGL_DMA_BUF_PLANE ## plane ## _MODIFIER_HI_EXT, drm_format_modifier >> 32); \
} \
} while (0)
static bool vaapi_gl_map(struct ra_hwdec_mapper *mapper, bool probing)
static bool vaapi_gl_map(struct ra_hwdec_mapper *mapper,
struct dmabuf_interop *dmabuf_interop,
bool probing)
{
struct priv *p_mapper = mapper->priv;
struct priv_owner *p_owner = mapper->owner->priv;
struct vaapi_gl_mapper_priv *p = p_mapper->interop_mapper_priv;
GL *gl = ra_gl_get(mapper->ra);
@ -168,7 +169,7 @@ static bool vaapi_gl_map(struct ra_hwdec_mapper *mapper, bool probing)
for (int n = 0; n < p_mapper->num_planes; n++) {
if (p_mapper->desc.layers[n].num_planes > 1) {
// Should never happen because we request separate layers
MP_ERR(mapper, "Multi-plane VA surfaces are not supported\n");
MP_ERR(mapper, "Multi-plane surfaces are not supported\n");
return false;
}
@ -190,7 +191,7 @@ static bool vaapi_gl_map(struct ra_hwdec_mapper *mapper, bool probing)
p->images[n] = p->CreateImageKHR(eglGetCurrentDisplay(),
EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
if (!p->images[n]) {
mp_msg(mapper->log, p_owner->probing_formats ? MSGL_DEBUG : MSGL_ERR,
mp_msg(mapper->log, probing ? MSGL_DEBUG : MSGL_ERR,
"Failed to import surface in EGL: %u\n", eglGetError());
return false;
}
@ -218,9 +219,9 @@ static void vaapi_gl_unmap(struct ra_hwdec_mapper *mapper)
}
}
bool dmabuf_interop_gl_init(const struct ra_hwdec *hw)
bool dmabuf_interop_gl_init(const struct ra_hwdec *hw,
struct dmabuf_interop *dmabuf_interop)
{
struct priv_owner *p = hw->priv;
if (!ra_is_gl(hw->ra)) {
// This is not an OpenGL RA.
return false;
@ -240,14 +241,15 @@ bool dmabuf_interop_gl_init(const struct ra_hwdec *hw)
!(gl->mpgl_caps & MPGL_CAP_TEX_RG))
return false;
p->use_modifiers = gl_check_extension(exts, "EGL_EXT_image_dma_buf_import_modifiers");
dmabuf_interop->use_modifiers =
gl_check_extension(exts, "EGL_EXT_image_dma_buf_import_modifiers");
MP_VERBOSE(hw, "using VAAPI EGL interop\n");
MP_VERBOSE(hw, "using EGL dmabuf interop\n");
p->interop_init = vaapi_gl_mapper_init;
p->interop_uninit = vaapi_gl_mapper_uninit;
p->interop_map = vaapi_gl_map;
p->interop_unmap = vaapi_gl_unmap;
dmabuf_interop->interop_init = vaapi_gl_mapper_init;
dmabuf_interop->interop_uninit = vaapi_gl_mapper_uninit;
dmabuf_interop->interop_map = vaapi_gl_map;
dmabuf_interop->interop_unmap = vaapi_gl_unmap;
return true;
}

View File

@ -23,7 +23,9 @@
#include "video/out/placebo/ra_pl.h"
#include "video/out/placebo/utils.h"
static bool vaapi_pl_map(struct ra_hwdec_mapper *mapper, bool probing)
static bool vaapi_pl_map(struct ra_hwdec_mapper *mapper,
struct dmabuf_interop *dmabuf_interop,
bool probing)
{
struct priv *p = mapper->priv;
pl_gpu gpu = ra_pl_get(mapper->ra);
@ -113,9 +115,9 @@ static void vaapi_pl_unmap(struct ra_hwdec_mapper *mapper)
ra_tex_free(mapper->ra, &mapper->tex[n]);
}
bool dmabuf_interop_pl_init(const struct ra_hwdec *hw)
bool dmabuf_interop_pl_init(const struct ra_hwdec *hw,
struct dmabuf_interop *dmabuf_interop)
{
struct priv_owner *p = hw->priv;
pl_gpu gpu = ra_pl_get(hw->ra);
if (!gpu) {
// This is not a libplacebo RA;
@ -123,15 +125,15 @@ bool dmabuf_interop_pl_init(const struct ra_hwdec *hw)
}
if (!(gpu->import_caps.tex & PL_HANDLE_DMA_BUF)) {
MP_VERBOSE(hw, "VAAPI libplacebo interop requires support for "
MP_VERBOSE(hw, "libplacebo dmabuf interop requires support for "
"PL_HANDLE_DMA_BUF import.\n");
return false;
}
MP_VERBOSE(hw, "using VAAPI libplacebo interop\n");
MP_VERBOSE(hw, "using libplacebo dmabuf interop\n");
p->interop_map = vaapi_pl_map;
p->interop_unmap = vaapi_pl_unmap;
dmabuf_interop->interop_map = vaapi_pl_map;
dmabuf_interop->interop_unmap = vaapi_pl_unmap;
return true;
}

View File

@ -99,6 +99,15 @@ static VADisplay *create_native_va_display(struct ra *ra, struct mp_log *log)
static void determine_working_formats(struct ra_hwdec *hw);
struct priv_owner {
struct mp_vaapi_ctx *ctx;
VADisplay *display;
int *formats;
bool probing_formats; // temporary during init
struct dmabuf_interop dmabuf_interop;
};
static void uninit(struct ra_hwdec *hw)
{
struct priv_owner *p = hw->priv;
@ -122,12 +131,12 @@ static int init(struct ra_hwdec *hw)
struct priv_owner *p = hw->priv;
for (int i = 0; interop_inits[i]; i++) {
if (interop_inits[i](hw)) {
if (interop_inits[i](hw, &p->dmabuf_interop)) {
break;
}
}
if (!p->interop_map || !p->interop_unmap) {
if (!p->dmabuf_interop.interop_map || !p->dmabuf_interop.interop_unmap) {
MP_VERBOSE(hw, "VAAPI hwdec only works with OpenGL or Vulkan backends.\n");
return -1;
}
@ -169,7 +178,7 @@ static void mapper_unmap(struct ra_hwdec_mapper *mapper)
struct priv_owner *p_owner = mapper->owner->priv;
struct priv *p = mapper->priv;
p_owner->interop_unmap(mapper);
p_owner->dmabuf_interop.interop_unmap(mapper);
if (p->surface_acquired) {
for (int n = 0; n < p->desc.num_objects; n++)
@ -181,8 +190,8 @@ static void mapper_unmap(struct ra_hwdec_mapper *mapper)
static void mapper_uninit(struct ra_hwdec_mapper *mapper)
{
struct priv_owner *p_owner = mapper->owner->priv;
if (p_owner->interop_uninit) {
p_owner->interop_uninit(mapper);
if (p_owner->dmabuf_interop.interop_uninit) {
p_owner->dmabuf_interop.interop_uninit(mapper);
}
}
@ -213,8 +222,8 @@ static int mapper_init(struct ra_hwdec_mapper *mapper)
p->num_planes = desc.num_planes;
mp_image_set_params(&p->layout, &mapper->dst_params);
if (p_owner->interop_init)
if (!p_owner->interop_init(mapper, &desc))
if (p_owner->dmabuf_interop.interop_init)
if (!p_owner->dmabuf_interop.interop_init(mapper, &desc))
return -1;
if (!p_owner->probing_formats && !check_fmt(mapper, mapper->dst_params.imgfmt))
@ -267,7 +276,8 @@ static int mapper_map(struct ra_hwdec_mapper *mapper)
goto err;
}
if (!p_owner->interop_map(mapper, p_owner->probing_formats))
if (!p_owner->dmabuf_interop.interop_map(mapper, &p_owner->dmabuf_interop,
p_owner->probing_formats))
goto err;
if (p->desc.fourcc == VA_FOURCC_YV12)