Slowly but surely

This commit is contained in:
Isaac Marovitz 2024-05-08 22:36:19 -04:00
parent c1c0ccbaf5
commit 0d72c7650a
No known key found for this signature in database
GPG key ID: 97250B2B09A132E1
16 changed files with 253 additions and 237 deletions

View file

@ -6,9 +6,9 @@ namespace Ryujinx.Graphics.OpenGL
{ {
static class Buffer static class Buffer
{ {
public static void Clear(BufferHandle destination, int offset, int size, uint value) public static void Clear(GL api, BufferHandle destination, int offset, uint size, uint value)
{ {
GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, destination.ToInt32()); api.BindBuffer(BufferTargetARB.CopyWriteBuffer, destination.ToUInt32());
unsafe unsafe
{ {
@ -16,60 +16,60 @@ namespace Ryujinx.Graphics.OpenGL
valueArr[0] = value; valueArr[0] = value;
GL.ClearBufferSubData( api.ClearBufferSubData(
BufferTargetARB.CopyWriteBuffer, BufferTargetARB.CopyWriteBuffer,
InternalFormat.Rgba8ui, SizedInternalFormat.Rgba8ui,
(IntPtr)offset, offset,
(IntPtr)size, size,
PixelFormat.RgbaInteger, PixelFormat.RgbaInteger,
PixelType.UnsignedByte, PixelType.UnsignedByte,
(IntPtr)valueArr); (IntPtr)valueArr);
} }
} }
public static BufferHandle Create() public static BufferHandle Create(GL api)
{ {
return Handle.FromInt32<BufferHandle>(GL.GenBuffer()); return Handle.FromUInt32<BufferHandle>(api.GenBuffer());
} }
public static BufferHandle Create(int size) public static BufferHandle Create(GL api, int size)
{ {
int handle = GL.GenBuffer(); uint handle = api.GenBuffer();
GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle); api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle);
GL.BufferData(BufferTargetARB.CopyWriteBuffer, size, IntPtr.Zero, BufferUsageARB.DynamicDraw); api.BufferData(BufferTargetARB.CopyWriteBuffer, (uint)size, UIntPtr.Zero, BufferUsageARB.DynamicDraw);
return Handle.FromInt32<BufferHandle>(handle); return Handle.FromUInt32<BufferHandle>(handle);
} }
public static BufferHandle CreatePersistent(int size) public static BufferHandle CreatePersistent(GL api, int size)
{ {
int handle = GL.GenBuffer(); uint handle = api.GenBuffer();
GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle); api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle);
GL.BufferStorage(BufferTargetARB.CopyWriteBuffer, size, IntPtr.Zero, api.BufferStorage(BufferStorageTarget.CopyWriteBuffer, (uint)size, UIntPtr.Zero,
BufferStorageMask.MapPersistentBit | BufferStorageMask.MapPersistentBit |
BufferStorageMask.MapCoherentBit | BufferStorageMask.MapCoherentBit |
BufferStorageMask.ClientStorageBit | BufferStorageMask.ClientStorageBit |
BufferStorageMask.MapReadBit); BufferStorageMask.MapReadBit);
return Handle.FromInt32<BufferHandle>(handle); return Handle.FromUInt32<BufferHandle>(handle);
} }
public static void Copy(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size) public static void Copy(GL api, BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
{ {
GL.BindBuffer(BufferTargetARB.CopyReadBuffer, source.ToInt32()); api.BindBuffer(BufferTargetARB.CopyReadBuffer, source.ToUInt32());
GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, destination.ToInt32()); api.BindBuffer(BufferTargetARB.CopyWriteBuffer, destination.ToUInt32());
GL.CopyBufferSubData( api.CopyBufferSubData(
BufferTargetARB.CopyReadBuffer, CopyBufferSubDataTarget.CopyReadBuffer,
BufferTargetARB.CopyWriteBuffer, CopyBufferSubDataTarget.CopyWriteBuffer,
(IntPtr)srcOffset, srcOffset,
(IntPtr)dstOffset, dstOffset,
(IntPtr)size); (uint)size);
} }
public static unsafe PinnedSpan<byte> GetData(OpenGLRenderer renderer, BufferHandle buffer, int offset, int size) public static unsafe PinnedSpan<byte> GetData(GL api, OpenGLRenderer renderer, BufferHandle buffer, int offset, int size)
{ {
// Data in the persistent buffer and host array is guaranteed to be available // Data in the persistent buffer and host array is guaranteed to be available
// until the next time the host thread requests data. // until the next time the host thread requests data.
@ -86,36 +86,36 @@ namespace Ryujinx.Graphics.OpenGL
{ {
IntPtr target = renderer.PersistentBuffers.Default.GetHostArray(size); IntPtr target = renderer.PersistentBuffers.Default.GetHostArray(size);
GL.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToInt32()); api.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32());
GL.GetBufferSubData(BufferTargetARB.CopyReadBuffer, (IntPtr)offset, size, target); api.GetBufferSubData(BufferTargetARB.CopyReadBuffer, offset, (uint)size, target);
return new PinnedSpan<byte>(target.ToPointer(), size); return new PinnedSpan<byte>(target.ToPointer(), size);
} }
} }
public static void Resize(BufferHandle handle, int size) public static void Resize(GL api, BufferHandle handle, int size)
{ {
GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToInt32()); api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32());
GL.BufferData(BufferTargetARB.CopyWriteBuffer, size, IntPtr.Zero, BufferUsageARB.StreamCopy); api.BufferData(BufferTargetARB.CopyWriteBuffer, (uint)size, UIntPtr.Zero, BufferUsageARB.StreamCopy);
} }
public static void SetData(BufferHandle buffer, int offset, ReadOnlySpan<byte> data) public static void SetData(GL api, BufferHandle buffer, int offset, ReadOnlySpan<byte> data)
{ {
GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, buffer.ToInt32()); api.BindBuffer(BufferTargetARB.CopyWriteBuffer, buffer.ToUInt32());
unsafe unsafe
{ {
fixed (byte* ptr = data) fixed (byte* ptr = data)
{ {
GL.BufferSubData(BufferTargetARB.CopyWriteBuffer, (IntPtr)offset, data.Length, (IntPtr)ptr); api.BufferSubData(BufferTargetARB.CopyWriteBuffer, offset, (uint)data.Length, (IntPtr)ptr);
} }
} }
} }
public static void Delete(BufferHandle buffer) public static void Delete(GL api, BufferHandle buffer)
{ {
GL.DeleteBuffer(buffer.ToInt32()); api.DeleteBuffer(buffer.ToUInt32());
} }
} }
} }

