smaa.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "video_core/host_shaders/opengl_smaa_glsl.h"
  4. #include "video_core/host_shaders/smaa_blending_weight_calculation_frag.h"
  5. #include "video_core/host_shaders/smaa_blending_weight_calculation_vert.h"
  6. #include "video_core/host_shaders/smaa_edge_detection_frag.h"
  7. #include "video_core/host_shaders/smaa_edge_detection_vert.h"
  8. #include "video_core/host_shaders/smaa_neighborhood_blending_frag.h"
  9. #include "video_core/host_shaders/smaa_neighborhood_blending_vert.h"
  10. #include "video_core/renderer_opengl/gl_shader_manager.h"
  11. #include "video_core/renderer_opengl/gl_shader_util.h"
  12. #include "video_core/renderer_opengl/present/smaa.h"
  13. #include "video_core/renderer_opengl/present/util.h"
  14. #include "video_core/smaa_area_tex.h"
  15. #include "video_core/smaa_search_tex.h"
  16. namespace OpenGL {
  17. SMAA::SMAA(u32 width, u32 height) {
  18. const auto SmaaShader = [&](std::string_view specialized_source, GLenum stage) {
  19. std::string shader_source{specialized_source};
  20. ReplaceInclude(shader_source, "opengl_smaa.glsl", HostShaders::OPENGL_SMAA_GLSL);
  21. return CreateProgram(shader_source, stage);
  22. };
  23. edge_detection_vert = SmaaShader(HostShaders::SMAA_EDGE_DETECTION_VERT, GL_VERTEX_SHADER);
  24. edge_detection_frag = SmaaShader(HostShaders::SMAA_EDGE_DETECTION_FRAG, GL_FRAGMENT_SHADER);
  25. blending_weight_calculation_vert =
  26. SmaaShader(HostShaders::SMAA_BLENDING_WEIGHT_CALCULATION_VERT, GL_VERTEX_SHADER);
  27. blending_weight_calculation_frag =
  28. SmaaShader(HostShaders::SMAA_BLENDING_WEIGHT_CALCULATION_FRAG, GL_FRAGMENT_SHADER);
  29. neighborhood_blending_vert =
  30. SmaaShader(HostShaders::SMAA_NEIGHBORHOOD_BLENDING_VERT, GL_VERTEX_SHADER);
  31. neighborhood_blending_frag =
  32. SmaaShader(HostShaders::SMAA_NEIGHBORHOOD_BLENDING_FRAG, GL_FRAGMENT_SHADER);
  33. glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
  34. glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
  35. glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
  36. glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  37. glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
  38. glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  39. glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  40. glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
  41. area_tex.Create(GL_TEXTURE_2D);
  42. glTextureStorage2D(area_tex.handle, 1, GL_RG8, AREATEX_WIDTH, AREATEX_HEIGHT);
  43. glTextureSubImage2D(area_tex.handle, 0, 0, 0, AREATEX_WIDTH, AREATEX_HEIGHT, GL_RG,
  44. GL_UNSIGNED_BYTE, areaTexBytes);
  45. search_tex.Create(GL_TEXTURE_2D);
  46. glTextureStorage2D(search_tex.handle, 1, GL_R8, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT);
  47. glTextureSubImage2D(search_tex.handle, 0, 0, 0, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, GL_RED,
  48. GL_UNSIGNED_BYTE, searchTexBytes);
  49. edges_tex.Create(GL_TEXTURE_2D);
  50. glTextureStorage2D(edges_tex.handle, 1, GL_RG16F, width, height);
  51. blend_tex.Create(GL_TEXTURE_2D);
  52. glTextureStorage2D(blend_tex.handle, 1, GL_RGBA16F, width, height);
  53. sampler = CreateBilinearSampler();
  54. framebuffer.Create();
  55. texture.Create(GL_TEXTURE_2D);
  56. glTextureStorage2D(texture.handle, 1, GL_RGBA16F, width, height);
  57. glNamedFramebufferTexture(framebuffer.handle, GL_COLOR_ATTACHMENT0, texture.handle, 0);
  58. }
  59. SMAA::~SMAA() = default;
  60. GLuint SMAA::Draw(ProgramManager& program_manager, GLuint input_texture) {
  61. glClearColor(0, 0, 0, 0);
  62. glFrontFace(GL_CCW);
  63. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.handle);
  64. glBindSampler(0, sampler.handle);
  65. glBindSampler(1, sampler.handle);
  66. glBindSampler(2, sampler.handle);
  67. glBindTextureUnit(0, input_texture);
  68. glNamedFramebufferTexture(framebuffer.handle, GL_COLOR_ATTACHMENT0, edges_tex.handle, 0);
  69. glClear(GL_COLOR_BUFFER_BIT);
  70. program_manager.BindPresentPrograms(edge_detection_vert.handle, edge_detection_frag.handle);
  71. glDrawArrays(GL_TRIANGLES, 0, 3);
  72. glBindTextureUnit(0, edges_tex.handle);
  73. glBindTextureUnit(1, area_tex.handle);
  74. glBindTextureUnit(2, search_tex.handle);
  75. glNamedFramebufferTexture(framebuffer.handle, GL_COLOR_ATTACHMENT0, blend_tex.handle, 0);
  76. glClear(GL_COLOR_BUFFER_BIT);
  77. program_manager.BindPresentPrograms(blending_weight_calculation_vert.handle,
  78. blending_weight_calculation_frag.handle);
  79. glDrawArrays(GL_TRIANGLES, 0, 3);
  80. glBindTextureUnit(0, input_texture);
  81. glBindTextureUnit(1, blend_tex.handle);
  82. glNamedFramebufferTexture(framebuffer.handle, GL_COLOR_ATTACHMENT0, texture.handle, 0);
  83. program_manager.BindPresentPrograms(neighborhood_blending_vert.handle,
  84. neighborhood_blending_frag.handle);
  85. glClear(GL_COLOR_BUFFER_BIT);
  86. glDrawArrays(GL_TRIANGLES, 0, 3);
  87. glFrontFace(GL_CW);
  88. return texture.handle;
  89. }
  90. } // namespace OpenGL