Skip to content

Commit

Permalink
vo_gpu_next: add D3D11 RA texture wrapping/unwrapping for hwdec
Browse files Browse the repository at this point in the history
This mostly copies the API used in the GL backend.
  • Loading branch information
rossy authored and haasn committed Mar 3, 2022
1 parent dfe846f commit 11f0947
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 5 deletions.
19 changes: 15 additions & 4 deletions video/out/d3d11/ra_d3d11.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -643,6 +643,17 @@ struct ra_tex *ra_d3d11_wrap_tex_video(struct ra *ra, ID3D11Texture2D *res,
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;
Expand Down
8 changes: 8 additions & 0 deletions video/out/d3d11/ra_d3d11.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand Down
22 changes: 21 additions & 1 deletion video/out/vo_gpu_next.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@
#include "video/out/opengl/ra_gl.h"
#endif

#if HAVE_D3D11 && defined(PL_HAVE_D3D11)
#include <libplacebo/d3d11.h>
#include "video/out/d3d11/ra_d3d11.h"
#include "osdep/windows_utils.h"
#endif

struct osd_entry {
pl_tex tex;
struct pl_overlay_part *parts;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 11f0947

Please sign in to comment.