View file

@ -13,48 +13,48 @@ namespace Ryujinx.Graphics.OpenGL
private static int _counter; private static int _counter;
public static void Initialize(GraphicsDebugLevel logLevel) public static void Initialize(GL gl, GraphicsDebugLevel logLevel)
{ {
// Disable everything // Disable everything
GL.DebugMessageControl(DebugSource.DontCare, DebugType.DontCare, DebugSeverity.DontCare, 0, (int[])null, false); gl.DebugMessageControl(DebugSource.DontCare, DebugType.DontCare, DebugSeverity.DontCare, 0, (int[])null, false);
if (logLevel == GraphicsDebugLevel.None) if (logLevel == GraphicsDebugLevel.None)
{ {
GL.Disable(EnableCap.DebugOutputSynchronous); gl.Disable(EnableCap.DebugOutputSynchronous);
GL.DebugMessageCallback(null, IntPtr.Zero); gl.DebugMessageCallback(null, IntPtr.Zero);
return; return;
} }
GL.Enable(EnableCap.DebugOutputSynchronous); gl.Enable(EnableCap.DebugOutputSynchronous);
if (logLevel == GraphicsDebugLevel.Error) if (logLevel == GraphicsDebugLevel.Error)
{ {
GL.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypeError, DebugSeverity.DontCare, 0, (int[])null, true); gl.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypeError, DebugSeverity.DontCare, 0, (int[])null, true);
} }
else if (logLevel == GraphicsDebugLevel.Slowdowns) else if (logLevel == GraphicsDebugLevel.Slowdowns)
{ {
GL.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypeError, DebugSeverity.DontCare, 0, (int[])null, true); gl.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypeError, DebugSeverity.DontCare, 0, (int[])null, true);
GL.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypePerformance, DebugSeverity.DontCare, 0, (int[])null, true); gl.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypePerformance, DebugSeverity.DontCare, 0, (int[])null, true);
} }
else else
{ {
GL.DebugMessageControl(DebugSource.DontCare, DebugType.DontCare, DebugSeverity.DontCare, 0, (int[])null, true); gl.DebugMessageControl(DebugSource.DontCare, DebugType.DontCare, DebugSeverity.DontCare, 0, (int[])null, true);
} }
_counter = 0; _counter = 0;
_debugCallback = GLDebugHandler; _debugCallback = GLDebugHandler;
GL.DebugMessageCallback(_debugCallback, IntPtr.Zero); gl.DebugMessageCallback(_debugCallback, IntPtr.Zero);
Logger.Warning?.Print(LogClass.Gpu, "OpenGL Debugging is enabled. Performance will be negatively impacted."); Logger.Warning?.Print(LogClass.Gpu, "OpenGL Debugging is enabled. Performance will be negatively impacted.");
} }
private static void GLDebugHandler( private static void GLDebugHandler(
DebugSource source, GLEnum source,
DebugType type, GLEnum type,
int id, int id,
DebugSeverity severity, GLEnum severity,
int length, int length,
IntPtr message, IntPtr message,
IntPtr userParam) IntPtr userParam)
@ -89,21 +89,21 @@ namespace Ryujinx.Graphics.OpenGL
} }
// Useful debug helpers // Useful debug helpers
public static void PushGroup(string dbgMsg) public static void PushGroup(GL gl, string dbgMsg)
{ {
int counter = Interlocked.Increment(ref _counter); int counter = Interlocked.Increment(ref _counter);
GL.PushDebugGroup(DebugSource.DebugSourceApplication, counter, dbgMsg.Length, dbgMsg); gl.PushDebugGroup(DebugSource.DebugSourceApplication, counter, dbgMsg.Length, dbgMsg);
} }
public static void PopGroup() public static void PopGroup(GL gl)
{ {
GL.PopDebugGroup(); gl.PopDebugGroup();
} }
public static void Print(string dbgMsg, DebugType type = DebugType.DebugTypeMarker, DebugSeverity severity = DebugSeverity.DebugSeverityNotification, int id = 999999) public static void Print(GL gl, string dbgMsg, DebugType type = DebugType.DebugTypeMarker, DebugSeverity severity = DebugSeverity.DebugSeverityNotification, int id = 999999)
{ {
GL.DebugMessageInsert(DebugSource.DebugSourceApplication, type, id, severity, dbgMsg.Length, dbgMsg); gl.DebugMessageInsert(DebugSource.DebugSourceApplication, type, id, severity, dbgMsg.Length, dbgMsg);
} }
} }
} }

