From b90eff4bc666548a77eb58ac152408c80ff952b3 Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sun, 14 Jan 2024 21:11:28 -0500
Subject: [PATCH] renderer_opengl: split out SMAA

---
 src/video_core/CMakeLists.txt                 |   7 +-
 .../renderer_opengl/gl_blit_screen.cpp        |  90 ++-------------
 .../renderer_opengl/gl_blit_screen.h          |  17 +--
 .../{gl_fsr.cpp => present/fsr.cpp}           |   2 +-
 .../{gl_fsr.h => present/fsr.h}               |   0
 .../renderer_opengl/present/smaa.cpp          | 108 ++++++++++++++++++
 src/video_core/renderer_opengl/present/smaa.h |  35 ++++++
 src/video_core/renderer_opengl/present/util.h |  32 ++++++
 .../renderer_opengl/renderer_opengl.cpp       |   1 -
 .../renderer_opengl/renderer_opengl.h         |   1 -
 10 files changed, 197 insertions(+), 96 deletions(-)
 rename src/video_core/renderer_opengl/{gl_fsr.cpp => present/fsr.cpp} (98%)
 rename src/video_core/renderer_opengl/{gl_fsr.h => present/fsr.h} (100%)
 create mode 100644 src/video_core/renderer_opengl/present/smaa.cpp
 create mode 100644 src/video_core/renderer_opengl/present/smaa.h
 create mode 100644 src/video_core/renderer_opengl/present/util.h

diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 825815ebd1..524e2cae81 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -116,6 +116,11 @@ add_library(video_core STATIC
     renderer_null/null_rasterizer.h
     renderer_null/renderer_null.cpp
     renderer_null/renderer_null.h
+    renderer_opengl/present/fsr.cpp
+    renderer_opengl/present/fsr.h
+    renderer_opengl/present/smaa.cpp
+    renderer_opengl/present/smaa.h
+    renderer_opengl/present/util.h
     renderer_opengl/blit_image.cpp
     renderer_opengl/blit_image.h
     renderer_opengl/gl_blit_screen.cpp
@@ -129,8 +134,6 @@ add_library(video_core STATIC
     renderer_opengl/gl_device.h
     renderer_opengl/gl_fence_manager.cpp
     renderer_opengl/gl_fence_manager.h
-    renderer_opengl/gl_fsr.cpp
-    renderer_opengl/gl_fsr.h
     renderer_opengl/gl_graphics_pipeline.cpp
     renderer_opengl/gl_graphics_pipeline.h
     renderer_opengl/gl_rasterizer.cpp
diff --git a/src/video_core/renderer_opengl/gl_blit_screen.cpp b/src/video_core/renderer_opengl/gl_blit_screen.cpp
index 88757ba388..cc343f1713 100644
--- a/src/video_core/renderer_opengl/gl_blit_screen.cpp
+++ b/src/video_core/renderer_opengl/gl_blit_screen.cpp
@@ -13,22 +13,16 @@
 #include "video_core/host_shaders/opengl_present_frag.h"
 #include "video_core/host_shaders/opengl_present_scaleforce_frag.h"
 #include "video_core/host_shaders/opengl_present_vert.h"
-#include "video_core/host_shaders/opengl_smaa_glsl.h"
 #include "video_core/host_shaders/present_bicubic_frag.h"
 #include "video_core/host_shaders/present_gaussian_frag.h"
-#include "video_core/host_shaders/smaa_blending_weight_calculation_frag.h"
-#include "video_core/host_shaders/smaa_blending_weight_calculation_vert.h"
-#include "video_core/host_shaders/smaa_edge_detection_frag.h"
-#include "video_core/host_shaders/smaa_edge_detection_vert.h"
-#include "video_core/host_shaders/smaa_neighborhood_blending_frag.h"
-#include "video_core/host_shaders/smaa_neighborhood_blending_vert.h"
+
 #include "video_core/renderer_opengl/gl_blit_screen.h"
 #include "video_core/renderer_opengl/gl_rasterizer.h"
 #include "video_core/renderer_opengl/gl_shader_manager.h"
 #include "video_core/renderer_opengl/gl_shader_util.h"
 #include "video_core/renderer_opengl/gl_state_tracker.h"
-#include "video_core/smaa_area_tex.h"
-#include "video_core/smaa_search_tex.h"
+#include "video_core/renderer_opengl/present/fsr.h"
+#include "video_core/renderer_opengl/present/smaa.h"
 #include "video_core/textures/decoders.h"
 
 namespace OpenGL {
@@ -84,24 +78,6 @@ BlitScreen::BlitScreen(RasterizerOpenGL& rasterizer_,
         shader_source.replace(pos, include_string.size(), include_content);
     };
 
-    const auto SmaaShader = [&](std::string_view specialized_source, GLenum stage) {
-        std::string shader_source{specialized_source};
-        replace_include(shader_source, "opengl_smaa.glsl", HostShaders::OPENGL_SMAA_GLSL);
-        return CreateProgram(shader_source, stage);
-    };
-
-    smaa_edge_detection_vert = SmaaShader(HostShaders::SMAA_EDGE_DETECTION_VERT, GL_VERTEX_SHADER);
-    smaa_edge_detection_frag =
-        SmaaShader(HostShaders::SMAA_EDGE_DETECTION_FRAG, GL_FRAGMENT_SHADER);
-    smaa_blending_weight_calculation_vert =
-        SmaaShader(HostShaders::SMAA_BLENDING_WEIGHT_CALCULATION_VERT, GL_VERTEX_SHADER);
-    smaa_blending_weight_calculation_frag =
-        SmaaShader(HostShaders::SMAA_BLENDING_WEIGHT_CALCULATION_FRAG, GL_FRAGMENT_SHADER);
-    smaa_neighborhood_blending_vert =
-        SmaaShader(HostShaders::SMAA_NEIGHBORHOOD_BLENDING_VERT, GL_VERTEX_SHADER);
-    smaa_neighborhood_blending_frag =
-        SmaaShader(HostShaders::SMAA_NEIGHBORHOOD_BLENDING_FRAG, GL_FRAGMENT_SHADER);
-
     present_vertex = CreateProgram(HostShaders::OPENGL_PRESENT_VERT, GL_VERTEX_SHADER);
     present_bilinear_fragment = CreateProgram(HostShaders::OPENGL_PRESENT_FRAG, GL_FRAGMENT_SHADER);
     present_bicubic_fragment = CreateProgram(HostShaders::PRESENT_BICUBIC_FRAG, GL_FRAGMENT_SHADER);
@@ -157,15 +133,6 @@ BlitScreen::BlitScreen(RasterizerOpenGL& rasterizer_,
 
     aa_framebuffer.Create();
 
-    smaa_area_tex.Create(GL_TEXTURE_2D);
-    glTextureStorage2D(smaa_area_tex.handle, 1, GL_RG8, AREATEX_WIDTH, AREATEX_HEIGHT);
-    glTextureSubImage2D(smaa_area_tex.handle, 0, 0, 0, AREATEX_WIDTH, AREATEX_HEIGHT, GL_RG,
-                        GL_UNSIGNED_BYTE, areaTexBytes);
-    smaa_search_tex.Create(GL_TEXTURE_2D);
-    glTextureStorage2D(smaa_search_tex.handle, 1, GL_R8, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT);
-    glTextureSubImage2D(smaa_search_tex.handle, 0, 0, 0, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, GL_RED,
-                        GL_UNSIGNED_BYTE, searchTexBytes);
-
     // Enable unified vertex attributes and query vertex buffer address when the driver supports it
     if (device.HasVertexBufferUnifiedMemory()) {
         glEnableClientState(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV);
@@ -176,6 +143,8 @@ BlitScreen::BlitScreen(RasterizerOpenGL& rasterizer_,
     }
 }
 
+BlitScreen::~BlitScreen() = default;
+
 FramebufferTextureInfo BlitScreen::PrepareRenderTarget(
     const Tegra::FramebufferConfig& framebuffer) {
     // If framebuffer is provided, reload it from memory to a texture
@@ -281,16 +250,10 @@ void BlitScreen::ConfigureFramebufferTexture(const Tegra::FramebufferConfig& fra
                        Settings::values.resolution_info.ScaleUp(framebuffer_texture.width),
                        Settings::values.resolution_info.ScaleUp(framebuffer_texture.height));
     glNamedFramebufferTexture(aa_framebuffer.handle, GL_COLOR_ATTACHMENT0, aa_texture.handle, 0);
-    smaa_edges_tex.Release();
-    smaa_edges_tex.Create(GL_TEXTURE_2D);
-    glTextureStorage2D(smaa_edges_tex.handle, 1, GL_RG16F,
-                       Settings::values.resolution_info.ScaleUp(framebuffer_texture.width),
-                       Settings::values.resolution_info.ScaleUp(framebuffer_texture.height));
-    smaa_blend_tex.Release();
-    smaa_blend_tex.Create(GL_TEXTURE_2D);
-    glTextureStorage2D(smaa_blend_tex.handle, 1, GL_RGBA16F,
-                       Settings::values.resolution_info.ScaleUp(framebuffer_texture.width),
-                       Settings::values.resolution_info.ScaleUp(framebuffer_texture.height));
+
+    smaa = std::make_unique<SMAA>(
+        Settings::values.resolution_info.ScaleUp(framebuffer_texture.width),
+        Settings::values.resolution_info.ScaleUp(framebuffer_texture.height));
 }
 
 void BlitScreen::DrawScreen(const Tegra::FramebufferConfig& framebuffer,
@@ -363,39 +326,10 @@ void BlitScreen::DrawScreen(const Tegra::FramebufferConfig& framebuffer,
             program_manager.BindPresentPrograms(fxaa_vertex.handle, fxaa_fragment.handle);
             glBindFramebuffer(GL_DRAW_FRAMEBUFFER, aa_framebuffer.handle);
             glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+            glBindTextureUnit(0, aa_texture.handle);
         } break;
         case Settings::AntiAliasing::Smaa: {
-            glClearColor(0, 0, 0, 0);
-            glFrontFace(GL_CCW);
-            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, aa_framebuffer.handle);
-            glBindSampler(1, present_sampler.handle);
-            glBindSampler(2, present_sampler.handle);
-
-            glNamedFramebufferTexture(aa_framebuffer.handle, GL_COLOR_ATTACHMENT0,
-                                      smaa_edges_tex.handle, 0);
-            glClear(GL_COLOR_BUFFER_BIT);
-            program_manager.BindPresentPrograms(smaa_edge_detection_vert.handle,
-                                                smaa_edge_detection_frag.handle);
-            glDrawArrays(GL_TRIANGLES, 0, 3);
-
-            glBindTextureUnit(0, smaa_edges_tex.handle);
-            glBindTextureUnit(1, smaa_area_tex.handle);
-            glBindTextureUnit(2, smaa_search_tex.handle);
-            glNamedFramebufferTexture(aa_framebuffer.handle, GL_COLOR_ATTACHMENT0,
-                                      smaa_blend_tex.handle, 0);
-            glClear(GL_COLOR_BUFFER_BIT);
-            program_manager.BindPresentPrograms(smaa_blending_weight_calculation_vert.handle,
-                                                smaa_blending_weight_calculation_frag.handle);
-            glDrawArrays(GL_TRIANGLES, 0, 3);
-
-            glBindTextureUnit(0, info.display_texture);
-            glBindTextureUnit(1, smaa_blend_tex.handle);
-            glNamedFramebufferTexture(aa_framebuffer.handle, GL_COLOR_ATTACHMENT0,
-                                      aa_texture.handle, 0);
-            program_manager.BindPresentPrograms(smaa_neighborhood_blending_vert.handle,
-                                                smaa_neighborhood_blending_frag.handle);
-            glDrawArrays(GL_TRIANGLES, 0, 3);
-            glFrontFace(GL_CW);
+            glBindTextureUnit(0, smaa->Draw(program_manager, info.display_texture));
         } break;
         default:
             UNREACHABLE();
@@ -403,8 +337,6 @@ void BlitScreen::DrawScreen(const Tegra::FramebufferConfig& framebuffer,
 
         glBindFramebuffer(GL_READ_FRAMEBUFFER, old_read_fb);
         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw_fb);
-
-        glBindTextureUnit(0, aa_texture.handle);
     }
     glDisablei(GL_SCISSOR_TEST, 0);
 
diff --git a/src/video_core/renderer_opengl/gl_blit_screen.h b/src/video_core/renderer_opengl/gl_blit_screen.h
index 13d769958c..945c7226ac 100644
--- a/src/video_core/renderer_opengl/gl_blit_screen.h
+++ b/src/video_core/renderer_opengl/gl_blit_screen.h
@@ -8,7 +8,6 @@
 
 #include "core/hle/service/nvnflinger/pixel_format.h"
 #include "video_core/host1x/gpu_device_memory_manager.h"
-#include "video_core/renderer_opengl/gl_fsr.h"
 #include "video_core/renderer_opengl/gl_resource_manager.h"
 
 namespace Layout {
@@ -22,7 +21,10 @@ struct FramebufferConfig;
 namespace OpenGL {
 
 class Device;
+class FSR;
+class ProgramManager;
 class RasterizerOpenGL;
+class SMAA;
 class StateTracker;
 
 /// Structure used for storing information about the textures for the Switch screen
@@ -50,6 +52,7 @@ public:
                         Tegra::MaxwellDeviceMemoryManager& device_memory,
                         StateTracker& state_tracker, ProgramManager& program_manager,
                         Device& device);
+    ~BlitScreen();
 
     void ConfigureFramebufferTexture(const Tegra::FramebufferConfig& framebuffer);
 
@@ -87,18 +90,8 @@ private:
     OGLTexture aa_texture;
     OGLFramebuffer aa_framebuffer;
 
-    OGLProgram smaa_edge_detection_vert;
-    OGLProgram smaa_blending_weight_calculation_vert;
-    OGLProgram smaa_neighborhood_blending_vert;
-    OGLProgram smaa_edge_detection_frag;
-    OGLProgram smaa_blending_weight_calculation_frag;
-    OGLProgram smaa_neighborhood_blending_frag;
-    OGLTexture smaa_area_tex;
-    OGLTexture smaa_search_tex;
-    OGLTexture smaa_edges_tex;
-    OGLTexture smaa_blend_tex;
-
     std::unique_ptr<FSR> fsr;
+    std::unique_ptr<SMAA> smaa;
 
     /// OpenGL framebuffer data
     std::vector<u8> gl_framebuffer_data;
diff --git a/src/video_core/renderer_opengl/gl_fsr.cpp b/src/video_core/renderer_opengl/present/fsr.cpp
similarity index 98%
rename from src/video_core/renderer_opengl/gl_fsr.cpp
rename to src/video_core/renderer_opengl/present/fsr.cpp
index 429dcdc6ca..e5945b80bb 100644
--- a/src/video_core/renderer_opengl/gl_fsr.cpp
+++ b/src/video_core/renderer_opengl/present/fsr.cpp
@@ -3,9 +3,9 @@
 
 #include "common/settings.h"
 #include "video_core/fsr.h"
-#include "video_core/renderer_opengl/gl_fsr.h"
 #include "video_core/renderer_opengl/gl_shader_manager.h"
 #include "video_core/renderer_opengl/gl_shader_util.h"
+#include "video_core/renderer_opengl/present/fsr.h"
 
 namespace OpenGL {
 using namespace FSR;
diff --git a/src/video_core/renderer_opengl/gl_fsr.h b/src/video_core/renderer_opengl/present/fsr.h
similarity index 100%
rename from src/video_core/renderer_opengl/gl_fsr.h
rename to src/video_core/renderer_opengl/present/fsr.h
diff --git a/src/video_core/renderer_opengl/present/smaa.cpp b/src/video_core/renderer_opengl/present/smaa.cpp
new file mode 100644
index 0000000000..a9a0eb6c69
--- /dev/null
+++ b/src/video_core/renderer_opengl/present/smaa.cpp
@@ -0,0 +1,108 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "video_core/host_shaders/opengl_smaa_glsl.h"
+#include "video_core/host_shaders/smaa_blending_weight_calculation_frag.h"
+#include "video_core/host_shaders/smaa_blending_weight_calculation_vert.h"
+#include "video_core/host_shaders/smaa_edge_detection_frag.h"
+#include "video_core/host_shaders/smaa_edge_detection_vert.h"
+#include "video_core/host_shaders/smaa_neighborhood_blending_frag.h"
+#include "video_core/host_shaders/smaa_neighborhood_blending_vert.h"
+#include "video_core/renderer_opengl/gl_shader_manager.h"
+#include "video_core/renderer_opengl/gl_shader_util.h"
+#include "video_core/renderer_opengl/present/smaa.h"
+#include "video_core/renderer_opengl/present/util.h"
+#include "video_core/smaa_area_tex.h"
+#include "video_core/smaa_search_tex.h"
+
+namespace OpenGL {
+
+SMAA::SMAA(u32 width, u32 height) {
+    const auto SmaaShader = [&](std::string_view specialized_source, GLenum stage) {
+        std::string shader_source{specialized_source};
+        ReplaceInclude(shader_source, "opengl_smaa.glsl", HostShaders::OPENGL_SMAA_GLSL);
+        return CreateProgram(shader_source, stage);
+    };
+
+    edge_detection_vert = SmaaShader(HostShaders::SMAA_EDGE_DETECTION_VERT, GL_VERTEX_SHADER);
+    edge_detection_frag = SmaaShader(HostShaders::SMAA_EDGE_DETECTION_FRAG, GL_FRAGMENT_SHADER);
+    blending_weight_calculation_vert =
+        SmaaShader(HostShaders::SMAA_BLENDING_WEIGHT_CALCULATION_VERT, GL_VERTEX_SHADER);
+    blending_weight_calculation_frag =
+        SmaaShader(HostShaders::SMAA_BLENDING_WEIGHT_CALCULATION_FRAG, GL_FRAGMENT_SHADER);
+    neighborhood_blending_vert =
+        SmaaShader(HostShaders::SMAA_NEIGHBORHOOD_BLENDING_VERT, GL_VERTEX_SHADER);
+    neighborhood_blending_frag =
+        SmaaShader(HostShaders::SMAA_NEIGHBORHOOD_BLENDING_FRAG, GL_FRAGMENT_SHADER);
+
+    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+    glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
+    glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
+    glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+    glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
+    glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+    glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+    area_tex.Create(GL_TEXTURE_2D);
+    glTextureStorage2D(area_tex.handle, 1, GL_RG8, AREATEX_WIDTH, AREATEX_HEIGHT);
+    glTextureSubImage2D(area_tex.handle, 0, 0, 0, AREATEX_WIDTH, AREATEX_HEIGHT, GL_RG,
+                        GL_UNSIGNED_BYTE, areaTexBytes);
+    search_tex.Create(GL_TEXTURE_2D);
+    glTextureStorage2D(search_tex.handle, 1, GL_R8, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT);
+    glTextureSubImage2D(search_tex.handle, 0, 0, 0, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, GL_RED,
+                        GL_UNSIGNED_BYTE, searchTexBytes);
+
+    edges_tex.Create(GL_TEXTURE_2D);
+    glTextureStorage2D(edges_tex.handle, 1, GL_RG16F, width, height);
+
+    blend_tex.Create(GL_TEXTURE_2D);
+    glTextureStorage2D(blend_tex.handle, 1, GL_RGBA16F, width, height);
+
+    sampler = CreateBilinearSampler();
+
+    framebuffer.Create();
+
+    texture.Create(GL_TEXTURE_2D);
+    glTextureStorage2D(texture.handle, 1, GL_RGBA16F, width, height);
+    glNamedFramebufferTexture(framebuffer.handle, GL_COLOR_ATTACHMENT0, texture.handle, 0);
+}
+
+SMAA::~SMAA() = default;
+
+GLuint SMAA::Draw(ProgramManager& program_manager, GLuint input_texture) {
+    glClearColor(0, 0, 0, 0);
+    glFrontFace(GL_CCW);
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.handle);
+    glBindSampler(0, sampler.handle);
+    glBindSampler(1, sampler.handle);
+    glBindSampler(2, sampler.handle);
+
+    glBindTextureUnit(0, input_texture);
+    glNamedFramebufferTexture(framebuffer.handle, GL_COLOR_ATTACHMENT0, edges_tex.handle, 0);
+    glClear(GL_COLOR_BUFFER_BIT);
+    program_manager.BindPresentPrograms(edge_detection_vert.handle, edge_detection_frag.handle);
+    glDrawArrays(GL_TRIANGLES, 0, 3);
+
+    glBindTextureUnit(0, edges_tex.handle);
+    glBindTextureUnit(1, area_tex.handle);
+    glBindTextureUnit(2, search_tex.handle);
+    glNamedFramebufferTexture(framebuffer.handle, GL_COLOR_ATTACHMENT0, blend_tex.handle, 0);
+    glClear(GL_COLOR_BUFFER_BIT);
+    program_manager.BindPresentPrograms(blending_weight_calculation_vert.handle,
+                                        blending_weight_calculation_frag.handle);
+    glDrawArrays(GL_TRIANGLES, 0, 3);
+
+    glBindTextureUnit(0, input_texture);
+    glBindTextureUnit(1, blend_tex.handle);
+    glNamedFramebufferTexture(framebuffer.handle, GL_COLOR_ATTACHMENT0, texture.handle, 0);
+    program_manager.BindPresentPrograms(neighborhood_blending_vert.handle,
+                                        neighborhood_blending_frag.handle);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glDrawArrays(GL_TRIANGLES, 0, 3);
+    glFrontFace(GL_CW);
+
+    return texture.handle;
+}
+
+} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/present/smaa.h b/src/video_core/renderer_opengl/present/smaa.h
new file mode 100644
index 0000000000..a48cb4fa9c
--- /dev/null
+++ b/src/video_core/renderer_opengl/present/smaa.h
@@ -0,0 +1,35 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "video_core/renderer_opengl/gl_resource_manager.h"
+
+namespace OpenGL {
+
+class ProgramManager;
+
+class SMAA {
+public:
+    explicit SMAA(u32 width, u32 height);
+    ~SMAA();
+
+    GLuint Draw(ProgramManager& program_manager, GLuint input_texture);
+
+private:
+    OGLProgram edge_detection_vert;
+    OGLProgram blending_weight_calculation_vert;
+    OGLProgram neighborhood_blending_vert;
+    OGLProgram edge_detection_frag;
+    OGLProgram blending_weight_calculation_frag;
+    OGLProgram neighborhood_blending_frag;
+    OGLTexture area_tex;
+    OGLTexture search_tex;
+    OGLTexture edges_tex;
+    OGLTexture blend_tex;
+    OGLSampler sampler;
+    OGLFramebuffer framebuffer;
+    OGLTexture texture;
+};
+
+} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/present/util.h b/src/video_core/renderer_opengl/present/util.h
new file mode 100644
index 0000000000..0aa8b110c1
--- /dev/null
+++ b/src/video_core/renderer_opengl/present/util.h
@@ -0,0 +1,32 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <string>
+
+#include "common/assert.h"
+#include "video_core/renderer_opengl/gl_resource_manager.h"
+
+namespace OpenGL {
+
+static inline void ReplaceInclude(std::string& shader_source, std::string_view include_name,
+                                  std::string_view include_content) {
+    const std::string include_string = fmt::format("#include \"{}\"", include_name);
+    const std::size_t pos = shader_source.find(include_string);
+    ASSERT(pos != std::string::npos);
+    shader_source.replace(pos, include_string.size(), include_content);
+};
+
+static inline OGLSampler CreateBilinearSampler() {
+    OGLSampler sampler;
+    sampler.Create();
+    glSamplerParameteri(sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glSamplerParameteri(sampler.handle, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glSamplerParameteri(sampler.handle, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glSamplerParameteri(sampler.handle, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glSamplerParameteri(sampler.handle, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+    return sampler;
+}
+
+} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 38b0aacf47..3d75fd17a3 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -17,7 +17,6 @@
 #include "core/frontend/emu_window.h"
 #include "core/telemetry_session.h"
 #include "video_core/renderer_opengl/gl_blit_screen.h"
-#include "video_core/renderer_opengl/gl_fsr.h"
 #include "video_core/renderer_opengl/gl_rasterizer.h"
 #include "video_core/renderer_opengl/gl_shader_manager.h"
 #include "video_core/renderer_opengl/gl_shader_util.h"
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 23aff055aa..7ab1633722 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -10,7 +10,6 @@
 
 #include "video_core/renderer_base.h"
 #include "video_core/renderer_opengl/gl_device.h"
-#include "video_core/renderer_opengl/gl_fsr.h"
 #include "video_core/renderer_opengl/gl_rasterizer.h"
 #include "video_core/renderer_opengl/gl_resource_manager.h"
 #include "video_core/renderer_opengl/gl_shader_manager.h"