gl_fsr.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "common/settings.h"
  4. #include "video_core/fsr.h"
  5. #include "video_core/renderer_opengl/gl_fsr.h"
  6. #include "video_core/renderer_opengl/gl_shader_manager.h"
  7. #include "video_core/renderer_opengl/gl_shader_util.h"
  8. namespace OpenGL {
  9. using namespace FSR;
  10. using FsrConstants = std::array<u32, 4 * 4>;
  11. FSR::FSR(std::string_view fsr_vertex_source, std::string_view fsr_easu_source,
  12. std::string_view fsr_rcas_source)
  13. : fsr_vertex{CreateProgram(fsr_vertex_source, GL_VERTEX_SHADER)},
  14. fsr_easu_frag{CreateProgram(fsr_easu_source, GL_FRAGMENT_SHADER)},
  15. fsr_rcas_frag{CreateProgram(fsr_rcas_source, GL_FRAGMENT_SHADER)} {
  16. glProgramUniform2f(fsr_vertex.handle, 0, 1.0f, 1.0f);
  17. glProgramUniform2f(fsr_vertex.handle, 1, 0.0f, 0.0f);
  18. }
  19. FSR::~FSR() = default;
  20. void FSR::Draw(ProgramManager& program_manager, const Common::Rectangle<u32>& screen,
  21. u32 input_image_width, u32 input_image_height,
  22. const Common::Rectangle<int>& crop_rect) {
  23. const auto output_image_width = screen.GetWidth();
  24. const auto output_image_height = screen.GetHeight();
  25. if (fsr_intermediate_tex.handle) {
  26. GLint fsr_tex_width, fsr_tex_height;
  27. glGetTextureLevelParameteriv(fsr_intermediate_tex.handle, 0, GL_TEXTURE_WIDTH,
  28. &fsr_tex_width);
  29. glGetTextureLevelParameteriv(fsr_intermediate_tex.handle, 0, GL_TEXTURE_HEIGHT,
  30. &fsr_tex_height);
  31. if (static_cast<u32>(fsr_tex_width) != output_image_width ||
  32. static_cast<u32>(fsr_tex_height) != output_image_height) {
  33. fsr_intermediate_tex.Release();
  34. }
  35. }
  36. if (!fsr_intermediate_tex.handle) {
  37. fsr_intermediate_tex.Create(GL_TEXTURE_2D);
  38. glTextureStorage2D(fsr_intermediate_tex.handle, 1, GL_RGB16F, output_image_width,
  39. output_image_height);
  40. glNamedFramebufferTexture(fsr_framebuffer.handle, GL_COLOR_ATTACHMENT0,
  41. fsr_intermediate_tex.handle, 0);
  42. }
  43. GLint old_draw_fb;
  44. glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw_fb);
  45. glFrontFace(GL_CW);
  46. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fsr_framebuffer.handle);
  47. glViewportIndexedf(0, 0.0f, 0.0f, static_cast<GLfloat>(output_image_width),
  48. static_cast<GLfloat>(output_image_height));
  49. FsrConstants constants;
  50. FsrEasuConOffset(
  51. constants.data() + 0, constants.data() + 4, constants.data() + 8, constants.data() + 12,
  52. static_cast<f32>(crop_rect.GetWidth()), static_cast<f32>(crop_rect.GetHeight()),
  53. static_cast<f32>(input_image_width), static_cast<f32>(input_image_height),
  54. static_cast<f32>(output_image_width), static_cast<f32>(output_image_height),
  55. static_cast<f32>(crop_rect.left), static_cast<f32>(crop_rect.top));
  56. glProgramUniform4uiv(fsr_easu_frag.handle, 0, sizeof(constants), std::data(constants));
  57. program_manager.BindPresentPrograms(fsr_vertex.handle, fsr_easu_frag.handle);
  58. glDrawArrays(GL_TRIANGLES, 0, 3);
  59. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw_fb);
  60. glBindTextureUnit(0, fsr_intermediate_tex.handle);
  61. const float sharpening =
  62. static_cast<float>(Settings::values.fsr_sharpening_slider.GetValue()) / 100.0f;
  63. FsrRcasCon(constants.data(), sharpening);
  64. glProgramUniform4uiv(fsr_rcas_frag.handle, 0, sizeof(constants), std::data(constants));
  65. }
  66. void FSR::InitBuffers() {
  67. fsr_framebuffer.Create();
  68. }
  69. void FSR::ReleaseBuffers() {
  70. fsr_framebuffer.Release();
  71. fsr_intermediate_tex.Release();
  72. }
  73. const OGLProgram& FSR::GetPresentFragmentProgram() const noexcept {
  74. return fsr_rcas_frag;
  75. }
  76. bool FSR::AreBuffersInitialized() const noexcept {
  77. return fsr_framebuffer.handle;
  78. }
  79. } // namespace OpenGL