View file

@ -35,9 +35,9 @@ void main()
colour = texture(tex, texcoord); colour = texture(tex, texcoord);
}"; }";
private int _vsHandle; private uint _vsHandle;
private int _fsHandle; private uint _fsHandle;
private int _programHandle; private uint _programHandle;
private int _uniformSrcX0Location; private int _uniformSrcX0Location;
private int _uniformSrcY0Location; private int _uniformSrcY0Location;
private int _uniformSrcX1Location; private int _uniformSrcX1Location;
@ -45,6 +45,7 @@ void main()
private bool _initialized; private bool _initialized;
public void Draw( public void Draw(
GL api,
TextureView texture, TextureView texture,
Sampler sampler, Sampler sampler,
float x0, float x0,
@ -56,9 +57,9 @@ void main()
float s1, float s1,
float t1) float t1)
{ {
EnsureInitialized(); EnsureInitialized(api);
GL.UseProgram(_programHandle); api.UseProgram(_programHandle);
texture.Bind(0); texture.Bind(0);
sampler.Bind(0); sampler.Bind(0);
@ -73,17 +74,17 @@ void main()
(t1, t0) = (t0, t1); (t1, t0) = (t0, t1);
} }
GL.Uniform1(_uniformSrcX0Location, s0); api.Uniform1(_uniformSrcX0Location, s0);
GL.Uniform1(_uniformSrcY0Location, t0); api.Uniform1(_uniformSrcY0Location, t0);
GL.Uniform1(_uniformSrcX1Location, s1); api.Uniform1(_uniformSrcX1Location, s1);
GL.Uniform1(_uniformSrcY1Location, t1); api.Uniform1(_uniformSrcY1Location, t1);
GL.ViewportIndexed(0, MathF.Min(x0, x1), MathF.Min(y0, y1), MathF.Abs(x1 - x0), MathF.Abs(y1 - y0)); api.ViewportIndexed(0, MathF.Min(x0, x1), MathF.Min(y0, y1), MathF.Abs(x1 - x0), MathF.Abs(y1 - y0));
GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4); api.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
} }
private void EnsureInitialized() private void EnsureInitialized(GL api)
{ {
if (_initialized) if (_initialized)
{ {
@ -92,41 +93,41 @@ void main()
_initialized = true; _initialized = true;
_vsHandle = GL.CreateShader(ShaderType.VertexShader); _vsHandle = api.CreateShader(ShaderType.VertexShader);
_fsHandle = GL.CreateShader(ShaderType.FragmentShader); _fsHandle = api.CreateShader(ShaderType.FragmentShader);
GL.ShaderSource(_vsHandle, VertexShader); api.ShaderSource(_vsHandle, VertexShader);
GL.ShaderSource(_fsHandle, FragmentShader); api.ShaderSource(_fsHandle, FragmentShader);
GL.CompileShader(_vsHandle); api.CompileShader(_vsHandle);
GL.CompileShader(_fsHandle); api.CompileShader(_fsHandle);
_programHandle = GL.CreateProgram(); _programHandle = api.CreateProgram();
GL.AttachShader(_programHandle, _vsHandle); api.AttachShader(_programHandle, _vsHandle);
GL.AttachShader(_programHandle, _fsHandle); api.AttachShader(_programHandle, _fsHandle);
GL.LinkProgram(_programHandle); api.LinkProgram(_programHandle);
GL.DetachShader(_programHandle, _vsHandle); api.DetachShader(_programHandle, _vsHandle);
GL.DetachShader(_programHandle, _fsHandle); api.DetachShader(_programHandle, _fsHandle);
_uniformSrcX0Location = GL.GetUniformLocation(_programHandle, "srcX0"); _uniformSrcX0Location = api.GetUniformLocation(_programHandle, "srcX0");
_uniformSrcY0Location = GL.GetUniformLocation(_programHandle, "srcY0"); _uniformSrcY0Location = api.GetUniformLocation(_programHandle, "srcY0");
_uniformSrcX1Location = GL.GetUniformLocation(_programHandle, "srcX1"); _uniformSrcX1Location = api.GetUniformLocation(_programHandle, "srcX1");
_uniformSrcY1Location = GL.GetUniformLocation(_programHandle, "srcY1"); _uniformSrcY1Location = api.GetUniformLocation(_programHandle, "srcY1");
} }
public void Dispose() public void Dispose(GL api)
{ {
if (!_initialized) if (!_initialized)
{ {
return; return;
} }
GL.DeleteShader(_vsHandle); api.DeleteShader(_vsHandle);
GL.DeleteShader(_fsHandle); api.DeleteShader(_fsHandle);
GL.DeleteProgram(_programHandle); api.DeleteProgram(_programHandle);
_initialized = false; _initialized = false;
} }

View file

@ -552,9 +552,9 @@ namespace Ryujinx.Graphics.OpenGL
return All.Zero; return All.Zero;
} }
public static ImageTarget ConvertToImageTarget(this Target target) public static CopyImageSubDataTarget ConvertToImageTarget(this Target target)
{ {
return (ImageTarget)target.Convert(); return (CopyImageSubDataTarget)target.Convert();
} }
public static TextureTarget Convert(this Target target) public static TextureTarget Convert(this Target target)

