mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-09 03:29:43 -10:00
video: follow the GPU an index was chosen as, not the position
A GPU index is a position in the list its driver enumerates, which a driver update, a BIOS change or another card reorders; the saved index then names a different GPU, and the frontend renders on a device that may not be able to reach the display at all. Every index - Vulkan, OpenGL, Direct3D 10, 11 and 12, and Metal - now remembers the device it was chosen as: where that device has moved in the list its new position is used, where it is gone the driver's first device is used with a warning, and index 0 means the driver's own choice as it always did. The name is kept up to date with what was resolved, and an index set by hand takes the device at that position and remembers it.
This commit is contained in:
1 parent
82c06f7d17
commit
0e7a56f171
12 files changed
+139
No files matched your search
@@ -1799,6 +1799,12 @@ static struct config_array_setting *populate_settings_array(
|
||||
SETTING_ARRAY_SENSITIVE("twitch_stream_key", settings->arrays.twitch_stream_key, true, NULL, true);
|
||||
SETTING_ARRAY_SENSITIVE("facebook_stream_key", settings->arrays.facebook_stream_key, true, NULL, true);
|
||||
SETTING_ARRAY_SENSITIVE("kick_stream_key", settings->arrays.kick_stream_key, true, NULL, true);
|
||||
SETTING_ARRAY("video_gpu_name_vulkan", settings->arrays.video_gpu_name_vulkan, false, NULL, true);
|
||||
SETTING_ARRAY("video_gpu_name_gl", settings->arrays.video_gpu_name_gl, false, NULL, true);
|
||||
SETTING_ARRAY("video_gpu_name_d3d10", settings->arrays.video_gpu_name_d3d10, false, NULL, true);
|
||||
SETTING_ARRAY("video_gpu_name_d3d11", settings->arrays.video_gpu_name_d3d11, false, NULL, true);
|
||||
SETTING_ARRAY("video_gpu_name_d3d12", settings->arrays.video_gpu_name_d3d12, false, NULL, true);
|
||||
SETTING_ARRAY("video_gpu_name_metal", settings->arrays.video_gpu_name_metal, false, NULL, true);
|
||||
SETTING_ARRAY("discord_app_id", settings->arrays.discord_app_id, true, DEFAULT_DISCORD_APP_ID, true);
|
||||
SETTING_ARRAY("ai_service_url", settings->arrays.ai_service_url, true, DEFAULT_AI_SERVICE_URL, true);
|
||||
#endif
|
||||
|
||||
@@ -1250,6 +1250,15 @@ typedef struct settings
|
||||
char twitch_stream_key[PATH_MAX_LENGTH];
|
||||
char facebook_stream_key[PATH_MAX_LENGTH];
|
||||
char kick_stream_key[PATH_MAX_LENGTH];
|
||||
/* The device each GPU index named when it was chosen, so a list
|
||||
* that has changed order since is noticed rather than silently
|
||||
* selecting another GPU. */
|
||||
char video_gpu_name_vulkan[NAME_MAX_LENGTH];
|
||||
char video_gpu_name_gl[NAME_MAX_LENGTH];
|
||||
char video_gpu_name_d3d10[NAME_MAX_LENGTH];
|
||||
char video_gpu_name_d3d11[NAME_MAX_LENGTH];
|
||||
char video_gpu_name_d3d12[NAME_MAX_LENGTH];
|
||||
char video_gpu_name_metal[NAME_MAX_LENGTH];
|
||||
char discord_app_id[PATH_MAX_LENGTH];
|
||||
char ai_service_url[PATH_MAX_LENGTH];
|
||||
|
||||
|
||||
@@ -696,6 +696,10 @@ static bool vulkan_context_init_gpu(gfx_ctx_vulkan_data_t *vk)
|
||||
|
||||
video_driver_set_gpu_api_devices(GFX_CTX_VULKAN_API, vk->gpu_list);
|
||||
|
||||
/* The device the index was chosen as, wherever the list now puts it */
|
||||
gpu_index = video_driver_gpu_index_resolve(GFX_CTX_VULKAN_API,
|
||||
gpu_index, vk->gpu_list);
|
||||
|
||||
if (0 <= gpu_index && gpu_index < (int)gpu_count)
|
||||
{
|
||||
RARCH_LOG("[Vulkan] Using GPU #%d: \"%s\".\n", gpu_index, vk->gpu_list->elems[gpu_index].data);
|
||||
|
||||
@@ -2776,6 +2776,11 @@ static void *d3d10_gfx_init(const video_info_t* video,
|
||||
|
||||
video_driver_set_gpu_api_devices(GFX_CTX_DIRECT3D10_API, d3d10->gpu_list);
|
||||
|
||||
/* The device the index was chosen as, wherever the list now
|
||||
* puts it */
|
||||
gpu_index = video_driver_gpu_index_resolve(GFX_CTX_DIRECT3D10_API,
|
||||
gpu_index, d3d10->gpu_list);
|
||||
|
||||
if (0 <= gpu_index && gpu_index <= i && (gpu_index < D3D10_MAX_GPU_COUNT))
|
||||
{
|
||||
RARCH_LOG("[D3D10] Using GPU #%d: \"%s\".\n", gpu_index, d3d10->gpu_list->elems[gpu_index].data);
|
||||
|
||||
@@ -4232,6 +4232,11 @@ static void *d3d11_gfx_init(const video_info_t* video,
|
||||
|
||||
video_driver_set_gpu_api_devices(GFX_CTX_DIRECT3D11_API, d3d11->gpu_list);
|
||||
|
||||
/* The device the index was chosen as, wherever the list now
|
||||
* puts it */
|
||||
gpu_index = video_driver_gpu_index_resolve(GFX_CTX_DIRECT3D11_API,
|
||||
gpu_index, d3d11->gpu_list);
|
||||
|
||||
if (0 <= gpu_index && gpu_index <= i && gpu_index < D3D11_MAX_GPU_COUNT)
|
||||
{
|
||||
RARCH_LOG("[D3D11] Using GPU #%d: \"%s\".\n", gpu_index, d3d11->gpu_list->elems[gpu_index].data);
|
||||
|
||||
@@ -4443,6 +4443,11 @@ static void d3d12_init_base(d3d12_video_t* d3d12)
|
||||
|
||||
video_driver_set_gpu_api_devices(GFX_CTX_DIRECT3D12_API, d3d12->gpu_list);
|
||||
|
||||
/* The device the index was chosen as, wherever the list now
|
||||
* puts it */
|
||||
gpu_index = video_driver_gpu_index_resolve(GFX_CTX_DIRECT3D12_API,
|
||||
gpu_index, d3d12->gpu_list);
|
||||
|
||||
if (0 <= gpu_index && gpu_index <= i && gpu_index < D3D12_MAX_GPU_COUNT)
|
||||
{
|
||||
RARCH_LOG("[D3D12] Using GPU #%d: \"%s\".\n", gpu_index, d3d12->gpu_list->elems[gpu_index].data);
|
||||
|
||||
@@ -4344,6 +4344,11 @@ static void metal_pull_cached_frame_cb(void *userdata,
|
||||
}
|
||||
}
|
||||
|
||||
/* The device the index was chosen as, wherever the list
|
||||
* now puts it */
|
||||
gpu_index = video_driver_gpu_index_resolve(GFX_CTX_METAL_API,
|
||||
gpu_index, _gpu_list);
|
||||
|
||||
if (count > 0 && gpu_index >= 0 && gpu_index < (int)count)
|
||||
{
|
||||
const char *picked_name;
|
||||
|
||||
@@ -1033,6 +1033,9 @@ static void *gfx_ctx_drm_init(void *video_driver)
|
||||
* the others in their usual order after it; the display follows the
|
||||
* card, through GBM. */
|
||||
drm->gl_gpu_list = egl_gpu_list_new();
|
||||
if (drm->gl_gpu_list && settings)
|
||||
settings->ints.gl_gpu_index = video_driver_gpu_index_resolve(
|
||||
drm_api, settings->ints.gl_gpu_index, drm->gl_gpu_list);
|
||||
if (drm->gl_gpu_list && settings->ints.gl_gpu_index > 0)
|
||||
{
|
||||
if ((preferred = egl_gpu_device_file(settings->ints.gl_gpu_index)))
|
||||
|
||||
@@ -232,6 +232,11 @@ static bool gfx_ctx_wl_egl_init_context(gfx_ctx_wayland_data_t *wl)
|
||||
if (wl->gl_gpu_list)
|
||||
string_list_free(wl->gl_gpu_list);
|
||||
wl->gl_gpu_list = egl_gpu_list_new();
|
||||
/* The device the index was chosen as, wherever the list now
|
||||
* puts it */
|
||||
if (wl->gl_gpu_list && settings)
|
||||
settings->ints.gl_gpu_index = video_driver_gpu_index_resolve(
|
||||
wl_api, settings->ints.gl_gpu_index, wl->gl_gpu_list);
|
||||
if (wl->gl_gpu_list && settings && settings->ints.gl_gpu_index > 0)
|
||||
{
|
||||
if ((device = egl_gpu_device_at(settings->ints.gl_gpu_index)))
|
||||
|
||||
@@ -191,6 +191,11 @@ static void *gfx_ctx_xegl_init(void *video_driver)
|
||||
void *device = NULL;
|
||||
settings_t *settings = config_get_ptr();
|
||||
xegl->gl_gpu_list = egl_gpu_list_new();
|
||||
/* The device the index was chosen as, wherever the list now
|
||||
* puts it */
|
||||
if (xegl->gl_gpu_list && settings)
|
||||
settings->ints.gl_gpu_index = video_driver_gpu_index_resolve(
|
||||
xegl_api, settings->ints.gl_gpu_index, xegl->gl_gpu_list);
|
||||
if (xegl->gl_gpu_list && settings && settings->ints.gl_gpu_index > 0)
|
||||
{
|
||||
if ((device = egl_gpu_device_at(settings->ints.gl_gpu_index)))
|
||||
|
||||
@@ -1197,6 +1197,81 @@ float video_driver_hdr_metadata_peak(float driver_value)
|
||||
return display ? (float)display : driver_value;
|
||||
}
|
||||
|
||||
/* The setting holding the device name an API's GPU index was chosen
|
||||
* as; NULL for an API without one. */
|
||||
static char *video_driver_gpu_name_setting(enum gfx_ctx_api api)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
if (!settings)
|
||||
return NULL;
|
||||
switch (api)
|
||||
{
|
||||
case GFX_CTX_VULKAN_API:
|
||||
return settings->arrays.video_gpu_name_vulkan;
|
||||
case GFX_CTX_OPENGL_API:
|
||||
case GFX_CTX_OPENGL_ES_API:
|
||||
return settings->arrays.video_gpu_name_gl;
|
||||
case GFX_CTX_DIRECT3D10_API:
|
||||
return settings->arrays.video_gpu_name_d3d10;
|
||||
case GFX_CTX_DIRECT3D11_API:
|
||||
return settings->arrays.video_gpu_name_d3d11;
|
||||
case GFX_CTX_DIRECT3D12_API:
|
||||
return settings->arrays.video_gpu_name_d3d12;
|
||||
case GFX_CTX_METAL_API:
|
||||
return settings->arrays.video_gpu_name_metal;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int video_driver_gpu_index_resolve(enum gfx_ctx_api api, int index,
|
||||
struct string_list *list)
|
||||
{
|
||||
size_t i;
|
||||
char *saved = video_driver_gpu_name_setting(api);
|
||||
|
||||
if (!list || list->size < 1)
|
||||
return index;
|
||||
/* The default device is whatever the driver puts first */
|
||||
if (index <= 0)
|
||||
{
|
||||
if (saved)
|
||||
*saved = '\0';
|
||||
return 0;
|
||||
}
|
||||
if (saved && *saved)
|
||||
{
|
||||
/* Still where it was */
|
||||
if ( index < (int)list->size
|
||||
&& string_is_equal(list->elems[index].data, saved))
|
||||
return index;
|
||||
/* Moved: follow the device, not the position */
|
||||
for (i = 0; i < list->size; i++)
|
||||
if (string_is_equal(list->elems[i].data, saved))
|
||||
{
|
||||
RARCH_WARN("[Video] GPU \"%s\" is now #%u, not #%d; using it.\n",
|
||||
saved, (unsigned)i, index);
|
||||
return (int)i;
|
||||
}
|
||||
RARCH_WARN("[Video] GPU \"%s\" is gone; using the first device found.\n",
|
||||
saved);
|
||||
*saved = '\0';
|
||||
return 0;
|
||||
}
|
||||
/* Chosen before the name was kept, or by hand: take it as it is and
|
||||
* remember what it named */
|
||||
if (index < (int)list->size)
|
||||
{
|
||||
if (saved)
|
||||
strlcpy(saved, list->elems[index].data, NAME_MAX_LENGTH);
|
||||
return index;
|
||||
}
|
||||
RARCH_WARN("[Video] GPU index %d is past the %u device(s) there are; using the first.\n",
|
||||
index, (unsigned)list->size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void video_driver_set_gpu_api_devices(
|
||||
enum gfx_ctx_api api, struct string_list *list)
|
||||
{
|
||||
|
||||
@@ -2029,6 +2029,18 @@ float video_driver_get_hdr_max_nits(void);
|
||||
* driver's own fixed value, unchanged. */
|
||||
float video_driver_hdr_metadata_peak(float driver_value);
|
||||
|
||||
/* The GPU index to use for 'api' out of the devices in 'list'.
|
||||
*
|
||||
* An index alone is a position in a list that a driver update, a BIOS
|
||||
* change or another GPU reorders, after which it names a different
|
||||
* device. The device the index was chosen as is remembered with it:
|
||||
* where that name has moved, its new position is returned; where it is
|
||||
* gone, 0 with a warning, rather than whatever now sits at the index.
|
||||
* The name is kept up to date with what was resolved.
|
||||
*/
|
||||
int video_driver_gpu_index_resolve(enum gfx_ctx_api api, int index,
|
||||
struct string_list *list);
|
||||
|
||||
struct string_list* video_driver_get_gpu_api_devices(enum gfx_ctx_api api);
|
||||
|
||||
const char *hw_render_context_name(
|
||||
|
||||
Reference in new issue
Block a user