Add DXGIDebug logic to help track memory leaks, fix SRV leak it discovered

d3d11-revived
Caleb Cornett 2024-02-07 08:02:49 -06:00
parent 1b63ff8467
commit 30fe868ea2
2 changed files with 81 additions and 1 deletions

View File

@ -29,10 +29,12 @@
#define D3D11_NO_HELPERS #define D3D11_NO_HELPERS
#define CINTERFACE #define CINTERFACE
#define COBJMACROS #define COBJMACROS
#include <d3d11.h> #include <d3d11.h>
#include <d3d11_1.h> #include <d3d11_1.h>
#include <dxgi.h> #include <dxgi.h>
#include <dxgi1_6.h> #include <dxgi1_6.h>
#include <dxgidebug.h>
#include <d3dcompiler.h> #include <d3dcompiler.h>
#include "Refresh_Driver.h" #include "Refresh_Driver.h"
@ -45,9 +47,11 @@
#define D3D11_DLL "d3d11.dll" #define D3D11_DLL "d3d11.dll"
#define DXGI_DLL "dxgi.dll" #define DXGI_DLL "dxgi.dll"
#define DXGIDEBUG_DLL "dxgidebug.dll"
#define D3D11_CREATE_DEVICE_FUNC "D3D11CreateDevice" #define D3D11_CREATE_DEVICE_FUNC "D3D11CreateDevice"
#define D3DCOMPILE_FUNC "D3DCompile" #define D3DCOMPILE_FUNC "D3DCompile"
#define CREATE_DXGI_FACTORY1_FUNC "CreateDXGIFactory1" #define CREATE_DXGI_FACTORY1_FUNC "CreateDXGIFactory1"
#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
#define WINDOW_DATA "Refresh_D3D11WindowData" #define WINDOW_DATA "Refresh_D3D11WindowData"
#define UBO_BUFFER_SIZE 16000 /* 16KB */ #define UBO_BUFFER_SIZE 16000 /* 16KB */
@ -463,8 +467,11 @@ typedef struct D3D11Renderer
ID3D11DeviceContext *immediateContext; ID3D11DeviceContext *immediateContext;
IDXGIFactory1 *factory; IDXGIFactory1 *factory;
IDXGIAdapter1 *adapter; IDXGIAdapter1 *adapter;
IDXGIDebug *dxgiDebug;
IDXGIInfoQueue *dxgiInfoQueue;
void *d3d11_dll; void *d3d11_dll;
void *dxgi_dll; void *dxgi_dll;
void *dxgidebug_dll;
void *d3dcompiler_dll; void *d3dcompiler_dll;
uint8_t debugMode; uint8_t debugMode;
@ -612,9 +619,25 @@ static void D3D11_DestroyDevice(
IDXGIAdapter_Release(renderer->adapter); IDXGIAdapter_Release(renderer->adapter);
IDXGIFactory_Release(renderer->factory); IDXGIFactory_Release(renderer->factory);
/* Report leaks and clean up debug objects */
if (renderer->dxgiDebug)
{
IDXGIDebug_ReportLiveObjects(renderer->dxgiDebug, D3D_IID_DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_ALL);
IDXGIDebug_Release(renderer->dxgiDebug);
}
if (renderer->dxgiInfoQueue)
{
IDXGIInfoQueue_Release(renderer->dxgiInfoQueue);
}
/* Release the DLLs */ /* Release the DLLs */
SDL_UnloadObject(renderer->d3d11_dll); SDL_UnloadObject(renderer->d3d11_dll);
SDL_UnloadObject(renderer->dxgi_dll); SDL_UnloadObject(renderer->dxgi_dll);
if (renderer->dxgidebug_dll)
{
SDL_UnloadObject(renderer->dxgidebug_dll);
}
SDL_UnloadObject(renderer->d3dcompiler_dll); SDL_UnloadObject(renderer->d3dcompiler_dll);
/* Free the primary Refresh structures */ /* Free the primary Refresh structures */
@ -1842,7 +1865,18 @@ static void D3D11_QueueDestroyTexture(
Refresh_Texture *texture Refresh_Texture *texture
) { ) {
D3D11Texture *d3d11Texture = (D3D11Texture*) texture; D3D11Texture *d3d11Texture = (D3D11Texture*) texture;
if (d3d11Texture->shaderView)
{
ID3D11ShaderResourceView_Release(d3d11Texture->shaderView);
}
if (d3d11Texture->targetView)
{
ID3D11View_Release(d3d11Texture->targetView);
}
ID3D11Resource_Release(d3d11Texture->handle); ID3D11Resource_Release(d3d11Texture->handle);
SDL_free(d3d11Texture); SDL_free(d3d11Texture);
} }
@ -3052,6 +3086,42 @@ static uint8_t D3D11_PrepareDriver(
return 1; return 1;
} }
static void D3D11_INTERNAL_TryInitializeDXGIDebug(D3D11Renderer *renderer)
{
PFN_DXGI_GET_DEBUG_INTERFACE DXGIGetDebugInterfaceFunc;
HRESULT res;
renderer->dxgidebug_dll = SDL_LoadObject(DXGIDEBUG_DLL);
if (renderer->dxgidebug_dll == NULL)
{
Refresh_LogWarn("Could not find " DXGIDEBUG_DLL);
return;
}
DXGIGetDebugInterfaceFunc = SDL_LoadFunction(
renderer->dxgidebug_dll,
DXGI_GET_DEBUG_INTERFACE_FUNC
);
if (DXGIGetDebugInterfaceFunc == NULL)
{
Refresh_LogWarn("Could not load function: " DXGI_GET_DEBUG_INTERFACE_FUNC);
return;
}
res = DXGIGetDebugInterfaceFunc(&D3D_IID_IDXGIDebug, &renderer->dxgiDebug);
if (FAILED(res))
{
Refresh_LogWarn("Could not get IDXGIDebug interface");
}
/* FIXME: Actually do something with the info queue! */
res = DXGIGetDebugInterfaceFunc(&D3D_IID_IDXGIInfoQueue, &renderer->dxgiInfoQueue);
if (FAILED(res))
{
Refresh_LogWarn("Could not get IDXGIInfoQueue interface");
}
}
static Refresh_Device* D3D11_CreateDevice( static Refresh_Device* D3D11_CreateDevice(
uint8_t debugMode uint8_t debugMode
) { ) {
@ -3141,6 +3211,12 @@ static Refresh_Device* D3D11_CreateDevice(
/* Get information about the selected adapter. Used for logging info. */ /* Get information about the selected adapter. Used for logging info. */
IDXGIAdapter1_GetDesc1(renderer->adapter, &adapterDesc); IDXGIAdapter1_GetDesc1(renderer->adapter, &adapterDesc);
/* Initialize the DXGI debug layer, if applicable */
if (debugMode)
{
D3D11_INTERNAL_TryInitializeDXGIDebug(renderer);
}
/* Load the D3D library */ /* Load the D3D library */
renderer->d3d11_dll = SDL_LoadObject(D3D11_DLL); renderer->d3d11_dll = SDL_LoadObject(D3D11_DLL);
if (renderer->d3d11_dll == NULL) if (renderer->d3d11_dll == NULL)

View File

@ -26,11 +26,15 @@
/* Function Pointer Signatures */ /* Function Pointer Signatures */
typedef HRESULT(WINAPI* PFN_CREATE_DXGI_FACTORY1)(const GUID* riid, void** ppFactory); typedef HRESULT(WINAPI* PFN_CREATE_DXGI_FACTORY1)(const GUID* riid, void** ppFactory);
typedef HRESULT(WINAPI* PFN_DXGI_GET_DEBUG_INTERFACE)(const GUID* riid, void** ppDebug);
/* IIDs (from https://magnumdb.com) */ /* IIDs (from https://magnumdb.com) */
static const IID D3D_IID_IDXGIFactory1 = { 0x770aae78,0xf26f,0x4dba,{0xa8,0x29,0x25,0x3c,0x83,0xd1,0xb3,0x87} }; static const IID D3D_IID_IDXGIFactory1 = { 0x770aae78,0xf26f,0x4dba,{0xa8,0x29,0x25,0x3c,0x83,0xd1,0xb3,0x87} };
static const IID D3D_IID_IDXGIFactory6 = { 0xc1b6694f,0xff09,0x44a9,{0xb0,0x3c,0x77,0x90,0x0a,0x0a,0x1d,0x17} }; static const IID D3D_IID_IDXGIFactory6 = { 0xc1b6694f,0xff09,0x44a9,{0xb0,0x3c,0x77,0x90,0x0a,0x0a,0x1d,0x17} };
static const IID D3D_IID_IDXGIAdapter1 = { 0x29038f61,0x3839,0x4626,{0x91,0xfd,0x08,0x68,0x79,0x01,0x1a,0x05} }; static const IID D3D_IID_IDXGIAdapter1 = { 0x29038f61,0x3839,0x4626,{0x91,0xfd,0x08,0x68,0x79,0x01,0x1a,0x05} };
static const IID D3D_IID_ID3D11Texture2D = { 0x6f15aaf2,0xd208,0x4e89,{0x9a,0xb4,0x48,0x95,0x35,0xd3,0x4f,0x9c} }; static const IID D3D_IID_ID3D11Texture2D = { 0x6f15aaf2,0xd208,0x4e89,{0x9a,0xb4,0x48,0x95,0x35,0xd3,0x4f,0x9c} };
static const IID D3D_IID_ID3D11Device1 = { 0xa04bfb29,0x08ef,0x43d6,{0xa4,0x9c,0xa9,0xbd,0xbd,0xcb,0xe6,0x86} }; static const IID D3D_IID_ID3D11Device1 = { 0xa04bfb29,0x08ef,0x43d6,{0xa4,0x9c,0xa9,0xbd,0xbd,0xcb,0xe6,0x86} };
static const IID D3D_IID_IDXGIDebug = { 0x119e7452,0xde9e,0x40fe,{0x88,0x06,0x88,0xf9,0x0c,0x12,0xb4,0x41} };
static const IID D3D_IID_IDXGIInfoQueue = { 0xd67441c7,0x672a,0x476f,{0x9e,0x82,0xcd,0x55,0xb4,0x49,0x49,0xce} };
static const GUID D3D_IID_DXGI_DEBUG_ALL = { 0xe48ae283,0xda80,0x490b,{0x87,0xe6,0x43,0xe9,0xa9,0xcf,0xda,0x08} };