View file

@ -8,8 +8,8 @@ namespace Ryujinx.Graphics.OpenGL
{ {
class Framebuffer : IDisposable class Framebuffer : IDisposable
{ {
public int Handle { get; private set; } public uint Handle { get; private set; }
private int _clearFbHandle; private uint _clearFbHandle;
private bool _clearFbInitialized; private bool _clearFbInitialized;
private FramebufferAttachment _lastDsAttachment; private FramebufferAttachment _lastDsAttachment;
@ -19,18 +19,20 @@ namespace Ryujinx.Graphics.OpenGL
private int _colorsCount; private int _colorsCount;
private bool _dualSourceBlend; private bool _dualSourceBlend;
private GL _api;
public Framebuffer() public Framebuffer(GL api)
{ {
Handle = GL.GenFramebuffer(); Handle = GL.GenFramebuffer();
_clearFbHandle = GL.GenFramebuffer(); _clearFbHandle = GL.GenFramebuffer();
_colors = new TextureView[8]; _colors = new TextureView[8];
_api = api;
} }
public int Bind() public int Bind()
{ {
GL.BindFramebuffer(FramebufferTarget.Framebuffer, Handle); _api.BindFramebuffer(FramebufferTarget.Framebuffer, Handle);
return Handle; return Handle;
} }
@ -44,7 +46,7 @@ namespace Ryujinx.Graphics.OpenGL
FramebufferAttachment attachment = FramebufferAttachment.ColorAttachment0 + index; FramebufferAttachment attachment = FramebufferAttachment.ColorAttachment0 + index;
GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.Handle ?? 0, 0); _api.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.Handle ?? 0, 0);
_colors[index] = color; _colors[index] = color;
} }
@ -54,14 +56,14 @@ namespace Ryujinx.Graphics.OpenGL
// Detach the last depth/stencil buffer if there is any. // Detach the last depth/stencil buffer if there is any.
if (_lastDsAttachment != 0) if (_lastDsAttachment != 0)
{ {
GL.FramebufferTexture(FramebufferTarget.Framebuffer, _lastDsAttachment, 0, 0); _api.FramebufferTexture(FramebufferTarget.Framebuffer, _lastDsAttachment, 0, 0);
} }
if (depthStencil != null) if (depthStencil != null)
{ {
FramebufferAttachment attachment = GetAttachment(depthStencil.Format); FramebufferAttachment attachment = GetAttachment(depthStencil.Format);
GL.FramebufferTexture( _api.FramebufferTexture(
FramebufferTarget.Framebuffer, FramebufferTarget.Framebuffer,
attachment, attachment,
depthStencil.Handle, depthStencil.Handle,
@ -87,11 +89,11 @@ namespace Ryujinx.Graphics.OpenGL
// we can only have one draw buffer. // we can only have one draw buffer.
if (enable) if (enable)
{ {
GL.DrawBuffer(DrawBufferMode.ColorAttachment0); _api.DrawBuffer(DrawBufferMode.ColorAttachment0);
} }
else if (oldEnable) else if (oldEnable)
{ {
SetDrawBuffersImpl(_colorsCount); SetDrawBuffersImpl(_api, _colorsCount);
} }
} }
@ -99,13 +101,13 @@ namespace Ryujinx.Graphics.OpenGL
{ {
if (_colorsCount != colorsCount && !_dualSourceBlend) if (_colorsCount != colorsCount && !_dualSourceBlend)
{ {
SetDrawBuffersImpl(colorsCount); SetDrawBuffersImpl(_api, colorsCount);
} }
_colorsCount = colorsCount; _colorsCount = colorsCount;
} }
private static void SetDrawBuffersImpl(int colorsCount) private static void SetDrawBuffersImpl(GL api, int colorsCount)
{ {
DrawBufferMode[] drawBuffers = new DrawBufferMode[colorsCount]; DrawBufferMode[] drawBuffers = new DrawBufferMode[colorsCount];
@ -114,7 +116,7 @@ namespace Ryujinx.Graphics.OpenGL
drawBuffers[index] = DrawBufferMode.ColorAttachment0 + index; drawBuffers[index] = DrawBufferMode.ColorAttachment0 + index;
} }
GL.DrawBuffers(colorsCount, drawBuffers); api.DrawBuffers(colorsCount, drawBuffers);
} }
private static FramebufferAttachment GetAttachment(Format format) private static FramebufferAttachment GetAttachment(Format format)
@ -153,7 +155,7 @@ namespace Ryujinx.Graphics.OpenGL
} }
BindClearFb(); BindClearFb();
GL.FramebufferTextureLayer(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + index, color.Handle, 0, layer); _api.FramebufferTextureLayer(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + index, color.Handle, 0, layer);
} }
public void DetachColorLayerForClear(int index) public void DetachColorLayerForClear(int index)
@ -165,7 +167,7 @@ namespace Ryujinx.Graphics.OpenGL
return; return;
} }
GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + index, 0, 0); _api.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + index, 0, 0);
Bind(); Bind();
} }
@ -179,7 +181,7 @@ namespace Ryujinx.Graphics.OpenGL
} }
BindClearFb(); BindClearFb();
GL.FramebufferTextureLayer(FramebufferTarget.Framebuffer, GetAttachment(depthStencil.Format), depthStencil.Handle, 0, layer); _api.FramebufferTextureLayer(FramebufferTarget.Framebuffer, GetAttachment(depthStencil.Format), depthStencil.Handle, 0, layer);
} }
public void DetachDepthStencilLayerForClear() public void DetachDepthStencilLayerForClear()
@ -191,13 +193,13 @@ namespace Ryujinx.Graphics.OpenGL
return; return;
} }
GL.FramebufferTexture(FramebufferTarget.Framebuffer, GetAttachment(depthStencil.Format), 0, 0); _api.FramebufferTexture(FramebufferTarget.Framebuffer, GetAttachment(depthStencil.Format), 0, 0);
Bind(); Bind();
} }
private void BindClearFb() private void BindClearFb()
{ {
GL.BindFramebuffer(FramebufferTarget.Framebuffer, _clearFbHandle); _api.BindFramebuffer(FramebufferTarget.Framebuffer, _clearFbHandle);
if (!_clearFbInitialized) if (!_clearFbInitialized)
{ {
@ -219,14 +221,14 @@ namespace Ryujinx.Graphics.OpenGL
{ {
if (Handle != 0) if (Handle != 0)
{ {
GL.DeleteFramebuffer(Handle); _api.DeleteFramebuffer(Handle);
Handle = 0; Handle = 0;
} }
if (_clearFbHandle != 0) if (_clearFbHandle != 0)
{ {
GL.DeleteFramebuffer(_clearFbHandle); _api.DeleteFramebuffer(_clearFbHandle);
_clearFbHandle = 0; _clearFbHandle = 0;
} }

View file

@ -6,18 +6,18 @@ namespace Ryujinx.Graphics.OpenGL
{ {
static class Handle static class Handle
{ {
public static T FromInt32<T>(int handle) where T : unmanaged public static T FromUInt32<T>(uint handle) where T : unmanaged
{ {
Debug.Assert(Unsafe.SizeOf<T>() == sizeof(ulong)); Debug.Assert(Unsafe.SizeOf<T>() == sizeof(ulong));
ulong handle64 = (uint)handle; ulong handle64 = handle;
return Unsafe.As<ulong, T>(ref handle64); return Unsafe.As<ulong, T>(ref handle64);
} }
public static int ToInt32(this BufferHandle handle) public static uint ToUInt32(this BufferHandle handle)
{ {
return (int)Unsafe.As<BufferHandle, ulong>(ref handle); return (uint)Unsafe.As<BufferHandle, ulong>(ref handle);
} }
} }
} }

View file

@ -131,13 +131,13 @@ namespace Ryujinx.Graphics.OpenGL
} }
} }
private static bool SupportsQuadsCheck() private static bool SupportsQuadsCheck(GL api)
{ {
GL.GetError(); // Clear any existing error. api.GetError(); // Clear any existing error.
GL.Begin(PrimitiveType.Quads); api.Begin(PrimitiveType.Quads);
GL.End(); api.End();
return GL.GetError() == ErrorCode.NoError; return api.GetError() == ErrorCode.NoError;
} }
} }
} }

