Win32: Add an UI option to change the GPU backend.

It requires an application restart to work.
This commit is contained in:
The Dax 2014-09-14 06:59:27 -04:00
parent 2b4ff04c32
commit 436f39d3f6
5 changed files with 62 additions and 1 deletions

View File

@ -407,6 +407,8 @@ static ConfigSetting graphicsSettings[] = {
ReportedConfigSetting("FrameRate", &g_Config.iFpsLimit, 0),
#ifdef _WIN32
ConfigSetting("FrameSkipUnthrottle", &g_Config.bFrameSkipUnthrottle, false),
ConfigSetting("TemporaryGPUBackend", &g_Config.iTempGPUBackend, -1, false),
ConfigSetting("RestartRequired", &g_Config.bRestartRequired, false, false),
#else
ConfigSetting("FrameSkipUnthrottle", &g_Config.bFrameSkipUnthrottle, true),
#endif
@ -828,6 +830,10 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
}
CleanRecent();
#ifdef _WIN32
iTempGPUBackend = iGPUBackend;
#endif
}
void Config::Save() {

View File

@ -82,6 +82,12 @@ public:
bool bTopMost;
std::string sFont;
bool bIgnoreWindowsKey;
// Used for switching the GPU backend in GameSettingsScreen.
// Without this, PPSSPP instantly crashes if we edit iGPUBackend directly...
int iTempGPUBackend;
bool bRestartRequired;
#endif
bool bPauseWhenMinimized;

View File

@ -49,6 +49,10 @@
#include "GPU/GPUInterface.h"
#include "GPU/GLES/Framebuffer.h"
#if defined(_WIN32)
#include "Windows/WndMainWindow.h"
#endif
#ifdef IOS
extern bool iosCanUseJit;
#endif
@ -112,6 +116,11 @@ void GameSettingsScreen::CreateViews() {
tabHolder->AddTab(ms->T("Graphics"), graphicsSettingsScroll);
graphicsSettings->Add(new ItemHeader(gs->T("Rendering Mode")));
#if defined(_WIN32)
static const char *renderingBackend[] = { "OpenGL", "DirectX" };
PopupMultiChoice *renderingBackendChoice = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iTempGPUBackend, gs->T("Backend"), renderingBackend, GPU_BACKEND_OPENGL, ARRAY_SIZE(renderingBackend), gs, screenManager()));
renderingBackendChoice->OnChoice.Handle(this, &GameSettingsScreen::OnRenderingBackend);
#endif
static const char *renderingMode[] = { "Non-Buffered Rendering", "Buffered Rendering", "Read Framebuffers To Memory (CPU)", "Read Framebuffers To Memory (GPU)"};
PopupMultiChoice *renderingModeChoice = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iRenderingMode, gs->T("Mode"), renderingMode, 0, ARRAY_SIZE(renderingMode), gs, screenManager()));
renderingModeChoice->OnChoice.Handle(this, &GameSettingsScreen::OnRenderingMode);
@ -603,6 +612,32 @@ void GlobalSettingsScreen::CreateViews() {
enableReports_ = Reporting::IsEnabled();
}*/
void GameSettingsScreen::CallbackRenderingBackend(bool yes) {
#if defined(_WIN32)
// If the user ends up deciding not to restart, set the temporary variable back to the current backend
// so it doesn't get switched by accident.
if (yes) {
g_Config.bRestartRequired = true;
PostMessage(MainWindow::GetHWND(), WM_CLOSE, 0, 0);
} else {
g_Config.iTempGPUBackend = g_Config.iGPUBackend;
}
#endif
}
UI::EventReturn GameSettingsScreen::OnRenderingBackend(UI::EventParams &e) {
#if defined(_WIN32)
I18NCategory *d = GetI18NCategory("Dialog");
// It only makes sense to show the restart prompt if the backend was actually changed.
if (g_Config.iTempGPUBackend != g_Config.iGPUBackend) {
screenManager()->push(new PromptScreen(d->T("ChangingGPUBackends", "Changing GPU backends requires PPSSPP to restart. Restart now?"), d->T("Yes"), d->T("No"),
std::bind(&GameSettingsScreen::CallbackRenderingBackend, this, placeholder::_1)));
}
#endif
return UI::EVENT_DONE;
}
UI::EventReturn GameSettingsScreen::OnChangeNickname(UI::EventParams &e) {
#if defined(_WIN32) || defined(USING_QT_UI)
const size_t name_len = 256;

View File

@ -35,7 +35,7 @@ protected:
virtual void CreateViews();
virtual void sendMessage(const char *message, const char *value);
void CallbackRestoreDefaults(bool yes);
void CallbackRenderingBackend(bool yes);
bool UseVerticalLayout() const;
private:
@ -75,6 +75,7 @@ private:
UI::EventReturn OnShaderChange(UI::EventParams &e);
UI::EventReturn OnRestoreDefaultSettings(UI::EventParams &e);
UI::EventReturn OnRenderingMode(UI::EventParams &e);
UI::EventReturn OnRenderingBackend(UI::EventParams &e);
UI::EventReturn OnJitAffectingSetting(UI::EventParams &e);
UI::EventReturn OnSoftwareRendering(UI::EventParams &e);
UI::EventReturn OnHardwareTransform(UI::EventParams &e);

View File

@ -588,7 +588,20 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
DialogManager::DestroyAll();
timeEndPeriod(1);
delete host;
// Is there a safer place to do this?
// Doing this in Config::Save requires knowing if the UI state is UISTATE_EXIT,
// but that causes UnitTest to fail linking with 400 errors if System.h is included..
if (g_Config.iTempGPUBackend != g_Config.iGPUBackend)
g_Config.iGPUBackend = g_Config.iTempGPUBackend;
g_Config.Save();
LogManager::Shutdown();
if (g_Config.bRestartRequired) {
wchar_t moduleFilename[MAX_PATH];
GetModuleFileName(GetModuleHandle(NULL), moduleFilename, MAX_PATH);
ShellExecute(NULL, NULL, moduleFilename, NULL, NULL, SW_SHOW);
}
return 0;
}