diff options
| author | 2024-01-15 14:28:03 -0500 | |
|---|---|---|
| committer | 2024-01-31 11:27:21 -0500 | |
| commit | dd2918efd83b586861ebc463dfee20c35e9d3bb3 (patch) | |
| tree | 7c3e814d9ff1b26741a823dbc285877f49e7e57a /src/video_core | |
| parent | renderer_vulkan: convert FSR to graphics pipeline (diff) | |
| download | yuzu-dd2918efd83b586861ebc463dfee20c35e9d3bb3.tar.gz yuzu-dd2918efd83b586861ebc463dfee20c35e9d3bb3.tar.xz yuzu-dd2918efd83b586861ebc463dfee20c35e9d3bb3.zip | |
renderer_opengl: move out ownership of FSR resources
Diffstat (limited to 'src/video_core')
| -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_, | |||
| 75 | CreateProgram(fmt::format("#version 460\n{}", HostShaders::OPENGL_PRESENT_SCALEFORCE_FRAG), | 75 | CreateProgram(fmt::format("#version 460\n{}", HostShaders::OPENGL_PRESENT_SCALEFORCE_FRAG), |
| 76 | GL_FRAGMENT_SHADER); | 76 | GL_FRAGMENT_SHADER); |
| 77 | 77 | ||
| 78 | fsr = std::make_unique<FSR>(); | ||
| 79 | |||
| 80 | // Generate presentation sampler | 78 | // Generate presentation sampler |
| 81 | present_sampler.Create(); | 79 | present_sampler.Create(); |
| 82 | glSamplerParameteri(present_sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 80 | glSamplerParameteri(present_sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| @@ -269,7 +267,7 @@ void BlitScreen::DrawScreen(const Tegra::FramebufferConfig& framebuffer, | |||
| 269 | glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | 267 | glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
| 270 | glDepthRangeIndexed(0, 0.0, 0.0); | 268 | glDepthRangeIndexed(0, 0.0, 0.0); |
| 271 | 269 | ||
| 272 | glBindTextureUnit(0, info.display_texture); | 270 | GLuint texture = info.display_texture; |
| 273 | 271 | ||
| 274 | auto anti_aliasing = Settings::values.anti_aliasing.GetValue(); | 272 | auto anti_aliasing = Settings::values.anti_aliasing.GetValue(); |
| 275 | if (anti_aliasing >= Settings::AntiAliasing::MaxEnum) { | 273 | if (anti_aliasing >= Settings::AntiAliasing::MaxEnum) { |
| @@ -296,10 +294,10 @@ void BlitScreen::DrawScreen(const Tegra::FramebufferConfig& framebuffer, | |||
| 296 | 294 | ||
| 297 | switch (anti_aliasing) { | 295 | switch (anti_aliasing) { |
| 298 | case Settings::AntiAliasing::Fxaa: { | 296 | case Settings::AntiAliasing::Fxaa: { |
| 299 | glBindTextureUnit(0, fxaa->Draw(program_manager, info.display_texture)); | 297 | texture = fxaa->Draw(program_manager, info.display_texture); |
| 300 | } break; | 298 | } break; |
| 301 | case Settings::AntiAliasing::Smaa: { | 299 | case Settings::AntiAliasing::Smaa: { |
| 302 | glBindTextureUnit(0, smaa->Draw(program_manager, info.display_texture)); | 300 | texture = smaa->Draw(program_manager, info.display_texture); |
| 303 | } break; | 301 | } break; |
| 304 | default: | 302 | default: |
| 305 | UNREACHABLE(); | 303 | UNREACHABLE(); |
| @@ -311,34 +309,37 @@ void BlitScreen::DrawScreen(const Tegra::FramebufferConfig& framebuffer, | |||
| 311 | glDisablei(GL_SCISSOR_TEST, 0); | 309 | glDisablei(GL_SCISSOR_TEST, 0); |
| 312 | 310 | ||
| 313 | if (Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::Fsr) { | 311 | if (Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::Fsr) { |
| 314 | if (!fsr->AreBuffersInitialized()) { | 312 | GLint old_read_fb; |
| 315 | fsr->InitBuffers(); | 313 | GLint old_draw_fb; |
| 316 | } | 314 | glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &old_read_fb); |
| 315 | glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw_fb); | ||
| 317 | 316 | ||
| 318 | glBindSampler(0, present_sampler.handle); | 317 | if (!fsr || fsr->NeedsRecreation(layout.screen)) { |
| 319 | fsr->Draw(program_manager, layout.screen, info.scaled_width, info.scaled_height, crop); | 318 | fsr = std::make_unique<FSR>(layout.screen.GetWidth(), layout.screen.GetHeight()); |
| 320 | } else { | ||
| 321 | if (fsr->AreBuffersInitialized()) { | ||
| 322 | fsr->ReleaseBuffers(); | ||
| 323 | } | 319 | } |
| 320 | |||
| 321 | texture = fsr->Draw(program_manager, texture, info.scaled_width, info.scaled_height, crop); | ||
| 322 | |||
| 323 | glBindFramebuffer(GL_READ_FRAMEBUFFER, old_read_fb); | ||
| 324 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw_fb); | ||
| 324 | } | 325 | } |
| 325 | 326 | ||
| 327 | glBindTextureUnit(0, texture); | ||
| 328 | |||
| 326 | const std::array ortho_matrix = | 329 | const std::array ortho_matrix = |
| 327 | MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); | 330 | MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); |
| 328 | 331 | ||
| 329 | const auto fragment_handle = [this]() { | 332 | const auto fragment_handle = [this]() { |
| 330 | switch (Settings::values.scaling_filter.GetValue()) { | 333 | switch (Settings::values.scaling_filter.GetValue()) { |
| 331 | case Settings::ScalingFilter::NearestNeighbor: | ||
| 332 | case Settings::ScalingFilter::Bilinear: | ||
| 333 | return present_bilinear_fragment.handle; | ||
| 334 | case Settings::ScalingFilter::Bicubic: | 334 | case Settings::ScalingFilter::Bicubic: |
| 335 | return present_bicubic_fragment.handle; | 335 | return present_bicubic_fragment.handle; |
| 336 | case Settings::ScalingFilter::Gaussian: | 336 | case Settings::ScalingFilter::Gaussian: |
| 337 | return present_gaussian_fragment.handle; | 337 | return present_gaussian_fragment.handle; |
| 338 | case Settings::ScalingFilter::ScaleForce: | 338 | case Settings::ScalingFilter::ScaleForce: |
| 339 | return present_scaleforce_fragment.handle; | 339 | return present_scaleforce_fragment.handle; |
| 340 | case Settings::ScalingFilter::NearestNeighbor: | ||
| 341 | case Settings::ScalingFilter::Bilinear: | ||
| 340 | case Settings::ScalingFilter::Fsr: | 342 | case Settings::ScalingFilter::Fsr: |
| 341 | return fsr->GetPresentFragmentProgram().handle; | ||
| 342 | default: | 343 | default: |
| 343 | return present_bilinear_fragment.handle; | 344 | return present_bilinear_fragment.handle; |
| 344 | } | 345 | } |
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; | |||
| 19 | 19 | ||
| 20 | using FsrConstants = std::array<u32, 4 * 4>; | 20 | using FsrConstants = std::array<u32, 4 * 4>; |
| 21 | 21 | ||
| 22 | FSR::FSR() { | 22 | FSR::FSR(u32 output_width_, u32 output_height_) : width(output_width_), height(output_height_) { |
| 23 | std::string fsr_source{HostShaders::OPENGL_FIDELITYFX_FSR_FRAG}; | 23 | std::string fsr_source{HostShaders::OPENGL_FIDELITYFX_FSR_FRAG}; |
| 24 | ReplaceInclude(fsr_source, "ffx_a.h", HostShaders::FFX_A_H); | 24 | ReplaceInclude(fsr_source, "ffx_a.h", HostShaders::FFX_A_H); |
| 25 | ReplaceInclude(fsr_source, "ffx_fsr1.h", HostShaders::FFX_FSR1_H); | 25 | ReplaceInclude(fsr_source, "ffx_fsr1.h", HostShaders::FFX_FSR1_H); |
| @@ -29,94 +29,70 @@ FSR::FSR() { | |||
| 29 | ReplaceInclude(fsr_easu_source, "opengl_fidelityfx_fsr.frag", fsr_source); | 29 | ReplaceInclude(fsr_easu_source, "opengl_fidelityfx_fsr.frag", fsr_source); |
| 30 | ReplaceInclude(fsr_rcas_source, "opengl_fidelityfx_fsr.frag", fsr_source); | 30 | ReplaceInclude(fsr_rcas_source, "opengl_fidelityfx_fsr.frag", fsr_source); |
| 31 | 31 | ||
| 32 | fsr_vertex = CreateProgram(HostShaders::FULL_SCREEN_TRIANGLE_VERT, GL_VERTEX_SHADER); | 32 | vert = CreateProgram(HostShaders::FULL_SCREEN_TRIANGLE_VERT, GL_VERTEX_SHADER); |
| 33 | fsr_easu_frag = CreateProgram(fsr_easu_source, GL_FRAGMENT_SHADER); | 33 | easu_frag = CreateProgram(fsr_easu_source, GL_FRAGMENT_SHADER); |
| 34 | fsr_rcas_frag = CreateProgram(fsr_rcas_source, GL_FRAGMENT_SHADER); | 34 | rcas_frag = CreateProgram(fsr_rcas_source, GL_FRAGMENT_SHADER); |
| 35 | 35 | ||
| 36 | glProgramUniform2f(fsr_vertex.handle, 0, 1.0f, 1.0f); | 36 | glProgramUniform2f(vert.handle, 0, 1.0f, -1.0f); |
| 37 | glProgramUniform2f(fsr_vertex.handle, 1, 0.0f, 0.0f); | 37 | glProgramUniform2f(vert.handle, 1, 0.0f, 1.0f); |
| 38 | } | ||
| 39 | 38 | ||
| 40 | FSR::~FSR() = default; | 39 | sampler = CreateBilinearSampler(); |
| 40 | framebuffer.Create(); | ||
| 41 | 41 | ||
| 42 | void FSR::Draw(ProgramManager& program_manager, const Common::Rectangle<u32>& screen, | 42 | easu_tex.Create(GL_TEXTURE_2D); |
| 43 | u32 input_image_width, u32 input_image_height, | 43 | glTextureStorage2D(easu_tex.handle, 1, GL_RGBA16F, width, height); |
| 44 | const Common::Rectangle<f32>& crop_rect) { | ||
| 45 | |||
| 46 | const auto output_image_width = screen.GetWidth(); | ||
| 47 | const auto output_image_height = screen.GetHeight(); | ||
| 48 | |||
| 49 | if (fsr_intermediate_tex.handle) { | ||
| 50 | GLint fsr_tex_width, fsr_tex_height; | ||
| 51 | glGetTextureLevelParameteriv(fsr_intermediate_tex.handle, 0, GL_TEXTURE_WIDTH, | ||
| 52 | &fsr_tex_width); | ||
| 53 | glGetTextureLevelParameteriv(fsr_intermediate_tex.handle, 0, GL_TEXTURE_HEIGHT, | ||
| 54 | &fsr_tex_height); | ||
| 55 | if (static_cast<u32>(fsr_tex_width) != output_image_width || | ||
| 56 | static_cast<u32>(fsr_tex_height) != output_image_height) { | ||
| 57 | fsr_intermediate_tex.Release(); | ||
| 58 | } | ||
| 59 | } | ||
| 60 | if (!fsr_intermediate_tex.handle) { | ||
| 61 | fsr_intermediate_tex.Create(GL_TEXTURE_2D); | ||
| 62 | glTextureStorage2D(fsr_intermediate_tex.handle, 1, GL_RGB16F, output_image_width, | ||
| 63 | output_image_height); | ||
| 64 | glNamedFramebufferTexture(fsr_framebuffer.handle, GL_COLOR_ATTACHMENT0, | ||
| 65 | fsr_intermediate_tex.handle, 0); | ||
| 66 | } | ||
| 67 | |||
| 68 | GLint old_draw_fb; | ||
| 69 | glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw_fb); | ||
| 70 | 44 | ||
| 71 | glFrontFace(GL_CW); | 45 | rcas_tex.Create(GL_TEXTURE_2D); |
| 72 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fsr_framebuffer.handle); | 46 | glTextureStorage2D(rcas_tex.handle, 1, GL_RGBA16F, width, height); |
| 73 | glViewportIndexedf(0, 0.0f, 0.0f, static_cast<GLfloat>(output_image_width), | 47 | } |
| 74 | static_cast<GLfloat>(output_image_height)); | ||
| 75 | 48 | ||
| 49 | FSR::~FSR() = default; | ||
| 50 | |||
| 51 | GLuint FSR::Draw(ProgramManager& program_manager, GLuint texture, u32 input_image_width, | ||
| 52 | u32 input_image_height, const Common::Rectangle<f32>& crop_rect) { | ||
| 76 | const f32 input_width = static_cast<f32>(input_image_width); | 53 | const f32 input_width = static_cast<f32>(input_image_width); |
| 77 | const f32 input_height = static_cast<f32>(input_image_height); | 54 | const f32 input_height = static_cast<f32>(input_image_height); |
| 78 | const f32 output_width = static_cast<f32>(screen.GetWidth()); | 55 | const f32 output_width = static_cast<f32>(width); |
| 79 | const f32 output_height = static_cast<f32>(screen.GetHeight()); | 56 | const f32 output_height = static_cast<f32>(height); |
| 80 | const f32 viewport_width = (crop_rect.right - crop_rect.left) * input_width; | 57 | const f32 viewport_width = (crop_rect.right - crop_rect.left) * input_width; |
| 81 | const f32 viewport_x = crop_rect.left * input_width; | 58 | const f32 viewport_x = crop_rect.left * input_width; |
| 82 | const f32 viewport_height = (crop_rect.bottom - crop_rect.top) * input_height; | 59 | const f32 viewport_height = (crop_rect.bottom - crop_rect.top) * input_height; |
| 83 | const f32 viewport_y = crop_rect.top * input_height; | 60 | const f32 viewport_y = crop_rect.top * input_height; |
| 84 | 61 | ||
| 85 | FsrConstants constants; | 62 | FsrConstants easu_con{}; |
| 86 | FsrEasuConOffset(constants.data() + 0, constants.data() + 4, constants.data() + 8, | 63 | FsrConstants rcas_con{}; |
| 87 | constants.data() + 12, viewport_width, viewport_height, input_width, | ||
| 88 | input_height, output_width, output_height, viewport_x, viewport_y); | ||
| 89 | |||
| 90 | glProgramUniform4uiv(fsr_easu_frag.handle, 0, sizeof(constants), std::data(constants)); | ||
| 91 | |||
| 92 | program_manager.BindPresentPrograms(fsr_vertex.handle, fsr_easu_frag.handle); | ||
| 93 | glDrawArrays(GL_TRIANGLES, 0, 3); | ||
| 94 | 64 | ||
| 95 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw_fb); | 65 | FsrEasuConOffset(easu_con.data() + 0, easu_con.data() + 4, easu_con.data() + 8, |
| 96 | glBindTextureUnit(0, fsr_intermediate_tex.handle); | 66 | easu_con.data() + 12, viewport_width, viewport_height, input_width, |
| 67 | input_height, output_width, output_height, viewport_x, viewport_y); | ||
| 97 | 68 | ||
| 98 | const float sharpening = | 69 | const float sharpening = |
| 99 | static_cast<float>(Settings::values.fsr_sharpening_slider.GetValue()) / 100.0f; | 70 | static_cast<float>(Settings::values.fsr_sharpening_slider.GetValue()) / 100.0f; |
| 100 | 71 | ||
| 101 | FsrRcasCon(constants.data(), sharpening); | 72 | FsrRcasCon(rcas_con.data(), sharpening); |
| 102 | glProgramUniform4uiv(fsr_rcas_frag.handle, 0, sizeof(constants), std::data(constants)); | ||
| 103 | } | ||
| 104 | 73 | ||
| 105 | void FSR::InitBuffers() { | 74 | glProgramUniform4uiv(easu_frag.handle, 0, sizeof(easu_con), easu_con.data()); |
| 106 | fsr_framebuffer.Create(); | 75 | glProgramUniform4uiv(rcas_frag.handle, 0, sizeof(rcas_con), rcas_con.data()); |
| 107 | } | ||
| 108 | 76 | ||
| 109 | void FSR::ReleaseBuffers() { | 77 | glFrontFace(GL_CW); |
| 110 | fsr_framebuffer.Release(); | 78 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.handle); |
| 111 | fsr_intermediate_tex.Release(); | 79 | glNamedFramebufferTexture(framebuffer.handle, GL_COLOR_ATTACHMENT0, easu_tex.handle, 0); |
| 112 | } | 80 | glViewportIndexedf(0, 0.0f, 0.0f, output_width, output_height); |
| 81 | program_manager.BindPresentPrograms(vert.handle, easu_frag.handle); | ||
| 82 | glBindTextureUnit(0, texture); | ||
| 83 | glBindSampler(0, sampler.handle); | ||
| 84 | glDrawArrays(GL_TRIANGLES, 0, 3); | ||
| 85 | |||
| 86 | glNamedFramebufferTexture(framebuffer.handle, GL_COLOR_ATTACHMENT0, rcas_tex.handle, 0); | ||
| 87 | program_manager.BindPresentPrograms(vert.handle, rcas_frag.handle); | ||
| 88 | glBindTextureUnit(0, easu_tex.handle); | ||
| 89 | glDrawArrays(GL_TRIANGLES, 0, 3); | ||
| 113 | 90 | ||
| 114 | const OGLProgram& FSR::GetPresentFragmentProgram() const noexcept { | 91 | return rcas_tex.handle; |
| 115 | return fsr_rcas_frag; | ||
| 116 | } | 92 | } |
| 117 | 93 | ||
| 118 | bool FSR::AreBuffersInitialized() const noexcept { | 94 | bool FSR::NeedsRecreation(const Common::Rectangle<u32>& screen) { |
| 119 | return fsr_framebuffer.handle; | 95 | return screen.GetWidth() != width || screen.GetHeight() != height; |
| 120 | } | 96 | } |
| 121 | 97 | ||
| 122 | } // namespace OpenGL | 98 | } // 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; | |||
| 16 | 16 | ||
| 17 | class FSR { | 17 | class FSR { |
| 18 | public: | 18 | public: |
| 19 | explicit FSR(); | 19 | explicit FSR(u32 output_width, u32 output_height); |
| 20 | ~FSR(); | 20 | ~FSR(); |
| 21 | 21 | ||
| 22 | void Draw(ProgramManager& program_manager, const Common::Rectangle<u32>& screen, | 22 | GLuint Draw(ProgramManager& program_manager, GLuint texture, u32 input_image_width, |
| 23 | u32 input_image_width, u32 input_image_height, | 23 | u32 input_image_height, const Common::Rectangle<f32>& crop_rect); |
| 24 | const Common::Rectangle<f32>& crop_rect); | ||
| 25 | 24 | ||
| 26 | void InitBuffers(); | 25 | bool NeedsRecreation(const Common::Rectangle<u32>& screen); |
| 27 | |||
| 28 | void ReleaseBuffers(); | ||
| 29 | |||
| 30 | [[nodiscard]] const OGLProgram& GetPresentFragmentProgram() const noexcept; | ||
| 31 | |||
| 32 | [[nodiscard]] bool AreBuffersInitialized() const noexcept; | ||
| 33 | 26 | ||
| 34 | private: | 27 | private: |
| 35 | OGLFramebuffer fsr_framebuffer; | 28 | const u32 width; |
| 36 | OGLProgram fsr_vertex; | 29 | const u32 height; |
| 37 | OGLProgram fsr_easu_frag; | 30 | OGLFramebuffer framebuffer; |
| 38 | OGLProgram fsr_rcas_frag; | 31 | OGLSampler sampler; |
| 39 | OGLTexture fsr_intermediate_tex; | 32 | OGLProgram vert; |
| 33 | OGLProgram easu_frag; | ||
| 34 | OGLProgram rcas_frag; | ||
| 35 | OGLTexture easu_tex; | ||
| 36 | OGLTexture rcas_tex; | ||
| 40 | }; | 37 | }; |
| 41 | 38 | ||
| 42 | } // namespace OpenGL | 39 | } // namespace OpenGL |