Prefer high-performance discrete GPUs when enumerating adapters

This commit is contained in:
2023-05-26 19:55:11 +03:00
parent 9572073eda
commit bdf6a11491
4 changed files with 115 additions and 13 deletions

View File

@@ -89,7 +89,15 @@ GPUDevice* GPUDeviceDX12::Create()
// Create DXGI factory (CreateDXGIFactory2 is supported on Windows 8.1 or newer)
IDXGIFactory4* dxgiFactory;
HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
IDXGIFactory6* dxgiFactory6;
HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory6));
if (hr == S_OK)
dxgiFactory = dxgiFactory6;
else
{
dxgiFactory6 = nullptr;
hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
}
if (hr != S_OK)
{
LOG(Error, "Cannot create DXGI adapter. Error code: {0:x}.", hr);
@@ -97,6 +105,7 @@ GPUDevice* GPUDeviceDX12::Create()
}
// Enumerate the DXGIFactory's adapters
int32 selectedAdapterIndex = -1;
Array<GPUAdapterDX> adapters;
IDXGIAdapter* tempAdapter;
for (uint32 index = 0; dxgiFactory->EnumAdapters(index, &tempAdapter) != DXGI_ERROR_NOT_FOUND; index++)
@@ -118,8 +127,39 @@ GPUDevice* GPUDeviceDX12::Create()
}
}
// Find the best performing adapter and prefer using it instead of the first device
const auto gpuPreference = DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE;
if (dxgiFactory6 != nullptr && selectedAdapterIndex == -1)
{
if (dxgiFactory6->EnumAdapterByGpuPreference(0, gpuPreference, IID_PPV_ARGS(&tempAdapter)) != DXGI_ERROR_NOT_FOUND)
{
GPUAdapterDX adapter;
if (tempAdapter && CheckDX12Support(tempAdapter))
{
DXGI_ADAPTER_DESC desc;
VALIDATE_DIRECTX_RESULT(tempAdapter->GetDesc(&desc));
for (int i = 0; i < adapters.Count(); i++)
{
if (adapters[i].Description.AdapterLuid.LowPart == desc.AdapterLuid.LowPart &&
adapters[i].Description.AdapterLuid.HighPart == desc.AdapterLuid.HighPart)
{
selectedAdapterIndex = i;
break;
}
}
}
}
}
// Select the adapter to use
GPUAdapterDX selectedAdapter = adapters[0];
if (selectedAdapterIndex < 0)
selectedAdapterIndex = 0;
if (adapters.Count() == 0 || selectedAdapterIndex >= adapters.Count())
{
LOG(Error, "Failed to find valid DirectX adapter!");
return nullptr;
}
GPUAdapterDX selectedAdapter = adapters[selectedAdapterIndex];
uint32 vendorId = 0;
if (CommandLine::Options.NVIDIA)
vendorId = GPU_VENDOR_ID_NVIDIA;