summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
Diffstat (limited to 'video')
-rw-r--r--video/filter/vf_gpu.c117
-rw-r--r--video/filter/vf_gpu.h35
-rw-r--r--video/filter/vf_gpu_egl.c107
-rw-r--r--video/filter/vf_gpu_vulkan.c115
-rw-r--r--video/out/cocoa_cb_common.swift19
-rw-r--r--video/out/d3d11/context.c1
-rw-r--r--video/out/d3d11/ra_d3d11.c89
-rw-r--r--video/out/gpu/context.c208
-rw-r--r--video/out/gpu/context.h5
-rw-r--r--video/out/gpu/d3d11_helpers.c44
-rw-r--r--video/out/gpu/d3d11_helpers.h13
-rw-r--r--video/out/mac/common.swift55
-rw-r--r--video/out/mac/gl_layer.swift30
-rw-r--r--video/out/mac/title_bar.swift45
-rw-r--r--video/out/mac/view.swift10
-rw-r--r--video/out/mac/window.swift62
-rw-r--r--video/out/mac_common.swift15
-rw-r--r--video/out/opengl/context_android.c1
-rw-r--r--video/out/opengl/context_angle.c1
-rw-r--r--video/out/opengl/context_drm_egl.c4
-rw-r--r--video/out/opengl/context_dxinterop.c1
-rw-r--r--video/out/opengl/context_glx.c1
-rw-r--r--video/out/opengl/context_wayland.c1
-rw-r--r--video/out/opengl/context_win.c1
-rw-r--r--video/out/opengl/context_x11egl.c1
-rw-r--r--video/out/vo_dmabuf_wayland.c10
-rw-r--r--video/out/vo_gpu_next.c8
-rw-r--r--video/out/vo_kitty.c2
-rw-r--r--video/out/vo_sixel.c2
-rw-r--r--video/out/vo_tct.c2
-rw-r--r--video/out/vulkan/context.c58
-rw-r--r--video/out/vulkan/context.h6
-rw-r--r--video/out/vulkan/context_android.c1
-rw-r--r--video/out/vulkan/context_display.c1
-rw-r--r--video/out/vulkan/context_mac.m1
-rw-r--r--video/out/vulkan/context_wayland.c1
-rw-r--r--video/out/vulkan/context_win.c1
-rw-r--r--video/out/vulkan/context_xlib.c1
-rw-r--r--video/out/w32_common.c17
-rw-r--r--video/out/wldmabuf/context_wldmabuf.c2
-rw-r--r--video/out/x11_common.c24
41 files changed, 736 insertions, 382 deletions
diff --git a/video/filter/vf_gpu.c b/video/filter/vf_gpu.c
index e19faaef42..d2ba990a00 100644
--- a/video/filter/vf_gpu.c
+++ b/video/filter/vf_gpu.c
@@ -24,95 +24,49 @@
#include "options/options.h"
#include "video/out/aspect.h"
#include "video/out/gpu/video.h"
-#include "video/out/opengl/egl_helpers.h"
-#include "video/out/opengl/ra_gl.h"
-
-struct offscreen_ctx {
- struct mp_log *log;
- struct ra *ra;
- void *priv;
-
- void (*set_context)(struct offscreen_ctx *ctx, bool enable);
-};
-
-struct gl_offscreen_ctx {
- GL gl;
- EGLDisplay egl_display;
- EGLContext egl_context;
+#include "video/filter/vf_gpu.h"
+
+extern const struct offscreen_context offscreen_vk;
+extern const struct offscreen_context offscreen_egl;
+
+static const struct offscreen_context *contexts[] = {
+#if HAVE_EGL
+ &offscreen_egl,
+#endif
+#if HAVE_VULKAN
+ &offscreen_vk,
+#endif
};
-static void gl_ctx_destroy(void *p)
+static inline OPT_STRING_VALIDATE_FUNC(offscreen_ctx_validate_api)
{
- struct offscreen_ctx *ctx = p;
- struct gl_offscreen_ctx *gl = ctx->priv;
-
- ra_free(&ctx->ra);
-
- if (gl->egl_context)
- eglDestroyContext(gl->egl_display, gl->egl_context);
+ struct bstr param = bstr0(*value);
+ for (int i = 0; i < MP_ARRAY_SIZE(contexts); i++) {
+ if (bstr_equals0(param, contexts[i]->api))
+ return 1;
+ }
+ return M_OPT_INVALID;
}
-static void gl_ctx_set_context(struct offscreen_ctx *ctx, bool enable)
+static int offscreen_ctx_api_help(struct mp_log *log, const struct m_option *opt,
+ struct bstr name)
{
- struct gl_offscreen_ctx *gl = ctx->priv;
- EGLContext c = enable ? gl->egl_context : EGL_NO_CONTEXT;
-
- if (!eglMakeCurrent(gl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, c))
- MP_ERR(ctx, "Could not make EGL context current.\n");
+ mp_info(log, "GPU APIs (offscreen contexts):\n");
+ for (int i = 0; i < MP_ARRAY_SIZE(contexts); i++)
+ mp_info(log, " %s\n", contexts[i]->api);
+ return M_OPT_EXIT;
}
-static struct offscreen_ctx *gl_offscreen_ctx_create(struct mpv_global *global,
- struct mp_log *log)
+static struct offscreen_ctx *offscreen_ctx_create(struct mpv_global *global,
+ struct mp_log *log,
+ const char *api)
{
- struct offscreen_ctx *ctx = talloc_zero(NULL, struct offscreen_ctx);
- struct gl_offscreen_ctx *gl = talloc_zero(ctx, struct gl_offscreen_ctx);
- talloc_set_destructor(ctx, gl_ctx_destroy);
- *ctx = (struct offscreen_ctx){
- .log = log,
- .priv = gl,
- .set_context = gl_ctx_set_context,
- };
-
- // This appears to work with Mesa. EGL 1.5 doesn't specify what a "default
- // display" is at all.
- gl->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (!eglInitialize(gl->egl_display, NULL, NULL)) {
- MP_ERR(ctx, "Could not initialize EGL.\n");
- goto error;
+ for (int i = 0; i < MP_ARRAY_SIZE(contexts); i++) {
+ if (api && strcmp(contexts[i]->api, api) != 0)
+ continue;
+ mp_info(log, "Creating offscreen GPU context '%s'\n", contexts[i]->api);
+ return contexts[i]->offscreen_ctx_create(global, log);
}
-
- // Unfortunately, mpegl_create_context() is entangled with ra_ctx.
- // Fortunately, it does not need much, and we can provide a stub.
- struct ra_ctx ractx = {
- .log = ctx->log,
- .global = global,
- };
- EGLConfig config;
- if (!mpegl_create_context(&ractx, gl->egl_display, &gl->egl_context, &config))
- {
- MP_ERR(ctx, "Could not create EGL context.\n");
- goto error;
- }
-
- if (!eglMakeCurrent(gl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
- gl->egl_context))
- {
- MP_ERR(ctx, "Could not make EGL context current.\n");
- goto error;
- }
-
- mpegl_load_functions(&gl->gl, ctx->log);
- ctx->ra = ra_create_gl(&gl->gl, ctx->log);
-
- if (!ctx->ra)
- goto error;
-
- gl_ctx_set_context(ctx, false);
-
- return ctx;
-
-error:
- talloc_free(ctx);
return NULL;
}
@@ -124,6 +78,7 @@ static void offscreen_ctx_set_current(struct offscreen_ctx *ctx, bool enable)
struct gpu_opts {
int w, h;
+ char *api;
};
struct priv {
@@ -327,7 +282,7 @@ static struct mp_filter *gpu_create(struct mp_filter *parent, void *options)
priv->vo_opts_cache = m_config_cache_alloc(f, f->global, &vo_sub_opts);
priv->vo_opts = priv->vo_opts_cache->opts;
- priv->ctx = gl_offscreen_ctx_create(f->global, f->log);
+ priv->ctx = offscreen_ctx_create(f->global, f->log, priv->opts->api);
if (!priv->ctx) {
MP_FATAL(f, "Could not create offscreen ra context.\n");
goto error;
@@ -368,6 +323,8 @@ const struct mp_user_filter_entry vf_gpu = {
.options = (const struct m_option[]){
{"w", OPT_INT(w)},
{"h", OPT_INT(h)},
+ {"api", OPT_STRING_VALIDATE(api, offscreen_ctx_validate_api),
+ .help = offscreen_ctx_api_help},
{0}
},
},
diff --git a/video/filter/vf_gpu.h b/video/filter/vf_gpu.h
new file mode 100644
index 0000000000..2cc9a16eea
--- /dev/null
+++ b/video/filter/vf_gpu.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "common/common.h"
+#include "common/global.h"
+
+struct offscreen_ctx {
+ struct mp_log *log;
+ struct ra *ra;
+ void *priv;
+
+ void (*set_context)(struct offscreen_ctx *ctx, bool enable);
+};
+
+struct offscreen_context {
+ const char *api;
+ struct offscreen_ctx *(*offscreen_ctx_create)(struct mpv_global *,
+ struct mp_log *);
+};
diff --git a/video/filter/vf_gpu_egl.c b/video/filter/vf_gpu_egl.c
new file mode 100644
index 0000000000..cd90a6e06a
--- /dev/null
+++ b/video/filter/vf_gpu_egl.c
@@ -0,0 +1,107 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "common/common.h"
+#include "video/filter/vf_gpu.h"
+#include "video/out/opengl/egl_helpers.h"
+#include "video/out/opengl/ra_gl.h"
+
+struct gl_offscreen_ctx {
+ GL gl;
+ EGLDisplay egl_display;
+ EGLContext egl_context;
+};
+
+static void gl_ctx_destroy(void *p)
+{
+ struct offscreen_ctx *ctx = p;
+ struct gl_offscreen_ctx *gl = ctx->priv;
+
+ ra_free(&ctx->ra);
+
+ if (gl->egl_context)
+ eglDestroyContext(gl->egl_display, gl->egl_context);
+}
+
+static void gl_ctx_set_context(struct offscreen_ctx *ctx, bool enable)
+{
+ struct gl_offscreen_ctx *gl = ctx->priv;
+ EGLContext c = enable ? gl->egl_context : EGL_NO_CONTEXT;
+
+ if (!eglMakeCurrent(gl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, c))
+ MP_ERR(ctx, "Could not make EGL context current.\n");
+}
+
+static struct offscreen_ctx *gl_offscreen_ctx_create(struct mpv_global *global,
+ struct mp_log *log)
+{
+ struct offscreen_ctx *ctx = talloc(NULL, struct offscreen_ctx);
+ struct gl_offscreen_ctx *gl = talloc_zero(ctx, struct gl_offscreen_ctx);
+ talloc_set_destructor(ctx, gl_ctx_destroy);
+ *ctx = (struct offscreen_ctx){
+ .log = log,
+ .priv = gl,
+ .set_context = gl_ctx_set_context,
+ };
+
+ // This appears to work with Mesa. EGL 1.5 doesn't specify what a "default
+ // display" is at all.
+ gl->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (!eglInitialize(gl->egl_display, NULL, NULL)) {
+ MP_ERR(ctx, "Could not initialize EGL.\n");
+ goto error;
+ }
+
+ // Unfortunately, mpegl_create_context() is entangled with ra_ctx.
+ // Fortunately, it does not need much, and we can provide a stub.
+ struct ra_ctx ractx = {
+ .log = ctx->log,
+ .global = global,
+ };
+ EGLConfig config;
+ if (!mpegl_create_context(&ractx, gl->egl_display, &gl->egl_context, &config))
+ {
+ MP_ERR(ctx, "Could not create EGL context.\n");
+ goto error;
+ }
+
+ if (!eglMakeCurrent(gl->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ gl->egl_context))
+ {
+ MP_ERR(ctx, "Could not make EGL context current.\n");
+ goto error;
+ }
+
+ mpegl_load_functions(&gl->gl, ctx->log);
+ ctx->ra = ra_create_gl(&gl->gl, ctx->log);
+
+ if (!ctx->ra)
+ goto error;
+
+ gl_ctx_set_context(ctx, false);
+
+ return ctx;
+
+error:
+ talloc_free(ctx);
+ return NULL;
+}
+
+const struct offscreen_context offscreen_egl = {
+ .api = "egl",
+ .offscreen_ctx_create = gl_offscreen_ctx_create
+};
diff --git a/video/filter/vf_gpu_vulkan.c b/video/filter/vf_gpu_vulkan.c
new file mode 100644
index 0000000000..81a84becfa
--- /dev/null
+++ b/video/filter/vf_gpu_vulkan.c
@@ -0,0 +1,115 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "options/m_config.h"
+#include "video/filter/vf_gpu.h"
+#include "video/out/placebo/ra_pl.h"
+#include "video/out/placebo/utils.h"
+#include "video/out/vulkan/context.h"
+#include "video/out/vulkan/utils.h"
+
+struct vk_offscreen_ctx {
+ struct ra_ctx *ractx;
+ struct mpvk_ctx *vk;
+};
+
+extern const struct m_sub_options vulkan_conf;
+
+static void vk_ctx_destroy(void *p)
+{
+ struct offscreen_ctx *ctx = p;
+ struct vk_offscreen_ctx *vkctx = ctx->priv;
+ struct ra_ctx *ractx = vkctx->ractx;
+ struct mpvk_ctx *vk = vkctx->vk;
+
+ if (ractx->ra) {
+ pl_gpu_finish(vk->gpu);
+ ractx->ra->fns->destroy(ctx->ra);
+ ractx->ra = NULL;
+ ctx->ra = NULL;
+ }
+
+ vk->gpu = NULL;
+ pl_vulkan_destroy(&vk->vulkan);
+ mpvk_uninit(vk);
+ talloc_free(vk);
+ talloc_free(ractx);
+}
+
+static struct offscreen_ctx *vk_offscreen_ctx_create(struct mpv_global *global,
+ struct mp_log *log)
+{
+ struct offscreen_ctx *ctx = talloc(NULL, struct offscreen_ctx);
+ talloc_set_destructor(ctx, vk_ctx_destroy);
+ *ctx = (struct offscreen_ctx){
+ .log = log,
+ };
+
+ struct ra_ctx *ractx = talloc_zero(ctx, struct ra_ctx);
+ struct mpvk_ctx *vk = talloc_zero(ctx, struct mpvk_ctx);
+ ractx->log = ctx->log;
+ ractx->global = global;
+
+ vk->pllog = mppl_log_create(ctx, log);
+ if (!vk->pllog)
+ goto error;
+
+ struct pl_vk_inst_params pl_vk_params = {0};
+ struct ra_ctx_opts *ctx_opts = mp_get_config_group(NULL, global, &ra_ctx_conf);
+ pl_vk_params.debug = ctx_opts->debug;
+ talloc_free(ctx_opts);
+ mppl_log_set_probing(vk->pllog, true);
+ vk->vkinst = pl_vk_inst_create(vk->pllog, &pl_vk_params);
+ mppl_log_set_probing(vk->pllog, false);
+ if (!vk->vkinst)
+ goto error;
+
+ struct vulkan_opts *vk_opts = mp_get_config_group(NULL, global, &vulkan_conf);
+ vk->vulkan = mppl_create_vulkan(vk_opts, vk->vkinst, vk->pllog, NULL);
+ talloc_free(vk_opts);
+ if (!vk->vulkan)
+ goto error;
+
+ vk->gpu = vk->vulkan->gpu;
+ ractx->ra = ra_create_pl(vk->gpu, ractx->log);
+ if (!ractx->ra)
+ goto error;
+
+ struct vk_offscreen_ctx *vkctx = talloc(ctx, struct vk_offscreen_ctx);
+ *vkctx = (struct vk_offscreen_ctx){
+ .ractx = ractx,
+ .vk = vk
+ };
+
+ ctx->ra = ractx->ra;
+ ctx->priv = vkctx;
+
+ return ctx;
+
+error:
+ pl_vulkan_destroy(&vk->vulkan);
+ mpvk_uninit(vk);
+ talloc_free(vk);
+ talloc_free(ractx);
+ talloc_free(ctx);
+ return NULL;
+}
+
+const struct offscreen_context offscreen_vk = {
+ .api = "vulkan",
+ .offscreen_ctx_create = vk_offscreen_ctx_create
+};
diff --git a/video/out/cocoa_cb_common.swift b/video/out/cocoa_cb_common.swift
index 9f32ed651f..38c47a19a2 100644
--- a/video/out/cocoa_cb_common.swift
+++ b/video/out/cocoa_cb_common.swift
@@ -87,8 +87,7 @@ class CocoaCB: Common, EventSubscriber {
}
func updateWindowSize(_ vo: UnsafeMutablePointer<vo>) {
- guard let targetScreen = getTargetScreen(forFullscreen: false) ?? NSScreen.main else
- {
+ guard let targetScreen = getTargetScreen(forFullscreen: false) ?? NSScreen.main else {
log.warning("Couldn't update Window size, no Screen available")
return
}
@@ -102,11 +101,10 @@ class CocoaCB: Common, EventSubscriber {
}
override func displayLinkCallback(_ displayLink: CVDisplayLink,
- _ inNow: UnsafePointer<CVTimeStamp>,
- _ inOutputTime: UnsafePointer<CVTimeStamp>,
- _ flagsIn: CVOptionFlags,
- _ flagsOut: UnsafeMutablePointer<CVOptionFlags>) -> CVReturn
- {
+ _ inNow: UnsafePointer<CVTimeStamp>,
+ _ inOutputTime: UnsafePointer<CVTimeStamp>,
+ _ flagsIn: CVOptionFlags,
+ _ flagsOut: UnsafeMutablePointer<CVOptionFlags>) -> CVReturn {
libmpv.reportRenderFlip()
return kCVReturnSuccess
}
@@ -178,10 +176,9 @@ class CocoaCB: Common, EventSubscriber {
}
override func control(_ vo: UnsafeMutablePointer<vo>,
- events: UnsafeMutablePointer<Int32>,
- request: UInt32,
- data: UnsafeMutableRawPointer?) -> Int32
- {
+ events: UnsafeMutablePointer<Int32>,
+ request: UInt32,
+ data: UnsafeMutableRawPointer?) -> Int32 {
switch mp_voctrl(request) {
case VOCTRL_PREINIT:
DispatchQueue.main.sync { self.preinit(vo) }
diff --git a/video/out/d3d11/context.c b/video/out/d3d11/context.c
index c563b5fa15..f183ae8be5 100644
--- a/video/out/d3d11/context.c
+++ b/video/out/d3d11/context.c
@@ -547,6 +547,7 @@ bool ra_d3d11_ctx_prefer_8bit_output_format(struct ra_ctx *ra)
const struct ra_ctx_fns ra_ctx_d3d11 = {
.type = "d3d11",
.name = "d3d11",
+ .description = "Direct3D 11",
.reconfig = d3d11_reconfig,
.control = d3d11_control,
.update_render_opts = d3d11_update_render_opts,
diff --git a/video/out/d3d11/ra_d3d11.c b/video/out/d3d11/ra_d3d11.c
index 84fd004adc..4438b2083c 100644
--- a/video/out/d3d11/ra_d3d11.c
+++ b/video/out/d3d11/ra_d3d11.c
@@ -13,6 +13,7 @@
#include "osdep/windows_utils.h"
#include "video/out/gpu/spirv.h"
#include "video/out/gpu/utils.h"
+#include "video/out/gpu/d3d11_helpers.h"
#include "ra_d3d11.h"
@@ -43,9 +44,11 @@ struct ra_d3d11 {
struct dll_version d3d_compiler_ver;
+#if HAVE_DXGI_DEBUG
// Debug interfaces (--gpu-debug)
- ID3D11Debug *debug;
- ID3D11InfoQueue *iqueue;
+ IDXGIDebug *debug;
+ IDXGIInfoQueue *iqueue;
+#endif
// Device capabilities
D3D_FEATURE_LEVEL fl;
@@ -2094,24 +2097,25 @@ static uint64_t timer_stop(struct ra *ra, ra_timer *ratimer)
return timer->result;
}
-static int map_msg_severity(D3D11_MESSAGE_SEVERITY sev)
+#if HAVE_DXGI_DEBUG
+static int map_msg_severity(DXGI_INFO_QUEUE_MESSAGE_SEVERITY sev)
{
switch (sev) {
- case D3D11_MESSAGE_SEVERITY_CORRUPTION:
+ case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION:
return MSGL_FATAL;
- case D3D11_MESSAGE_SEVERITY_ERROR:
+ case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR:
return MSGL_ERR;
- case D3D11_MESSAGE_SEVERITY_WARNING:
+ case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_WARNING:
return MSGL_WARN;
default:
- case D3D11_MESSAGE_SEVERITY_INFO:
- case D3D11_MESSAGE_SEVERITY_MESSAGE:
+ case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_INFO:
+ case DXGI_INFO_QUEUE_MESSAGE_SEVERITY_MESSAGE:
return MSGL_DEBUG;
}
}
static int map_msg_severity_by_id(D3D11_MESSAGE_ID id,
- D3D11_MESSAGE_SEVERITY sev)
+ DXGI_INFO_QUEUE_MESSAGE_SEVERITY sev)
{
switch (id) {
// These are normal. The RA timer queue habitually reuses timer objects
@@ -2168,9 +2172,11 @@ static int map_msg_severity_by_id(D3D11_MESSAGE_ID id,
return map_msg_severity(sev);
}
}
+#endif
static void debug_marker(struct ra *ra, const char *msg)
{
+#if HAVE_DXGI_DEBUG
struct ra_d3d11 *p = ra->priv;
void *talloc_ctx = talloc_new(NULL);
HRESULT hr;
@@ -2180,33 +2186,38 @@ static void debug_marker(struct ra *ra, const char *msg)
// Copy debug-layer messages to mpv's log output
bool printed_header = false;
- uint64_t messages = ID3D11InfoQueue_GetNumStoredMessages(p->iqueue);
+ uint64_t messages = IDXGIInfoQueue_GetNumStoredMessages(p->iqueue,
+ DXGI_DEBUG_ALL);
for (uint64_t i = 0; i < messages; i++) {
SIZE_T len;
- hr = ID3D11InfoQueue_GetMessage(p->iqueue, i, NULL, &len);
+ hr = IDXGIInfoQueue_GetMessage(p->iqueue, DXGI_DEBUG_ALL, i, NULL, &len);
if (FAILED(hr) || !len)
goto done;
- D3D11_MESSAGE *d3dmsg = talloc_size(talloc_ctx, len);
- hr = ID3D11InfoQueue_GetMessage(p->iqueue, i, d3dmsg, &len);
+ DXGI_INFO_QUEUE_MESSAGE *dxgimsg = talloc_size(talloc_ctx, len);
+ hr = IDXGIInfoQueue_GetMessage(p->iqueue, DXGI_DEBUG_ALL, i, dxgimsg, &len);
if (FAILED(hr))
goto done;
- int msgl = map_msg_severity_by_id(d3dmsg->ID, d3dmsg->Severity);
+ int msgl = IsEqualGUID(&dxgimsg->Producer, &DXGI_DEBUG_D3D11)
+ ? map_msg_severity_by_id(dxgimsg->ID, dxgimsg->Severity)
+ : map_msg_severity(dxgimsg->Severity);
+
if (mp_msg_test(ra->log, msgl)) {
if (!printed_header)
MP_INFO(ra, "%s:\n", msg);
printed_header = true;
- MP_MSG(ra, msgl, "%d: %.*s\n", (int)d3dmsg->ID,
- (int)d3dmsg->DescriptionByteLength, d3dmsg->pDescription);
- talloc_free(d3dmsg);
+ MP_MSG(ra, msgl, "%d: %.*s\n", (int)dxgimsg->ID,
+ (int)dxgimsg->DescriptionByteLength, dxgimsg->pDescription);
+ talloc_free(dxgimsg);
}
}
- ID3D11InfoQueue_ClearStoredMessages(p->iqueue);
+ IDXGIInfoQueue_ClearStoredMessages(p->iqueue, DXGI_DEBUG_ALL);
done:
talloc_free(talloc_ctx);
+#endif
}
static void destroy(struct ra *ra)
@@ -2237,16 +2248,18 @@ static void destroy(struct ra *ra)
}
SAFE_RELEASE(p->ctx);
+#if HAVE_DXGI_DEBUG
if (p->debug) {
// Report any leaked objects
debug_marker(ra, "after destroy");
- ID3D11Debug_ReportLiveDeviceObjects(p->debug, D3D11_RLDO_DETAIL);
+ IDXGIDebug_ReportLiveObjects(p->debug, DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_DETAIL);
debug_marker(ra, "after leak check");
- ID3D11Debug_ReportLiveDeviceObjects(p->debug, D3D11_RLDO_SUMMARY);
+ IDXGIDebug_ReportLiveObjects(p->debug, DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_SUMMARY);
debug_marker(ra, "after leak summary");
}
SAFE_RELEASE(p->debug);
SAFE_RELEASE(p->iqueue);
+#endif
talloc_free(ra);
}
@@ -2280,34 +2293,6 @@ void ra_d3d11_flush(struct ra *ra)
ID3D11DeviceContext_Flush(p->ctx);
}
-static void init_debug_layer(struct ra *ra)
-{
- struct ra_d3d11 *p = ra->priv;
- HRESULT hr;
-
- hr = ID3D11Device_QueryInterface(p->dev, &IID_ID3D11Debug,
- (void**)&p->debug);
- if (FAILED(hr)) {
- MP_ERR(ra, "Failed to get debug device: %s\n", mp_HRESULT_to_str(hr));
- return;
- }
-
- hr = ID3D11Device_QueryInterface(p->dev, &IID_ID3D11InfoQueue,
- (void**)&p->iqueue);
- if (FAILED(hr)) {
- MP_ERR(ra, "Failed to get info queue: %s\n", mp_HRESULT_to_str(hr));
- return;
- }
-
- // Store an unlimited amount of messages in the buffer. This is fine
- // because we flush stored messages regularly (in debug_marker.)
- ID3D11InfoQueue_SetMessageCountLimit(p->iqueue, -1);
-
- // Push empty filter to get everything
- D3D11_INFO_QUEUE_FILTER filter = {0};
- ID3D11InfoQueue_PushStorageFilter(p->iqueue, &filter);
-}
-
static struct dll_version get_dll_version(HMODULE dll)
{
void *ctx = talloc_new(NULL);
@@ -2466,8 +2451,10 @@ struct ra *ra_d3d11_create(ID3D11Device *dev, struct mp_log *log,
p->max_uavs = D3D11_PS_CS_UAV_REGISTER_COUNT;
}
+#if HAVE_DXGI_DEBUG
if (ID3D11Device_GetCreationFlags(p->dev) & D3D11_CREATE_DEVICE_DEBUG)
- init_debug_layer(ra);
+ mp_d3d11_get_debug_interfaces(ra->log, &p->debug, &p->iqueue);
+#endif
// Some level 9_x devices don't have timestamp queries
hr = ID3D11Device_CreateQuery(p->dev,
@@ -2481,9 +2468,11 @@ struct ra *ra_d3d11_create(ID3D11Device *dev, struct mp_log *log,
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff476874.aspx
find_max_texture_dimension(ra);
+#if HAVE_DXGI_DEBUG
// Ignore any messages during find_max_texture_dimension
if (p->iqueue)
- ID3D11InfoQueue_ClearStoredMessages(p->iqueue);
+ IDXGIInfoQueue_ClearStoredMessages(p->iqueue, DXGI_DEBUG_ALL);
+#endif
MP_VERBOSE(ra, "Maximum Texture2D size: %dx%d\n", ra->max_texture_wh,
ra->max_texture_wh);
diff --git a/video/out/gpu/context.c b/video/out/gpu/context.c
index 88d4f4232d..3202729741 100644
--- a/video/out/gpu/context.c
+++ b/video/out/gpu/context.c
@@ -57,7 +57,27 @@ extern const struct ra_ctx_fns ra_ctx_d3d11;
/* No API */
extern const struct ra_ctx_fns ra_ctx_wldmabuf;
+/* Autoprobe dummy. Always fails to create. */
+static bool dummy_init(struct ra_ctx *ctx)
+{
+ return false;
+}
+
+static void dummy_uninit(struct ra_ctx *ctx)
+{
+}
+
+static const struct ra_ctx_fns ra_ctx_dummy = {
+ .type = "auto",
+ .name = "auto",
+ .description = "Auto detect",
+ .init = dummy_init,
+ .uninit = dummy_uninit,
+};
+
static const struct ra_ctx_fns *contexts[] = {
+ &ra_ctx_dummy,
+// Direct3D contexts:
#if HAVE_D3D11
&ra_ctx_d3d11,
#endif
@@ -110,21 +130,53 @@ static const struct ra_ctx_fns *contexts[] = {
&ra_ctx_vulkan_mac,
#endif
#endif
+};
+static const struct ra_ctx_fns *no_api_contexts[] = {
+ &ra_ctx_dummy,
/* No API contexts: */
#if HAVE_DMABUF_WAYLAND
&ra_ctx_wldmabuf,
#endif
};
+static bool get_desc(struct m_obj_desc *dst, int index)
+{
+ if (index >= MP_ARRAY_SIZE(contexts))
+ return false;