From 29e3a11d78fdb87942afe9ec2a4338fa98509ba6 Mon Sep 17 00:00:00 2001 From: Steve Pronovost Date: Sun, 25 Apr 2021 11:20:46 -0700 Subject: [PATCH] d3d12: Add mechanism for D3D12 Adapter Selection This add a simple mechanism to select which GPU adapter the d3d12 driver should be using. A new environment variable is introduced. MESA_D3D12_DEFAULT_ADAPTER_NAME This represent a substring to search for in the GPU descrition, for example "NVIDIA" or "INTEL", or "NVIDIA GeForce RTX 3090", etc... GPU are searched in order and the first one to include the substring becomes a match. If no match is found, we default to the first enumerated GPU. Reviewed-by: Jesse Natalie Reviewed-by: Erik Faye-Lund Part-of: --- docs/drivers/d3d12.rst | 12 ++++ .../drivers/d3d12/d3d12_dxcore_screen.cpp | 55 ++++++++++++++++--- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/docs/drivers/d3d12.rst b/docs/drivers/d3d12.rst index aa03481055a..4608b2fbeb2 100644 --- a/docs/drivers/d3d12.rst +++ b/docs/drivers/d3d12.rst @@ -47,3 +47,15 @@ environment variables: .. _debug layer: https://docs.microsoft.com/en-us/windows/win32/direct3d12/understanding-the-d3d12-debug-layer .. _GPU validator: https://docs.microsoft.com/en-us/windows/win32/direct3d12/using-d3d12-debug-layer-gpu-based-validation + +Utilities +--------- + +Environment variables that control the behavior of the D3D12 driver. + +.. envvar:: MESA_D3D12_DEFAULT_ADAPTER_NAME ("") + +Specifies a substring to search for when chosing a default adapter to run on. +The first adapter matching the substring is chosen. The substring is not +case sensitive. + diff --git a/src/gallium/drivers/d3d12/d3d12_dxcore_screen.cpp b/src/gallium/drivers/d3d12/d3d12_dxcore_screen.cpp index 20b72eebb57..7c5b032cfc9 100644 --- a/src/gallium/drivers/d3d12/d3d12_dxcore_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_dxcore_screen.cpp @@ -60,20 +60,59 @@ get_dxcore_factory() } static IDXCoreAdapter * -choose_dxcore_adapter(IDXCoreAdapterFactory *factory, LUID *adapter) +choose_dxcore_adapter(IDXCoreAdapterFactory *factory, LUID *adapter_luid) { - IDXCoreAdapter *ret; - if (adapter) { - if (SUCCEEDED(factory->GetAdapterByLuid(*adapter, &ret))) - return ret; + IDXCoreAdapter *adapter = nullptr; + if (adapter_luid) { + if (SUCCEEDED(factory->GetAdapterByLuid(*adapter_luid, &adapter))) + return adapter; debug_printf("D3D12: requested adapter missing, falling back to auto-detection...\n"); } - // The first adapter is the default IDXCoreAdapterList *list = nullptr; if (SUCCEEDED(factory->CreateAdapterList(1, &DXCORE_ADAPTER_ATTRIBUTE_D3D12_GRAPHICS, &list))) { - if (list->GetAdapterCount() > 0 && SUCCEEDED(list->GetAdapter(0, &ret))) - return ret; + +#ifndef _WIN32 + // Pick the user selected adapter if any + char *adapter_name = getenv("MESA_D3D12_DEFAULT_ADAPTER_NAME"); + if (adapter_name) { + for (unsigned i=0; iGetAdapterCount(); i++) { + if (SUCCEEDED(list->GetAdapter(i, &adapter))) { + + size_t desc_size; + if (!SUCCEEDED(adapter->GetPropertySize(DXCoreAdapterProperty::DriverDescription, &desc_size))) { + adapter->Release(); + continue; + } + + char *desc = (char*)malloc(desc_size); + if (!desc) { + adapter->Release(); + continue; + } + + if (!SUCCEEDED(adapter->GetProperty(DXCoreAdapterProperty::DriverDescription, desc_size, desc))) { + free(desc); + adapter->Release(); + continue; + } + + if (strcasestr(desc, adapter_name)) { + free(desc); + return adapter; + } else { + free(desc); + adapter->Release(); + } + } + } + debug_printf("D3D12: Couldn't find an adapter containing the substring (%s)\n", adapter_name); + } +#endif + + // No adapter specified or not found, pick 0 as the default + if (list->GetAdapterCount() > 0 && SUCCEEDED(list->GetAdapter(0, &adapter))) + return adapter; } return NULL;