diff --git a/Core/CmdLine.cpp b/Core/CmdLine.cpp index b4bfe8abf0..52f76eac8c 100644 --- a/Core/CmdLine.cpp +++ b/Core/CmdLine.cpp @@ -262,23 +262,32 @@ CommandLineParseResult CommandLineOptions::Parse(int argc, const char *argv[]) { return CommandLineParseResult::Exit; // Commands with parameters. TODO: Should support both space and equals, like --config=foo.ini and --config foo.ini } else if (startsWith(argv[i], gpuBackendStr)) { - const std::string_view restOfOption = argv[i] + gpuBackendStr.size(); + const std::string restOfOption = argv[i] + gpuBackendStr.size(); // Force software rendering off, as picking gles implies HW acceleration. // We could add more options for software such as "software-gles", // "software-vulkan" and "software-d3d11", or something similar. // For now, software rendering force-activates OpenGL. + double glVersionTemp = 0.0f; if (restOfOption == "directx11" || restOfOption == "d3d11") { gpuBackend = GPUBackend::DIRECT3D11; softwareRendering = false; - } else if (restOfOption == "gles") { - gpuBackend = GPUBackend::OPENGL; - softwareRendering = false; } else if (restOfOption == "vulkan") { gpuBackend = GPUBackend::VULKAN; softwareRendering = false; } else if (restOfOption == "software") { gpuBackend = GPUBackend::OPENGL; softwareRendering = true; + } else if (sscanf(restOfOption.c_str(), "gles%lg", &glVersionTemp) == 1 || sscanf(restOfOption.c_str(), "opengl%lg", &glVersionTemp) == 1) { + g_Config.iGPUBackend = (int)GPUBackend::OPENGL; + g_Config.bSoftwareRendering = false; + force_gl_version = int(10.0 * glVersionTemp + 0.5); + } else if (restOfOption == "gles") { + gpuBackend = GPUBackend::OPENGL; + softwareRendering = false; + } else { + // Bad value, report error and exit. + PRINT_STDERR("Invalid value for --graphics: %s", restOfOption.c_str()); + return CommandLineParseResult::Exit; } } else if (startsWith(argv[i], configOption)) { configFilename = std::string(argv[i] + configOption.size()); diff --git a/Core/CmdLine.h b/Core/CmdLine.h index 049eac9746..aa35ef7a96 100644 --- a/Core/CmdLine.h +++ b/Core/CmdLine.h @@ -18,6 +18,14 @@ struct CommandLineOptions { std::optional bootFilename; + // SDL only: Option to force a specific OpenGL version (42="4.2", + // etc.; -1 means "try them all"). + // Implemented as a workaround for https://github.com/hrydgard/ppsspp/issues/20687 + // NOTE: this is currently not persistent (doesn't + // go to config), even though --graphics=openglX.Y + // also sets the GPU backend which does persist. + int force_gl_version = -1; + #ifndef _DEBUG bool showLogWindow = false; #else diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index 4eb9788c2a..40c6adfad0 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -1312,16 +1312,32 @@ bool TestFriendlyPath() { } bool TestCmdLine() { - const char *argv[] = { - "ppsspp", - "--fullscreen", - "My_Game.iso" - }; - int argc = ARRAY_SIZE(argv); - CommandLineOptions options; - options.Parse(argc, argv); - EXPECT_TRUE(options.fullscreen.value_or(false)); - EXPECT_EQ_STR(options.bootFilename.value_or(""), std::string("My_Game.iso")); + { + const char *argv[] = { + "ppsspp", + "--fullscreen", + "--graphics=d3d11", + "My_Game.iso" + }; + int argc = ARRAY_SIZE(argv); + CommandLineOptions options; + options.Parse(argc, argv); + EXPECT_TRUE(options.fullscreen.value_or(false)); + EXPECT_EQ_STR(options.bootFilename.value_or(""), std::string("My_Game.iso")); + EXPECT_TRUE(options.gpuBackend.has_value()); + EXPECT_EQ_INT((int)options.gpuBackend.value_or((GPUBackend)-1), (int)GPUBackend::DIRECT3D11); + } + // Test GL version override + { + const char *argv[] = { + "ppsspp", + "--graphics=gles3.3", + }; + int argc = ARRAY_SIZE(argv); + CommandLineOptions options; + options.Parse(argc, argv); + EXPECT_EQ_INT(options.force_gl_version, 33); + } return true; }