mirror of
https://github.com/ryujinx-mirror/ryujinx.git
synced 2024-12-23 14:54:00 +00:00
81 lines
3.1 KiB
C#
81 lines
3.1 KiB
C#
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|