diff --git a/pcsx2/GS/GSUtil.cpp b/pcsx2/GS/GSUtil.cpp index 4007672574..576a21cc00 100644 --- a/pcsx2/GS/GSUtil.cpp +++ b/pcsx2/GS/GSUtil.cpp @@ -14,18 +14,22 @@ */ #include "PrecompiledHeader.h" -#include "GS.h" -#include "GSExtra.h" -#include "GSUtil.h" +#include "GS/GS.h" +#include "GS/GSExtra.h" +#include "GS/GSUtil.h" #include "MultiISA.h" #include "common/StringUtil.h" +#ifdef ENABLE_VULKAN +#include "GS/Renderers/Vulkan/GSDeviceVK.h" +#endif + #ifdef _WIN32 #include "common/RedtapeWindows.h" #include #include #include -#include "Renderers/DX11/D3D.h" +#include "GS/Renderers/DX11/D3D.h" #include #endif @@ -206,7 +210,13 @@ GSRendererType GSUtil::GetPreferredRenderer() // Use D3D device info to select renderer. return D3D::GetPreferredRenderer(); #else - // Linux: Prefer GL/Vulkan, whatever is available. + // Linux: Prefer Vulkan if the driver isn't buggy. +#if defined(ENABLE_VULKAN) + if (GSDeviceVK::IsSuitableDefaultRenderer()) + return GSRendererType::VK; +#endif + + // Otherwise, whatever is available. #if defined(ENABLE_OPENGL) return GSRendererType::OGL; #elif defined(ENABLE_VULKAN) diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp index a1cf61a0eb..4c36f198a4 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp @@ -127,6 +127,40 @@ void GSDeviceVK::GetAdaptersAndFullscreenModes( } } +bool GSDeviceVK::IsSuitableDefaultRenderer() +{ + std::vector adapters; + GetAdaptersAndFullscreenModes(&adapters, nullptr); + if (adapters.empty()) + { + // No adapters, not gonna be able to use VK. + return false; + } + + // Check the first GPU, should be enough. + const std::string& name = adapters.front(); + Console.WriteLn(fmt::format("Using Vulkan GPU '{}' for automatic renderer check.", name)); + + // Any software rendering (LLVMpipe, SwiftShader). + if (StringUtil::StartsWithNoCase(name, "llvmpipe") || + StringUtil::StartsWithNoCase(name, "SwiftShader")) + { + Console.WriteLn(Color_StrongOrange, "Not using Vulkan for software renderer."); + return false; + } + + // For Intel, OpenGL usually ends up faster on Linux, because of fbfetch. + // Plus, the Ivy Bridge and Haswell drivers are incomplete. + if (StringUtil::StartsWithNoCase(name, "Intel")) + { + Console.WriteLn(Color_StrongOrange, "Not using Vulkan for Intel GPU."); + return false; + } + + Console.WriteLn(Color_StrongGreen, "Allowing Vulkan as default renderer."); + return true; +} + RenderAPI GSDeviceVK::GetRenderAPI() const { return RenderAPI::Vulkan; diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.h b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.h index 0c75d99a0a..16344c6786 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.h +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.h @@ -217,6 +217,9 @@ public: static void GetAdaptersAndFullscreenModes(std::vector* adapters, std::vector* fullscreen_modes); + /// Returns true if Vulkan is suitable as a default for the devices in the system. + static bool IsSuitableDefaultRenderer(); + __fi VkRenderPass GetTFXRenderPass(bool rt, bool ds, bool hdr, DATE_RENDER_PASS date, bool fbl, bool dsp, VkAttachmentLoadOp rt_op, VkAttachmentLoadOp ds_op) const {