View file

@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
interface ITextureInfo interface ITextureInfo
{ {
ITextureInfo Storage { get; } ITextureInfo Storage { get; }
int Handle { get; } uint Handle { get; }
int FirstLayer => 0; int FirstLayer => 0;
int FirstLevel => 0; int FirstLevel => 0;

View file

@ -7,18 +7,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
private record struct TextureRef private record struct TextureRef
{ {
public int Handle; public uint Handle;
public Format Format; public Format Format;
} }
private readonly TextureRef[] _images; private readonly TextureRef[] _images;
private GL _api;
public ImageArray(int size) public ImageArray(GL api, int size)
{ {
_api = api;
_images = new TextureRef[size]; _images = new TextureRef[size];
} }
public void SetFormats(int index, GAL.Format[] imageFormats) public void SetFormats(int index, Format[] imageFormats)
{ {
for (int i = 0; i < imageFormats.Length; i++) for (int i = 0; i < imageFormats.Length; i++)
{ {
@ -43,21 +45,21 @@ namespace Ryujinx.Graphics.OpenGL.Image
} }
} }
public void Bind(int baseBinding) public void Bind(uint baseBinding)
{ {
for (int i = 0; i < _images.Length; i++) for (int i = 0; i < _images.Length; i++)
{ {
if (_images[i].Handle == 0) if (_images[i].Handle == 0)
{ {
GL.BindImageTexture(baseBinding + i, 0, 0, true, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8); _api.BindImageTexture((uint)(baseBinding + i), 0, 0, true, 0, BufferAccessARB.ReadWrite, InternalFormat.Rgba8);
} }
else else
{ {
SizedInternalFormat format = FormatTable.GetImageFormat(_images[i].Format); InternalFormat format = (InternalFormat)FormatTable.GetImageFormat(_images[i].Format);
if (format != 0) if (format != 0)
{ {
GL.BindImageTexture(baseBinding + i, _images[i].Handle, 0, true, 0, BufferAccessARB.ReadWrite, format); _api.BindImageTexture((uint)(baseBinding + i), _images[i].Handle, 0, true, 0, BufferAccessARB.ReadWrite, format);
} }
} }
} }

View file

@ -5,26 +5,28 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
class Sampler : ISampler class Sampler : ISampler
{ {
public int Handle { get; private set; } public uint Handle { get; private set; }
private GL _api;
public Sampler(SamplerCreateInfo info) public Sampler(GL api, SamplerCreateInfo info)
{ {
Handle = GL.GenSampler(); _api = api;
Handle = _api.GenSampler();
GL.SamplerParameter(Handle, SamplerParameterI.MinFilter, (int)info.MinFilter.Convert()); _api.SamplerParameter(Handle, SamplerParameterI.MinFilter, (int)info.MinFilter.Convert());
GL.SamplerParameter(Handle, SamplerParameterI.MagFilter, (int)info.MagFilter.Convert()); _api.SamplerParameter(Handle, SamplerParameterI.MagFilter, (int)info.MagFilter.Convert());
if (HwCapabilities.SupportsSeamlessCubemapPerTexture) if (HwCapabilities.SupportsSeamlessCubemapPerTexture)
{ {
GL.SamplerParameter(Handle, (SamplerParameterName)ArbSeamlessCubemapPerTexture.TextureCubeMapSeamless, info.SeamlessCubemap ? 1 : 0); _api.SamplerParameter(Handle, GLEnum.TextureCubeMapSeamless, info.SeamlessCubemap ? 1 : 0);
} }
GL.SamplerParameter(Handle, SamplerParameterI.WrapS, (int)info.AddressU.Convert()); _api.SamplerParameter(Handle, SamplerParameterI.WrapS, (int)info.AddressU.Convert());
GL.SamplerParameter(Handle, SamplerParameterI.WrapT, (int)info.AddressV.Convert()); _api.SamplerParameter(Handle, SamplerParameterI.WrapT, (int)info.AddressV.Convert());
GL.SamplerParameter(Handle, SamplerParameterI.WrapR, (int)info.AddressP.Convert()); _api.SamplerParameter(Handle, SamplerParameterI.WrapR, (int)info.AddressP.Convert());
GL.SamplerParameter(Handle, SamplerParameterI.CompareMode, (int)info.CompareMode.Convert()); _api.SamplerParameter(Handle, SamplerParameterI.CompareMode, (int)info.CompareMode.Convert());
GL.SamplerParameter(Handle, SamplerParameterI.CompareFunc, (int)info.CompareOp.Convert()); _api.SamplerParameter(Handle, SamplerParameterI.CompareFunc, (int)info.CompareOp.Convert());
unsafe unsafe
{ {
@ -36,26 +38,26 @@ namespace Ryujinx.Graphics.OpenGL.Image
info.BorderColor.Alpha, info.BorderColor.Alpha,
}; };
GL.SamplerParameter(Handle, SamplerParameterF.BorderColor, borderColor); _api.SamplerParameter(Handle, SamplerParameterF.BorderColor, borderColor);
} }
GL.SamplerParameter(Handle, SamplerParameterF.TextureMinLod, info.MinLod); _api.SamplerParameter(Handle, SamplerParameterF.TextureMinLod, info.MinLod);
GL.SamplerParameter(Handle, SamplerParameterF.TextureMaxLod, info.MaxLod); _api.SamplerParameter(Handle, SamplerParameterF.TextureMaxLod, info.MaxLod);
GL.SamplerParameter(Handle, SamplerParameterF.TextureLodBias, info.MipLodBias); _api.SamplerParameter(Handle, SamplerParameterF.TextureLodBias, info.MipLodBias);
GL.SamplerParameter(Handle, SamplerParameterF.MaxAnisotropy, info.MaxAnisotropy); _api.SamplerParameter(Handle, SamplerParameterF.MaxAnisotropy, info.MaxAnisotropy);
} }
public void Bind(int unit) public void Bind(uint unit)
{ {
GL.BindSampler(unit, Handle); _api.BindSampler(unit, Handle);
} }
public void Dispose() public void Dispose()
{ {
if (Handle != 0) if (Handle != 0)
{ {
GL.DeleteSampler(Handle); _api.DeleteSampler(Handle);
Handle = 0; Handle = 0;
} }

View file

@ -1,4 +1,5 @@
using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.GAL;
using Silk.NET.OpenGL;
namespace Ryujinx.Graphics.OpenGL.Image namespace Ryujinx.Graphics.OpenGL.Image
{ {
@ -11,9 +12,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
} }
private readonly TextureRef[] _textureRefs; private readonly TextureRef[] _textureRefs;
private GL _api;
public TextureArray(int size) public TextureArray(GL api, int size)
{ {
_api = api;
_textureRefs = new TextureRef[size]; _textureRefs = new TextureRef[size];
} }
@ -33,9 +36,9 @@ namespace Ryujinx.Graphics.OpenGL.Image
} }
} }
public void Bind(int baseBinding) public void Bind(uint baseBinding)
{ {
for (int i = 0; i < _textureRefs.Length; i++) for (uint i = 0; i < _textureRefs.Length; i++)
{ {
if (_textureRefs[i].Texture != null) if (_textureRefs[i].Texture != null)
{ {
@ -44,7 +47,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
} }
else else
{ {
TextureBase.ClearBinding(baseBinding + i); TextureBase.ClearBinding(_api, baseBinding + i);
} }
} }
} }

View file

@ -5,7 +5,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
class TextureBase class TextureBase
{ {
public int Handle { get; protected set; } public uint Handle { get; protected set; }
public TextureCreateInfo Info { get; } public TextureCreateInfo Info { get; }
@ -15,28 +15,31 @@ namespace Ryujinx.Graphics.OpenGL.Image
public Target Target => Info.Target; public Target Target => Info.Target;
public Format Format => Info.Format; public Format Format => Info.Format;
public TextureBase(TextureCreateInfo info) private protected GL _api;
public TextureBase(GL api, TextureCreateInfo info)
{ {
_api = api;
Info = info; Info = info;
Handle = GL.GenTexture(); Handle = _api.GenTexture();
} }
public void Bind(int unit) public void Bind(uint unit)
{ {
Bind(Target.Convert(), unit); Bind(Target.Convert(), unit);
} }
protected void Bind(TextureTarget target, int unit) protected void Bind(TextureTarget target, uint unit)
{ {
GL.ActiveTexture(TextureUnit.Texture0 + unit); _api.ActiveTexture((TextureUnit)((uint)TextureUnit.Texture0 + unit));
GL.BindTexture(target, Handle); _api.BindTexture(target, Handle);
} }
public static void ClearBinding(int unit) public static void ClearBinding(GL api, uint unit)
{ {
GL.ActiveTexture(TextureUnit.Texture0 + unit); api.ActiveTexture((TextureUnit)((uint)TextureUnit.Texture0 + unit));
GL.BindTextureUnit(unit, 0); api.BindTextureUnit(unit, 0);
} }
} }
} }

