forked from MoonsideGames/Refresh
Add DXGIDebug logic to help track memory leaks, fix SRV leak it discovered
parent
1b63ff8467
commit
30fe868ea2
|
@ -29,10 +29,12 @@
|
|||
#define D3D11_NO_HELPERS
|
||||
#define CINTERFACE
|
||||
#define COBJMACROS
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <d3d11_1.h>
|
||||
#include <dxgi.h>
|
||||
#include <dxgi1_6.h>
|
||||
#include <dxgidebug.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#include "Refresh_Driver.h"
|
||||
|
@ -45,9 +47,11 @@
|
|||
|
||||
#define D3D11_DLL "d3d11.dll"
|
||||
#define DXGI_DLL "dxgi.dll"
|
||||
#define DXGIDEBUG_DLL "dxgidebug.dll"
|
||||
#define D3D11_CREATE_DEVICE_FUNC "D3D11CreateDevice"
|
||||
#define D3DCOMPILE_FUNC "D3DCompile"
|
||||
#define CREATE_DXGI_FACTORY1_FUNC "CreateDXGIFactory1"
|
||||
#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
|
||||
#define WINDOW_DATA "Refresh_D3D11WindowData"
|
||||
#define UBO_BUFFER_SIZE 16000 /* 16KB */
|
||||
|
||||
|
@ -463,8 +467,11 @@ typedef struct D3D11Renderer
|
|||
ID3D11DeviceContext *immediateContext;
|
||||
IDXGIFactory1 *factory;
|
||||
IDXGIAdapter1 *adapter;
|
||||
IDXGIDebug *dxgiDebug;
|
||||
IDXGIInfoQueue *dxgiInfoQueue;
|
||||
void *d3d11_dll;
|
||||
void *dxgi_dll;
|
||||
void *dxgidebug_dll;
|
||||
void *d3dcompiler_dll;
|
||||
|
||||
uint8_t debugMode;
|
||||
|
@ -612,9 +619,25 @@ static void D3D11_DestroyDevice(
|
|||
IDXGIAdapter_Release(renderer->adapter);
|
||||
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 */
|
||||
SDL_UnloadObject(renderer->d3d11_dll);
|
||||
SDL_UnloadObject(renderer->dxgi_dll);
|
||||
if (renderer->dxgidebug_dll)
|
||||
{
|
||||
SDL_UnloadObject(renderer->dxgidebug_dll);
|
||||
}
|
||||
SDL_UnloadObject(renderer->d3dcompiler_dll);
|
||||
|
||||
/* Free the primary Refresh structures */
|
||||
|
@ -1842,7 +1865,18 @@ static void D3D11_QueueDestroyTexture(
|
|||
Refresh_Texture *texture
|
||||
) {
|
||||
D3D11Texture *d3d11Texture = (D3D11Texture*) texture;
|
||||
|
||||
if (d3d11Texture->shaderView)
|
||||
{
|
||||
ID3D11ShaderResourceView_Release(d3d11Texture->shaderView);
|
||||
}
|
||||
if (d3d11Texture->targetView)
|
||||
{
|
||||
ID3D11View_Release(d3d11Texture->targetView);
|
||||
}
|
||||
|
||||
ID3D11Resource_Release(d3d11Texture->handle);
|
||||
|
||||
SDL_free(d3d11Texture);
|
||||
}
|
||||
|
||||
|
@ -3052,6 +3086,42 @@ static uint8_t D3D11_PrepareDriver(
|
|||
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(
|
||||
uint8_t debugMode
|
||||
) {
|
||||
|
@ -3141,6 +3211,12 @@ static Refresh_Device* D3D11_CreateDevice(
|
|||
/* Get information about the selected adapter. Used for logging info. */
|
||||
IDXGIAdapter1_GetDesc1(renderer->adapter, &adapterDesc);
|
||||
|
||||
/* Initialize the DXGI debug layer, if applicable */
|
||||
if (debugMode)
|
||||
{
|
||||
D3D11_INTERNAL_TryInitializeDXGIDebug(renderer);
|
||||
}
|
||||
|
||||
/* Load the D3D library */
|
||||
renderer->d3d11_dll = SDL_LoadObject(D3D11_DLL);
|
||||
if (renderer->d3d11_dll == NULL)
|
||||
|
|
|
@ -26,11 +26,15 @@
|
|||
|
||||
/* Function Pointer Signatures */
|
||||
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) */
|
||||
|
||||
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_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_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} };
|
||||
|
|
Loading…
Reference in New Issue