From 1f76e6914596868e53b5ed4f50353ba44177ab4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ekstr=C3=B6m?= Date: Sun, 29 Sep 2019 18:21:59 +0300 Subject: vo_gpu/d3d11: add adapter name validation and listing with "help" Not the prettiest way to get it done, but seems to work. --- video/out/d3d11/context.c | 37 ++++++++++++++++++++++++++++++++++++- video/out/gpu/d3d11_helpers.c | 38 +++++++++++++++++++++++++++++++++----- video/out/gpu/d3d11_helpers.h | 4 ++++ 3 files changed, 73 insertions(+), 6 deletions(-) (limited to 'video/out') diff --git a/video/out/d3d11/context.c b/video/out/d3d11/context.c index 8359f7ffd2..17bcdcc1f6 100644 --- a/video/out/d3d11/context.c +++ b/video/out/d3d11/context.c @@ -26,6 +26,10 @@ #include "video/out/w32_common.h" #include "ra_d3d11.h" +static int d3d11_validate_adapter(struct mp_log *log, + const struct m_option *opt, + struct bstr name, struct bstr param); + struct d3d11_opts { int feature_level; int warp; @@ -53,7 +57,8 @@ const struct m_sub_options d3d11_conf = { {"9_1", D3D_FEATURE_LEVEL_9_1})), OPT_FLAG("d3d11-flip", flip, 0), OPT_INTRANGE("d3d11-sync-interval", sync_interval, 0, 0, 4), - OPT_STRING("d3d11-adapter", adapter_name, 0), + OPT_STRING_VALIDATE("d3d11-adapter", adapter_name, 0, + d3d11_validate_adapter), {0} }, .defaults = &(const struct d3d11_opts) { @@ -80,6 +85,36 @@ struct priv { int64_t last_submit_qpc; }; +static int d3d11_validate_adapter(struct mp_log *log, + const struct m_option *opt, + struct bstr name, struct bstr param) +{ + bool help = bstr_equals0(param, "help"); + bool adapter_matched = false; + struct bstr listing = { 0 }; + + if (bstr_equals0(param, "")) { + return 0; + } + + adapter_matched = mp_d3d11_list_or_verify_adapters(log, + help ? NULL : ¶m, + help ? &listing : NULL); + + if (help) { + mp_info(log, "Available D3D11 adapters:\n%.*s", + BSTR_P(listing)); + talloc_free(listing.start); + return M_OPT_EXIT; + } + + if (!adapter_matched) { + mp_err(log, "No adapter with name '%.*s'!\n", BSTR_P(param)); + } + + return adapter_matched ? 0 : M_OPT_INVALID; +} + static struct ra_tex *get_backbuffer(struct ra_ctx *ctx) { struct priv *p = ctx->priv; diff --git a/video/out/gpu/d3d11_helpers.c b/video/out/gpu/d3d11_helpers.c index cfabfbe3ab..14a30faa86 100644 --- a/video/out/gpu/d3d11_helpers.c +++ b/video/out/gpu/d3d11_helpers.c @@ -22,6 +22,7 @@ #include "common/common.h" #include "common/msg.h" +#include "misc/bstr.h" #include "osdep/io.h" #include "osdep/windows_utils.h" @@ -92,7 +93,9 @@ static int get_feature_levels(int max_fl, int min_fl, return len; } -static IDXGIAdapter1 *get_d3d11_adapter(struct mp_log *log, char *requested_adapter_name) +static IDXGIAdapter1 *get_d3d11_adapter(struct mp_log *log, + char *requested_adapter_name, + struct bstr *listing) { HRESULT hr = S_OK; IDXGIFactory1 *factory; @@ -128,9 +131,12 @@ static IDXGIAdapter1 *get_d3d11_adapter(struct mp_log *log, char *requested_adap 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 : ""); + if (listing) { + bstr_xappend_asprintf(NULL, listing, + "Adapter %u: vendor: %u, description: %s\n", + adapter_num, desc.VendorId, + adapter_description ? adapter_description : ""); + } if (requested_adapter_name && adapter_description && !strcmp(requested_adapter_name, adapter_description)) @@ -166,6 +172,28 @@ static HRESULT create_device(struct mp_log *log, IDXGIAdapter1 *adapter, NULL, flags, levels, levels_len, D3D11_SDK_VERSION, dev, NULL, NULL); } +bool mp_d3d11_list_or_verify_adapters(struct mp_log *log, + bstr *adapter_name, + bstr *listing) +{ + IDXGIAdapter1 *picked_adapter = NULL; + + if (!load_d3d11_functions(log)) { + return false; + } + + if ((picked_adapter = get_d3d11_adapter(log, + adapter_name ? + (char *)adapter_name->start : NULL, + listing))) + { + SAFE_RELEASE(picked_adapter); + return true; + } + + return false; +} + // Create a Direct3D 11 device for rendering and presentation. This is meant to // reduce boilerplate in backends that D3D11, while also making sure they share // the same device creation logic and log the same information. @@ -189,7 +217,7 @@ bool mp_d3d11_create_present_device(struct mp_log *log, goto done; } - adapter = get_d3d11_adapter(log, adapter_name); + adapter = get_d3d11_adapter(log, adapter_name, NULL); if (adapter_name && !adapter) { mp_warn(log, "Adapter '%s' was not found in the system! " diff --git a/video/out/gpu/d3d11_helpers.h b/video/out/gpu/d3d11_helpers.h index c28afc5405..705c5a59cb 100644 --- a/video/out/gpu/d3d11_helpers.h +++ b/video/out/gpu/d3d11_helpers.h @@ -59,6 +59,10 @@ struct d3d11_device_opts { char *adapter_name; }; +bool mp_d3d11_list_or_verify_adapters(struct mp_log *log, + bstr *adapter_name, + bstr *listing); + bool mp_d3d11_create_present_device(struct mp_log *log, struct d3d11_device_opts *opts, ID3D11Device **dev_out); -- cgit v1.2.3