Compare commits

...

5 commits

Author SHA1 Message Date
Isaac Marovitz 914f6d6af3
NV Usage 2024-05-09 12:38:23 -04:00
Isaac Marovitz 21c3dd3bcb
Extensions 2024-05-09 12:19:24 -04:00
Isaac Marovitz 5d6d8a4311
Stencil Ops 2024-05-09 12:12:36 -04:00
Isaac Marovitz d8b7d87e13
Use Legacy namespace 2024-05-09 12:10:46 -04:00
Isaac Marovitz 4ee4b0f3ac
More progress 2024-05-09 11:46:39 -04:00
38 changed files with 895 additions and 876 deletions

View file

@ -38,8 +38,9 @@
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.OpenGL" Version="2.21.0" />
<PackageVersion Include="Silk.NET.OpenGL.Legacy" Version="2.21.0" />
<PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.EXT" Version="2.21.0" />
<PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.NV" Version="2.21.0" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.16.0" />
<PackageVersion Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.16.0" />

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Graphics.GAL;
using System;
@ -69,26 +69,26 @@ namespace Ryujinx.Graphics.OpenGL
(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
// 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);
}
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
{
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, (void*)target);
return new PinnedSpan<byte>(target.ToPointer(), size);
}

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using System;

View file

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

View file

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

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Common;
using Ryujinx.Graphics.OpenGL.Image;
@ -6,25 +6,25 @@ namespace Ryujinx.Graphics.OpenGL.Effects
{
internal class FxaaPostProcessingEffect : IPostProcessingEffect
{
private readonly OpenGLRenderer _renderer;
private readonly OpenGLRenderer _gd;
private int _resolutionUniform;
private int _inputUniform;
private int _outputUniform;
private int _shaderProgram;
private uint _shaderProgram;
private TextureStorage _textureStorage;
public FxaaPostProcessingEffect(OpenGLRenderer renderer)
public FxaaPostProcessingEffect(OpenGLRenderer gd)
{
Initialize();
_renderer = renderer;
_gd = gd;
}
public void Dispose()
{
if (_shaderProgram != 0)
{
GL.DeleteProgram(_shaderProgram);
_gd.Api.DeleteProgram(_shaderProgram);
_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);
_resolutionUniform = GL.GetUniformLocation(_shaderProgram, "invResolution");
_inputUniform = GL.GetUniformLocation(_shaderProgram, "inputTexture");
_outputUniform = GL.GetUniformLocation(_shaderProgram, "imgOutput");
_resolutionUniform = _gd.Api.GetUniformLocation(_shaderProgram, "invResolution");
_inputUniform = _gd.Api.GetUniformLocation(_shaderProgram, "inputTexture");
_outputUniform = _gd.Api.GetUniformLocation(_shaderProgram, "imgOutput");
}
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)
{
_textureStorage?.Dispose();
_textureStorage = new TextureStorage(_renderer, view.Info);
_textureStorage = new TextureStorage(_gd, view.Info);
_textureStorage.CreateDefaultView();
}
var textureView = _textureStorage.CreateView(view.Info, 0, 0) as TextureView;
int previousProgram = GL.GetInteger(GetPName.CurrentProgram);
int previousUnit = GL.GetInteger(GetPName.ActiveTexture);
GL.ActiveTexture(TextureUnit.Texture0);
int previousTextureBinding = GL.GetInteger(GetPName.TextureBinding2D);
int previousProgram = _gd.Api.GetInteger(GetPName.CurrentProgram);
int previousUnit = _gd.Api.GetInteger(GetPName.ActiveTexture);
_gd.Api.ActiveTexture(TextureUnit.Texture0);
int previousTextureBinding = _gd.Api.GetInteger(GetPName.TextureBinding2D);
GL.BindImageTexture(0, textureView.Handle, 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
GL.UseProgram(_shaderProgram);
_gd.Api.BindImageTexture(0, textureView.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8);
_gd.Api.UseProgram(_shaderProgram);
var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
view.Bind(0);
GL.Uniform1(_inputUniform, 0);
GL.Uniform1(_outputUniform, 0);
GL.Uniform2(_resolutionUniform, (float)view.Width, (float)view.Height);
GL.DispatchCompute(dispatchX, dispatchY, 1);
GL.UseProgram(previousProgram);
GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit);
_gd.Api.Uniform1(_inputUniform, 0);
_gd.Api.Uniform1(_outputUniform, 0);
_gd.Api.Uniform2(_resolutionUniform, (float)view.Width, (float)view.Height);
_gd.Api.DispatchCompute(dispatchX, dispatchY, 1);
_gd.Api.UseProgram(previousProgram);
_gd.Api.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit);
(_renderer.Pipeline as Pipeline).RestoreImages1And2();
(_gd.Pipeline as Pipeline).RestoreImages1And2();
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, previousTextureBinding);
_gd.Api.ActiveTexture(TextureUnit.Texture0);
_gd.Api.BindTexture(TextureTarget.Texture2D, previousTextureBinding);
GL.ActiveTexture((TextureUnit)previousUnit);
_gd.Api.ActiveTexture((TextureUnit)previousUnit);
return textureView;
}

View file

@ -1,37 +1,37 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
namespace Ryujinx.Graphics.OpenGL.Effects
{
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);
GL.ShaderSource(shader, shaderCode);
GL.CompileShader(shader);
var shader = api.CreateShader(shaderType);
api.ShaderSource(shader, shaderCode);
api.CompileShader(shader);
var program = GL.CreateProgram();
GL.AttachShader(program, shader);
GL.LinkProgram(program);
var program = api.CreateProgram();
api.AttachShader(program, shader);
api.LinkProgram(program);
GL.DetachShader(program, shader);
GL.DeleteShader(shader);
api.DetachShader(program, shader);
api.DeleteShader(shader);
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);
GL.ShaderSource(shader, shaders.Length, shaders, (int[])null);
GL.CompileShader(shader);
var shader = api.CreateShader(shaderType);
api.ShaderSource(shader, (uint)shaders.Length, shaders, 0);
api.CompileShader(shader);
var program = GL.CreateProgram();
GL.AttachShader(program, shader);
GL.LinkProgram(program);
var program = api.CreateProgram();
api.AttachShader(program, shader);
api.LinkProgram(program);
GL.DetachShader(program, shader);
GL.DeleteShader(shader);
api.DetachShader(program, shader);
api.DeleteShader(shader);
return program;
}

View file

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

View file

