More progress

This commit is contained in:
Isaac Marovitz 2024-05-09 11:46:39 -04:00
parent 5f1c880805
commit 4ee4b0f3ac
No known key found for this signature in database
GPG key ID: 97250B2B09A132E1
21 changed files with 697 additions and 695 deletions

View file

@ -69,26 +69,26 @@ namespace Ryujinx.Graphics.OpenGL
(uint)size); (uint)size);
} }
public static unsafe PinnedSpan<byte> GetData(GL api, OpenGLRenderer renderer, BufferHandle buffer, int offset, int size) public static unsafe PinnedSpan<byte> GetData(OpenGLRenderer gd, BufferHandle buffer, int offset, int size)
{ {
// Data in the persistent buffer and host array is guaranteed to be available // Data in the persistent buffer and host array is guaranteed to be available
// until the next time the host thread requests data. // until the next time the host thread requests data.
if (renderer.PersistentBuffers.TryGet(buffer, out IntPtr ptr)) if (gd.PersistentBuffers.TryGet(buffer, out IntPtr ptr))
{ {
return new PinnedSpan<byte>(IntPtr.Add(ptr, offset).ToPointer(), size); return new PinnedSpan<byte>(IntPtr.Add(ptr, offset).ToPointer(), size);
} }
else if (HwCapabilities.UsePersistentBufferForFlush) else if (HwCapabilities.UsePersistentBufferForFlush)
{ {
return PinnedSpan<byte>.UnsafeFromSpan(renderer.PersistentBuffers.Default.GetBufferData(buffer, offset, size)); return PinnedSpan<byte>.UnsafeFromSpan(gd.PersistentBuffers.Default.GetBufferData(buffer, offset, size));
} }
else else
{ {
IntPtr target = renderer.PersistentBuffers.Default.GetHostArray(size); IntPtr target = gd.PersistentBuffers.Default.GetHostArray(size);
api.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32()); gd.Api.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32());
api.GetBufferSubData(BufferTargetARB.CopyReadBuffer, offset, (uint)size, target); gd.Api.GetBufferSubData(BufferTargetARB.CopyReadBuffer, offset, (uint)size, target);
return new PinnedSpan<byte>(target.ToPointer(), size); return new PinnedSpan<byte>(target.ToPointer(), size);
} }

View file

@ -1,6 +1,7 @@
using Silk.NET.OpenGL; using Silk.NET.OpenGL;
using Ryujinx.Graphics.OpenGL.Image; using Ryujinx.Graphics.OpenGL.Image;
using System; using System;
using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler;
namespace Ryujinx.Graphics.OpenGL namespace Ryujinx.Graphics.OpenGL
{ {

View file

@ -9,15 +9,15 @@ namespace Ryujinx.Graphics.OpenGL.Effects
{ {
internal class FsrScalingFilter : IScalingFilter internal class FsrScalingFilter : IScalingFilter
{ {
private readonly OpenGLRenderer _renderer; private readonly OpenGLRenderer _gd;
private int _inputUniform; private int _inputUniform;
private int _outputUniform; private int _outputUniform;
private int _sharpeningUniform; private int _sharpeningUniform;
private int _srcX0Uniform; private int _srcX0Uniform;
private int _srcX1Uniform; private int _srcX1Uniform;
private int _srcY0Uniform; private int _srcY0Uniform;
private int _scalingShaderProgram; private uint _scalingShaderProgram;
private int _sharpeningShaderProgram; private uint _sharpeningShaderProgram;
private float _scale = 1; private float _scale = 1;
private int _srcY1Uniform; private int _srcY1Uniform;
private int _dstX0Uniform; private int _dstX0Uniform;
@ -37,19 +37,19 @@ namespace Ryujinx.Graphics.OpenGL.Effects
} }
} }
public FsrScalingFilter(OpenGLRenderer renderer) public FsrScalingFilter(OpenGLRenderer gd)
{ {
Initialize(); Initialize();
_renderer = renderer; _gd = gd;
} }
public void Dispose() public void Dispose()
{ {
if (_scalingShaderProgram != 0) if (_scalingShaderProgram != 0)
{ {
GL.DeleteProgram(_scalingShaderProgram); _gd.Api.DeleteProgram(_scalingShaderProgram);
GL.DeleteProgram(_sharpeningShaderProgram); _gd.Api.DeleteProgram(_sharpeningShaderProgram);
} }
_intermediaryTexture?.Dispose(); _intermediaryTexture?.Dispose();
@ -67,23 +67,23 @@ namespace Ryujinx.Graphics.OpenGL.Effects
sharpeningShader = sharpeningShader.Replace("#include \"ffx_a.h\"", fsrA); sharpeningShader = sharpeningShader.Replace("#include \"ffx_a.h\"", fsrA);
sharpeningShader = sharpeningShader.Replace("#include \"ffx_fsr1.h\"", fsr1); sharpeningShader = sharpeningShader.Replace("#include \"ffx_fsr1.h\"", fsr1);
_scalingShaderProgram = CompileProgram(scalingShader, ShaderType.ComputeShader); _scalingShaderProgram = CompileProgram(_gd.Api, scalingShader, ShaderType.ComputeShader);
_sharpeningShaderProgram = CompileProgram(sharpeningShader, ShaderType.ComputeShader); _sharpeningShaderProgram = CompileProgram(_gd.Api, sharpeningShader, ShaderType.ComputeShader);
_inputUniform = GL.GetUniformLocation(_scalingShaderProgram, "Source"); _inputUniform = _gd.Api.GetUniformLocation(_scalingShaderProgram, "Source");
_outputUniform = GL.GetUniformLocation(_scalingShaderProgram, "imgOutput"); _outputUniform = _gd.Api.GetUniformLocation(_scalingShaderProgram, "imgOutput");
_sharpeningUniform = GL.GetUniformLocation(_sharpeningShaderProgram, "sharpening"); _sharpeningUniform = _gd.Api.GetUniformLocation(_sharpeningShaderProgram, "sharpening");
_srcX0Uniform = GL.GetUniformLocation(_scalingShaderProgram, "srcX0"); _srcX0Uniform = _gd.Api.GetUniformLocation(_scalingShaderProgram, "srcX0");
_srcX1Uniform = GL.GetUniformLocation(_scalingShaderProgram, "srcX1"); _srcX1Uniform = _gd.Api.GetUniformLocation(_scalingShaderProgram, "srcX1");
_srcY0Uniform = GL.GetUniformLocation(_scalingShaderProgram, "srcY0"); _srcY0Uniform = _gd.Api.GetUniformLocation(_scalingShaderProgram, "srcY0");
_srcY1Uniform = GL.GetUniformLocation(_scalingShaderProgram, "srcY1"); _srcY1Uniform = _gd.Api.GetUniformLocation(_scalingShaderProgram, "srcY1");
_dstX0Uniform = GL.GetUniformLocation(_scalingShaderProgram, "dstX0"); _dstX0Uniform = _gd.Api.GetUniformLocation(_scalingShaderProgram, "dstX0");
_dstX1Uniform = GL.GetUniformLocation(_scalingShaderProgram, "dstX1"); _dstX1Uniform = _gd.Api.GetUniformLocation(_scalingShaderProgram, "dstX1");
_dstY0Uniform = GL.GetUniformLocation(_scalingShaderProgram, "dstY0"); _dstY0Uniform = _gd.Api.GetUniformLocation(_scalingShaderProgram, "dstY0");
_dstY1Uniform = GL.GetUniformLocation(_scalingShaderProgram, "dstY1"); _dstY1Uniform = _gd.Api.GetUniformLocation(_scalingShaderProgram, "dstY1");
_scaleXUniform = GL.GetUniformLocation(_scalingShaderProgram, "scaleX"); _scaleXUniform = _gd.Api.GetUniformLocation(_scalingShaderProgram, "scaleX");
_scaleYUniform = GL.GetUniformLocation(_scalingShaderProgram, "scaleY"); _scaleYUniform = _gd.Api.GetUniformLocation(_scalingShaderProgram, "scaleY");
} }
public void Run( public void Run(
@ -114,18 +114,18 @@ namespace Ryujinx.Graphics.OpenGL.Effects
originalInfo.SwizzleB, originalInfo.SwizzleB,
originalInfo.SwizzleA); originalInfo.SwizzleA);
_intermediaryTexture = new TextureStorage(_renderer, info); _intermediaryTexture = new TextureStorage(_gd, info);
_intermediaryTexture.CreateDefaultView(); _intermediaryTexture.CreateDefaultView();
} }
var textureView = _intermediaryTexture.CreateView(_intermediaryTexture.Info, 0, 0) as TextureView; var textureView = _intermediaryTexture.CreateView(_intermediaryTexture.Info, 0, 0) as TextureView;
int previousProgram = GL.GetInteger(GetPName.CurrentProgram); uint previousProgram = (uint)_gd.Api.GetInteger(GetPName.CurrentProgram);
int previousUnit = GL.GetInteger(GetPName.ActiveTexture); int previousUnit = _gd.Api.GetInteger(GetPName.ActiveTexture);
GL.ActiveTexture(TextureUnit.Texture0); _gd.Api.ActiveTexture(TextureUnit.Texture0);
int previousTextureBinding = GL.GetInteger(GetPName.TextureBinding2D); int previousTextureBinding = _gd.Api.GetInteger(GetPName.TextureBinding2D);
GL.BindImageTexture(0, textureView.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8); _gd.Api.BindImageTexture(0, textureView.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8);
int threadGroupWorkRegionDim = 16; int threadGroupWorkRegionDim = 16;
int dispatchX = (width + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim; int dispatchX = (width + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
@ -136,42 +136,42 @@ namespace Ryujinx.Graphics.OpenGL.Effects
float srcHeight = Math.Abs(source.Y2 - source.Y1); float srcHeight = Math.Abs(source.Y2 - source.Y1);
float scaleX = srcWidth / view.Width; float scaleX = srcWidth / view.Width;
float scaleY = srcHeight / view.Height; float scaleY = srcHeight / view.Height;
GL.UseProgram(_scalingShaderProgram); _gd.Api.UseProgram(_scalingShaderProgram);
view.Bind(0); view.Bind(0);
GL.Uniform1(_inputUniform, 0); _gd.Api.Uniform1(_inputUniform, 0);
GL.Uniform1(_outputUniform, 0); _gd.Api.Uniform1(_outputUniform, 0);
GL.Uniform1(_srcX0Uniform, (float)source.X1); _gd.Api.Uniform1(_srcX0Uniform, (float)source.X1);
GL.Uniform1(_srcX1Uniform, (float)source.X2); _gd.Api.Uniform1(_srcX1Uniform, (float)source.X2);
GL.Uniform1(_srcY0Uniform, (float)source.Y1); _gd.Api.Uniform1(_srcY0Uniform, (float)source.Y1);
GL.Uniform1(_srcY1Uniform, (float)source.Y2); _gd.Api.Uniform1(_srcY1Uniform, (float)source.Y2);
GL.Uniform1(_dstX0Uniform, (float)destination.X1); _gd.Api.Uniform1(_dstX0Uniform, (float)destination.X1);
GL.Uniform1(_dstX1Uniform, (float)destination.X2); _gd.Api.Uniform1(_dstX1Uniform, (float)destination.X2);
GL.Uniform1(_dstY0Uniform, (float)destination.Y1); _gd.Api.Uniform1(_dstY0Uniform, (float)destination.Y1);
GL.Uniform1(_dstY1Uniform, (float)destination.Y2); _gd.Api.Uniform1(_dstY1Uniform, (float)destination.Y2);
GL.Uniform1(_scaleXUniform, scaleX); _gd.Api.Uniform1(_scaleXUniform, scaleX);
GL.Uniform1(_scaleYUniform, scaleY); _gd.Api.Uniform1(_scaleYUniform, scaleY);
GL.DispatchCompute(dispatchX, dispatchY, 1); _gd.Api.DispatchCompute(dispatchX, dispatchY, 1);
GL.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit); _gd.Api.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit);
// Sharpening Pass // Sharpening Pass
GL.UseProgram(_sharpeningShaderProgram); _gd.Api.UseProgram(_sharpeningShaderProgram);
GL.BindImageTexture(0, destinationTexture.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8); _gd.Api.BindImageTexture(0, destinationTexture.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8);
textureView.Bind(0); textureView.Bind(0);
GL.Uniform1(_inputUniform, 0); _gd.Api.Uniform1(_inputUniform, 0);
GL.Uniform1(_outputUniform, 0); _gd.Api.Uniform1(_outputUniform, 0);
GL.Uniform1(_sharpeningUniform, 1.5f - (Level * 0.01f * 1.5f)); _gd.Api.Uniform1(_sharpeningUniform, 1.5f - (Level * 0.01f * 1.5f));
GL.DispatchCompute(dispatchX, dispatchY, 1); _gd.Api.DispatchCompute(dispatchX, dispatchY, 1);
GL.UseProgram(previousProgram); _gd.Api.UseProgram(previousProgram);
GL.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit); _gd.Api.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit);
(_renderer.Pipeline as Pipeline).RestoreImages1And2(); (_gd.Pipeline as Pipeline).RestoreImages1And2();
GL.ActiveTexture(TextureUnit.Texture0); _gd.Api.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, previousTextureBinding); _gd.Api.BindTexture(TextureTarget.Texture2D, previousTextureBinding);
GL.ActiveTexture((TextureUnit)previousUnit); _gd.Api.ActiveTexture((TextureUnit)previousUnit);
} }
} }
} }

View file

