aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs')
-rw-r--r--Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs81
1 files changed, 81 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs b/Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs
new file mode 100644
index 00000000..3a2d685b
--- /dev/null
+++ b/Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs
@@ -0,0 +1,81 @@
+using OpenTK.Graphics.OpenGL;
+using Ryujinx.Common;
+using Ryujinx.Graphics.OpenGL.Image;
+
+namespace Ryujinx.Graphics.OpenGL.Effects
+{
+ internal class FxaaPostProcessingEffect : IPostProcessingEffect
+ {
+ private readonly OpenGLRenderer _renderer;
+ private int _resolutionUniform;
+ private int _inputUniform;
+ private int _outputUniform;
+ private int _shaderProgram;
+ private TextureStorage _textureStorage;
+
+ public FxaaPostProcessingEffect(OpenGLRenderer renderer)
+ {
+ Initialize();
+
+ _renderer = renderer;
+ }
+
+ public void Dispose()
+ {
+ if (_shaderProgram != 0)
+ {
+ GL.DeleteProgram(_shaderProgram);
+ _textureStorage?.Dispose();
+ }
+ }
+
+ private void Initialize()
+ {
+ _shaderProgram = ShaderHelper.CompileProgram(EmbeddedResources.ReadAllText("Ryujinx.Graphics.OpenGL/Effects/Shaders/fxaa.glsl"), ShaderType.ComputeShader);
+
+ _resolutionUniform = GL.GetUniformLocation(_shaderProgram, "invResolution");
+ _inputUniform = GL.GetUniformLocation(_shaderProgram, "inputTexture");
+ _outputUniform = GL.GetUniformLocation(_shaderProgram, "imgOutput");
+ }
+
+ public TextureView Run(TextureView view, int width, int height)
+ {
+ if (_textureStorage == null || _textureStorage.Info.Width != view.Width || _textureStorage.Info.Height != view.Height)
+ {
+ _textureStorage?.Dispose();
+ _textureStorage = new TextureStorage(_renderer, view.Info, view.ScaleFactor);
+ _textureStorage.CreateDefaultView();
+ }
+
+ var textureView = _textureStorage.CreateView(view.Info, 0, 0) as TextureView;
+
+ int previousProgram = GL.GetInteger(GetPName.CurrentProgram);
+ int previousUnit = GL.GetInteger(GetPName.ActiveTexture);
+ GL.ActiveTexture(TextureUnit.Texture0);
+ int previousTextureBinding = GL.GetInteger(GetPName.TextureBinding2D);
+
+ GL.BindImageTexture(0, textureView.Handle, 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
+ GL.UseProgram(_shaderProgram);
+
+ var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
+ var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
+
+ view.Bind(0);
+ GL.Uniform1(_inputUniform, 0);
+ GL.Uniform1(_outputUniform, 0);
+ GL.Uniform2(_resolutionUniform, (float)view.Width, (float)view.Height);
+ GL.DispatchCompute(dispatchX, dispatchY, 1);
+ GL.UseProgram(previousProgram);
+ GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit);
+
+ (_renderer.Pipeline as Pipeline).RestoreImages1And2();
+
+ GL.ActiveTexture(TextureUnit.Texture0);
+ GL.BindTexture(TextureTarget.Texture2D, previousTextureBinding);
+
+ GL.ActiveTexture((TextureUnit)previousUnit);
+
+ return textureView;
+ }
+ }
+} \ No newline at end of file