Implement the fallback path from OpenGL to Vulkan

This commit is contained in:
Henrik Rydgård 2024-09-16 12:28:38 +02:00
parent 41b1165dcd
commit 99a65f3a0a
5 changed files with 46 additions and 13 deletions

View file

@ -1289,6 +1289,8 @@ bool IsProbablyInDownloadsFolder(const Path &filename) {
} }
break; break;
} }
default:
break;
} }
return filename.FilePathContainsNoCase("download"); return filename.FilePathContainsNoCase("download");
} }

View file

@ -528,7 +528,11 @@ static u32 sceAtracGetStreamDataInfo(int atracID, u32 writePtrAddr, u32 writable
static u32 sceAtracReleaseAtracID(int atracID) { static u32 sceAtracReleaseAtracID(int atracID) {
int result = deleteAtrac(atracID); int result = deleteAtrac(atracID);
if (result < 0) { if (result < 0) {
return hleLogError(Log::ME, result, "did not exist"); if (atracID >= 0) {
return hleLogError(Log::ME, result, "did not exist");
} else {
return hleLogWarning(Log::ME, result, "did not exist");
}
} }
return hleLogSuccessInfoI(Log::ME, result); return hleLogSuccessInfoI(Log::ME, result);
} }

View file

@ -299,8 +299,8 @@ void EGL_Close() {
#endif // USING_EGL #endif // USING_EGL
bool SDLGLGraphicsContext::InitFromRenderThread() { bool SDLGLGraphicsContext::InitFromRenderThread(std::string *errorMessage) {
bool retval = GraphicsContext::InitFromRenderThread(); bool retval = GraphicsContext::InitFromRenderThread(errorMessage);
// HACK: Ensure that the swap interval is set after context creation (needed for kmsdrm) // HACK: Ensure that the swap interval is set after context creation (needed for kmsdrm)
SDL_GL_SetSwapInterval(1); SDL_GL_SetSwapInterval(1);
return retval; return retval;
@ -375,6 +375,7 @@ int SDLGLGraphicsContext::Init(SDL_Window *&window, int x, int y, int w, int h,
glContext = SDL_GL_CreateContext(window); glContext = SDL_GL_CreateContext(window);
if (glContext == nullptr) { if (glContext == nullptr) {
// OK, now we really have tried everything.
NativeShutdown(); NativeShutdown();
fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError()); fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
SDL_Quit(); SDL_Quit();

View file

@ -7,6 +7,8 @@
#include "SDL_syswm.h" #include "SDL_syswm.h"
#endif #endif
#include <string>
#include "Common/GPU/OpenGL/GLRenderManager.h" #include "Common/GPU/OpenGL/GLRenderManager.h"
#include "Common/GPU/OpenGL/GLCommon.h" #include "Common/GPU/OpenGL/GLCommon.h"
#include "Common/GraphicsContext.h" #include "Common/GraphicsContext.h"
@ -16,7 +18,7 @@ public:
// Returns 0 on success. // Returns 0 on success.
int Init(SDL_Window *&window, int x, int y, int w, int h, int mode, std::string *error_message); int Init(SDL_Window *&window, int x, int y, int w, int h, int mode, std::string *error_message);
bool InitFromRenderThread() override; bool InitFromRenderThread(std::string *errorMessage) override;
void Shutdown() override {} void Shutdown() override {}
void ShutdownFromRenderThread() override; void ShutdownFromRenderThread() override;

View file

@ -1336,24 +1336,44 @@ int main(int argc, char *argv[]) {
std::string error_message; std::string error_message;
if (g_Config.iGPUBackend == (int)GPUBackend::OPENGL) { if (g_Config.iGPUBackend == (int)GPUBackend::OPENGL) {
SDLGLGraphicsContext *ctx = new SDLGLGraphicsContext(); SDLGLGraphicsContext *glctx = new SDLGLGraphicsContext();
if (ctx->Init(window, x, y, w, h, mode, &error_message) != 0) { if (glctx->Init(window, x, y, w, h, mode, &error_message) != 0) {
printf("GL init error '%s'\n", error_message.c_str()); // Let's try the fallback once per process run.
printf("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;
// NOTE : This should match the lines below in the Vulkan case.
SDLVulkanGraphicsContext *vkctx = new SDLVulkanGraphicsContext();
if (!vkctx->Init(window, x, y, w, h, mode | SDL_WINDOW_VULKAN, &error_message)) {
printf("Vulkan fallback failed: %s\n", error_message.c_str());
return 1;
}
graphicsContext = vkctx;
} else {
graphicsContext = glctx;
} }
graphicsContext = ctx;
#if !PPSSPP_PLATFORM(SWITCH) #if !PPSSPP_PLATFORM(SWITCH)
} else if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN) { } else if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN) {
SDLVulkanGraphicsContext *ctx = new SDLVulkanGraphicsContext(); SDLVulkanGraphicsContext *vkctx = new SDLVulkanGraphicsContext();
if (!ctx->Init(window, x, y, w, h, mode | SDL_WINDOW_VULKAN, &error_message)) { if (!vkctx->Init(window, x, y, w, h, mode | SDL_WINDOW_VULKAN, &error_message)) {
// Let's try the fallback once per process run.
printf("Vulkan init error '%s' - falling back to GL\n", error_message.c_str()); printf("Vulkan init error '%s' - falling back to GL\n", error_message.c_str());
g_Config.iGPUBackend = (int)GPUBackend::OPENGL; g_Config.iGPUBackend = (int)GPUBackend::OPENGL;
SetGPUBackend((GPUBackend)g_Config.iGPUBackend); SetGPUBackend((GPUBackend)g_Config.iGPUBackend);
delete ctx; delete vkctx;
// NOTE : This should match the three lines above in the OpenGL case.
SDLGLGraphicsContext *glctx = new SDLGLGraphicsContext(); SDLGLGraphicsContext *glctx = new SDLGLGraphicsContext();
glctx->Init(window, x, y, w, h, mode, &error_message); if (glctx->Init(window, x, y, w, h, mode, &error_message) != 0) {
printf("GL fallback failed: %s\n", error_message.c_str());
return 1;
}
graphicsContext = glctx; graphicsContext = glctx;
} else { } else {
graphicsContext = ctx; graphicsContext = vkctx;
} }
#endif #endif
} }
@ -1396,8 +1416,12 @@ int main(int argc, char *argv[]) {
// Since we render from the main thread, there's nothing done here, but we call it to avoid confusion. // Since we render from the main thread, there's nothing done here, but we call it to avoid confusion.
if (!graphicsContext->InitFromRenderThread(&error_message)) { if (!graphicsContext->InitFromRenderThread(&error_message)) {
printf("Init from thread error: '%s'\n", error_message.c_str()); printf("Init from thread error: '%s'\n", error_message.c_str());
return 1;
} }
// OK, we have a valid graphics backend selected. Let's clear the failures.
g_Config.sFailedGPUBackends.clear();
#ifdef MOBILE_DEVICE #ifdef MOBILE_DEVICE
SDL_ShowCursor(SDL_DISABLE); SDL_ShowCursor(SDL_DISABLE);
#endif #endif