From afa50a17c483b9cace720cf5e7625e6f1359705a Mon Sep 17 00:00:00 2001 From: jackun Date: Tue, 30 Mar 2021 04:56:38 +0300 Subject: [PATCH] [OpenGL] Add gl_size_query, gl_bind_framebuffer, gl_dont_flip options for workarounds `gl_size_query = viewport` - specify what to use for getting display size. Options are "viewport", "scissorbox" or disabled. Defaults to using glXQueryDrawable. `gl_bind_framebuffer = 0` - (re)bind given framebuffer before MangoHud gets drawn. Helps with Crusader Kings 3. `gl_dont_flip = 1` - don't swap origin if using GL_UPPER_LEFT. Helps with Ryujinx. --- bin/MangoHud.conf | 11 +++++++++++ src/gl/imgui_impl_opengl3.cpp | 15 +++++++++++---- src/gl/imgui_impl_opengl3.h | 4 ++-- src/gl/inject_egl.cpp | 1 - src/gl/inject_glx.cpp | 29 ++++++++++++++++++++--------- src/overlay_params.cpp | 14 ++++++++++++++ src/overlay_params.h | 12 ++++++++++++ 7 files changed, 70 insertions(+), 16 deletions(-) diff --git a/bin/MangoHud.conf b/bin/MangoHud.conf index 99c7e443..4906b4d9 100644 --- a/bin/MangoHud.conf +++ b/bin/MangoHud.conf @@ -157,6 +157,17 @@ background_alpha=0.5 ### Blacklist # blacklist = +################## WORKAROUNDS ################# +### Options starting with "gl_*" are for OpenGL. +### Specify what to use for getting display size. Options are "viewport", "scissorbox" or disabled. Defaults to using glXQueryDrawable. +# gl_size_query = viewport + +### (Re)bind given framebuffer before MangoHud gets drawn. Helps with Crusader Kings III. +# gl_bind_framebuffer = 0 + +### Don't swap origin if using GL_UPPER_LEFT. Helps with Ryujinx. +# gl_dont_flip = 1 + ################## INTERACTION ################# ### Change toggle keybinds for the hud & logging diff --git a/src/gl/imgui_impl_opengl3.cpp b/src/gl/imgui_impl_opengl3.cpp index beb85e7b..e726c360 100644 --- a/src/gl/imgui_impl_opengl3.cpp +++ b/src/gl/imgui_impl_opengl3.cpp @@ -74,7 +74,9 @@ #include "overlay.h" -namespace MangoHud { +namespace MangoHud { namespace GL { + +extern overlay_params params; // Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have. #if defined(IMGUI_IMPL_OPENGL_ES2) || defined(IMGUI_IMPL_OPENGL_ES3) || !defined(GL_VERSION_3_2) @@ -501,6 +503,8 @@ void ImGui_ImplOpenGL3_NewFrame() static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object) { // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill + if (params.gl_bind_framebuffer >= 0 && g_GlVersion >= 300) + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, params.gl_bind_framebuffer); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); @@ -535,7 +539,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; float T = draw_data->DisplayPos.y; float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; - if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left + if (!params.gl_dont_flip && !clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left const float ortho_projection[4][4] = { { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, @@ -662,7 +666,10 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) { // Apply scissor/clipping rectangle - glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); + if (!params.gl_dont_flip) + glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)); + else + glScissor((int)clip_rect.x, (int)clip_rect.y, (int)clip_rect.z, (int)clip_rect.w); // Bind texture, Draw glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); @@ -712,4 +719,4 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) glEnable(GL_FRAMEBUFFER_SRGB); } -} +}} // namespace diff --git a/src/gl/imgui_impl_opengl3.h b/src/gl/imgui_impl_opengl3.h index 01609368..a01390d4 100644 --- a/src/gl/imgui_impl_opengl3.h +++ b/src/gl/imgui_impl_opengl3.h @@ -25,7 +25,7 @@ #ifndef MANGOHUD_IMGUI_IMPL_OPENGL3_H #define MANGOHUD_IMGUI_IMPL_OPENGL3_H -namespace MangoHud { +namespace MangoHud { namespace GL { void GetOpenGLVersion(int& major, int& minor, bool& isGLES); @@ -42,6 +42,6 @@ IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture(); //IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects(); //IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); -} +}} #endif //MANGOHUD_IMGUI_IMPL_OPENGL3_H diff --git a/src/gl/inject_egl.cpp b/src/gl/inject_egl.cpp index 4f335090..ae836374 100644 --- a/src/gl/inject_egl.cpp +++ b/src/gl/inject_egl.cpp @@ -14,7 +14,6 @@ using namespace MangoHud::GL; -#define EXPORT_C_(type) extern "C" __attribute__((__visibility__("default"))) type EXPORT_C_(void *) eglGetProcAddress(const char* procName); void* get_egl_proc_address(const char* name) { diff --git a/src/gl/inject_glx.cpp b/src/gl/inject_glx.cpp index 34a35992..4b38b631 100644 --- a/src/gl/inject_glx.cpp +++ b/src/gl/inject_glx.cpp @@ -16,18 +16,17 @@ #include #include +#include #include "imgui_hud.h" using namespace MangoHud::GL; -#define EXPORT_C_(type) extern "C" __attribute__((__visibility__("default"))) type - EXPORT_C_(void *) glXGetProcAddress(const unsigned char* procName); EXPORT_C_(void *) glXGetProcAddressARB(const unsigned char* procName); #ifndef GLX_WIDTH #define GLX_WIDTH 0x801D -#define GLX_HEIGTH 0x801E +#define GLX_HEIGHT 0x801E #endif static glx_loader glx; @@ -136,17 +135,29 @@ EXPORT_C_(int) glXMakeCurrent(void* dpy, void* drawable, void* ctx) { static void do_imgui_swap(void *dpy, void *drawable) { + GLint vp[4]; if (!is_blacklisted()) { imgui_create(glx.GetCurrentContext()); unsigned int width = -1, height = -1; - glx.QueryDrawable(dpy, drawable, GLX_WIDTH, &width); - glx.QueryDrawable(dpy, drawable, GLX_HEIGTH, &height); - - /*GLint vp[4]; glGetIntegerv (GL_VIEWPORT, vp); - width = vp[2]; - height = vp[3];*/ + switch (params.gl_size_query) + { + case GL_SIZE_VIEWPORT: + glGetIntegerv (GL_VIEWPORT, vp); + width = vp[2]; + height = vp[3]; + break; + case GL_SIZE_SCISSORBOX: + glGetIntegerv (GL_SCISSOR_BOX, vp); + width = vp[2]; + height = vp[3]; + break; + default: + glx.QueryDrawable(dpy, drawable, GLX_WIDTH, &width); + glx.QueryDrawable(dpy, drawable, GLX_HEIGHT, &height); + break; + } imgui_render(width, height); } diff --git a/src/overlay_params.cpp b/src/overlay_params.cpp index 63d046ea..7f7138ba 100644 --- a/src/overlay_params.cpp +++ b/src/overlay_params.cpp @@ -362,7 +362,19 @@ parse_font_glyph_ranges(const char *str) fg |= FG_LATIN_EXT_B; } return fg; +} +static gl_size_query +parse_gl_size_query(const char *str) +{ + std::string value(str); + trim(value); + std::transform(value.begin(), value.end(), value.begin(), ::tolower); + if (value == "viewport") + return GL_SIZE_VIEWPORT; + if (value == "scissorbox") + return GL_SIZE_SCISSORBOX; + return GL_SIZE_DRAWABLE; } #define parse_width(s) parse_unsigned(s) @@ -395,6 +407,8 @@ parse_font_glyph_ranges(const char *str) #define parse_cellpadding_y(s) parse_float(s) #define parse_table_columns(s) parse_unsigned(s) #define parse_autostart_log(s) parse_unsigned(s) +#define parse_gl_bind_framebuffer(s) parse_unsigned(s) +#define parse_gl_dont_flip(s) parse_unsigned(s) != 0 #define parse_cpu_color(s) parse_color(s) #define parse_gpu_color(s) parse_color(s) diff --git a/src/overlay_params.h b/src/overlay_params.h index cf28fea9..cf240eb6 100644 --- a/src/overlay_params.h +++ b/src/overlay_params.h @@ -87,6 +87,9 @@ typedef unsigned long KeySym; OVERLAY_PARAM_CUSTOM(fps_limit) \ OVERLAY_PARAM_CUSTOM(vsync) \ OVERLAY_PARAM_CUSTOM(gl_vsync) \ + OVERLAY_PARAM_CUSTOM(gl_size_query) \ + OVERLAY_PARAM_CUSTOM(gl_bind_framebuffer) \ + OVERLAY_PARAM_CUSTOM(gl_dont_flip) \ OVERLAY_PARAM_CUSTOM(toggle_hud) \ OVERLAY_PARAM_CUSTOM(toggle_fps_limit) \ OVERLAY_PARAM_CUSTOM(toggle_logging) \ @@ -164,6 +167,12 @@ enum font_glyph_ranges { FG_LATIN_EXT_B = (1u << 8), }; +enum gl_size_query { + GL_SIZE_DRAWABLE, + GL_SIZE_VIEWPORT, + GL_SIZE_SCISSORBOX, // needed? +}; + enum overlay_param_enabled { #define OVERLAY_PARAM_BOOL(name) OVERLAY_PARAM_ENABLED_##name, #define OVERLAY_PARAM_CUSTOM(name) @@ -188,6 +197,9 @@ struct overlay_params { int offset_x, offset_y; unsigned vsync; int gl_vsync; + int gl_bind_framebuffer {-1}; + enum gl_size_query gl_size_query {GL_SIZE_DRAWABLE}; + bool gl_dont_flip {false}; uint64_t log_duration; unsigned cpu_color, gpu_color, vram_color, ram_color, engine_color, io_color, frametime_color, background_color, text_color, wine_color; std::vector gpu_load_color;