d3d10/11/12: add GPU selection

This commit is contained in:
Brad Parker 2019-06-18 16:33:37 -04:00
parent 6753bfcf9c
commit d01f04c146
14 changed files with 352 additions and 38 deletions

View File

@ -874,6 +874,18 @@ static const bool enable_device_vibration = false;
#define DEFAULT_VULKAN_GPU_INDEX 0
#endif
#ifdef HAVE_D3D10
#define DEFAULT_D3D10_GPU_INDEX 0
#endif
#ifdef HAVE_D3D11
#define DEFAULT_D3D11_GPU_INDEX 0
#endif
#ifdef HAVE_D3D12
#define DEFAULT_D3D12_GPU_INDEX 0
#endif
#if defined(HAKCHI)
static char buildbot_server_url[] = "http://hakchicloud.com/Libretro_Cores/";
#elif defined(ANDROID)

View File

@ -1867,6 +1867,15 @@ static struct config_int_setting *populate_settings_int(settings_t *settings, in
#ifdef HAVE_VULKAN
SETTING_INT("vulkan_gpu_index", &settings->ints.vulkan_gpu_index, true, DEFAULT_VULKAN_GPU_INDEX, false);
#endif
#ifdef HAVE_D3D10
SETTING_INT("d3d10_gpu_index", &settings->ints.d3d10_gpu_index, true, DEFAULT_D3D10_GPU_INDEX, false);
#endif
#ifdef HAVE_D3D11
SETTING_INT("d3d11_gpu_index", &settings->ints.d3d11_gpu_index, true, DEFAULT_D3D11_GPU_INDEX, false);
#endif
#ifdef HAVE_D3D12
SETTING_INT("d3d12_gpu_index", &settings->ints.d3d12_gpu_index, true, DEFAULT_D3D12_GPU_INDEX, false);
#endif
*size = count;

View File

@ -390,6 +390,15 @@ typedef struct settings
int crt_switch_center_adjust;
#ifdef HAVE_VULKAN
int vulkan_gpu_index;
#endif
#ifdef HAVE_D3D10
int d3d10_gpu_index;
#endif
#ifdef HAVE_D3D11
int d3d11_gpu_index;
#endif
#ifdef HAVE_D3D12
int d3d12_gpu_index;
#endif
} ints;

View File

@ -1,5 +1,6 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2018 - Ali Bouhlel
* Copyright (C) 2016-2019 - Brad Parker
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -24,12 +25,14 @@
#include "d3dcompiler_common.h"
#include "../verbosity.h"
#include "../../configuration.h"
#ifdef HAVE_DYNAMIC
#include <dynamic/dylib.h>
#endif
#include <encodings/utf.h>
#include <lists/string_list.h>
#include <dxgi.h>
#ifdef __MINGW32__
@ -172,35 +175,59 @@ bool d3d12_init_base(d3d12_video_t* d3d12)
{
int i = 0;
settings_t *settings = config_get_ptr();
if (d3d12->gpu_list)
string_list_free(d3d12->gpu_list);
d3d12->gpu_list = string_list_new();
while (true)
{
char str[128];
union string_list_elem_attr attr = {0};
DXGI_ADAPTER_DESC desc = {0};
str[0] = '\0';
#ifdef __WINRT__
if (FAILED(DXGIEnumAdapters2(d3d12->factory, i++, &d3d12->adapter)))
if (FAILED(DXGIEnumAdapters2(d3d12->factory, i, &d3d12->adapter)))
return false;
#else
if (FAILED(DXGIEnumAdapters(d3d12->factory, i++, &d3d12->adapter)))
if (FAILED(DXGIEnumAdapters(d3d12->factory, i, &d3d12->adapter)))
return false;
#endif
if (SUCCEEDED(D3D12CreateDevice_(d3d12->adapter, D3D_FEATURE_LEVEL_11_0, &d3d12->device)))
{
char str[128];
DXGI_ADAPTER_DESC desc = {0};
IDXGIAdapter_GetDesc(d3d12->adapter, &desc);
IDXGIAdapter_GetDesc(d3d12->adapter, &desc);
utf16_to_char_string((const uint16_t*)desc.Description, str, sizeof(str));
utf16_to_char_string((const uint16_t*)desc.Description, str, sizeof(str));
RARCH_LOG("[D3D12]: Found GPU at index %d: %s\n", i, str);
RARCH_LOG("[D3D12]: Using GPU: %s\n", str);
string_list_append(d3d12->gpu_list, str, attr);
video_driver_set_gpu_device_string(str);
if (i < D3D12_MAX_GPU_COUNT)
d3d12->adapters[i] = d3d12->adapter;
break;
}
Release(d3d12->adapter);
i++;
}
video_driver_set_gpu_api_devices(GFX_CTX_DIRECT3D12_API, d3d12->gpu_list);
if (0 <= settings->ints.d3d12_gpu_index && settings->ints.d3d12_gpu_index <= i && settings->ints.d3d12_gpu_index < D3D12_MAX_GPU_COUNT)
{
d3d12->adapter = d3d12->adapters[settings->ints.d3d12_gpu_index];
RARCH_LOG("[D3D12]: Using GPU index %d.\n", settings->ints.d3d12_gpu_index);
video_driver_set_gpu_device_string(d3d12->gpu_list->elems[settings->ints.d3d12_gpu_index].data);
}
else
{
RARCH_WARN("[D3D12]: Invalid GPU index %d, using first device found.\n", settings->ints.d3d12_gpu_index);
d3d12->adapter = d3d12->adapters[0];
}
if (!SUCCEEDED(D3D12CreateDevice_(d3d12->adapter, D3D_FEATURE_LEVEL_11_0, &d3d12->device)))
RARCH_WARN("[D3D12]: Could not create D3D12 device.\n");
}
return true;

