diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 0daa204e1..0caf5e31c 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -894,9 +894,11 @@ const char* Settings::GetCPUFastmemModeDisplayName(CPUFastmemMode mode) return Host::TranslateToCString("CPUFastmemMode", s_cpu_fastmem_mode_display_names[static_cast(mode)]); } -static constexpr auto s_gpu_renderer_names = make_array( +static constexpr std::array(GPURenderer::Count)> s_gpu_renderer_names = {{ + "Automatic", #ifdef _WIN32 - "D3D11", "D3D12", + "D3D11", + "D3D12", #endif #ifdef __APPLE__ "Metal", @@ -907,10 +909,13 @@ static constexpr auto s_gpu_renderer_names = make_array( #ifdef ENABLE_OPENGL "OpenGL", #endif - "Software"); -static constexpr auto s_gpu_renderer_display_names = make_array( + "Software", +}}; +static constexpr std::array(GPURenderer::Count)> s_gpu_renderer_display_names = {{ + TRANSLATE_NOOP("GPURenderer", "Automatic"), #ifdef _WIN32 - TRANSLATE_NOOP("GPURenderer", "Hardware (D3D11)"), TRANSLATE_NOOP("GPURenderer", "Hardware (D3D12)"), + TRANSLATE_NOOP("GPURenderer", "Hardware (D3D11)"), + TRANSLATE_NOOP("GPURenderer", "Hardware (D3D12)"), #endif #ifdef __APPLE__ TRANSLATE_NOOP("GPURenderer", "Hardware (Metal)"), @@ -921,7 +926,8 @@ static constexpr auto s_gpu_renderer_display_names = make_array( #ifdef ENABLE_OPENGL TRANSLATE_NOOP("GPURenderer", "Hardware (OpenGL)"), #endif - TRANSLATE_NOOP("GPURenderer", "Software")); + TRANSLATE_NOOP("GPURenderer", "Software"), +}}; std::optional Settings::ParseRendererName(const char* str) { @@ -969,6 +975,7 @@ RenderAPI Settings::GetRenderAPIForRenderer(GPURenderer renderer) return RenderAPI::OpenGL; #endif case GPURenderer::Software: + case GPURenderer::Automatic: default: return GPUDevice::GetPreferredAPI(); } diff --git a/src/core/settings.h b/src/core/settings.h index 6c55a3c85..35e3665df 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -412,19 +412,7 @@ struct Settings static const char* GetMultitapModeDisplayName(MultitapMode mode); // Default to D3D11 on Windows as it's more performant and at this point, less buggy. -#if defined(_WIN32) && defined(_M_ARM64) - static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::HardwareD3D12; -#elif defined(_WIN32) - static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::HardwareD3D11; -#elif defined(__APPLE__) - static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::HardwareMetal; -#elif defined(ENABLE_OPENGL) - static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::HardwareOpenGL; -#elif defined(ENABLE_VULKAN) - static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::HardwareVulkan; -#else - static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::Software; -#endif + static constexpr GPURenderer DEFAULT_GPU_RENDERER = GPURenderer::Automatic; static constexpr GPUTextureFilter DEFAULT_GPU_TEXTURE_FILTER = GPUTextureFilter::Nearest; static constexpr GPUDownsampleMode DEFAULT_GPU_DOWNSAMPLE_MODE = GPUDownsampleMode::Disabled; static constexpr GPUWireframeMode DEFAULT_GPU_WIREFRAME_MODE = GPUWireframeMode::Disabled; diff --git a/src/core/types.h b/src/core/types.h index 117843f03..1732263b4 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -58,6 +58,7 @@ enum class PGXPMode : u8 enum class GPURenderer : u8 { + Automatic, #ifdef _WIN32 HardwareD3D11, HardwareD3D12, diff --git a/src/util/gpu_device.cpp b/src/util/gpu_device.cpp index d14abb1e3..cf86d132f 100644 --- a/src/util/gpu_device.cpp +++ b/src/util/gpu_device.cpp @@ -176,10 +176,24 @@ GPUDevice::~GPUDevice() = default; RenderAPI GPUDevice::GetPreferredAPI() { -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_M_ARM64) + // Perfer DX11 on Windows, except ARM64, where QCom has slow DX11 drivers. return RenderAPI::D3D11; -#else +#elif defined(_WIN32) && defined(_M_ARM64) + return RenderAPI::D3D12; +#elif defined(__APPLE__) + // Prefer Metal on MacOS. return RenderAPI::Metal; +#elif defined(ENABLE_OPENGL) && defined(ENABLE_VULKAN) + // On Linux, if we have both GL and Vulkan, prefer VK if the driver isn't software. + return VulkanDevice::IsSuitableDefaultRenderer() ? RenderAPI::Vulkan : RenderAPI::OpenGL; +#elif defined(ENABLE_OPENGL) + return RenderAPI::OpenGL; +#elif defined(ENABLE_VULKAN) + return RenderAPI::Vulkan; +#else + // Uhhh, what? + return RenderAPI::None; #endif }