@ -6,25 +6,25 @@ namespace Ryujinx.Graphics.OpenGL.Effects
{ {
internal class FxaaPostProcessingEffect : IPostProcessingEffect internal class FxaaPostProcessingEffect : IPostProcessingEffect
{ {
private readonly OpenGLRenderer _renderer; private readonly OpenGLRenderer _gd;
private int _resolutionUniform; private int _resolutionUniform;
private int _inputUniform; private int _inputUniform;
private int _outputUniform; private int _outputUniform;
private int _shaderProgram; private uint _shaderProgram;
private TextureStorage _textureStorage; private TextureStorage _textureStorage;
public FxaaPostProcessingEffect(OpenGLRenderer renderer) public FxaaPostProcessingEffect(OpenGLRenderer gd)
{ {
Initialize(); Initialize();
_renderer = renderer; _gd = gd;
} }
public void Dispose() public void Dispose()
{ {
if (_shaderProgram != 0) if (_shaderProgram != 0)
{ {
GL.DeleteProgram(_shaderProgram); _gd.Api.DeleteProgram(_shaderProgram);
_textureStorage?.Dispose(); _textureStorage?.Dispose();
} }
} }
@ -33,9 +33,9 @@ namespace Ryujinx.Graphics.OpenGL.Effects
{ {
_shaderProgram = ShaderHelper.CompileProgram(EmbeddedResources.ReadAllText("Ryujinx.Graphics.OpenGL/Effects/Shaders/fxaa.glsl"), ShaderType.ComputeShader); _shaderProgram = ShaderHelper.CompileProgram(EmbeddedResources.ReadAllText("Ryujinx.Graphics.OpenGL/Effects/Shaders/fxaa.glsl"), ShaderType.ComputeShader);
_resolutionUniform = GL.GetUniformLocation(_shaderProgram, "invResolution"); _resolutionUniform = _gd.Api.GetUniformLocation(_shaderProgram, "invResolution");
_inputUniform = GL.GetUniformLocation(_shaderProgram, "inputTexture"); _inputUniform = _gd.Api.GetUniformLocation(_shaderProgram, "inputTexture");
_outputUniform = GL.GetUniformLocation(_shaderProgram, "imgOutput"); _outputUniform = _gd.Api.GetUniformLocation(_shaderProgram, "imgOutput");
} }
public TextureView Run(TextureView view, int width, int height) public TextureView Run(TextureView view, int width, int height)
@ -43,37 +43,37 @@ namespace Ryujinx.Graphics.OpenGL.Effects
if (_textureStorage == null || _textureStorage.Info.Width != view.Width || _textureStorage.Info.Height != view.Height) if (_textureStorage == null || _textureStorage.Info.Width != view.Width || _textureStorage.Info.Height != view.Height)
{ {
_textureStorage?.Dispose(); _textureStorage?.Dispose();
_textureStorage = new TextureStorage(_renderer, view.Info); _textureStorage = new TextureStorage(_gd, view.Info);
_textureStorage.CreateDefaultView(); _textureStorage.CreateDefaultView();
} }
var textureView = _textureStorage.CreateView(view.Info, 0, 0) as TextureView; var textureView = _textureStorage.CreateView(view.Info, 0, 0) as TextureView;
int previousProgram = GL.GetInteger(GetPName.CurrentProgram); int previousProgram = _gd.Api.GetInteger(GetPName.CurrentProgram);
int previousUnit = GL.GetInteger(GetPName.ActiveTexture); int previousUnit = _gd.Api.GetInteger(GetPName.ActiveTexture);
GL.ActiveTexture(TextureUnit.Texture0); _gd.Api.ActiveTexture(TextureUnit.Texture0);
int previousTextureBinding = GL.GetInteger(GetPName.TextureBinding2D); int previousTextureBinding = _gd.Api.GetInteger(GetPName.TextureBinding2D);
GL.BindImageTexture(0, textureView.Handle, 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8); _gd.Api.BindImageTexture(0, textureView.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8);
GL.UseProgram(_shaderProgram); _gd.Api.UseProgram(_shaderProgram);
var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize); var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize); var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
view.Bind(0); view.Bind(0);
GL.Uniform1(_inputUniform, 0); _gd.Api.Uniform1(_inputUniform, 0);
GL.Uniform1(_outputUniform, 0); _gd.Api.Uniform1(_outputUniform, 0);
GL.Uniform2(_resolutionUniform, (float)view.Width, (float)view.Height); _gd.Api.Uniform2(_resolutionUniform, (float)view.Width, (float)view.Height);
GL.DispatchCompute(dispatchX, dispatchY, 1); _gd.Api.DispatchCompute(dispatchX, dispatchY, 1);
GL.UseProgram(previousProgram); _gd.Api.UseProgram(previousProgram);
GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit); _gd.Api.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit);
(_renderer.Pipeline as Pipeline).RestoreImages1And2(); (_gd.Pipeline as Pipeline).RestoreImages1And2();
GL.ActiveTexture(TextureUnit.Texture0); _gd.Api.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, previousTextureBinding); _gd.Api.BindTexture(TextureTarget.Texture2D, previousTextureBinding);
GL.ActiveTexture((TextureUnit)previousUnit); _gd.Api.ActiveTexture((TextureUnit)previousUnit);
return textureView; return textureView;
} }

View file

@ -4,34 +4,34 @@ namespace Ryujinx.Graphics.OpenGL.Effects
{ {
internal static class ShaderHelper internal static class ShaderHelper
{ {
public static int CompileProgram(string shaderCode, ShaderType shaderType) public static uint CompileProgram(GL api, string shaderCode, ShaderType shaderType)
{ {
var shader = GL.CreateShader(shaderType); var shader = api.CreateShader(shaderType);
GL.ShaderSource(shader, shaderCode); api.ShaderSource(shader, shaderCode);
GL.CompileShader(shader); api.CompileShader(shader);
var program = GL.CreateProgram(); var program = api.CreateProgram();
GL.AttachShader(program, shader); api.AttachShader(program, shader);
GL.LinkProgram(program); api.LinkProgram(program);
GL.DetachShader(program, shader); api.DetachShader(program, shader);
GL.DeleteShader(shader); api.DeleteShader(shader);
return program; return program;
} }
public static int CompileProgram(string[] shaders, ShaderType shaderType) public static uint CompileProgram(GL api, string[] shaders, ShaderType shaderType)
{ {
var shader = GL.CreateShader(shaderType); var shader = api.CreateShader(shaderType);
GL.ShaderSource(shader, shaders.Length, shaders, (int[])null); api.ShaderSource(shader, (uint)shaders.Length, shaders, 0);
GL.CompileShader(shader); api.CompileShader(shader);
var program = GL.CreateProgram(); var program = api.CreateProgram();
GL.AttachShader(program, shader); api.AttachShader(program, shader);
GL.LinkProgram(program); api.LinkProgram(program);
GL.DetachShader(program, shader); api.DetachShader(program, shader);
GL.DeleteShader(shader); api.DeleteShader(shader);
return program; return program;
} }

View file

@ -6,20 +6,20 @@ using System;
namespace Ryujinx.Graphics.OpenGL.Effects.Smaa namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
{ {
internal partial class SmaaPostProcessingEffect : IPostProcessingEffect internal class SmaaPostProcessingEffect : IPostProcessingEffect
{ {
public const int AreaWidth = 160; public const int AreaWidth = 160;
public const int AreaHeight = 560; public const int AreaHeight = 560;
public const int SearchWidth = 64; public const int SearchWidth = 64;
public const int SearchHeight = 16; public const int SearchHeight = 16;
private readonly OpenGLRenderer _renderer; private readonly OpenGLRenderer _gd;
private TextureStorage _outputTexture; private TextureStorage _outputTexture;
private TextureStorage _searchTexture; private TextureStorage _searchTexture;
private TextureStorage _areaTexture; private TextureStorage _areaTexture;
private int[] _edgeShaderPrograms; private uint[] _edgeShaderPrograms;
private int[] _blendShaderPrograms; private uint[] _blendShaderPrograms;
private int[] _neighbourShaderPrograms; private uint[] _neighbourShaderPrograms;
private TextureStorage _edgeOutputTexture; private TextureStorage _edgeOutputTexture;
private TextureStorage _blendOutputTexture; private TextureStorage _blendOutputTexture;
private readonly string[] _qualities; private readonly string[] _qualities;
@ -39,15 +39,15 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
_quality = Math.Clamp(value, 0, _qualities.Length - 1); _quality = Math.Clamp(value, 0, _qualities.Length - 1);
} }
} }
public SmaaPostProcessingEffect(OpenGLRenderer renderer, int quality) public SmaaPostProcessingEffect(OpenGLRenderer gd, int quality)
{ {
_renderer = renderer; _gd = gd;
_edgeShaderPrograms = Array.Empty<int>(); _edgeShaderPrograms = Array.Empty<uint>();
_blendShaderPrograms = Array.Empty<int>(); _blendShaderPrograms = Array.Empty<uint>();
_neighbourShaderPrograms = Array.Empty<int>(); _neighbourShaderPrograms = Array.Empty<uint>();
_qualities = new string[] { "SMAA_PRESET_LOW", "SMAA_PRESET_MEDIUM", "SMAA_PRESET_HIGH", "SMAA_PRESET_ULTRA" }; _qualities = ["SMAA_PRESET_LOW", "SMAA_PRESET_MEDIUM", "SMAA_PRESET_HIGH", "SMAA_PRESET_ULTRA"];
Quality = quality; Quality = quality;
@ -69,9 +69,9 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
{ {
for (int i = 0; i < _edgeShaderPrograms.Length; i++) for (int i = 0; i < _edgeShaderPrograms.Length; i++)
{ {
GL.DeleteProgram(_edgeShaderPrograms[i]); _gd.Api.DeleteProgram(_edgeShaderPrograms[i]);
GL.DeleteProgram(_blendShaderPrograms[i]); _gd.Api.DeleteProgram(_blendShaderPrograms[i]);
GL.DeleteProgram(_neighbourShaderPrograms[i]); _gd.Api.DeleteProgram(_neighbourShaderPrograms[i]);
} }
} }
@ -80,9 +80,9 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
string baseShader = EmbeddedResources.ReadAllText("Ryujinx.Graphics.OpenGL/Effects/Shaders/smaa.hlsl"); string baseShader = EmbeddedResources.ReadAllText("Ryujinx.Graphics.OpenGL/Effects/Shaders/smaa.hlsl");
var pixelSizeDefine = $"#define SMAA_RT_METRICS float4(1.0 / {width}.0, 1.0 / {height}.0, {width}, {height}) \n"; var pixelSizeDefine = $"#define SMAA_RT_METRICS float4(1.0 / {width}.0, 1.0 / {height}.0, {width}, {height}) \n";
_edgeShaderPrograms = new int[_qualities.Length]; _edgeShaderPrograms = new uint[_qualities.Length];
_blendShaderPrograms = new int[_qualities.Length]; _blendShaderPrograms = new uint[_qualities.Length];
_neighbourShaderPrograms = new int[_qualities.Length]; _neighbourShaderPrograms = new uint[_qualities.Length];
for (int i = 0; i < +_edgeShaderPrograms.Length; i++) for (int i = 0; i < +_edgeShaderPrograms.Length; i++)
{ {
@ -106,12 +106,12 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
_neighbourShaderPrograms[i] = neighbourProgram; _neighbourShaderPrograms[i] = neighbourProgram;
} }
_inputUniform = GL.GetUniformLocation(_edgeShaderPrograms[0], "inputTexture"); _inputUniform = _gd.Api.GetUniformLocation(_edgeShaderPrograms[0], "inputTexture");
_outputUniform = GL.GetUniformLocation(_edgeShaderPrograms[0], "imgOutput"); _outputUniform = _gd.Api.GetUniformLocation(_edgeShaderPrograms[0], "imgOutput");
_samplerAreaUniform = GL.GetUniformLocation(_blendShaderPrograms[0], "samplerArea"); _samplerAreaUniform = _gd.Api.GetUniformLocation(_blendShaderPrograms[0], "samplerArea");
_samplerSearchUniform = GL.GetUniformLocation(_blendShaderPrograms[0], "samplerSearch"); _samplerSearchUniform = _gd.Api.GetUniformLocation(_blendShaderPrograms[0], "samplerSearch");
_samplerBlendUniform = GL.GetUniformLocation(_neighbourShaderPrograms[0], "samplerBlend"); _samplerBlendUniform = _gd.Api.GetUniformLocation(_neighbourShaderPrograms[0], "samplerBlend");
_resolutionUniform = GL.GetUniformLocation(_edgeShaderPrograms[0], "invResolution"); _resolutionUniform = _gd.Api.GetUniformLocation(_edgeShaderPrograms[0], "invResolution");
} }
private void Initialize() private void Initialize()
@ -148,8 +148,8 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
SwizzleComponent.Blue, SwizzleComponent.Blue,
SwizzleComponent.Alpha); SwizzleComponent.Alpha);
_areaTexture = new TextureStorage(_renderer, areaInfo); _areaTexture = new TextureStorage(_gd, areaInfo);
_searchTexture = new TextureStorage(_renderer, searchInfo); _searchTexture = new TextureStorage(_gd, searchInfo);
var areaTexture = EmbeddedResources.ReadFileToRentedMemory("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaAreaTexture.bin"); var areaTexture = EmbeddedResources.ReadFileToRentedMemory("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaAreaTexture.bin");
var searchTexture = EmbeddedResources.ReadFileToRentedMemory("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaSearchTexture.bin"); var searchTexture = EmbeddedResources.ReadFileToRentedMemory("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaSearchTexture.bin");
@ -166,11 +166,11 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
if (_outputTexture == null || _outputTexture.Info.Width != view.Width || _outputTexture.Info.Height != view.Height) if (_outputTexture == null || _outputTexture.Info.Width != view.Width || _outputTexture.Info.Height != view.Height)
{ {
_outputTexture?.Dispose(); _outputTexture?.Dispose();
_outputTexture = new TextureStorage(_renderer, view.Info); _outputTexture = new TextureStorage(_gd, view.Info);
_outputTexture.CreateDefaultView(); _outputTexture.CreateDefaultView();
_edgeOutputTexture = new TextureStorage(_renderer, view.Info); _edgeOutputTexture = new TextureStorage(_gd, view.Info);
_edgeOutputTexture.CreateDefaultView(); _edgeOutputTexture.CreateDefaultView();
_blendOutputTexture = new TextureStorage(_renderer, view.Info); _blendOutputTexture = new TextureStorage(_gd, view.Info);
_blendOutputTexture.CreateDefaultView(); _blendOutputTexture.CreateDefaultView();
DeleteShaders(); DeleteShaders();
@ -184,77 +184,77 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
var areaTexture = _areaTexture.DefaultView as TextureView; var areaTexture = _areaTexture.DefaultView as TextureView;
var searchTexture = _searchTexture.DefaultView as TextureView; var searchTexture = _searchTexture.DefaultView as TextureView;
var previousFramebuffer = GL.GetInteger(GetPName.FramebufferBinding); var previousFramebuffer = _gd.Api.GetInteger(GetPName.DrawFramebufferBinding);
int previousUnit = GL.GetInteger(GetPName.ActiveTexture); int previousUnit = _gd.Api.GetInteger(GetPName.ActiveTexture);
GL.ActiveTexture(TextureUnit.Texture0); _gd.Api.ActiveTexture(TextureUnit.Texture0);
int previousTextureBinding0 = GL.GetInteger(GetPName.TextureBinding2D); int previousTextureBinding0 = _gd.Api.GetInteger(GetPName.TextureBinding2D);
GL.ActiveTexture(TextureUnit.Texture1); _gd.Api.ActiveTexture(TextureUnit.Texture1);
int previousTextureBinding1 = GL.GetInteger(GetPName.TextureBinding2D); int previousTextureBinding1 = _gd.Api.GetInteger(GetPName.TextureBinding2D);
GL.ActiveTexture(TextureUnit.Texture2); _gd.Api.ActiveTexture(TextureUnit.Texture2);
int previousTextureBinding2 = GL.GetInteger(GetPName.TextureBinding2D); int previousTextureBinding2 = _gd.Api.GetInteger(GetPName.TextureBinding2D);
var framebuffer = new Framebuffer(); var framebuffer = new Framebuffer(_gd.Api);
framebuffer.Bind(); framebuffer.Bind();
framebuffer.AttachColor(0, edgeOutput); framebuffer.AttachColor(0, edgeOutput);
GL.Clear(ClearBufferMask.ColorBufferBit); _gd.Api.Clear(ClearBufferMask.ColorBufferBit);
GL.ClearColor(0, 0, 0, 0); _gd.Api.ClearColor(0, 0, 0, 0);
framebuffer.AttachColor(0, blendOutput); framebuffer.AttachColor(0, blendOutput);
GL.Clear(ClearBufferMask.ColorBufferBit); _gd.Api.Clear(ClearBufferMask.ColorBufferBit);
GL.ClearColor(0, 0, 0, 0); _gd.Api.ClearColor(0, 0, 0, 0);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, previousFramebuffer); _gd.Api.BindFramebuffer(FramebufferTarget.Framebuffer, previousFramebuffer);
framebuffer.Dispose(); framebuffer.Dispose();
var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize); var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize); var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
int previousProgram = GL.GetInteger(GetPName.CurrentProgram); uint previousProgram = (uint)_gd.Api.GetInteger(GetPName.CurrentProgram);
GL.BindImageTexture(0, edgeOutput.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8); _gd.Api.BindImageTexture(0, edgeOutput.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8);
GL.UseProgram(_edgeShaderPrograms[Quality]); _gd.Api.UseProgram(_edgeShaderPrograms[Quality]);
view.Bind(0); view.Bind(0);
GL.Uniform1(_inputUniform, 0); _gd.Api.Uniform1(_inputUniform, 0);
GL.Uniform1(_outputUniform, 0); _gd.Api.Uniform1(_outputUniform, 0);
GL.Uniform2(_resolutionUniform, (float)view.Width, (float)view.Height); _gd.Api.Uniform2(_resolutionUniform, view.Width, view.Height);
GL.DispatchCompute(dispatchX, dispatchY, 1); _gd.Api.DispatchCompute(dispatchX, dispatchY, 1);
GL.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit); _gd.Api.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit);
GL.BindImageTexture(0, blendOutput.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8); _gd.Api.BindImageTexture(0, blendOutput.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8);
GL.UseProgram(_blendShaderPrograms[Quality]); _gd.Api.UseProgram(_blendShaderPrograms[Quality]);
edgeOutput.Bind(0); edgeOutput.Bind(0);
areaTexture.Bind(1); areaTexture.Bind(1);
searchTexture.Bind(2); searchTexture.Bind(2);
GL.Uniform1(_inputUniform, 0); _gd.Api.Uniform1(_inputUniform, 0);
GL.Uniform1(_outputUniform, 0); _gd.Api.Uniform1(_outputUniform, 0);
GL.Uniform1(_samplerAreaUniform, 1); _gd.Api.Uniform1(_samplerAreaUniform, 1);
GL.Uniform1(_samplerSearchUniform, 2); _gd.Api.Uniform1(_samplerSearchUniform, 2);
GL.Uniform2(_resolutionUniform, (float)view.Width, (float)view.Height); _gd.Api.Uniform2(_resolutionUniform, view.Width, view.Height);
GL.DispatchCompute(dispatchX, dispatchY, 1); _gd.Api.DispatchCompute(dispatchX, dispatchY, 1);
GL.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit); _gd.Api.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit);
GL.BindImageTexture(0, textureView.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8); _gd.Api.BindImageTexture(0, textureView.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8);
GL.UseProgram(_neighbourShaderPrograms[Quality]); _gd.Api.UseProgram(_neighbourShaderPrograms[Quality]);
view.Bind(0); view.Bind(0);
blendOutput.Bind(1); blendOutput.Bind(1);
GL.Uniform1(_inputUniform, 0); _gd.Api.Uniform1(_inputUniform, 0);
GL.Uniform1(_outputUniform, 0); _gd.Api.Uniform1(_outputUniform, 0);
GL.Uniform1(_samplerBlendUniform, 1); _gd.Api.Uniform1(_samplerBlendUniform, 1);
GL.Uniform2(_resolutionUniform, (float)view.Width, (float)view.Height); _gd.Api.Uniform2(_resolutionUniform, view.Width, view.Height);
GL.DispatchCompute(dispatchX, dispatchY, 1); _gd.Api.DispatchCompute(dispatchX, dispatchY, 1);
GL.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit); _gd.Api.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit);
(_renderer.Pipeline as Pipeline).RestoreImages1And2(); (_gd.Pipeline as Pipeline).RestoreImages1And2();
GL.UseProgram(previousProgram); _gd.Api.UseProgram(previousProgram);
GL.ActiveTexture(TextureUnit.Texture0); _gd.Api.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, previousTextureBinding0); _gd.Api.BindTexture(TextureTarget.Texture2D, previousTextureBinding0);
GL.ActiveTexture(TextureUnit.Texture1); _gd.Api.ActiveTexture(TextureUnit.Texture1);
GL.BindTexture(TextureTarget.Texture2D, previousTextureBinding1); _gd.Api.BindTexture(TextureTarget.Texture2D, previousTextureBinding1);
GL.ActiveTexture(TextureUnit.Texture2); _gd.Api.ActiveTexture(TextureUnit.Texture2);
GL.BindTexture(TextureTarget.Texture2D, previousTextureBinding2); _gd.Api.BindTexture(TextureTarget.Texture2D, previousTextureBinding2);
GL.ActiveTexture((TextureUnit)previousUnit); _gd.Api.ActiveTexture((TextureUnit)previousUnit);
return textureView; return textureView;
} }

