diff --git a/config.def.h b/config.def.h index fd2780e72f..d85035f5e2 100644 --- a/config.def.h +++ b/config.def.h @@ -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) diff --git a/configuration.c b/configuration.c index fb4b73931d..6ee253c670 100644 --- a/configuration.c +++ b/configuration.c @@ -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; diff --git a/configuration.h b/configuration.h index de693f0834..82316b5c92 100644 --- a/configuration.h +++ b/configuration.h @@ -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; diff --git a/gfx/common/d3d12_common.c b/gfx/common/d3d12_common.c index 873d7ad0c9..7008a3fbcf 100644 --- a/gfx/common/d3d12_common.c +++ b/gfx/common/d3d12_common.c @@ -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 #endif #include +#include #include #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; diff --git a/gfx/common/d3d12_common.h b/gfx/common/d3d12_common.h index 707701abf0..ef4a7863fc 100644 --- a/gfx/common/d3d12_common.h +++ b/gfx/common/d3d12_common.h @@ -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; diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index 83ec6ab279..7bad3af2ed 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -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); } diff --git a/gfx/drivers/d3d10.c b/gfx/drivers/d3d10.c index 83984c10a1..6bbc39a15f 100644 --- a/gfx/drivers/d3d10.c +++ b/gfx/drivers/d3d10.c @@ -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 #include #include +#include #include #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; } } diff --git a/gfx/drivers/d3d11.c b/gfx/drivers/d3d11.c index 33d2437c49..724b2d3e62 100644 --- a/gfx/drivers/d3d11.c +++ b/gfx/drivers/d3d11.c @@ -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 #include #include +#include #include #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; } } diff --git a/gfx/drivers/d3d12.c b/gfx/drivers/d3d12.c index f49ccd7eca..c191471be6 100644 --- a/gfx/drivers/d3d12.c +++ b/gfx/drivers/d3d12.c @@ -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 diff --git a/menu/cbs/menu_cbs_left.c b/menu/cbs/menu_cbs_left.c index 3ab6a1fcf3..2a3de08eb1 100644 --- a/menu/cbs/menu_cbs_left.c +++ b/menu/cbs/menu_cbs_left.c @@ -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; } diff --git a/menu/cbs/menu_cbs_right.c b/menu/cbs/menu_cbs_right.c index 709ca06c65..672fd49f19 100644 --- a/menu/cbs/menu_cbs_right.c +++ b/menu/cbs/menu_cbs_right.c @@ -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; } diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 14d8f5c727..23dcae8b3f 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -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( diff --git a/retroarch.c b/retroarch.c index 1ab9abd298..2a65994adb 100644 --- a/retroarch.c +++ b/retroarch.c @@ -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) diff --git a/retroarch.h b/retroarch.h index 07911b79e9..1aae5b5b07 100644 --- a/retroarch.h +++ b/retroarch.h @@ -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-