/ src / Ryujinx.Graphics.OpenGL / Effects / AreaScalingFilter.cs
AreaScalingFilter.cs
  1  using OpenTK.Graphics.OpenGL;
  2  using Ryujinx.Common;
  3  using Ryujinx.Graphics.GAL;
  4  using Ryujinx.Graphics.OpenGL.Image;
  5  using System;
  6  using static Ryujinx.Graphics.OpenGL.Effects.ShaderHelper;
  7  
  8  namespace Ryujinx.Graphics.OpenGL.Effects
  9  {
 10      internal class AreaScalingFilter : IScalingFilter
 11      {
 12          private readonly OpenGLRenderer _renderer;
 13          private int _inputUniform;
 14          private int _outputUniform;
 15          private int _srcX0Uniform;
 16          private int _srcX1Uniform;
 17          private int _srcY0Uniform;
 18          private int _scalingShaderProgram;
 19          private int _srcY1Uniform;
 20          private int _dstX0Uniform;
 21          private int _dstX1Uniform;
 22          private int _dstY0Uniform;
 23          private int _dstY1Uniform;
 24  
 25          public float Level { get; set; }
 26  
 27          public AreaScalingFilter(OpenGLRenderer renderer)
 28          {
 29              Initialize();
 30  
 31              _renderer = renderer;
 32          }
 33  
 34          public void Dispose()
 35          {
 36              if (_scalingShaderProgram != 0)
 37              {
 38                  GL.DeleteProgram(_scalingShaderProgram);
 39              }
 40          }
 41  
 42          private void Initialize()
 43          {
 44              var scalingShader = EmbeddedResources.ReadAllText("Ryujinx.Graphics.OpenGL/Effects/Shaders/area_scaling.glsl");
 45  
 46              _scalingShaderProgram = CompileProgram(scalingShader, ShaderType.ComputeShader);
 47  
 48              _inputUniform = GL.GetUniformLocation(_scalingShaderProgram, "Source");
 49              _outputUniform = GL.GetUniformLocation(_scalingShaderProgram, "imgOutput");
 50  
 51              _srcX0Uniform = GL.GetUniformLocation(_scalingShaderProgram, "srcX0");
 52              _srcX1Uniform = GL.GetUniformLocation(_scalingShaderProgram, "srcX1");
 53              _srcY0Uniform = GL.GetUniformLocation(_scalingShaderProgram, "srcY0");
 54              _srcY1Uniform = GL.GetUniformLocation(_scalingShaderProgram, "srcY1");
 55              _dstX0Uniform = GL.GetUniformLocation(_scalingShaderProgram, "dstX0");
 56              _dstX1Uniform = GL.GetUniformLocation(_scalingShaderProgram, "dstX1");
 57              _dstY0Uniform = GL.GetUniformLocation(_scalingShaderProgram, "dstY0");
 58              _dstY1Uniform = GL.GetUniformLocation(_scalingShaderProgram, "dstY1");
 59          }
 60  
 61          public void Run(
 62              TextureView view,
 63              TextureView destinationTexture,
 64              int width,
 65              int height,
 66              Extents2D source,
 67              Extents2D destination)
 68          {
 69              int previousProgram = GL.GetInteger(GetPName.CurrentProgram);
 70              int previousUnit = GL.GetInteger(GetPName.ActiveTexture);
 71              GL.ActiveTexture(TextureUnit.Texture0);
 72              int previousTextureBinding = GL.GetInteger(GetPName.TextureBinding2D);
 73  
 74              GL.BindImageTexture(0, destinationTexture.Handle, 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
 75  
 76              int threadGroupWorkRegionDim = 16;
 77              int dispatchX = (width + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
 78              int dispatchY = (height + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
 79  
 80              // Scaling pass
 81              GL.UseProgram(_scalingShaderProgram);
 82              view.Bind(0);
 83              GL.Uniform1(_inputUniform, 0);
 84              GL.Uniform1(_outputUniform, 0);
 85              GL.Uniform1(_srcX0Uniform, (float)source.X1);
 86              GL.Uniform1(_srcX1Uniform, (float)source.X2);
 87              GL.Uniform1(_srcY0Uniform, (float)source.Y1);
 88              GL.Uniform1(_srcY1Uniform, (float)source.Y2);
 89              GL.Uniform1(_dstX0Uniform, (float)destination.X1);
 90              GL.Uniform1(_dstX1Uniform, (float)destination.X2);
 91              GL.Uniform1(_dstY0Uniform, (float)destination.Y1);
 92              GL.Uniform1(_dstY1Uniform, (float)destination.Y2);
 93              GL.DispatchCompute(dispatchX, dispatchY, 1);
 94  
 95              GL.UseProgram(previousProgram);
 96              GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit);
 97  
 98              (_renderer.Pipeline as Pipeline).RestoreImages1And2();
 99  
100              GL.ActiveTexture(TextureUnit.Texture0);
101              GL.BindTexture(TextureTarget.Texture2D, previousTextureBinding);
102  
103              GL.ActiveTexture((TextureUnit)previousUnit);
104          }
105      }
106  }