0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 03:52:22 +02:00

vo_gpu/d3d11: utilize the passed adapter name

Normalize nullptr and an empty string both to nullptr to simplify
handling. API users cannot set a value back to nullptr, so both
an empty string as well as nullptr should behave the same.
This commit is contained in:
Jan Ekström 2019-04-20 01:30:49 +03:00
parent e6447e2e89
commit b7438d3aff

View File

@ -78,8 +78,65 @@ static int get_feature_levels(int max_fl, int min_fl,
return len;
}
static HRESULT create_device(struct mp_log *log, bool warp, bool debug,
int max_fl, int min_fl, ID3D11Device **dev)
static IDXGIAdapter1 *get_d3d11_adapter(struct mp_log *log, char *requested_adapter_name)
{
HRESULT hr = S_OK;
IDXGIFactory1 *factory;
IDXGIAdapter1 *picked_adapter = NULL;
hr = pCreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&factory);
if (FAILED(hr)) {
mp_fatal(log, "Failed to create a DXGI factory: %s\n",
mp_HRESULT_to_str(hr));
return NULL;
}
for (unsigned int adapter_num = 0; hr != DXGI_ERROR_NOT_FOUND; adapter_num++)
{
IDXGIAdapter1 *adapter = NULL;
DXGI_ADAPTER_DESC1 desc = { 0 };
char *adapter_description = NULL;
hr = IDXGIFactory1_EnumAdapters1(factory, adapter_num, &adapter);
if (FAILED(hr)) {
if (hr != DXGI_ERROR_NOT_FOUND) {
mp_fatal(log, "Failed to enumerate at adapter %u\n",
adapter_num);
}
continue;
}
if (FAILED(IDXGIAdapter1_GetDesc1(adapter, &desc))) {
mp_fatal(log, "Failed to get adapter description when listing at adapter %u\n",
adapter_num);
continue;
}
adapter_description = mp_to_utf8(NULL, desc.Description);
mp_verbose(log, "Adapter %u: vendor: %u, description: %s\n",
adapter_num, desc.VendorId,
adapter_description ? adapter_description : "<No Description>");
if (requested_adapter_name && adapter_description &&
!strcmp(requested_adapter_name, adapter_description))
{
picked_adapter = adapter;
break;
}
talloc_free(adapter_description);
SAFE_RELEASE(adapter);
}
SAFE_RELEASE(factory);
return picked_adapter;
}
static HRESULT create_device(struct mp_log *log, IDXGIAdapter1 *adapter,
bool warp, bool debug, int max_fl, int min_fl,
ID3D11Device **dev)
{
const D3D_FEATURE_LEVEL *levels;
int levels_len = get_feature_levels(max_fl, min_fl, &levels);
@ -91,8 +148,8 @@ static HRESULT create_device(struct mp_log *log, bool warp, bool debug,
D3D_DRIVER_TYPE type = warp ? D3D_DRIVER_TYPE_WARP
: D3D_DRIVER_TYPE_HARDWARE;
UINT flags = debug ? D3D11_CREATE_DEVICE_DEBUG : 0;
return pD3D11CreateDevice(NULL, type, NULL, flags, levels, levels_len,
D3D11_SDK_VERSION, dev, NULL, NULL);
return pD3D11CreateDevice((IDXGIAdapter *)adapter, adapter ? D3D_DRIVER_TYPE_UNKNOWN : type,
NULL, flags, levels, levels_len, D3D11_SDK_VERSION, dev, NULL, NULL);
}
// Create a Direct3D 11 device for rendering and presentation. This is meant to
@ -105,6 +162,9 @@ bool mp_d3d11_create_present_device(struct mp_log *log,
bool warp = opts->force_warp;
int max_fl = opts->max_feature_level;
int min_fl = opts->min_feature_level;
// Normalize nullptr and an empty string to nullptr to simplify handling.
char *adapter_name = (opts->adapter_name && *(opts->adapter_name)) ?
opts->adapter_name : NULL;
ID3D11Device *dev = NULL;
IDXGIDevice1 *dxgi_dev = NULL;
IDXGIAdapter1 *adapter = NULL;
@ -120,13 +180,21 @@ bool mp_d3d11_create_present_device(struct mp_log *log,
goto done;
}
adapter = get_d3d11_adapter(log, adapter_name);
if (adapter_name && !adapter) {
mp_warn(log, "Adapter '%s' was not found in the system! "
"Will fall back to the default adapter.\n",
adapter_name);
}
// Return here to retry creating the device
do {
// Use these default feature levels if they are not set
max_fl = max_fl ? max_fl : D3D_FEATURE_LEVEL_11_0;
min_fl = min_fl ? min_fl : D3D_FEATURE_LEVEL_9_1;
hr = create_device(log, warp, opts->debug, max_fl, min_fl, &dev);
hr = create_device(log, adapter, warp, opts->debug, max_fl, min_fl, &dev);
if (SUCCEEDED(hr))
break;
@ -164,6 +232,10 @@ bool mp_d3d11_create_present_device(struct mp_log *log,
goto done;
} while (true);
// if we picked an adapter, release it here - we're taking another
// from the device.
SAFE_RELEASE(adapter);
hr = ID3D11Device_QueryInterface(dev, &IID_IDXGIDevice1, (void**)&dxgi_dev);
if (FAILED(hr)) {
mp_fatal(log, "Failed to get DXGI device\n");