summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
Diffstat (limited to 'video/out')
-rw-r--r--video/out/cocoa_cb_common.swift69
-rw-r--r--video/out/d3d11/ra_d3d11.c89
-rw-r--r--video/out/drm_atomic.c54
-rw-r--r--video/out/drm_common.c2
-rw-r--r--video/out/drm_prime.c14
-rw-r--r--video/out/gpu/d3d11_helpers.c44
-rw-r--r--video/out/gpu/d3d11_helpers.h13
-rw-r--r--video/out/gpu/lcms.h2
-rw-r--r--video/out/gpu/video.c4
-rw-r--r--video/out/hwdec/dmabuf_interop_wl.c4
-rw-r--r--video/out/hwdec/hwdec_cuda.c47
-rw-r--r--video/out/hwdec/hwdec_cuda.h9
-rw-r--r--video/out/hwdec/hwdec_cuda_gl.c32
-rw-r--r--video/out/hwdec/hwdec_cuda_vk.c50
-rw-r--r--video/out/hwdec/hwdec_drmprime_overlay.c2
-rw-r--r--video/out/hwdec/hwdec_vaapi.c3
-rw-r--r--video/out/mac/common.swift57
-rw-r--r--video/out/mac/gl_layer.swift31
-rw-r--r--video/out/mac/title_bar.swift45
-rw-r--r--video/out/mac/view.swift11
-rw-r--r--video/out/mac/window.swift62
-rw-r--r--video/out/mac_common.swift15
-rw-r--r--video/out/opengl/common.c1
-rw-r--r--video/out/vo_dmabuf_wayland.c16
-rw-r--r--video/out/vo_gpu_next.c5
-rw-r--r--video/out/vo_sdl.c1
-rw-r--r--video/out/vo_sixel.c4
-rw-r--r--video/out/vo_tct.c1
-rw-r--r--video/out/vo_xv.c2
-rw-r--r--video/out/vulkan/context.c58
-rw-r--r--video/out/vulkan/context.h6
-rw-r--r--video/out/w32_common.c107
-rw-r--r--video/out/wayland_common.c106
-rw-r--r--video/out/win32/menu.c17
-rw-r--r--video/out/win32/menu.h2
-rw-r--r--video/out/x11_common.c2
36 files changed, 614 insertions, 373 deletions
diff --git a/video/out/cocoa_cb_common.swift b/video/out/cocoa_cb_common.swift
index 9f32ed651f..b2910dba85 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
}
@@ -122,7 +120,55 @@ class CocoaCB: Common, EventSubscriber {
}
libmpv.setRenderICCProfile(colorSpace)
- layer?.colorspace = colorSpace.cgColorSpace
+ layer?.colorspace = getColorSpace()
+ }
+
+ func getColorSpace() -> CGColorSpace? {
+ guard let colorSpace = window?.screen?.colorSpace?.cgColorSpace else {
+ log.warning("Couldn't retrieve ICC Profile, no color space available")
+ return nil
+ }
+
+ let outputCsp = Int(option.mac.cocoa_cb_output_csp)
+
+ switch outputCsp {
+ case MAC_CSP_AUTO: return colorSpace
+ case MAC_CSP_DISPLAY_P3: return CGColorSpace(name: CGColorSpace.displayP3)
+ case MAC_CSP_DISPLAY_P3_HLG: return CGColorSpace(name: CGColorSpace.displayP3_HLG)
+ case MAC_CSP_DISPLAY_P3_PQ: return CGColorSpace(name: CGColorSpace.displayP3_PQ)
+ case MAC_CSP_DCI_P3: return CGColorSpace(name: CGColorSpace.dcip3)
+ case MAC_CSP_BT_2020: return CGColorSpace(name: CGColorSpace.itur_2020)
+ case MAC_CSP_BT_709: return CGColorSpace(name: CGColorSpace.itur_709)
+ case MAC_CSP_SRGB: return CGColorSpace(name: CGColorSpace.sRGB)
+ case MAC_CSP_SRGB_LINEAR: return CGColorSpace(name: CGColorSpace.linearSRGB)
+ case MAC_CSP_RGB_LINEAR: return CGColorSpace(name: CGColorSpace.genericRGBLinear)
+ case MAC_CSP_ADOBE: return CGColorSpace(name: CGColorSpace.adobeRGB1998)
+ default: break
+ }
+
+#if HAVE_MACOS_11_FEATURES
+ if #available(macOS 11.0, *) {
+ switch outputCsp {
+ case MAC_CSP_BT_2100_HLG: return CGColorSpace(name: CGColorSpace.itur_2100_HLG)
+ case MAC_CSP_BT_2100_PQ: return CGColorSpace(name: CGColorSpace.itur_2100_PQ)
+ default: break
+ }
+ }
+#endif
+
+#if HAVE_MACOS_12_FEATURES
+ if #available(macOS 12.0, *) {
+ switch outputCsp {
+ case MAC_CSP_DISPLAY_P3_LINEAR: return CGColorSpace(name: CGColorSpace.linearDisplayP3)
+ case MAC_CSP_BT_2020_LINEAR: return CGColorSpace(name: CGColorSpace.linearITUR_2020)
+ default: break
+ }
+ }
+#endif
+
+ log.warning("Couldn't retrieve configured color space, falling back to auto")
+
+ return colorSpace
}
override func windowDidEndAnimation() {
@@ -178,10 +224,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/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/drm_atomic.c b/video/out/drm_atomic.c
index 5754504e98..c1a15fa75f 100644
--- a/video/out/drm_atomic.c
+++ b/video/out/drm_atomic.c
@@ -43,7 +43,7 @@ int drm_object_create_properties(struct mp_log *log, int fd,
return 0;
- fail:
+fail:
drm_object_free_properties(object);
return -1;
}
@@ -68,43 +68,43 @@ void drm_object_free_properties(struct drm_object *object)
int drm_object_get_property(struct drm_object *object, char *name, uint64_t *value)
{
- for (int i = 0; i < object->props->count_props; i++) {
- if (strcasecmp(name, object->props_info[i]->name) == 0) {
- *value = object->props->prop_values[i];
- return 0;
- }
- }
-
- return -EINVAL;
+ for (int i = 0; i < object->props->count_props; i++) {
+ if (strcasecmp(name, object->props_info[i]->name) == 0) {
+ *value = object->props->prop_values[i];
+ return 0;
+ }
+ }
+
+ return -EINVAL;
}
drmModePropertyBlobPtr drm_object_get_property_blob(struct drm_object *object, char *name)
{
- uint64_t blob_id;
+ uint64_t blob_id;
- if (!drm_object_get_property(object, name, &blob_id)) {
- return drmModeGetPropertyBlob(object->fd, blob_id);
- }
+ if (!drm_object_get_property(object, name, &blob_id)) {
+ return drmModeGetPropertyBlob(object->fd, blob_id);
+ }
- return NULL;
+ return NULL;
}
int drm_object_set_property(drmModeAtomicReq *request, struct drm_object *object,
char *name, uint64_t value)
{
- for (int i = 0; i < object->props->count_props; i++) {
- if (strcasecmp(name, object->props_info[i]->name) == 0) {
- if (object->props_info[i]->flags & DRM_MODE_PROP_IMMUTABLE) {
- /* Do not try to set immutable values, as this might cause the
- * atomic commit operation to fail. */
- return -EINVAL;
- }
- return drmModeAtomicAddProperty(request, object->id,
- object->props_info[i]->prop_id, value);
- }
- }
-
- return -EINVAL;
+ for (int i = 0; i < object->props->count_props; i++) {
+ if (strcasecmp(name, object->props_info[i]->name) == 0) {
+ if (object->props_info[i]->flags & DRM_MODE_PROP_IMMUTABLE) {
+ /* Do not try to set immutable values, as this might cause the
+ * atomic commit operation to fail. */
+ return -EINVAL;
+ }
+ return drmModeAtomicAddProperty(request, object->id,
+ object->props_info[i]->prop_id, value);
+ }
+ }
+
+ return -EINVAL;
}
struct drm_object *drm_object_create(struct mp_log *log, int fd,
diff --git a/video/out/drm_common.c b/video/out/drm_common.c
index e47de7df86..0f65a8426a 100644
--- a/video/out/drm_common.c
+++ b/video/out/drm_common.c
@@ -583,7 +583,7 @@ static bool setup_crtc(struct vo_drm_state *drm, const drmModeRes *res)
drm->connector->connector_id);
return false;
- success:
+success:
MP_VERBOSE(drm, "Selected Encoder %u with CRTC %u\n",
drm->encoder->encoder_id, drm->crtc_id);
return true;
diff --git a/video/out/drm_prime.c b/video/out/drm_prime.c
index 9335fa8e02..581eb717bb 100644
--- a/video/out/drm_prime.c
+++ b/video/out/drm_prime.c
@@ -86,13 +86,13 @@ int drm_prime_create_framebuffer(struct mp_log *log, int fd,
for (int plane = 0; plane < AV_DRM_MAX_PLANES; plane++) {
drm_prime_add_handle_ref(handle_refs, framebuffer->gem_handles[plane]);
}
- }
+ }
- return 0;
+ return 0;
fail:
- memset(framebuffer, 0, sizeof(*framebuffer));
- return -1;
+ memset(framebuffer, 0, sizeof(*framebuffer));
+ return -1;
}
void drm_prime_destroy_framebuffer(struct mp_log *log, int fd,
@@ -129,9 +129,11 @@ void drm_prime_add_handle_ref(struct drm_prime_handle_refs *handle_refs,
{
if (handle) {
if (handle > handle_refs->size) {
- handle_refs->size = handle;
MP_TARRAY_GROW(handle_refs->ctx, handle_refs->handle_ref_count,
- handle_refs->size);
+ handle - 1);
+ uint32_t *p = handle_refs->handle_ref_count;
+ memset(&p[handle_refs->size], 0, (handle - handle_refs->size) * sizeof(p[0]));
+ handle_refs->size = handle;
}
handle_refs->handle_ref_count[handle - 1]++;
}
diff --git a/video/out/gpu/d3d11_helpers.c b/video/out/gpu/d3d11_helpers.c
index d45c038553..fa37d5ef30 100644
--- a/video/out/gpu/d3d11_helpers.c
+++ b/video/out/gpu/d3d11_helpers.c
@@ -32,14 +32,17 @@
// Windows 8 enum value, not present in mingw-w64 headers
#define DXGI_ADAPTER_FLAG_SOFTWARE (2)
typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID riid, void **ppFactory);
+typedef HRESULT(WINAPI *PFN_DXGI_GET_DEBUG_INTERFACE)(REFIID riid, void **ppDebug);
static mp_once d3d11_once = MP_STATIC_ONCE_INITIALIZER;
static PFN_D3D11_CREATE_DEVICE pD3D11CreateDevice = NULL;
static PFN_CREATE_DXGI_FACTORY pCreateDXGIFactory1 = NULL;
+static PFN_DXGI_GET_DEBUG_INTERFACE pDXGIGetDebugInterface = NULL;
static void d3d11_load(void)
{
HMODULE d3d11 = LoadLibraryW(L"d3d11.dll");
HMODULE dxgilib = LoadLibraryW(L"dxgi.dll");
+ HMODULE dxgidebuglib = LoadLibraryW(L"dxgidebug.dll");
if (!d3d11 || !dxgilib)
return;
@@ -47,6 +50,10 @@ static void d3d11_load(void)
GetProcAddress(d3d11, "D3D11CreateDevice");
pCreateDXGIFactory1 = (PFN_CREATE_DXGI_FACTORY)
GetProcAddress(dxgilib, "CreateDXGIFactory1");
+ if (dxgidebuglib) {
+ pDXGIGetDebugInterface = (PFN_DXGI_GET_DEBUG_INTERFACE)
+ GetProcAddress(dxgidebuglib, "DXGIGetDebugInterface");
+ }
}
static bool load_d3d11_functions(struct mp_log *log)
@@ -995,3 +1002,40 @@ done:
SAFE_RELEASE(output6);
return ret;
}
+
+#if HAVE_DXGI_DEBUG
+void mp_d3d11_get_debug_interfaces(struct mp_log *log, IDXGIDebug **debug,
+ IDXGIInfoQueue **iqueue)
+{
+ load_d3d11_functions(log);
+
+ *iqueue = NULL;
+ *debug = NULL;
+
+ if (!pDXGIGetDebugInterface)
+ return;
+
+ HRESULT hr;
+
+ hr = pDXGIGetDebugInterface(&IID_IDXGIInfoQueue, (void **) iqueue);
+ if (FAILED(hr)) {
+ mp_fatal(log, "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.)
+ IDXGIInfoQueue_SetMessageCountLimit(*iqueue, DXGI_DEBUG_D3D11, -1);
+ IDXGIInfoQueue_SetMessageCountLimit(*iqueue, DXGI_DEBUG_DXGI, -1);
+
+ // Push empty filter to get everything
+ DXGI_INFO_QUEUE_FILTER filter = {0};
+ IDXGIInfoQueue_PushStorageFilter(*iqueue, DXGI_DEBUG_ALL, &filter);
+
+ hr = pDXGIGetDebugInterface(&IID_IDXGIDebug, (void **) debug);
+ if (FAILED(hr)) {
+ mp_fatal(log, "Failed to get debug device: %s\n", mp_HRESULT_to_str(hr));
+ return;
+ }
+}
+#endif
diff --git a/video/out/gpu/d3d11_helpers.h b/video/out/gpu/d3d11_helpers.h
index 6cc6818064..92322b9152 100644
--- a/video/out/gpu/d3d11_helpers.h
+++ b/video/out/gpu/d3d11_helpers.h
@@ -24,6 +24,10 @@
#include <dxgi1_2.h>
#include <dxgi1_6.h>
+#if HAVE_DXGI_DEBUG
+#include <dxgidebug.h>
+#endif
+
#include "video/mp_image.h"
#define D3D_FEATURE_LEVEL_12_0 (0xc000)
@@ -35,6 +39,10 @@
#define DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P2020 ((DXGI_COLOR_SPACE_TYPE)23)
#define DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_TOPLEFT_P2020 ((DXGI_COLOR_SPACE_TYPE)24)
+#if !HAVE_DXGI_DEBUG_D3D11
+DEFINE_GUID(DXGI_DEBUG_D3D11, 0x4b99317b, 0xac39, 0x4aa6, 0xbb, 0xb, 0xba, 0xa0, 0x47, 0x84, 0x79, 0x8f);
+#endif
+
struct d3d11_device_opts {
// Enable the debug layer (D3D11_CREATE_DEVICE_DEBUG)
bool debug;
@@ -109,4 +117,9 @@ bool mp_d3d11_create_swapchain(ID3D11Device *dev, struct mp_log *log,
struct d3d11_swapchain_opts *opts,
IDXGISwapChain **swapchain_out);
+#if HAVE_DXGI_DEBUG
+void mp_d3d11_get_debug_interfaces(struct mp_log *log, IDXGIDebug **debug,
+ IDXGIInfoQueue **iqueue);
+#endif
+
#endif
diff --git a/video/out/gpu/lcms.h b/video/out/gpu/lcms.h
index d0b0fe5b89..30a6c54e83 100644
--- a/video/out/gpu/lcms.h
+++ b/video/out/gpu/lcms.h
@@ -44,6 +44,8 @@ bool gl_lcms_has_changed(struct gl_lcms *p, enum pl_color_primaries prim,
static inline bool gl_parse_3dlut_size(const char *arg, int *p1, int *p2, int *p3)
{
+ if (!arg)
+ return false;
if (!strcmp(arg, "auto")) {
*p1 = *p2 = *p3 = 0;
return true;
diff --git a/video/out/gpu/video.c b/video/out/gpu/video.c
index 1478ec4687..4d8e197229 100644
--- a/video/out/gpu/video.c
+++ b/video/out/gpu/video.c
@@ -965,8 +965,8 @@ static void init_video(struct gl_video *p)
static struct dr_buffer *gl_find_dr_buffer(struct gl_video *p, uint8_t *ptr)
{
- for (int i = 0; i < p->num_dr_buffers; i++) {
- struct dr_buffer *buffer = &p->dr_buffers[i];
+ for (int i = 0; i < p->num_dr_buffers; i++) {
+ struct dr_buffer *buffer = &p->dr_buffers[i];
uint8_t *bufptr = buffer->buf->data;
size_t size = buffer->buf->params.size;
if (ptr >= bufptr && ptr < bufptr + size)
diff --git a/video/out/hwdec/dmabuf_interop_wl.c b/video/out/hwdec/dmabuf_interop_wl.c
index 606a0aa601..78baf146f0 100644
--- a/video/out/hwdec/dmabuf_interop_wl.c
+++ b/video/out/hwdec/dmabuf_interop_wl.c
@@ -46,7 +46,7 @@ static bool map(struct ra_hwdec_mapper *mapper,
return false;
} else if (!ra_compatible_format(mapper->ra, drm_format,
mapper_p->desc.objects[0].format_modifier)) {
- MP_VERBOSE(mapper, "Mapped surface with format %s; drm format '%s(%016lx)' "
+ MP_VERBOSE(mapper, "Mapped surface with format %s; drm format '%s(%016" PRIx64 ")' "
"is not supported by compositor.\n",
mp_imgfmt_to_name(mapper->src->params.hw_subfmt),
mp_tag_str(drm_format),
@@ -54,7 +54,7 @@ static bool map(struct ra_hwdec_mapper *mapper,
return false;
}
- MP_VERBOSE(mapper, "Supported Wayland display format %s: '%s(%016lx)'\n",
+ MP_VERBOSE(mapper, "Supported Wayland display format %s: '%s(%016" PRIx64 ")'\n",
mp_imgfmt_to_name(mapper->src->params.hw_subfmt),
mp_tag_str(drm_format), mapper_p->desc.objects[0].format_modifier);
diff --git a/video/out/hwdec/hwdec_cuda.c b/video/out/hwdec/hwdec_cuda.c
index 57e4fb40e3..8987cf3407 100644
--- a/video/out/hwdec/hwdec_cuda.c
+++ b/video/out/hwdec/hwdec_cuda.c
@@ -57,12 +57,12 @@ int check_cu(const struct ra_hwdec *hw, CUresult err, const char *func)
#define CHECK_CU(x) check_cu(hw, (x), #x)
-static const cuda_interop_init interop_inits[] = {
+static const struct cuda_interop_fn *interop_fns[] = {
#if HAVE_GL
- cuda_gl_init,
+ &cuda_gl_fn,
#endif
#if HAVE_VULKAN
- cuda_vk_init,
+ &cuda_vk_fn,
#endif
NULL
};
@@ -73,25 +73,36 @@ static int cuda_init(struct ra_hwdec *hw)
CUcontext dummy;
int ret = 0;
struct cuda_hw_priv *p = hw->priv;
- CudaFunctions *cu;
+ CudaFunctions *cu = NULL;
int level = hw->probing ? MSGL_V : MSGL_ERR;
-
- ret = cuda_load_functions(&p->cu, NULL);
- if (ret != 0) {
- MP_MSG(hw, level, "Failed to load CUDA symbols\n");
- return -1;
- }
- cu = p->cu;
-
- ret = CHECK_CU(cu->cuInit(0));
- if (ret < 0)
- return -1;
+ bool initialized = false;
// Initialise CUDA context from backend.
- for (int i = 0; interop_inits[i]; i++) {
- if (interop_inits[i](hw)) {
- break;
+ // Note that the interop check doesn't require the CUDA backend to be initialized.
+ // This is important because cuInit wakes up the dgpu (even if the cuda hwdec won't be used!)
+ // Doing this allows us to check if CUDA should be used without waking up the dgpu, avoiding
+ // a few seconds of delay and improving battery life for laptops!
+ for (int i = 0; interop_fns[i]; i++) {
+ if (!interop_fns[i]->check(hw))
+ continue;
+
+ if (!initialized) {
+ ret = cuda_load_functions(&p->cu, NULL);
+ if (ret != 0) {
+ MP_MSG(hw, level, "Failed to load CUDA symbols\n");
+ return -1;
+ }
+
+ cu = p->cu;
+ ret = CHECK_CU(cu->cuInit(0));
+ if (ret < 0)
+ return -1;
+
+ initialized = true;
}
+
+ if (interop_fns[i]->init(hw))
+ break;
}
if (!p->ext_init || !p->ext_uninit) {
diff --git a/video/out/hwdec/hwdec_cuda.h b/video/out/hwdec/hwdec_cuda.h
index 9c55053d59..6e671b364e 100644
--- a/video/out/hwdec/hwdec_cuda.h
+++ b/video/out/hwdec/hwdec_cuda.h
@@ -50,10 +50,13 @@ struct cuda_mapper_priv {
void *ext[4];
};
-typedef bool (*cuda_interop_init)(const struct ra_hwdec *hw);
+struct cuda_interop_fn {
+ bool (*check)(const struct ra_hwdec *hw);
+ bool (*init)(const struct ra_hwdec *hw);
+};
-bool cuda_gl_init(const struct ra_hwdec *hw);
+extern struct cuda_interop_fn cuda_gl_fn;
-bool cuda_vk_init(const struct ra_hwdec *hw);
+extern struct cuda_interop_fn cuda_vk_fn;
int check_cu(const struct ra_hwdec *hw, CUresult err, const char *func);
diff --git a/video/out/hwdec/hwdec_cuda_gl.c b/video/out/hwdec/hwdec_cuda_gl.c
index f20540ed4d..4c2535232f 100644
--- a/video/out/hwdec/hwdec_cuda_gl.c
+++ b/video/out/hwdec/hwdec_cuda_gl.c
@@ -25,7 +25,6 @@
#include <libavutil/hwcontext.h>
#include <libavutil/hwcontext_cuda.h>
-#include <unistd.h>
#define CHECK_CU(x) check_cu((mapper)->owner, (x), #x)
@@ -106,22 +105,24 @@ static void cuda_ext_gl_uninit(const struct ra_hwdec_mapper *mapper, int n)
#undef CHECK_CU
#define CHECK_CU(x) check_cu(hw, (x), #x)
-bool cuda_gl_init(const struct ra_hwdec *hw) {
- int ret = 0;
- struct cuda_hw_priv *p = hw->priv;
- CudaFunctions *cu = p->cu;
+static bool cuda_gl_check(const struct ra_hwdec *hw) {
+ if (!ra_is_gl(hw->ra_ctx->ra))
+ return false; // This is not an OpenGL RA.
- if (ra_is_gl(hw->ra_ctx->ra)) {
- GL *gl = ra_gl_get(hw->ra_ctx->ra);
- if (gl->version < 210 && gl->es < 300) {
- MP_VERBOSE(hw, "need OpenGL >= 2.1 or OpenGL-ES >= 3.0\n");
- return false;
- }
- } else {
- // This is not an OpenGL RA.