From 80b497213981512e9ba1a629bcd5e2c519d2e566 Mon Sep 17 00:00:00 2001 From: Emmanuel Hansen Date: Mon, 27 Feb 2023 21:11:55 +0000 Subject: Add Support for Post Processing Effects (#3616) * Add Post Processing Effects * fix events and shader issues * fix gtk upscale slider value * fix bgra games * don't swap swizzle if already swapped * restore opengl texture state after effects run * addressed review * use single pipeline for smaa and fsr * call finish on all pipelines * addressed review * attempt fix file case * attempt fixing file case * fix filter level tick frequency * adjust filter slider margins * replace fxaa shaders with original shader * addressed review --- .../Effects/FxaaPostProcessingEffect.cs | 81 ++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs (limited to 'Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs') 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 -- cgit v1.2.3