Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions libmpv/render.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,10 @@ typedef enum mpv_render_param_type {
* See MPV_RENDER_PARAM_SW_STRIDE for alignment requirements.
*/
MPV_RENDER_PARAM_SW_POINTER = 20,
/*
* MPV_RENDER_API_TYPE_DXGI only
*/
MPV_RENDER_PARAM_DXGI_INIT_PARAMS = 21,
} mpv_render_param_type;

/**
Expand Down Expand Up @@ -467,6 +471,8 @@ typedef struct mpv_render_param {
#define MPV_RENDER_API_TYPE_OPENGL "opengl"
// See section "Software renderer"
#define MPV_RENDER_API_TYPE_SW "sw"
// See render_dxgi.h
#define MPV_RENDER_API_TYPE_DXGI "dxgi"

/**
* Flags used in mpv_render_frame_info.flags. Each value represents a bit in it.
Expand Down
18 changes: 18 additions & 0 deletions libmpv/render_dxgi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef MPV_CLIENT_API_RENDER_DXGI_H_
#define MPV_CLIENT_API_RENDER_DXGI_H_

#include "render.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct mpv_dxgi_init_params {
void *device;
void *swapchain;
} mpv_dxgi_init_params;

#ifdef __cplusplus
}
#endif
#endif // MPV_CLIENT_API_RENDER_DXGI_H_
6 changes: 4 additions & 2 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,8 @@ d3d11 = get_option('d3d11').require(
features += {'d3d11': d3d11.allowed()}
if features['d3d11']
sources += files('video/out/d3d11/context.c',
'video/out/d3d11/ra_d3d11.c')
'video/out/d3d11/ra_d3d11.c',
'video/out/d3d11/libmpv_d3d11.c')
endif

wayland = {
Expand Down Expand Up @@ -1724,7 +1725,8 @@ if get_option('libmpv')
description: 'mpv media player client library')

headers = ['libmpv/client.h', 'libmpv/render.h',
'libmpv/render_gl.h', 'libmpv/stream_cb.h']
'libmpv/render_gl.h', 'libmpv/stream_cb.h',
'libmpv/render_dxgi.h']
install_headers(headers, subdir: 'mpv')
endif

Expand Down
87 changes: 87 additions & 0 deletions video/out/d3d11/libmpv_d3d11.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include "common/msg.h"
#include "ra_d3d11.h"
#include "libmpv/render_dxgi.h"
#include "video/out/gpu/libmpv_gpu.h"
#include "osdep/windows_utils.h"

struct priv {
struct ra_tex *tex;
ID3D11Device *device;
IDXGISwapChain *swapchain;
};

static int init(struct libmpv_gpu_context *ctx, mpv_render_param *params)
{
MP_VERBOSE(ctx, "Creating libmpv d3d11 context\n");
struct priv *p = ctx->priv = talloc_zero(NULL, struct priv);

mpv_dxgi_init_params *init_params =
get_mpv_render_param(params, MPV_RENDER_PARAM_DXGI_INIT_PARAMS, NULL);
if (!init_params)
return MPV_ERROR_INVALID_PARAMETER;

p->device = init_params->device;
p->swapchain = init_params->swapchain;
ID3D11Device_AddRef(p->device);
ID3D11Device_AddRef(p->swapchain);

// initialize a blank ra_ctx to reuse ra_gl_ctx
struct ra_ctx *ra_ctx = talloc_zero(p, struct ra_ctx);
ra_ctx->log = ctx->log;
ra_ctx->global = ctx->global;

if (!spirv_compiler_init(ra_ctx))
return MPV_ERROR_UNSUPPORTED;

ra_ctx->ra = ra_d3d11_create(p->device, ctx->log, ra_ctx->spirv);
if (!ra_ctx->ra)
return MPV_ERROR_UNSUPPORTED;

ctx->ra_ctx = ra_ctx;
return 0;
}

static int wrap_fbo(struct libmpv_gpu_context *ctx, mpv_render_param *params, struct ra_tex **out)
{
struct priv *p = ctx->priv;
ID3D11Resource *backbuffer = NULL;

if (!p->tex) {
HRESULT hr = IDXGISwapChain_GetBuffer(p->swapchain, 0, &IID_ID3D11Texture2D,
(void**)&backbuffer);
if (FAILED(hr)) {
MP_ERR(ctx, "Couldn't get swapchain image\n");
return MPV_ERROR_UNSUPPORTED;
}
p->tex = ra_d3d11_wrap_tex(ctx->ra_ctx->ra, backbuffer);
SAFE_RELEASE(backbuffer);
}

*out = p->tex;
return 0;
}

static void done_frame(struct libmpv_gpu_context *ctx, bool ds)
{
struct priv *p = ctx->priv;

ra_d3d11_flush(ctx->ra_ctx->ra);
ra_tex_free(ctx->ra_ctx->ra, &p->tex);
}

static void destroy(struct libmpv_gpu_context *ctx)
{
struct priv *p = ctx->priv;
if (ctx->ra_ctx->ra)
ra_tex_free(ctx->ra_ctx->ra, &p->tex);
SAFE_RELEASE(p->swapchain);
SAFE_RELEASE(p->device);
}

const struct libmpv_gpu_context_fns libmpv_gpu_context_d3d11 = {
.api_name = MPV_RENDER_API_TYPE_DXGI,
.init = init,
.wrap_fbo = wrap_fbo,
.done_frame = done_frame,
.destroy = destroy,
};
3 changes: 3 additions & 0 deletions video/out/gpu/libmpv_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
#include "video/out/libmpv.h"

static const struct libmpv_gpu_context_fns *context_backends[] = {
#if HAVE_D3D11
&libmpv_gpu_context_d3d11,
#endif
#if HAVE_GL
&libmpv_gpu_context_gl,
#endif
Expand Down
1 change: 1 addition & 0 deletions video/out/gpu/libmpv_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ struct libmpv_gpu_context_fns {
};

extern const struct libmpv_gpu_context_fns libmpv_gpu_context_gl;
extern const struct libmpv_gpu_context_fns libmpv_gpu_context_d3d11;