diff --git a/src/main/cpp/config/settings.cpp b/src/main/cpp/config/settings.cpp index eec16f2..8ddbbae 100644 --- a/src/main/cpp/config/settings.cpp +++ b/src/main/cpp/config/settings.cpp @@ -24,6 +24,7 @@ void init_settings() { global_settings.angle_depth_clear_fix_mode = AngleDepthClearFixMode::Disabled; global_settings.ext_direct_state_access = true; global_settings.custom_gl_version = { 0, 0, 0 }; // will go default + global_settings.fsr1_setting = FSR1_Quality_Preset::Disabled; #else @@ -44,6 +45,8 @@ void init_settings() { multidraw_mode_t multidrawMode = success ? static_cast(config_get_int("multidrawMode")) : multidraw_mode_t::Auto; AngleDepthClearFixMode angleDepthClearFixMode = success ? static_cast(config_get_int("angleDepthClearFixMode")) : AngleDepthClearFixMode::Disabled; int customGLVersionInt = success ? config_get_int("customGLVersion") : DEFAULT_GL_VERSION; + FSR1_Quality_Preset fsr1Setting = success ? static_cast(config_get_int("fsr1Setting")) : FSR1_Quality_Preset::Disabled; + if (customGLVersionInt < 0) { customGLVersionInt = 0; } @@ -74,6 +77,9 @@ void init_settings() { } else if (customGLVersionInt == 0) { customGLVersionInt = DEFAULT_GL_VERSION; } + if (static_cast(fsr1Setting) < 0 || static_cast(fsr1Setting) >= static_cast(FSR1_Quality_Preset::MaxValue)) { + fsr1Setting = FSR1_Quality_Preset::Disabled; + } Version customGLVersion(customGLVersionInt); @@ -96,6 +102,8 @@ void init_settings() { enableExtDirectStateAccess = true; maxGlslCacheSize = 0; angleDepthClearFixMode = AngleDepthClearFixMode::Disabled; + fsr1Setting = FSR1_Quality_Preset::Disabled; + multidrawMode = multidraw_mode_t::DrawElements; } AngleMode finalAngleMode = AngleMode::Disabled; @@ -176,6 +184,7 @@ void init_settings() { global_settings.multidraw_mode = multidrawMode; global_settings.angle_depth_clear_fix_mode = angleDepthClearFixMode; global_settings.custom_gl_version = customGLVersion; + global_settings.fsr1_setting = fsr1Setting; #endif std::string draw_mode_str; @@ -215,6 +224,7 @@ void init_settings() { LOG_V("[MobileGlues] Setting: customGLVersion = %s", global_settings.custom_gl_version.toString().c_str()); } + LOG_V("[MobileGlues] Setting: fsr1Setting = %i", static_cast(global_settings.fsr1_setting)) GLVersion = global_settings.custom_gl_version.isEmpty() ? Version(DEFAULT_GL_VERSION) : global_settings.custom_gl_version; } diff --git a/src/main/cpp/config/settings.h b/src/main/cpp/config/settings.h index d229499..516714d 100644 --- a/src/main/cpp/config/settings.h +++ b/src/main/cpp/config/settings.h @@ -137,6 +137,15 @@ struct Version { } }; +typedef enum class FSR1_Quality_Preset : int { // may be useless + Disabled = 0, + UltraQuality, // 1 + Quality, // 2 + Balanced, // 3 + Performance, // 4 + MaxValue // 5 +}; + struct global_settings_t { AngleMode angle; IgnoreErrorLevel ignore_error; @@ -149,6 +158,7 @@ struct global_settings_t { multidraw_mode_t multidraw_mode; AngleDepthClearFixMode angle_depth_clear_fix_mode; Version custom_gl_version; + FSR1_Quality_Preset fsr1_setting; }; extern global_settings_t global_settings; diff --git a/src/main/cpp/egl/egl.cpp b/src/main/cpp/egl/egl.cpp index d4bbb37..537f156 100644 --- a/src/main/cpp/egl/egl.cpp +++ b/src/main/cpp/egl/egl.cpp @@ -7,6 +7,7 @@ #include "../gles/loader.h" #include "../gl/FSR1/FSR1.h" #include "../glx/lookup.h" +#include "../config/settings.h" #define DEBUG 0 @@ -201,10 +202,15 @@ extern "C" { EGL_API EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { LOG_D("eglSwapBuffers, dpy: %p, surface: %p", dpy, surface); - ApplyFSR(); LOAD_EGL(eglSwapBuffers) - EGLBoolean result = egl_eglSwapBuffers(dpy, surface); - CheckResolutionChange(); + EGLBoolean result; + if (global_settings.fsr1_setting != FSR1_Quality_Preset::Disabled) { + ApplyFSR(); + result = egl_eglSwapBuffers(dpy, surface); + CheckResolutionChange(); + } else { + result = egl_eglSwapBuffers(dpy, surface); + } return result; } diff --git a/src/main/cpp/gl/FSR1/FSR1.cpp b/src/main/cpp/gl/FSR1/FSR1.cpp index 3725813..e2f1c0e 100644 --- a/src/main/cpp/gl/FSR1/FSR1.cpp +++ b/src/main/cpp/gl/FSR1/FSR1.cpp @@ -1,5 +1,6 @@ #include "FSR1.h" #include "FSRShaderSource.h" +#include "../../config/settings.h" #define DEBUG 0 @@ -47,6 +48,9 @@ namespace FSR1_Context { GLuint g_quadVAO = 0; GLuint g_quadVBO = 0; GLuint g_fsrProgram = 0; + + GLuint g_targetFBO = 0; + GLuint g_targetTexture = 0; GLuint g_currentDrawFBO = 0; GLint g_viewport[4] = { 0 }; @@ -61,23 +65,16 @@ namespace FSR1_Context { GLsizei g_pendingHeight = 0; } -typedef enum { - FSR_QUALITY_ULTRA_QUALITY = 0, - FSR_QUALITY_QUALITY, - FSR_QUALITY_BALANCED, - FSR_QUALITY_PERFORMANCE -} FSR1_Quality_Preset; - void CalculateTargetResolution(FSR1_Quality_Preset preset, int renderWidth, int renderHeight, int* targetWidth, int* targetHeight) { float scale; switch (preset) { - case FSR_QUALITY_ULTRA_QUALITY: scale = 1.3f; break; - case FSR_QUALITY_QUALITY: scale = 1.5f; break; - case FSR_QUALITY_BALANCED: scale = 1.7f; break; - case FSR_QUALITY_PERFORMANCE: scale = 2.0f; break; + case FSR1_Quality_Preset::UltraQuality: scale = 1.3f; break; + case FSR1_Quality_Preset::Quality: scale = 1.5f; break; + case FSR1_Quality_Preset::Balanced: scale = 1.7f; break; + case FSR1_Quality_Preset::Performance: scale = 2.0f; break; default: scale = 1.5f; break; } @@ -96,16 +93,16 @@ void CalculateRenderResolution(FSR1_Quality_Preset preset, { float scale; switch (preset) { - case FSR_QUALITY_ULTRA_QUALITY: + case FSR1_Quality_Preset::UltraQuality: scale = 1.3f; break; - case FSR_QUALITY_QUALITY: + case FSR1_Quality_Preset::Quality: scale = 1.5f; break; - case FSR_QUALITY_BALANCED: + case FSR1_Quality_Preset::Balanced: scale = 1.7f; break; - case FSR_QUALITY_PERFORMANCE: + case FSR1_Quality_Preset::Performance: scale = 2.0f; break; default: @@ -236,7 +233,22 @@ void InitFSRResources() { GLES.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, FSR1_Context::g_depthStencilRBO); - GLES.glBindFramebuffer(GL_FRAMEBUFFER, FSR1_Context::g_renderFBO); + GLES.glGenTextures(1, &FSR1_Context::g_targetTexture); + GLES.glBindTexture(GL_TEXTURE_2D, FSR1_Context::g_targetTexture); + GLES.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, FSR1_Context::g_targetWidth, FSR1_Context::g_targetHeight, + 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + GLES.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + GLES.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + GLES.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + GLES.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + GLES.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + + GLES.glGenFramebuffers(1, &FSR1_Context::g_targetFBO); + GLES.glBindFramebuffer(GL_FRAMEBUFFER, FSR1_Context::g_targetFBO); + GLES.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, FSR1_Context::g_targetTexture, 0); + + GLES.glBindFramebuffer(GL_FRAMEBUFFER, FSR1_Context::g_renderFBO); } void RecreateFSRFBO() { @@ -245,6 +257,9 @@ void RecreateFSRFBO() { GLES.glDeleteTextures(1, &FSR1_Context::g_renderTexture); GLES.glDeleteRenderbuffers(1, &FSR1_Context::g_depthStencilRBO); + GLES.glDeleteFramebuffers(1, &FSR1_Context::g_targetFBO); + GLES.glDeleteTextures(1, &FSR1_Context::g_targetTexture); + GLES.glGenTextures(1, &FSR1_Context::g_renderTexture); GLES.glBindTexture(GL_TEXTURE_2D, FSR1_Context::g_renderTexture); GLES.glTexImage2D( @@ -272,19 +287,37 @@ void RecreateFSRFBO() { GL_TEXTURE_2D, FSR1_Context::g_renderTexture, 0); GLES.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, FSR1_Context::g_depthStencilRBO); + + GLES.glGenTextures(1, &FSR1_Context::g_targetTexture); + GLES.glBindTexture(GL_TEXTURE_2D, FSR1_Context::g_targetTexture); + GLES.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, FSR1_Context::g_targetWidth, FSR1_Context::g_targetHeight, + 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + GLES.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + GLES.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + GLES.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + GLES.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + GLES.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + + GLES.glGenFramebuffers(1, &FSR1_Context::g_targetFBO); + GLES.glBindFramebuffer(GL_FRAMEBUFFER, FSR1_Context::g_targetFBO); + GLES.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, FSR1_Context::g_targetTexture, 0); + GLES.glBindFramebuffer(GL_FRAMEBUFFER, FSR1_Context::g_renderFBO); GLES.glViewport(0, 0, FSR1_Context::g_renderWidth, FSR1_Context::g_renderHeight); - LOG_D("FSR1 resources recreated: %dx%d", FSR1_Context::g_renderWidth, FSR1_Context::g_renderHeight); + LOG_D("FSR1 resources recreated: render %dx%d, target %dx%d", + FSR1_Context::g_renderWidth, FSR1_Context::g_renderHeight, + FSR1_Context::g_targetWidth, FSR1_Context::g_targetHeight); } std::vector> g_viewportStack; void ApplyFSR() { GLStateGuard state; - GLES.glBindFramebuffer(GL_FRAMEBUFFER, 0); + + GLES.glBindFramebuffer(GL_FRAMEBUFFER, FSR1_Context::g_targetFBO); GLES.glViewport(0, 0, FSR1_Context::g_targetWidth, FSR1_Context::g_targetHeight); - GLES.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); GLES.glClear(GL_COLOR_BUFFER_BIT); @@ -309,12 +342,20 @@ void ApplyFSR() { GLES.glBindVertexArray(FSR1_Context::g_quadVAO); GLES.glDrawArrays(GL_TRIANGLES, 0, 6); GLES.glBindVertexArray(0); + + GLES.glBindFramebuffer(GL_READ_FRAMEBUFFER, FSR1_Context::g_targetFBO); + GLES.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + GLES.glBlitFramebuffer( + 0, 0, FSR1_Context::g_targetWidth, FSR1_Context::g_targetHeight, + 0, 0, FSR1_Context::g_targetWidth, FSR1_Context::g_targetHeight, + GL_COLOR_BUFFER_BIT, GL_LINEAR + ); - GLES.glUseProgram(gl_state->current_program); + GLES.glBindFramebuffer(GL_FRAMEBUFFER, FSR1_Context::g_renderFBO); + GLES.glViewport(0, 0, FSR1_Context::g_renderWidth, FSR1_Context::g_renderHeight); } void CheckResolutionChange() { - /* GLsizei width = 0, height = 0; LOAD_EGL(eglQuerySurface); static EGLDisplay display; @@ -326,22 +367,7 @@ void CheckResolutionChange() { egl_eglQuerySurface(display, surface, EGL_WIDTH, &width); egl_eglQuerySurface(display, surface, EGL_HEIGHT, &height); OnResize(width, height); - */ - //get the biggest viewport size from the stack - //GLsizei width = 0, height = 0; - //for (const auto& vp : g_viewportStack) { - // if (vp.first > width) { - // width = vp.first; - // } - // if (vp.second > height) { - // height = vp.second; - // } - //} - //g_viewportStack.clear(); - //OnResize(width, height); - - - + if (FSR1_Context::g_resolutionChanged) { FSR1_Context::g_resolutionChanged = false; GLsizei width = FSR1_Context::g_pendingWidth; @@ -349,7 +375,7 @@ void CheckResolutionChange() { FSR1_Context::g_renderWidth = width; FSR1_Context::g_renderHeight = height; - CalculateTargetResolution(FSR_QUALITY_QUALITY, + CalculateTargetResolution(global_settings.fsr1_setting, width, height, reinterpret_cast(&FSR1_Context::g_targetWidth), reinterpret_cast(&FSR1_Context::g_targetHeight)); @@ -370,6 +396,12 @@ void OnResize(int width, int height) { void glViewport(GLint x, GLint y, GLsizei w, GLsizei h) { LOG() LOG_D("glViewport: x=%d, y=%d, w=%d, h=%d", x, y, w, h); - g_viewportStack.push_back({ w, h }); + + if (w > FSR1_Context::g_pendingWidth || h > FSR1_Context::g_pendingHeight) { + FSR1_Context::g_pendingWidth = w; + FSR1_Context::g_pendingHeight = h; + FSR1_Context::g_resolutionChanged = true; + } + GLES.glViewport(x, y, w, h); } \ No newline at end of file diff --git a/src/main/cpp/gl/FSR1/FSR1.h b/src/main/cpp/gl/FSR1/FSR1.h index 084c030..a2a48cb 100644 --- a/src/main/cpp/gl/FSR1/FSR1.h +++ b/src/main/cpp/gl/FSR1/FSR1.h @@ -26,6 +26,12 @@ namespace FSR1_Context { extern GLuint g_renderFBO; extern GLuint g_renderTexture; extern GLuint g_depthStencilRBO; + extern GLuint g_quadVAO; + extern GLuint g_quadVBO; + extern GLuint g_fsrProgram; + + extern GLuint g_targetFBO; + extern GLuint g_targetTexture; extern GLuint g_currentDrawFBO; extern GLint g_viewport[4]; @@ -34,6 +40,10 @@ namespace FSR1_Context { extern GLsizei g_renderWidth; extern GLsizei g_renderHeight; extern bool g_dirty; + + extern bool g_resolutionChanged; + extern GLsizei g_pendingWidth; + extern GLsizei g_pendingHeight; } extern bool fsrInitialized; diff --git a/src/main/cpp/gl/shader.cpp b/src/main/cpp/gl/shader.cpp index b071ea2..00a4358 100644 --- a/src/main/cpp/gl/shader.cpp +++ b/src/main/cpp/gl/shader.cpp @@ -125,7 +125,7 @@ void glGetShaderiv(GLuint shader, GLenum pname, GLint *params) { } GLuint glCreateShader(GLenum shaderType) { - if (!fsrInitialized) { + if (global_settings.fsr1_setting != FSR1_Quality_Preset::Disabled && !fsrInitialized) { InitFSRResources(); }