mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Merge pull request #12118 from unknownbrackets/gpu-config
Add a hidden ini setting to disable graphics backends
This commit is contained in:
commit
068ec3059b
119
Core/Config.cpp
119
Core/Config.cpp
@ -120,6 +120,13 @@ struct ConfigSetting {
|
||||
default_.i = def;
|
||||
}
|
||||
|
||||
ConfigSetting(const char *ini, int *v, int def, std::function<std::string(int)> transTo, std::function<int(const std::string &)> transFrom, bool save = true, bool perGame = false)
|
||||
: ini_(ini), type_(TYPE_INT), report_(false), save_(save), perGame_(perGame), translateTo_(transTo), translateFrom_(transFrom) {
|
||||
ptr_.i = v;
|
||||
cb_.i = nullptr;
|
||||
default_.i = def;
|
||||
}
|
||||
|
||||
ConfigSetting(const char *ini, uint32_t *v, uint32_t def, bool save = true, bool perGame = false)
|
||||
: ini_(ini), type_(TYPE_UINT32), report_(false), save_(save), perGame_(perGame) {
|
||||
ptr_.u = v;
|
||||
@ -160,6 +167,12 @@ struct ConfigSetting {
|
||||
cb_.i = def;
|
||||
}
|
||||
|
||||
ConfigSetting(const char *ini, int *v, IntDefaultCallback def, std::function<std::string(int)> transTo, std::function<int(const std::string &)> transFrom, bool save = true, bool perGame = false)
|
||||
: ini_(ini), type_(TYPE_INT), report_(false), save_(save), perGame_(perGame), translateTo_(transTo), translateFrom_(transFrom) {
|
||||
ptr_.i = v;
|
||||
cb_.i = def;
|
||||
}
|
||||
|
||||
ConfigSetting(const char *ini, uint32_t *v, Uint32DefaultCallback def, bool save = true, bool perGame = false)
|
||||
: ini_(ini), type_(TYPE_UINT32), report_(false), save_(save), perGame_(perGame) {
|
||||
ptr_ .u = v;
|
||||
@ -199,6 +212,13 @@ struct ConfigSetting {
|
||||
if (cb_.i) {
|
||||
default_.i = cb_.i();
|
||||
}
|
||||
if (translateFrom_) {
|
||||
std::string value;
|
||||
if (section->Get(ini_, &value, nullptr)) {
|
||||
*ptr_.i = translateFrom_(value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return section->Get(ini_, ptr_.i, default_.i);
|
||||
case TYPE_UINT32:
|
||||
if (cb_.u) {
|
||||
@ -242,6 +262,10 @@ struct ConfigSetting {
|
||||
case TYPE_BOOL:
|
||||
return section->Set(ini_, *ptr_.b);
|
||||
case TYPE_INT:
|
||||
if (translateTo_) {
|
||||
std::string value = translateTo_(*ptr_.i);
|
||||
return section->Set(ini_, value);
|
||||
}
|
||||
return section->Set(ini_, *ptr_.i);
|
||||
case TYPE_UINT32:
|
||||
return section->Set(ini_, *ptr_.u);
|
||||
@ -298,6 +322,10 @@ struct ConfigSetting {
|
||||
SettingPtr ptr_;
|
||||
Value default_;
|
||||
Callback cb_;
|
||||
|
||||
// We only support transform for ints.
|
||||
std::function<std::string(int)> translateTo_;
|
||||
std::function<int(const std::string &)> translateFrom_;
|
||||
};
|
||||
|
||||
struct ReportedConfigSetting : public ConfigSetting {
|
||||
@ -306,6 +334,12 @@ struct ReportedConfigSetting : public ConfigSetting {
|
||||
: ConfigSetting(ini, v, def, save, perGame) {
|
||||
report_ = true;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
ReportedConfigSetting(const char *ini, T1 *v, T2 def, std::function<std::string(int)> transTo, std::function<int(const std::string &)> transFrom, bool save = true, bool perGame = false)
|
||||
: ConfigSetting(ini, v, def, transTo, transFrom, save, perGame) {
|
||||
report_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
const char *DefaultLangRegion() {
|
||||
@ -546,34 +580,43 @@ static int DefaultGPUBackend() {
|
||||
|
||||
int Config::NextValidBackend() {
|
||||
std::vector<std::string> split;
|
||||
std::set<int> failed;
|
||||
std::set<GPUBackend> failed;
|
||||
|
||||
SplitString(sFailedGPUBackends, ',', split);
|
||||
for (const auto &str : split) {
|
||||
if (!str.empty() && str != "ALL") {
|
||||
failed.insert(atoi(str.c_str()));
|
||||
failed.insert(GPUBackendFromString(str));
|
||||
}
|
||||
}
|
||||
|
||||
if (failed.count(iGPUBackend)) {
|
||||
// Count these as "failed" too so we don't pick them.
|
||||
SplitString(sDisabledGPUBackends, ',', split);
|
||||
for (const auto &str : split) {
|
||||
if (!str.empty()) {
|
||||
failed.insert(GPUBackendFromString(str));
|
||||
}
|
||||
}
|
||||
|
||||
if (failed.count((GPUBackend)iGPUBackend)) {
|
||||
ERROR_LOG(LOADER, "Graphics backend failed for %d, trying another", iGPUBackend);
|
||||
|
||||
#if (PPSSPP_PLATFORM(WINDOWS) || PPSSPP_PLATFORM(ANDROID)) && !PPSSPP_PLATFORM(UWP)
|
||||
if (VulkanMayBeAvailable() && !failed.count((int)GPUBackend::VULKAN)) {
|
||||
if (!failed.count(GPUBackend::VULKAN) && VulkanMayBeAvailable()) {
|
||||
return (int)GPUBackend::VULKAN;
|
||||
}
|
||||
#endif
|
||||
#if PPSSPP_PLATFORM(WINDOWS)
|
||||
if (DoesVersionMatchWindows(6, 1, 0, 0, true) && !failed.count((int)GPUBackend::DIRECT3D11)) {
|
||||
if (!failed.count(GPUBackend::DIRECT3D11) && DoesVersionMatchWindows(6, 1, 0, 0, true)) {
|
||||
return (int)GPUBackend::DIRECT3D11;
|
||||
}
|
||||
#endif
|
||||
#if PPSSPP_API(ANY_GL)
|
||||
if (!failed.count((int)GPUBackend::OPENGL)) {
|
||||
if (!failed.count(GPUBackend::OPENGL)) {
|
||||
return (int)GPUBackend::OPENGL;
|
||||
}
|
||||
#endif
|
||||
#if PPSSPP_API(D3D9)
|
||||
if (!failed.count((int)GPUBackend::DIRECT3D9)) {
|
||||
if (!failed.count(GPUBackend::DIRECT3D9)) {
|
||||
return (int)GPUBackend::DIRECT3D9;
|
||||
}
|
||||
#endif
|
||||
@ -587,18 +630,78 @@ int Config::NextValidBackend() {
|
||||
return iGPUBackend;
|
||||
}
|
||||
|
||||
bool Config::IsBackendEnabled(GPUBackend backend, bool validate) {
|
||||
std::vector<std::string> split;
|
||||
|
||||
SplitString(sDisabledGPUBackends, ',', split);
|
||||
for (const auto &str : split) {
|
||||
if (str.empty())
|
||||
continue;
|
||||
auto match = GPUBackendFromString(str);
|
||||
if (match == backend)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if PPSSPP_PLATFORM(IOS)
|
||||
if (backend != GPUBackend::OPENGL)
|
||||
return false;
|
||||
#elif PPSSPP_PLATFORM(UWP)
|
||||
if (backend != GPUBackend::DIRECT3D11)
|
||||
return false;
|
||||
#elif PPSSPP_PLATFORM(WINDOWS)
|
||||
if (validate) {
|
||||
if (backend == GPUBackend::DIRECT3D11 && !DoesVersionMatchWindows(6, 0, 0, 0, true))
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (backend == GPUBackend::DIRECT3D11 || backend == GPUBackend::DIRECT3D9)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
#if !PPSSPP_API(ANY_GL)
|
||||
if (backend == GPUBackend::OPENGL)
|
||||
return false;
|
||||
#endif
|
||||
#if !PPSSPP_PLATFORM(IOS)
|
||||
if (validate) {
|
||||
if (backend == GPUBackend::VULKAN && !VulkanMayBeAvailable())
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool DefaultVertexCache() {
|
||||
return DefaultGPUBackend() == (int)GPUBackend::OPENGL;
|
||||
}
|
||||
|
||||
template <typename T, std::string (*FTo)(T), T (*FFrom)(const std::string &)>
|
||||
struct ConfigTranslator {
|
||||
static std::string To(int v) {
|
||||
return StringFromInt(v) + " (" + FTo(T(v)) + ")";
|
||||
}
|
||||
|
||||
static int From(const std::string &v) {
|
||||
int result;
|
||||
if (TryParse(v, &result)) {
|
||||
return result;
|
||||
}
|
||||
return (int)FFrom(v);
|
||||
}
|
||||
};
|
||||
|
||||
typedef ConfigTranslator<GPUBackend, GPUBackendToString, GPUBackendFromString> GPUBackendTranslator;
|
||||
|
||||
static ConfigSetting graphicsSettings[] = {
|
||||
ConfigSetting("EnableCardboard", &g_Config.bEnableCardboard, false, true, true),
|
||||
ConfigSetting("CardboardScreenSize", &g_Config.iCardboardScreenSize, 50, true, true),
|
||||
ConfigSetting("CardboardXShift", &g_Config.iCardboardXShift, 0, true, true),
|
||||
ConfigSetting("CardboardYShift", &g_Config.iCardboardXShift, 0, true, true),
|
||||
ConfigSetting("ShowFPSCounter", &g_Config.iShowFPSCounter, 0, true, true),
|
||||
ReportedConfigSetting("GraphicsBackend", &g_Config.iGPUBackend, &DefaultGPUBackend),
|
||||
ReportedConfigSetting("GraphicsBackend", &g_Config.iGPUBackend, &DefaultGPUBackend, &GPUBackendTranslator::To, &GPUBackendTranslator::From, true, false),
|
||||
ConfigSetting("FailedGraphicsBackends", &g_Config.sFailedGPUBackends, ""),
|
||||
ConfigSetting("DisabledGraphicsBackends", &g_Config.sDisabledGPUBackends, ""),
|
||||
ConfigSetting("VulkanDevice", &g_Config.sVulkanDevice, "", true, false),
|
||||
#ifdef _WIN32
|
||||
ConfigSetting("D3D11Device", &g_Config.sD3D11Device, "", true, false),
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "ppsspp_config.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/ConfigValues.h"
|
||||
|
||||
extern const char *PPSSPP_GIT_VERSION;
|
||||
|
||||
@ -124,6 +125,7 @@ public:
|
||||
// GFX
|
||||
int iGPUBackend;
|
||||
std::string sFailedGPUBackends;
|
||||
std::string sDisabledGPUBackends;
|
||||
// We have separate device parameters for each backend so it doesn't get erased if you switch backends.
|
||||
// If not set, will use the "best" device.
|
||||
std::string sVulkanDevice;
|
||||
@ -441,6 +443,7 @@ public:
|
||||
|
||||
bool IsPortrait() const;
|
||||
int NextValidBackend();
|
||||
bool IsBackendEnabled(GPUBackend backend, bool validate = true);
|
||||
|
||||
protected:
|
||||
void LoadStandardControllerIni();
|
||||
|
@ -18,6 +18,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#ifndef _MSC_VER
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include "Common/CommonFuncs.h"
|
||||
|
||||
const int PSP_MODEL_FAT = 0;
|
||||
const int PSP_MODEL_SLIM = 1;
|
||||
@ -53,6 +58,33 @@ enum class GPUBackend {
|
||||
VULKAN = 3,
|
||||
};
|
||||
|
||||
inline std::string GPUBackendToString(GPUBackend backend) {
|
||||
switch (backend) {
|
||||
case GPUBackend::OPENGL:
|
||||
return "OPENGL";
|
||||
case GPUBackend::DIRECT3D9:
|
||||
return "DIRECT3D9";
|
||||
case GPUBackend::DIRECT3D11:
|
||||
return "DIRECT3D11";
|
||||
case GPUBackend::VULKAN:
|
||||
return "VULKAN";
|
||||
}
|
||||
// Intentionally not a default so we get a warning.
|
||||
return "INVALID";
|
||||
}
|
||||
|
||||
inline GPUBackend GPUBackendFromString(const std::string &backend) {
|
||||
if (!strcasecmp(backend.c_str(), "OPENGL") || backend == "0")
|
||||
return GPUBackend::OPENGL;
|
||||
if (!strcasecmp(backend.c_str(), "DIRECT3D9") || backend == "1")
|
||||
return GPUBackend::DIRECT3D9;
|
||||
if (!strcasecmp(backend.c_str(), "DIRECT3D11") || backend == "2")
|
||||
return GPUBackend::DIRECT3D11;
|
||||
if (!strcasecmp(backend.c_str(), "VULKAN") || backend == "3")
|
||||
return GPUBackend::VULKAN;
|
||||
return GPUBackend::OPENGL;
|
||||
}
|
||||
|
||||
enum AudioBackendType {
|
||||
AUDIO_BACKEND_AUTO,
|
||||
AUDIO_BACKEND_DSOUND,
|
||||
|
@ -822,7 +822,7 @@ void NotifyDisplay(u32 framebuf, int stride, int fmt) {
|
||||
int linesize, pixelFormat;
|
||||
};
|
||||
|
||||
DisplayBufData disp{ framebuf, stride, fmt };
|
||||
DisplayBufData disp{ { framebuf }, stride, fmt };
|
||||
|
||||
FlushRegisters();
|
||||
u32 ptr = (u32)pushbuf.size();
|
||||
|
@ -68,8 +68,6 @@
|
||||
#include "Windows/W32Util/ShellUtil.h"
|
||||
#endif
|
||||
|
||||
extern bool VulkanMayBeAvailable();
|
||||
|
||||
GameSettingsScreen::GameSettingsScreen(std::string gamePath, std::string gameID, bool editThenRestore)
|
||||
: UIDialogScreenWithGameBackground(gamePath), gameID_(gameID), enableReports_(false), editThenRestore_(editThenRestore) {
|
||||
lastVertical_ = UseVerticalLayout();
|
||||
@ -199,26 +197,17 @@ void GameSettingsScreen::CreateViews() {
|
||||
static const char *renderingBackend[] = { "OpenGL", "Direct3D 9", "Direct3D 11", "Vulkan" };
|
||||
PopupMultiChoice *renderingBackendChoice = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iGPUBackend, gr->T("Backend"), renderingBackend, (int)GPUBackend::OPENGL, ARRAY_SIZE(renderingBackend), gr->GetName(), screenManager()));
|
||||
renderingBackendChoice->OnChoice.Handle(this, &GameSettingsScreen::OnRenderingBackend);
|
||||
#if !PPSSPP_PLATFORM(WINDOWS)
|
||||
renderingBackendChoice->HideChoice(1); // D3D9
|
||||
renderingBackendChoice->HideChoice(2); // D3D11
|
||||
#else
|
||||
#if !PPSSPP_API(ANY_GL)
|
||||
renderingBackendChoice->HideChoice(0); // OpenGL
|
||||
#endif
|
||||
if (!DoesVersionMatchWindows(6, 0, 0, 0, true)) {
|
||||
// Hide the D3D11 choice if Windows version is older than Windows Vista.
|
||||
renderingBackendChoice->HideChoice(2); // D3D11
|
||||
}
|
||||
#endif
|
||||
bool vulkanAvailable = false;
|
||||
#ifndef IOS
|
||||
vulkanAvailable = VulkanMayBeAvailable();
|
||||
#endif
|
||||
if (!vulkanAvailable) {
|
||||
renderingBackendChoice->HideChoice(3);
|
||||
}
|
||||
|
||||
if (!g_Config.IsBackendEnabled(GPUBackend::OPENGL))
|
||||
renderingBackendChoice->HideChoice((int)GPUBackend::OPENGL);
|
||||
if (!g_Config.IsBackendEnabled(GPUBackend::DIRECT3D9))
|
||||
renderingBackendChoice->HideChoice((int)GPUBackend::DIRECT3D9);
|
||||
if (!g_Config.IsBackendEnabled(GPUBackend::DIRECT3D11))
|
||||
renderingBackendChoice->HideChoice((int)GPUBackend::DIRECT3D11);
|
||||
if (!g_Config.IsBackendEnabled(GPUBackend::VULKAN))
|
||||
renderingBackendChoice->HideChoice((int)GPUBackend::VULKAN);
|
||||
#endif
|
||||
|
||||
Draw::DrawContext *draw = screenManager()->getDrawContext();
|
||||
|
||||
// Backends that don't allow a device choice will only expose one device.
|
||||
|
@ -392,9 +392,9 @@ static void CheckFailedGPUBackends() {
|
||||
WARN_LOG(LOADER, "Failed graphics backend switched from %d to %d", lastBackend, g_Config.iGPUBackend);
|
||||
// And then let's - for now - add the current to the failed list.
|
||||
if (g_Config.sFailedGPUBackends.empty()) {
|
||||
g_Config.sFailedGPUBackends = StringFromFormat("%d", g_Config.iGPUBackend);
|
||||
g_Config.sFailedGPUBackends = GPUBackendToString((GPUBackend)g_Config.iGPUBackend);
|
||||
} else if (g_Config.sFailedGPUBackends.find("ALL") == std::string::npos) {
|
||||
g_Config.sFailedGPUBackends += StringFromFormat(",%d", g_Config.iGPUBackend);
|
||||
g_Config.sFailedGPUBackends += "," + GPUBackendToString((GPUBackend)g_Config.iGPUBackend);
|
||||
}
|
||||
|
||||
if (System_GetPropertyBool(SYSPROP_SUPPORTS_PERMISSIONS)) {
|
||||
|
@ -1290,14 +1290,11 @@ namespace MainWindow {
|
||||
CheckMenuItem(menu, savestateSlot[i], MF_BYCOMMAND | ((i == g_Config.iCurrentStateSlot) ? MF_CHECKED : MF_UNCHECKED));
|
||||
}
|
||||
|
||||
bool allowD3D11 = DoesVersionMatchWindows(6, 0, 0, 0, true);
|
||||
bool allowVulkan = VulkanMayBeAvailable();
|
||||
bool allowD3D9 = g_Config.IsBackendEnabled(GPUBackend::DIRECT3D9);
|
||||
bool allowD3D11 = g_Config.IsBackendEnabled(GPUBackend::DIRECT3D11);
|
||||
bool allowOpenGL = g_Config.IsBackendEnabled(GPUBackend::OPENGL);
|
||||
bool allowVulkan = g_Config.IsBackendEnabled(GPUBackend::VULKAN);
|
||||
|
||||
#if PPSSPP_API(ANY_GL)
|
||||
bool allowOpenGL = true;
|
||||
#else
|
||||
bool allowOpenGL = false;
|
||||
#endif
|
||||
switch (GetGPUBackend()) {
|
||||
case GPUBackend::DIRECT3D9:
|
||||
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_GRAYED);
|
||||
@ -1310,7 +1307,7 @@ namespace MainWindow {
|
||||
CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_UNCHECKED);
|
||||
break;
|
||||
case GPUBackend::OPENGL:
|
||||
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_ENABLED);
|
||||
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, allowD3D9 ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(menu, ID_OPTIONS_OPENGL, MF_GRAYED);
|
||||
EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED);
|
||||
@ -1320,7 +1317,7 @@ namespace MainWindow {
|
||||
CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_UNCHECKED);
|
||||
break;
|
||||
case GPUBackend::VULKAN:
|
||||
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_ENABLED);
|
||||
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, allowD3D9 ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, allowD3D11 ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(menu, ID_OPTIONS_OPENGL, allowOpenGL ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(menu, ID_OPTIONS_VULKAN, MF_GRAYED);
|
||||
@ -1330,7 +1327,7 @@ namespace MainWindow {
|
||||
CheckMenuItem(menu, ID_OPTIONS_VULKAN, MF_CHECKED);
|
||||
break;
|
||||
case GPUBackend::DIRECT3D11:
|
||||
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, MF_ENABLED);
|
||||
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D9, allowD3D9 ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(menu, ID_OPTIONS_DIRECT3D11, MF_GRAYED);
|
||||
EnableMenuItem(menu, ID_OPTIONS_OPENGL, allowOpenGL ? MF_ENABLED : MF_GRAYED);
|
||||
EnableMenuItem(menu, ID_OPTIONS_VULKAN, allowVulkan ? MF_ENABLED : MF_GRAYED);
|
||||
|
@ -572,7 +572,9 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
|
||||
|
||||
#ifndef _DEBUG
|
||||
// See #11719 - too many Vulkan drivers crash on basic init.
|
||||
VulkanSetAvailable(DetectVulkanInExternalProcess());
|
||||
if (g_Config.IsBackendEnabled(GPUBackend::VULKAN)) {
|
||||
VulkanSetAvailable(DetectVulkanInExternalProcess());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (iCmdShow == SW_MAXIMIZE) {
|
||||
|
Loading…
Reference in New Issue
Block a user