mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
SDL: Simplify graphics context fallback
This commit is contained in:
1 parent
09bf426ee7
commit
1c0740c4b9
6 files changed
+145
-94
No files matched your search
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) Launch PPSSPPSDL (WSL)",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "/home/hrydg/ppsspp/build/PPSSPPSDL",
|
||||
"osx": {
|
||||
"program": "${workspaceFolder}/build/PPSSPPSDL.app/Contents/MacOS/PPSSPPSDL"
|
||||
},
|
||||
"linux": {
|
||||
"program": "/home/hrydg/ppsspp/build/PPSSPPSDL"
|
||||
},
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "/home/hrydg/ppsspp",
|
||||
"sourceFileMap": {
|
||||
"/home/hrydg/ppsspp": "${workspaceFolder}"
|
||||
},
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"pipeTransport": {
|
||||
"pipeProgram": "wsl.exe",
|
||||
"pipeArgs": [
|
||||
"-d",
|
||||
"Ubuntu",
|
||||
"--"
|
||||
],
|
||||
"pipeCwd": "C:/",
|
||||
"quoteArgs": false,
|
||||
"debuggerPath": "/usr/bin/gdb"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"comment": "Copy this to launch.json if you want to, or edit as desired first",
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(lldb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "",
|
||||
"osx": {
|
||||
"program": "${workspaceFolder}/build/PPSSPPSDL.app/Contents/MacOS/PPSSPPSDL"
|
||||
},
|
||||
"linux": {
|
||||
"program": "${workspaceRoot}/build/PPSSPPSDL"
|
||||
},
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "lldb"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Common/System/Display.h"
|
||||
#include "Common/Math/math_util.h"
|
||||
#include "Common/GPU/MiscTypes.h"
|
||||
#include "Common/Log.h"
|
||||
|
||||
DisplayProperties g_display;
|
||||
|
||||
@@ -70,6 +71,7 @@ DisplayProperties::DisplayProperties() {
|
||||
}
|
||||
|
||||
bool DisplayProperties::Recalculate(int new_pixel_xres, int new_pixel_yres, float new_scale_x, float new_scale_y, float customScale) {
|
||||
INFO_LOG(Log::G3D, "recalculate: %dx%d, %f, %f, %f", new_pixel_xres, new_pixel_yres, new_scale_x, new_scale_y, customScale);
|
||||
bool px_changed = false;
|
||||
if (new_pixel_xres > 0 && pixel_xres != new_pixel_xres) {
|
||||
pixel_xres = new_pixel_xres;
|
||||
|
||||
@@ -255,7 +255,7 @@ void ScreenManager::deviceRestored(Draw::DrawContext *draw) {
|
||||
}
|
||||
|
||||
void ScreenManager::resized() {
|
||||
INFO_LOG(Log::UI, "ScreenManager::resized(dp: %dx%d)", g_display.dp_xres, g_display.dp_yres);
|
||||
INFO_LOG(Log::UI, "ScreenManager::resized(g_display.dp_xres/dp_yres: %dx%d)", g_display.dp_xres, g_display.dp_yres);
|
||||
// Have to notify the whole stack, otherwise there will be problems when going back
|
||||
// to non-top screens.
|
||||
for (auto &layer : stack_) {
|
||||
|
||||
@@ -286,6 +286,8 @@ void EGL_Close() {
|
||||
|
||||
#endif // USING_EGL
|
||||
|
||||
|
||||
|
||||
// TODO: All this stuff doesn't really belong here.
|
||||
bool SDLGLGraphicsContext::InitSurface(WindowSystem winsys, void *data1, void *data2, std::string *error_message) {
|
||||
SDL_Window *window = *(SDL_Window **)data1;
|
||||
@@ -448,10 +450,6 @@ bool SDLGLGraphicsContext::InitSurface(WindowSystem winsys, void *data1, void *d
|
||||
});
|
||||
|
||||
window_ = window;
|
||||
|
||||
// HACK: Ensure that the swap interval is set after context creation (needed for kmsdrm)
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+79
-89
@@ -96,8 +96,6 @@ static float g_ForcedDPI = 0.0f; // if this is 0.0f, use g_DesktopDPI
|
||||
static float g_RefreshRate = 60.f;
|
||||
static int g_sampleRate = 44100;
|
||||
|
||||
static bool g_rebootEmuThread = false;
|
||||
|
||||
static SDL_AudioSpec g_retFmt;
|
||||
static int g_audioFramesPerBuffer = 0;
|
||||
|
||||
@@ -1334,6 +1332,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta
|
||||
#if !defined(MOBILE_DEVICE)
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
{
|
||||
INFO_LOG(Log::UI, "SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED: %d x %d", event.window.data1, event.window.data2);
|
||||
int new_width = event.window.data1;
|
||||
int new_height = event.window.data2;
|
||||
|
||||
@@ -1342,6 +1341,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta
|
||||
Uint64 window_flags = SDL_GetWindowFlags(window);
|
||||
bool fullscreen = (window_flags & SDL_WINDOW_FULLSCREEN) != 0;
|
||||
|
||||
// !!! This is the wrong thread!
|
||||
// This one calls NativeResized if the size changed.
|
||||
Native_UpdateScreenScale(new_width, new_height, UIScaleFactorToMultiplier(g_Config.iUIScaleFactor));
|
||||
|
||||
@@ -1408,7 +1408,9 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta
|
||||
#endif
|
||||
case SDL_EVENT_KEY_DOWN:
|
||||
{
|
||||
if (event.key.repeat > 0) { break;}
|
||||
if (event.key.repeat > 0) {
|
||||
break;
|
||||
}
|
||||
int k = event.key.key;
|
||||
KeyInput key;
|
||||
key.flags = KeyInputFlags::DOWN;
|
||||
@@ -1420,15 +1422,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta
|
||||
key.deviceId = DEVICE_ID_KEYBOARD;
|
||||
NativeKey(key);
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (k == SDLK_F7) {
|
||||
fprintf(stderr, "f7 pressed - rebooting emuthread\n");
|
||||
g_rebootEmuThread = true;
|
||||
}
|
||||
#endif
|
||||
// Convenience subset of what
|
||||
// "Enable standard shortcut keys"
|
||||
// does on Windows.
|
||||
// Convenience subset of what "Enable standard shortcut keys" does on Windows.
|
||||
if (g_Config.bSystemControls) {
|
||||
bool ctrl = bool(event.key.mod & SDL_KMOD_CTRL);
|
||||
if (ctrl && (k == SDLK_W))
|
||||
@@ -1539,6 +1533,7 @@ static void ProcessSDLEvent(SDL_Window *window, const SDL_Event &event, InputSta
|
||||
switch (event.button.button) {
|
||||
case SDL_BUTTON_LEFT:
|
||||
{
|
||||
INFO_LOG(Log::UI, "SDL_EVENT_MOUSE_BUTTON_DOWN: %f x %f", event.button.x, event.button.y);
|
||||
// We have to juggle around 3 kinds of "DPI spaces" if a logical DPI is
|
||||
// provided (through --dpi, it is equal to system DPI if unspecified):
|
||||
// - SDL gives us motion events in "system DPI" points
|
||||
@@ -1749,6 +1744,7 @@ void UpdateSDLCursor() {
|
||||
}
|
||||
|
||||
bool DetermineVulkanWindowSystem(SDL_Window *window, WindowSystem *windowSystem, void **data1, void **data2) {
|
||||
_dbg_assert_(window);
|
||||
SDL_PropertiesID windowProps = SDL_GetWindowProperties(window);
|
||||
void *x11Display = SDL_GetPointerProperty(windowProps, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, nullptr);
|
||||
if (x11Display != nullptr) {
|
||||
@@ -2039,82 +2035,93 @@ int main(int argc, char *argv[]) {
|
||||
SDL_Window *window = nullptr;
|
||||
|
||||
// Switch away from Vulkan if not available.
|
||||
if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN && !vulkanMayBeAvailable) {
|
||||
g_Config.iGPUBackend = (int)GPUBackend::OPENGL;
|
||||
int fallbackGPUBackend = -1;
|
||||
switch ((GPUBackend)g_Config.iGPUBackend) {
|
||||
case GPUBackend::VULKAN:
|
||||
if (!vulkanMayBeAvailable) {
|
||||
fprintf(stderr, "Vulkan is not available, switching to OpenGL.\n");
|
||||
g_Config.iGPUBackend = (int)GPUBackend::OPENGL;
|
||||
} else {
|
||||
fallbackGPUBackend = (int)GPUBackend::OPENGL;
|
||||
}
|
||||
break;
|
||||
case GPUBackend::OPENGL:
|
||||
fallbackGPUBackend = (int)GPUBackend::VULKAN;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown GPU backend %d, switching to Vulkan.\n", g_Config.iGPUBackend);
|
||||
g_Config.iGPUBackend = (int)GPUBackend::VULKAN;
|
||||
fallbackGPUBackend = (int)GPUBackend::OPENGL;
|
||||
break;
|
||||
}
|
||||
|
||||
window = SDL_CreateWindow("Initializing graphics...", w, h, (SDL_WindowFlags)mode);
|
||||
auto initializeBackend = [&](GPUBackend backend, GraphicsContext **graphicsContext, std::string *errorMessage) -> bool {
|
||||
// Surface init params.
|
||||
WindowSystem windowSystem = WINDOWSYSTEM_NONE;
|
||||
void *data1 = &window;
|
||||
void *data2 = (void *)(uintptr_t)mode;
|
||||
if (backend == GPUBackend::OPENGL) {
|
||||
mode |= SDL_WINDOW_OPENGL;
|
||||
window = SDL_CreateWindow("Initializing graphics...", w, h, (SDL_WindowFlags)mode);
|
||||
if (!window) {
|
||||
fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Surface init params. These are set up for OpenGL by default.
|
||||
WindowSystem windowSystem = WINDOWSYSTEM_NONE;
|
||||
void *data1 = &window;
|
||||
void *data2 = nullptr;
|
||||
SDLGLGraphicsContext *glctx = new SDLGLGraphicsContext(cmdLineOptions.force_gl_version);
|
||||
*graphicsContext = glctx;
|
||||
|
||||
std::string error_message;
|
||||
if (g_Config.iGPUBackend == (int)GPUBackend::OPENGL) {
|
||||
SDLGLGraphicsContext *glctx = new SDLGLGraphicsContext(cmdLineOptions.force_gl_version);
|
||||
if (!window) {
|
||||
fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
if (x != SDL_WINDOWPOS_UNDEFINED && y != SDL_WINDOWPOS_UNDEFINED) {
|
||||
SDL_SetWindowPosition(window, x, y);
|
||||
}
|
||||
|
||||
glctx->InitAPI(nullptr, nullptr, &error_message);
|
||||
if (!glctx->InitSurface(WINDOWSYSTEM_NONE, &window, (void *)(uintptr_t)mode, &error_message)) {
|
||||
// Let's try the fallback once per process run.
|
||||
fprintf(stderr, "GL init error '%s' - falling back to Vulkan\n", error_message.c_str());
|
||||
g_Config.iGPUBackend = (int)GPUBackend::VULKAN;
|
||||
SetGPUBackend((GPUBackend)g_Config.iGPUBackend);
|
||||
delete glctx;
|
||||
glctx->InitAPI(nullptr, nullptr, errorMessage);
|
||||
if (!glctx->InitSurface(windowSystem, data1, data2, errorMessage)) {
|
||||
fprintf(stderr, "OpenGL surface creation failed: %s\n", errorMessage->c_str());
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
mode |= SDL_WINDOW_VULKAN;
|
||||
window = SDL_CreateWindow("Initializing graphics...", w, h, (SDL_WindowFlags)mode);
|
||||
if (!window) {
|
||||
fprintf(stderr, "Error creating SDL window: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Overwrite the surface init params with what we need for Vulkan..
|
||||
if (!DetermineVulkanWindowSystem(window, &windowSystem, &data1, &data2)) {
|
||||
return 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE : This should match the lines below in the Vulkan case.
|
||||
VulkanGraphicsContext *vkctx = new VulkanGraphicsContext();
|
||||
vkctx->InitAPI(nullptr, &g_Config.sVulkanDevice, &error_message);
|
||||
if (!vkctx->InitAPI(nullptr, &g_Config.sVulkanDevice, errorMessage)) {
|
||||
fprintf(stderr, "Vulkan initialization failed: %s\n", errorMessage->c_str());
|
||||
return false;
|
||||
}
|
||||
if (!vkctx->InitSurface(windowSystem, data1, data2, errorMessage)) {
|
||||
fprintf(stderr, "Vulkan surface creation failed: %s\n", errorMessage->c_str());
|
||||
return false;
|
||||
}
|
||||
*graphicsContext = vkctx;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
if (!vkctx->InitSurface(windowSystem, data1, data2, &error_message)) {
|
||||
fprintf(stderr, "Vulkan fallback failed: %s\n", error_message.c_str());
|
||||
std::string error_message;
|
||||
if (!initializeBackend((GPUBackend)g_Config.iGPUBackend, &graphicsContext, &error_message)) {
|
||||
fprintf(stderr, "Failed to initialize graphics backend: %s\n", error_message.c_str());
|
||||
if (fallbackGPUBackend != -1) {
|
||||
fprintf(stderr, "Attempting to fall back to %s...\n", fallbackGPUBackend == (int)GPUBackend::OPENGL ? "OpenGL" : "Vulkan");
|
||||
g_Config.iGPUBackend = fallbackGPUBackend;
|
||||
error_message.clear();
|
||||
if (!initializeBackend((GPUBackend)g_Config.iGPUBackend, &graphicsContext, &error_message)) {
|
||||
fprintf(stderr, "Fallback failed: %s\n", error_message.c_str());
|
||||
return 1;
|
||||
}
|
||||
graphicsContext = vkctx;
|
||||
} else {
|
||||
graphicsContext = glctx;
|
||||
}
|
||||
#if !PPSSPP_PLATFORM(SWITCH)
|
||||
} else if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN) {
|
||||
// Overwrite the surface init params with what we need for Vulkan..
|
||||
if (!DetermineVulkanWindowSystem(window, &windowSystem, &data1, &data2)) {
|
||||
fprintf(stderr, "No fallback GPU backend available. Exiting.\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
VulkanGraphicsContext *vkctx = new VulkanGraphicsContext();
|
||||
vkctx->InitAPI(nullptr, &g_Config.sVulkanDevice, &error_message);
|
||||
if (!vkctx->InitSurface(windowSystem, data1, data2, &error_message)) {
|
||||
// Let's try the fallback once per process run.
|
||||
|
||||
fprintf(stderr, "Vulkan init error '%s' - falling back to GL\n", error_message.c_str());
|
||||
g_Config.iGPUBackend = (int)GPUBackend::OPENGL;
|
||||
SetGPUBackend((GPUBackend)g_Config.iGPUBackend);
|
||||
delete vkctx;
|
||||
|
||||
// NOTE : This should match the three lines above in the OpenGL case.
|
||||
SDLGLGraphicsContext *glctx = new SDLGLGraphicsContext(cmdLineOptions.force_gl_version);
|
||||
glctx->InitAPI(nullptr, nullptr, &error_message);
|
||||
if (!glctx->InitSurface(windowSystem, data1, data2, &error_message)) {
|
||||
fprintf(stderr, "GL fallback failed: %s\n", error_message.c_str());
|
||||
return 1;
|
||||
}
|
||||
graphicsContext = glctx;
|
||||
} else {
|
||||
graphicsContext = vkctx;
|
||||
}
|
||||
#endif
|
||||
if (x != SDL_WINDOWPOS_UNDEFINED && y != SDL_WINDOWPOS_UNDEFINED) {
|
||||
SDL_SetWindowPosition(window, x, y);
|
||||
}
|
||||
|
||||
UpdateScreenDPI(window);
|
||||
@@ -2175,6 +2182,7 @@ int main(int argc, char *argv[]) {
|
||||
EnableFZ();
|
||||
|
||||
// We use the emuthread both for OpenGL and Vulkan, but in OpenGL mode we also render from the main thread.
|
||||
_dbg_assert_(graphicsContext);
|
||||
std::thread emuThread = EmuThread_Start(graphicsContext, new NativeApplication(), nullptr);
|
||||
|
||||
InputStateTracker inputTracker{};
|
||||
@@ -2251,24 +2259,6 @@ int main(int argc, char *argv[]) {
|
||||
UpdateWindowState(window);
|
||||
}
|
||||
}
|
||||
|
||||
if (g_rebootEmuThread) {
|
||||
fprintf(stderr, "rebooting emu thread");
|
||||
g_rebootEmuThread = false;
|
||||
EmuThread_Join(graphicsContext, emuThread);
|
||||
graphicsContext->ShutdownSurface();
|
||||
|
||||
fprintf(stderr, "OK, shutdown complete. starting up graphics again.\n");
|
||||
|
||||
if (g_Config.iGPUBackend == (int)GPUBackend::OPENGL) {
|
||||
SDLGLGraphicsContext *ctx = (SDLGLGraphicsContext *)graphicsContext;
|
||||
if (!ctx->InitSurface(windowSystem,data1, data2, &error_message)) {
|
||||
fprintf(stderr, "Failed to reinit graphics.\n");
|
||||
}
|
||||
}
|
||||
|
||||
emuThread = EmuThread_Start(graphicsContext, new NativeApplication(), nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
EmuThread_Join(graphicsContext, emuThread);
|
||||
|
||||
Reference in new issue
Block a user