View file

@ -23,14 +23,15 @@ namespace Ryujinx.Graphics.OpenGL
public Framebuffer(GL api) public Framebuffer(GL api)
{ {
Handle = GL.GenFramebuffer(); _api = api;
_clearFbHandle = GL.GenFramebuffer();
Handle = _api.GenFramebuffer();
_clearFbHandle = _api.GenFramebuffer();
_colors = new TextureView[8]; _colors = new TextureView[8];
_api = api;
} }
public int Bind() public uint Bind()
{ {
_api.BindFramebuffer(FramebufferTarget.Framebuffer, Handle); _api.BindFramebuffer(FramebufferTarget.Framebuffer, Handle);
return Handle; return Handle;
@ -203,7 +204,7 @@ namespace Ryujinx.Graphics.OpenGL
if (!_clearFbInitialized) if (!_clearFbInitialized)
{ {
SetDrawBuffersImpl(Constants.MaxRenderTargets); SetDrawBuffersImpl(_api, Constants.MaxRenderTargets);
_clearFbInitialized = true; _clearFbInitialized = true;
} }
} }

View file

@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
class Sampler : ISampler class Sampler : ISampler
{ {
public uint Handle { get; private set; } public uint Handle { get; private set; }
private GL _api; private readonly GL _api;
public Sampler(GL api, SamplerCreateInfo info) public Sampler(GL api, SamplerCreateInfo info)
{ {

View file

@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
class TextureBase class TextureBase
{ {
private readonly protected GL Api; private readonly protected OpenGLRenderer _gd;
public uint Handle { get; protected set; } public uint Handle { get; protected set; }
public TextureCreateInfo Info { get; } public TextureCreateInfo Info { get; }
@ -16,12 +16,12 @@ namespace Ryujinx.Graphics.OpenGL.Image
public Target Target => Info.Target; public Target Target => Info.Target;
public Format Format => Info.Format; public Format Format => Info.Format;
public TextureBase(GL api, TextureCreateInfo info) public TextureBase(OpenGLRenderer gd, TextureCreateInfo info)
{ {
Api = api; _gd = gd;
Info = info; Info = info;
Handle = Api.GenTexture(); Handle = _gd.Api.GenTexture();
} }
public void Bind(uint unit) public void Bind(uint unit)
@ -31,8 +31,8 @@ namespace Ryujinx.Graphics.OpenGL.Image
protected void Bind(TextureTarget target, uint unit) protected void Bind(TextureTarget target, uint unit)
{ {
Api.ActiveTexture((TextureUnit)((uint)TextureUnit.Texture0 + unit)); _gd.Api.ActiveTexture((TextureUnit)((uint)TextureUnit.Texture0 + unit));
Api.BindTexture(target, Handle); _gd.Api.BindTexture(target, Handle);
} }
public static void ClearBinding(GL api, uint unit) public static void ClearBinding(GL api, uint unit)

View file

@ -7,16 +7,15 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
class TextureBuffer : TextureBase, ITexture class TextureBuffer : TextureBase, ITexture
{ {
private readonly OpenGLRenderer _renderer;
private int _bufferOffset; private int _bufferOffset;
private int _bufferSize; private int _bufferSize;
private int _bufferCount; private int _bufferCount;
private BufferHandle _buffer; private BufferHandle _buffer;
public TextureBuffer(GL api, OpenGLRenderer renderer, TextureCreateInfo info) : base(api, info) public TextureBuffer(OpenGLRenderer gd, TextureCreateInfo info) : base(gd, info)
{ {
_renderer = renderer;
} }
public void CopyTo(ITexture destination, int firstLayer, int firstLevel) public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
@ -41,7 +40,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
public PinnedSpan<byte> GetData() public PinnedSpan<byte> GetData()
{ {
return Buffer.GetData(Api, _renderer, _buffer, _bufferOffset, _bufferSize); return Buffer.GetData(_gd, _buffer, _bufferOffset, _bufferSize);
} }
public PinnedSpan<byte> GetData(int layer, int level) public PinnedSpan<byte> GetData(int layer, int level)
@ -59,7 +58,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
var dataSpan = data.Memory.Span; var dataSpan = data.Memory.Span;
Buffer.SetData(Api, _buffer, _bufferOffset, dataSpan[..Math.Min(dataSpan.Length, _bufferSize)]); Buffer.SetData(_gd.Api, _buffer, _bufferOffset, dataSpan[..Math.Min(dataSpan.Length, _bufferSize)]);
data.Dispose(); data.Dispose();
} }
@ -82,7 +81,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
_buffer == buffer.Handle && _buffer == buffer.Handle &&
buffer.Offset == _bufferOffset && buffer.Offset == _bufferOffset &&
buffer.Size == _bufferSize && buffer.Size == _bufferSize &&
_renderer.BufferCount == _bufferCount) _gd.BufferCount == _bufferCount)
{ {
// Only rebind the buffer when more have been created. // Only rebind the buffer when more have been created.
return; return;
@ -91,20 +90,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
_buffer = buffer.Handle; _buffer = buffer.Handle;
_bufferOffset = buffer.Offset; _bufferOffset = buffer.Offset;
_bufferSize = buffer.Size; _bufferSize = buffer.Size;
_bufferCount = _renderer.BufferCount; _bufferCount = _gd.BufferCount;
Bind(0); Bind(0);
SizedInternalFormat format = (SizedInternalFormat)FormatTable.GetFormatInfo(Info.Format).InternalFormat; SizedInternalFormat format = (SizedInternalFormat)FormatTable.GetFormatInfo(Info.Format).InternalFormat;
Api.TexBufferRange(TextureTarget.TextureBuffer, format, _buffer.ToUInt32(), buffer.Offset, (uint)buffer.Size); _gd.Api.TexBufferRange(TextureTarget.TextureBuffer, format, _buffer.ToUInt32(), buffer.Offset, (uint)buffer.Size);
} }
public void Dispose() public void Dispose()
{ {
if (Handle != 0) if (Handle != 0)
{ {
Api.DeleteTexture(Handle); _gd.Api.DeleteTexture(Handle);
Handle = 0; Handle = 0;
} }

View file

@ -7,8 +7,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
class TextureCopy : IDisposable class TextureCopy : IDisposable
{ {
private readonly GL _api; private readonly OpenGLRenderer _gd;
private readonly OpenGLRenderer _renderer;
private uint _srcFramebuffer; private uint _srcFramebuffer;
private uint _dstFramebuffer; private uint _dstFramebuffer;
@ -18,11 +17,10 @@ namespace Ryujinx.Graphics.OpenGL.Image
public IntermediatePool IntermediatePool { get; } public IntermediatePool IntermediatePool { get; }
public TextureCopy(GL api, OpenGLRenderer renderer) public TextureCopy(OpenGLRenderer gd)
{ {
_api = api; _gd = gd;
_renderer = renderer; IntermediatePool = new IntermediatePool(gd);
IntermediatePool = new IntermediatePool(renderer);
} }
public void Copy( public void Copy(
@ -57,10 +55,10 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
TextureView srcConverted = src.Format.IsBgr() != dst.Format.IsBgr() ? BgraSwap(src) : src; TextureView srcConverted = src.Format.IsBgr() != dst.Format.IsBgr() ? BgraSwap(src) : src;
(uint oldDrawFramebufferHandle, uint oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers(); (uint oldDrawFramebufferHandle, uint oldReadFramebufferHandle) = ((Pipeline)_gd.Pipeline).GetBoundFramebuffers();
_api.BindFramebuffer(FramebufferTarget.ReadFramebuffer, GetSrcFramebufferLazy()); _gd.Api.BindFramebuffer(FramebufferTarget.ReadFramebuffer, GetSrcFramebufferLazy());
_api.BindFramebuffer(FramebufferTarget.DrawFramebuffer, GetDstFramebufferLazy()); _gd.Api.BindFramebuffer(FramebufferTarget.DrawFramebuffer, GetDstFramebufferLazy());
if (srcLevel != 0) if (srcLevel != 0)
{ {
@ -78,13 +76,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
if ((srcLayer | dstLayer) != 0 || layers > 1) if ((srcLayer | dstLayer) != 0 || layers > 1)
{ {
Attach(_api, FramebufferTarget.ReadFramebuffer, src.Format, srcConverted.Handle, srcLevel + level, srcLayer + layer); Attach(_gd.Api, FramebufferTarget.ReadFramebuffer, src.Format, srcConverted.Handle, srcLevel + level, srcLayer + layer);
Attach(_api, FramebufferTarget.DrawFramebuffer, dst.Format, dst.Handle, dstLevel + level, dstLayer + layer); Attach(_gd.Api, FramebufferTarget.DrawFramebuffer, dst.Format, dst.Handle, dstLevel + level, dstLayer + layer);
} }
else else
{ {
Attach(_api, FramebufferTarget.ReadFramebuffer, src.Format, srcConverted.Handle, srcLevel + level); Attach(_gd.Api, FramebufferTarget.ReadFramebuffer, src.Format, srcConverted.Handle, srcLevel + level);
Attach(_api, FramebufferTarget.DrawFramebuffer, dst.Format, dst.Handle, dstLevel + level); Attach(_gd.Api, FramebufferTarget.DrawFramebuffer, dst.Format, dst.Handle, dstLevel + level);
} }
ClearBufferMask mask = GetMask(src.Format); ClearBufferMask mask = GetMask(src.Format);
@ -98,13 +96,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
? BlitFramebufferFilter.Linear ? BlitFramebufferFilter.Linear
: BlitFramebufferFilter.Nearest; : BlitFramebufferFilter.Nearest;
_api.ReadBuffer(ReadBufferMode.ColorAttachment0); _gd.Api.ReadBuffer(ReadBufferMode.ColorAttachment0);
_api.DrawBuffer(DrawBufferMode.ColorAttachment0); _gd.Api.DrawBuffer(DrawBufferMode.ColorAttachment0);
_api.Disable(EnableCap.RasterizerDiscard); _gd.Api.Disable(EnableCap.RasterizerDiscard);
_api.Disable(EnableCap.ScissorTest, 0); _gd.Api.Disable(EnableCap.ScissorTest, 0);
_api.BlitFramebuffer( _gd.Api.BlitFramebuffer(
srcRegion.X1, srcRegion.X1,
srcRegion.Y1, srcRegion.Y1,
srcRegion.X2, srcRegion.X2,
@ -124,14 +122,14 @@ namespace Ryujinx.Graphics.OpenGL.Image
} }
} }
Attach(_api, FramebufferTarget.ReadFramebuffer, src.Format, 0); Attach(_gd.Api, FramebufferTarget.ReadFramebuffer, src.Format, 0);
Attach(_api, FramebufferTarget.DrawFramebuffer, dst.Format, 0); Attach(_gd.Api, FramebufferTarget.DrawFramebuffer, dst.Format, 0);
_api.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); _gd.Api.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle);
_api.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); _gd.Api.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle);
((Pipeline)_renderer.Pipeline).RestoreScissor0Enable(); ((Pipeline)_gd.Pipeline).RestoreScissor0Enable();
((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard(); ((Pipeline)_gd.Pipeline).RestoreRasterizerDiscard();
if (srcConverted != src) if (srcConverted != src)
{ {
@ -180,8 +178,8 @@ namespace Ryujinx.Graphics.OpenGL.Image
TextureCreateInfo srcInfo = src.Info; TextureCreateInfo srcInfo = src.Info;
TextureCreateInfo dstInfo = dst.Info; TextureCreateInfo dstInfo = dst.Info;
uint srcHandle = (uint)src.Handle; uint srcHandle = src.Handle;
uint dstHandle = (uint)dst.Handle; uint dstHandle = dst.Handle;
int srcWidth = srcInfo.Width; int srcWidth = srcInfo.Width;
int srcHeight = srcInfo.Height; int srcHeight = srcInfo.Height;
@ -242,7 +240,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows) if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows)
{ {
_api.CopyImageSubData( _gd.Api.CopyImageSubData(
src.Storage.Handle, src.Storage.Handle,
src.Storage.Info.Target.ConvertToImageTarget(), src.Storage.Info.Target.ConvertToImageTarget(),
(int)src.FirstLevel + srcLevel + level, (int)src.FirstLevel + srcLevel + level,
@ -261,7 +259,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
} }
else else
{ {
_api.CopyImageSubData( _gd.Api.CopyImageSubData(
srcHandle, srcHandle,
srcInfo.Target.ConvertToImageTarget(), srcInfo.Target.ConvertToImageTarget(),
srcLevel + level, srcLevel + level,
@ -346,20 +344,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
public TextureView BgraSwap(TextureView from) public TextureView BgraSwap(TextureView from)
{ {
TextureView to = (TextureView)_renderer.CreateTexture(from.Info); TextureView to = (TextureView)_gd.CreateTexture(from.Info);
EnsurePbo(from); EnsurePbo(from);
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyPboHandle); _gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyPboHandle);
from.WriteToPbo(0, forceBgra: true); from.WriteToPbo(0, forceBgra: true);
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0); _gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
_api.BindBuffer(BufferTargetARB.PixelUnpackBuffer, _copyPboHandle); _gd.Api.BindBuffer(BufferTargetARB.PixelUnpackBuffer, _copyPboHandle);
to.ReadFromPbo(0, _copyPboSize); to.ReadFromPbo(0, _copyPboSize);
_api.BindBuffer(BufferTargetARB.PixelUnpackBuffer, 0); _gd.Api.BindBuffer(BufferTargetARB.PixelUnpackBuffer, 0);
return to; return to;
} }
@ -395,7 +393,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
EnsurePbo(from); EnsurePbo(from);
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyPboHandle); _gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyPboHandle);
// The source texture is written out in full, then the destination is taken as a slice from the data using unpack params. // The source texture is written out in full, then the destination is taken as a slice from the data using unpack params.
// The offset points to the base at which the requested layer is at. // The offset points to the base at which the requested layer is at.
@ -409,39 +407,39 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (slice) if (slice)
{ {
// Set unpack parameters to take a slice of width/height: // Set unpack parameters to take a slice of width/height:
_api.PixelStore(PixelStoreParameter.UnpackRowLength, unpackWidth); _gd.Api.PixelStore(PixelStoreParameter.UnpackRowLength, unpackWidth);
_api.PixelStore(PixelStoreParameter.UnpackImageHeight, unpackHeight); _gd.Api.PixelStore(PixelStoreParameter.UnpackImageHeight, unpackHeight);
if (to.Info.IsCompressed) if (to.Info.IsCompressed)
{ {
_api.PixelStore(GLEnum.UnpackCompressedBlockWidth, to.Info.BlockWidth); _gd.Api.PixelStore(GLEnum.UnpackCompressedBlockWidth, to.Info.BlockWidth);
_api.PixelStore(GLEnum.UnpackCompressedBlockHeight, to.Info.BlockHeight); _gd.Api.PixelStore(GLEnum.UnpackCompressedBlockHeight, to.Info.BlockHeight);
_api.PixelStore(GLEnum.UnpackCompressedBlockDepth, 1); _gd.Api.PixelStore(GLEnum.UnpackCompressedBlockDepth, 1);
_api.PixelStore(GLEnum.UnpackCompressedBlockSize, to.Info.BytesPerPixel); _gd.Api.PixelStore(GLEnum.UnpackCompressedBlockSize, to.Info.BytesPerPixel);
} }
} }
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0); _gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
_api.BindBuffer(BufferTargetARB.PixelUnpackBuffer, _copyPboHandle); _gd.Api.BindBuffer(BufferTargetARB.PixelUnpackBuffer, _copyPboHandle);
to.ReadFromPbo2D(offset, dstLayer, dstLevel, dstWidth, dstHeight); to.ReadFromPbo2D(offset, dstLayer, dstLevel, dstWidth, dstHeight);
if (slice) if (slice)
{ {
// Reset unpack parameters // Reset unpack parameters
_api.PixelStore(PixelStoreParameter.UnpackRowLength, 0); _gd.Api.PixelStore(PixelStoreParameter.UnpackRowLength, 0);
_api.PixelStore(PixelStoreParameter.UnpackImageHeight, 0); _gd.Api.PixelStore(PixelStoreParameter.UnpackImageHeight, 0);
if (to.Info.IsCompressed) if (to.Info.IsCompressed)
{ {
_api.PixelStore(GLEnum.UnpackCompressedBlockWidth, 0); _gd.Api.PixelStore(GLEnum.UnpackCompressedBlockWidth, 0);
_api.PixelStore(GLEnum.UnpackCompressedBlockHeight, 0); _gd.Api.PixelStore(GLEnum.UnpackCompressedBlockHeight, 0);
_api.PixelStore(GLEnum.UnpackCompressedBlockDepth, 0); _gd.Api.PixelStore(GLEnum.UnpackCompressedBlockDepth, 0);
_api.PixelStore(GLEnum.UnpackCompressedBlockSize, 0); _gd.Api.PixelStore(GLEnum.UnpackCompressedBlockSize, 0);
} }
} }
_api.BindBuffer(BufferTargetARB.PixelUnpackBuffer, 0); _gd.Api.BindBuffer(BufferTargetARB.PixelUnpackBuffer, 0);
} }
private void EnsurePbo(TextureView view) private void EnsurePbo(TextureView view)
@ -455,18 +453,18 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (_copyPboSize < requiredSize && _copyPboHandle != 0) if (_copyPboSize < requiredSize && _copyPboHandle != 0)
{ {
_api.DeleteBuffer(_copyPboHandle); _gd.Api.DeleteBuffer(_copyPboHandle);
_copyPboHandle = 0; _copyPboHandle = 0;
} }
if (_copyPboHandle == 0) if (_copyPboHandle == 0)
{ {
_copyPboHandle = _api.GenBuffer(); _copyPboHandle = _gd.Api.GenBuffer();
_copyPboSize = requiredSize; _copyPboSize = requiredSize;
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyPboHandle); _gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyPboHandle);
_api.BufferData(BufferTargetARB.PixelPackBuffer, (uint)requiredSize, IntPtr.Zero, BufferUsageARB.DynamicCopy); _gd.Api.BufferData(BufferTargetARB.PixelPackBuffer, (uint)requiredSize, IntPtr.Zero, BufferUsageARB.DynamicCopy);
} }
} }
@ -474,7 +472,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
if (_srcFramebuffer == 0) if (_srcFramebuffer == 0)
{ {
_srcFramebuffer = _api.GenFramebuffer(); _srcFramebuffer = _gd.Api.GenFramebuffer();
} }
return _srcFramebuffer; return _srcFramebuffer;
@ -484,7 +482,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
if (_dstFramebuffer == 0) if (_dstFramebuffer == 0)
{ {
_dstFramebuffer = _api.GenFramebuffer(); _dstFramebuffer = _gd.Api.GenFramebuffer();
} }
return _dstFramebuffer; return _dstFramebuffer;
@ -494,21 +492,21 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
if (_srcFramebuffer != 0) if (_srcFramebuffer != 0)
{ {
_api.DeleteFramebuffer(_srcFramebuffer); _gd.Api.DeleteFramebuffer(_srcFramebuffer);
_srcFramebuffer = 0; _srcFramebuffer = 0;
} }
if (_dstFramebuffer != 0) if (_dstFramebuffer != 0)
{ {
_api.DeleteFramebuffer(_dstFramebuffer); _gd.Api.DeleteFramebuffer(_dstFramebuffer);
_dstFramebuffer = 0; _dstFramebuffer = 0;
} }
if (_copyPboHandle != 0) if (_copyPboHandle != 0)
{ {
_api.DeleteBuffer(_copyPboHandle); _gd.Api.DeleteBuffer(_copyPboHandle);
_copyPboHandle = 0; _copyPboHandle = 0;
} }

View file

@ -67,15 +67,13 @@ void main()
imageStore(dst, ivec2(coords), uvec4(r, g, b, a)); imageStore(dst, ivec2(coords), uvec4(r, g, b, a));
}"; }";
private readonly GL _api; private readonly OpenGLRenderer _gd;
private readonly OpenGLRenderer _renderer;
private readonly Dictionary<int, uint> _shorteningProgramHandles; private readonly Dictionary<int, uint> _shorteningProgramHandles;
private readonly Dictionary<int, uint> _wideningProgramHandles; private readonly Dictionary<int, uint> _wideningProgramHandles;
public TextureCopyIncompatible(GL api, OpenGLRenderer renderer) public TextureCopyIncompatible(OpenGLRenderer gd)
{ {
_api = api; _gd = gd;
_renderer = renderer;
_shorteningProgramHandles = new Dictionary<int, uint>(); _shorteningProgramHandles = new Dictionary<int, uint>();
_wideningProgramHandles = new Dictionary<int, uint>(); _wideningProgramHandles = new Dictionary<int, uint>();
} }
@ -96,7 +94,7 @@ void main()
var srcFormat = (InternalFormat)GetFormat(componentSize, srcComponentsCount); var srcFormat = (InternalFormat)GetFormat(componentSize, srcComponentsCount);
var dstFormat = (InternalFormat)GetFormat(componentSize, dstComponentsCount); var dstFormat = (InternalFormat)GetFormat(componentSize, dstComponentsCount);
_api.UseProgram(srcBpp < dstBpp _gd.Api.UseProgram(srcBpp < dstBpp
? GetWideningShader(componentSize, srcComponentsCount, dstComponentsCount) ? GetWideningShader(componentSize, srcComponentsCount, dstComponentsCount)
: GetShorteningShader(componentSize, srcComponentsCount, dstComponentsCount)); : GetShorteningShader(componentSize, srcComponentsCount, dstComponentsCount));
@ -113,14 +111,14 @@ void main()
for (int z = 0; z < depth; z++) for (int z = 0; z < depth; z++)
{ {
_api.BindImageTexture(0, src.Handle, srcLevel + l, false, srcLayer + z, BufferAccessARB.ReadOnly, srcFormat); _gd.Api.BindImageTexture(0, src.Handle, srcLevel + l, false, srcLayer + z, BufferAccessARB.ReadOnly, srcFormat);
_api.BindImageTexture(1, dst.Handle, dstLevel + l, false, dstLayer + z, BufferAccessARB.WriteOnly, dstFormat); _gd.Api.BindImageTexture(1, dst.Handle, dstLevel + l, false, dstLayer + z, BufferAccessARB.WriteOnly, dstFormat);
_api.DispatchCompute((width + 31) / 32, (height + 31) / 32, 1); _gd.Api.DispatchCompute((width + 31) / 32, (height + 31) / 32, 1);
} }
} }
Pipeline pipeline = (Pipeline)_renderer.Pipeline; Pipeline pipeline = (Pipeline)_gd.Pipeline;
pipeline.RestoreProgram(); pipeline.RestoreProgram();
pipeline.RestoreImages1And2(); pipeline.RestoreImages1And2();
@ -190,7 +188,7 @@ void main()
if (!programHandles.TryGetValue(key, out uint programHandle)) if (!programHandles.TryGetValue(key, out uint programHandle))
{ {
uint csHandle = _api.CreateShader(ShaderType.ComputeShader); uint csHandle = _gd.Api.CreateShader(ShaderType.ComputeShader);
string[] formatTable = new[] { "r8ui", "r16ui", "r32ui", "rg8ui", "rg16ui", "rg32ui", "rgba8ui", "rgba16ui", "rgba32ui" }; string[] formatTable = new[] { "r8ui", "r16ui", "r32ui", "rg8ui", "rg16ui", "rg32ui", "rgba8ui", "rgba16ui", "rgba32ui" };
@ -203,25 +201,25 @@ void main()
int ratio = srcBpp < dstBpp ? dstBpp / srcBpp : srcBpp / dstBpp; int ratio = srcBpp < dstBpp ? dstBpp / srcBpp : srcBpp / dstBpp;
int ratioLog2 = BitOperations.Log2((uint)ratio); int ratioLog2 = BitOperations.Log2((uint)ratio);
_api.ShaderSource(csHandle, code _gd.Api.ShaderSource(csHandle, code
.Replace("$SRC_FORMAT$", srcFormat) .Replace("$SRC_FORMAT$", srcFormat)
.Replace("$DST_FORMAT$", dstFormat) .Replace("$DST_FORMAT$", dstFormat)
.Replace("$RATIO_LOG2$", ratioLog2.ToString(CultureInfo.InvariantCulture))); .Replace("$RATIO_LOG2$", ratioLog2.ToString(CultureInfo.InvariantCulture)));
_api.CompileShader(csHandle); _gd.Api.CompileShader(csHandle);
programHandle = _api.CreateProgram(); programHandle = _gd.Api.CreateProgram();
_api.AttachShader(programHandle, csHandle); _gd.Api.AttachShader(programHandle, csHandle);
_api.LinkProgram(programHandle); _gd.Api.LinkProgram(programHandle);
_api.DetachShader(programHandle, csHandle); _gd.Api.DetachShader(programHandle, csHandle);
_api.DeleteShader(csHandle); _gd.Api.DeleteShader(csHandle);
_api.GetProgram(programHandle, ProgramPropertyARB.LinkStatus, out int status); _gd.Api.GetProgram(programHandle, ProgramPropertyARB.LinkStatus, out int status);
if (status == 0) if (status == 0)
{ {
throw new Exception(_api.GetProgramInfoLog(programHandle)); throw new Exception(_gd.Api.GetProgramInfoLog(programHandle));
} }
programHandles.Add(key, programHandle); programHandles.Add(key, programHandle);
@ -234,14 +232,14 @@ void main()
{ {
foreach (uint handle in _shorteningProgramHandles.Values) foreach (uint handle in _shorteningProgramHandles.Values)
{ {
_api.DeleteProgram(handle); _gd.Api.DeleteProgram(handle);
} }
_shorteningProgramHandles.Clear(); _shorteningProgramHandles.Clear();
foreach (uint handle in _wideningProgramHandles.Values) foreach (uint handle in _wideningProgramHandles.Values)
{ {
_api.DeleteProgram(handle); _gd.Api.DeleteProgram(handle);
} }
_wideningProgramHandles.Clear(); _wideningProgramHandles.Clear();

View file

@ -93,15 +93,13 @@ void main()
imageStore(imgOut, ivec2(int(coords.x) >> samplesInXLog2, int(coords.y) >> samplesInYLog2), sampleIdx, value); imageStore(imgOut, ivec2(int(coords.x) >> samplesInXLog2, int(coords.y) >> samplesInYLog2), sampleIdx, value);
}"; }";
private readonly GL _api; private readonly OpenGLRenderer _gd;
private readonly OpenGLRenderer _renderer;
private readonly uint[] _msToNonMSProgramHandles; private readonly uint[] _msToNonMSProgramHandles;
private readonly uint[] _nonMSToMSProgramHandles; private readonly uint[] _nonMSToMSProgramHandles;
public TextureCopyMS(GL api, OpenGLRenderer renderer) public TextureCopyMS(OpenGLRenderer gd)
{ {
_api = api; _gd = gd;
_renderer = renderer;
_msToNonMSProgramHandles = new uint[5]; _msToNonMSProgramHandles = new uint[5];
_nonMSToMSProgramHandles = new uint[5]; _nonMSToMSProgramHandles = new uint[5];
} }
@ -117,17 +115,17 @@ void main()
uint dstWidth = (uint)dstInfo.Width; uint dstWidth = (uint)dstInfo.Width;
uint dstHeight = (uint)dstInfo.Height; uint dstHeight = (uint)dstInfo.Height;
_api.UseProgram(GetMSToNonMSShader(srcInfo.BytesPerPixel)); _gd.Api.UseProgram(GetMSToNonMSShader(srcInfo.BytesPerPixel));
for (int z = 0; z < depth; z++) for (int z = 0; z < depth; z++)
{ {
_api.BindImageTexture(0, srcHandle, 0, false, srcLayer + z, BufferAccessARB.ReadOnly, (InternalFormat)GetFormat(srcInfo.BytesPerPixel)); _gd.Api.BindImageTexture(0, srcHandle, 0, false, srcLayer + z, BufferAccessARB.ReadOnly, (InternalFormat)GetFormat(srcInfo.BytesPerPixel));
_api.BindImageTexture(1, dstHandle, 0, false, dstLayer + z, BufferAccessARB.WriteOnly, (InternalFormat)GetFormat(dstInfo.BytesPerPixel)); _gd.Api.BindImageTexture(1, dstHandle, 0, false, dstLayer + z, BufferAccessARB.WriteOnly, (InternalFormat)GetFormat(dstInfo.BytesPerPixel));
_api.DispatchCompute((dstWidth + 31) / 32, (dstHeight + 31) / 32, 1); _gd.Api.DispatchCompute((dstWidth + 31) / 32, (dstHeight + 31) / 32, 1);
} }
Pipeline pipeline = (Pipeline)_renderer.Pipeline; Pipeline pipeline = (Pipeline)_gd.Pipeline;
pipeline.RestoreProgram(); pipeline.RestoreProgram();
pipeline.RestoreImages1And2(); pipeline.RestoreImages1And2();
@ -147,17 +145,17 @@ void main()
uint srcWidth = (uint)srcInfo.Width; uint srcWidth = (uint)srcInfo.Width;
uint srcHeight = (uint)srcInfo.Height; uint srcHeight = (uint)srcInfo.Height;
_api.UseProgram(GetNonMSToMSShader(srcInfo.BytesPerPixel)); _gd.Api.UseProgram(GetNonMSToMSShader(srcInfo.BytesPerPixel));
for (int z = 0; z < depth; z++) for (int z = 0; z < depth; z++)
{ {
_api.BindImageTexture(0, srcHandle, 0, false, srcLayer + z, BufferAccessARB.ReadOnly, (InternalFormat)GetFormat(srcInfo.BytesPerPixel)); _gd.Api.BindImageTexture(0, srcHandle, 0, false, srcLayer + z, BufferAccessARB.ReadOnly, (InternalFormat)GetFormat(srcInfo.BytesPerPixel));
_api.BindImageTexture(1, dstHandle, 0, false, dstLayer + z, BufferAccessARB.WriteOnly, (InternalFormat)GetFormat(dstInfo.BytesPerPixel)); _gd.Api.BindImageTexture(1, dstHandle, 0, false, dstLayer + z, BufferAccessARB.WriteOnly, (InternalFormat)GetFormat(dstInfo.BytesPerPixel));
_api.DispatchCompute((srcWidth + 31) / 32, (srcHeight + 31) / 32, 1); _gd.Api.DispatchCompute((srcWidth + 31) / 32, (srcHeight + 31) / 32, 1);
} }
Pipeline pipeline = (Pipeline)_renderer.Pipeline; Pipeline pipeline = (Pipeline)_gd.Pipeline;
pipeline.RestoreProgram(); pipeline.RestoreProgram();
pipeline.RestoreImages1And2(); pipeline.RestoreImages1And2();
@ -185,9 +183,9 @@ void main()
// we need to create and bind a RGBA view for it to work. // we need to create and bind a RGBA view for it to work.
if (texture.Info.Format == Format.R8G8B8A8Srgb) if (texture.Info.Format == Format.R8G8B8A8Srgb)
{ {
uint handle = _api.GenTexture(); uint handle = _gd.Api.GenTexture();
_api.TextureView( _gd.Api.TextureView(
handle, handle,
texture.Info.Target.Convert(), texture.Info.Target.Convert(),
texture.Storage.Handle, texture.Storage.Handle,
@ -207,7 +205,7 @@ void main()
{ {
if (info.Handle != handle) if (info.Handle != handle)
{ {
_api.DeleteTexture(handle); _gd.Api.DeleteTexture(handle);
} }
} }
@ -227,25 +225,25 @@ void main()
if (programHandles[index] == 0) if (programHandles[index] == 0)
{ {
uint csHandle = _api.CreateShader(ShaderType.ComputeShader); uint csHandle = _gd.Api.CreateShader(ShaderType.ComputeShader);
string format = new[] { "r8ui", "r16ui", "r32ui", "rg32ui", "rgba32ui" }[index]; string format = new[] { "r8ui", "r16ui", "r32ui", "rg32ui", "rgba32ui" }[index];
_api.ShaderSource(csHandle, code.Replace("$FORMAT$", format)); _gd.Api.ShaderSource(csHandle, code.Replace("$FORMAT$", format));
_api.CompileShader(csHandle); _gd.Api.CompileShader(csHandle);
uint programHandle = _api.CreateProgram(); uint programHandle = _gd.Api.CreateProgram();
_api.AttachShader(programHandle, csHandle); _gd.Api.AttachShader(programHandle, csHandle);
_api.LinkProgram(programHandle); _gd.Api.LinkProgram(programHandle);
_api.DetachShader(programHandle, csHandle); _gd.Api.DetachShader(programHandle, csHandle);
_api.DeleteShader(csHandle); _gd.Api.DeleteShader(csHandle);
_api.GetProgram(programHandle, ProgramPropertyARB.LinkStatus, out int status); _gd.Api.GetProgram(programHandle, ProgramPropertyARB.LinkStatus, out int status);
if (status == 0) if (status == 0)
{ {
throw new Exception(_api.GetProgramInfoLog(programHandle)); throw new Exception(_gd.Api.GetProgramInfoLog(programHandle));
} }
programHandles[index] = programHandle; programHandles[index] = programHandle;
@ -260,7 +258,7 @@ void main()
{ {
if (_msToNonMSProgramHandles[i] != 0) if (_msToNonMSProgramHandles[i] != 0)
{ {
_api.DeleteProgram(_msToNonMSProgramHandles[i]); _gd.Api.DeleteProgram(_msToNonMSProgramHandles[i]);
_msToNonMSProgramHandles[i] = 0; _msToNonMSProgramHandles[i] = 0;
} }
} }
@ -269,7 +267,7 @@ void main()
{ {
if (_nonMSToMSProgramHandles[i] != 0) if (_nonMSToMSProgramHandles[i] != 0)
{ {
_api.DeleteProgram(_nonMSToMSProgramHandles[i]); _gd.Api.DeleteProgram(_nonMSToMSProgramHandles[i]);
_nonMSToMSProgramHandles[i] = 0; _nonMSToMSProgramHandles[i] = 0;
} }
} }

View file

@ -11,20 +11,18 @@ namespace Ryujinx.Graphics.OpenGL.Image
public TextureCreateInfo Info { get; } public TextureCreateInfo Info { get; }
private readonly OpenGLRenderer _renderer; private readonly OpenGLRenderer _gd;
private readonly GL _api;
private int _viewsCount; private int _viewsCount;
internal ITexture DefaultView { get; private set; } internal ITexture DefaultView { get; private set; }
public TextureStorage(GL api, OpenGLRenderer renderer, TextureCreateInfo info) public TextureStorage(OpenGLRenderer gd, TextureCreateInfo info)
{ {
_api = api; _gd = gd;
_renderer = renderer;
Info = info; Info = info;
Handle = _api.GenTexture(); Handle = _gd.Api.GenTexture();
CreateImmutableStorage(); CreateImmutableStorage();
} }
@ -33,9 +31,9 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
TextureTarget target = Info.Target.Convert(); TextureTarget target = Info.Target.Convert();
_api.ActiveTexture(TextureUnit.Texture0); _gd.Api.ActiveTexture(TextureUnit.Texture0);
_api.BindTexture(target, Handle); _gd.Api.BindTexture(target, Handle);
FormatInfo format = FormatTable.GetFormatInfo(Info.Format); FormatInfo format = FormatTable.GetFormatInfo(Info.Format);
@ -55,7 +53,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
switch (Info.Target) switch (Info.Target)
{ {
case Target.Texture1D: case Target.Texture1D:
_api.TexStorage1D( _gd.Api.TexStorage1D(
TextureTarget.Texture1D, TextureTarget.Texture1D,
levels, levels,
internalFormat, internalFormat,
@ -63,7 +61,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break; break;
case Target.Texture1DArray: case Target.Texture1DArray:
_api.TexStorage2D( _gd.Api.TexStorage2D(
TextureTarget.Texture1DArray, TextureTarget.Texture1DArray,
levels, levels,
internalFormat, internalFormat,
@ -72,7 +70,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break; break;
case Target.Texture2D: case Target.Texture2D:
_api.TexStorage2D( _gd.Api.TexStorage2D(
TextureTarget.Texture2D, TextureTarget.Texture2D,
levels, levels,
internalFormat, internalFormat,
@ -81,7 +79,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break; break;
case Target.Texture2DArray: case Target.Texture2DArray:
_api.TexStorage3D( _gd.Api.TexStorage3D(
TextureTarget.Texture2DArray, TextureTarget.Texture2DArray,
levels, levels,
internalFormat, internalFormat,
@ -91,7 +89,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break; break;
case Target.Texture2DMultisample: case Target.Texture2DMultisample:
_api.TexStorage2DMultisample( _gd.Api.TexStorage2DMultisample(
TextureTarget.Texture2DMultisample, TextureTarget.Texture2DMultisample,
(uint)Info.Samples, (uint)Info.Samples,
internalFormat, internalFormat,
@ -101,7 +99,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break; break;
case Target.Texture2DMultisampleArray: case Target.Texture2DMultisampleArray:
_api.TexStorage3DMultisample( _gd.Api.TexStorage3DMultisample(
TextureTarget.Texture2DMultisampleArray, TextureTarget.Texture2DMultisampleArray,
(uint)Info.Samples, (uint)Info.Samples,
internalFormat, internalFormat,
@ -112,7 +110,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break; break;
case Target.Texture3D: case Target.Texture3D:
_api.TexStorage3D( _gd.Api.TexStorage3D(
TextureTarget.Texture3D, TextureTarget.Texture3D,
levels, levels,
internalFormat, internalFormat,
@ -122,7 +120,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break; break;
case Target.Cubemap: case Target.Cubemap:
_api.TexStorage2D( _gd.Api.TexStorage2D(
TextureTarget.TextureCubeMap, TextureTarget.TextureCubeMap,
levels, levels,
internalFormat, internalFormat,
@ -131,7 +129,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break; break;
case Target.CubemapArray: case Target.CubemapArray:
_api.TexStorage3D( _gd.Api.TexStorage3D(
TextureTarget.TextureCubeMapArray, TextureTarget.TextureCubeMapArray,
levels, levels,
internalFormat, internalFormat,
@ -153,11 +151,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
return DefaultView; return DefaultView;
} }
public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel) public ITexture CreateView(TextureCreateInfo info, uint firstLayer, uint firstLevel)
{ {
IncrementViewsCount(); IncrementViewsCount();
return new TextureView(_renderer, this, info, firstLayer, firstLevel); return new TextureView(_gd, this, info, firstLayer, firstLevel);
} }
private void IncrementViewsCount() private void IncrementViewsCount()
@ -189,7 +187,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
_viewsCount = 1; // When we are used again, we will have the default view. _viewsCount = 1; // When we are used again, we will have the default view.
_renderer.ResourcePool.AddTexture((TextureView)DefaultView); _gd.ResourcePool.AddTexture((TextureView)DefaultView);
} }
public void DeleteDefault() public void DeleteDefault()
@ -203,7 +201,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (Handle != 0) if (Handle != 0)
{ {
_api.DeleteTexture(Handle); _gd.Api.DeleteTexture(Handle);
Handle = 0; Handle = 0;
} }

View file

@ -9,23 +9,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
class TextureView : TextureBase, ITexture, ITextureInfo class TextureView : TextureBase, ITexture, ITextureInfo
{ {
private readonly OpenGLRenderer _renderer;
private readonly TextureStorage _parent; private readonly TextureStorage _parent;
public ITextureInfo Storage => _parent; public ITextureInfo Storage => _parent;
public int FirstLayer { get; private set; } public uint FirstLayer { get; private set; }
public int FirstLevel { get; private set; } public uint FirstLevel { get; private set; }
public TextureView( public TextureView(
OpenGLRenderer renderer, OpenGLRenderer gd,
TextureStorage parent, TextureStorage parent,
TextureCreateInfo info, TextureCreateInfo info,
int firstLayer, uint firstLayer,
int firstLevel) : base(info) uint firstLevel) : base(gd, info)
{ {
_renderer = renderer;
_parent = parent; _parent = parent;
FirstLayer = firstLayer; FirstLayer = firstLayer;
@ -40,20 +37,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
FormatInfo format = FormatTable.GetFormatInfo(Info.Format); FormatInfo format = FormatTable.GetFormatInfo(Info.Format);
InternalFormat pixelInternalFormat; SizedInternalFormat pixelInternalFormat;
if (format.IsCompressed) if (format.IsCompressed)
{ {
pixelInternalFormat = (InternalFormat)format.PixelFormat; pixelInternalFormat = (SizedInternalFormat)format.PixelFormat;
} }
else else
{ {
pixelInternalFormat = format.InternalFormat; pixelInternalFormat = (SizedInternalFormat)format.InternalFormat;
} }
int levels = Info.GetLevelsClamped(); uint levels = (uint)Info.GetLevelsClamped();
GL.TextureView( _gd.Api.TextureView(
Handle, Handle,
target, target,
_parent.Handle, _parent.Handle,
@ -61,11 +58,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
FirstLevel, FirstLevel,
levels, levels,
FirstLayer, FirstLayer,
Info.GetLayers()); (uint)Info.GetLayers());
GL.ActiveTexture(TextureUnit.Texture0); _gd.Api.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(target, Handle); _gd.Api.BindTexture(target, Handle);
int[] swizzleRgba = new int[] int[] swizzleRgba = new int[]
{ {
@ -91,20 +88,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
(swizzleRgba[2], swizzleRgba[0]) = (swizzleRgba[0], swizzleRgba[2]); (swizzleRgba[2], swizzleRgba[0]) = (swizzleRgba[0], swizzleRgba[2]);
} }
GL.TexParameter(target, TextureParameterName.TextureSwizzleRgba, swizzleRgba); _gd.Api.TexParameter(target, TextureParameterName.TextureSwizzleRgba, swizzleRgba);
int maxLevel = levels - 1; uint maxLevel = levels - 1;
if (maxLevel < 0) if (maxLevel < 0)
{ {
maxLevel = 0; maxLevel = 0;
} }
GL.TexParameter(target, TextureParameterName.TextureMaxLevel, maxLevel); _gd.Api.TexParameter(target, TextureParameterName.TextureMaxLevel, maxLevel);
GL.TexParameter(target, TextureParameterName.DepthStencilTextureMode, (int)Info.DepthStencilMode.Convert()); _gd.Api.TexParameter(target, TextureParameterName.DepthStencilTextureMode, (int)Info.DepthStencilMode.Convert());
} }
public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel) public ITexture CreateView(TextureCreateInfo info, uint firstLayer, uint firstLevel)
{ {
firstLayer += FirstLayer; firstLayer += FirstLayer;
firstLevel += FirstLevel; firstLevel += FirstLevel;
@ -112,7 +109,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
return _parent.CreateView(info, firstLayer, firstLevel); return _parent.CreateView(info, firstLayer, firstLevel);
} }
public void CopyTo(ITexture destination, int firstLayer, int firstLevel) public void CopyTo(ITexture destination, uint firstLayer, uint firstLevel)
{ {
TextureView destinationView = (TextureView)destination; TextureView destinationView = (TextureView)destination;
@ -121,24 +118,24 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (dstIsMultisample != srcIsMultisample && Info.Format.IsDepthOrStencil()) if (dstIsMultisample != srcIsMultisample && Info.Format.IsDepthOrStencil())
{ {
int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer); uint layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
CopyWithBlitForDepthMS(destinationView, 0, firstLayer, layers); CopyWithBlitForDepthMS(destinationView, 0, firstLayer, layers);
} }
else if (!dstIsMultisample && srcIsMultisample) else if (!dstIsMultisample && srcIsMultisample)
{ {
int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer); uint layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
_renderer.TextureCopyMS.CopyMSToNonMS(this, destinationView, 0, firstLayer, layers); _gd.TextureCopyMS.CopyMSToNonMS(this, destinationView, 0, firstLayer, layers);
} }
else if (dstIsMultisample && !srcIsMultisample) else if (dstIsMultisample && !srcIsMultisample)
{ {
int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer); uint layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
_renderer.TextureCopyMS.CopyNonMSToMS(this, destinationView, 0, firstLayer, layers); _gd.TextureCopyMS.CopyNonMSToMS(this, destinationView, 0, firstLayer, layers);
} }
else if (destinationView.Info.BytesPerPixel != Info.BytesPerPixel) else if (destinationView.Info.BytesPerPixel != Info.BytesPerPixel)
{ {
int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer); int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
int levels = Math.Min(Info.Levels, destinationView.Info.Levels - firstLevel); int levels = Math.Min(Info.Levels, destinationView.Info.Levels - firstLevel);
_renderer.TextureCopyIncompatible.CopyIncompatibleFormats(this, destinationView, 0, firstLayer, 0, firstLevel, layers, levels); _gd.TextureCopyIncompatible.CopyIncompatibleFormats(this, destinationView, 0, firstLayer, 0, firstLevel, layers, levels);
} }
else if (destinationView.Format.IsDepthOrStencil() != Format.IsDepthOrStencil()) else if (destinationView.Format.IsDepthOrStencil() != Format.IsDepthOrStencil())
{ {
@ -158,13 +155,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
for (int layer = 0; layer < layers; layer++) for (int layer = 0; layer < layers; layer++)
{ {
_renderer.TextureCopy.PboCopy(this, destinationView, 0, firstLayer + layer, 0, firstLevel + level, minWidth, minHeight); _gd.TextureCopy.PboCopy(this, destinationView, 0, firstLayer + layer, 0, firstLevel + level, minWidth, minHeight);
} }
} }
} }
else else
{ {
_renderer.TextureCopy.CopyUnscaled(this, destinationView, 0, firstLayer, 0, firstLevel); _gd.TextureCopy.CopyUnscaled(this, destinationView, 0, firstLayer, 0, firstLevel);
} }
} }
@ -181,30 +178,30 @@ namespace Ryujinx.Graphics.OpenGL.Image
} }
else if (!dstIsMultisample && srcIsMultisample) else if (!dstIsMultisample && srcIsMultisample)
{ {
_renderer.TextureCopyMS.CopyMSToNonMS(this, destinationView, srcLayer, dstLayer, 1); _gd.TextureCopyMS.CopyMSToNonMS(this, destinationView, srcLayer, dstLayer, 1);
} }
else if (dstIsMultisample && !srcIsMultisample) else if (dstIsMultisample && !srcIsMultisample)
{ {
_renderer.TextureCopyMS.CopyNonMSToMS(this, destinationView, srcLayer, dstLayer, 1); _gd.TextureCopyMS.CopyNonMSToMS(this, destinationView, srcLayer, dstLayer, 1);
} }
else if (destinationView.Info.BytesPerPixel != Info.BytesPerPixel) else if (destinationView.Info.BytesPerPixel != Info.BytesPerPixel)
{ {
_renderer.TextureCopyIncompatible.CopyIncompatibleFormats(this, destinationView, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1); _gd.TextureCopyIncompatible.CopyIncompatibleFormats(this, destinationView, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1);
} }
else if (destinationView.Format.IsDepthOrStencil() != Format.IsDepthOrStencil()) else if (destinationView.Format.IsDepthOrStencil() != Format.IsDepthOrStencil())
{ {
int minWidth = Math.Min(Width, destinationView.Width); int minWidth = Math.Min(Width, destinationView.Width);
int minHeight = Math.Min(Height, destinationView.Height); int minHeight = Math.Min(Height, destinationView.Height);
_renderer.TextureCopy.PboCopy(this, destinationView, srcLayer, dstLayer, srcLevel, dstLevel, minWidth, minHeight); _gd.TextureCopy.PboCopy(this, destinationView, srcLayer, dstLayer, srcLevel, dstLevel, minWidth, minHeight);
} }
else else
{ {
_renderer.TextureCopy.CopyUnscaled(this, destinationView, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1); _gd.TextureCopy.CopyUnscaled(this, destinationView, srcLayer, dstLayer, srcLevel, dstLevel, 1, 1);
} }
} }
private void CopyWithBlitForDepthMS(TextureView destinationView, int srcLayer, int dstLayer, int layers) private void CopyWithBlitForDepthMS(TextureView destinationView, int srcLayer, int dstLayer, uint layers)
{ {
// This is currently used for multisample <-> non-multisample copies. // This is currently used for multisample <-> non-multisample copies.
// We can't do that with compute because it's not possible to write depth textures on compute. // We can't do that with compute because it's not possible to write depth textures on compute.
@ -218,7 +215,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (destinationView.Target.IsMultisample()) if (destinationView.Target.IsMultisample())
{ {
TextureView intermmediate = _renderer.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast( TextureView intermmediate = _gd.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast(
Info.Target, Info.Target,
Info.BlockWidth, Info.BlockWidth,
Info.BlockHeight, Info.BlockHeight,
@ -230,8 +227,8 @@ namespace Ryujinx.Graphics.OpenGL.Image
1, 1,
1); 1);
_renderer.TextureCopy.Copy(this, intermmediate, srcRegion, dstRegion, false); _gd.TextureCopy.Copy(this, intermmediate, srcRegion, dstRegion, false);
_renderer.TextureCopy.Copy(intermmediate, destinationView, dstRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1); _gd.TextureCopy.Copy(intermmediate, destinationView, dstRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1);
} }
else else
{ {
@ -242,7 +239,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
_ => Target, _ => Target,
}; };
TextureView intermmediate = _renderer.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast( TextureView intermmediate = _gd.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast(
target, target,
Info.BlockWidth, Info.BlockWidth,
Info.BlockHeight, Info.BlockHeight,
@ -254,14 +251,14 @@ namespace Ryujinx.Graphics.OpenGL.Image
1, 1,
1); 1);
_renderer.TextureCopy.Copy(this, intermmediate, srcRegion, srcRegion, false); _gd.TextureCopy.Copy(this, intermmediate, srcRegion, srcRegion, false);
_renderer.TextureCopy.Copy(intermmediate, destinationView, srcRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1); _gd.TextureCopy.Copy(intermmediate, destinationView, srcRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1);
} }
} }
public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter) public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
{ {
_renderer.TextureCopy.Copy(this, (TextureView)destination, srcRegion, dstRegion, linearFilter); _gd.TextureCopy.Copy(this, (TextureView)destination, srcRegion, dstRegion, linearFilter);
} }
public unsafe PinnedSpan<byte> GetData() public unsafe PinnedSpan<byte> GetData()
@ -278,11 +275,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (HwCapabilities.UsePersistentBufferForFlush) if (HwCapabilities.UsePersistentBufferForFlush)
{ {
data = _renderer.PersistentBuffers.Default.GetTextureData(this, size); data = _gd.PersistentBuffers.Default.GetTextureData(this, size);
} }
else else
{ {
IntPtr target = _renderer.PersistentBuffers.Default.GetHostArray(size); IntPtr target = _gd.PersistentBuffers.Default.GetHostArray(size);
WriteTo(target); WriteTo(target);
@ -303,11 +300,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (HwCapabilities.UsePersistentBufferForFlush) if (HwCapabilities.UsePersistentBufferForFlush)
{ {
return PinnedSpan<byte>.UnsafeFromSpan(_renderer.PersistentBuffers.Default.GetTextureData(this, size, layer, level)); return PinnedSpan<byte>.UnsafeFromSpan(_gd.PersistentBuffers.Default.GetTextureData(this, size, layer, level));
} }
else else
{ {
IntPtr target = _renderer.PersistentBuffers.Default.GetHostArray(size); IntPtr target = _gd.PersistentBuffers.Default.GetHostArray(size);
int offset = WriteTo2D(target, layer, level); int offset = WriteTo2D(target, layer, level);
@ -322,7 +319,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
throw new NotSupportedException("Stride conversion for texture copy to buffer not supported."); throw new NotSupportedException("Stride conversion for texture copy to buffer not supported.");
} }
GL.BindBuffer(BufferTargetARB.PixelPackBuffer, range.Handle.ToInt32()); _gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, range.Handle.ToUInt32());
FormatInfo format = FormatTable.GetFormatInfo(Info.Format); FormatInfo format = FormatTable.GetFormatInfo(Info.Format);
if (format.PixelFormat == PixelFormat.DepthStencil) if (format.PixelFormat == PixelFormat.DepthStencil)
@ -334,7 +331,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
Debug.Assert(offset == 0); Debug.Assert(offset == 0);
GL.BindBuffer(BufferTargetARB.PixelPackBuffer, 0); _gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
} }
public void WriteToPbo(int offset, bool forceBgra) public void WriteToPbo(int offset, bool forceBgra)
@ -367,15 +364,15 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (format.IsCompressed) if (format.IsCompressed)
{ {
GL.GetCompressedTextureSubImage(Handle, level, 0, 0, layer, Math.Max(1, Info.Width >> level), Math.Max(1, Info.Height >> level), 1, mipSize, data); _gd.Api.GetCompressedTextureSubImage(Handle, level, 0, 0, layer, Math.Max(1, Info.Width >> level), Math.Max(1, Info.Height >> level), 1, mipSize, data);
} }
else if (format.PixelFormat != PixelFormat.DepthStencil) else if (format.PixelFormat != PixelFormat.DepthStencil)
{ {
GL.GetTextureSubImage(Handle, level, 0, 0, layer, Math.Max(1, Info.Width >> level), Math.Max(1, Info.Height >> level), 1, pixelFormat, pixelType, mipSize, data); _gd.Api.GetTextureSubImage(Handle, level, 0, 0, layer, Math.Max(1, Info.Width >> level), Math.Max(1, Info.Height >> level), 1, pixelFormat, pixelType, mipSize, data);
} }
else else
{ {
GL.GetTexImage(target, level, pixelFormat, pixelType, data); _gd.Api.GetTexImage(target, level, pixelFormat, pixelType, data);
// The GL function returns all layers. Must return the offset of the layer we're interested in. // The GL function returns all layers. Must return the offset of the layer we're interested in.
return target switch return target switch
@ -436,11 +433,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (format.IsCompressed) if (format.IsCompressed)
{ {
GL.GetCompressedTexImage(target + face, level, data + faceOffset); _gd.Api.GetCompressedTexImage(target + face, level, data + faceOffset);
} }
else else
{ {
GL.GetTexImage(target + face, level, pixelFormat, pixelType, data + faceOffset); _gd.Api.GetTexImage(target + face, level, pixelFormat, pixelType, data + faceOffset);
} }
} }
@ -548,22 +545,22 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.Texture1D: case Target.Texture1D:
if (format.IsCompressed) if (format.IsCompressed)
{ {
GL.CompressedTexSubImage1D( _gd.Api.CompressedTexSubImage1D(
target, target,
level, level,
x, x,
width, (uint)width,
format.PixelFormat, (InternalFormat)format.PixelFormat,
mipSize, (uint)mipSize,
data); data);
} }
else else
{ {
GL.TexSubImage1D( _gd.Api.TexSubImage1D(
target, target,
level, level,
x, x,
width, (uint)width,
format.PixelFormat, format.PixelFormat,
format.PixelType, format.PixelType,
data); data);
@ -573,25 +570,25 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.Texture1DArray: case Target.Texture1DArray:
if (format.IsCompressed) if (format.IsCompressed)
{ {
GL.CompressedTexSubImage2D( _gd.Api.CompressedTexSubImage2D(
target, target,
level, level,
x, x,
layer, layer,
width, (uint)width,
1, 1,
format.PixelFormat, (InternalFormat)format.PixelFormat,
mipSize, (uint)mipSize,
data); data);
} }
else else
{ {
GL.TexSubImage2D( _gd.Api.TexSubImage2D(
target, target,
level, level,
x, x,
layer, layer,
width, (uint)width,
1, 1,
format.PixelFormat, format.PixelFormat,
format.PixelType, format.PixelType,
@ -602,26 +599,26 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.Texture2D: case Target.Texture2D:
if (format.IsCompressed) if (format.IsCompressed)
{ {
GL.CompressedTexSubImage2D( _gd.Api.CompressedTexSubImage2D(
target, target,
level, level,
x, x,
y, y,
width, (uint)width,
height, (uint)height,
format.PixelFormat, (InternalFormat)format.PixelFormat,
mipSize, (uint)mipSize,
data); data);
} }
else else
{ {
GL.TexSubImage2D( _gd.Api.TexSubImage2D(
target, target,
level, level,
x, x,
y, y,
width, (uint)width,
height, (uint)height,
format.PixelFormat, format.PixelFormat,
format.PixelType, format.PixelType,
data); data);
@ -633,29 +630,29 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.CubemapArray: case Target.CubemapArray:
if (format.IsCompressed) if (format.IsCompressed)
{ {
GL.CompressedTexSubImage3D( _gd.Api.CompressedTexSubImage3D(
target, target,
level, level,
x, x,
y, y,
layer, layer,
width, (uint)width,
height, (uint)height,
1, 1,
format.PixelFormat, (InternalFormat)format.PixelFormat,
mipSize, (uint)mipSize,
data); data);
} }
else else
{ {
GL.TexSubImage3D( _gd.Api.TexSubImage3D(
target, target,
level, level,
x, x,
y, y,
layer, layer,
width, (uint)width,
height, (uint)height,
1, 1,
format.PixelFormat, format.PixelFormat,
format.PixelType, format.PixelType,
@ -666,26 +663,26 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.Cubemap: case Target.Cubemap:
if (format.IsCompressed) if (format.IsCompressed)
{ {
GL.CompressedTexSubImage2D( _gd.Api.CompressedTexSubImage2D(
TextureTarget.TextureCubeMapPositiveX + layer, TextureTarget.TextureCubeMapPositiveX + layer,
level, level,
x, x,
y, y,
width, (uint)width,
height, (uint)height,
format.PixelFormat, (InternalFormat)format.PixelFormat,
mipSize, (uint)mipSize,
data); data);
} }
else else
{ {
GL.TexSubImage2D( _gd.Api.TexSubImage2D(
TextureTarget.TextureCubeMapPositiveX + layer, TextureTarget.TextureCubeMapPositiveX + layer,
level, level,
x, x,
y, y,
width, (uint)width,
height, (uint)height,
format.PixelFormat, format.PixelFormat,
format.PixelType, format.PixelType,
data); data);
@ -697,13 +694,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
private void ReadFrom(IntPtr data, int size) private void ReadFrom(IntPtr data, int size)
{ {
TextureTarget target = Target.Convert(); TextureTarget target = Target.Convert();
int baseLevel = 0; uint baseLevel = 0;
// glTexSubImage on cubemap views is broken on Intel, we have to use the storage instead. // glTexSubImage on cubemap views is broken on Intel, we have to use the storage instead.
if (Target == Target.Cubemap && HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows) if (Target == Target.Cubemap && HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows)
{ {
GL.ActiveTexture(TextureUnit.Texture0); _gd.Api.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(target, Storage.Handle); _gd.Api.BindTexture(target, Storage.Handle);
baseLevel = FirstLevel; baseLevel = FirstLevel;
} }
else else
@ -736,7 +733,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.Texture1D: case Target.Texture1D:
if (format.IsCompressed) if (format.IsCompressed)
{ {
GL.CompressedTexSubImage1D( _gd.Api.CompressedTexSubImage1D(
target, target,
level, level,
0, 0,
@ -747,7 +744,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
} }
else else
{ {
GL.TexSubImage1D( _gd.Api.TexSubImage1D(
target, target,
level, level,
0, 0,
@ -762,7 +759,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.Texture2D: case Target.Texture2D:
if (format.IsCompressed) if (format.IsCompressed)
{ {
GL.CompressedTexSubImage2D( _gd.Api.CompressedTexSubImage2D(
target, target,
level, level,
0, 0,
@ -775,7 +772,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
} }
else else
{ {
GL.TexSubImage2D( _gd.Api.TexSubImage2D(
target, target,
level, level,
0, 0,
@ -793,7 +790,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.CubemapArray: case Target.CubemapArray:
if (format.IsCompressed) if (format.IsCompressed)
{ {
GL.CompressedTexSubImage3D( _gd.Api.CompressedTexSubImage3D(
target, target,
level, level,
0, 0,
@ -808,7 +805,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
} }
else else
{ {
GL.TexSubImage3D( _gd.Api.TexSubImage3D(
target, target,
level, level,
0, 0,
@ -830,7 +827,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
if (format.IsCompressed) if (format.IsCompressed)
{ {
GL.CompressedTexSubImage2D( _gd.Api.CompressedTexSubImage2D(
TextureTarget.TextureCubeMapPositiveX + face, TextureTarget.TextureCubeMapPositiveX + face,
baseLevel + level, baseLevel + level,
0, 0,
@ -843,7 +840,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
} }
else else
{ {
GL.TexSubImage2D( _gd.Api.TexSubImage2D(
TextureTarget.TextureCubeMapPositiveX + face, TextureTarget.TextureCubeMapPositiveX + face,
baseLevel + level, baseLevel + level,
0, 0,
@ -880,7 +877,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
if (Handle != 0) if (Handle != 0)
{ {
GL.DeleteTexture(Handle); _gd.Api.DeleteTexture(Handle);
Handle = 0; Handle = 0;
} }

View file

@ -6,12 +6,13 @@ using Ryujinx.Graphics.OpenGL.Image;
using Ryujinx.Graphics.OpenGL.Queries; using Ryujinx.Graphics.OpenGL.Queries;
using Ryujinx.Graphics.Shader.Translation; using Ryujinx.Graphics.Shader.Translation;
using System; using System;
using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler;
namespace Ryujinx.Graphics.OpenGL namespace Ryujinx.Graphics.OpenGL
{ {
public sealed class OpenGLRenderer : IRenderer public sealed class OpenGLRenderer : IRenderer
{ {
private GL _api; public readonly GL Api;
private readonly Pipeline _pipeline; private readonly Pipeline _pipeline;
public IPipeline Pipeline => _pipeline; public IPipeline Pipeline => _pipeline;
@ -44,10 +45,11 @@ namespace Ryujinx.Graphics.OpenGL
public bool PreferThreading => true; public bool PreferThreading => true;
public OpenGLRenderer() public OpenGLRenderer(GL api)
{ {
Api = api;
_pipeline = new Pipeline(); _pipeline = new Pipeline();
_counters = new Counters(); _counters = new Counters(Api);
_window = new Window(this); _window = new Window(this);
_textureCopy = new TextureCopy(this); _textureCopy = new TextureCopy(this);
_backgroundTextureCopy = new TextureCopy(this); _backgroundTextureCopy = new TextureCopy(this);
@ -64,7 +66,7 @@ namespace Ryujinx.Graphics.OpenGL
if (access.HasFlag(BufferAccess.FlushPersistent)) if (access.HasFlag(BufferAccess.FlushPersistent))
{ {
BufferHandle handle = Buffer.CreatePersistent(_api, size); BufferHandle handle = Buffer.CreatePersistent(Api, size);
PersistentBuffers.Map(handle, size); PersistentBuffers.Map(handle, size);
@ -72,7 +74,7 @@ namespace Ryujinx.Graphics.OpenGL
} }
else else
{ {
return Buffer.Create(_api, size); return Buffer.Create(Api, size);
} }
} }
@ -93,7 +95,7 @@ namespace Ryujinx.Graphics.OpenGL
public IImageArray CreateImageArray(int size, bool isBuffer) public IImageArray CreateImageArray(int size, bool isBuffer)
{ {
return new ImageArray(size); return new ImageArray(Api, size);
} }
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info) public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
@ -103,7 +105,7 @@ namespace Ryujinx.Graphics.OpenGL
public ISampler CreateSampler(SamplerCreateInfo info) public ISampler CreateSampler(SamplerCreateInfo info)
{ {
return new Sampler(info); return new Sampler(Api, info);
} }
public ITexture CreateTexture(TextureCreateInfo info) public ITexture CreateTexture(TextureCreateInfo info)
@ -120,14 +122,14 @@ namespace Ryujinx.Graphics.OpenGL
public ITextureArray CreateTextureArray(int size, bool isBuffer) public ITextureArray CreateTextureArray(int size, bool isBuffer)
{ {
return new TextureArray(size); return new TextureArray(Api, size);
} }
public void DeleteBuffer(BufferHandle buffer) public void DeleteBuffer(BufferHandle buffer)
{ {
PersistentBuffers.Unmap(buffer); PersistentBuffers.Unmap(buffer);
Buffer.Delete(buffer); Buffer.Delete(Api, buffer);
} }
public HardwareInfo GetHardwareInfo() public HardwareInfo GetHardwareInfo()
@ -203,7 +205,7 @@ namespace Ryujinx.Graphics.OpenGL
public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan<byte> data) public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan<byte> data)
{ {
Buffer.SetData(buffer, offset, data); Buffer.SetData(Api, buffer, offset, data);
} }
public void UpdateCounters() public void UpdateCounters()
@ -224,7 +226,7 @@ namespace Ryujinx.Graphics.OpenGL
public void Initialize(GraphicsDebugLevel glLogLevel) public void Initialize(GraphicsDebugLevel glLogLevel)
{ {
Debugger.Initialize(glLogLevel); Debugger.Initialize(Api, glLogLevel);
PrintGpuInformation(); PrintGpuInformation();
@ -239,14 +241,14 @@ namespace Ryujinx.Graphics.OpenGL
// This call is expected to fail if we're running with a core profile, // This call is expected to fail if we're running with a core profile,
// as this clamp target was deprecated, but that's fine as a core profile // as this clamp target was deprecated, but that's fine as a core profile
// should already have the desired behaviour were outputs are not clamped. // should already have the desired behaviour were outputs are not clamped.
GL.ClampColor(ClampColorTargetARB.FragmentColorArb, ClampColorModeARB.False); Api.ClampColor(ClampColorTargetARB.FragmentColorArb, ClampColorModeARB.False);
} }
private void PrintGpuInformation() private void PrintGpuInformation()
{ {
GpuVendor = GL.GetString(StringName.Vendor); GpuVendor = Api.GetString(StringName.Vendor);
GpuRenderer = GL.GetString(StringName.Renderer); GpuRenderer = Api.GetString(StringName.Renderer);
GpuVersion = GL.GetString(StringName.Version); GpuVersion = Api.GetString(StringName.Version);
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})"); Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
} }

View file

@ -52,7 +52,7 @@ namespace Ryujinx.Graphics.OpenGL
class PersistentBuffer : IDisposable class PersistentBuffer : IDisposable
{ {
private IntPtr _bufferMap; private IntPtr _bufferMap;
private int _copyBufferHandle; private uint _copyBufferHandle;
private int _copyBufferSize; private int _copyBufferSize;
private byte[] _data; private byte[] _data;
@ -140,7 +140,7 @@ namespace Ryujinx.Graphics.OpenGL
{ {
EnsureBuffer(size); EnsureBuffer(size);
GL.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToInt32()); GL.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32());
GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle); GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle);
GL.CopyBufferSubData(BufferTargetARB.CopyReadBuffer, BufferTargetARB.CopyWriteBuffer, (IntPtr)offset, IntPtr.Zero, size); GL.CopyBufferSubData(BufferTargetARB.CopyReadBuffer, BufferTargetARB.CopyWriteBuffer, (IntPtr)offset, IntPtr.Zero, size);

File diff suppressed because it is too large Load diff

View file

@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.OpenGL
{ {
Handle = GL.CreateProgram(); Handle = GL.CreateProgram();
GL.ProgramParameter(Handle, ProgramParameterName.ProgramBinaryRetrievableHint, 1); GL.ProgramParameter(Handle, ProgramParameterPName.BinaryRetrievableHint, 1);
_shaderHandles = new int[shaders.Length]; _shaderHandles = new int[shaders.Length];
bool hasFragmentShader = false; bool hasFragmentShader = false;

View file

@ -15,23 +15,29 @@ namespace Ryujinx.Graphics.OpenGL
} }
private ulong _firstHandle = 0; private ulong _firstHandle = 0;
private static ClientWaitSyncFlags SyncFlags => HwCapabilities.RequiresSyncFlush ? ClientWaitSyncFlags.None : ClientWaitSyncFlags.SyncFlushCommandsBit; private static SyncBehaviorFlags SyncFlags => HwCapabilities.RequiresSyncFlush ? SyncBehaviorFlags.None : SyncBehaviorFlags.SyncFlushCommandsBit;
private readonly List<SyncHandle> _handles = new(); private readonly List<SyncHandle> _handles = new();
private readonly GL _api;
public Sync(GL api)
{
_api = api;
}
public void Create(ulong id) public void Create(ulong id)
{ {
SyncHandle handle = new() SyncHandle handle = new()
{ {
ID = id, ID = id,
Handle = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None), Handle = _api.FenceSync(SyncCondition.SyncGpuCommandsComplete, SyncBehaviorFlags.None),
}; };
if (HwCapabilities.RequiresSyncFlush) if (HwCapabilities.RequiresSyncFlush)
{ {
// Force commands to flush up to the syncpoint. // Force commands to flush up to the syncpoint.
GL.ClientWaitSync(handle.Handle, ClientWaitSyncFlags.SyncFlushCommandsBit, 0); _api.ClientWaitSync(handle.Handle, SyncBehaviorFlags.SyncFlushCommandsBit, 0);
} }
lock (_handles) lock (_handles)
@ -57,9 +63,9 @@ namespace Ryujinx.Graphics.OpenGL
if (handle.ID > lastHandle) if (handle.ID > lastHandle)
{ {
WaitSyncStatus syncResult = GL.ClientWaitSync(handle.Handle, SyncFlags, 0); GLEnum syncResult = _api.ClientWaitSync(handle.Handle, SyncFlags, 0);
if (syncResult == WaitSyncStatus.AlreadySignaled) if (syncResult == GLEnum.AlreadySignaled)
{ {
lastHandle = handle.ID; lastHandle = handle.ID;
} }
@ -101,9 +107,9 @@ namespace Ryujinx.Graphics.OpenGL
return; return;
} }
WaitSyncStatus syncResult = GL.ClientWaitSync(result.Handle, SyncFlags, 1000000000); GLEnum syncResult = _api.ClientWaitSync(result.Handle, SyncFlags, 1000000000);
if (syncResult == WaitSyncStatus.TimeoutExpired) if (syncResult == GLEnum.TimeoutExpired)
{ {
Logger.Error?.PrintMsg(LogClass.Gpu, $"GL Sync Object {result.ID} failed to signal within 1000ms. Continuing..."); Logger.Error?.PrintMsg(LogClass.Gpu, $"GL Sync Object {result.ID} failed to signal within 1000ms. Continuing...");
} }
@ -128,9 +134,9 @@ namespace Ryujinx.Graphics.OpenGL
break; break;
} }
WaitSyncStatus syncResult = GL.ClientWaitSync(first.Handle, SyncFlags, 0); GLEnum syncResult = _api.ClientWaitSync(first.Handle, SyncFlags, 0);
if (syncResult == WaitSyncStatus.AlreadySignaled) if (syncResult == GLEnum.AlreadySignaled)
{ {
// Delete the sync object. // Delete the sync object.
lock (_handles) lock (_handles)
@ -139,7 +145,7 @@ namespace Ryujinx.Graphics.OpenGL
{ {
_firstHandle = first.ID + 1; _firstHandle = first.ID + 1;
_handles.RemoveAt(0); _handles.RemoveAt(0);
GL.DeleteSync(first.Handle); _api.DeleteSync(first.Handle);
first.Handle = IntPtr.Zero; first.Handle = IntPtr.Zero;
} }
} }
@ -160,7 +166,7 @@ namespace Ryujinx.Graphics.OpenGL
{ {
lock (handle) lock (handle)
{ {
GL.DeleteSync(handle.Handle); _api.DeleteSync(handle.Handle);
handle.Handle = IntPtr.Zero; handle.Handle = IntPtr.Zero;
} }
} }

View file

@ -9,14 +9,14 @@ namespace Ryujinx.Graphics.OpenGL
{ {
class Window : IWindow, IDisposable class Window : IWindow, IDisposable
{ {
private readonly OpenGLRenderer _renderer; private readonly OpenGLRenderer _gd;
private bool _initialized; private bool _initialized;
private int _width; private int _width;
private int _height; private int _height;
private bool _updateSize; private bool _updateSize;
private int _copyFramebufferHandle; private uint _copyFramebufferHandle;
private IPostProcessingEffect _antiAliasing; private IPostProcessingEffect _antiAliasing;
private IScalingFilter _scalingFilter; private IScalingFilter _scalingFilter;
private bool _isLinear; private bool _isLinear;
@ -32,26 +32,26 @@ namespace Ryujinx.Graphics.OpenGL
internal bool ScreenCaptureRequested { get; set; } internal bool ScreenCaptureRequested { get; set; }
public Window(OpenGLRenderer renderer) public Window(OpenGLRenderer gd)
{ {
_renderer = renderer; _gd = gd;
} }
public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback) public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
{ {
GL.Disable(EnableCap.FramebufferSrgb); _gd.Api.Disable(EnableCap.FramebufferSrgb);
(int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers(); (uint oldDrawFramebufferHandle, uint oldReadFramebufferHandle) = ((Pipeline)_gd.Pipeline).GetBoundFramebuffers();
CopyTextureToFrameBufferRGB(0, GetCopyFramebufferHandleLazy(), (TextureView)texture, crop, swapBuffersCallback); CopyTextureToFrameBufferRGB(0, GetCopyFramebufferHandleLazy(), (TextureView)texture, crop, swapBuffersCallback);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); _gd.Api.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); _gd.Api.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle);
GL.Enable(EnableCap.FramebufferSrgb); _gd.Api.Enable(EnableCap.FramebufferSrgb);
// Restore unpack alignment to 4, as performance overlays such as RTSS may change this to load their resources. // Restore unpack alignment to 4, as performance overlays such as RTSS may change this to load their resources.
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4); _gd.Api.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
} }
public void ChangeVSyncMode(bool vsyncEnabled) { } public void ChangeVSyncMode(bool vsyncEnabled) { }
@ -64,12 +64,12 @@ namespace Ryujinx.Graphics.OpenGL
_updateSize = true; _updateSize = true;
} }
private void CopyTextureToFrameBufferRGB(int drawFramebuffer, int readFramebuffer, TextureView view, ImageCrop crop, Action swapBuffersCallback) private void CopyTextureToFrameBufferRGB(uint drawFramebuffer, uint readFramebuffer, TextureView view, ImageCrop crop, Action swapBuffersCallback)
{ {
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer); _gd.Api.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer); _gd.Api.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer);
TextureView viewConverted = view.Format.IsBgr() ? _renderer.TextureCopy.BgraSwap(view) : view; TextureView viewConverted = view.Format.IsBgr() ? _gd.TextureCopy.BgraSwap(view) : view;
UpdateEffect(); UpdateEffect();
@ -81,7 +81,7 @@ namespace Ryujinx.Graphics.OpenGL
if (viewConverted.Format.IsBgr()) if (viewConverted.Format.IsBgr())
{ {
var swappedView = _renderer.TextureCopy.BgraSwap(viewConverted); var swappedView = _gd.TextureCopy.BgraSwap(viewConverted);
viewConverted?.Dispose(); viewConverted?.Dispose();
@ -94,21 +94,21 @@ namespace Ryujinx.Graphics.OpenGL
} }
} }
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer); _gd.Api.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer); _gd.Api.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer);
GL.FramebufferTexture( _gd.Api.FramebufferTexture(
FramebufferTarget.ReadFramebuffer, FramebufferTarget.ReadFramebuffer,
FramebufferAttachment.ColorAttachment0, FramebufferAttachment.ColorAttachment0,
viewConverted.Handle, viewConverted.Handle,
0); 0);
GL.ReadBuffer(ReadBufferMode.ColorAttachment0); _gd.Api.ReadBuffer(ReadBufferMode.ColorAttachment0);
GL.Disable(EnableCap.RasterizerDiscard); _gd.Api.Disable(EnableCap.RasterizerDiscard);
GL.Disable(IndexedEnableCap.ScissorTest, 0); _gd.Api.Disable(EnableCap.ScissorTest, 0);
GL.Clear(ClearBufferMask.ColorBufferBit); _gd.Api.Clear(ClearBufferMask.ColorBufferBit);
int srcX0, srcX1, srcY0, srcY1; int srcX0, srcX1, srcY0, srcY1;
@ -151,7 +151,7 @@ namespace Ryujinx.Graphics.OpenGL
if (ScreenCaptureRequested) if (ScreenCaptureRequested)
{ {
CaptureFrame(srcX0, srcY0, srcX1, srcY1, view.Format.IsBgr(), crop.FlipX, crop.FlipY); CaptureFrame(srcX0, srcY0, (uint)srcX1, (uint)srcY1, view.Format.IsBgr(), crop.FlipX, crop.FlipY);
ScreenCaptureRequested = false; ScreenCaptureRequested = false;
} }
@ -185,14 +185,14 @@ namespace Ryujinx.Graphics.OpenGL
srcX1 = dstX1; srcX1 = dstX1;
srcY1 = dstY1; srcY1 = dstY1;
GL.FramebufferTexture( _gd.Api.FramebufferTexture(
FramebufferTarget.ReadFramebuffer, FramebufferTarget.ReadFramebuffer,
FramebufferAttachment.ColorAttachment0, FramebufferAttachment.ColorAttachment0,
_upscaledTexture.Handle, _upscaledTexture.Handle,
0); 0);
} }
GL.BlitFramebuffer( _gd.Api.BlitFramebuffer(
srcX0, srcX0,
srcY0, srcY0,
srcX1, srcX1,
@ -205,26 +205,26 @@ namespace Ryujinx.Graphics.OpenGL
_isLinear ? BlitFramebufferFilter.Linear : BlitFramebufferFilter.Nearest); _isLinear ? BlitFramebufferFilter.Linear : BlitFramebufferFilter.Nearest);
// Remove Alpha channel // Remove Alpha channel
GL.ColorMask(false, false, false, true); _gd.Api.ColorMask(false, false, false, true);
GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f); _gd.Api.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GL.Clear(ClearBufferMask.ColorBufferBit); _gd.Api.Clear(ClearBufferMask.ColorBufferBit);
for (int i = 0; i < Constants.MaxRenderTargets; i++) for (int i = 0; i < Constants.MaxRenderTargets; i++)
{ {
((Pipeline)_renderer.Pipeline).RestoreComponentMask(i); ((Pipeline)_gd.Pipeline).RestoreComponentMask(i);
} }
// Set clip control, viewport and the framebuffer to the output to placate overlays and OBS capture. // Set clip control, viewport and the framebuffer to the output to placate overlays and OBS capture.
GL.ClipControl(ClipOrigin.LowerLeft, ClipDepthMode.NegativeOneToOne); _gd.Api.ClipControl(ClipControlOrigin.LowerLeft, ClipControlDepth.NegativeOneToOne);
GL.Viewport(0, 0, _width, _height); _gd.Api.Viewport(0, 0, (uint)_width, (uint)_height);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, drawFramebuffer); _gd.Api.BindFramebuffer(FramebufferTarget.Framebuffer, drawFramebuffer);
swapBuffersCallback(); swapBuffersCallback();
((Pipeline)_renderer.Pipeline).RestoreClipControl(); ((Pipeline)_gd.Pipeline).RestoreClipControl();
((Pipeline)_renderer.Pipeline).RestoreScissor0Enable(); ((Pipeline)_gd.Pipeline).RestoreScissor0Enable();
((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard(); ((Pipeline)_gd.Pipeline).RestoreRasterizerDiscard();
((Pipeline)_renderer.Pipeline).RestoreViewport0(); ((Pipeline)_gd.Pipeline).RestoreViewport0();
if (viewConverted != view) if (viewConverted != view)
{ {
@ -232,13 +232,13 @@ namespace Ryujinx.Graphics.OpenGL
} }
} }
private int GetCopyFramebufferHandleLazy() private uint GetCopyFramebufferHandleLazy()
{ {
int handle = _copyFramebufferHandle; uint handle = _copyFramebufferHandle;
if (handle == 0) if (handle == 0)
{ {
handle = GL.GenFramebuffer(); handle = _gd.Api.GenFramebuffer();
_copyFramebufferHandle = handle; _copyFramebufferHandle = handle;
} }
@ -252,14 +252,14 @@ namespace Ryujinx.Graphics.OpenGL
_initialized = true; _initialized = true;
} }
public void CaptureFrame(int x, int y, int width, int height, bool isBgra, bool flipX, bool flipY) public void CaptureFrame(int x, int y, uint width, uint height, bool isBgra, bool flipX, bool flipY)
{ {
long size = Math.Abs(4 * width * height); long size = 4 * width * height;
byte[] bitmap = new byte[size]; byte[] bitmap = new byte[size];
GL.ReadPixels(x, y, width, height, isBgra ? PixelFormat.Bgra : PixelFormat.Rgba, PixelType.UnsignedByte, bitmap); _gd.Api.ReadPixels(x, y, width, height, isBgra ? PixelFormat.Bgra : PixelFormat.Rgba, PixelType.UnsignedByte, bitmap);
_renderer.OnScreenCaptured(new ScreenCaptureImageInfo(width, height, isBgra, bitmap, flipX, flipY)); _gd.OnScreenCaptured(new ScreenCaptureImageInfo((int)width, (int)height, isBgra, bitmap, flipX, flipY));
} }
public void Dispose() public void Dispose()
@ -273,7 +273,7 @@ namespace Ryujinx.Graphics.OpenGL
if (_copyFramebufferHandle != 0) if (_copyFramebufferHandle != 0)
{ {
GL.DeleteFramebuffer(_copyFramebufferHandle); _gd.Api.DeleteFramebuffer(_copyFramebufferHandle);
_copyFramebufferHandle = 0; _copyFramebufferHandle = 0;
} }
@ -319,7 +319,7 @@ namespace Ryujinx.Graphics.OpenGL
{ {
case AntiAliasing.Fxaa: case AntiAliasing.Fxaa:
_antiAliasing?.Dispose(); _antiAliasing?.Dispose();
_antiAliasing = new FxaaPostProcessingEffect(_renderer); _antiAliasing = new FxaaPostProcessingEffect(_gd);
break; break;
case AntiAliasing.None: case AntiAliasing.None:
_antiAliasing?.Dispose(); _antiAliasing?.Dispose();
@ -337,7 +337,7 @@ namespace Ryujinx.Graphics.OpenGL
else else
{ {
_antiAliasing?.Dispose(); _antiAliasing?.Dispose();
_antiAliasing = new SmaaPostProcessingEffect(_renderer, quality); _antiAliasing = new SmaaPostProcessingEffect(_gd, quality);
} }
break; break;
} }
@ -368,7 +368,7 @@ namespace Ryujinx.Graphics.OpenGL
if (_scalingFilter is not FsrScalingFilter) if (_scalingFilter is not FsrScalingFilter)
{ {
_scalingFilter?.Dispose(); _scalingFilter?.Dispose();
_scalingFilter = new FsrScalingFilter(_renderer); _scalingFilter = new FsrScalingFilter(_gd);
} }
_isLinear = false; _isLinear = false;
_scalingFilter.Level = _scalingFilterLevel; _scalingFilter.Level = _scalingFilterLevel;
@ -401,7 +401,7 @@ namespace Ryujinx.Graphics.OpenGL
SwizzleComponent.Alpha); SwizzleComponent.Alpha);
_isBgra = forceBgra; _isBgra = forceBgra;
_upscaledTexture = _renderer.CreateTexture(info) as TextureView; _upscaledTexture = _gd.CreateTexture(info) as TextureView;
} }
public void SetScalingFilterLevel(float level) public void SetScalingFilterLevel(float level)