summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Liam2024-01-15 14:28:03 -0500
committerGravatar Liam2024-01-31 11:27:21 -0500
commitdd2918efd83b586861ebc463dfee20c35e9d3bb3 (patch)
tree7c3e814d9ff1b26741a823dbc285877f49e7e57a /src
parentrenderer_vulkan: convert FSR to graphics pipeline (diff)
downloadyuzu-dd2918efd83b586861ebc463dfee20c35e9d3bb3.tar.gz
yuzu-dd2918efd83b586861ebc463dfee20c35e9d3bb3.tar.xz
yuzu-dd2918efd83b586861ebc463dfee20c35e9d3bb3.zip
renderer_opengl: move out ownership of FSR resources
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_blit_screen.cpp35
-rw-r--r--src/video_core/renderer_opengl/present/fsr.cpp110
-rw-r--r--src/video_core/renderer_opengl/present/fsr.h29
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
20using FsrConstants = std::array<u32, 4 * 4>; 20using FsrConstants = std::array<u32, 4 * 4>;
21 21
22FSR::FSR() { 22FSR::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
40FSR::~FSR() = default; 39 sampler = CreateBilinearSampler();
40 framebuffer.Create();
41 41
42void 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
49FSR::~FSR() = default;
50
51GLuint 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
105void 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
109void 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
114const OGLProgram& FSR::GetPresentFragmentProgram() const noexcept { 91 return rcas_tex.handle;
115 return fsr_rcas_frag;
116} 92}
117 93
118bool FSR::AreBuffersInitialized() const noexcept { 94bool 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
17class FSR { 17class FSR {
18public: 18public:
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
34private: 27private:
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