FxaaPostProcessingEffect.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using OpenTK.Graphics.OpenGL;
  2. using Ryujinx.Common;
  3. using Ryujinx.Graphics.OpenGL.Image;
  4. namespace Ryujinx.Graphics.OpenGL.Effects
  5. {
  6. internal class FxaaPostProcessingEffect : IPostProcessingEffect
  7. {
  8. private readonly OpenGLRenderer _renderer;
  9. private int _resolutionUniform;
  10. private int _inputUniform;
  11. private int _outputUniform;
  12. private int _shaderProgram;
  13. private TextureStorage _textureStorage;
  14. public FxaaPostProcessingEffect(OpenGLRenderer renderer)
  15. {
  16. Initialize();
  17. _renderer = renderer;
  18. }
  19. public void Dispose()
  20. {
  21. if (_shaderProgram != 0)
  22. {
  23. GL.DeleteProgram(_shaderProgram);
  24. _textureStorage?.Dispose();
  25. }
  26. }
  27. private void Initialize()
  28. {
  29. _shaderProgram = ShaderHelper.CompileProgram(EmbeddedResources.ReadAllText("Ryujinx.Graphics.OpenGL/Effects/Shaders/fxaa.glsl"), ShaderType.ComputeShader);
  30. _resolutionUniform = GL.GetUniformLocation(_shaderProgram, "invResolution");
  31. _inputUniform = GL.GetUniformLocation(_shaderProgram, "inputTexture");
  32. _outputUniform = GL.GetUniformLocation(_shaderProgram, "imgOutput");
  33. }
  34. public TextureView Run(TextureView view, int width, int height)
  35. {
  36. if (_textureStorage == null || _textureStorage.Info.Width != view.Width || _textureStorage.Info.Height != view.Height)
  37. {
  38. _textureStorage?.Dispose();
  39. _textureStorage = new TextureStorage(_renderer, view.Info, view.ScaleFactor);
  40. _textureStorage.CreateDefaultView();
  41. }
  42. var textureView = _textureStorage.CreateView(view.Info, 0, 0) as TextureView;
  43. int previousProgram = GL.GetInteger(GetPName.CurrentProgram);
  44. int previousUnit = GL.GetInteger(GetPName.ActiveTexture);
  45. GL.ActiveTexture(TextureUnit.Texture0);
  46. int previousTextureBinding = GL.GetInteger(GetPName.TextureBinding2D);
  47. GL.BindImageTexture(0, textureView.Handle, 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
  48. GL.UseProgram(_shaderProgram);
  49. var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
  50. var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
  51. view.Bind(0);
  52. GL.Uniform1(_inputUniform, 0);
  53. GL.Uniform1(_outputUniform, 0);
  54. GL.Uniform2(_resolutionUniform, (float)view.Width, (float)view.Height);
  55. GL.DispatchCompute(dispatchX, dispatchY, 1);
  56. GL.UseProgram(previousProgram);
  57. GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit);
  58. (_renderer.Pipeline as Pipeline).RestoreImages1And2();
  59. GL.ActiveTexture(TextureUnit.Texture0);
  60. GL.BindTexture(TextureTarget.Texture2D, previousTextureBinding);
  61. GL.ActiveTexture((TextureUnit)previousUnit);
  62. return textureView;
  63. }
  64. }
  65. }