From 11f0947d460c85b82c7e5fdb642c3dccdb1f6e07 Mon Sep 17 00:00:00 2001 From: James Ross-Gowan Date: Tue, 1 Mar 2022 00:18:26 +1100 Subject: vo_gpu_next: add D3D11 RA texture wrapping/unwrapping for hwdec This mostly copies the API used in the GL backend. --- video/out/d3d11/ra_d3d11.c | 19 +++++++++++++++---- video/out/d3d11/ra_d3d11.h | 8 ++++++++ video/out/vo_gpu_next.c | 22 +++++++++++++++++++++- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/video/out/d3d11/ra_d3d11.c b/video/out/d3d11/ra_d3d11.c index b4d4c7fdb8..ebf3ab9fba 100644 --- a/video/out/d3d11/ra_d3d11.c +++ b/video/out/d3d11/ra_d3d11.c @@ -196,7 +196,7 @@ static bool dll_version_equal(struct dll_version a, struct dll_version b) a.revision == b.revision; } -static DXGI_FORMAT fmt_to_dxgi(const struct ra_format *fmt) +DXGI_FORMAT ra_d3d11_get_format(const struct ra_format *fmt) { struct d3d_fmt *d3d = fmt->priv; return d3d->fmt; @@ -273,7 +273,7 @@ static bool tex_init(struct ra *ra, struct ra_tex *tex) // texture format for textures created with tex_create, but it can be // different for wrapped planar video textures. D3D11_SHADER_RESOURCE_VIEW_DESC srvdesc = { - .Format = fmt_to_dxgi(params->format), + .Format = ra_d3d11_get_format(params->format), }; switch (params->dimensions) { case 1: @@ -393,7 +393,7 @@ static struct ra_tex *tex_create(struct ra *ra, tex->params.initial_data = NULL; struct d3d_tex *tex_p = tex->priv = talloc_zero(tex, struct d3d_tex); - DXGI_FORMAT fmt = fmt_to_dxgi(params->format); + DXGI_FORMAT fmt = ra_d3d11_get_format(params->format); D3D11_SUBRESOURCE_DATA data; D3D11_SUBRESOURCE_DATA *pdata = NULL; @@ -564,7 +564,7 @@ struct ra_tex *ra_d3d11_wrap_tex(struct ra *ra, ID3D11Resource *res) } for (int i = 0; i < ra->num_formats; i++) { - DXGI_FORMAT target_fmt = fmt_to_dxgi(ra->formats[i]); + DXGI_FORMAT target_fmt = ra_d3d11_get_format(ra->formats[i]); if (fmt == target_fmt) { params->format = ra->formats[i]; break; @@ -643,6 +643,17 @@ error: return NULL; } +ID3D11Resource *ra_d3d11_get_raw_tex(struct ra *ra, struct ra_tex *tex, + int *array_slice) +{ + struct d3d_tex *tex_p = tex->priv; + + ID3D11Resource_AddRef(tex_p->res); + if (array_slice) + *array_slice = tex_p->array_slice; + return tex_p->res; +} + static bool tex_upload(struct ra *ra, const struct ra_tex_upload_params *params) { struct ra_d3d11 *p = ra->priv; diff --git a/video/out/d3d11/ra_d3d11.h b/video/out/d3d11/ra_d3d11.h index 54033b6cee..f9cada132c 100644 --- a/video/out/d3d11/ra_d3d11.h +++ b/video/out/d3d11/ra_d3d11.h @@ -8,6 +8,9 @@ #include "video/out/gpu/ra.h" #include "video/out/gpu/spirv.h" +// Get the underlying DXGI format from an RA format +DXGI_FORMAT ra_d3d11_get_format(const struct ra_format *fmt); + // Create an RA instance from a D3D11 device. This takes a reference to the // device, which is released when the RA instance is destroyed. struct ra *ra_d3d11_create(ID3D11Device *device, struct mp_log *log, @@ -27,6 +30,11 @@ struct ra_tex *ra_d3d11_wrap_tex_video(struct ra *ra, ID3D11Texture2D *res, int w, int h, int array_slice, const struct ra_format *fmt); +// Get the underlying D3D11 resource from an RA texture. The returned resource +// is refcounted and must be released by the caller. +ID3D11Resource *ra_d3d11_get_raw_tex(struct ra *ra, struct ra_tex *tex, + int *array_slice); + // Get the underlying D3D11 device from an RA instance. The returned device is // refcounted and must be released by the caller. ID3D11Device *ra_d3d11_get_device(struct ra *ra); diff --git a/video/out/vo_gpu_next.c b/video/out/vo_gpu_next.c index 0b78bf0acc..889ba9443c 100644 --- a/video/out/vo_gpu_next.c +++ b/video/out/vo_gpu_next.c @@ -48,6 +48,12 @@ #include "video/out/opengl/ra_gl.h" #endif +#if HAVE_D3D11 && defined(PL_HAVE_D3D11) +#include +#include "video/out/d3d11/ra_d3d11.h" +#include "osdep/windows_utils.h" +#endif + struct osd_entry { pl_tex tex; struct pl_overlay_part *parts; @@ -477,7 +483,21 @@ static pl_tex hwdec_get_tex(struct frame_priv *fp, int n) } #endif - // TODO: d3d11 wrapping/unwrapping +#if HAVE_D3D11 && defined(PL_HAVE_D3D11) + if (ra_is_d3d11(ra)) { + int array_slice = 0; + ID3D11Resource *res = ra_d3d11_get_raw_tex(ra, ratex, &array_slice); + pl_tex tex = pl_d3d11_wrap(p->gpu, pl_d3d11_wrap_params( + .tex = res, + .array_slice = array_slice, + .fmt = ra_d3d11_get_format(ratex->params.format), + .w = ratex->params.w, + .h = ratex->params.h, + )); + SAFE_RELEASE(res); + return tex; + } +#endif MP_ERR(p, "Failed mapping hwdec frame? Open a bug!\n"); return false; -- cgit v1.2.3