상황
DirectX11로 구현한 렌더러를 사용하는 플레이어가 그래픽카드 영역을 넘나들 때,
리소스가 제대로 해제가 안되는지 메모리, 쓰레드, 핸들이 증가하는 현상이 발생하였다.
위 현상을 해결하기 위해 위 사이트의 내용대로 아래와 같은 방법이 사용되었다.
해제안된 DirectX11 COM 객체를 추적하는 함수 정의
#ifdef _DEBUG
#include <dxgidebug.h>
#endif
#pragma comment(lib, "dxguid.lib")
#ifdef _DEBUG
void list_remaining_d3d_objects()
{
HMODULE dxgidebugdll = GetModuleHandleW(L"dxgidebug.dll");
decltype(&DXGIGetDebugInterface) GetDebugInterface = reinterpret_cast<decltype(&DXGIGetDebugInterface)>(GetProcAddress(dxgidebugdll, "DXGIGetDebugInterface"));
IDXGIDebug *debug;
GetDebugInterface(IID_PPV_ARGS(&debug));
OutputDebugStringW(L"Starting Live Direct3D Object Dump:\r\n");
debug->ReportLiveObjects(DXGI_DEBUG_D3D11, DXGI_DEBUG_RLO_DETAIL);
OutputDebugStringW(L"Completed Live Direct3D Object Dump.\r\n");
debug->Release();
}
#endif
Device 생성할 때 D3D11_CREATE_DEVICE_DEBUG 플래그 설정.
생성 함수에 flag를 파라미터로 넘겨 DEBUG 옵션을 설정하고,
객체 사용이 끝난 뒤 해제 로직을 실행하는 부분 다음에,
위에서 정의한 함수를 실행하여 해제 안된 COM 객체 추적
UINT flags = 0;
//DEBUG flag 설정
#ifdef _DEBUG
flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
//flag 설정한대로 Device 생성
HRESULT ret = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, flags, fls, 2, D3D11_SDK_VERSION, &d3d11dev, &fl, &d3d11devctx);
//... Release() 호출하여 Device 해제 후
//해제안된 COM객체 추적
#ifdef _DEBUG
list_remaining_d3d_objects();
#endif
Refcount가 0이 아닌 것을 찾으면 해제 안된 것을 추적할 수 있다.
우리 회사 코드는 COM 객체가 많지 않아 위 방법으로도 충분했지만,
COM 객체가 같은 종류가 많아서 그 사이에 구분이 필요하다면,
링크를 걸어둔 사이트의 답변처럼 SetPrivateData를 사용자가 설정하면,
아래와 같이 지정한 이름으로 추적 가능하다.
d3d11dev->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("Device") - 1, "Device");
d3d11devctx->SetPrivateData(WKPDID_D3DDebugObjectName, sizeof("DeviceCtx") - 1, "DeviceCtx");
'일하면서 사용한 짧은 지식 > C++, DirectX11' 카테고리의 다른 글
Handle Leak 디버깅 (0) | 2024.01.24 |
---|---|
C++에서 std::to_string으로 int를 string으로 변환, c_str()로 string에서 const char* 반환 (0) | 2022.08.07 |
Direct2D에서 SetTransform으로 설정한 값 초기화하기 (0) | 2022.03.22 |
DirectX11의 Shader를 컴파일하여 헤더파일로 만들기 (0) | 2022.01.05 |
C++에서 인터페이스로 사용하기 위해 Class를 정의한다면, 소멸자에 virtual를 지정해 줘야 한다. (0) | 2022.01.03 |