Merge pull request #8465 from CookiePLMonster/d3d-common-cleanup

D3DCommon: Cleanups and resource leak fix
This commit is contained in:
Anthony 2019-11-27 16:03:44 -08:00 committed by GitHub
commit 9822a2d582
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 48 deletions

View File

@ -72,20 +72,20 @@ void UnloadLibraries()
s_libraries_loaded = false; s_libraries_loaded = false;
} }
IDXGIFactory* CreateDXGIFactory(bool debug_device) Microsoft::WRL::ComPtr<IDXGIFactory> CreateDXGIFactory(bool debug_device)
{ {
IDXGIFactory* factory; Microsoft::WRL::ComPtr<IDXGIFactory> factory;
// Use Win8.1 version if available. // Use Win8.1 version if available.
if (create_dxgi_factory2 && if (create_dxgi_factory2 &&
SUCCEEDED(create_dxgi_factory2(debug_device ? DXGI_CREATE_FACTORY_DEBUG : 0, SUCCEEDED(create_dxgi_factory2(debug_device ? DXGI_CREATE_FACTORY_DEBUG : 0,
IID_PPV_ARGS(&factory)))) IID_PPV_ARGS(factory.GetAddressOf()))))
{ {
return factory; return factory;
} }
// Fallback to original version, without debug support. // Fallback to original version, without debug support.
HRESULT hr = create_dxgi_factory(IID_PPV_ARGS(&factory)); HRESULT hr = create_dxgi_factory(IID_PPV_ARGS(factory.ReleaseAndGetAddressOf()));
if (FAILED(hr)) if (FAILED(hr))
{ {
PanicAlert("CreateDXGIFactory() failed with HRESULT %08X", hr); PanicAlert("CreateDXGIFactory() failed with HRESULT %08X", hr);
@ -98,14 +98,14 @@ IDXGIFactory* CreateDXGIFactory(bool debug_device)
std::vector<std::string> GetAdapterNames() std::vector<std::string> GetAdapterNames()
{ {
Microsoft::WRL::ComPtr<IDXGIFactory> factory; Microsoft::WRL::ComPtr<IDXGIFactory> factory;
HRESULT hr = create_dxgi_factory(IID_PPV_ARGS(&factory)); HRESULT hr = create_dxgi_factory(IID_PPV_ARGS(factory.GetAddressOf()));
if (!SUCCEEDED(hr)) if (FAILED(hr))
return {}; return {};
std::vector<std::string> adapters; std::vector<std::string> adapters;
IDXGIAdapter* adapter; Microsoft::WRL::ComPtr<IDXGIAdapter> adapter;
while (factory->EnumAdapters(static_cast<UINT>(adapters.size()), &adapter) != while (factory->EnumAdapters(static_cast<UINT>(adapters.size()),
DXGI_ERROR_NOT_FOUND) adapter.ReleaseAndGetAddressOf()) != DXGI_ERROR_NOT_FOUND)
{ {
std::string name; std::string name;
DXGI_ADAPTER_DESC desc; DXGI_ADAPTER_DESC desc;
@ -268,53 +268,22 @@ AbstractTextureFormat GetAbstractFormatForDXGIFormat(DXGI_FORMAT format)
} }
} }
void SetDebugObjectName(IUnknown* resource, const char* format, ...) void SetDebugObjectName(IUnknown* resource, std::string_view name)
{ {
if (!g_ActiveConfig.bEnableValidationLayer) if (!g_ActiveConfig.bEnableValidationLayer)
return; return;
std::va_list ap;
va_start(ap, format);
std::string name = StringFromFormatV(format, ap);
va_end(ap);
Microsoft::WRL::ComPtr<ID3D11DeviceChild> child11; Microsoft::WRL::ComPtr<ID3D11DeviceChild> child11;
Microsoft::WRL::ComPtr<ID3D12DeviceChild> child12; Microsoft::WRL::ComPtr<ID3D12DeviceChild> child12;
if (SUCCEEDED(resource->QueryInterface(IID_PPV_ARGS(&child11)))) if (SUCCEEDED(resource->QueryInterface(IID_PPV_ARGS(child11.GetAddressOf()))))
{ {
child11->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast<UINT>(name.length()), child11->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast<UINT>(name.length()),
name.c_str()); name.data());
} }
else if (SUCCEEDED(resource->QueryInterface(IID_PPV_ARGS(&child12)))) else if (SUCCEEDED(resource->QueryInterface(IID_PPV_ARGS(child12.GetAddressOf()))))
{ {
child12->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast<UINT>(name.length()), child12->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast<UINT>(name.length()),
name.c_str()); name.data());
} }
} }
std::string GetDebugObjectName(IUnknown* resource)
{
if (!g_ActiveConfig.bEnableValidationLayer)
return {};
std::string name;
UINT size = 0;
Microsoft::WRL::ComPtr<ID3D11DeviceChild> child11;
Microsoft::WRL::ComPtr<ID3D12DeviceChild> child12;
if (SUCCEEDED(resource->QueryInterface(IID_PPV_ARGS(&child11))))
{
child11->GetPrivateData(WKPDID_D3DDebugObjectName, &size, nullptr);
name.resize(size);
child11->GetPrivateData(WKPDID_D3DDebugObjectName, &size, name.data());
}
else if (SUCCEEDED(resource->QueryInterface(IID_PPV_ARGS(&child12))))
{
child12->GetPrivateData(WKPDID_D3DDebugObjectName, &size, nullptr);
name.resize(size);
child12->GetPrivateData(WKPDID_D3DDebugObjectName, &size, name.data());
}
return name;
}
} // namespace D3DCommon } // namespace D3DCommon

View File

@ -8,6 +8,7 @@
#include <dxgiformat.h> #include <dxgiformat.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <wrl/client.h>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
@ -25,7 +26,7 @@ void UnloadLibraries();
std::vector<std::string> GetAdapterNames(); std::vector<std::string> GetAdapterNames();
// Helper function which creates a DXGI factory. // Helper function which creates a DXGI factory.
IDXGIFactory* CreateDXGIFactory(bool debug_device); Microsoft::WRL::ComPtr<IDXGIFactory> CreateDXGIFactory(bool debug_device);
// Globally-accessible D3DCompiler function. // Globally-accessible D3DCompiler function.
extern pD3DCompile d3d_compile; extern pD3DCompile d3d_compile;
@ -40,6 +41,5 @@ AbstractTextureFormat GetAbstractFormatForDXGIFormat(DXGI_FORMAT format);
// This function will assign a name to the given resource. // This function will assign a name to the given resource.
// The DirectX debug layer will make it easier to identify resources that way, // The DirectX debug layer will make it easier to identify resources that way,
// e.g. when listing up all resources who have unreleased references. // e.g. when listing up all resources who have unreleased references.
void SetDebugObjectName(IUnknown* resource, const char* format, ...); void SetDebugObjectName(IUnknown* resource, std::string_view name);
std::string GetDebugObjectName(IUnknown* resource);
} // namespace D3DCommon } // namespace D3DCommon