diff options
| author | Liam <byteslice@airmail.cc> | 2024-01-15 14:28:03 -0500 | 
|---|---|---|
| committer | Liam <byteslice@airmail.cc> | 2024-01-31 11:27:21 -0500 | 
| commit | dd2918efd83b586861ebc463dfee20c35e9d3bb3 (patch) | |
| tree | 7c3e814d9ff1b26741a823dbc285877f49e7e57a | |
| parent | 2ed9586130a7b1de6aefc2aede464c4d3430d484 (diff) | |
renderer_opengl: move out ownership of FSR resources
| -rw-r--r-- | src/video_core/renderer_opengl/gl_blit_screen.cpp | 35 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/present/fsr.cpp | 110 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/present/fsr.h | 29 | 
3 files changed, 74 insertions, 100 deletions
diff --git a/src/video_core/renderer_opengl/gl_blit_screen.cpp b/src/video_core/renderer_opengl/gl_blit_screen.cpp index 4e9d80d10..5f6221b9b 100644 --- a/src/video_core/renderer_opengl/gl_blit_screen.cpp +++ b/src/video_core/renderer_opengl/gl_blit_screen.cpp @@ -75,8 +75,6 @@ BlitScreen::BlitScreen(RasterizerOpenGL& rasterizer_,          CreateProgram(fmt::format("#version 460\n{}", HostShaders::OPENGL_PRESENT_SCALEFORCE_FRAG),                        GL_FRAGMENT_SHADER); -    fsr = std::make_unique<FSR>(); -      // Generate presentation sampler      present_sampler.Create();      glSamplerParameteri(present_sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -269,7 +267,7 @@ void BlitScreen::DrawScreen(const Tegra::FramebufferConfig& framebuffer,      glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);      glDepthRangeIndexed(0, 0.0, 0.0); -    glBindTextureUnit(0, info.display_texture); +    GLuint texture = info.display_texture;      auto anti_aliasing = Settings::values.anti_aliasing.GetValue();      if (anti_aliasing >= Settings::AntiAliasing::MaxEnum) { @@ -296,10 +294,10 @@ void BlitScreen::DrawScreen(const Tegra::FramebufferConfig& framebuffer,          switch (anti_aliasing) {          case Settings::AntiAliasing::Fxaa: { -            glBindTextureUnit(0, fxaa->Draw(program_manager, info.display_texture)); +            texture = fxaa->Draw(program_manager, info.display_texture);          } break;          case Settings::AntiAliasing::Smaa: { -            glBindTextureUnit(0, smaa->Draw(program_manager, info.display_texture)); +            texture = smaa->Draw(program_manager, info.display_texture);          } break;          default:              UNREACHABLE(); @@ -311,34 +309,37 @@ void BlitScreen::DrawScreen(const Tegra::FramebufferConfig& framebuffer,      glDisablei(GL_SCISSOR_TEST, 0);      if (Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::Fsr) { -        if (!fsr->AreBuffersInitialized()) { -            fsr->InitBuffers(); -        } +        GLint old_read_fb; +        GLint old_draw_fb; +        glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &old_read_fb); +        glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw_fb); -        glBindSampler(0, present_sampler.handle); -        fsr->Draw(program_manager, layout.screen, info.scaled_width, info.scaled_height, crop); -    } else { -        if (fsr->AreBuffersInitialized()) { -            fsr->ReleaseBuffers(); +        if (!fsr || fsr->NeedsRecreation(layout.screen)) { +            fsr = std::make_unique<FSR>(layout.screen.GetWidth(), layout.screen.GetHeight());          } + +        texture = fsr->Draw(program_manager, texture, info.scaled_width, info.scaled_height, crop); + +        glBindFramebuffer(GL_READ_FRAMEBUFFER, old_read_fb); +        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw_fb);      } +    glBindTextureUnit(0, texture); +      const std::array ortho_matrix =          MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height));      const auto fragment_handle = [this]() {          switch (Settings::values.scaling_filter.GetValue()) { -        case Settings::ScalingFilter::NearestNeighbor: -        case Settings::ScalingFilter::Bilinear: -            return present_bilinear_fragment.handle;          case Settings::ScalingFilter::Bicubic:              return present_bicubic_fragment.handle;          case Settings::ScalingFilter::Gaussian:              return present_gaussian_fragment.handle;          case Settings::ScalingFilter::ScaleForce:              return present_scaleforce_fragment.handle; +        case Settings::ScalingFilter::NearestNeighbor: +        case Settings::ScalingFilter::Bilinear:          case Settings::ScalingFilter::Fsr: -            return fsr->GetPresentFragmentProgram().handle;          default:              return present_bilinear_fragment.handle;          } diff --git a/src/video_core/renderer_opengl/present/fsr.cpp b/src/video_core/renderer_opengl/present/fsr.cpp index a5540bb0c..b764aadae 100644 --- a/src/video_core/renderer_opengl/present/fsr.cpp +++ b/src/video_core/renderer_opengl/present/fsr.cpp @@ -19,7 +19,7 @@ using namespace FSR;  using FsrConstants = std::array<u32, 4 * 4>; -FSR::FSR() { +FSR::FSR(u32 output_width_, u32 output_height_) : width(output_width_), height(output_height_) {      std::string fsr_source{HostShaders::OPENGL_FIDELITYFX_FSR_FRAG};      ReplaceInclude(fsr_source, "ffx_a.h", HostShaders::FFX_A_H);      ReplaceInclude(fsr_source, "ffx_fsr1.h", HostShaders::FFX_FSR1_H); @@ -29,94 +29,70 @@ FSR::FSR() {      ReplaceInclude(fsr_easu_source, "opengl_fidelityfx_fsr.frag", fsr_source);      ReplaceInclude(fsr_rcas_source, "opengl_fidelityfx_fsr.frag", fsr_source); -    fsr_vertex = CreateProgram(HostShaders::FULL_SCREEN_TRIANGLE_VERT, GL_VERTEX_SHADER); -    fsr_easu_frag = CreateProgram(fsr_easu_source, GL_FRAGMENT_SHADER); -    fsr_rcas_frag = CreateProgram(fsr_rcas_source, GL_FRAGMENT_SHADER); +    vert = CreateProgram(HostShaders::FULL_SCREEN_TRIANGLE_VERT, GL_VERTEX_SHADER); +    easu_frag = CreateProgram(fsr_easu_source, GL_FRAGMENT_SHADER); +    rcas_frag = CreateProgram(fsr_rcas_source, GL_FRAGMENT_SHADER); -    glProgramUniform2f(fsr_vertex.handle, 0, 1.0f, 1.0f); -    glProgramUniform2f(fsr_vertex.handle, 1, 0.0f, 0.0f); -} +    glProgramUniform2f(vert.handle, 0, 1.0f, -1.0f); +    glProgramUniform2f(vert.handle, 1, 0.0f, 1.0f); -FSR::~FSR() = default; +    sampler = CreateBilinearSampler(); +    framebuffer.Create(); -void FSR::Draw(ProgramManager& program_manager, const Common::Rectangle<u32>& screen, -               u32 input_image_width, u32 input_image_height, -               const Common::Rectangle<f32>& crop_rect) { - -    const auto output_image_width = screen.GetWidth(); -    const auto output_image_height = screen.GetHeight(); - -    if (fsr_intermediate_tex.handle) { -        GLint fsr_tex_width, fsr_tex_height; -        glGetTextureLevelParameteriv(fsr_intermediate_tex.handle, 0, GL_TEXTURE_WIDTH, -                                     &fsr_tex_width); -        glGetTextureLevelParameteriv(fsr_intermediate_tex.handle, 0, GL_TEXTURE_HEIGHT, -                                     &fsr_tex_height); -        if (static_cast<u32>(fsr_tex_width) != output_image_width || -            static_cast<u32>(fsr_tex_height) != output_image_height) { -            fsr_intermediate_tex.Release(); -        } -    } -    if (!fsr_intermediate_tex.handle) { -        fsr_intermediate_tex.Create(GL_TEXTURE_2D); -        glTextureStorage2D(fsr_intermediate_tex.handle, 1, GL_RGB16F, output_image_width, -                           output_image_height); -        glNamedFramebufferTexture(fsr_framebuffer.handle, GL_COLOR_ATTACHMENT0, -                                  fsr_intermediate_tex.handle, 0); -    } - -    GLint old_draw_fb; -    glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw_fb); +    easu_tex.Create(GL_TEXTURE_2D); +    glTextureStorage2D(easu_tex.handle, 1, GL_RGBA16F, width, height); -    glFrontFace(GL_CW); -    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fsr_framebuffer.handle); -    glViewportIndexedf(0, 0.0f, 0.0f, static_cast<GLfloat>(output_image_width), -                       static_cast<GLfloat>(output_image_height)); +    rcas_tex.Create(GL_TEXTURE_2D); +    glTextureStorage2D(rcas_tex.handle, 1, GL_RGBA16F, width, height); +} +FSR::~FSR() = default; + +GLuint FSR::Draw(ProgramManager& program_manager, GLuint texture, u32 input_image_width, +                 u32 input_image_height, const Common::Rectangle<f32>& crop_rect) {      const f32 input_width = static_cast<f32>(input_image_width);      const f32 input_height = static_cast<f32>(input_image_height); -    const f32 output_width = static_cast<f32>(screen.GetWidth()); -    const f32 output_height = static_cast<f32>(screen.GetHeight()); +    const f32 output_width = static_cast<f32>(width); +    const f32 output_height = static_cast<f32>(height);      const f32 viewport_width = (crop_rect.right - crop_rect.left) * input_width;      const f32 viewport_x = crop_rect.left * input_width;      const f32 viewport_height = (crop_rect.bottom - crop_rect.top) * input_height;      const f32 viewport_y = crop_rect.top * input_height; -    FsrConstants constants; -    FsrEasuConOffset(constants.data() + 0, constants.data() + 4, constants.data() + 8, -                     constants.data() + 12, viewport_width, viewport_height, input_width, -                     input_height, output_width, output_height, viewport_x, viewport_y); - -    glProgramUniform4uiv(fsr_easu_frag.handle, 0, sizeof(constants), std::data(constants)); - -    program_manager.BindPresentPrograms(fsr_vertex.handle, fsr_easu_frag.handle); -    glDrawArrays(GL_TRIANGLES, 0, 3); +    FsrConstants easu_con{}; +    FsrConstants rcas_con{}; -    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw_fb); -    glBindTextureUnit(0, fsr_intermediate_tex.handle); +    FsrEasuConOffset(easu_con.data() + 0, easu_con.data() + 4, easu_con.data() + 8, +                     easu_con.data() + 12, viewport_width, viewport_height, input_width, +                     input_height, output_width, output_height, viewport_x, viewport_y);      const float sharpening =          static_cast<float>(Settings::values.fsr_sharpening_slider.GetValue()) / 100.0f; -    FsrRcasCon(constants.data(), sharpening); -    glProgramUniform4uiv(fsr_rcas_frag.handle, 0, sizeof(constants), std::data(constants)); -} +    FsrRcasCon(rcas_con.data(), sharpening); -void FSR::InitBuffers() { -    fsr_framebuffer.Create(); -} +    glProgramUniform4uiv(easu_frag.handle, 0, sizeof(easu_con), easu_con.data()); +    glProgramUniform4uiv(rcas_frag.handle, 0, sizeof(rcas_con), rcas_con.data()); -void FSR::ReleaseBuffers() { -    fsr_framebuffer.Release(); -    fsr_intermediate_tex.Release(); -} +    glFrontFace(GL_CW); +    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.handle); +    glNamedFramebufferTexture(framebuffer.handle, GL_COLOR_ATTACHMENT0, easu_tex.handle, 0); +    glViewportIndexedf(0, 0.0f, 0.0f, output_width, output_height); +    program_manager.BindPresentPrograms(vert.handle, easu_frag.handle); +    glBindTextureUnit(0, texture); +    glBindSampler(0, sampler.handle); +    glDrawArrays(GL_TRIANGLES, 0, 3); + +    glNamedFramebufferTexture(framebuffer.handle, GL_COLOR_ATTACHMENT0, rcas_tex.handle, 0); +    program_manager.BindPresentPrograms(vert.handle, rcas_frag.handle); +    glBindTextureUnit(0, easu_tex.handle); +    glDrawArrays(GL_TRIANGLES, 0, 3); -const OGLProgram& FSR::GetPresentFragmentProgram() const noexcept { -    return fsr_rcas_frag; +    return rcas_tex.handle;  } -bool FSR::AreBuffersInitialized() const noexcept { -    return fsr_framebuffer.handle; +bool FSR::NeedsRecreation(const Common::Rectangle<u32>& screen) { +    return screen.GetWidth() != width || screen.GetHeight() != height;  }  } // namespace OpenGL diff --git a/src/video_core/renderer_opengl/present/fsr.h b/src/video_core/renderer_opengl/present/fsr.h index fa57c6f00..606935a01 100644 --- a/src/video_core/renderer_opengl/present/fsr.h +++ b/src/video_core/renderer_opengl/present/fsr.h @@ -16,27 +16,24 @@ class ProgramManager;  class FSR {  public: -    explicit FSR(); +    explicit FSR(u32 output_width, u32 output_height);      ~FSR(); -    void Draw(ProgramManager& program_manager, const Common::Rectangle<u32>& screen, -              u32 input_image_width, u32 input_image_height, -              const Common::Rectangle<f32>& crop_rect); +    GLuint Draw(ProgramManager& program_manager, GLuint texture, u32 input_image_width, +                u32 input_image_height, const Common::Rectangle<f32>& crop_rect); -    void InitBuffers(); - -    void ReleaseBuffers(); - -    [[nodiscard]] const OGLProgram& GetPresentFragmentProgram() const noexcept; - -    [[nodiscard]] bool AreBuffersInitialized() const noexcept; +    bool NeedsRecreation(const Common::Rectangle<u32>& screen);  private: -    OGLFramebuffer fsr_framebuffer; -    OGLProgram fsr_vertex; -    OGLProgram fsr_easu_frag; -    OGLProgram fsr_rcas_frag; -    OGLTexture fsr_intermediate_tex; +    const u32 width; +    const u32 height; +    OGLFramebuffer framebuffer; +    OGLSampler sampler; +    OGLProgram vert; +    OGLProgram easu_frag; +    OGLProgram rcas_frag; +    OGLTexture easu_tex; +    OGLTexture rcas_tex;  };  } // namespace OpenGL  | 
