Clean up DXGI adapter enumeration code

This commit is contained in:
Cameron Gutman
2022-05-02 19:05:00 -05:00
parent a1c350a537
commit 2480849f39
2 changed files with 24 additions and 33 deletions
@@ -144,52 +144,39 @@ D3D11VARenderer::~D3D11VARenderer()
SAFE_COM_RELEASE(m_Factory); SAFE_COM_RELEASE(m_Factory);
} }
bool D3D11VARenderer::createDeviceByAdapterIndex(int adapterIndex, bool* indexWasInvalid) bool D3D11VARenderer::createDeviceByAdapterIndex(int adapterIndex, bool* adapterNotFound)
{ {
IDXGIAdapter1* adapter; bool success = false;
IDXGIAdapter1* adapter = nullptr;
DXGI_ADAPTER_DESC1 adapterDesc;
HRESULT hr; HRESULT hr;
SDL_assert(m_Device == nullptr); SDL_assert(m_Device == nullptr);
SDL_assert(m_DeviceContext == nullptr); SDL_assert(m_DeviceContext == nullptr);
// If we fail in EnumAdapters(), assume it was an invalid index.
// Even if it wasn't, there's a good chance it will result in an
// infinite loop if we don't treat it like one anyway.
if (indexWasInvalid != nullptr) {
*indexWasInvalid = true;
}
hr = m_Factory->EnumAdapters1(adapterIndex, &adapter); hr = m_Factory->EnumAdapters1(adapterIndex, &adapter);
if (hr == DXGI_ERROR_NOT_FOUND) { if (hr == DXGI_ERROR_NOT_FOUND) {
// Expected at the end of enumeration // Expected at the end of enumeration
return false; goto Exit;
} }
else if (FAILED(hr)) { else if (FAILED(hr)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"IDXGIFactory::EnumAdapters1() failed: %x", "IDXGIFactory::EnumAdapters1() failed: %x",
hr); hr);
return false; goto Exit;
} }
// From now on, we know the adapter was valid
if (indexWasInvalid != nullptr) {
*indexWasInvalid = false;
}
DXGI_ADAPTER_DESC1 adapterDesc;
hr = adapter->GetDesc1(&adapterDesc); hr = adapter->GetDesc1(&adapterDesc);
if (FAILED(hr)) { if (FAILED(hr)) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"IDXGIAdapter::GetDesc() failed: %x", "IDXGIAdapter::GetDesc() failed: %x",
hr); hr);
adapter->Release(); goto Exit;
return false;
} }
if (adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) { if (adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) {
// Skip the WARP device // Skip the WARP device. We know it will fail.
adapter->Release(); goto Exit;
return false;
} }
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
@@ -217,8 +204,7 @@ bool D3D11VARenderer::createDeviceByAdapterIndex(int adapterIndex, bool* indexWa
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"D3D11CreateDevice() failed: %x", "D3D11CreateDevice() failed: %x",
hr); hr);
adapter->Release(); goto Exit;
return false;
} }
if (!checkDecoderSupport(adapter)) { if (!checkDecoderSupport(adapter)) {
@@ -227,12 +213,17 @@ bool D3D11VARenderer::createDeviceByAdapterIndex(int adapterIndex, bool* indexWa
m_Device->Release(); m_Device->Release();
m_Device = nullptr; m_Device = nullptr;
adapter->Release(); goto Exit;
return false;
} }
adapter->Release(); success = true;
return true;
Exit:
if (adapterNotFound != nullptr) {
*adapterNotFound = (adapter == nullptr);
}
SAFE_COM_RELEASE(adapter);
return success;
} }
bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params) bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params)
@@ -271,20 +262,20 @@ bool D3D11VARenderer::initialize(PDECODER_PARAMETERS params)
if (!createDeviceByAdapterIndex(adapterIndex)) { if (!createDeviceByAdapterIndex(adapterIndex)) {
// If that didn't work, we'll try all GPUs in order until we find one // If that didn't work, we'll try all GPUs in order until we find one
// or run out of GPUs (DXGI_ERROR_NOT_FOUND from EnumAdapters()) // or run out of GPUs (DXGI_ERROR_NOT_FOUND from EnumAdapters())
bool invalidIndex = false; bool adapterNotFound = false;
for (int i = 0; !invalidIndex; i++) { for (int i = 0; !adapterNotFound; i++) {
if (i == adapterIndex) { if (i == adapterIndex) {
// Don't try the same GPU again // Don't try the same GPU again
continue; continue;
} }
if (createDeviceByAdapterIndex(i, &invalidIndex)) { if (createDeviceByAdapterIndex(i, &adapterNotFound)) {
// This GPU worked! Continue initialization. // This GPU worked! Continue initialization.
break; break;
} }
} }
if (invalidIndex) { if (adapterNotFound) {
SDL_assert(m_Device == nullptr); SDL_assert(m_Device == nullptr);
SDL_assert(m_DeviceContext == nullptr); SDL_assert(m_DeviceContext == nullptr);
return false; return false;
@@ -34,7 +34,7 @@ private:
void bindColorConversion(AVFrame* frame); void bindColorConversion(AVFrame* frame);
void renderVideo(AVFrame* frame); void renderVideo(AVFrame* frame);
bool checkDecoderSupport(IDXGIAdapter* adapter); bool checkDecoderSupport(IDXGIAdapter* adapter);
bool createDeviceByAdapterIndex(int adapterIndex, bool* indexWasInvalid = nullptr); bool createDeviceByAdapterIndex(int adapterIndex, bool* adapterNotFound = nullptr);
IDXGIFactory5* m_Factory; IDXGIFactory5* m_Factory;
ID3D11Device* m_Device; ID3D11Device* m_Device;