View File

@ -1,5 +1,6 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2018 - Ali Bouhlel
* Copyright (C) 2016-2019 - Brad Parker
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -1263,6 +1264,8 @@ D3D12GetGPUDescriptorHandleForHeapStart(D3D12DescriptorHeap descriptor_heap)
#include "../../retroarch.h"
#include "../drivers_shader/slang_process.h"
#define D3D12_MAX_GPU_COUNT 16
typedef struct d3d12_vertex_t
{
float position[2];
@ -1351,6 +1354,9 @@ typedef struct
DXGIAdapter adapter;
D3D12Device device;
IDXGIAdapter1 *adapters[D3D12_MAX_GPU_COUNT];
struct string_list *gpu_list;
struct
{
D3D12CommandQueue handle;

View File

@ -1,5 +1,6 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2016-2017 - Hans-Kristian Arntzen
* Copyright (C) 2016-2019 - Brad Parker
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -1646,7 +1647,7 @@ static bool vulkan_context_init_gpu(gfx_ctx_vulkan_data_t *vk)
vkGetPhysicalDeviceProperties(gpus[i],
&gpu_properties);
RARCH_LOG("[Vulkan]: Found GPU: %s\n", gpu_properties.deviceName);
RARCH_LOG("[Vulkan]: Found GPU at index %d: %s\n", i, gpu_properties.deviceName);
string_list_append(vulkan_gpu_list, gpu_properties.deviceName, attr);
}

View File

@ -1,5 +1,6 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2018 - Ali Bouhlel
* Copyright (C) 2016-2019 - Brad Parker
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -21,6 +22,7 @@
#include <string/stdstring.h>
#include <file/file_path.h>
#include <encodings/utf.h>
#include <lists/string_list.h>
#include <dxgi.h>
#include "../../driver.h"
@ -46,6 +48,12 @@
#error "UWP does not support D3D10"
#endif
#define D3D10_MAX_GPU_COUNT 16
static struct string_list *d3d10_gpu_list = NULL;
static IDXGIAdapter1 *d3d10_adapters[D3D10_MAX_GPU_COUNT] = {NULL};
static IDXGIAdapter1 *d3d10_current_adapter = NULL;
#ifdef HAVE_OVERLAY
static void d3d10_free_overlays(d3d10_video_t* d3d10)
{
@ -577,6 +585,15 @@ static void d3d10_gfx_free(void* data)
Release(d3d10->device);
}
for (i = 0; i < D3D10_MAX_GPU_COUNT; i++)
{
if (d3d10_adapters[i])
{
Release(d3d10_adapters[i]);
d3d10_adapters[i] = NULL;
}
}
#ifdef HAVE_MONITOR
win32_monitor_from_window();
#endif
@ -665,7 +682,7 @@ d3d10_gfx_init(const video_info_t* video,
#endif
if (FAILED(D3D10CreateDeviceAndSwapChain(
NULL, D3D10_DRIVER_TYPE_HARDWARE,
(IDXGIAdapter*)d3d10->adapter, D3D10_DRIVER_TYPE_HARDWARE,
NULL, flags, D3D10_SDK_VERSION, &desc,
(IDXGISwapChain**)&d3d10->swapChain, &d3d10->device)))
goto error;
@ -977,18 +994,25 @@ d3d10_gfx_init(const video_info_t* video,
{
int i = 0;
DXGI_ADAPTER_DESC desc = {0};
char str[128];
str[0] = '\0';
if (d3d10_gpu_list)
string_list_free(d3d10_gpu_list);
d3d10_gpu_list = string_list_new();
while (true)
{
DXGI_ADAPTER_DESC desc = {0};
union string_list_elem_attr attr = {0};
char str[128];
str[0] = '\0';
#ifdef __WINRT__
if (FAILED(DXGIEnumAdapters2(d3d10->factory, i++, &d3d10->adapter)))
if (FAILED(DXGIEnumAdapters2(d3d10->factory, i, &d3d10->adapter)))
break;
#else
if (FAILED(DXGIEnumAdapters(d3d10->factory, i++, &d3d10->adapter)))
if (FAILED(DXGIEnumAdapters(d3d10->factory, i, &d3d10->adapter)))
break;
#endif
@ -997,14 +1021,30 @@ d3d10_gfx_init(const video_info_t* video,
utf16_to_char_string((const uint16_t*)
desc.Description, str, sizeof(str));
RARCH_LOG("[D3D10]: Using GPU: %s\n", str);
RARCH_LOG("[D3D10]: Found GPU at index %d: %s\n", i, str);
video_driver_set_gpu_device_string(str);
string_list_append(d3d10_gpu_list, str, attr);
Release(d3d10->adapter);
if (i < D3D10_MAX_GPU_COUNT)
d3d10_adapters[i] = d3d10->adapter;
/* We only care about the first adapter for now */
break;
i++;
}
video_driver_set_gpu_api_devices(GFX_CTX_DIRECT3D10_API, d3d10_gpu_list);
if (0 <= settings->ints.d3d10_gpu_index && settings->ints.d3d10_gpu_index <= i && settings->ints.d3d10_gpu_index < D3D10_MAX_GPU_COUNT)
{
d3d10_current_adapter = d3d10_adapters[settings->ints.d3d10_gpu_index];
d3d10->adapter = d3d10_current_adapter;
RARCH_LOG("[D3D10]: Using GPU index %d.\n", settings->ints.d3d10_gpu_index);
video_driver_set_gpu_device_string(d3d10_gpu_list->elems[settings->ints.d3d10_gpu_index].data);
}
else
{
RARCH_WARN("[D3D10]: Invalid GPU index %d, using first device found.\n", settings->ints.d3d10_gpu_index);
d3d10_current_adapter = d3d10_adapters[0];
d3d10->adapter = d3d10_current_adapter;
}
}

View File

@ -1,5 +1,6 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2018 - Ali Bouhlel
* Copyright (C) 2016-2019 - Brad Parker
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -23,6 +24,7 @@
#include <retro_miscellaneous.h>
#include <file/file_path.h>
#include <encodings/utf.h>
#include <lists/string_list.h>
#include <dxgi.h>
#ifdef HAVE_MENU
@ -60,6 +62,12 @@ static D3D11Device cached_device_d3d11;
static D3D_FEATURE_LEVEL cached_supportedFeatureLevel;
static D3D11DeviceContext cached_context;
#define D3D11_MAX_GPU_COUNT 16
static struct string_list *d3d11_gpu_list = NULL;
static IDXGIAdapter1 *d3d11_adapters[D3D11_MAX_GPU_COUNT] = {NULL};
static IDXGIAdapter1 *d3d11_current_adapter = NULL;
#ifdef HAVE_OVERLAY
static void d3d11_free_overlays(d3d11_video_t* d3d11)
{
@ -593,6 +601,15 @@ static void d3d11_gfx_free(void* data)
Release(d3d11->device);
}
for (i = 0; i < D3D11_MAX_GPU_COUNT; i++)
{
if (d3d11_adapters[i])
{
Release(d3d11_adapters[i]);
d3d11_adapters[i] = NULL;
}
}
#ifdef HAVE_MONITOR
win32_monitor_from_window();
#endif
@ -713,7 +730,7 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
else
{
if (FAILED(D3D11CreateDevice(
NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags,
(IDXGIAdapter*)d3d11->adapter, D3D_DRIVER_TYPE_HARDWARE, NULL, flags,
requested_feature_levels, number_feature_levels,
D3D11_SDK_VERSION, &d3d11->device,
&d3d11->supportedFeatureLevel, &d3d11->context)))
@ -1051,18 +1068,25 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
{
int i = 0;
DXGI_ADAPTER_DESC desc = {0};
char str[128];
str[0] = '\0';
if (d3d11_gpu_list)
string_list_free(d3d11_gpu_list);
d3d11_gpu_list = string_list_new();
while (true)
{
DXGI_ADAPTER_DESC desc = {0};
char str[128];
union string_list_elem_attr attr = {0};
str[0] = '\0';
#ifdef __WINRT__
if (FAILED(DXGIEnumAdapters2(d3d11->factory, i++, &d3d11->adapter)))
if (FAILED(DXGIEnumAdapters2(d3d11->factory, i, &d3d11->adapter)))
break;
#else
if (FAILED(DXGIEnumAdapters(d3d11->factory, i++, &d3d11->adapter)))
if (FAILED(DXGIEnumAdapters(d3d11->factory, i, &d3d11->adapter)))
break;
#endif
@ -1071,14 +1095,30 @@ d3d11_gfx_init(const video_info_t* video, const input_driver_t** input, void** i
utf16_to_char_string((const uint16_t*)
desc.Description, str, sizeof(str));
RARCH_LOG("[D3D11]: Using GPU: %s\n", str);
RARCH_LOG("[D3D11]: Found GPU at index %d: %s\n", i, str);
video_driver_set_gpu_device_string(str);
string_list_append(d3d11_gpu_list, str, attr);
Release(d3d11->adapter);
if (i < D3D11_MAX_GPU_COUNT)
d3d11_adapters[i] = d3d11->adapter;
/* We only care about the first adapter for now */
break;
i++;
}
video_driver_set_gpu_api_devices(GFX_CTX_DIRECT3D11_API, d3d11_gpu_list);
if (0 <= settings->ints.d3d11_gpu_index && settings->ints.d3d11_gpu_index <= i && settings->ints.d3d11_gpu_index < D3D11_MAX_GPU_COUNT)
{
d3d11_current_adapter = d3d11_adapters[settings->ints.d3d11_gpu_index];
d3d11->adapter = d3d11_current_adapter;
RARCH_LOG("[D3D11]: Using GPU index %d.\n", settings->ints.d3d11_gpu_index);
video_driver_set_gpu_device_string(d3d11_gpu_list->elems[settings->ints.d3d11_gpu_index].data);
}
else
{
RARCH_WARN("[D3D11]: Invalid GPU index %d, using first device found.\n", settings->ints.d3d11_gpu_index);
d3d11_current_adapter = d3d11_adapters[0];
d3d11->adapter = d3d11_current_adapter;
}
}

View File

@ -1,5 +1,6 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2018 - Ali Bouhlel
* Copyright (C) 2016-2019 - Brad Parker
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -871,6 +872,15 @@ static void d3d12_gfx_free(void* data)
Release(d3d12->device);
Release(d3d12->adapter);
for (i = 0; i < D3D12_MAX_GPU_COUNT; i++)
{
if (d3d12->adapters[i])
{
Release(d3d12->adapters[i]);
d3d12->adapters[i] = NULL;
}
}
#ifdef HAVE_MONITOR
win32_monitor_from_window();
#endif

View File

@ -466,6 +466,54 @@ static int action_left_video_gpu_index(unsigned type, const char *label,
break;
}
#endif
#ifdef HAVE_D3D10
case GFX_CTX_DIRECT3D10_API:
{
struct string_list *list = video_driver_get_gpu_api_devices(api);
if (list)
{
if (settings->ints.d3d10_gpu_index > 0)
settings->ints.d3d10_gpu_index--;
else
settings->ints.d3d10_gpu_index = list->size - 1;
}
break;
}
#endif
#ifdef HAVE_D3D11
case GFX_CTX_DIRECT3D11_API:
{
struct string_list *list = video_driver_get_gpu_api_devices(api);
if (list)
{
if (settings->ints.d3d11_gpu_index > 0)
settings->ints.d3d11_gpu_index--;
else
settings->ints.d3d11_gpu_index = list->size - 1;
}
break;
}
#endif
#ifdef HAVE_D3D12
case GFX_CTX_DIRECT3D12_API:
{
struct string_list *list = video_driver_get_gpu_api_devices(api);
if (list)
{
if (settings->ints.d3d12_gpu_index > 0)
settings->ints.d3d12_gpu_index--;
else
settings->ints.d3d12_gpu_index = list->size - 1;
}
break;
}
#endif
default:
break;
}

View File

@ -394,6 +394,54 @@ static int action_right_video_gpu_index(unsigned type, const char *label,
break;
}
#endif
#ifdef HAVE_D3D10
case GFX_CTX_DIRECT3D10_API:
{
struct string_list *list = video_driver_get_gpu_api_devices(api);
if (list)
{
if (settings->ints.d3d10_gpu_index < list->size - 1)
settings->ints.d3d10_gpu_index++;
else if (settings->ints.d3d10_gpu_index == list->size - 1)
settings->ints.d3d10_gpu_index = 0;
}
break;
}
#endif
#ifdef HAVE_D3D11
case GFX_CTX_DIRECT3D11_API:
{
struct string_list *list = video_driver_get_gpu_api_devices(api);
if (list)
{
if (settings->ints.d3d11_gpu_index < list->size - 1)
settings->ints.d3d11_gpu_index++;
else if (settings->ints.d3d11_gpu_index == list->size - 1)
settings->ints.d3d11_gpu_index = 0;
}
break;
}
#endif
#ifdef HAVE_D3D12
case GFX_CTX_DIRECT3D12_API:
{
struct string_list *list = video_driver_get_gpu_api_devices(api);
if (list)
{
if (settings->ints.d3d12_gpu_index < list->size - 1)
settings->ints.d3d12_gpu_index++;
else if (settings->ints.d3d12_gpu_index == list->size - 1)
settings->ints.d3d12_gpu_index = 0;
}
break;
}
#endif
default:
break;
}

View File

@ -8364,6 +8364,66 @@ static bool setting_append_list(
}
#endif
#ifdef HAVE_D3D10
if (string_is_equal(video_driver_get_ident(), "d3d10"))
{
CONFIG_INT(
list, list_info,
&settings->ints.d3d10_gpu_index,
MENU_ENUM_LABEL_VIDEO_GPU_INDEX,
MENU_ENUM_LABEL_VALUE_VIDEO_GPU_INDEX,
0,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
menu_settings_list_current_add_range(list, list_info, 0, 15, 1, true, true);
(*list)[list_info->index - 1].get_string_representation =
&setting_get_string_representation_int_gpu_index;
}
#endif
#ifdef HAVE_D3D11
if (string_is_equal(video_driver_get_ident(), "d3d11"))
{
CONFIG_INT(
list, list_info,
&settings->ints.d3d11_gpu_index,
MENU_ENUM_LABEL_VIDEO_GPU_INDEX,
MENU_ENUM_LABEL_VALUE_VIDEO_GPU_INDEX,
0,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
menu_settings_list_current_add_range(list, list_info, 0, 15, 1, true, true);
(*list)[list_info->index - 1].get_string_representation =
&setting_get_string_representation_int_gpu_index;
}
#endif
#ifdef HAVE_D3D12
if (string_is_equal(video_driver_get_ident(), "d3d12"))
{
CONFIG_INT(
list, list_info,
&settings->ints.d3d12_gpu_index,
MENU_ENUM_LABEL_VIDEO_GPU_INDEX,
MENU_ENUM_LABEL_VALUE_VIDEO_GPU_INDEX,
0,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
menu_settings_list_current_add_range(list, list_info, 0, 15, 1, true, true);
(*list)[list_info->index - 1].get_string_representation =
&setting_get_string_representation_int_gpu_index;
}
#endif
if (video_driver_has_windowed())
{
CONFIG_BOOL(

View File

@ -7390,7 +7390,10 @@ typedef struct {
} gfx_api_gpu_map;
static gfx_api_gpu_map gpu_map[] = {
{ GFX_CTX_VULKAN_API, NULL }
{ GFX_CTX_VULKAN_API, NULL },
{ GFX_CTX_DIRECT3D10_API, NULL },
{ GFX_CTX_DIRECT3D11_API, NULL },
{ GFX_CTX_DIRECT3D12_API, NULL }
};
bool video_driver_started_fullscreen(void)

View File

@ -1,6 +1,7 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2016 - Daniel De Matteis
* Copyright (C) 2016-2019 - Brad Parker
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-