@ -1,4 +1,6 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Silk.NET.OpenGL.Legacy.Extensions.NV;
using Silk.NET.OpenGL.Legacy.Extensions.EXT;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Shader;
@ -12,15 +14,15 @@ namespace Ryujinx.Graphics.OpenGL
switch (mode)
{
case AddressMode.Clamp:
return GLEnum.Clamp;
return TextureWrapMode.Clamp;
case AddressMode.Repeat:
return TextureWrapMode.Repeat;
case AddressMode.MirrorClamp:
return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampExt;
return (TextureWrapMode)EXT.MirrorClampExt;
case AddressMode.MirrorClampToEdge:
return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToEdgeExt;
return (TextureWrapMode)EXT.MirrorClampToEdgeExt;
case AddressMode.MirrorClampToBorder:
return (TextureWrapMode)ExtTextureMirrorClamp.MirrorClampToBorderExt;
return (TextureWrapMode)EXT.MirrorClampToBorderExt;
case AddressMode.ClampToBorder:
return TextureWrapMode.ClampToBorder;
case AddressMode.MirroredRepeat:
@ -34,124 +36,124 @@ namespace Ryujinx.Graphics.OpenGL
return TextureWrapMode.Clamp;
}
public static NvBlendEquationAdvanced Convert(this AdvancedBlendOp op)
public static NV Convert(this AdvancedBlendOp op)
{
switch (op)
{
case AdvancedBlendOp.Zero:
return NvBlendEquationAdvanced.Zero;
return NV.Zero;
case AdvancedBlendOp.Src:
return NvBlendEquationAdvanced.SrcNv;
return NV.SrcNV;
case AdvancedBlendOp.Dst:
return NvBlendEquationAdvanced.DstNv;
return NV.DstNV;
case AdvancedBlendOp.SrcOver:
return NvBlendEquationAdvanced.SrcOverNv;
return NV.SrcOverNV;
case AdvancedBlendOp.DstOver:
return NvBlendEquationAdvanced.DstOverNv;
return NV.DstOverNV;
case AdvancedBlendOp.SrcIn:
return NvBlendEquationAdvanced.SrcInNv;
return NV.SrcInNV;
case AdvancedBlendOp.DstIn:
return NvBlendEquationAdvanced.DstInNv;
return NV.DstInNV;
case AdvancedBlendOp.SrcOut:
return NvBlendEquationAdvanced.SrcOutNv;
return NV.SrcOutNV;
case AdvancedBlendOp.DstOut:
return NvBlendEquationAdvanced.DstOutNv;
return NV.DstOutNV;
case AdvancedBlendOp.SrcAtop:
return NvBlendEquationAdvanced.SrcAtopNv;
return NV.SrcAtopNV;
case AdvancedBlendOp.DstAtop:
return NvBlendEquationAdvanced.DstAtopNv;
return NV.DstAtopNV;
case AdvancedBlendOp.Xor:
return NvBlendEquationAdvanced.XorNv;
return NV.XorNV;
case AdvancedBlendOp.Plus:
return NvBlendEquationAdvanced.PlusNv;
return NV.PlusNV;
case AdvancedBlendOp.PlusClamped:
return NvBlendEquationAdvanced.PlusClampedNv;
return NV.PlusClampedNV;
case AdvancedBlendOp.PlusClampedAlpha:
return NvBlendEquationAdvanced.PlusClampedAlphaNv;
return NV.PlusClampedAlphaNV;
case AdvancedBlendOp.PlusDarker:
return NvBlendEquationAdvanced.PlusDarkerNv;
return NV.PlusDarkerNV;
case AdvancedBlendOp.Multiply:
return NvBlendEquationAdvanced.MultiplyNv;
return NV.MultiplyNV;
case AdvancedBlendOp.Screen:
return NvBlendEquationAdvanced.ScreenNv;
return NV.ScreenNV;
case AdvancedBlendOp.Overlay:
return NvBlendEquationAdvanced.OverlayNv;
return NV.OverlayNV;
case AdvancedBlendOp.Darken:
return NvBlendEquationAdvanced.DarkenNv;
return NV.DarkenNV;
case AdvancedBlendOp.Lighten:
return NvBlendEquationAdvanced.LightenNv;
return NV.LightenNV;
case AdvancedBlendOp.ColorDodge:
return NvBlendEquationAdvanced.ColordodgeNv;
return NV.ColordodgeNV;
case AdvancedBlendOp.ColorBurn:
return NvBlendEquationAdvanced.ColorburnNv;
return NV.ColorburnNV;
case AdvancedBlendOp.HardLight:
return NvBlendEquationAdvanced.HardlightNv;
return NV.HardlightNV;
case AdvancedBlendOp.SoftLight:
return NvBlendEquationAdvanced.SoftlightNv;
return NV.SoftlightNV;
case AdvancedBlendOp.Difference:
return NvBlendEquationAdvanced.DifferenceNv;
return NV.DifferenceNV;
case AdvancedBlendOp.Minus:
return NvBlendEquationAdvanced.MinusNv;
return NV.MinusNV;
case AdvancedBlendOp.MinusClamped:
return NvBlendEquationAdvanced.MinusClampedNv;
return NV.MinusClampedNV;
case AdvancedBlendOp.Exclusion:
return NvBlendEquationAdvanced.ExclusionNv;
return NV.ExclusionNV;
case AdvancedBlendOp.Contrast:
return NvBlendEquationAdvanced.ContrastNv;
return NV.ContrastNV;
case AdvancedBlendOp.Invert:
return NvBlendEquationAdvanced.Invert;
return NV.Invert;
case AdvancedBlendOp.InvertRGB:
return NvBlendEquationAdvanced.InvertRgbNv;
return NV.InvertRgbNV;
case AdvancedBlendOp.InvertOvg:
return NvBlendEquationAdvanced.InvertOvgNv;
return NV.InvertOvgNV;
case AdvancedBlendOp.LinearDodge:
return NvBlendEquationAdvanced.LineardodgeNv;
return NV.LineardodgeNV;
case AdvancedBlendOp.LinearBurn:
return NvBlendEquationAdvanced.LinearburnNv;
return NV.LinearburnNV;
case AdvancedBlendOp.VividLight:
return NvBlendEquationAdvanced.VividlightNv;
return NV.VividlightNV;
case AdvancedBlendOp.LinearLight:
return NvBlendEquationAdvanced.LinearlightNv;
return NV.LinearlightNV;
case AdvancedBlendOp.PinLight:
return NvBlendEquationAdvanced.PinlightNv;
return NV.PinlightNV;
case AdvancedBlendOp.HardMix:
return NvBlendEquationAdvanced.HardmixNv;
return NV.HardmixNV;
case AdvancedBlendOp.Red:
return NvBlendEquationAdvanced.RedNv;
return NV.RedNV;
case AdvancedBlendOp.Green:
return NvBlendEquationAdvanced.GreenNv;
return NV.GreenNV;
case AdvancedBlendOp.Blue:
return NvBlendEquationAdvanced.BlueNv;
return NV.BlueNV;
case AdvancedBlendOp.HslHue:
return NvBlendEquationAdvanced.HslHueNv;
return NV.HslHueNV;
case AdvancedBlendOp.HslSaturation:
return NvBlendEquationAdvanced.HslSaturationNv;
return NV.HslSaturationNV;
case AdvancedBlendOp.HslColor:
return NvBlendEquationAdvanced.HslColorNv;
return NV.HslColorNV;
case AdvancedBlendOp.HslLuminosity:
return NvBlendEquationAdvanced.HslLuminosityNv;
return NV.HslLuminosityNV;
}
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(AdvancedBlendOp)} enum value: {op}.");
return NvBlendEquationAdvanced.Zero;
return NV.Zero;
}
public static All Convert(this AdvancedBlendOverlap overlap)
public static NV Convert(this AdvancedBlendOverlap overlap)
{
switch (overlap)
{
case AdvancedBlendOverlap.Uncorrelated:
return All.UncorrelatedNv;
return NV.UncorrelatedNV;
case AdvancedBlendOverlap.Disjoint:
return All.DisjointNv;
return NV.DisjointNV;
case AdvancedBlendOverlap.Conjoint:
return All.ConjointNv;
return NV.ConjointNV;
}
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(AdvancedBlendOverlap)} enum value: {overlap}.");
return All.UncorrelatedNv;
return NV.UncorrelatedNV;
}
public static GLEnum Convert(this BlendFactor factor)
@ -411,21 +413,21 @@ namespace Ryujinx.Graphics.OpenGL
return TextureMinFilter.Nearest;
}
public static Silk.NET.OpenGL.PolygonMode Convert(this GAL.PolygonMode mode)
public static Silk.NET.OpenGL.Legacy.PolygonMode Convert(this GAL.PolygonMode mode)
{
switch (mode)
{
case GAL.PolygonMode.Point:
return Silk.NET.OpenGL.PolygonMode.Point;
return Silk.NET.OpenGL.Legacy.PolygonMode.Point;
case GAL.PolygonMode.Line:
return Silk.NET.OpenGL.PolygonMode.Line;
return Silk.NET.OpenGL.Legacy.PolygonMode.Line;
case GAL.PolygonMode.Fill:
return Silk.NET.OpenGL.PolygonMode.Fill;
return Silk.NET.OpenGL.Legacy.PolygonMode.Fill;
}
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(GAL.PolygonMode)} enum value: {mode}.");
return Silk.NET.OpenGL.PolygonMode.Fill;
return Silk.NET.OpenGL.Legacy.PolygonMode.Fill;
}
public static PrimitiveType Convert(this PrimitiveTopology topology)
@ -469,87 +471,87 @@ namespace Ryujinx.Graphics.OpenGL
return PrimitiveType.Points;
}
public static TransformFeedbackPrimitiveType ConvertToTfType(this PrimitiveTopology topology)
public static PrimitiveType ConvertToTfType(this PrimitiveTopology topology)
{
switch (topology)
{
case PrimitiveTopology.Points:
return TransformFeedbackPrimitiveType.Points;
return PrimitiveType.Points;
case PrimitiveTopology.Lines:
case PrimitiveTopology.LineLoop:
case PrimitiveTopology.LineStrip:
case PrimitiveTopology.LinesAdjacency:
case PrimitiveTopology.LineStripAdjacency:
return TransformFeedbackPrimitiveType.Lines;
return PrimitiveType.Lines;
case PrimitiveTopology.Triangles:
case PrimitiveTopology.TriangleStrip:
case PrimitiveTopology.TriangleFan:
case PrimitiveTopology.TrianglesAdjacency:
case PrimitiveTopology.TriangleStripAdjacency:
return TransformFeedbackPrimitiveType.Triangles;
return PrimitiveType.Triangles;
}
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(PrimitiveTopology)} enum value: {topology}.");
return TransformFeedbackPrimitiveType.Points;
return PrimitiveType.Points;
}
public static OpenTK.Graphics.OpenGL.StencilOp Convert(this GAL.StencilOp op)
public static Silk.NET.OpenGL.Legacy.StencilOp Convert(this GAL.StencilOp op)
{
switch (op)
{
case GAL.StencilOp.Keep:
case GAL.StencilOp.KeepGl:
return OpenTK.Graphics.OpenGL.StencilOp.Keep;
return Silk.NET.OpenGL.Legacy.StencilOp.Keep;
case GAL.StencilOp.Zero:
case GAL.StencilOp.ZeroGl:
return OpenTK.Graphics.OpenGL.StencilOp.Zero;
return Silk.NET.OpenGL.Legacy.StencilOp.Zero;
case GAL.StencilOp.Replace:
case GAL.StencilOp.ReplaceGl:
return OpenTK.Graphics.OpenGL.StencilOp.Replace;
return Silk.NET.OpenGL.Legacy.StencilOp.Replace;
case GAL.StencilOp.IncrementAndClamp:
case GAL.StencilOp.IncrementAndClampGl:
return OpenTK.Graphics.OpenGL.StencilOp.Incr;
return Silk.NET.OpenGL.Legacy.StencilOp.Incr;
case GAL.StencilOp.DecrementAndClamp:
case GAL.StencilOp.DecrementAndClampGl:
return OpenTK.Graphics.OpenGL.StencilOp.Decr;
return Silk.NET.OpenGL.Legacy.StencilOp.Decr;
case GAL.StencilOp.Invert:
case GAL.StencilOp.InvertGl:
return OpenTK.Graphics.OpenGL.StencilOp.Invert;
return Silk.NET.OpenGL.Legacy.StencilOp.Invert;
case GAL.StencilOp.IncrementAndWrap:
case GAL.StencilOp.IncrementAndWrapGl:
return OpenTK.Graphics.OpenGL.StencilOp.IncrWrap;
return Silk.NET.OpenGL.Legacy.StencilOp.IncrWrap;
case GAL.StencilOp.DecrementAndWrap:
case GAL.StencilOp.DecrementAndWrapGl:
return OpenTK.Graphics.OpenGL.StencilOp.DecrWrap;
return Silk.NET.OpenGL.Legacy.StencilOp.DecrWrap;
}
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(GAL.StencilOp)} enum value: {op}.");
return OpenTK.Graphics.OpenGL.StencilOp.Keep;
return Silk.NET.OpenGL.Legacy.StencilOp.Keep;
}
public static All Convert(this SwizzleComponent swizzleComponent)
public static GLEnum Convert(this SwizzleComponent swizzleComponent)
{
switch (swizzleComponent)
{
case SwizzleComponent.Zero:
return All.Zero;
return GLEnum.Zero;
case SwizzleComponent.One:
return All.One;
return GLEnum.One;
case SwizzleComponent.Red:
return All.Red;
return GLEnum.Red;
case SwizzleComponent.Green:
return All.Green;
return GLEnum.Green;
case SwizzleComponent.Blue:
return All.Blue;
return GLEnum.Blue;
case SwizzleComponent.Alpha:
return All.Alpha;
return GLEnum.Alpha;
}
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(SwizzleComponent)} enum value: {swizzleComponent}.");
return All.Zero;
return GLEnum.Zero;
}
public static CopyImageSubDataTarget ConvertToImageTarget(this Target target)
@ -588,31 +590,31 @@ namespace Ryujinx.Graphics.OpenGL
return TextureTarget.Texture2D;
}
public static NvViewportSwizzle Convert(this ViewportSwizzle swizzle)
public static NV Convert(this ViewportSwizzle swizzle)
{
switch (swizzle)
{
case ViewportSwizzle.PositiveX:
return NvViewportSwizzle.ViewportSwizzlePositiveXNv;
return NV.ViewportSwizzlePositiveXNV;
case ViewportSwizzle.PositiveY:
return NvViewportSwizzle.ViewportSwizzlePositiveYNv;
return NV.ViewportSwizzlePositiveYNV;
case ViewportSwizzle.PositiveZ:
return NvViewportSwizzle.ViewportSwizzlePositiveZNv;
return NV.ViewportSwizzlePositiveZNV;
case ViewportSwizzle.PositiveW:
return NvViewportSwizzle.ViewportSwizzlePositiveWNv;
return NV.ViewportSwizzlePositiveWNV;
case ViewportSwizzle.NegativeX:
return NvViewportSwizzle.ViewportSwizzleNegativeXNv;
return NV.ViewportSwizzleNegativeXNV;
case ViewportSwizzle.NegativeY:
return NvViewportSwizzle.ViewportSwizzleNegativeYNv;
return NV.ViewportSwizzleNegativeYNV;
case ViewportSwizzle.NegativeZ:
return NvViewportSwizzle.ViewportSwizzleNegativeZNv;
return NV.ViewportSwizzleNegativeZNV;
case ViewportSwizzle.NegativeW:
return NvViewportSwizzle.ViewportSwizzleNegativeWNv;
return NV.ViewportSwizzleNegativeWNV;
}
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(ViewportSwizzle)} enum value: {swizzle}.");
return NvViewportSwizzle.ViewportSwizzlePositiveXNv;
return NV.ViewportSwizzlePositiveXNV;
}
public static GLEnum Convert(this LogicalOp op)

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
namespace Ryujinx.Graphics.OpenGL
{

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Graphics.GAL;
using System;

View file

@ -1,6 +1,7 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.OpenGL.Image;
using Silk.NET.OpenGL.Legacy.Extensions.NV;
using System;
using System.Runtime.CompilerServices;
@ -23,14 +24,15 @@ namespace Ryujinx.Graphics.OpenGL
public Framebuffer(GL api)
{
Handle = GL.GenFramebuffer();
_clearFbHandle = GL.GenFramebuffer();
_api = api;
Handle = _api.GenFramebuffer();
_clearFbHandle = _api.GenFramebuffer();
_colors = new TextureView[8];
_api = api;
}
public int Bind()
public uint Bind()
{
_api.BindFramebuffer(FramebufferTarget.Framebuffer, Handle);
return Handle;
@ -203,7 +205,7 @@ namespace Ryujinx.Graphics.OpenGL
if (!_clearFbInitialized)
{
SetDrawBuffersImpl(Constants.MaxRenderTargets);
SetDrawBuffersImpl(_api, Constants.MaxRenderTargets);
_clearFbInitialized = true;
}
}

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using System;
namespace Ryujinx.Graphics.OpenGL

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Graphics.GAL;
namespace Ryujinx.Graphics.OpenGL.Image

View file

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

View file

@ -1,5 +1,5 @@
using Ryujinx.Graphics.GAL;
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
namespace Ryujinx.Graphics.OpenGL.Image
{

View file

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

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Graphics.GAL;
using System;
using System.Buffers;
@ -7,16 +7,15 @@ namespace Ryujinx.Graphics.OpenGL.Image
{
class TextureBuffer : TextureBase, ITexture
{
private readonly OpenGLRenderer _renderer;
private int _bufferOffset;
private int _bufferSize;
private int _bufferCount;
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)
@ -41,7 +40,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
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)
@ -59,7 +58,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{
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();
}
@ -82,7 +81,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
_buffer == buffer.Handle &&
buffer.Offset == _bufferOffset &&
buffer.Size == _bufferSize &&
_renderer.BufferCount == _bufferCount)
_gd.BufferCount == _bufferCount)
{
// Only rebind the buffer when more have been created.
return;
@ -91,20 +90,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
_buffer = buffer.Handle;
_bufferOffset = buffer.Offset;
_bufferSize = buffer.Size;
_bufferCount = _renderer.BufferCount;
_bufferCount = _gd.BufferCount;
Bind(0);
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()
{
if (Handle != 0)
{
Api.DeleteTexture(Handle);
_gd.Api.DeleteTexture(Handle);
Handle = 0;
}

View file

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

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using System;
using System.Collections.Generic;
using System.Globalization;
@ -67,15 +67,13 @@ void main()
imageStore(dst, ivec2(coords), uvec4(r, g, b, a));
}";
private readonly GL _api;
private readonly OpenGLRenderer _renderer;
private readonly OpenGLRenderer _gd;
private readonly Dictionary<int, uint> _shorteningProgramHandles;
private readonly Dictionary<int, uint> _wideningProgramHandles;
public TextureCopyIncompatible(GL api, OpenGLRenderer renderer)
public TextureCopyIncompatible(OpenGLRenderer gd)
{
_api = api;
_renderer = renderer;
_gd = gd;
_shorteningProgramHandles = new Dictionary<int, uint>();
_wideningProgramHandles = new Dictionary<int, uint>();
}
@ -96,7 +94,7 @@ void main()
var srcFormat = (InternalFormat)GetFormat(componentSize, srcComponentsCount);
var dstFormat = (InternalFormat)GetFormat(componentSize, dstComponentsCount);
_api.UseProgram(srcBpp < dstBpp
_gd.Api.UseProgram(srcBpp < dstBpp
? GetWideningShader(componentSize, srcComponentsCount, dstComponentsCount)
: GetShorteningShader(componentSize, srcComponentsCount, dstComponentsCount));
@ -113,14 +111,14 @@ void main()
for (int z = 0; z < depth; z++)
{
_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(0, src.Handle, srcLevel + l, false, srcLayer + z, BufferAccessARB.ReadOnly, srcFormat);
_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.RestoreImages1And2();
@ -190,7 +188,7 @@ void main()
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" };
@ -203,25 +201,25 @@ void main()
int ratio = srcBpp < dstBpp ? dstBpp / srcBpp : srcBpp / dstBpp;
int ratioLog2 = BitOperations.Log2((uint)ratio);
_api.ShaderSource(csHandle, code
_gd.Api.ShaderSource(csHandle, code
.Replace("$SRC_FORMAT$", srcFormat)
.Replace("$DST_FORMAT$", dstFormat)
.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);
_api.LinkProgram(programHandle);
_api.DetachShader(programHandle, csHandle);
_api.DeleteShader(csHandle);
_gd.Api.AttachShader(programHandle, csHandle);
_gd.Api.LinkProgram(programHandle);
_gd.Api.DetachShader(programHandle, 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)
{
throw new Exception(_api.GetProgramInfoLog(programHandle));
throw new Exception(_gd.Api.GetProgramInfoLog(programHandle));
}
programHandles.Add(key, programHandle);
@ -234,14 +232,14 @@ void main()
{
foreach (uint handle in _shorteningProgramHandles.Values)
{
_api.DeleteProgram(handle);
_gd.Api.DeleteProgram(handle);
}
_shorteningProgramHandles.Clear();
foreach (uint handle in _wideningProgramHandles.Values)
{
_api.DeleteProgram(handle);
_gd.Api.DeleteProgram(handle);
}
_wideningProgramHandles.Clear();

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Graphics.GAL;
using System;
using System.Numerics;
@ -93,15 +93,13 @@ void main()
imageStore(imgOut, ivec2(int(coords.x) >> samplesInXLog2, int(coords.y) >> samplesInYLog2), sampleIdx, value);
}";
private readonly GL _api;
private readonly OpenGLRenderer _renderer;
private readonly OpenGLRenderer _gd;
private readonly uint[] _msToNonMSProgramHandles;
private readonly uint[] _nonMSToMSProgramHandles;
public TextureCopyMS(GL api, OpenGLRenderer renderer)
public TextureCopyMS(OpenGLRenderer gd)
{
_api = api;
_renderer = renderer;
_gd = gd;
_msToNonMSProgramHandles = new uint[5];
_nonMSToMSProgramHandles = new uint[5];
}
@ -117,17 +115,17 @@ void main()
uint dstWidth = (uint)dstInfo.Width;
uint dstHeight = (uint)dstInfo.Height;
_api.UseProgram(GetMSToNonMSShader(srcInfo.BytesPerPixel));
_gd.Api.UseProgram(GetMSToNonMSShader(srcInfo.BytesPerPixel));
for (int z = 0; z < depth; z++)
{
_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(0, srcHandle, 0, false, srcLayer + z, BufferAccessARB.ReadOnly, (InternalFormat)GetFormat(srcInfo.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.RestoreImages1And2();
@ -147,17 +145,17 @@ void main()
uint srcWidth = (uint)srcInfo.Width;
uint srcHeight = (uint)srcInfo.Height;
_api.UseProgram(GetNonMSToMSShader(srcInfo.BytesPerPixel));
_gd.Api.UseProgram(GetNonMSToMSShader(srcInfo.BytesPerPixel));
for (int z = 0; z < depth; z++)
{
_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(0, srcHandle, 0, false, srcLayer + z, BufferAccessARB.ReadOnly, (InternalFormat)GetFormat(srcInfo.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.RestoreImages1And2();
@ -185,9 +183,9 @@ void main()
// we need to create and bind a RGBA view for it to work.
if (texture.Info.Format == Format.R8G8B8A8Srgb)
{
uint handle = _api.GenTexture();
uint handle = _gd.Api.GenTexture();
_api.TextureView(
_gd.Api.TextureView(
handle,
texture.Info.Target.Convert(),
texture.Storage.Handle,
@ -207,7 +205,7 @@ void main()
{
if (info.Handle != handle)
{
_api.DeleteTexture(handle);
_gd.Api.DeleteTexture(handle);
}
}
@ -227,25 +225,25 @@ void main()
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];
_api.ShaderSource(csHandle, code.Replace("$FORMAT$", format));
_api.CompileShader(csHandle);
_gd.Api.ShaderSource(csHandle, code.Replace("$FORMAT$", format));
_gd.Api.CompileShader(csHandle);
uint programHandle = _api.CreateProgram();
uint programHandle = _gd.Api.CreateProgram();
_api.AttachShader(programHandle, csHandle);
_api.LinkProgram(programHandle);
_api.DetachShader(programHandle, csHandle);
_api.DeleteShader(csHandle);
_gd.Api.AttachShader(programHandle, csHandle);
_gd.Api.LinkProgram(programHandle);
_gd.Api.DetachShader(programHandle, 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)
{
throw new Exception(_api.GetProgramInfoLog(programHandle));
throw new Exception(_gd.Api.GetProgramInfoLog(programHandle));
}
programHandles[index] = programHandle;
@ -260,7 +258,7 @@ void main()
{
if (_msToNonMSProgramHandles[i] != 0)
{
_api.DeleteProgram(_msToNonMSProgramHandles[i]);
_gd.Api.DeleteProgram(_msToNonMSProgramHandles[i]);
_msToNonMSProgramHandles[i] = 0;
}
}
@ -269,7 +267,7 @@ void main()
{
if (_nonMSToMSProgramHandles[i] != 0)
{
_api.DeleteProgram(_nonMSToMSProgramHandles[i]);
_gd.Api.DeleteProgram(_nonMSToMSProgramHandles[i]);
_nonMSToMSProgramHandles[i] = 0;
}
}

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
@ -11,20 +11,18 @@ namespace Ryujinx.Graphics.OpenGL.Image
public TextureCreateInfo Info { get; }
private readonly OpenGLRenderer _renderer;
private readonly GL _api;
private readonly OpenGLRenderer _gd;
private int _viewsCount;
internal ITexture DefaultView { get; private set; }
public TextureStorage(GL api, OpenGLRenderer renderer, TextureCreateInfo info)
public TextureStorage(OpenGLRenderer gd, TextureCreateInfo info)
{
_api = api;
_renderer = renderer;
_gd = gd;
Info = info;
Handle = _api.GenTexture();
Handle = _gd.Api.GenTexture();
CreateImmutableStorage();
}
@ -33,9 +31,9 @@ namespace Ryujinx.Graphics.OpenGL.Image
{
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);
@ -55,7 +53,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
switch (Info.Target)
{
case Target.Texture1D:
_api.TexStorage1D(
_gd.Api.TexStorage1D(
TextureTarget.Texture1D,
levels,
internalFormat,
@ -63,7 +61,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break;
case Target.Texture1DArray:
_api.TexStorage2D(
_gd.Api.TexStorage2D(
TextureTarget.Texture1DArray,
levels,
internalFormat,
@ -72,7 +70,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break;
case Target.Texture2D:
_api.TexStorage2D(
_gd.Api.TexStorage2D(
TextureTarget.Texture2D,
levels,
internalFormat,
@ -81,7 +79,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break;
case Target.Texture2DArray:
_api.TexStorage3D(
_gd.Api.TexStorage3D(
TextureTarget.Texture2DArray,
levels,
internalFormat,
@ -91,7 +89,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break;
case Target.Texture2DMultisample:
_api.TexStorage2DMultisample(
_gd.Api.TexStorage2DMultisample(
TextureTarget.Texture2DMultisample,
(uint)Info.Samples,
internalFormat,
@ -101,7 +99,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break;
case Target.Texture2DMultisampleArray:
_api.TexStorage3DMultisample(
_gd.Api.TexStorage3DMultisample(
TextureTarget.Texture2DMultisampleArray,
(uint)Info.Samples,
internalFormat,
@ -112,7 +110,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break;
case Target.Texture3D:
_api.TexStorage3D(
_gd.Api.TexStorage3D(
TextureTarget.Texture3D,
levels,
internalFormat,
@ -122,7 +120,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break;
case Target.Cubemap:
_api.TexStorage2D(
_gd.Api.TexStorage2D(
TextureTarget.TextureCubeMap,
levels,
internalFormat,
@ -131,7 +129,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
break;
case Target.CubemapArray:
_api.TexStorage3D(
_gd.Api.TexStorage3D(
TextureTarget.TextureCubeMapArray,
levels,
internalFormat,
@ -153,11 +151,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
return DefaultView;
}
public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel)
public ITexture CreateView(TextureCreateInfo info, uint firstLayer, uint firstLevel)
{
IncrementViewsCount();
return new TextureView(_renderer, this, info, firstLayer, firstLevel);
return new TextureView(_gd, this, info, firstLayer, firstLevel);
}
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.
_renderer.ResourcePool.AddTexture((TextureView)DefaultView);
_gd.ResourcePool.AddTexture((TextureView)DefaultView);
}
public void DeleteDefault()
@ -203,7 +201,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (Handle != 0)
{
_api.DeleteTexture(Handle);
_gd.Api.DeleteTexture(Handle);
Handle = 0;
}

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Common;
using Ryujinx.Graphics.GAL;
using System;
@ -9,23 +9,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
{
class TextureView : TextureBase, ITexture, ITextureInfo
{
private readonly OpenGLRenderer _renderer;
private readonly TextureStorage _parent;
public ITextureInfo Storage => _parent;
public int FirstLayer { get; private set; }
public int FirstLevel { get; private set; }
public uint FirstLayer { get; private set; }
public uint FirstLevel { get; private set; }
public TextureView(
OpenGLRenderer renderer,
OpenGLRenderer gd,
TextureStorage parent,
TextureCreateInfo info,
int firstLayer,
int firstLevel) : base(info)
uint firstLayer,
uint firstLevel) : base(gd, info)
{
_renderer = renderer;
_parent = parent;
FirstLayer = firstLayer;
@ -40,20 +37,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
FormatInfo format = FormatTable.GetFormatInfo(Info.Format);
InternalFormat pixelInternalFormat;
SizedInternalFormat pixelInternalFormat;
if (format.IsCompressed)
{
pixelInternalFormat = (InternalFormat)format.PixelFormat;
pixelInternalFormat = (SizedInternalFormat)format.PixelFormat;
}
else
{
pixelInternalFormat = format.InternalFormat;
pixelInternalFormat = (SizedInternalFormat)format.InternalFormat;
}
int levels = Info.GetLevelsClamped();
uint levels = (uint)Info.GetLevelsClamped();
GL.TextureView(
_gd.Api.TextureView(
Handle,
target,
_parent.Handle,
@ -61,11 +58,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
FirstLevel,
levels,
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[]
{
@ -91,20 +88,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
(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)
{
maxLevel = 0;
}
GL.TexParameter(target, TextureParameterName.TextureMaxLevel, maxLevel);
GL.TexParameter(target, TextureParameterName.DepthStencilTextureMode, (int)Info.DepthStencilMode.Convert());
_gd.Api.TexParameter(target, TextureParameterName.TextureMaxLevel, maxLevel);
_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;
firstLevel += FirstLevel;
@ -112,7 +109,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
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;
@ -121,24 +118,24 @@ namespace Ryujinx.Graphics.OpenGL.Image
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);
}
else if (!dstIsMultisample && srcIsMultisample)
{
int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
_renderer.TextureCopyMS.CopyMSToNonMS(this, destinationView, 0, firstLayer, layers);
uint layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
_gd.TextureCopyMS.CopyMSToNonMS(this, destinationView, 0, firstLayer, layers);
}
else if (dstIsMultisample && !srcIsMultisample)
{
int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
_renderer.TextureCopyMS.CopyNonMSToMS(this, destinationView, 0, firstLayer, layers);
uint layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
_gd.TextureCopyMS.CopyNonMSToMS(this, destinationView, 0, firstLayer, layers);
}
else if (destinationView.Info.BytesPerPixel != Info.BytesPerPixel)
{
int layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
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())
{
@ -158,13 +155,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
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
{
_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)
{
_renderer.TextureCopyMS.CopyMSToNonMS(this, destinationView, srcLayer, dstLayer, 1);
_gd.TextureCopyMS.CopyMSToNonMS(this, destinationView, srcLayer, dstLayer, 1);
}
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)
{
_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())
{
int minWidth = Math.Min(Width, destinationView.Width);
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
{
_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.
// 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())
{
TextureView intermmediate = _renderer.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast(
TextureView intermmediate = _gd.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast(
Info.Target,
Info.BlockWidth,
Info.BlockHeight,
@ -230,8 +227,8 @@ namespace Ryujinx.Graphics.OpenGL.Image
1,
1);
_renderer.TextureCopy.Copy(this, intermmediate, srcRegion, dstRegion, false);
_renderer.TextureCopy.Copy(intermmediate, destinationView, dstRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1);
_gd.TextureCopy.Copy(this, intermmediate, srcRegion, dstRegion, false);
_gd.TextureCopy.Copy(intermmediate, destinationView, dstRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1);
}
else
{
@ -242,7 +239,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
_ => Target,
};
TextureView intermmediate = _renderer.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast(
TextureView intermmediate = _gd.TextureCopy.IntermediatePool.GetOrCreateWithAtLeast(
target,
Info.BlockWidth,
Info.BlockHeight,
@ -254,14 +251,14 @@ namespace Ryujinx.Graphics.OpenGL.Image
1,
1);
_renderer.TextureCopy.Copy(this, intermmediate, srcRegion, srcRegion, false);
_renderer.TextureCopy.Copy(intermmediate, destinationView, srcRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1);
_gd.TextureCopy.Copy(this, intermmediate, srcRegion, srcRegion, false);
_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)
{
_renderer.TextureCopy.Copy(this, (TextureView)destination, srcRegion, dstRegion, linearFilter);
_gd.TextureCopy.Copy(this, (TextureView)destination, srcRegion, dstRegion, linearFilter);
}
public unsafe PinnedSpan<byte> GetData()
@ -278,11 +275,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (HwCapabilities.UsePersistentBufferForFlush)
{
data = _renderer.PersistentBuffers.Default.GetTextureData(this, size);
data = _gd.PersistentBuffers.Default.GetTextureData(this, size);
}
else
{
IntPtr target = _renderer.PersistentBuffers.Default.GetHostArray(size);
IntPtr target = _gd.PersistentBuffers.Default.GetHostArray(size);
WriteTo(target);
@ -303,11 +300,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
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
{
IntPtr target = _renderer.PersistentBuffers.Default.GetHostArray(size);
IntPtr target = _gd.PersistentBuffers.Default.GetHostArray(size);
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.");
}
GL.BindBuffer(BufferTargetARB.PixelPackBuffer, range.Handle.ToInt32());
_gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, range.Handle.ToUInt32());
FormatInfo format = FormatTable.GetFormatInfo(Info.Format);
if (format.PixelFormat == PixelFormat.DepthStencil)
@ -334,7 +331,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
Debug.Assert(offset == 0);
GL.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
_gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
}
public void WriteToPbo(int offset, bool forceBgra)
@ -367,15 +364,15 @@ namespace Ryujinx.Graphics.OpenGL.Image
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)
{
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
{
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.
return target switch
@ -436,11 +433,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
if (format.IsCompressed)
{
GL.GetCompressedTexImage(target + face, level, data + faceOffset);
_gd.Api.GetCompressedTexImage(target + face, level, data + faceOffset);
}
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:
if (format.IsCompressed)
{
GL.CompressedTexSubImage1D(
_gd.Api.CompressedTexSubImage1D(
target,
level,
x,
width,
format.PixelFormat,
mipSize,
(uint)width,
(InternalFormat)format.PixelFormat,
(uint)mipSize,
data);
}
else
{
GL.TexSubImage1D(
_gd.Api.TexSubImage1D(
target,
level,
x,
width,
(uint)width,
format.PixelFormat,
format.PixelType,
data);
@ -573,25 +570,25 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.Texture1DArray:
if (format.IsCompressed)
{
GL.CompressedTexSubImage2D(
_gd.Api.CompressedTexSubImage2D(
target,
level,
x,
layer,
width,
(uint)width,
1,
format.PixelFormat,
mipSize,
(InternalFormat)format.PixelFormat,
(uint)mipSize,
data);
}
else
{
GL.TexSubImage2D(
_gd.Api.TexSubImage2D(
target,
level,
x,
layer,
width,
(uint)width,
1,
format.PixelFormat,
format.PixelType,
@ -602,26 +599,26 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.Texture2D:
if (format.IsCompressed)
{
GL.CompressedTexSubImage2D(
_gd.Api.CompressedTexSubImage2D(
target,
level,
x,
y,
width,
height,
format.PixelFormat,
mipSize,
(uint)width,
(uint)height,
(InternalFormat)format.PixelFormat,
(uint)mipSize,
data);
}
else
{
GL.TexSubImage2D(
_gd.Api.TexSubImage2D(
target,
level,
x,
y,
width,
height,
(uint)width,
(uint)height,
format.PixelFormat,
format.PixelType,
data);
@ -633,29 +630,29 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.CubemapArray:
if (format.IsCompressed)
{
GL.CompressedTexSubImage3D(
_gd.Api.CompressedTexSubImage3D(
target,
level,
x,
y,
layer,
width,
height,
(uint)width,
(uint)height,
1,
format.PixelFormat,
mipSize,
(InternalFormat)format.PixelFormat,
(uint)mipSize,
data);
}
else
{
GL.TexSubImage3D(
_gd.Api.TexSubImage3D(
target,
level,
x,
y,
layer,
width,
height,
(uint)width,
(uint)height,
1,
format.PixelFormat,
format.PixelType,
@ -666,26 +663,26 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.Cubemap:
if (format.IsCompressed)
{
GL.CompressedTexSubImage2D(
_gd.Api.CompressedTexSubImage2D(
TextureTarget.TextureCubeMapPositiveX + layer,
level,
x,
y,
width,
height,
format.PixelFormat,
mipSize,
(uint)width,
(uint)height,
(InternalFormat)format.PixelFormat,
(uint)mipSize,
data);
}
else
{
GL.TexSubImage2D(
_gd.Api.TexSubImage2D(
TextureTarget.TextureCubeMapPositiveX + layer,
level,
x,
y,
width,
height,
(uint)width,
(uint)height,
format.PixelFormat,
format.PixelType,
data);
@ -697,13 +694,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
private void ReadFrom(IntPtr data, int size)
{
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.
if (Target == Target.Cubemap && HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows)
{
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(target, Storage.Handle);
_gd.Api.ActiveTexture(TextureUnit.Texture0);
_gd.Api.BindTexture(target, Storage.Handle);
baseLevel = FirstLevel;
}
else
@ -736,7 +733,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.Texture1D:
if (format.IsCompressed)
{
GL.CompressedTexSubImage1D(
_gd.Api.CompressedTexSubImage1D(
target,
level,
0,
@ -747,7 +744,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
}
else
{
GL.TexSubImage1D(
_gd.Api.TexSubImage1D(
target,
level,
0,
@ -762,7 +759,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.Texture2D:
if (format.IsCompressed)
{
GL.CompressedTexSubImage2D(
_gd.Api.CompressedTexSubImage2D(
target,
level,
0,
@ -775,7 +772,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
}
else
{
GL.TexSubImage2D(
_gd.Api.TexSubImage2D(
target,
level,
0,
@ -793,7 +790,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
case Target.CubemapArray:
if (format.IsCompressed)
{
GL.CompressedTexSubImage3D(
_gd.Api.CompressedTexSubImage3D(
target,
level,
0,
@ -808,7 +805,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
}
else
{
GL.TexSubImage3D(
_gd.Api.TexSubImage3D(
target,
level,
0,
@ -830,7 +827,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{
if (format.IsCompressed)
{
GL.CompressedTexSubImage2D(
_gd.Api.CompressedTexSubImage2D(
TextureTarget.TextureCubeMapPositiveX + face,
baseLevel + level,
0,
@ -843,7 +840,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
}
else
{
GL.TexSubImage2D(
_gd.Api.TexSubImage2D(
TextureTarget.TextureCubeMapPositiveX + face,
baseLevel + level,
0,
@ -880,7 +877,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{
if (Handle != 0)
{
GL.DeleteTexture(Handle);
_gd.Api.DeleteTexture(Handle);
Handle = 0;
}

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
@ -6,12 +6,13 @@ using Ryujinx.Graphics.OpenGL.Image;
using Ryujinx.Graphics.OpenGL.Queries;
using Ryujinx.Graphics.Shader.Translation;
using System;
using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler;
namespace Ryujinx.Graphics.OpenGL
{
public sealed class OpenGLRenderer : IRenderer
{
private GL _api;
public readonly GL Api;
private readonly Pipeline _pipeline;
public IPipeline Pipeline => _pipeline;
@ -44,16 +45,17 @@ namespace Ryujinx.Graphics.OpenGL
public bool PreferThreading => true;
public OpenGLRenderer()
public OpenGLRenderer(GL api)
{
_pipeline = new Pipeline();
_counters = new Counters();
Api = api;
_pipeline = new Pipeline(Api);
_counters = new Counters(Api);
_window = new Window(this);
_textureCopy = new TextureCopy(this);
_backgroundTextureCopy = new TextureCopy(this);
TextureCopyIncompatible = new TextureCopyIncompatible(this);
TextureCopyMS = new TextureCopyMS(this);
_sync = new Sync();
_sync = new Sync(Api);
PersistentBuffers = new PersistentBuffers();
ResourcePool = new ResourcePool();
}
@ -64,7 +66,7 @@ namespace Ryujinx.Graphics.OpenGL
if (access.HasFlag(BufferAccess.FlushPersistent))
{
BufferHandle handle = Buffer.CreatePersistent(_api, size);
BufferHandle handle = Buffer.CreatePersistent(Api, size);
PersistentBuffers.Map(handle, size);
@ -72,7 +74,7 @@ namespace Ryujinx.Graphics.OpenGL
}
else
{
return Buffer.Create(_api, size);
return Buffer.Create(Api, size);
}
}
@ -93,17 +95,17 @@ namespace Ryujinx.Graphics.OpenGL
public IImageArray CreateImageArray(int size, bool isBuffer)
{
return new ImageArray(size);
return new ImageArray(Api, size);
}
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
{
return new Program(shaders, info.FragmentOutputMap);
return new Program(Api, shaders, info.FragmentOutputMap);
}
public ISampler CreateSampler(SamplerCreateInfo info)
{
return new Sampler(info);
return new Sampler(Api, info);
}
public ITexture CreateTexture(TextureCreateInfo info)
@ -120,14 +122,14 @@ namespace Ryujinx.Graphics.OpenGL
public ITextureArray CreateTextureArray(int size, bool isBuffer)
{
return new TextureArray(size);
return new TextureArray(Api, size);
}
public void DeleteBuffer(BufferHandle buffer)
{
PersistentBuffers.Unmap(buffer);
Buffer.Delete(buffer);
Buffer.Delete(Api, buffer);
}
public HardwareInfo GetHardwareInfo()
@ -203,7 +205,7 @@ namespace Ryujinx.Graphics.OpenGL
public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan<byte> data)
{
Buffer.SetData(buffer, offset, data);
Buffer.SetData(Api, buffer, offset, data);
}
public void UpdateCounters()
@ -224,7 +226,7 @@ namespace Ryujinx.Graphics.OpenGL
public void Initialize(GraphicsDebugLevel glLogLevel)
{
Debugger.Initialize(glLogLevel);
Debugger.Initialize(Api, glLogLevel);
PrintGpuInformation();
@ -239,14 +241,14 @@ namespace Ryujinx.Graphics.OpenGL
// 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
// 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()
{
GpuVendor = GL.GetString(StringName.Vendor);
GpuRenderer = GL.GetString(StringName.Renderer);
GpuVersion = GL.GetString(StringName.Version);
GpuVendor = Api.GetString(StringName.Vendor);
GpuRenderer = Api.GetString(StringName.Renderer);
GpuVersion = Api.GetString(StringName.Version);
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
}
@ -290,7 +292,7 @@ namespace Ryujinx.Graphics.OpenGL
public IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info)
{
return new Program(programBinary, hasFragmentShader, info.FragmentOutputMap);
return new Program(Api, programBinary, hasFragmentShader, info.FragmentOutputMap);
}
public void CreateSync(ulong id, bool strict)

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Shader;
@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.OpenGL
{
private const int MaxShaderLogLength = 2048;
public int Handle { get; private set; }
public uint Handle { get; private set; }
public bool IsLinked
{
@ -27,18 +27,20 @@ namespace Ryujinx.Graphics.OpenGL
}
}
private readonly GL _api;
private ProgramLinkStatus _status = ProgramLinkStatus.Incomplete;
private int[] _shaderHandles;
private uint[] _shaderHandles;
public int FragmentOutputMap { get; }
public Program(ShaderSource[] shaders, int fragmentOutputMap)
public Program(GL api, ShaderSource[] shaders, int fragmentOutputMap)
{
Handle = GL.CreateProgram();
_api = api;
Handle = _api.CreateProgram();
GL.ProgramParameter(Handle, ProgramParameterName.ProgramBinaryRetrievableHint, 1);
_api.ProgramParameter(Handle, ProgramParameterPName.BinaryRetrievableHint, 1);
_shaderHandles = new int[shaders.Length];
_shaderHandles = new uint[shaders.Length];
bool hasFragmentShader = false;
for (int index = 0; index < shaders.Length; index++)
@ -50,43 +52,44 @@ namespace Ryujinx.Graphics.OpenGL
hasFragmentShader = true;
}
int shaderHandle = GL.CreateShader(shader.Stage.Convert());
uint shaderHandle = _api.CreateShader(shader.Stage.Convert());
switch (shader.Language)
{
case TargetLanguage.Glsl:
GL.ShaderSource(shaderHandle, shader.Code);
GL.CompileShader(shaderHandle);
_api.ShaderSource(shaderHandle, shader.Code);
_api.CompileShader(shaderHandle);
break;
case TargetLanguage.Spirv:
GL.ShaderBinary(1, ref shaderHandle, (BinaryFormat)All.ShaderBinaryFormatSpirVArb, shader.BinaryCode, shader.BinaryCode.Length);
GL.SpecializeShader(shaderHandle, "main", 0, (int[])null, (int[])null);
_api.ShaderBinary(1, ref shaderHandle, ShaderBinaryFormat.ShaderBinaryFormatSpirV, shader.BinaryCode, shader.BinaryCode.Length);
_api.SpecializeShader(shaderHandle, "main", 0, (int[])null, (int[])null);
break;
}
GL.AttachShader(Handle, shaderHandle);
_api.AttachShader(Handle, shaderHandle);
_shaderHandles[index] = shaderHandle;
}
GL.LinkProgram(Handle);
_api.LinkProgram(Handle);
FragmentOutputMap = hasFragmentShader ? fragmentOutputMap : 0;
}
public Program(ReadOnlySpan<byte> code, bool hasFragmentShader, int fragmentOutputMap)
public Program(GL api, ReadOnlySpan<byte> code, bool hasFragmentShader, int fragmentOutputMap)
{
Handle = GL.CreateProgram();
_api = api;
Handle = _api.CreateProgram();
if (code.Length >= 4)
{
BinaryFormat binaryFormat = (BinaryFormat)BinaryPrimitives.ReadInt32LittleEndian(code.Slice(code.Length - 4, 4));
ShaderBinaryFormat binaryFormat = (ShaderBinaryFormat)BinaryPrimitives.ReadInt32LittleEndian(code.Slice(code.Length - 4, 4));
unsafe
{
fixed (byte* ptr = code)
{
GL.ProgramBinary(Handle, binaryFormat, (IntPtr)ptr, code.Length - 4);
_api.ProgramBinary(Handle, binaryFormat, (IntPtr)ptr, code.Length - 4);
}
}
}
@ -96,14 +99,14 @@ namespace Ryujinx.Graphics.OpenGL
public void Bind()
{
GL.UseProgram(Handle);
_api.UseProgram(Handle);
}
public ProgramLinkStatus CheckProgramLink(bool blocking)
{
if (!blocking && HwCapabilities.SupportsParallelShaderCompile)
{
GL.GetProgram(Handle, (GetProgramParameterName)ArbParallelShaderCompile.CompletionStatusArb, out int completed);
_api.GetProgram(Handle, (GetProgramParameterName)ArbParallelShaderCompile.CompletionStatusArb, out int completed);
if (completed == 0)
{
@ -111,14 +114,14 @@ namespace Ryujinx.Graphics.OpenGL
}
}
GL.GetProgram(Handle, GetProgramParameterName.LinkStatus, out int status);
_api.GetProgram(Handle, ProgramPropertyARB.LinkStatus, out int status);
DeleteShaders();
if (status == 0)
{
_status = ProgramLinkStatus.Failure;
string log = GL.GetProgramInfoLog(Handle);
string log = _api.GetProgramInfoLog(Handle);
if (log.Length > MaxShaderLogLength)
{
@ -137,11 +140,11 @@ namespace Ryujinx.Graphics.OpenGL
public byte[] GetBinary()
{
GL.GetProgram(Handle, (GetProgramParameterName)All.ProgramBinaryLength, out int size);
_api.GetProgram(Handle, ProgramPropertyARB.ProgramBinaryLength, out int size);
byte[] data = new byte[size + 4];
GL.GetProgramBinary(Handle, size, out _, out BinaryFormat binFormat, data);
_api.GetProgramBinary(Handle, size, out _, out ShaderBinaryFormat binFormat, data);
BinaryPrimitives.WriteInt32LittleEndian(data.AsSpan(size, 4), (int)binFormat);
@ -152,10 +155,10 @@ namespace Ryujinx.Graphics.OpenGL
{
if (_shaderHandles != null)
{
foreach (int shaderHandle in _shaderHandles)
foreach (uint shaderHandle in _shaderHandles)
{
GL.DetachShader(Handle, shaderHandle);
GL.DeleteShader(shaderHandle);
_api.DetachShader(Handle, shaderHandle);
_api.DeleteShader(shaderHandle);
}
_shaderHandles = null;
@ -167,7 +170,7 @@ namespace Ryujinx.Graphics.OpenGL
if (Handle != 0)
{
DeleteShaders();
GL.DeleteProgram(Handle);
_api.DeleteProgram(Handle);
Handle = 0;
}

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Common.Logging;
using System;
using System.Runtime.InteropServices;

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Graphics.GAL;
using System;
using System.Collections.Generic;

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Graphics.GAL;
using System;
using System.Threading;

View file

@ -1,5 +1,5 @@
using Ryujinx.Graphics.GAL;
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using System;
namespace Ryujinx.Graphics.OpenGL.Queries

View file

@ -6,8 +6,9 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Silk.NET.OpenGL" />
<PackageReference Include="Silk.NET.OpenGL.Legacy" />
<PackageReference Include="Silk.NET.OpenGL.Legacy.Extensions.EXT" />
<PackageReference Include="Silk.NET.OpenGL.Legacy.Extensions.NV" />
</ItemGroup>
<ItemGroup>

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Common.Logging;
using System;
using System.Collections.Generic;
@ -15,23 +15,29 @@ namespace Ryujinx.Graphics.OpenGL
}
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 GL _api;
public Sync(GL api)
{
_api = api;
}
public void Create(ulong id)
{
SyncHandle handle = new()
{
ID = id,
Handle = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None),
Handle = _api.FenceSync(SyncCondition.SyncGpuCommandsComplete, SyncBehaviorFlags.None),
};
if (HwCapabilities.RequiresSyncFlush)
{
// Force commands to flush up to the syncpoint.
GL.ClientWaitSync(handle.Handle, ClientWaitSyncFlags.SyncFlushCommandsBit, 0);
_api.ClientWaitSync(handle.Handle, SyncBehaviorFlags.SyncFlushCommandsBit, 0);
}
lock (_handles)
@ -57,9 +63,9 @@ namespace Ryujinx.Graphics.OpenGL
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;
}
@ -101,9 +107,9 @@ namespace Ryujinx.Graphics.OpenGL
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...");
}
@ -128,9 +134,9 @@ namespace Ryujinx.Graphics.OpenGL
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.
lock (_handles)
@ -139,7 +145,7 @@ namespace Ryujinx.Graphics.OpenGL
{
_firstHandle = first.ID + 1;
_handles.RemoveAt(0);
GL.DeleteSync(first.Handle);
_api.DeleteSync(first.Handle);
first.Handle = IntPtr.Zero;
}
}
@ -160,7 +166,7 @@ namespace Ryujinx.Graphics.OpenGL
{
lock (handle)
{
GL.DeleteSync(handle.Handle);
_api.DeleteSync(handle.Handle);
handle.Handle = IntPtr.Zero;
}
}

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Graphics.GAL;
using System;
using System.Numerics;

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.OpenGL.Effects;
using Ryujinx.Graphics.OpenGL.Effects.Smaa;
@ -9,14 +9,14 @@ namespace Ryujinx.Graphics.OpenGL
{
class Window : IWindow, IDisposable
{
private readonly OpenGLRenderer _renderer;
private readonly OpenGLRenderer _gd;
private bool _initialized;
private int _width;
private int _height;
private bool _updateSize;
private int _copyFramebufferHandle;
private uint _copyFramebufferHandle;
private IPostProcessingEffect _antiAliasing;
private IScalingFilter _scalingFilter;
private bool _isLinear;
@ -32,26 +32,26 @@ namespace Ryujinx.Graphics.OpenGL
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)
{
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);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle);
_gd.Api.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle);
_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.
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
_gd.Api.PixelStore(PixelStoreParameter.UnpackAlignment, 4);
}
public void ChangeVSyncMode(bool vsyncEnabled) { }
@ -64,12 +64,12 @@ namespace Ryujinx.Graphics.OpenGL
_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);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer);
_gd.Api.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer);
_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();
@ -81,7 +81,7 @@ namespace Ryujinx.Graphics.OpenGL
if (viewConverted.Format.IsBgr())
{
var swappedView = _renderer.TextureCopy.BgraSwap(viewConverted);
var swappedView = _gd.TextureCopy.BgraSwap(viewConverted);
viewConverted?.Dispose();
@ -94,21 +94,21 @@ namespace Ryujinx.Graphics.OpenGL
}
}
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer);
_gd.Api.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFramebuffer);
_gd.Api.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFramebuffer);
GL.FramebufferTexture(
_gd.Api.FramebufferTexture(
FramebufferTarget.ReadFramebuffer,
FramebufferAttachment.ColorAttachment0,
viewConverted.Handle,
0);
GL.ReadBuffer(ReadBufferMode.ColorAttachment0);
_gd.Api.ReadBuffer(ReadBufferMode.ColorAttachment0);
GL.Disable(EnableCap.RasterizerDiscard);
GL.Disable(IndexedEnableCap.ScissorTest, 0);
_gd.Api.Disable(EnableCap.RasterizerDiscard);
_gd.Api.Disable(EnableCap.ScissorTest, 0);
GL.Clear(ClearBufferMask.ColorBufferBit);
_gd.Api.Clear(ClearBufferMask.ColorBufferBit);
int srcX0, srcX1, srcY0, srcY1;
@ -151,7 +151,7 @@ namespace Ryujinx.Graphics.OpenGL
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;
}
@ -185,14 +185,14 @@ namespace Ryujinx.Graphics.OpenGL
srcX1 = dstX1;
srcY1 = dstY1;
GL.FramebufferTexture(
_gd.Api.FramebufferTexture(
FramebufferTarget.ReadFramebuffer,
FramebufferAttachment.ColorAttachment0,
_upscaledTexture.Handle,
0);
}
GL.BlitFramebuffer(
_gd.Api.BlitFramebuffer(
srcX0,
srcY0,
srcX1,
@ -205,26 +205,26 @@ namespace Ryujinx.Graphics.OpenGL
_isLinear ? BlitFramebufferFilter.Linear : BlitFramebufferFilter.Nearest);
// Remove Alpha channel
GL.ColorMask(false, false, false, true);
GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GL.Clear(ClearBufferMask.ColorBufferBit);
_gd.Api.ColorMask(false, false, false, true);
_gd.Api.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
_gd.Api.Clear(ClearBufferMask.ColorBufferBit);
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.
GL.ClipControl(ClipOrigin.LowerLeft, ClipDepthMode.NegativeOneToOne);
GL.Viewport(0, 0, _width, _height);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, drawFramebuffer);
_gd.Api.ClipControl(ClipControlOrigin.LowerLeft, ClipControlDepth.NegativeOneToOne);
_gd.Api.Viewport(0, 0, (uint)_width, (uint)_height);
_gd.Api.BindFramebuffer(FramebufferTarget.Framebuffer, drawFramebuffer);
swapBuffersCallback();
((Pipeline)_renderer.Pipeline).RestoreClipControl();
((Pipeline)_renderer.Pipeline).RestoreScissor0Enable();
((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard();
((Pipeline)_renderer.Pipeline).RestoreViewport0();
((Pipeline)_gd.Pipeline).RestoreClipControl();
((Pipeline)_gd.Pipeline).RestoreScissor0Enable();
((Pipeline)_gd.Pipeline).RestoreRasterizerDiscard();
((Pipeline)_gd.Pipeline).RestoreViewport0();
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)
{
handle = GL.GenFramebuffer();
handle = _gd.Api.GenFramebuffer();
_copyFramebufferHandle = handle;
}
@ -252,14 +252,14 @@ namespace Ryujinx.Graphics.OpenGL
_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];
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()
@ -273,7 +273,7 @@ namespace Ryujinx.Graphics.OpenGL
if (_copyFramebufferHandle != 0)
{
GL.DeleteFramebuffer(_copyFramebufferHandle);
_gd.Api.DeleteFramebuffer(_copyFramebufferHandle);
_copyFramebufferHandle = 0;
}
@ -319,7 +319,7 @@ namespace Ryujinx.Graphics.OpenGL
{
case AntiAliasing.Fxaa:
_antiAliasing?.Dispose();
_antiAliasing = new FxaaPostProcessingEffect(_renderer);
_antiAliasing = new FxaaPostProcessingEffect(_gd);
break;
case AntiAliasing.None:
_antiAliasing?.Dispose();
@ -337,7 +337,7 @@ namespace Ryujinx.Graphics.OpenGL
else
{
_antiAliasing?.Dispose();
_antiAliasing = new SmaaPostProcessingEffect(_renderer, quality);
_antiAliasing = new SmaaPostProcessingEffect(_gd, quality);
}
break;
}
@ -368,7 +368,7 @@ namespace Ryujinx.Graphics.OpenGL
if (_scalingFilter is not FsrScalingFilter)
{
_scalingFilter?.Dispose();
_scalingFilter = new FsrScalingFilter(_renderer);
_scalingFilter = new FsrScalingFilter(_gd);
}
_isLinear = false;
_scalingFilter.Level = _scalingFilterLevel;
@ -401,7 +401,7 @@ namespace Ryujinx.Graphics.OpenGL
SwizzleComponent.Alpha);
_isBgra = forceBgra;
_upscaledTexture = _renderer.CreateTexture(info) as TextureView;
_upscaledTexture = _gd.CreateTexture(info) as TextureView;
}
public void SetScalingFilterLevel(float level)

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Input.HLE;

View file

@ -1,4 +1,4 @@
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Graphics.OpenGL;
using SPB.Graphics;
using SPB.Graphics.OpenGL;

View file

@ -1,5 +1,5 @@
using OpenTK;
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.OpenGL;