Эта программа:
#include <d3d12.h>
#pragma comment(lib,"d3d12")
int main()
{
ID3D12Debug *pDebug = NULL;
D3D12GetDebugInterface(__uuidof(ID3D12Debug),(void**)&pDebug);
pDebug->EnableDebugLayer();
pDebug->Release();
ID3D12Device *pDev = NULL;
D3D12CreateDevice(NULL,D3D_FEATURE_LEVEL_12_1,__uuidof(ID3D12Device),(void**)&pDev);
ID3D12DebugDevice *pDebugDevice = NULL;
pDev->QueryInterface(&pDebugDevice);
pDev->Release();
pDebugDevice->ReportLiveDeviceObjects(D3D12_RLDO_DETAIL);
pDebugDevice->Release();
}
дает это в выходных данных отладки:
D3D12 WARNING: Live ID3D12Device at 0x000C6BA8, Refcount: 2 [ STATE_CREATION WARNING #274: LIVE_DEVICE]
D3D12 WARNING: Live ID3D12RootSignature at 0x000E62E8, Refcount: 0, IntRef: 2 [ STATE_CREATION WARNING #577: LIVE_ROOTSIGNATURE]
D3D12 WARNING: Live ID3D12PipelineState at 0x0011C3C8, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #572: LIVE_PIPELINESTATE]
D3D12 WARNING: Live ID3D12PipelineState at 0x001421D8, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #572: LIVE_PIPELINESTATE]
D3D12 WARNING: Live ID3D12Resource at 0x00138FF8, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #575: LIVE_RESOURCE]
D3D12 WARNING: Live ID3D12Heap at 0x00144DD8, Refcount: 0, IntRef: 1 [ STATE_CREATION WARNING #579: LIVE_HEAP]
Отладочное устройство сообщает, что созданное мной устройство D3D12 все еще живо даже после его выпуска. Я знаю, что это действительно так, потому что само отладочное устройство фактически является единственным оставшимся реферером, который поддерживает работу устройства D3D12, но это не утечка с моей точки зрения, так как я правильно выпустил свое устройство D3D12. Это просто загрязняет вывод моей программы, давая ложное указание на наличие ошибки в моем коде.
У меня вопрос: действительно ли я здесь что-то не так делаю? или это плохое поведение в том, как работает отчетность на отладочном устройстве D3D12? Есть идеи, как это решить?
Спасибо!
Вы должны попробовать использовать D3D12_RLDO_IGNORE_INTERNAL
флаг, чтобы игнорировать те элементы, которые имеют RefCount 0, но все еще имеют IntRef.
Я предпочитаю использовать отчеты по отладочным устройствам DXGI вместо Direct3D для сценария «чистого отключения».
В моем DeviceResources В реализации я создаю устройство DXGI следующим образом:
m_dxgiFactoryFlags = 0;
#if defined(_DEBUG)
// Enable the debug layer (requires the Graphics Tools "optional feature").
//
// NOTE: Enabling the debug layer after device creation will invalidate the active device.
{
ComPtr<ID3D12Debug> debugController;
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(debugController.GetAddressOf()))))
{
debugController->EnableDebugLayer();
}
else
{
OutputDebugStringA("WARNING: Direct3D Debug Device is not available\n");
}
ComPtr<IDXGIInfoQueue> dxgiInfoQueue;
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(dxgiInfoQueue.GetAddressOf()))))
{
m_dxgiFactoryFlags = DXGI_CREATE_FACTORY_DEBUG;
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, true);
dxgiInfoQueue->SetBreakOnSeverity(DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, true);
}
}
#endif
ThrowIfFailed(CreateDXGIFactory2(m_dxgiFactoryFlags, IID_PPV_ARGS(m_dxgiFactory.ReleaseAndGetAddressOf())));
Затем, когда я делаю выключение и хочу проверить «утечки»:
#ifdef _DEBUG
{
ComPtr<IDXGIDebug1> dxgiDebug;
if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug))))
{
dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_IGNORE_INTERNAL));
}
}
#endif
Для приложений Win32 есть четкое время для утечек отчета «чистого выхода». Для приложений UWP время жизни контролируется PLM, поэтому вы никогда не получите «чистого выхода» — процесс просто прекращается после приостановки. Для UWP лучшее место для проверки утечки — обработчик «потеря устройства», вызванный ошибками удаления устройства.
Других решений пока нет …