summaryrefslogtreecommitdiffstats
path: root/video/out/gpu/d3d11_helpers.c
diff options
context:
space:
mode:
authorKacper Michajłow <kasper93@gmail.com>2023-05-01 03:11:15 +0200
committerKacper Michajłow <kasper93@gmail.com>2024-04-19 03:32:29 +0200
commit19a9164e246c197c77ec2d0c0f1f462e42bb4817 (patch)
treee041bb7a86c00e47163ff3820241170161da67e6 /video/out/gpu/d3d11_helpers.c
parent56b3bcaaf2594e38e35f0d115d84ee0e1aeac7ee (diff)
downloadmpv-19a9164e246c197c77ec2d0c0f1f462e42bb4817.tar.bz2
mpv-19a9164e246c197c77ec2d0c0f1f462e42bb4817.tar.xz
d3d11: use IDXGIInfoQueue instead ID3D11InfoQueue
DXGI debug interface encapsulate multiple message queues, which allows to get validation not only for D3D11 calls, but also DXGI ones. Also this makes leak detector not report self debug interface as alive like it was before. And same as with validation, it has ability to detect more alive objects, not being limited to D3D11.
Diffstat (limited to 'video/out/gpu/d3d11_helpers.c')
-rw-r--r--video/out/gpu/d3d11_helpers.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/video/out/gpu/d3d11_helpers.c b/video/out/gpu/d3d11_helpers.c
index d45c038553..358a7deb8b 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,38 @@ done:
SAFE_RELEASE(output6);
return ret;
}
+
+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;
+ }
+}