View file

@ -14,7 +14,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
private BufferHandle _buffer; private BufferHandle _buffer;
public TextureBuffer(OpenGLRenderer renderer, TextureCreateInfo info) : base(info) public TextureBuffer(GL api, OpenGLRenderer renderer, TextureCreateInfo info) : base(api, info)
{ {
_renderer = renderer; _renderer = renderer;
} }
@ -41,7 +41,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
public PinnedSpan<byte> GetData() public PinnedSpan<byte> GetData()
{ {
return Buffer.GetData(_renderer, _buffer, _bufferOffset, _bufferSize); return Buffer.GetData(_api, _renderer, _buffer, _bufferOffset, _bufferSize);
} }
public PinnedSpan<byte> GetData(int layer, int level) public PinnedSpan<byte> GetData(int layer, int level)
@ -59,7 +59,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
{ {
var dataSpan = data.Memory.Span; var dataSpan = data.Memory.Span;
Buffer.SetData(_buffer, _bufferOffset, dataSpan[..Math.Min(dataSpan.Length, _bufferSize)]); Buffer.SetData(_api, _buffer, _bufferOffset, dataSpan[..Math.Min(dataSpan.Length, _bufferSize)]);
data.Dispose(); data.Dispose();
} }
@ -97,14 +97,14 @@ namespace Ryujinx.Graphics.OpenGL.Image
SizedInternalFormat format = (SizedInternalFormat)FormatTable.GetFormatInfo(Info.Format).InternalFormat; SizedInternalFormat format = (SizedInternalFormat)FormatTable.GetFormatInfo(Info.Format).InternalFormat;
GL.TexBufferRange(TextureTarget.TextureBuffer, format, _buffer.ToInt32(), (IntPtr)buffer.Offset, buffer.Size); _api.TexBufferRange(TextureTarget.TextureBuffer, format, _buffer.ToUInt32(), buffer.Offset, (uint)buffer.Size);
} }
public void Dispose() public void Dispose()
{ {
if (Handle != 0) if (Handle != 0)
{ {
GL.DeleteTexture(Handle); _api.DeleteTexture(Handle);
Handle = 0; Handle = 0;
} }

View file

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

View file

@ -11,6 +11,7 @@ namespace Ryujinx.Graphics.OpenGL
{ {
public sealed class OpenGLRenderer : IRenderer public sealed class OpenGLRenderer : IRenderer
{ {
private GL _api;
private readonly Pipeline _pipeline; private readonly Pipeline _pipeline;
public IPipeline Pipeline => _pipeline; public IPipeline Pipeline => _pipeline;
@ -57,13 +58,13 @@ namespace Ryujinx.Graphics.OpenGL
ResourcePool = new ResourcePool(); ResourcePool = new ResourcePool();
} }
public BufferHandle CreateBuffer(int size, GAL.BufferAccess access) public BufferHandle CreateBuffer(int size, BufferAccess access)
{ {
BufferCount++; BufferCount++;
if (access.HasFlag(GAL.BufferAccess.FlushPersistent)) if (access.HasFlag(BufferAccess.FlushPersistent))
{ {
BufferHandle handle = Buffer.CreatePersistent(size); BufferHandle handle = Buffer.CreatePersistent(_api, size);
PersistentBuffers.Map(handle, size); PersistentBuffers.Map(handle, size);
@ -71,7 +72,7 @@ namespace Ryujinx.Graphics.OpenGL
} }
else else
{ {
return Buffer.Create(size); return Buffer.Create(_api, size);
} }
} }

View file

@ -38,8 +38,8 @@ namespace Ryujinx.Graphics.OpenGL
private float[] _viewportArray = Array.Empty<float>(); private float[] _viewportArray = Array.Empty<float>();
private double[] _depthRangeArray = Array.Empty<double>(); private double[] _depthRangeArray = Array.Empty<double>();
private int _boundDrawFramebuffer; private uint _boundDrawFramebuffer;
private int _boundReadFramebuffer; private uint _boundReadFramebuffer;
private CounterQueueEvent _activeConditionalRender; private CounterQueueEvent _activeConditionalRender;
@ -1496,7 +1496,7 @@ namespace Ryujinx.Graphics.OpenGL
} }
} }
internal (int drawHandle, int readHandle) GetBoundFramebuffers() internal (uint drawHandle, uint readHandle) GetBoundFramebuffers()
{ {
if (BackgroundContextWorker.InBackground) if (BackgroundContextWorker.InBackground)
{ {