From 0582faa52c2de5b70b73cd780e125910e3a35ce0 Mon Sep 17 00:00:00 2001 From: Rinnegatamante Date: Sun, 26 Jul 2020 21:34:25 +0200 Subject: [PATCH] Fix a bug causing a GPU crash when changing post-processing shader. --- .../SysVita/Graphics/GraphicsContextVita.cpp | 2 +- Source/SysVita/UI/Menu.h | 2 +- Source/SysVita/UI/MenuBarScreen.cpp | 45 ++++++++++--------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/Source/SysVita/Graphics/GraphicsContextVita.cpp b/Source/SysVita/Graphics/GraphicsContextVita.cpp index 4f4930b9..d1c7280b 100644 --- a/Source/SysVita/Graphics/GraphicsContextVita.cpp +++ b/Source/SysVita/Graphics/GraphicsContextVita.cpp @@ -210,7 +210,7 @@ void IGraphicsContext::UpdateFrame(bool wait_for_vbl) glLoadIdentity(); vglStartRendering(); glBindTexture(GL_TEXTURE_2D, emu_fb_tex); - glUseProgram(program); + glUseProgram(cur_prog); vglVertexAttribPointerMapped(0, vflux_vertices); vglVertexAttribPointerMapped(1, vflux_texcoords); vglDrawObjects(GL_TRIANGLE_FAN, 4, true); diff --git a/Source/SysVita/UI/Menu.h b/Source/SysVita/UI/Menu.h index 9431fb09..7a9b3be7 100644 --- a/Source/SysVita/UI/Menu.h +++ b/Source/SysVita/UI/Menu.h @@ -215,7 +215,7 @@ enum { #define GET_VALUE(x) x, #define GET_STRING(x) #x, -extern GLuint program; +extern GLuint cur_prog; extern GLuint cur_overlay; extern float *vflux_vertices; extern float *vflux_texcoords; diff --git a/Source/SysVita/UI/MenuBarScreen.cpp b/Source/SysVita/UI/MenuBarScreen.cpp index a4eac160..a4e57a8f 100644 --- a/Source/SysVita/UI/MenuBarScreen.cpp +++ b/Source/SysVita/UI/MenuBarScreen.cpp @@ -46,8 +46,11 @@ bool gTexturesDumper = false; bool gUseHighResTextures = false; bool gUseRearpad = false; -GLuint shaders[2]; -GLuint program = 0xDEADBEEF; +uint8_t shader_idx = 0; + +GLuint shaders[4]; +GLuint program[2] = {0xDEADBEEF, 0xDEADBEEF}; +GLuint cur_prog; GLuint cur_overlay = 0xDEADBEEF; static char custom_path_str[512]; @@ -435,37 +438,39 @@ void DrawCommonMenuBar() { int i = 0; while (p) { if (ImGui::MenuItem(p->name, nullptr, gPostProcessing == i)){ - gPostProcessing = i; - if (gPostProcessing) { - if (program != 0xDEADBEEF) { - glDeleteProgram(program); - glDeleteShader(shaders[0]); - glDeleteShader(shaders[1]); + if (gPostProcessing != i && i) { + shader_idx = (shader_idx + 1) % 2; + if (program[shader_idx] != 0xDEADBEEF) { + glDeleteProgram(program[shader_idx]); + glDeleteShader(shaders[shader_idx * 2]); + glDeleteShader(shaders[shader_idx * 2 + 1]); } - shaders[0] = glCreateShader(GL_VERTEX_SHADER); - shaders[1] = glCreateShader(GL_FRAGMENT_SHADER); - program = glCreateProgram(); + shaders[shader_idx * 2] = glCreateShader(GL_VERTEX_SHADER); + shaders[shader_idx * 2 + 1] = glCreateShader(GL_FRAGMENT_SHADER); + program[shader_idx] = glCreateProgram(); char fpath[128]; if (p->compiled) { sprintf(fpath, "%s%s_v.gxp", DAEDALUS_VITA_PATH_EXT("ux0:", "Shaders/"), p->name); - loadCompiledShader(0, fpath); + loadCompiledShader(shader_idx * 2, fpath); sprintf(fpath, "%s%s_f.gxp", DAEDALUS_VITA_PATH_EXT("ux0:", "Shaders/"), p->name); - loadCompiledShader(1, fpath); + loadCompiledShader(shader_idx * 2 + 1, fpath); } else { sprintf(fpath, "%s%s_v.cg", DAEDALUS_VITA_PATH_EXT("ux0:", "Shaders/"), p->name); - loadShader(0, fpath); + loadShader(shader_idx * 2, fpath); sprintf(fpath, "%s%s_f.cg", DAEDALUS_VITA_PATH_EXT("ux0:", "Shaders/"), p->name); - loadShader(1, fpath); + loadShader(shader_idx * 2 + 1, fpath); } - glAttachShader(program, shaders[0]); - glAttachShader(program, shaders[1]); + glAttachShader(program[shader_idx], shaders[shader_idx * 2]); + glAttachShader(program[shader_idx], shaders[shader_idx * 2 + 1]); - vglBindAttribLocation(program, 0, "position", 3, GL_FLOAT); - vglBindAttribLocation(program, 1, "texcoord", 2, GL_FLOAT); + vglBindAttribLocation(program[shader_idx], 0, "position", 3, GL_FLOAT); + vglBindAttribLocation(program[shader_idx], 1, "texcoord", 2, GL_FLOAT); - glLinkProgram(program); + glLinkProgram(program[shader_idx]); + cur_prog = program[shader_idx]; } + gPostProcessing = i; } i++; p = p->next;