Merge 91f63270cc
into 2f427deb67
This commit is contained in:
commit
d29e9464c7
50 changed files with 2042 additions and 1891 deletions
|
@ -28,7 +28,6 @@
|
|||
<PackageVersion Include="NUnit" Version="3.13.3" />
|
||||
<PackageVersion Include="NUnit3TestAdapter" Version="4.1.0" />
|
||||
<PackageVersion Include="OpenTK.Core" Version="4.8.2" />
|
||||
<PackageVersion Include="OpenTK.Graphics" Version="4.8.2" />
|
||||
<PackageVersion Include="OpenTK.Audio.OpenAL" Version="4.8.2" />
|
||||
<PackageVersion Include="OpenTK.Windowing.GraphicsLibraryFramework" Version="4.8.2" />
|
||||
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
||||
|
@ -39,6 +38,10 @@
|
|||
<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.Legacy" Version="2.16.0" />
|
||||
<PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.ARB" Version="2.16.0" />
|
||||
<PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.EXT" Version="2.16.0" />
|
||||
<PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.NV" Version="2.16.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" />
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
{
|
||||
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(BufferTarget.CopyWriteBuffer, destination.ToInt32());
|
||||
api.BindBuffer(BufferTargetARB.CopyWriteBuffer, destination.ToUInt32());
|
||||
|
||||
unsafe
|
||||
{
|
||||
|
@ -16,106 +16,97 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
valueArr[0] = value;
|
||||
|
||||
GL.ClearBufferSubData(
|
||||
BufferTarget.CopyWriteBuffer,
|
||||
PixelInternalFormat.Rgba8ui,
|
||||
(IntPtr)offset,
|
||||
(IntPtr)size,
|
||||
api.ClearBufferSubData(
|
||||
BufferTargetARB.CopyWriteBuffer,
|
||||
SizedInternalFormat.Rgba8ui,
|
||||
offset,
|
||||
size,
|
||||
PixelFormat.RgbaInteger,
|
||||
PixelType.UnsignedByte,
|
||||
(IntPtr)valueArr);
|
||||
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 unsafe static BufferHandle Create(GL api, int size)
|
||||
{
|
||||
int handle = GL.GenBuffer();
|
||||
uint handle = api.GenBuffer();
|
||||
|
||||
GL.BindBuffer(BufferTarget.CopyWriteBuffer, handle);
|
||||
GL.BufferData(BufferTarget.CopyWriteBuffer, size, IntPtr.Zero, BufferUsageHint.DynamicDraw);
|
||||
api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle);
|
||||
api.BufferData(BufferTargetARB.CopyWriteBuffer, (uint)size, null, BufferUsageARB.DynamicDraw);
|
||||
|
||||
return Handle.FromInt32<BufferHandle>(handle);
|
||||
return Handle.FromUInt32<BufferHandle>(handle);
|
||||
}
|
||||
|
||||
public static BufferHandle CreatePersistent(int size)
|
||||
public unsafe static BufferHandle CreatePersistent(GL api, int size)
|
||||
{
|
||||
int handle = GL.GenBuffer();
|
||||
uint handle = api.GenBuffer();
|
||||
|
||||
GL.BindBuffer(BufferTarget.CopyWriteBuffer, handle);
|
||||
GL.BufferStorage(BufferTarget.CopyWriteBuffer, size, IntPtr.Zero,
|
||||
BufferStorageFlags.MapPersistentBit |
|
||||
BufferStorageFlags.MapCoherentBit |
|
||||
BufferStorageFlags.ClientStorageBit |
|
||||
BufferStorageFlags.MapReadBit);
|
||||
api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle);
|
||||
api.BufferStorage(BufferStorageTarget.CopyWriteBuffer, (uint)size, null,
|
||||
BufferStorageMask.MapPersistentBit |
|
||||
BufferStorageMask.MapCoherentBit |
|
||||
BufferStorageMask.ClientStorageBit |
|
||||
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(BufferTarget.CopyReadBuffer, source.ToInt32());
|
||||
GL.BindBuffer(BufferTarget.CopyWriteBuffer, destination.ToInt32());
|
||||
api.BindBuffer(BufferTargetARB.CopyReadBuffer, source.ToUInt32());
|
||||
api.BindBuffer(BufferTargetARB.CopyWriteBuffer, destination.ToUInt32());
|
||||
|
||||
GL.CopyBufferSubData(
|
||||
BufferTarget.CopyReadBuffer,
|
||||
BufferTarget.CopyWriteBuffer,
|
||||
(IntPtr)srcOffset,
|
||||
(IntPtr)dstOffset,
|
||||
(IntPtr)size);
|
||||
api.CopyBufferSubData(
|
||||
CopyBufferSubDataTarget.CopyReadBuffer,
|
||||
CopyBufferSubDataTarget.CopyWriteBuffer,
|
||||
srcOffset,
|
||||
dstOffset,
|
||||
(uint)size);
|
||||
}
|
||||
|
||||
public static unsafe PinnedSpan<byte> GetData(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)
|
||||
|
||||
if (gd.Capabilities.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);
|
||||
|
||||
GL.BindBuffer(BufferTarget.CopyReadBuffer, buffer.ToInt32());
|
||||
IntPtr target = gd.PersistentBuffers.Default.GetHostArray(size);
|
||||
|
||||
GL.GetBufferSubData(BufferTarget.CopyReadBuffer, (IntPtr)offset, size, target);
|
||||
gd.Api.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32());
|
||||
gd.Api.GetBufferSubData(BufferTargetARB.CopyReadBuffer, offset, (uint)size, (void*)target);
|
||||
|
||||
return new PinnedSpan<byte>(target.ToPointer(), size);
|
||||
}
|
||||
return new PinnedSpan<byte>(target.ToPointer(), size);
|
||||
}
|
||||
|
||||
public static void Resize(BufferHandle handle, int size)
|
||||
public unsafe static void Resize(GL api, BufferHandle handle, int size)
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.CopyWriteBuffer, handle.ToInt32());
|
||||
GL.BufferData(BufferTarget.CopyWriteBuffer, size, IntPtr.Zero, BufferUsageHint.StreamCopy);
|
||||
api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32());
|
||||
api.BufferData(BufferTargetARB.CopyWriteBuffer, (uint)size, null, 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(BufferTarget.CopyWriteBuffer, buffer.ToInt32());
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* ptr = data)
|
||||
{
|
||||
GL.BufferSubData(BufferTarget.CopyWriteBuffer, (IntPtr)offset, data.Length, (IntPtr)ptr);
|
||||
}
|
||||
}
|
||||
api.BindBuffer(BufferTargetARB.CopyWriteBuffer, buffer.ToUInt32());
|
||||
api.BufferSubData(BufferTargetARB.CopyWriteBuffer, offset, (uint)data.Length, data);
|
||||
}
|
||||
|
||||
public static void Delete(BufferHandle buffer)
|
||||
public static void Delete(GL api, BufferHandle buffer)
|
||||
{
|
||||
GL.DeleteBuffer(buffer.ToInt32());
|
||||
api.DeleteBuffer(buffer.ToUInt32());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
@ -13,55 +13,58 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
private static int _counter;
|
||||
|
||||
public static void Initialize(GraphicsDebugLevel logLevel)
|
||||
public unsafe static void Initialize(GL gl, GraphicsDebugLevel logLevel)
|
||||
{
|
||||
// Disable everything
|
||||
GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DontCare, DebugSeverityControl.DontCare, 0, (int[])null, false);
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DontCare, DebugSeverity.DontCare, 0, (uint[])null, false);
|
||||
|
||||
if (logLevel == GraphicsDebugLevel.None)
|
||||
{
|
||||
GL.Disable(EnableCap.DebugOutputSynchronous);
|
||||
GL.DebugMessageCallback(null, IntPtr.Zero);
|
||||
gl.Disable(EnableCap.DebugOutputSynchronous);
|
||||
gl.DebugMessageCallback(null, null);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
GL.Enable(EnableCap.DebugOutputSynchronous);
|
||||
gl.Enable(EnableCap.DebugOutputSynchronous);
|
||||
|
||||
if (logLevel == GraphicsDebugLevel.Error)
|
||||
switch (logLevel)
|
||||
{
|
||||
GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DebugTypeError, DebugSeverityControl.DontCare, 0, (int[])null, true);
|
||||
}
|
||||
else if (logLevel == GraphicsDebugLevel.Slowdowns)
|
||||
{
|
||||
GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DebugTypeError, DebugSeverityControl.DontCare, 0, (int[])null, true);
|
||||
GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DebugTypePerformance, DebugSeverityControl.DontCare, 0, (int[])null, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DontCare, DebugSeverityControl.DontCare, 0, (int[])null, true);
|
||||
case GraphicsDebugLevel.Error:
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypeError, DebugSeverity.DontCare, 0, (uint[])null, true);
|
||||
break;
|
||||
case GraphicsDebugLevel.Slowdowns:
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypeError, DebugSeverity.DontCare, 0, (uint[])null, true);
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypePerformance, DebugSeverity.DontCare, 0, (uint[])null, true);
|
||||
break;
|
||||
default:
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DontCare, DebugSeverity.DontCare, 0, (uint[])null, true);
|
||||
break;
|
||||
}
|
||||
|
||||
_counter = 0;
|
||||
_debugCallback = GLDebugHandler;
|
||||
|
||||
GL.DebugMessageCallback(_debugCallback, IntPtr.Zero);
|
||||
gl.DebugMessageCallback(_debugCallback, null);
|
||||
|
||||
Logger.Warning?.Print(LogClass.Gpu, "OpenGL Debugging is enabled. Performance will be negatively impacted.");
|
||||
}
|
||||
|
||||
private static void GLDebugHandler(
|
||||
DebugSource source,
|
||||
DebugType type,
|
||||
GLEnum source,
|
||||
GLEnum type,
|
||||
int id,
|
||||
DebugSeverity severity,
|
||||
GLEnum severity,
|
||||
int length,
|
||||
IntPtr message,
|
||||
IntPtr userParam)
|
||||
{
|
||||
string msg = Marshal.PtrToStringUTF8(message).Replace('\n', ' ');
|
||||
|
||||
switch (type)
|
||||
DebugType debugType = (DebugType)type;
|
||||
DebugSource debugSource = (DebugSource)source;
|
||||
|
||||
switch (debugType)
|
||||
{
|
||||
case DebugType.DebugTypeError:
|
||||
Logger.Error?.Print(LogClass.Gpu, $"{severity}: {msg}\nCallStack={Environment.StackTrace}", "GLERROR");
|
||||
|
@ -76,7 +79,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
Logger.Info?.Print(LogClass.Gpu, $"}} ({id}) {severity}: {msg}", "GLINFO");
|
||||
break;
|
||||
default:
|
||||
if (source == DebugSource.DebugSourceApplication)
|
||||
if (debugSource == DebugSource.DebugSourceApplication)
|
||||
{
|
||||
Logger.Info?.Print(LogClass.Gpu, $"{type} {severity}: {msg}", "GLINFO");
|
||||
}
|
||||
|
@ -89,21 +92,21 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
}
|
||||
|
||||
// Useful debug helpers
|
||||
public static void PushGroup(string dbgMsg)
|
||||
public static void PushGroup(GL gl, string dbgMsg)
|
||||
{
|
||||
int counter = Interlocked.Increment(ref _counter);
|
||||
|
||||
GL.PushDebugGroup(DebugSourceExternal.DebugSourceApplication, counter, dbgMsg.Length, dbgMsg);
|
||||
gl.PushDebugGroup(DebugSource.DebugSourceApplication, (uint)counter, (uint)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(DebugSourceExternal.DebugSourceApplication, type, id, severity, dbgMsg.Length, dbgMsg);
|
||||
gl.DebugMessageInsert(DebugSource.DebugSourceApplication, type, (uint)id, severity, (uint)dbgMsg.Length, dbgMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.OpenGL.Image;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
{
|
||||
|
@ -35,9 +36,9 @@ void main()
|
|||
colour = texture(tex, texcoord);
|
||||
}";
|
||||
|
||||
private int _vsHandle;
|
||||
private int _fsHandle;
|
||||
private int _programHandle;
|
||||
private uint _vsHandle;
|
||||
private uint _fsHandle;
|
||||
private uint _programHandle;
|
||||
private int _uniformSrcX0Location;
|
||||
private int _uniformSrcY0Location;
|
||||
private int _uniformSrcX1Location;
|
||||
|
@ -45,6 +46,7 @@ void main()
|
|||
private bool _initialized;
|
||||
|
||||
public void Draw(
|
||||
GL api,
|
||||
TextureView texture,
|
||||
Sampler sampler,
|
||||
float x0,
|
||||
|
@ -56,9 +58,9 @@ void main()
|
|||
float s1,
|
||||
float t1)
|
||||
{
|
||||
EnsureInitialized();
|
||||
EnsureInitialized(api);
|
||||
|
||||
GL.UseProgram(_programHandle);
|
||||
api.UseProgram(_programHandle);
|
||||
|
||||
texture.Bind(0);
|
||||
sampler.Bind(0);
|
||||
|
@ -73,17 +75,17 @@ void main()
|
|||
(t1, t0) = (t0, t1);
|
||||
}
|
||||
|
||||
GL.Uniform1(_uniformSrcX0Location, s0);
|
||||
GL.Uniform1(_uniformSrcY0Location, t0);
|
||||
GL.Uniform1(_uniformSrcX1Location, s1);
|
||||
GL.Uniform1(_uniformSrcY1Location, t1);
|
||||
api.Uniform1(_uniformSrcX0Location, s0);
|
||||
api.Uniform1(_uniformSrcY0Location, t0);
|
||||
api.Uniform1(_uniformSrcX1Location, s1);
|
||||
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)
|
||||
{
|
||||
|
@ -92,41 +94,41 @@ void main()
|
|||
|
||||
_initialized = true;
|
||||
|
||||
_vsHandle = GL.CreateShader(ShaderType.VertexShader);
|
||||
_fsHandle = GL.CreateShader(ShaderType.FragmentShader);
|
||||
_vsHandle = api.CreateShader(ShaderType.VertexShader);
|
||||
_fsHandle = api.CreateShader(ShaderType.FragmentShader);
|
||||
|
||||
GL.ShaderSource(_vsHandle, VertexShader);
|
||||
GL.ShaderSource(_fsHandle, FragmentShader);
|
||||
api.ShaderSource(_vsHandle, VertexShader);
|
||||
api.ShaderSource(_fsHandle, FragmentShader);
|
||||
|
||||
GL.CompileShader(_vsHandle);
|
||||
GL.CompileShader(_fsHandle);
|
||||
api.CompileShader(_vsHandle);
|
||||
api.CompileShader(_fsHandle);
|
||||
|
||||
_programHandle = GL.CreateProgram();
|
||||
_programHandle = api.CreateProgram();
|
||||
|
||||
GL.AttachShader(_programHandle, _vsHandle);
|
||||
GL.AttachShader(_programHandle, _fsHandle);
|
||||
api.AttachShader(_programHandle, _vsHandle);
|
||||
api.AttachShader(_programHandle, _fsHandle);
|
||||
|
||||
GL.LinkProgram(_programHandle);
|
||||
api.LinkProgram(_programHandle);
|
||||
|
||||
GL.DetachShader(_programHandle, _vsHandle);
|
||||
GL.DetachShader(_programHandle, _fsHandle);
|
||||
api.DetachShader(_programHandle, _vsHandle);
|
||||
api.DetachShader(_programHandle, _fsHandle);
|
||||
|
||||
_uniformSrcX0Location = GL.GetUniformLocation(_programHandle, "srcX0");
|
||||
_uniformSrcY0Location = GL.GetUniformLocation(_programHandle, "srcY0");
|
||||
_uniformSrcX1Location = GL.GetUniformLocation(_programHandle, "srcX1");
|
||||
_uniformSrcY1Location = GL.GetUniformLocation(_programHandle, "srcY1");
|
||||
_uniformSrcX0Location = api.GetUniformLocation(_programHandle, "srcX0");
|
||||
_uniformSrcY0Location = api.GetUniformLocation(_programHandle, "srcY0");
|
||||
_uniformSrcX1Location = api.GetUniformLocation(_programHandle, "srcX1");
|
||||
_uniformSrcY1Location = api.GetUniformLocation(_programHandle, "srcY1");
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
public void Dispose(GL api)
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GL.DeleteShader(_vsHandle);
|
||||
GL.DeleteShader(_fsHandle);
|
||||
GL.DeleteProgram(_programHandle);
|
||||
api.DeleteShader(_vsHandle);
|
||||
api.DeleteShader(_fsHandle);
|
||||
api.DeleteProgram(_programHandle);
|
||||
|
||||
_initialized = false;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.OpenGL.Image;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using static Ryujinx.Graphics.OpenGL.Effects.ShaderHelper;
|
||||
|
||||
|
@ -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,64 +114,64 @@ 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(GLEnum.CurrentProgram);
|
||||
int previousUnit = _gd.Api.GetInteger(GLEnum.ActiveTexture);
|
||||
_gd.Api.ActiveTexture(TextureUnit.Texture0);
|
||||
uint previousTextureBinding = (uint)_gd.Api.GetInteger(GLEnum.TextureBinding2D);
|
||||
|
||||
GL.BindImageTexture(0, textureView.Handle, 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
_gd.Api.BindImageTexture(0, textureView.Handle, 0, false, 0, BufferAccessARB.ReadWrite, InternalFormat.Rgba8);
|
||||
|
||||
int threadGroupWorkRegionDim = 16;
|
||||
int dispatchX = (width + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
|
||||
int dispatchY = (height + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim;
|
||||
uint dispatchX = (uint)((width + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim);
|
||||
uint dispatchY = (uint)((height + (threadGroupWorkRegionDim - 1)) / threadGroupWorkRegionDim);
|
||||
|
||||
// Scaling pass
|
||||
float srcWidth = Math.Abs(source.X2 - source.X1);
|
||||
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(MemoryBarrierFlags.ShaderImageAccessBarrierBit);
|
||||
_gd.Api.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit);
|
||||
|
||||
// Sharpening Pass
|
||||
GL.UseProgram(_sharpeningShaderProgram);
|
||||
GL.BindImageTexture(0, destinationTexture.Handle, 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
_gd.Api.UseProgram(_sharpeningShaderProgram);
|
||||
_gd.Api.BindImageTexture(0, destinationTexture.Handle, 0, false, 0, BufferAccessARB.ReadWrite, InternalFormat.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(MemoryBarrierFlags.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.OpenGL.Image;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
_shaderProgram = ShaderHelper.CompileProgram(EmbeddedResources.ReadAllText("Ryujinx.Graphics.OpenGL/Effects/Shaders/fxaa.glsl"), ShaderType.ComputeShader);
|
||||
_shaderProgram = ShaderHelper.CompileProgram(_gd.Api, 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);
|
||||
uint previousProgram = (uint)_gd.Api.GetInteger(GLEnum.CurrentProgram);
|
||||
int previousUnit = _gd.Api.GetInteger(GLEnum.ActiveTexture);
|
||||
_gd.Api.ActiveTexture(TextureUnit.Texture0);
|
||||
uint previousTextureBinding = (uint)_gd.Api.GetInteger(GLEnum.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, InternalFormat.Rgba8);
|
||||
_gd.Api.UseProgram(_shaderProgram);
|
||||
|
||||
var dispatchX = BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
|
||||
var dispatchY = BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
|
||||
uint dispatchX = (uint)BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
|
||||
uint dispatchY = (uint)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, view.Width, 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;
|
||||
}
|
||||
|
|
|
@ -1,37 +1,38 @@
|
|||
using OpenTK.Graphics.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);
|
||||
var length = 0;
|
||||
api.ShaderSource(shader, (uint)shaders.Length, shaders, in length);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.OpenGL.Image;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
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++)
|
||||
{
|
||||
|
@ -93,25 +93,25 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
|
|||
var neighbourShaderData = EmbeddedResources.ReadAllText("Ryujinx.Graphics.OpenGL/Effects/Shaders/smaa_neighbour.glsl");
|
||||
|
||||
var shaders = new string[] { presets, edgeShaderData };
|
||||
var edgeProgram = ShaderHelper.CompileProgram(shaders, ShaderType.ComputeShader);
|
||||
var edgeProgram = ShaderHelper.CompileProgram(_gd.Api, shaders, ShaderType.ComputeShader);
|
||||
|
||||
shaders[1] = blendShaderData;
|
||||
var blendProgram = ShaderHelper.CompileProgram(shaders, ShaderType.ComputeShader);
|
||||
var blendProgram = ShaderHelper.CompileProgram(_gd.Api, shaders, ShaderType.ComputeShader);
|
||||
|
||||
shaders[1] = neighbourShaderData;
|
||||
var neighbourProgram = ShaderHelper.CompileProgram(shaders, ShaderType.ComputeShader);
|
||||
var neighbourProgram = ShaderHelper.CompileProgram(_gd.Api, shaders, ShaderType.ComputeShader);
|
||||
|
||||
_edgeShaderPrograms[i] = edgeProgram;
|
||||
_blendShaderPrograms[i] = blendProgram;
|
||||
_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);
|
||||
uint previousFramebuffer = (uint)_gd.Api.GetInteger(GLEnum.DrawFramebufferBinding);
|
||||
int previousUnit = _gd.Api.GetInteger(GLEnum.ActiveTexture);
|
||||
_gd.Api.ActiveTexture(TextureUnit.Texture0);
|
||||
uint previousTextureBinding0 = (uint)_gd.Api.GetInteger(GLEnum.TextureBinding2D);
|
||||
_gd.Api.ActiveTexture(TextureUnit.Texture1);
|
||||
uint previousTextureBinding1 = (uint)_gd.Api.GetInteger(GLEnum.TextureBinding2D);
|
||||
_gd.Api.ActiveTexture(TextureUnit.Texture2);
|
||||
uint previousTextureBinding2 = (uint)_gd.Api.GetInteger(GLEnum.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);
|
||||
uint dispatchX = (uint)BitUtils.DivRoundUp(view.Width, IPostProcessingEffect.LocalGroupSize);
|
||||
uint dispatchY = (uint)BitUtils.DivRoundUp(view.Height, IPostProcessingEffect.LocalGroupSize);
|
||||
|
||||
int previousProgram = GL.GetInteger(GetPName.CurrentProgram);
|
||||
GL.BindImageTexture(0, edgeOutput.Handle, 0, false, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
GL.UseProgram(_edgeShaderPrograms[Quality]);
|
||||
uint previousProgram = (uint)_gd.Api.GetInteger(GLEnum.CurrentProgram);
|
||||
_gd.Api.BindImageTexture(0, edgeOutput.Handle, 0, false, 0, BufferAccessARB.ReadWrite, InternalFormat.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(MemoryBarrierFlags.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, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
GL.UseProgram(_blendShaderPrograms[Quality]);
|
||||
_gd.Api.BindImageTexture(0, blendOutput.Handle, 0, false, 0, BufferAccessARB.ReadWrite, InternalFormat.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(MemoryBarrierFlags.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, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
GL.UseProgram(_neighbourShaderPrograms[Quality]);
|
||||
_gd.Api.BindImageTexture(0, textureView.Handle, 0, false, 0, BufferAccessARB.ReadWrite, InternalFormat.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(MemoryBarrierFlags.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;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using Silk.NET.OpenGL.Legacy.Extensions.EXT;
|
||||
using Silk.NET.OpenGL.Legacy.Extensions.NV;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
{
|
||||
|
@ -12,15 +14,17 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
switch (mode)
|
||||
{
|
||||
case AddressMode.Clamp:
|
||||
#pragma warning disable CS0612 // Type or member is obsolete
|
||||
return TextureWrapMode.Clamp;
|
||||
#pragma warning restore CS0612 // Type or member is obsolete
|
||||
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:
|
||||
|
@ -31,217 +35,219 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(AddressMode)} enum value: {mode}.");
|
||||
|
||||
#pragma warning disable CS0612 // Type or member is obsolete
|
||||
return TextureWrapMode.Clamp;
|
||||
#pragma warning restore CS0612 // Type or member is obsolete
|
||||
}
|
||||
|
||||
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 All Convert(this BlendFactor factor)
|
||||
public static GLEnum Convert(this BlendFactor factor)
|
||||
{
|
||||
switch (factor)
|
||||
{
|
||||
case BlendFactor.Zero:
|
||||
case BlendFactor.ZeroGl:
|
||||
return All.Zero;
|
||||
return GLEnum.Zero;
|
||||
case BlendFactor.One:
|
||||
case BlendFactor.OneGl:
|
||||
return All.One;
|
||||
return GLEnum.One;
|
||||
case BlendFactor.SrcColor:
|
||||
case BlendFactor.SrcColorGl:
|
||||
return All.SrcColor;
|
||||
return GLEnum.SrcColor;
|
||||
case BlendFactor.OneMinusSrcColor:
|
||||
case BlendFactor.OneMinusSrcColorGl:
|
||||
return All.OneMinusSrcColor;
|
||||
return GLEnum.OneMinusSrcColor;
|
||||
case BlendFactor.SrcAlpha:
|
||||
case BlendFactor.SrcAlphaGl:
|
||||
return All.SrcAlpha;
|
||||
return GLEnum.SrcAlpha;
|
||||
case BlendFactor.OneMinusSrcAlpha:
|
||||
case BlendFactor.OneMinusSrcAlphaGl:
|
||||
return All.OneMinusSrcAlpha;
|
||||
return GLEnum.OneMinusSrcAlpha;
|
||||
case BlendFactor.DstAlpha:
|
||||
case BlendFactor.DstAlphaGl:
|
||||
return All.DstAlpha;
|
||||
return GLEnum.DstAlpha;
|
||||
case BlendFactor.OneMinusDstAlpha:
|
||||
case BlendFactor.OneMinusDstAlphaGl:
|
||||
return All.OneMinusDstAlpha;
|
||||
return GLEnum.OneMinusDstAlpha;
|
||||
case BlendFactor.DstColor:
|
||||
case BlendFactor.DstColorGl:
|
||||
return All.DstColor;
|
||||
return GLEnum.DstColor;
|
||||
case BlendFactor.OneMinusDstColor:
|
||||
case BlendFactor.OneMinusDstColorGl:
|
||||
return All.OneMinusDstColor;
|
||||
return GLEnum.OneMinusDstColor;
|
||||
case BlendFactor.SrcAlphaSaturate:
|
||||
case BlendFactor.SrcAlphaSaturateGl:
|
||||
return All.SrcAlphaSaturate;
|
||||
return GLEnum.SrcAlphaSaturate;
|
||||
case BlendFactor.Src1Color:
|
||||
case BlendFactor.Src1ColorGl:
|
||||
return All.Src1Color;
|
||||
return GLEnum.Src1Color;
|
||||
case BlendFactor.OneMinusSrc1Color:
|
||||
case BlendFactor.OneMinusSrc1ColorGl:
|
||||
return All.OneMinusSrc1Color;
|
||||
return GLEnum.OneMinusSrc1Color;
|
||||
case BlendFactor.Src1Alpha:
|
||||
case BlendFactor.Src1AlphaGl:
|
||||
return All.Src1Alpha;
|
||||
return GLEnum.Src1Alpha;
|
||||
case BlendFactor.OneMinusSrc1Alpha:
|
||||
case BlendFactor.OneMinusSrc1AlphaGl:
|
||||
return All.OneMinusSrc1Alpha;
|
||||
return GLEnum.OneMinusSrc1Alpha;
|
||||
case BlendFactor.ConstantColor:
|
||||
return All.ConstantColor;
|
||||
return GLEnum.ConstantColor;
|
||||
case BlendFactor.OneMinusConstantColor:
|
||||
return All.OneMinusConstantColor;
|
||||
return GLEnum.OneMinusConstantColor;
|
||||
case BlendFactor.ConstantAlpha:
|
||||
return All.ConstantAlpha;
|
||||
return GLEnum.ConstantAlpha;
|
||||
case BlendFactor.OneMinusConstantAlpha:
|
||||
return All.OneMinusConstantAlpha;
|
||||
return GLEnum.OneMinusConstantAlpha;
|
||||
}
|
||||
|
||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(BlendFactor)} enum value: {factor}.");
|
||||
|
||||
return All.Zero;
|
||||
return GLEnum.Zero;
|
||||
}
|
||||
|
||||
public static BlendEquationMode Convert(this BlendOp op)
|
||||
public static GLEnum Convert(this BlendOp op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case BlendOp.Add:
|
||||
case BlendOp.AddGl:
|
||||
return BlendEquationMode.FuncAdd;
|
||||
return GLEnum.FuncAdd;
|
||||
case BlendOp.Minimum:
|
||||
case BlendOp.MinimumGl:
|
||||
return BlendEquationMode.Min;
|
||||
return GLEnum.Min;
|
||||
case BlendOp.Maximum:
|
||||
case BlendOp.MaximumGl:
|
||||
return BlendEquationMode.Max;
|
||||
return GLEnum.Max;
|
||||
case BlendOp.Subtract:
|
||||
case BlendOp.SubtractGl:
|
||||
return BlendEquationMode.FuncSubtract;
|
||||
return GLEnum.FuncSubtract;
|
||||
case BlendOp.ReverseSubtract:
|
||||
case BlendOp.ReverseSubtractGl:
|
||||
return BlendEquationMode.FuncReverseSubtract;
|
||||
return GLEnum.FuncReverseSubtract;
|
||||
}
|
||||
|
||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(BlendOp)} enum value: {op}.");
|
||||
|
||||
return BlendEquationMode.FuncAdd;
|
||||
return GLEnum.FuncAdd;
|
||||
}
|
||||
|
||||
public static TextureCompareMode Convert(this CompareMode mode)
|
||||
|
@ -251,7 +257,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
case CompareMode.None:
|
||||
return TextureCompareMode.None;
|
||||
case CompareMode.CompareRToTexture:
|
||||
return TextureCompareMode.CompareRToTexture;
|
||||
return TextureCompareMode.CompareRefToTexture;
|
||||
}
|
||||
|
||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(CompareMode)} enum value: {mode}.");
|
||||
|
@ -259,86 +265,86 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
return TextureCompareMode.None;
|
||||
}
|
||||
|
||||
public static All Convert(this CompareOp op)
|
||||
public static GLEnum Convert(this CompareOp op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case CompareOp.Never:
|
||||
case CompareOp.NeverGl:
|
||||
return All.Never;
|
||||
return GLEnum.Never;
|
||||
case CompareOp.Less:
|
||||
case CompareOp.LessGl:
|
||||
return All.Less;
|
||||
return GLEnum.Less;
|
||||
case CompareOp.Equal:
|
||||
case CompareOp.EqualGl:
|
||||
return All.Equal;
|
||||
return GLEnum.Equal;
|
||||
case CompareOp.LessOrEqual:
|
||||
case CompareOp.LessOrEqualGl:
|
||||
return All.Lequal;
|
||||
return GLEnum.Lequal;
|
||||
case CompareOp.Greater:
|
||||
case CompareOp.GreaterGl:
|
||||
return All.Greater;
|
||||
return GLEnum.Greater;
|
||||
case CompareOp.NotEqual:
|
||||
case CompareOp.NotEqualGl:
|
||||
return All.Notequal;
|
||||
return GLEnum.Notequal;
|
||||
case CompareOp.GreaterOrEqual:
|
||||
case CompareOp.GreaterOrEqualGl:
|
||||
return All.Gequal;
|
||||
return GLEnum.Gequal;
|
||||
case CompareOp.Always:
|
||||
case CompareOp.AlwaysGl:
|
||||
return All.Always;
|
||||
return GLEnum.Always;
|
||||
}
|
||||
|
||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(CompareOp)} enum value: {op}.");
|
||||
|
||||
return All.Never;
|
||||
return GLEnum.Never;
|
||||
}
|
||||
|
||||
public static ClipDepthMode Convert(this DepthMode mode)
|
||||
public static GLEnum Convert(this DepthMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case DepthMode.MinusOneToOne:
|
||||
return ClipDepthMode.NegativeOneToOne;
|
||||
return GLEnum.NegativeOneToOne;
|
||||
case DepthMode.ZeroToOne:
|
||||
return ClipDepthMode.ZeroToOne;
|
||||
return GLEnum.ZeroToOne;
|
||||
}
|
||||
|
||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(DepthMode)} enum value: {mode}.");
|
||||
|
||||
return ClipDepthMode.NegativeOneToOne;
|
||||
return GLEnum.NegativeOneToOne;
|
||||
}
|
||||
|
||||
public static All Convert(this DepthStencilMode mode)
|
||||
public static GLEnum Convert(this DepthStencilMode mode)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case DepthStencilMode.Depth:
|
||||
return All.DepthComponent;
|
||||
return GLEnum.DepthComponent;
|
||||
case DepthStencilMode.Stencil:
|
||||
return All.StencilIndex;
|
||||
return GLEnum.StencilIndex;
|
||||
}
|
||||
|
||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(DepthStencilMode)} enum value: {mode}.");
|
||||
|
||||
return All.Depth;
|
||||
return GLEnum.Depth;
|
||||
}
|
||||
|
||||
public static CullFaceMode Convert(this Face face)
|
||||
public static GLEnum Convert(this Face face)
|
||||
{
|
||||
switch (face)
|
||||
{
|
||||
case Face.Back:
|
||||
return CullFaceMode.Back;
|
||||
return GLEnum.Back;
|
||||
case Face.Front:
|
||||
return CullFaceMode.Front;
|
||||
return GLEnum.Front;
|
||||
case Face.FrontAndBack:
|
||||
return CullFaceMode.FrontAndBack;
|
||||
return GLEnum.FrontAndBack;
|
||||
}
|
||||
|
||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(Face)} enum value: {face}.");
|
||||
|
||||
return CullFaceMode.Back;
|
||||
return GLEnum.Back;
|
||||
}
|
||||
|
||||
public static FrontFaceDirection Convert(this FrontFace frontFace)
|
||||
|
@ -346,14 +352,14 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
switch (frontFace)
|
||||
{
|
||||
case FrontFace.Clockwise:
|
||||
return FrontFaceDirection.Cw;
|
||||
return FrontFaceDirection.CW;
|
||||
case FrontFace.CounterClockwise:
|
||||
return FrontFaceDirection.Ccw;
|
||||
}
|
||||
|
||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(FrontFace)} enum value: {frontFace}.");
|
||||
|
||||
return FrontFaceDirection.Cw;
|
||||
return FrontFaceDirection.CW;
|
||||
}
|
||||
|
||||
public static DrawElementsType Convert(this IndexType type)
|
||||
|
@ -411,21 +417,21 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
return TextureMinFilter.Nearest;
|
||||
}
|
||||
|
||||
public static OpenTK.Graphics.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 OpenTK.Graphics.OpenGL.PolygonMode.Point;
|
||||
return Silk.NET.OpenGL.Legacy.PolygonMode.Point;
|
||||
case GAL.PolygonMode.Line:
|
||||
return OpenTK.Graphics.OpenGL.PolygonMode.Line;
|
||||
return Silk.NET.OpenGL.Legacy.PolygonMode.Line;
|
||||
case GAL.PolygonMode.Fill:
|
||||
return OpenTK.Graphics.OpenGL.PolygonMode.Fill;
|
||||
return Silk.NET.OpenGL.Legacy.PolygonMode.Fill;
|
||||
}
|
||||
|
||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(GAL.PolygonMode)} enum value: {mode}.");
|
||||
|
||||
return OpenTK.Graphics.OpenGL.PolygonMode.Fill;
|
||||
return Silk.NET.OpenGL.Legacy.PolygonMode.Fill;
|
||||
}
|
||||
|
||||
public static PrimitiveType Convert(this PrimitiveTopology topology)
|
||||
|
@ -449,7 +455,9 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
case PrimitiveTopology.Quads:
|
||||
return PrimitiveType.Quads;
|
||||
case PrimitiveTopology.QuadStrip:
|
||||
#pragma warning disable CS0612 // Type or member is obsolete
|
||||
return PrimitiveType.QuadStrip;
|
||||
#pragma warning restore CS0612 // Type or member is obsolete
|
||||
case PrimitiveTopology.Polygon:
|
||||
return PrimitiveType.TriangleFan;
|
||||
case PrimitiveTopology.LinesAdjacency:
|
||||
|
@ -469,92 +477,92 @@ 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 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)
|
||||
|
@ -588,74 +596,74 @@ 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 All Convert(this LogicalOp op)
|
||||
public static GLEnum Convert(this LogicalOp op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case LogicalOp.Clear:
|
||||
return All.Clear;
|
||||
return GLEnum.Clear;
|
||||
case LogicalOp.And:
|
||||
return All.And;
|
||||
return GLEnum.And;
|
||||
case LogicalOp.AndReverse:
|
||||
return All.AndReverse;
|
||||
return GLEnum.AndReverse;
|
||||
case LogicalOp.Copy:
|
||||
return All.Copy;
|
||||
return GLEnum.Copy;
|
||||
case LogicalOp.AndInverted:
|
||||
return All.AndInverted;
|
||||
return GLEnum.AndInverted;
|
||||
case LogicalOp.Noop:
|
||||
return All.Noop;
|
||||
return GLEnum.Noop;
|
||||
case LogicalOp.Xor:
|
||||
return All.Xor;
|
||||
return GLEnum.Xor;
|
||||
case LogicalOp.Or:
|
||||
return All.Or;
|
||||
return GLEnum.Or;
|
||||
case LogicalOp.Nor:
|
||||
return All.Nor;
|
||||
return GLEnum.Nor;
|
||||
case LogicalOp.Equiv:
|
||||
return All.Equiv;
|
||||
return GLEnum.Equiv;
|
||||
case LogicalOp.Invert:
|
||||
return All.Invert;
|
||||
return GLEnum.Invert;
|
||||
case LogicalOp.OrReverse:
|
||||
return All.OrReverse;
|
||||
return GLEnum.OrReverse;
|
||||
case LogicalOp.CopyInverted:
|
||||
return All.CopyInverted;
|
||||
return GLEnum.CopyInverted;
|
||||
case LogicalOp.OrInverted:
|
||||
return All.OrInverted;
|
||||
return GLEnum.OrInverted;
|
||||
case LogicalOp.Nand:
|
||||
return All.Nand;
|
||||
return GLEnum.Nand;
|
||||
case LogicalOp.Set:
|
||||
return All.Set;
|
||||
return GLEnum.Set;
|
||||
}
|
||||
|
||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(LogicalOp)} enum value: {op}.");
|
||||
|
||||
return All.Never;
|
||||
return GLEnum.Never;
|
||||
}
|
||||
|
||||
public static ShaderType Convert(this ShaderStage stage)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
{
|
||||
|
@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
public bool Normalized { get; }
|
||||
public bool Scaled { get; }
|
||||
|
||||
public PixelInternalFormat PixelInternalFormat { get; }
|
||||
public InternalFormat InternalFormat { get; }
|
||||
public PixelFormat PixelFormat { get; }
|
||||
public PixelType PixelType { get; }
|
||||
|
||||
|
@ -18,25 +18,25 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
int components,
|
||||
bool normalized,
|
||||
bool scaled,
|
||||
All pixelInternalFormat,
|
||||
InternalFormat internalFormat,
|
||||
PixelFormat pixelFormat,
|
||||
PixelType pixelType)
|
||||
{
|
||||
Components = components;
|
||||
Normalized = normalized;
|
||||
Scaled = scaled;
|
||||
PixelInternalFormat = (PixelInternalFormat)pixelInternalFormat;
|
||||
InternalFormat = internalFormat;
|
||||
PixelFormat = pixelFormat;
|
||||
PixelType = pixelType;
|
||||
IsCompressed = false;
|
||||
}
|
||||
|
||||
public FormatInfo(int components, bool normalized, bool scaled, All pixelFormat)
|
||||
public FormatInfo(int components, bool normalized, bool scaled, InternalFormat pixelFormat)
|
||||
{
|
||||
Components = components;
|
||||
Normalized = normalized;
|
||||
Scaled = scaled;
|
||||
PixelInternalFormat = 0;
|
||||
InternalFormat = 0;
|
||||
PixelFormat = (PixelFormat)pixelFormat;
|
||||
PixelType = 0;
|
||||
IsCompressed = true;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using Silk.NET.OpenGL.Legacy.Extensions.NV;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
|
@ -17,192 +18,192 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
_tableImage = new SizedInternalFormat[tableSize];
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
Add(Format.R8Unorm, new FormatInfo(1, true, false, All.R8, PixelFormat.Red, PixelType.UnsignedByte));
|
||||
Add(Format.R8Snorm, new FormatInfo(1, true, false, All.R8Snorm, PixelFormat.Red, PixelType.Byte));
|
||||
Add(Format.R8Uint, new FormatInfo(1, false, false, All.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8Sint, new FormatInfo(1, false, false, All.R8i, PixelFormat.RedInteger, PixelType.Byte));
|
||||
Add(Format.R16Float, new FormatInfo(1, false, false, All.R16f, PixelFormat.Red, PixelType.HalfFloat));
|
||||
Add(Format.R16Unorm, new FormatInfo(1, true, false, All.R16, PixelFormat.Red, PixelType.UnsignedShort));
|
||||
Add(Format.R16Snorm, new FormatInfo(1, true, false, All.R16Snorm, PixelFormat.Red, PixelType.Short));
|
||||
Add(Format.R16Uint, new FormatInfo(1, false, false, All.R16ui, PixelFormat.RedInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16Sint, new FormatInfo(1, false, false, All.R16i, PixelFormat.RedInteger, PixelType.Short));
|
||||
Add(Format.R32Float, new FormatInfo(1, false, false, All.R32f, PixelFormat.Red, PixelType.Float));
|
||||
Add(Format.R32Uint, new FormatInfo(1, false, false, All.R32ui, PixelFormat.RedInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32Sint, new FormatInfo(1, false, false, All.R32i, PixelFormat.RedInteger, PixelType.Int));
|
||||
Add(Format.R8G8Unorm, new FormatInfo(2, true, false, All.Rg8, PixelFormat.Rg, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8Snorm, new FormatInfo(2, true, false, All.Rg8Snorm, PixelFormat.Rg, PixelType.Byte));
|
||||
Add(Format.R8G8Uint, new FormatInfo(2, false, false, All.Rg8ui, PixelFormat.RgInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8Sint, new FormatInfo(2, false, false, All.Rg8i, PixelFormat.RgInteger, PixelType.Byte));
|
||||
Add(Format.R16G16Float, new FormatInfo(2, false, false, All.Rg16f, PixelFormat.Rg, PixelType.HalfFloat));
|
||||
Add(Format.R16G16Unorm, new FormatInfo(2, true, false, All.Rg16, PixelFormat.Rg, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16Snorm, new FormatInfo(2, true, false, All.Rg16Snorm, PixelFormat.Rg, PixelType.Short));
|
||||
Add(Format.R16G16Uint, new FormatInfo(2, false, false, All.Rg16ui, PixelFormat.RgInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16Sint, new FormatInfo(2, false, false, All.Rg16i, PixelFormat.RgInteger, PixelType.Short));
|
||||
Add(Format.R32G32Float, new FormatInfo(2, false, false, All.Rg32f, PixelFormat.Rg, PixelType.Float));
|
||||
Add(Format.R32G32Uint, new FormatInfo(2, false, false, All.Rg32ui, PixelFormat.RgInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32G32Sint, new FormatInfo(2, false, false, All.Rg32i, PixelFormat.RgInteger, PixelType.Int));
|
||||
Add(Format.R8G8B8Unorm, new FormatInfo(3, true, false, All.Rgb8, PixelFormat.Rgb, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8B8Snorm, new FormatInfo(3, true, false, All.Rgb8Snorm, PixelFormat.Rgb, PixelType.Byte));
|
||||
Add(Format.R8G8B8Uint, new FormatInfo(3, false, false, All.Rgb8ui, PixelFormat.RgbInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8B8Sint, new FormatInfo(3, false, false, All.Rgb8i, PixelFormat.RgbInteger, PixelType.Byte));
|
||||
Add(Format.R16G16B16Float, new FormatInfo(3, false, false, All.Rgb16f, PixelFormat.Rgb, PixelType.HalfFloat));
|
||||
Add(Format.R16G16B16Unorm, new FormatInfo(3, true, false, All.Rgb16, PixelFormat.Rgb, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16B16Snorm, new FormatInfo(3, true, false, All.Rgb16Snorm, PixelFormat.Rgb, PixelType.Short));
|
||||
Add(Format.R16G16B16Uint, new FormatInfo(3, false, false, All.Rgb16ui, PixelFormat.RgbInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16B16Sint, new FormatInfo(3, false, false, All.Rgb16i, PixelFormat.RgbInteger, PixelType.Short));
|
||||
Add(Format.R32G32B32Float, new FormatInfo(3, false, false, All.Rgb32f, PixelFormat.Rgb, PixelType.Float));
|
||||
Add(Format.R32G32B32Uint, new FormatInfo(3, false, false, All.Rgb32ui, PixelFormat.RgbInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32G32B32Sint, new FormatInfo(3, false, false, All.Rgb32i, PixelFormat.RgbInteger, PixelType.Int));
|
||||
Add(Format.R8G8B8A8Unorm, new FormatInfo(4, true, false, All.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8B8A8Snorm, new FormatInfo(4, true, false, All.Rgba8Snorm, PixelFormat.Rgba, PixelType.Byte));
|
||||
Add(Format.R8G8B8A8Uint, new FormatInfo(4, false, false, All.Rgba8ui, PixelFormat.RgbaInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8B8A8Sint, new FormatInfo(4, false, false, All.Rgba8i, PixelFormat.RgbaInteger, PixelType.Byte));
|
||||
Add(Format.R16G16B16A16Float, new FormatInfo(4, false, false, All.Rgba16f, PixelFormat.Rgba, PixelType.HalfFloat));
|
||||
Add(Format.R16G16B16A16Unorm, new FormatInfo(4, true, false, All.Rgba16, PixelFormat.Rgba, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16B16A16Snorm, new FormatInfo(4, true, false, All.Rgba16Snorm, PixelFormat.Rgba, PixelType.Short));
|
||||
Add(Format.R16G16B16A16Uint, new FormatInfo(4, false, false, All.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16B16A16Sint, new FormatInfo(4, false, false, All.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short));
|
||||
Add(Format.R32G32B32A32Float, new FormatInfo(4, false, false, All.Rgba32f, PixelFormat.Rgba, PixelType.Float));
|
||||
Add(Format.R32G32B32A32Uint, new FormatInfo(4, false, false, All.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32G32B32A32Sint, new FormatInfo(4, false, false, All.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int));
|
||||
Add(Format.S8Uint, new FormatInfo(1, false, false, All.StencilIndex8, PixelFormat.StencilIndex, PixelType.UnsignedByte));
|
||||
Add(Format.D16Unorm, new FormatInfo(1, false, false, All.DepthComponent16, PixelFormat.DepthComponent, PixelType.UnsignedShort));
|
||||
Add(Format.S8UintD24Unorm, new FormatInfo(1, false, false, All.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248));
|
||||
Add(Format.X8UintD24Unorm, new FormatInfo(1, false, false, All.DepthComponent24, PixelFormat.DepthComponent, PixelType.UnsignedInt));
|
||||
Add(Format.D32Float, new FormatInfo(1, false, false, All.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float));
|
||||
Add(Format.D24UnormS8Uint, new FormatInfo(1, false, false, All.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248));
|
||||
Add(Format.D32FloatS8Uint, new FormatInfo(1, false, false, All.Depth32fStencil8, PixelFormat.DepthStencil, PixelType.Float32UnsignedInt248Rev));
|
||||
Add(Format.R8G8B8A8Srgb, new FormatInfo(4, false, false, All.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte));
|
||||
Add(Format.R4G4B4A4Unorm, new FormatInfo(4, true, false, All.Rgba4, PixelFormat.Rgba, PixelType.UnsignedShort4444Reversed));
|
||||
Add(Format.R5G5B5X1Unorm, new FormatInfo(4, true, false, All.Rgb5, PixelFormat.Rgb, PixelType.UnsignedShort1555Reversed));
|
||||
Add(Format.R5G5B5A1Unorm, new FormatInfo(4, true, false, All.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort1555Reversed));
|
||||
Add(Format.R5G6B5Unorm, new FormatInfo(3, true, false, All.Rgb565, PixelFormat.Rgb, PixelType.UnsignedShort565Reversed));
|
||||
Add(Format.R10G10B10A2Unorm, new FormatInfo(4, true, false, All.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed));
|
||||
Add(Format.R10G10B10A2Uint, new FormatInfo(4, false, false, All.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed));
|
||||
Add(Format.R11G11B10Float, new FormatInfo(3, false, false, All.R11fG11fB10f, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev));
|
||||
Add(Format.R9G9B9E5Float, new FormatInfo(3, false, false, All.Rgb9E5, PixelFormat.Rgb, PixelType.UnsignedInt5999Rev));
|
||||
Add(Format.Bc1RgbaUnorm, new FormatInfo(4, true, false, All.CompressedRgbaS3tcDxt1Ext));
|
||||
Add(Format.Bc2Unorm, new FormatInfo(4, true, false, All.CompressedRgbaS3tcDxt3Ext));
|
||||
Add(Format.Bc3Unorm, new FormatInfo(4, true, false, All.CompressedRgbaS3tcDxt5Ext));
|
||||
Add(Format.Bc1RgbaSrgb, new FormatInfo(4, true, false, All.CompressedSrgbAlphaS3tcDxt1Ext));
|
||||
Add(Format.Bc2Srgb, new FormatInfo(4, false, false, All.CompressedSrgbAlphaS3tcDxt3Ext));
|
||||
Add(Format.Bc3Srgb, new FormatInfo(4, false, false, All.CompressedSrgbAlphaS3tcDxt5Ext));
|
||||
Add(Format.Bc4Unorm, new FormatInfo(1, true, false, All.CompressedRedRgtc1));
|
||||
Add(Format.Bc4Snorm, new FormatInfo(1, true, false, All.CompressedSignedRedRgtc1));
|
||||
Add(Format.Bc5Unorm, new FormatInfo(2, true, false, All.CompressedRgRgtc2));
|
||||
Add(Format.Bc5Snorm, new FormatInfo(2, true, false, All.CompressedSignedRgRgtc2));
|
||||
Add(Format.Bc7Unorm, new FormatInfo(4, true, false, All.CompressedRgbaBptcUnorm));
|
||||
Add(Format.Bc7Srgb, new FormatInfo(4, false, false, All.CompressedSrgbAlphaBptcUnorm));
|
||||
Add(Format.Bc6HSfloat, new FormatInfo(4, false, false, All.CompressedRgbBptcSignedFloat));
|
||||
Add(Format.Bc6HUfloat, new FormatInfo(4, false, false, All.CompressedRgbBptcUnsignedFloat));
|
||||
Add(Format.Etc2RgbUnorm, new FormatInfo(4, false, false, All.CompressedRgb8Etc2));
|
||||
Add(Format.Etc2RgbaUnorm, new FormatInfo(4, false, false, All.CompressedRgba8Etc2Eac));
|
||||
Add(Format.Etc2RgbPtaUnorm, new FormatInfo(4, false, false, All.CompressedRgb8PunchthroughAlpha1Etc2));
|
||||
Add(Format.Etc2RgbSrgb, new FormatInfo(4, false, false, All.CompressedSrgb8Etc2));
|
||||
Add(Format.Etc2RgbaSrgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Etc2Eac));
|
||||
Add(Format.Etc2RgbPtaSrgb, new FormatInfo(4, false, false, All.CompressedSrgb8PunchthroughAlpha1Etc2));
|
||||
Add(Format.R8Uscaled, new FormatInfo(1, false, true, All.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8Sscaled, new FormatInfo(1, false, true, All.R8i, PixelFormat.RedInteger, PixelType.Byte));
|
||||
Add(Format.R16Uscaled, new FormatInfo(1, false, true, All.R16ui, PixelFormat.RedInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16Sscaled, new FormatInfo(1, false, true, All.R16i, PixelFormat.RedInteger, PixelType.Short));
|
||||
Add(Format.R32Uscaled, new FormatInfo(1, false, true, All.R32ui, PixelFormat.RedInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32Sscaled, new FormatInfo(1, false, true, All.R32i, PixelFormat.RedInteger, PixelType.Int));
|
||||
Add(Format.R8G8Uscaled, new FormatInfo(2, false, true, All.Rg8ui, PixelFormat.RgInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8Sscaled, new FormatInfo(2, false, true, All.Rg8i, PixelFormat.RgInteger, PixelType.Byte));
|
||||
Add(Format.R16G16Uscaled, new FormatInfo(2, false, true, All.Rg16ui, PixelFormat.RgInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16Sscaled, new FormatInfo(2, false, true, All.Rg16i, PixelFormat.RgInteger, PixelType.Short));
|
||||
Add(Format.R32G32Uscaled, new FormatInfo(2, false, true, All.Rg32ui, PixelFormat.RgInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32G32Sscaled, new FormatInfo(2, false, true, All.Rg32i, PixelFormat.RgInteger, PixelType.Int));
|
||||
Add(Format.R8G8B8Uscaled, new FormatInfo(3, false, true, All.Rgb8ui, PixelFormat.RgbInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8B8Sscaled, new FormatInfo(3, false, true, All.Rgb8i, PixelFormat.RgbInteger, PixelType.Byte));
|
||||
Add(Format.R16G16B16Uscaled, new FormatInfo(3, false, true, All.Rgb16ui, PixelFormat.RgbInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16B16Sscaled, new FormatInfo(3, false, true, All.Rgb16i, PixelFormat.RgbInteger, PixelType.Short));
|
||||
Add(Format.R32G32B32Uscaled, new FormatInfo(3, false, true, All.Rgb32ui, PixelFormat.RgbInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32G32B32Sscaled, new FormatInfo(3, false, true, All.Rgb32i, PixelFormat.RgbInteger, PixelType.Int));
|
||||
Add(Format.R8G8B8A8Uscaled, new FormatInfo(4, false, true, All.Rgba8ui, PixelFormat.RgbaInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8B8A8Sscaled, new FormatInfo(4, false, true, All.Rgba8i, PixelFormat.RgbaInteger, PixelType.Byte));
|
||||
Add(Format.R16G16B16A16Uscaled, new FormatInfo(4, false, true, All.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16B16A16Sscaled, new FormatInfo(4, false, true, All.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short));
|
||||
Add(Format.R32G32B32A32Uscaled, new FormatInfo(4, false, true, All.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32G32B32A32Sscaled, new FormatInfo(4, false, true, All.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int));
|
||||
Add(Format.R10G10B10A2Snorm, new FormatInfo(4, true, false, All.Rgb10A2, PixelFormat.Rgba, (PixelType)All.Int2101010Rev));
|
||||
Add(Format.R10G10B10A2Sint, new FormatInfo(4, false, false, All.Rgb10A2, PixelFormat.RgbaInteger, (PixelType)All.Int2101010Rev));
|
||||
Add(Format.R10G10B10A2Uscaled, new FormatInfo(4, false, true, All.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed));
|
||||
Add(Format.R10G10B10A2Sscaled, new FormatInfo(4, false, true, All.Rgb10A2, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed));
|
||||
Add(Format.Astc4x4Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc4X4Khr));
|
||||
Add(Format.Astc5x4Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc5X4Khr));
|
||||
Add(Format.Astc5x5Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc5X5Khr));
|
||||
Add(Format.Astc6x5Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc6X5Khr));
|
||||
Add(Format.Astc6x6Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc6X6Khr));
|
||||
Add(Format.Astc8x5Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc8X5Khr));
|
||||
Add(Format.Astc8x6Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc8X6Khr));
|
||||
Add(Format.Astc8x8Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc8X8Khr));
|
||||
Add(Format.Astc10x5Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc10X5Khr));
|
||||
Add(Format.Astc10x6Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc10X6Khr));
|
||||
Add(Format.Astc10x8Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc10X8Khr));
|
||||
Add(Format.Astc10x10Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc10X10Khr));
|
||||
Add(Format.Astc12x10Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc12X10Khr));
|
||||
Add(Format.Astc12x12Unorm, new FormatInfo(4, true, false, All.CompressedRgbaAstc12X12Khr));
|
||||
Add(Format.Astc4x4Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc4X4Khr));
|
||||
Add(Format.Astc5x4Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc5X4Khr));
|
||||
Add(Format.Astc5x5Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc5X5Khr));
|
||||
Add(Format.Astc6x5Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc6X5Khr));
|
||||
Add(Format.Astc6x6Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc6X6Khr));
|
||||
Add(Format.Astc8x5Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc8X5Khr));
|
||||
Add(Format.Astc8x6Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc8X6Khr));
|
||||
Add(Format.Astc8x8Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc8X8Khr));
|
||||
Add(Format.Astc10x5Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc10X5Khr));
|
||||
Add(Format.Astc10x6Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc10X6Khr));
|
||||
Add(Format.Astc10x8Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc10X8Khr));
|
||||
Add(Format.Astc10x10Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc10X10Khr));
|
||||
Add(Format.Astc12x10Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc12X10Khr));
|
||||
Add(Format.Astc12x12Srgb, new FormatInfo(4, false, false, All.CompressedSrgb8Alpha8Astc12X12Khr));
|
||||
Add(Format.B5G6R5Unorm, new FormatInfo(3, true, false, All.Rgb565, PixelFormat.Rgb, PixelType.UnsignedShort565Reversed));
|
||||
Add(Format.B5G5R5A1Unorm, new FormatInfo(4, true, false, All.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort1555Reversed));
|
||||
Add(Format.A1B5G5R5Unorm, new FormatInfo(4, true, false, All.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551));
|
||||
Add(Format.B8G8R8A8Unorm, new FormatInfo(4, true, false, All.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte));
|
||||
Add(Format.B8G8R8A8Srgb, new FormatInfo(4, false, false, All.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte));
|
||||
Add(Format.B10G10R10A2Unorm, new FormatInfo(4, false, false, All.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed));
|
||||
Add(Format.R8Unorm, new FormatInfo(1, true, false, InternalFormat.R8, PixelFormat.Red, PixelType.UnsignedByte));
|
||||
Add(Format.R8Snorm, new FormatInfo(1, true, false, InternalFormat.R8SNorm, PixelFormat.Red, PixelType.Byte));
|
||||
Add(Format.R8Uint, new FormatInfo(1, false, false, InternalFormat.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8Sint, new FormatInfo(1, false, false, InternalFormat.R8i, PixelFormat.RedInteger, PixelType.Byte));
|
||||
Add(Format.R16Float, new FormatInfo(1, false, false, InternalFormat.R16f, PixelFormat.Red, (PixelType)NV.HalfFloatNV));
|
||||
Add(Format.R16Unorm, new FormatInfo(1, true, false, InternalFormat.R16, PixelFormat.Red, PixelType.UnsignedShort));
|
||||
Add(Format.R16Snorm, new FormatInfo(1, true, false, InternalFormat.R16SNorm, PixelFormat.Red, PixelType.Short));
|
||||
Add(Format.R16Uint, new FormatInfo(1, false, false, InternalFormat.R16ui, PixelFormat.RedInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16Sint, new FormatInfo(1, false, false, InternalFormat.R16i, PixelFormat.RedInteger, PixelType.Short));
|
||||
Add(Format.R32Float, new FormatInfo(1, false, false, InternalFormat.R32f, PixelFormat.Red, PixelType.Float));
|
||||
Add(Format.R32Uint, new FormatInfo(1, false, false, InternalFormat.R32ui, PixelFormat.RedInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32Sint, new FormatInfo(1, false, false, InternalFormat.R32i, PixelFormat.RedInteger, PixelType.Int));
|
||||
Add(Format.R8G8Unorm, new FormatInfo(2, true, false, InternalFormat.RG8, PixelFormat.RG, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8Snorm, new FormatInfo(2, true, false, InternalFormat.RG8SNorm, PixelFormat.RG, PixelType.Byte));
|
||||
Add(Format.R8G8Uint, new FormatInfo(2, false, false, InternalFormat.RG8ui, PixelFormat.RGInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8Sint, new FormatInfo(2, false, false, InternalFormat.RG8i, PixelFormat.RGInteger, PixelType.Byte));
|
||||
Add(Format.R16G16Float, new FormatInfo(2, false, false, InternalFormat.RG16f, PixelFormat.RG, (PixelType)NV.HalfFloatNV));
|
||||
Add(Format.R16G16Unorm, new FormatInfo(2, true, false, InternalFormat.RG16, PixelFormat.RG, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16Snorm, new FormatInfo(2, true, false, InternalFormat.RG16SNorm, PixelFormat.RG, PixelType.Short));
|
||||
Add(Format.R16G16Uint, new FormatInfo(2, false, false, InternalFormat.RG16ui, PixelFormat.RGInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16Sint, new FormatInfo(2, false, false, InternalFormat.RG16i, PixelFormat.RGInteger, PixelType.Short));
|
||||
Add(Format.R32G32Float, new FormatInfo(2, false, false, InternalFormat.RG32f, PixelFormat.RG, PixelType.Float));
|
||||
Add(Format.R32G32Uint, new FormatInfo(2, false, false, InternalFormat.RG32ui, PixelFormat.RGInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32G32Sint, new FormatInfo(2, false, false, InternalFormat.RG32i, PixelFormat.RGInteger, PixelType.Int));
|
||||
Add(Format.R8G8B8Unorm, new FormatInfo(3, true, false, InternalFormat.Rgb8, PixelFormat.Rgb, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8B8Snorm, new FormatInfo(3, true, false, InternalFormat.Rgb8SNorm, PixelFormat.Rgb, PixelType.Byte));
|
||||
Add(Format.R8G8B8Uint, new FormatInfo(3, false, false, InternalFormat.Rgb8ui, PixelFormat.RgbInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8B8Sint, new FormatInfo(3, false, false, InternalFormat.Rgb8i, PixelFormat.RgbInteger, PixelType.Byte));
|
||||
Add(Format.R16G16B16Float, new FormatInfo(3, false, false, InternalFormat.Rgb16f, PixelFormat.Rgb, (PixelType)NV.HalfFloatNV));
|
||||
Add(Format.R16G16B16Unorm, new FormatInfo(3, true, false, InternalFormat.Rgb16, PixelFormat.Rgb, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16B16Snorm, new FormatInfo(3, true, false, InternalFormat.Rgb16SNorm, PixelFormat.Rgb, PixelType.Short));
|
||||
Add(Format.R16G16B16Uint, new FormatInfo(3, false, false, InternalFormat.Rgb16ui, PixelFormat.RgbInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16B16Sint, new FormatInfo(3, false, false, InternalFormat.Rgb16i, PixelFormat.RgbInteger, PixelType.Short));
|
||||
Add(Format.R32G32B32Float, new FormatInfo(3, false, false, InternalFormat.Rgb32f, PixelFormat.Rgb, PixelType.Float));
|
||||
Add(Format.R32G32B32Uint, new FormatInfo(3, false, false, InternalFormat.Rgb32ui, PixelFormat.RgbInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32G32B32Sint, new FormatInfo(3, false, false, InternalFormat.Rgb32i, PixelFormat.RgbInteger, PixelType.Int));
|
||||
Add(Format.R8G8B8A8Unorm, new FormatInfo(4, true, false, InternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8B8A8Snorm, new FormatInfo(4, true, false, InternalFormat.Rgba8SNorm, PixelFormat.Rgba, PixelType.Byte));
|
||||
Add(Format.R8G8B8A8Uint, new FormatInfo(4, false, false, InternalFormat.Rgba8ui, PixelFormat.RgbaInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8B8A8Sint, new FormatInfo(4, false, false, InternalFormat.Rgba8i, PixelFormat.RgbaInteger, PixelType.Byte));
|
||||
Add(Format.R16G16B16A16Float, new FormatInfo(4, false, false, InternalFormat.Rgba16f, PixelFormat.Rgba, (PixelType)NV.HalfFloatNV));
|
||||
Add(Format.R16G16B16A16Unorm, new FormatInfo(4, true, false, InternalFormat.Rgba16, PixelFormat.Rgba, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16B16A16Snorm, new FormatInfo(4, true, false, InternalFormat.Rgba16SNorm, PixelFormat.Rgba, PixelType.Short));
|
||||
Add(Format.R16G16B16A16Uint, new FormatInfo(4, false, false, InternalFormat.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16B16A16Sint, new FormatInfo(4, false, false, InternalFormat.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short));
|
||||
Add(Format.R32G32B32A32Float, new FormatInfo(4, false, false, InternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float));
|
||||
Add(Format.R32G32B32A32Uint, new FormatInfo(4, false, false, InternalFormat.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32G32B32A32Sint, new FormatInfo(4, false, false, InternalFormat.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int));
|
||||
Add(Format.S8Uint, new FormatInfo(1, false, false, InternalFormat.StencilIndex8, PixelFormat.StencilIndex, PixelType.UnsignedByte));
|
||||
Add(Format.D16Unorm, new FormatInfo(1, false, false, InternalFormat.DepthComponent16, PixelFormat.DepthComponent, PixelType.UnsignedShort));
|
||||
Add(Format.S8UintD24Unorm, new FormatInfo(1, false, false, InternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, (PixelType)NV.UnsignedInt248NV));
|
||||
Add(Format.X8UintD24Unorm, new FormatInfo(1, false, false, InternalFormat.DepthComponent24, PixelFormat.DepthComponent, PixelType.UnsignedInt));
|
||||
Add(Format.D32Float, new FormatInfo(1, false, false, InternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float));
|
||||
Add(Format.D24UnormS8Uint, new FormatInfo(1, false, false, InternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, (PixelType)NV.UnsignedInt248NV));
|
||||
Add(Format.D32FloatS8Uint, new FormatInfo(1, false, false, InternalFormat.Depth32fStencil8, PixelFormat.DepthStencil, (PixelType)NV.Float32UnsignedInt248RevNV));
|
||||
Add(Format.R8G8B8A8Srgb, new FormatInfo(4, false, false, InternalFormat.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte));
|
||||
Add(Format.R4G4B4A4Unorm, new FormatInfo(4, true, false, InternalFormat.Rgba4, PixelFormat.Rgba, PixelType.UnsignedShort4444Rev));
|
||||
Add(Format.R5G5B5X1Unorm, new FormatInfo(4, true, false, InternalFormat.Rgb5, PixelFormat.Rgb, PixelType.UnsignedShort1555Rev));
|
||||
Add(Format.R5G5B5A1Unorm, new FormatInfo(4, true, false, InternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort1555Rev));
|
||||
Add(Format.R5G6B5Unorm, new FormatInfo(3, true, false, InternalFormat.Rgb565, PixelFormat.Rgb, PixelType.UnsignedShort565Rev));
|
||||
Add(Format.R10G10B10A2Unorm, new FormatInfo(4, true, false, InternalFormat.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Rev));
|
||||
Add(Format.R10G10B10A2Uint, new FormatInfo(4, false, false, InternalFormat.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Rev));
|
||||
Add(Format.R11G11B10Float, new FormatInfo(3, false, false, InternalFormat.R11fG11fB10f, PixelFormat.Rgb, (PixelType)0x8C3B)); // GL_UNSIGNED_INT_10F_11F_11F_REV Defined in Updated Silk.NET
|
||||
Add(Format.R9G9B9E5Float, new FormatInfo(3, false, false, InternalFormat.Rgb9E5, PixelFormat.Rgb, (PixelType)0x8C3E)); // GL_UNSIGNED_INT_5_9_9_9_REV Defined in Updated Silk.NET
|
||||
Add(Format.Bc1RgbaUnorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaS3TCDxt1Ext));
|
||||
Add(Format.Bc2Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaS3TCDxt3Ext));
|
||||
Add(Format.Bc3Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaS3TCDxt5Ext));
|
||||
Add(Format.Bc1RgbaSrgb, new FormatInfo(4, true, false, InternalFormat.CompressedSrgbAlphaS3TCDxt1Ext));
|
||||
Add(Format.Bc2Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgbAlphaS3TCDxt3Ext));
|
||||
Add(Format.Bc3Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgbAlphaS3TCDxt5Ext));
|
||||
Add(Format.Bc4Unorm, new FormatInfo(1, true, false, InternalFormat.CompressedRedRgtc1));
|
||||
Add(Format.Bc4Snorm, new FormatInfo(1, true, false, InternalFormat.CompressedSignedRedRgtc1));
|
||||
Add(Format.Bc5Unorm, new FormatInfo(2, true, false, InternalFormat.CompressedRGRgtc2));
|
||||
Add(Format.Bc5Snorm, new FormatInfo(2, true, false, InternalFormat.CompressedSignedRGRgtc2));
|
||||
Add(Format.Bc7Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaBptcUnorm));
|
||||
Add(Format.Bc7Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgbAlphaBptcUnorm));
|
||||
Add(Format.Bc6HSfloat, new FormatInfo(4, false, false, InternalFormat.CompressedRgbBptcSignedFloat));
|
||||
Add(Format.Bc6HUfloat, new FormatInfo(4, false, false, InternalFormat.CompressedRgbBptcUnsignedFloat));
|
||||
Add(Format.Etc2RgbUnorm, new FormatInfo(4, false, false, InternalFormat.CompressedRgb8Etc2));
|
||||
Add(Format.Etc2RgbaUnorm, new FormatInfo(4, false, false, InternalFormat.CompressedRgba8Etc2Eac));
|
||||
Add(Format.Etc2RgbPtaUnorm, new FormatInfo(4, false, false, InternalFormat.CompressedRgb8PunchthroughAlpha1Etc2));
|
||||
Add(Format.Etc2RgbSrgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Etc2));
|
||||
Add(Format.Etc2RgbaSrgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Etc2Eac));
|
||||
Add(Format.Etc2RgbPtaSrgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8PunchthroughAlpha1Etc2));
|
||||
Add(Format.R8Uscaled, new FormatInfo(1, false, true, InternalFormat.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8Sscaled, new FormatInfo(1, false, true, InternalFormat.R8i, PixelFormat.RedInteger, PixelType.Byte));
|
||||
Add(Format.R16Uscaled, new FormatInfo(1, false, true, InternalFormat.R16ui, PixelFormat.RedInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16Sscaled, new FormatInfo(1, false, true, InternalFormat.R16i, PixelFormat.RedInteger, PixelType.Short));
|
||||
Add(Format.R32Uscaled, new FormatInfo(1, false, true, InternalFormat.R32ui, PixelFormat.RedInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32Sscaled, new FormatInfo(1, false, true, InternalFormat.R32i, PixelFormat.RedInteger, PixelType.Int));
|
||||
Add(Format.R8G8Uscaled, new FormatInfo(2, false, true, InternalFormat.RG8ui, PixelFormat.RGInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8Sscaled, new FormatInfo(2, false, true, InternalFormat.RG8i, PixelFormat.RGInteger, PixelType.Byte));
|
||||
Add(Format.R16G16Uscaled, new FormatInfo(2, false, true, InternalFormat.RG16ui, PixelFormat.RGInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16Sscaled, new FormatInfo(2, false, true, InternalFormat.RG16i, PixelFormat.RGInteger, PixelType.Short));
|
||||
Add(Format.R32G32Uscaled, new FormatInfo(2, false, true, InternalFormat.RG32ui, PixelFormat.RGInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32G32Sscaled, new FormatInfo(2, false, true, InternalFormat.RG32i, PixelFormat.RGInteger, PixelType.Int));
|
||||
Add(Format.R8G8B8Uscaled, new FormatInfo(3, false, true, InternalFormat.Rgb8ui, PixelFormat.RgbInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8B8Sscaled, new FormatInfo(3, false, true, InternalFormat.Rgb8i, PixelFormat.RgbInteger, PixelType.Byte));
|
||||
Add(Format.R16G16B16Uscaled, new FormatInfo(3, false, true, InternalFormat.Rgb16ui, PixelFormat.RgbInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16B16Sscaled, new FormatInfo(3, false, true, InternalFormat.Rgb16i, PixelFormat.RgbInteger, PixelType.Short));
|
||||
Add(Format.R32G32B32Uscaled, new FormatInfo(3, false, true, InternalFormat.Rgb32ui, PixelFormat.RgbInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32G32B32Sscaled, new FormatInfo(3, false, true, InternalFormat.Rgb32i, PixelFormat.RgbInteger, PixelType.Int));
|
||||
Add(Format.R8G8B8A8Uscaled, new FormatInfo(4, false, true, InternalFormat.Rgba8ui, PixelFormat.RgbaInteger, PixelType.UnsignedByte));
|
||||
Add(Format.R8G8B8A8Sscaled, new FormatInfo(4, false, true, InternalFormat.Rgba8i, PixelFormat.RgbaInteger, PixelType.Byte));
|
||||
Add(Format.R16G16B16A16Uscaled, new FormatInfo(4, false, true, InternalFormat.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort));
|
||||
Add(Format.R16G16B16A16Sscaled, new FormatInfo(4, false, true, InternalFormat.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short));
|
||||
Add(Format.R32G32B32A32Uscaled, new FormatInfo(4, false, true, InternalFormat.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt));
|
||||
Add(Format.R32G32B32A32Sscaled, new FormatInfo(4, false, true, InternalFormat.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int));
|
||||
Add(Format.R10G10B10A2Snorm, new FormatInfo(4, true, false, InternalFormat.Rgb10A2, PixelFormat.Rgba, (PixelType)GLEnum.Int2101010Rev));
|
||||
Add(Format.R10G10B10A2Sint, new FormatInfo(4, false, false, InternalFormat.Rgb10A2, PixelFormat.RgbaInteger, (PixelType)GLEnum.Int2101010Rev));
|
||||
Add(Format.R10G10B10A2Uscaled, new FormatInfo(4, false, true, InternalFormat.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Rev));
|
||||
Add(Format.R10G10B10A2Sscaled, new FormatInfo(4, false, true, InternalFormat.Rgb10A2, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Rev));
|
||||
Add(Format.Astc4x4Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc4x4Khr));
|
||||
Add(Format.Astc5x4Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc5x4Khr));
|
||||
Add(Format.Astc5x5Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc5x5Khr));
|
||||
Add(Format.Astc6x5Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc6x5Khr));
|
||||
Add(Format.Astc6x6Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc6x6Khr));
|
||||
Add(Format.Astc8x5Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc8x5Khr));
|
||||
Add(Format.Astc8x6Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc8x6Khr));
|
||||
Add(Format.Astc8x8Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc8x8Khr));
|
||||
Add(Format.Astc10x5Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc10x5Khr));
|
||||
Add(Format.Astc10x6Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc10x6Khr));
|
||||
Add(Format.Astc10x8Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc10x8Khr));
|
||||
Add(Format.Astc10x10Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc10x10Khr));
|
||||
Add(Format.Astc12x10Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc12x10Khr));
|
||||
Add(Format.Astc12x12Unorm, new FormatInfo(4, true, false, InternalFormat.CompressedRgbaAstc12x12Khr));
|
||||
Add(Format.Astc4x4Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc4x4Khr));
|
||||
Add(Format.Astc5x4Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc5x4Khr));
|
||||
Add(Format.Astc5x5Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc5x5Khr));
|
||||
Add(Format.Astc6x5Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc6x5Khr));
|
||||
Add(Format.Astc6x6Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc6x6Khr));
|
||||
Add(Format.Astc8x5Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc8x5Khr));
|
||||
Add(Format.Astc8x6Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc8x6Khr));
|
||||
Add(Format.Astc8x8Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc8x8Khr));
|
||||
Add(Format.Astc10x5Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc10x5Khr));
|
||||
Add(Format.Astc10x6Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc10x6Khr));
|
||||
Add(Format.Astc10x8Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc10x8Khr));
|
||||
Add(Format.Astc10x10Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc10x10Khr));
|
||||
Add(Format.Astc12x10Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc12x10Khr));
|
||||
Add(Format.Astc12x12Srgb, new FormatInfo(4, false, false, InternalFormat.CompressedSrgb8Alpha8Astc12x12Khr));
|
||||
Add(Format.B5G6R5Unorm, new FormatInfo(3, true, false, InternalFormat.Rgb565, PixelFormat.Rgb, PixelType.UnsignedShort565Rev));
|
||||
Add(Format.B5G5R5A1Unorm, new FormatInfo(4, true, false, InternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort1555Rev));
|
||||
Add(Format.A1B5G5R5Unorm, new FormatInfo(4, true, false, InternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort5551));
|
||||
Add(Format.B8G8R8A8Unorm, new FormatInfo(4, true, false, InternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte));
|
||||
Add(Format.B8G8R8A8Srgb, new FormatInfo(4, false, false, InternalFormat.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte));
|
||||
Add(Format.B10G10R10A2Unorm, new FormatInfo(4, false, false, InternalFormat.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Rev));
|
||||
|
||||
Add(Format.R8Unorm, SizedInternalFormat.R8);
|
||||
Add(Format.R8Uint, SizedInternalFormat.R8ui);
|
||||
Add(Format.R8Sint, SizedInternalFormat.R8i);
|
||||
Add(Format.R16Float, SizedInternalFormat.R16f);
|
||||
Add(Format.R16Unorm, SizedInternalFormat.R16);
|
||||
Add(Format.R16Snorm, (SizedInternalFormat)All.R16Snorm);
|
||||
Add(Format.R16Snorm, SizedInternalFormat.R16SNorm);
|
||||
Add(Format.R16Uint, SizedInternalFormat.R16ui);
|
||||
Add(Format.R16Sint, SizedInternalFormat.R16i);
|
||||
Add(Format.R32Float, SizedInternalFormat.R32f);
|
||||
Add(Format.R32Uint, SizedInternalFormat.R32ui);
|
||||
Add(Format.R32Sint, SizedInternalFormat.R32i);
|
||||
Add(Format.R8G8Unorm, SizedInternalFormat.Rg8);
|
||||
Add(Format.R8G8Snorm, (SizedInternalFormat)All.Rg8Snorm);
|
||||
Add(Format.R8G8Uint, SizedInternalFormat.Rg8ui);
|
||||
Add(Format.R8G8Sint, SizedInternalFormat.Rg8i);
|
||||
Add(Format.R16G16Float, SizedInternalFormat.Rg16f);
|
||||
Add(Format.R16G16Unorm, SizedInternalFormat.Rg16);
|
||||
Add(Format.R16G16Snorm, (SizedInternalFormat)All.Rg16Snorm);
|
||||
Add(Format.R16G16Uint, SizedInternalFormat.Rg16ui);
|
||||
Add(Format.R16G16Sint, SizedInternalFormat.Rg16i);
|
||||
Add(Format.R32G32Float, SizedInternalFormat.Rg32f);
|
||||
Add(Format.R32G32Uint, SizedInternalFormat.Rg32ui);
|
||||
Add(Format.R32G32Sint, SizedInternalFormat.Rg32i);
|
||||
Add(Format.R8G8Unorm, SizedInternalFormat.RG8);
|
||||
Add(Format.R8G8Snorm, SizedInternalFormat.RG8SNorm);
|
||||
Add(Format.R8G8Uint, SizedInternalFormat.RG8ui);
|
||||
Add(Format.R8G8Sint, SizedInternalFormat.RG8i);
|
||||
Add(Format.R16G16Float, SizedInternalFormat.RG16f);
|
||||
Add(Format.R16G16Unorm, SizedInternalFormat.RG16);
|
||||
Add(Format.R16G16Snorm, SizedInternalFormat.RG16SNorm);
|
||||
Add(Format.R16G16Uint, SizedInternalFormat.RG16ui);
|
||||
Add(Format.R16G16Sint, SizedInternalFormat.RG16i);
|
||||
Add(Format.R32G32Float, SizedInternalFormat.RG32f);
|
||||
Add(Format.R32G32Uint, SizedInternalFormat.RG32ui);
|
||||
Add(Format.R32G32Sint, SizedInternalFormat.RG32i);
|
||||
Add(Format.R8G8B8A8Unorm, SizedInternalFormat.Rgba8);
|
||||
Add(Format.R8G8B8A8Snorm, (SizedInternalFormat)All.Rgba8Snorm);
|
||||
Add(Format.R8G8B8A8Snorm, SizedInternalFormat.Rgba8SNorm);
|
||||
Add(Format.R8G8B8A8Uint, SizedInternalFormat.Rgba8ui);
|
||||
Add(Format.R8G8B8A8Sint, SizedInternalFormat.Rgba8i);
|
||||
Add(Format.R16G16B16A16Float, SizedInternalFormat.Rgba16f);
|
||||
Add(Format.R16G16B16A16Unorm, SizedInternalFormat.Rgba16);
|
||||
Add(Format.R16G16B16A16Snorm, (SizedInternalFormat)All.Rgba16Snorm);
|
||||
Add(Format.R16G16B16A16Snorm, SizedInternalFormat.Rgba16SNorm);
|
||||
Add(Format.R16G16B16A16Uint, SizedInternalFormat.Rgba16ui);
|
||||
Add(Format.R16G16B16A16Sint, SizedInternalFormat.Rgba16i);
|
||||
Add(Format.R32G32B32A32Float, SizedInternalFormat.Rgba32f);
|
||||
Add(Format.R32G32B32A32Uint, SizedInternalFormat.Rgba32ui);
|
||||
Add(Format.R32G32B32A32Sint, SizedInternalFormat.Rgba32i);
|
||||
Add(Format.R8G8B8A8Srgb, SizedInternalFormat.Rgba8);
|
||||
Add(Format.R10G10B10A2Unorm, (SizedInternalFormat)All.Rgb10A2);
|
||||
Add(Format.R10G10B10A2Uint, (SizedInternalFormat)All.Rgb10A2ui);
|
||||
Add(Format.R11G11B10Float, (SizedInternalFormat)All.R11fG11fB10f);
|
||||
Add(Format.R10G10B10A2Unorm, SizedInternalFormat.Rgb10A2);
|
||||
Add(Format.R10G10B10A2Uint, SizedInternalFormat.Rgb10A2ui);
|
||||
Add(Format.R11G11B10Float, SizedInternalFormat.R11fG11fB10f);
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.OpenGL.Image;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using Silk.NET.OpenGL.Legacy.Extensions.NV;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
|
@ -8,8 +9,8 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
class Framebuffer : IDisposable
|
||||
{
|
||||
public int Handle { get; private set; }
|
||||
private int _clearFbHandle;
|
||||
public uint Handle { get; private set; }
|
||||
private uint _clearFbHandle;
|
||||
private bool _clearFbInitialized;
|
||||
|
||||
private FramebufferAttachment _lastDsAttachment;
|
||||
|
@ -19,18 +20,21 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
private int _colorsCount;
|
||||
private bool _dualSourceBlend;
|
||||
private readonly GL _api;
|
||||
|
||||
public Framebuffer()
|
||||
public Framebuffer(GL api)
|
||||
{
|
||||
Handle = GL.GenFramebuffer();
|
||||
_clearFbHandle = GL.GenFramebuffer();
|
||||
_api = api;
|
||||
|
||||
Handle = _api.GenFramebuffer();
|
||||
_clearFbHandle = _api.GenFramebuffer();
|
||||
|
||||
_colors = new TextureView[8];
|
||||
}
|
||||
|
||||
public int Bind()
|
||||
public uint Bind()
|
||||
{
|
||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, Handle);
|
||||
_api.BindFramebuffer(FramebufferTarget.Framebuffer, Handle);
|
||||
return Handle;
|
||||
}
|
||||
|
||||
|
@ -44,7 +48,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -54,14 +58,14 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
// Detach the last depth/stencil buffer if there is any.
|
||||
if (_lastDsAttachment != 0)
|
||||
{
|
||||
GL.FramebufferTexture(FramebufferTarget.Framebuffer, _lastDsAttachment, 0, 0);
|
||||
_api.FramebufferTexture(FramebufferTarget.Framebuffer, _lastDsAttachment, 0, 0);
|
||||
}
|
||||
|
||||
if (depthStencil != null)
|
||||
{
|
||||
FramebufferAttachment attachment = GetAttachment(depthStencil.Format);
|
||||
|
||||
GL.FramebufferTexture(
|
||||
_api.FramebufferTexture(
|
||||
FramebufferTarget.Framebuffer,
|
||||
attachment,
|
||||
depthStencil.Handle,
|
||||
|
@ -87,11 +91,11 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
// we can only have one draw buffer.
|
||||
if (enable)
|
||||
{
|
||||
GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
|
||||
_api.DrawBuffer(DrawBufferMode.ColorAttachment0);
|
||||
}
|
||||
else if (oldEnable)
|
||||
{
|
||||
SetDrawBuffersImpl(_colorsCount);
|
||||
SetDrawBuffersImpl(_api, _colorsCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,22 +103,22 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
if (_colorsCount != colorsCount && !_dualSourceBlend)
|
||||
{
|
||||
SetDrawBuffersImpl(colorsCount);
|
||||
SetDrawBuffersImpl(_api, colorsCount);
|
||||
}
|
||||
|
||||
_colorsCount = colorsCount;
|
||||
}
|
||||
|
||||
private static void SetDrawBuffersImpl(int colorsCount)
|
||||
private static void SetDrawBuffersImpl(GL api, int colorsCount)
|
||||
{
|
||||
DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[colorsCount];
|
||||
DrawBufferMode[] drawBuffers = new DrawBufferMode[colorsCount];
|
||||
|
||||
for (int index = 0; index < colorsCount; index++)
|
||||
{
|
||||
drawBuffers[index] = DrawBuffersEnum.ColorAttachment0 + index;
|
||||
drawBuffers[index] = DrawBufferMode.ColorAttachment0 + index;
|
||||
}
|
||||
|
||||
GL.DrawBuffers(colorsCount, drawBuffers);
|
||||
api.DrawBuffers((uint)colorsCount, drawBuffers);
|
||||
}
|
||||
|
||||
private static FramebufferAttachment GetAttachment(Format format)
|
||||
|
@ -123,14 +127,13 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
return FramebufferAttachment.DepthStencilAttachment;
|
||||
}
|
||||
else if (FormatTable.IsDepthOnly(format))
|
||||
|
||||
if (FormatTable.IsDepthOnly(format))
|
||||
{
|
||||
return FramebufferAttachment.DepthAttachment;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FramebufferAttachment.StencilAttachment;
|
||||
}
|
||||
|
||||
return FramebufferAttachment.StencilAttachment;
|
||||
}
|
||||
|
||||
public int GetColorLayerCount(int index)
|
||||
|
@ -153,7 +156,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
}
|
||||
|
||||
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)
|
||||
|
@ -165,7 +168,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
return;
|
||||
}
|
||||
|
||||
GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + index, 0, 0);
|
||||
_api.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + index, 0, 0);
|
||||
Bind();
|
||||
}
|
||||
|
||||
|
@ -179,7 +182,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
}
|
||||
|
||||
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()
|
||||
|
@ -191,17 +194,17 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
return;
|
||||
}
|
||||
|
||||
GL.FramebufferTexture(FramebufferTarget.Framebuffer, GetAttachment(depthStencil.Format), 0, 0);
|
||||
_api.FramebufferTexture(FramebufferTarget.Framebuffer, GetAttachment(depthStencil.Format), 0, 0);
|
||||
Bind();
|
||||
}
|
||||
|
||||
private void BindClearFb()
|
||||
{
|
||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, _clearFbHandle);
|
||||
_api.BindFramebuffer(FramebufferTarget.Framebuffer, _clearFbHandle);
|
||||
|
||||
if (!_clearFbInitialized)
|
||||
{
|
||||
SetDrawBuffersImpl(Constants.MaxRenderTargets);
|
||||
SetDrawBuffersImpl(_api, Constants.MaxRenderTargets);
|
||||
_clearFbInitialized = true;
|
||||
}
|
||||
}
|
||||
|
@ -219,14 +222,14 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
if (Handle != 0)
|
||||
{
|
||||
GL.DeleteFramebuffer(Handle);
|
||||
_api.DeleteFramebuffer(Handle);
|
||||
|
||||
Handle = 0;
|
||||
}
|
||||
|
||||
if (_clearFbHandle != 0)
|
||||
{
|
||||
GL.DeleteFramebuffer(_clearFbHandle);
|
||||
_api.DeleteFramebuffer(_clearFbHandle);
|
||||
|
||||
_clearFbHandle = 0;
|
||||
}
|
||||
|
|
|
@ -6,18 +6,18 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
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));
|
||||
|
||||
ulong handle64 = (uint)handle;
|
||||
ulong handle64 = handle;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
163
src/Ryujinx.Graphics.OpenGL/HardwareCapabilities.cs
Normal file
163
src/Ryujinx.Graphics.OpenGL/HardwareCapabilities.cs
Normal file
|
@ -0,0 +1,163 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
{
|
||||
public enum GpuVendor
|
||||
{
|
||||
Unknown,
|
||||
AmdWindows,
|
||||
AmdUnix,
|
||||
IntelWindows,
|
||||
IntelUnix,
|
||||
Nvidia,
|
||||
}
|
||||
|
||||
readonly struct HardwareCapabilities
|
||||
{
|
||||
public readonly bool SupportsAlphaToCoverageDitherControl;
|
||||
public readonly bool SupportsAstcCompression;
|
||||
public readonly bool SupportsBlendEquationAdvanced;
|
||||
public readonly bool SupportsDrawTexture;
|
||||
public readonly bool SupportsFragmentShaderInterlock;
|
||||
public readonly bool SupportsFragmentShaderOrdering;
|
||||
public readonly bool SupportsGeometryShaderPassthrough;
|
||||
public readonly bool SupportsImageLoadFormatted;
|
||||
public readonly bool SupportsIndirectParameters;
|
||||
public readonly bool SupportsParallelShaderCompile;
|
||||
public readonly bool SupportsPolygonOffsetClamp;
|
||||
public readonly bool SupportsQuads;
|
||||
public readonly bool SupportsSeamlessCubemapPerTexture;
|
||||
public readonly bool SupportsShaderBallot;
|
||||
public readonly bool SupportsShaderViewportLayerArray;
|
||||
public readonly bool SupportsViewportArray2;
|
||||
public readonly bool SupportsTextureCompressionBptc;
|
||||
public readonly bool SupportsTextureCompressionRgtc;
|
||||
public readonly bool SupportsTextureCompressionS3tc;
|
||||
public readonly bool SupportsTextureShadowLod;
|
||||
public readonly bool SupportsViewportSwizzle;
|
||||
|
||||
public bool SupportsMismatchingViewFormat => GpuVendor != GpuVendor.AmdWindows && GpuVendor != GpuVendor.IntelWindows;
|
||||
public bool SupportsNonConstantTextureOffset => GpuVendor == GpuVendor.Nvidia;
|
||||
public bool RequiresSyncFlush => GpuVendor == GpuVendor.AmdWindows || IsIntel;
|
||||
public bool UsePersistentBufferForFlush => GpuVendor == GpuVendor.AmdWindows || GpuVendor == GpuVendor.Nvidia;
|
||||
|
||||
public readonly int MaximumComputeSharedMemorySize;
|
||||
public readonly int StorageBufferOffsetAlignment;
|
||||
public readonly int TextureBufferOffsetAlignment;
|
||||
|
||||
public readonly float MaximumSupportedAnisotropy;
|
||||
|
||||
public readonly GpuVendor GpuVendor;
|
||||
|
||||
public HardwareCapabilities(
|
||||
bool supportsAlphaToCoverageDitherControl,
|
||||
bool supportsAstcCompression,
|
||||
bool supportsBlendEquationAdvanced,
|
||||
bool supportsDrawTexture,
|
||||
bool supportsFragmentShaderInterlock,
|
||||
bool supportsFragmentShaderOrdering,
|
||||
bool supportsGeometryShaderPassthrough,
|
||||
bool supportsImageLoadFormatted,
|
||||
bool supportsIndirectParameters,
|
||||
bool supportsParallelShaderCompile,
|
||||
bool supportsPolygonOffsetClamp,
|
||||
bool supportsQuads,
|
||||
bool supportsSeamlessCubemapPerTexture,
|
||||
bool supportsShaderBallot,
|
||||
bool supportsShaderViewportLayerArray,
|
||||
bool supportsViewportArray2,
|
||||
bool supportsTextureCompressionBptc,
|
||||
bool supportsTextureCompressionRgtc,
|
||||
bool supportsTextureCompressionS3Tc,
|
||||
bool supportsTextureShadowLod,
|
||||
bool supportsViewportSwizzle,
|
||||
int maximumComputeSharedMemorySize,
|
||||
int storageBufferOffsetAlignment,
|
||||
int textureBufferOffsetAlignment,
|
||||
float maximumSupportedAnisotropy,
|
||||
GpuVendor gpuVendor)
|
||||
{
|
||||
SupportsAlphaToCoverageDitherControl = supportsAlphaToCoverageDitherControl;
|
||||
SupportsAstcCompression = supportsAstcCompression;
|
||||
SupportsBlendEquationAdvanced = supportsBlendEquationAdvanced;
|
||||
SupportsDrawTexture = supportsDrawTexture;
|
||||
SupportsFragmentShaderInterlock = supportsFragmentShaderInterlock;
|
||||
SupportsFragmentShaderOrdering = supportsFragmentShaderOrdering;
|
||||
SupportsGeometryShaderPassthrough = supportsGeometryShaderPassthrough;
|
||||
SupportsImageLoadFormatted = supportsImageLoadFormatted;
|
||||
SupportsIndirectParameters = supportsIndirectParameters;
|
||||
SupportsParallelShaderCompile = supportsParallelShaderCompile;
|
||||
SupportsPolygonOffsetClamp = supportsPolygonOffsetClamp;
|
||||
SupportsQuads = supportsQuads;
|
||||
SupportsSeamlessCubemapPerTexture = supportsSeamlessCubemapPerTexture;
|
||||
SupportsShaderBallot = supportsShaderBallot;
|
||||
SupportsShaderViewportLayerArray = supportsShaderViewportLayerArray;
|
||||
SupportsViewportArray2 = supportsViewportArray2;
|
||||
SupportsTextureCompressionBptc = supportsTextureCompressionBptc;
|
||||
SupportsTextureCompressionRgtc = supportsTextureCompressionRgtc;
|
||||
SupportsTextureCompressionS3tc = supportsTextureCompressionS3Tc;
|
||||
SupportsTextureShadowLod = supportsTextureShadowLod;
|
||||
SupportsViewportSwizzle = supportsViewportSwizzle;
|
||||
MaximumComputeSharedMemorySize = maximumComputeSharedMemorySize;
|
||||
StorageBufferOffsetAlignment = storageBufferOffsetAlignment;
|
||||
TextureBufferOffsetAlignment = textureBufferOffsetAlignment;
|
||||
MaximumSupportedAnisotropy = maximumSupportedAnisotropy;
|
||||
GpuVendor = gpuVendor;
|
||||
}
|
||||
|
||||
public bool IsIntel => GpuVendor == GpuVendor.IntelWindows || GpuVendor == GpuVendor.IntelUnix;
|
||||
|
||||
public static unsafe bool HasExtension(GL api, string name)
|
||||
{
|
||||
int numExtensions = api.GetInteger(GLEnum.NumExtensions);
|
||||
|
||||
for (uint extension = 0; extension < numExtensions; extension++)
|
||||
{
|
||||
if (Marshal.PtrToStringAnsi((IntPtr)api.GetString(StringName.Extensions, extension)) == name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static unsafe GpuVendor GetGpuVendor(GL api)
|
||||
{
|
||||
string vendor = Marshal.PtrToStringAnsi((IntPtr)api.GetString(StringName.Vendor)).ToLowerInvariant();
|
||||
|
||||
switch (vendor)
|
||||
{
|
||||
case "nvidia corporation":
|
||||
return GpuVendor.Nvidia;
|
||||
case "intel":
|
||||
{
|
||||
string renderer = Marshal.PtrToStringAnsi((IntPtr)api.GetString(StringName.Renderer)).ToLowerInvariant();
|
||||
|
||||
return renderer.Contains("mesa") ? GpuVendor.IntelUnix : GpuVendor.IntelWindows;
|
||||
}
|
||||
case "ati technologies inc.":
|
||||
case "advanced micro devices, inc.":
|
||||
return GpuVendor.AmdWindows;
|
||||
case "amd":
|
||||
case "x.org":
|
||||
return GpuVendor.AmdUnix;
|
||||
default:
|
||||
return GpuVendor.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool SupportsQuadsCheck(GL api)
|
||||
{
|
||||
api.GetError(); // Clear any existing error.
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
api.Begin(PrimitiveType.Quads);
|
||||
api.End();
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
return api.GetError() == GLEnum.NoError;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
{
|
||||
static class HwCapabilities
|
||||
{
|
||||
private static readonly Lazy<bool> _supportsAlphaToCoverageDitherControl = new(() => HasExtension("GL_NV_alpha_to_coverage_dither_control"));
|
||||
private static readonly Lazy<bool> _supportsAstcCompression = new(() => HasExtension("GL_KHR_texture_compression_astc_ldr"));
|
||||
private static readonly Lazy<bool> _supportsBlendEquationAdvanced = new(() => HasExtension("GL_NV_blend_equation_advanced"));
|
||||
private static readonly Lazy<bool> _supportsDrawTexture = new(() => HasExtension("GL_NV_draw_texture"));
|
||||
private static readonly Lazy<bool> _supportsFragmentShaderInterlock = new(() => HasExtension("GL_ARB_fragment_shader_interlock"));
|
||||
private static readonly Lazy<bool> _supportsFragmentShaderOrdering = new(() => HasExtension("GL_INTEL_fragment_shader_ordering"));
|
||||
private static readonly Lazy<bool> _supportsGeometryShaderPassthrough = new(() => HasExtension("GL_NV_geometry_shader_passthrough"));
|
||||
private static readonly Lazy<bool> _supportsImageLoadFormatted = new(() => HasExtension("GL_EXT_shader_image_load_formatted"));
|
||||
private static readonly Lazy<bool> _supportsIndirectParameters = new(() => HasExtension("GL_ARB_indirect_parameters"));
|
||||
private static readonly Lazy<bool> _supportsParallelShaderCompile = new(() => HasExtension("GL_ARB_parallel_shader_compile"));
|
||||
private static readonly Lazy<bool> _supportsPolygonOffsetClamp = new(() => HasExtension("GL_EXT_polygon_offset_clamp"));
|
||||
private static readonly Lazy<bool> _supportsQuads = new(SupportsQuadsCheck);
|
||||
private static readonly Lazy<bool> _supportsSeamlessCubemapPerTexture = new(() => HasExtension("GL_ARB_seamless_cubemap_per_texture"));
|
||||
private static readonly Lazy<bool> _supportsShaderBallot = new(() => HasExtension("GL_ARB_shader_ballot"));
|
||||
private static readonly Lazy<bool> _supportsShaderViewportLayerArray = new(() => HasExtension("GL_ARB_shader_viewport_layer_array"));
|
||||
private static readonly Lazy<bool> _supportsViewportArray2 = new(() => HasExtension("GL_NV_viewport_array2"));
|
||||
private static readonly Lazy<bool> _supportsTextureCompressionBptc = new(() => HasExtension("GL_EXT_texture_compression_bptc"));
|
||||
private static readonly Lazy<bool> _supportsTextureCompressionRgtc = new(() => HasExtension("GL_EXT_texture_compression_rgtc"));
|
||||
private static readonly Lazy<bool> _supportsTextureCompressionS3tc = new(() => HasExtension("GL_EXT_texture_compression_s3tc"));
|
||||
private static readonly Lazy<bool> _supportsTextureShadowLod = new(() => HasExtension("GL_EXT_texture_shadow_lod"));
|
||||
private static readonly Lazy<bool> _supportsViewportSwizzle = new(() => HasExtension("GL_NV_viewport_swizzle"));
|
||||
|
||||
private static readonly Lazy<int> _maximumComputeSharedMemorySize = new(() => GetLimit(All.MaxComputeSharedMemorySize));
|
||||
private static readonly Lazy<int> _storageBufferOffsetAlignment = new(() => GetLimit(All.ShaderStorageBufferOffsetAlignment));
|
||||
private static readonly Lazy<int> _textureBufferOffsetAlignment = new(() => GetLimit(All.TextureBufferOffsetAlignment));
|
||||
|
||||
public enum GpuVendor
|
||||
{
|
||||
Unknown,
|
||||
AmdWindows,
|
||||
AmdUnix,
|
||||
IntelWindows,
|
||||
IntelUnix,
|
||||
Nvidia,
|
||||
}
|
||||
|
||||
private static readonly Lazy<GpuVendor> _gpuVendor = new(GetGpuVendor);
|
||||
|
||||
private static bool IsIntel => _gpuVendor.Value == GpuVendor.IntelWindows || _gpuVendor.Value == GpuVendor.IntelUnix;
|
||||
|
||||
public static GpuVendor Vendor => _gpuVendor.Value;
|
||||
|
||||
private static readonly Lazy<float> _maxSupportedAnisotropy = new(GL.GetFloat((GetPName)All.MaxTextureMaxAnisotropy));
|
||||
|
||||
public static bool UsePersistentBufferForFlush => _gpuVendor.Value == GpuVendor.AmdWindows || _gpuVendor.Value == GpuVendor.Nvidia;
|
||||
|
||||
public static bool SupportsAlphaToCoverageDitherControl => _supportsAlphaToCoverageDitherControl.Value;
|
||||
public static bool SupportsAstcCompression => _supportsAstcCompression.Value;
|
||||
public static bool SupportsBlendEquationAdvanced => _supportsBlendEquationAdvanced.Value;
|
||||
public static bool SupportsDrawTexture => _supportsDrawTexture.Value;
|
||||
public static bool SupportsFragmentShaderInterlock => _supportsFragmentShaderInterlock.Value;
|
||||
public static bool SupportsFragmentShaderOrdering => _supportsFragmentShaderOrdering.Value;
|
||||
public static bool SupportsGeometryShaderPassthrough => _supportsGeometryShaderPassthrough.Value;
|
||||
public static bool SupportsImageLoadFormatted => _supportsImageLoadFormatted.Value;
|
||||
public static bool SupportsIndirectParameters => _supportsIndirectParameters.Value;
|
||||
public static bool SupportsParallelShaderCompile => _supportsParallelShaderCompile.Value;
|
||||
public static bool SupportsPolygonOffsetClamp => _supportsPolygonOffsetClamp.Value;
|
||||
public static bool SupportsQuads => _supportsQuads.Value;
|
||||
public static bool SupportsSeamlessCubemapPerTexture => _supportsSeamlessCubemapPerTexture.Value;
|
||||
public static bool SupportsShaderBallot => _supportsShaderBallot.Value;
|
||||
public static bool SupportsShaderViewportLayerArray => _supportsShaderViewportLayerArray.Value;
|
||||
public static bool SupportsViewportArray2 => _supportsViewportArray2.Value;
|
||||
public static bool SupportsTextureCompressionBptc => _supportsTextureCompressionBptc.Value;
|
||||
public static bool SupportsTextureCompressionRgtc => _supportsTextureCompressionRgtc.Value;
|
||||
public static bool SupportsTextureCompressionS3tc => _supportsTextureCompressionS3tc.Value;
|
||||
public static bool SupportsTextureShadowLod => _supportsTextureShadowLod.Value;
|
||||
public static bool SupportsViewportSwizzle => _supportsViewportSwizzle.Value;
|
||||
|
||||
public static bool SupportsMismatchingViewFormat => _gpuVendor.Value != GpuVendor.AmdWindows && _gpuVendor.Value != GpuVendor.IntelWindows;
|
||||
public static bool SupportsNonConstantTextureOffset => _gpuVendor.Value == GpuVendor.Nvidia;
|
||||
public static bool RequiresSyncFlush => _gpuVendor.Value == GpuVendor.AmdWindows || IsIntel;
|
||||
|
||||
public static int MaximumComputeSharedMemorySize => _maximumComputeSharedMemorySize.Value;
|
||||
public static int StorageBufferOffsetAlignment => _storageBufferOffsetAlignment.Value;
|
||||
public static int TextureBufferOffsetAlignment => _textureBufferOffsetAlignment.Value;
|
||||
|
||||
public static float MaximumSupportedAnisotropy => _maxSupportedAnisotropy.Value;
|
||||
|
||||
private static bool HasExtension(string name)
|
||||
{
|
||||
int numExtensions = GL.GetInteger(GetPName.NumExtensions);
|
||||
|
||||
for (int extension = 0; extension < numExtensions; extension++)
|
||||
{
|
||||
if (GL.GetString(StringNameIndexed.Extensions, extension) == name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int GetLimit(All name)
|
||||
{
|
||||
return GL.GetInteger((GetPName)name);
|
||||
}
|
||||
|
||||
private static GpuVendor GetGpuVendor()
|
||||
{
|
||||
string vendor = GL.GetString(StringName.Vendor).ToLowerInvariant();
|
||||
|
||||
if (vendor == "nvidia corporation")
|
||||
{
|
||||
return GpuVendor.Nvidia;
|
||||
}
|
||||
else if (vendor == "intel")
|
||||
{
|
||||
string renderer = GL.GetString(StringName.Renderer).ToLowerInvariant();
|
||||
|
||||
return renderer.Contains("mesa") ? GpuVendor.IntelUnix : GpuVendor.IntelWindows;
|
||||
}
|
||||
else if (vendor == "ati technologies inc." || vendor == "advanced micro devices, inc.")
|
||||
{
|
||||
return GpuVendor.AmdWindows;
|
||||
}
|
||||
else if (vendor == "amd" || vendor == "x.org")
|
||||
{
|
||||
return GpuVendor.AmdUnix;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GpuVendor.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool SupportsQuadsCheck()
|
||||
{
|
||||
GL.GetError(); // Clear any existing error.
|
||||
GL.Begin(PrimitiveType.Quads);
|
||||
GL.End();
|
||||
|
||||
return GL.GetError() == ErrorCode.NoError;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
using Ryujinx.Graphics.OpenGL.Helper;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
|
|
|
@ -21,14 +21,14 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
if (Avx2.IsSupported)
|
||||
{
|
||||
var mask = Vector256.Create(
|
||||
(byte)3, (byte)0, (byte)1, (byte)2,
|
||||
(byte)7, (byte)4, (byte)5, (byte)6,
|
||||
(byte)11, (byte)8, (byte)9, (byte)10,
|
||||
(byte)15, (byte)12, (byte)13, (byte)14,
|
||||
(byte)19, (byte)16, (byte)17, (byte)18,
|
||||
(byte)23, (byte)20, (byte)21, (byte)22,
|
||||
(byte)27, (byte)24, (byte)25, (byte)26,
|
||||
(byte)31, (byte)28, (byte)29, (byte)30);
|
||||
3, 0, 1, 2,
|
||||
7, 4, 5, 6,
|
||||
11, 8, 9, 10,
|
||||
15, 12, 13, 14,
|
||||
19, 16, 17, 18,
|
||||
23, 20, 21, 22,
|
||||
27, 24, 25, 26,
|
||||
31, 28, 29, (byte)30);
|
||||
|
||||
int sizeAligned = data.Length & ~31;
|
||||
|
||||
|
@ -49,10 +49,10 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
else if (Ssse3.IsSupported)
|
||||
{
|
||||
var mask = Vector128.Create(
|
||||
(byte)3, (byte)0, (byte)1, (byte)2,
|
||||
(byte)7, (byte)4, (byte)5, (byte)6,
|
||||
(byte)11, (byte)8, (byte)9, (byte)10,
|
||||
(byte)15, (byte)12, (byte)13, (byte)14);
|
||||
3, 0, 1, 2,
|
||||
7, 4, 5, 6,
|
||||
11, 8, 9, 10,
|
||||
15, 12, 13, (byte)14);
|
||||
|
||||
int sizeAligned = data.Length & ~15;
|
||||
|
||||
|
@ -90,14 +90,14 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
if (Avx2.IsSupported)
|
||||
{
|
||||
var mask = Vector256.Create(
|
||||
(byte)1, (byte)2, (byte)3, (byte)0,
|
||||
(byte)5, (byte)6, (byte)7, (byte)4,
|
||||
(byte)9, (byte)10, (byte)11, (byte)8,
|
||||
(byte)13, (byte)14, (byte)15, (byte)12,
|
||||
(byte)17, (byte)18, (byte)19, (byte)16,
|
||||
(byte)21, (byte)22, (byte)23, (byte)20,
|
||||
(byte)25, (byte)26, (byte)27, (byte)24,
|
||||
(byte)29, (byte)30, (byte)31, (byte)28);
|
||||
1, 2, 3, 0,
|
||||
5, 6, 7, 4,
|
||||
9, 10, 11, 8,
|
||||
13, 14, 15, 12,
|
||||
17, 18, 19, 16,
|
||||
21, 22, 23, 20,
|
||||
25, 26, 27, 24,
|
||||
29, 30, 31, (byte)28);
|
||||
|
||||
int sizeAligned = data.Length & ~31;
|
||||
|
||||
|
@ -118,10 +118,10 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
else if (Ssse3.IsSupported)
|
||||
{
|
||||
var mask = Vector128.Create(
|
||||
(byte)1, (byte)2, (byte)3, (byte)0,
|
||||
(byte)5, (byte)6, (byte)7, (byte)4,
|
||||
(byte)9, (byte)10, (byte)11, (byte)8,
|
||||
(byte)13, (byte)14, (byte)15, (byte)12);
|
||||
1, 2, 3, 0,
|
||||
5, 6, 7, 4,
|
||||
9, 10, 11, 8,
|
||||
13, 14, 15, (byte)12);
|
||||
|
||||
int sizeAligned = data.Length & ~15;
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
interface ITextureInfo
|
||||
{
|
||||
ITextureInfo Storage { get; }
|
||||
int Handle { get; }
|
||||
int FirstLayer => 0;
|
||||
int FirstLevel => 0;
|
||||
uint Handle { get; }
|
||||
uint FirstLayer => 0;
|
||||
uint FirstLevel => 0;
|
||||
|
||||
TextureCreateInfo Info { get; }
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using System;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Image
|
||||
{
|
||||
|
@ -8,18 +7,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
private record struct TextureRef
|
||||
{
|
||||
public int Handle;
|
||||
public uint Handle;
|
||||
public Format Format;
|
||||
}
|
||||
|
||||
private readonly TextureRef[] _images;
|
||||
private readonly GL _api;
|
||||
|
||||
public ImageArray(int size)
|
||||
public ImageArray(GL api, int size)
|
||||
{
|
||||
_api = api;
|
||||
_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++)
|
||||
{
|
||||
|
@ -44,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++)
|
||||
{
|
||||
if (_images[i].Handle == 0)
|
||||
{
|
||||
GL.BindImageTexture(baseBinding + i, 0, 0, true, 0, TextureAccess.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
_api.BindImageTexture((uint)(baseBinding + i), 0, 0, true, 0, BufferAccessARB.ReadWrite, InternalFormat.Rgba8);
|
||||
}
|
||||
else
|
||||
{
|
||||
SizedInternalFormat format = FormatTable.GetImageFormat(_images[i].Format);
|
||||
InternalFormat format = (InternalFormat)FormatTable.GetImageFormat(_images[i].Format);
|
||||
|
||||
if (format != 0)
|
||||
{
|
||||
GL.BindImageTexture(baseBinding + i, _images[i].Handle, 0, true, 0, TextureAccess.ReadWrite, format);
|
||||
_api.BindImageTexture((uint)(baseBinding + i), _images[i].Handle, 0, true, 0, BufferAccessARB.ReadWrite, format);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,32 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Image
|
||||
{
|
||||
class Sampler : ISampler
|
||||
{
|
||||
public int Handle { get; private set; }
|
||||
public uint Handle { get; private set; }
|
||||
private readonly OpenGLRenderer _gd;
|
||||
|
||||
public Sampler(SamplerCreateInfo info)
|
||||
public Sampler(OpenGLRenderer gd, SamplerCreateInfo info)
|
||||
{
|
||||
Handle = GL.GenSampler();
|
||||
_gd = gd;
|
||||
Handle = _gd.Api.GenSampler();
|
||||
|
||||
GL.SamplerParameter(Handle, SamplerParameterName.TextureMinFilter, (int)info.MinFilter.Convert());
|
||||
GL.SamplerParameter(Handle, SamplerParameterName.TextureMagFilter, (int)info.MagFilter.Convert());
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterI.MinFilter, (int)info.MinFilter.Convert());
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterI.MagFilter, (int)info.MagFilter.Convert());
|
||||
|
||||
if (HwCapabilities.SupportsSeamlessCubemapPerTexture)
|
||||
if (_gd.Capabilities.SupportsSeamlessCubemapPerTexture)
|
||||
{
|
||||
GL.SamplerParameter(Handle, (SamplerParameterName)ArbSeamlessCubemapPerTexture.TextureCubeMapSeamless, info.SeamlessCubemap ? 1 : 0);
|
||||
_gd.Api.SamplerParameter(Handle, GLEnum.TextureCubeMapSeamless, info.SeamlessCubemap ? 1 : 0);
|
||||
}
|
||||
|
||||
GL.SamplerParameter(Handle, SamplerParameterName.TextureWrapS, (int)info.AddressU.Convert());
|
||||
GL.SamplerParameter(Handle, SamplerParameterName.TextureWrapT, (int)info.AddressV.Convert());
|
||||
GL.SamplerParameter(Handle, SamplerParameterName.TextureWrapR, (int)info.AddressP.Convert());
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterI.WrapS, (int)info.AddressU.Convert());
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterI.WrapT, (int)info.AddressV.Convert());
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterI.WrapR, (int)info.AddressP.Convert());
|
||||
|
||||
GL.SamplerParameter(Handle, SamplerParameterName.TextureCompareMode, (int)info.CompareMode.Convert());
|
||||
GL.SamplerParameter(Handle, SamplerParameterName.TextureCompareFunc, (int)info.CompareOp.Convert());
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterI.CompareMode, (int)info.CompareMode.Convert());
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterI.CompareFunc, (int)info.CompareOp.Convert());
|
||||
|
||||
unsafe
|
||||
{
|
||||
|
@ -36,26 +38,26 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
info.BorderColor.Alpha,
|
||||
};
|
||||
|
||||
GL.SamplerParameter(Handle, SamplerParameterName.TextureBorderColor, borderColor);
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterF.BorderColor, borderColor);
|
||||
}
|
||||
|
||||
GL.SamplerParameter(Handle, SamplerParameterName.TextureMinLod, info.MinLod);
|
||||
GL.SamplerParameter(Handle, SamplerParameterName.TextureMaxLod, info.MaxLod);
|
||||
GL.SamplerParameter(Handle, SamplerParameterName.TextureLodBias, info.MipLodBias);
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterF.MinLod, info.MinLod);
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterF.MaxLod, info.MaxLod);
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterF.LodBias, info.MipLodBias);
|
||||
|
||||
GL.SamplerParameter(Handle, SamplerParameterName.TextureMaxAnisotropyExt, info.MaxAnisotropy);
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterF.MaxAnisotropy, info.MaxAnisotropy);
|
||||
}
|
||||
|
||||
public void Bind(int unit)
|
||||
public void Bind(uint unit)
|
||||
{
|
||||
GL.BindSampler(unit, Handle);
|
||||
_gd.Api.BindSampler(unit, Handle);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Handle != 0)
|
||||
{
|
||||
GL.DeleteSampler(Handle);
|
||||
_gd.Api.DeleteSampler(Handle);
|
||||
|
||||
Handle = 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Image
|
||||
{
|
||||
|
@ -11,9 +12,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
}
|
||||
|
||||
private readonly TextureRef[] _textureRefs;
|
||||
private readonly GL _api;
|
||||
|
||||
public TextureArray(int size)
|
||||
public TextureArray(GL api, int size)
|
||||
{
|
||||
_api = api;
|
||||
_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)
|
||||
{
|
||||
|
@ -44,7 +47,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
}
|
||||
else
|
||||
{
|
||||
TextureBase.ClearBinding(baseBinding + i);
|
||||
TextureBase.ClearBinding(_api, baseBinding + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Image
|
||||
{
|
||||
class TextureBase
|
||||
{
|
||||
public int Handle { get; protected set; }
|
||||
private readonly protected OpenGLRenderer _gd;
|
||||
public uint Handle { get; protected set; }
|
||||
|
||||
public TextureCreateInfo Info { get; }
|
||||
|
||||
|
@ -15,28 +16,29 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
public Target Target => Info.Target;
|
||||
public Format Format => Info.Format;
|
||||
|
||||
public TextureBase(TextureCreateInfo info)
|
||||
public TextureBase(OpenGLRenderer gd, TextureCreateInfo info)
|
||||
{
|
||||
_gd = gd;
|
||||
Info = info;
|
||||
|
||||
Handle = GL.GenTexture();
|
||||
Handle = _gd.Api.GenTexture();
|
||||
}
|
||||
|
||||
public void Bind(int unit)
|
||||
public void Bind(uint unit)
|
||||
{
|
||||
Bind(Target.Convert(), unit);
|
||||
}
|
||||
|
||||
protected void Bind(TextureTarget target, int unit)
|
||||
protected void Bind(TextureTarget target, uint unit)
|
||||
{
|
||||
GL.ActiveTexture(TextureUnit.Texture0 + unit);
|
||||
GL.BindTexture(target, Handle);
|
||||
_gd.Api.ActiveTexture((TextureUnit)((uint)TextureUnit.Texture0 + unit));
|
||||
_gd.Api.BindTexture(target, Handle);
|
||||
}
|
||||
|
||||
public static void ClearBinding(int unit)
|
||||
public static void ClearBinding(GL api, uint unit)
|
||||
{
|
||||
GL.ActiveTexture(TextureUnit.Texture0 + unit);
|
||||
GL.BindTextureUnit(unit, 0);
|
||||
api.ActiveTexture((TextureUnit)((uint)TextureUnit.Texture0 + unit));
|
||||
api.BindTextureUnit(unit, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
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(OpenGLRenderer renderer, TextureCreateInfo info) : base(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(_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(_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).PixelInternalFormat;
|
||||
SizedInternalFormat format = (SizedInternalFormat)FormatTable.GetFormatInfo(Info.Format).InternalFormat;
|
||||
|
||||
GL.TexBufferRange(TextureBufferTarget.TextureBuffer, format, _buffer.ToInt32(), (IntPtr)buffer.Offset, buffer.Size);
|
||||
_gd.Api.TexBufferRange(TextureTarget.TextureBuffer, format, _buffer.ToUInt32(), buffer.Offset, (uint)buffer.Size);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Handle != 0)
|
||||
{
|
||||
GL.DeleteTexture(Handle);
|
||||
_gd.Api.DeleteTexture(Handle);
|
||||
|
||||
Handle = 0;
|
||||
}
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Image
|
||||
{
|
||||
class TextureCopy : IDisposable
|
||||
{
|
||||
private readonly OpenGLRenderer _renderer;
|
||||
private readonly OpenGLRenderer _gd;
|
||||
|
||||
private int _srcFramebuffer;
|
||||
private int _dstFramebuffer;
|
||||
private uint _srcFramebuffer;
|
||||
private uint _dstFramebuffer;
|
||||
|
||||
private int _copyPboHandle;
|
||||
private uint _copyPboHandle;
|
||||
private int _copyPboSize;
|
||||
|
||||
public IntermediatePool IntermediatePool { get; }
|
||||
|
||||
public TextureCopy(OpenGLRenderer renderer)
|
||||
public TextureCopy(OpenGLRenderer gd)
|
||||
{
|
||||
_renderer = renderer;
|
||||
IntermediatePool = new IntermediatePool(renderer);
|
||||
_gd = gd;
|
||||
IntermediatePool = new IntermediatePool(gd);
|
||||
}
|
||||
|
||||
public void Copy(
|
||||
|
@ -55,10 +55,10 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
TextureView srcConverted = src.Format.IsBgr() != dst.Format.IsBgr() ? BgraSwap(src) : src;
|
||||
|
||||
(int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers();
|
||||
(uint oldDrawFramebufferHandle, uint oldReadFramebufferHandle) = ((Pipeline)_gd.Pipeline).GetBoundFramebuffers();
|
||||
|
||||
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, GetSrcFramebufferLazy());
|
||||
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, GetDstFramebufferLazy());
|
||||
_gd.Api.BindFramebuffer(FramebufferTarget.ReadFramebuffer, GetSrcFramebufferLazy());
|
||||
_gd.Api.BindFramebuffer(FramebufferTarget.DrawFramebuffer, GetDstFramebufferLazy());
|
||||
|
||||
if (srcLevel != 0)
|
||||
{
|
||||
|
@ -76,13 +76,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
if ((srcLayer | dstLayer) != 0 || layers > 1)
|
||||
{
|
||||
Attach(FramebufferTarget.ReadFramebuffer, src.Format, srcConverted.Handle, srcLevel + level, srcLayer + layer);
|
||||
Attach(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(FramebufferTarget.ReadFramebuffer, src.Format, srcConverted.Handle, srcLevel + level);
|
||||
Attach(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);
|
||||
|
@ -96,13 +96,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
? BlitFramebufferFilter.Linear
|
||||
: BlitFramebufferFilter.Nearest;
|
||||
|
||||
GL.ReadBuffer(ReadBufferMode.ColorAttachment0);
|
||||
GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
|
||||
_gd.Api.ReadBuffer(ReadBufferMode.ColorAttachment0);
|
||||
_gd.Api.DrawBuffer(DrawBufferMode.ColorAttachment0);
|
||||
|
||||
GL.Disable(EnableCap.RasterizerDiscard);
|
||||
GL.Disable(IndexedEnableCap.ScissorTest, 0);
|
||||
_gd.Api.Disable(EnableCap.RasterizerDiscard);
|
||||
_gd.Api.Disable(EnableCap.ScissorTest, 0);
|
||||
|
||||
GL.BlitFramebuffer(
|
||||
_gd.Api.BlitFramebuffer(
|
||||
srcRegion.X1,
|
||||
srcRegion.Y1,
|
||||
srcRegion.X2,
|
||||
|
@ -122,14 +122,14 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
}
|
||||
}
|
||||
|
||||
Attach(FramebufferTarget.ReadFramebuffer, src.Format, 0);
|
||||
Attach(FramebufferTarget.DrawFramebuffer, dst.Format, 0);
|
||||
Attach(_gd.Api, FramebufferTarget.ReadFramebuffer, src.Format, 0);
|
||||
Attach(_gd.Api, FramebufferTarget.DrawFramebuffer, dst.Format, 0);
|
||||
|
||||
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle);
|
||||
GL.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)
|
||||
{
|
||||
|
@ -178,8 +178,8 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
TextureCreateInfo srcInfo = src.Info;
|
||||
TextureCreateInfo dstInfo = dst.Info;
|
||||
|
||||
int srcHandle = src.Handle;
|
||||
int dstHandle = dst.Handle;
|
||||
uint srcHandle = src.Handle;
|
||||
uint dstHandle = dst.Handle;
|
||||
|
||||
int srcWidth = srcInfo.Width;
|
||||
int srcHeight = srcInfo.Height;
|
||||
|
@ -238,28 +238,28 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
int copyWidth = sizeInBlocks ? BitUtils.DivRoundUp(width, blockWidth) : width;
|
||||
int copyHeight = sizeInBlocks ? BitUtils.DivRoundUp(height, blockHeight) : height;
|
||||
|
||||
if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows)
|
||||
if (_gd.Capabilities.GpuVendor == GpuVendor.IntelWindows)
|
||||
{
|
||||
GL.CopyImageSubData(
|
||||
_gd.Api.CopyImageSubData(
|
||||
src.Storage.Handle,
|
||||
src.Storage.Info.Target.ConvertToImageTarget(),
|
||||
src.FirstLevel + srcLevel + level,
|
||||
(int)src.FirstLevel + srcLevel + level,
|
||||
0,
|
||||
0,
|
||||
src.FirstLayer + srcLayer,
|
||||
(int)src.FirstLayer + srcLayer,
|
||||
dst.Storage.Handle,
|
||||
dst.Storage.Info.Target.ConvertToImageTarget(),
|
||||
dst.FirstLevel + dstLevel + level,
|
||||
(int)dst.FirstLevel + dstLevel + level,
|
||||
0,
|
||||
0,
|
||||
dst.FirstLayer + dstLayer,
|
||||
copyWidth,
|
||||
copyHeight,
|
||||
depth);
|
||||
(int)dst.FirstLayer + dstLayer,
|
||||
(uint)copyWidth,
|
||||
(uint)copyHeight,
|
||||
(uint)depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.CopyImageSubData(
|
||||
_gd.Api.CopyImageSubData(
|
||||
srcHandle,
|
||||
srcInfo.Target.ConvertToImageTarget(),
|
||||
srcLevel + level,
|
||||
|
@ -272,9 +272,9 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
0,
|
||||
0,
|
||||
dstLayer,
|
||||
copyWidth,
|
||||
copyHeight,
|
||||
depth);
|
||||
(uint)copyWidth,
|
||||
(uint)copyHeight,
|
||||
(uint)depth);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,18 +308,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);
|
||||
|
||||
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);
|
||||
|
||||
GL.FramebufferTextureLayer(target, attachment, handle, level, layer);
|
||||
api.FramebufferTextureLayer(target, attachment, handle, level, layer);
|
||||
}
|
||||
|
||||
private static ClearBufferMask GetMask(Format format)
|
||||
|
@ -344,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);
|
||||
|
||||
GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyPboHandle);
|
||||
_gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyPboHandle);
|
||||
|
||||
from.WriteToPbo(0, forceBgra: true);
|
||||
|
||||
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
|
||||
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, _copyPboHandle);
|
||||
_gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
|
||||
_gd.Api.BindBuffer(BufferTargetARB.PixelUnpackBuffer, _copyPboHandle);
|
||||
|
||||
to.ReadFromPbo(0, _copyPboSize);
|
||||
|
||||
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
|
||||
_gd.Api.BindBuffer(BufferTargetARB.PixelUnpackBuffer, 0);
|
||||
|
||||
return to;
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
EnsurePbo(from);
|
||||
|
||||
GL.BindBuffer(BufferTarget.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.
|
||||
|
@ -407,42 +407,42 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
if (slice)
|
||||
{
|
||||
// Set unpack parameters to take a slice of width/height:
|
||||
GL.PixelStore(PixelStoreParameter.UnpackRowLength, unpackWidth);
|
||||
GL.PixelStore(PixelStoreParameter.UnpackImageHeight, unpackHeight);
|
||||
_gd.Api.PixelStore(PixelStoreParameter.UnpackRowLength, unpackWidth);
|
||||
_gd.Api.PixelStore(PixelStoreParameter.UnpackImageHeight, unpackHeight);
|
||||
|
||||
if (to.Info.IsCompressed)
|
||||
{
|
||||
GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockWidth, to.Info.BlockWidth);
|
||||
GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockHeight, to.Info.BlockHeight);
|
||||
GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockDepth, 1);
|
||||
GL.PixelStore(PixelStoreParameter.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);
|
||||
}
|
||||
}
|
||||
|
||||
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
|
||||
GL.BindBuffer(BufferTarget.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
|
||||
GL.PixelStore(PixelStoreParameter.UnpackRowLength, 0);
|
||||
GL.PixelStore(PixelStoreParameter.UnpackImageHeight, 0);
|
||||
_gd.Api.PixelStore(PixelStoreParameter.UnpackRowLength, 0);
|
||||
_gd.Api.PixelStore(PixelStoreParameter.UnpackImageHeight, 0);
|
||||
|
||||
if (to.Info.IsCompressed)
|
||||
{
|
||||
GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockWidth, 0);
|
||||
GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockHeight, 0);
|
||||
GL.PixelStore(PixelStoreParameter.UnpackCompressedBlockDepth, 0);
|
||||
GL.PixelStore(PixelStoreParameter.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);
|
||||
}
|
||||
}
|
||||
|
||||
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0);
|
||||
_gd.Api.BindBuffer(BufferTargetARB.PixelUnpackBuffer, 0);
|
||||
}
|
||||
|
||||
private void EnsurePbo(TextureView view)
|
||||
private unsafe void EnsurePbo(TextureView view)
|
||||
{
|
||||
int requiredSize = 0;
|
||||
|
||||
|
@ -453,36 +453,36 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
if (_copyPboSize < requiredSize && _copyPboHandle != 0)
|
||||
{
|
||||
GL.DeleteBuffer(_copyPboHandle);
|
||||
_gd.Api.DeleteBuffer(_copyPboHandle);
|
||||
|
||||
_copyPboHandle = 0;
|
||||
}
|
||||
|
||||
if (_copyPboHandle == 0)
|
||||
{
|
||||
_copyPboHandle = GL.GenBuffer();
|
||||
_copyPboHandle = _gd.Api.GenBuffer();
|
||||
_copyPboSize = requiredSize;
|
||||
|
||||
GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyPboHandle);
|
||||
GL.BufferData(BufferTarget.PixelPackBuffer, requiredSize, IntPtr.Zero, BufferUsageHint.DynamicCopy);
|
||||
_gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyPboHandle);
|
||||
_gd.Api.BufferData(BufferTargetARB.PixelPackBuffer, (uint)requiredSize, null, BufferUsageARB.DynamicCopy);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetSrcFramebufferLazy()
|
||||
private uint GetSrcFramebufferLazy()
|
||||
{
|
||||
if (_srcFramebuffer == 0)
|
||||
{
|
||||
_srcFramebuffer = GL.GenFramebuffer();
|
||||
_srcFramebuffer = _gd.Api.GenFramebuffer();
|
||||
}
|
||||
|
||||
return _srcFramebuffer;
|
||||
}
|
||||
|
||||
private int GetDstFramebufferLazy()
|
||||
private uint GetDstFramebufferLazy()
|
||||
{
|
||||
if (_dstFramebuffer == 0)
|
||||
{
|
||||
_dstFramebuffer = GL.GenFramebuffer();
|
||||
_dstFramebuffer = _gd.Api.GenFramebuffer();
|
||||
}
|
||||
|
||||
return _dstFramebuffer;
|
||||
|
@ -492,21 +492,21 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
if (_srcFramebuffer != 0)
|
||||
{
|
||||
GL.DeleteFramebuffer(_srcFramebuffer);
|
||||
_gd.Api.DeleteFramebuffer(_srcFramebuffer);
|
||||
|
||||
_srcFramebuffer = 0;
|
||||
}
|
||||
|
||||
if (_dstFramebuffer != 0)
|
||||
{
|
||||
GL.DeleteFramebuffer(_dstFramebuffer);
|
||||
_gd.Api.DeleteFramebuffer(_dstFramebuffer);
|
||||
|
||||
_dstFramebuffer = 0;
|
||||
}
|
||||
|
||||
if (_copyPboHandle != 0)
|
||||
{
|
||||
GL.DeleteBuffer(_copyPboHandle);
|
||||
_gd.Api.DeleteBuffer(_copyPboHandle);
|
||||
|
||||
_copyPboHandle = 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
@ -67,15 +67,15 @@ void main()
|
|||
imageStore(dst, ivec2(coords), uvec4(r, g, b, a));
|
||||
}";
|
||||
|
||||
private readonly OpenGLRenderer _renderer;
|
||||
private readonly Dictionary<int, int> _shorteningProgramHandles;
|
||||
private readonly Dictionary<int, int> _wideningProgramHandles;
|
||||
private readonly OpenGLRenderer _gd;
|
||||
private readonly Dictionary<int, uint> _shorteningProgramHandles;
|
||||
private readonly Dictionary<int, uint> _wideningProgramHandles;
|
||||
|
||||
public TextureCopyIncompatible(OpenGLRenderer renderer)
|
||||
public TextureCopyIncompatible(OpenGLRenderer gd)
|
||||
{
|
||||
_renderer = renderer;
|
||||
_shorteningProgramHandles = new Dictionary<int, int>();
|
||||
_wideningProgramHandles = new Dictionary<int, int>();
|
||||
_gd = gd;
|
||||
_shorteningProgramHandles = new Dictionary<int, uint>();
|
||||
_wideningProgramHandles = new Dictionary<int, uint>();
|
||||
}
|
||||
|
||||
public void CopyIncompatibleFormats(ITextureInfo src, ITextureInfo dst, int srcLayer, int dstLayer, int srcLevel, int dstLevel, int depth, int levels)
|
||||
|
@ -91,10 +91,10 @@ void main()
|
|||
int srcComponentsCount = srcBpp / componentSize;
|
||||
int dstComponentsCount = dstBpp / componentSize;
|
||||
|
||||
var srcFormat = GetFormat(componentSize, srcComponentsCount);
|
||||
var dstFormat = GetFormat(componentSize, dstComponentsCount);
|
||||
var srcFormat = (InternalFormat)GetFormat(componentSize, srcComponentsCount);
|
||||
var dstFormat = (InternalFormat)GetFormat(componentSize, dstComponentsCount);
|
||||
|
||||
GL.UseProgram(srcBpp < dstBpp
|
||||
_gd.Api.UseProgram(srcBpp < dstBpp
|
||||
? GetWideningShader(componentSize, srcComponentsCount, dstComponentsCount)
|
||||
: GetShorteningShader(componentSize, srcComponentsCount, dstComponentsCount));
|
||||
|
||||
|
@ -106,19 +106,19 @@ void main()
|
|||
int dstWidth = Math.Max(1, dst.Info.Width >> l);
|
||||
int dstHeight = Math.Max(1, dst.Info.Height >> l);
|
||||
|
||||
int width = Math.Min(srcWidth, dstWidth);
|
||||
int height = Math.Min(srcHeight, dstHeight);
|
||||
uint width = (uint)Math.Min(srcWidth, dstWidth);
|
||||
uint height = (uint)Math.Min(srcHeight, dstHeight);
|
||||
|
||||
for (int z = 0; z < depth; z++)
|
||||
{
|
||||
GL.BindImageTexture(0, src.Handle, srcLevel + l, false, srcLayer + z, TextureAccess.ReadOnly, srcFormat);
|
||||
GL.BindImageTexture(1, dst.Handle, dstLevel + l, false, dstLayer + z, TextureAccess.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);
|
||||
|
||||
GL.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();
|
||||
|
@ -131,7 +131,7 @@ void main()
|
|||
return componentsCount switch
|
||||
{
|
||||
1 => SizedInternalFormat.R8ui,
|
||||
2 => SizedInternalFormat.Rg8ui,
|
||||
2 => SizedInternalFormat.RG8ui,
|
||||
4 => SizedInternalFormat.Rgba8ui,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
|
||||
};
|
||||
|
@ -141,7 +141,7 @@ void main()
|
|||
return componentsCount switch
|
||||
{
|
||||
1 => SizedInternalFormat.R16ui,
|
||||
2 => SizedInternalFormat.Rg16ui,
|
||||
2 => SizedInternalFormat.RG16ui,
|
||||
4 => SizedInternalFormat.Rgba16ui,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
|
||||
};
|
||||
|
@ -151,7 +151,7 @@ void main()
|
|||
return componentsCount switch
|
||||
{
|
||||
1 => SizedInternalFormat.R32ui,
|
||||
2 => SizedInternalFormat.Rg32ui,
|
||||
2 => SizedInternalFormat.RG32ui,
|
||||
4 => SizedInternalFormat.Rgba32ui,
|
||||
_ => throw new ArgumentException($"Invalid components count {componentsCount}."),
|
||||
};
|
||||
|
@ -162,19 +162,19 @@ void main()
|
|||
}
|
||||
}
|
||||
|
||||
private int GetShorteningShader(int componentSize, int srcComponentsCount, int dstComponentsCount)
|
||||
private uint GetShorteningShader(int componentSize, int srcComponentsCount, int dstComponentsCount)
|
||||
{
|
||||
return GetShader(ComputeShaderShortening, _shorteningProgramHandles, componentSize, srcComponentsCount, dstComponentsCount);
|
||||
}
|
||||
|
||||
private int GetWideningShader(int componentSize, int srcComponentsCount, int dstComponentsCount)
|
||||
private uint GetWideningShader(int componentSize, int srcComponentsCount, int dstComponentsCount)
|
||||
{
|
||||
return GetShader(ComputeShaderWidening, _wideningProgramHandles, componentSize, srcComponentsCount, dstComponentsCount);
|
||||
}
|
||||
|
||||
private static int GetShader(
|
||||
private uint GetShader(
|
||||
string code,
|
||||
Dictionary<int, int> programHandles,
|
||||
Dictionary<int, uint> programHandles,
|
||||
int componentSize,
|
||||
int srcComponentsCount,
|
||||
int dstComponentsCount)
|
||||
|
@ -186,11 +186,11 @@ void main()
|
|||
|
||||
int key = srcIndex | (dstIndex << 8);
|
||||
|
||||
if (!programHandles.TryGetValue(key, out int programHandle))
|
||||
if (!programHandles.TryGetValue(key, out uint programHandle))
|
||||
{
|
||||
int csHandle = GL.CreateShader(ShaderType.ComputeShader);
|
||||
uint csHandle = _gd.Api.CreateShader(ShaderType.ComputeShader);
|
||||
|
||||
string[] formatTable = new[] { "r8ui", "r16ui", "r32ui", "rg8ui", "rg16ui", "rg32ui", "rgba8ui", "rgba16ui", "rgba32ui" };
|
||||
string[] formatTable = ["r8ui", "r16ui", "r32ui", "rg8ui", "rg16ui", "rg32ui", "rgba8ui", "rgba16ui", "rgba32ui"];
|
||||
|
||||
string srcFormat = formatTable[srcIndex];
|
||||
string dstFormat = formatTable[dstIndex];
|
||||
|
@ -201,25 +201,25 @@ void main()
|
|||
int ratio = srcBpp < dstBpp ? dstBpp / srcBpp : srcBpp / dstBpp;
|
||||
int ratioLog2 = BitOperations.Log2((uint)ratio);
|
||||
|
||||
GL.ShaderSource(csHandle, code
|
||||
_gd.Api.ShaderSource(csHandle, code
|
||||
.Replace("$SRC_FORMAT$", srcFormat)
|
||||
.Replace("$DST_FORMAT$", dstFormat)
|
||||
.Replace("$RATIO_LOG2$", ratioLog2.ToString(CultureInfo.InvariantCulture)));
|
||||
|
||||
GL.CompileShader(csHandle);
|
||||
_gd.Api.CompileShader(csHandle);
|
||||
|
||||
programHandle = GL.CreateProgram();
|
||||
programHandle = _gd.Api.CreateProgram();
|
||||
|
||||
GL.AttachShader(programHandle, csHandle);
|
||||
GL.LinkProgram(programHandle);
|
||||
GL.DetachShader(programHandle, csHandle);
|
||||
GL.DeleteShader(csHandle);
|
||||
_gd.Api.AttachShader(programHandle, csHandle);
|
||||
_gd.Api.LinkProgram(programHandle);
|
||||
_gd.Api.DetachShader(programHandle, csHandle);
|
||||
_gd.Api.DeleteShader(csHandle);
|
||||
|
||||
GL.GetProgram(programHandle, GetProgramParameterName.LinkStatus, out int status);
|
||||
_gd.Api.GetProgram(programHandle, ProgramPropertyARB.LinkStatus, out int status);
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
throw new Exception(GL.GetProgramInfoLog(programHandle));
|
||||
throw new Exception(_gd.Api.GetProgramInfoLog(programHandle));
|
||||
}
|
||||
|
||||
programHandles.Add(key, programHandle);
|
||||
|
@ -230,16 +230,16 @@ void main()
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (int handle in _shorteningProgramHandles.Values)
|
||||
foreach (uint handle in _shorteningProgramHandles.Values)
|
||||
{
|
||||
GL.DeleteProgram(handle);
|
||||
_gd.Api.DeleteProgram(handle);
|
||||
}
|
||||
|
||||
_shorteningProgramHandles.Clear();
|
||||
|
||||
foreach (int handle in _wideningProgramHandles.Values)
|
||||
foreach (uint handle in _wideningProgramHandles.Values)
|
||||
{
|
||||
GL.DeleteProgram(handle);
|
||||
_gd.Api.DeleteProgram(handle);
|
||||
}
|
||||
|
||||
_wideningProgramHandles.Clear();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
|
@ -93,15 +93,15 @@ void main()
|
|||
imageStore(imgOut, ivec2(int(coords.x) >> samplesInXLog2, int(coords.y) >> samplesInYLog2), sampleIdx, value);
|
||||
}";
|
||||
|
||||
private readonly OpenGLRenderer _renderer;
|
||||
private readonly int[] _msToNonMSProgramHandles;
|
||||
private readonly int[] _nonMSToMSProgramHandles;
|
||||
private readonly OpenGLRenderer _gd;
|
||||
private readonly uint[] _msToNonMSProgramHandles;
|
||||
private readonly uint[] _nonMSToMSProgramHandles;
|
||||
|
||||
public TextureCopyMS(OpenGLRenderer renderer)
|
||||
public TextureCopyMS(OpenGLRenderer gd)
|
||||
{
|
||||
_renderer = renderer;
|
||||
_msToNonMSProgramHandles = new int[5];
|
||||
_nonMSToMSProgramHandles = new int[5];
|
||||
_gd = gd;
|
||||
_msToNonMSProgramHandles = new uint[5];
|
||||
_nonMSToMSProgramHandles = new uint[5];
|
||||
}
|
||||
|
||||
public void CopyMSToNonMS(ITextureInfo src, ITextureInfo dst, int srcLayer, int dstLayer, int depth)
|
||||
|
@ -109,23 +109,23 @@ void main()
|
|||
TextureCreateInfo srcInfo = src.Info;
|
||||
TextureCreateInfo dstInfo = dst.Info;
|
||||
|
||||
int srcHandle = CreateViewIfNeeded(src);
|
||||
int dstHandle = CreateViewIfNeeded(dst);
|
||||
uint srcHandle = CreateViewIfNeeded(src);
|
||||
uint dstHandle = CreateViewIfNeeded(dst);
|
||||
|
||||
int dstWidth = dstInfo.Width;
|
||||
int dstHeight = dstInfo.Height;
|
||||
uint dstWidth = (uint)dstInfo.Width;
|
||||
uint dstHeight = (uint)dstInfo.Height;
|
||||
|
||||
GL.UseProgram(GetMSToNonMSShader(srcInfo.BytesPerPixel));
|
||||
_gd.Api.UseProgram(GetMSToNonMSShader(srcInfo.BytesPerPixel));
|
||||
|
||||
for (int z = 0; z < depth; z++)
|
||||
{
|
||||
GL.BindImageTexture(0, srcHandle, 0, false, srcLayer + z, TextureAccess.ReadOnly, GetFormat(srcInfo.BytesPerPixel));
|
||||
GL.BindImageTexture(1, dstHandle, 0, false, dstLayer + z, TextureAccess.WriteOnly, 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));
|
||||
|
||||
GL.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();
|
||||
|
@ -139,23 +139,23 @@ void main()
|
|||
TextureCreateInfo srcInfo = src.Info;
|
||||
TextureCreateInfo dstInfo = dst.Info;
|
||||
|
||||
int srcHandle = CreateViewIfNeeded(src);
|
||||
int dstHandle = CreateViewIfNeeded(dst);
|
||||
uint srcHandle = CreateViewIfNeeded(src);
|
||||
uint dstHandle = CreateViewIfNeeded(dst);
|
||||
|
||||
int srcWidth = srcInfo.Width;
|
||||
int srcHeight = srcInfo.Height;
|
||||
uint srcWidth = (uint)srcInfo.Width;
|
||||
uint srcHeight = (uint)srcInfo.Height;
|
||||
|
||||
GL.UseProgram(GetNonMSToMSShader(srcInfo.BytesPerPixel));
|
||||
_gd.Api.UseProgram(GetNonMSToMSShader(srcInfo.BytesPerPixel));
|
||||
|
||||
for (int z = 0; z < depth; z++)
|
||||
{
|
||||
GL.BindImageTexture(0, srcHandle, 0, false, srcLayer + z, TextureAccess.ReadOnly, GetFormat(srcInfo.BytesPerPixel));
|
||||
GL.BindImageTexture(1, dstHandle, 0, false, dstLayer + z, TextureAccess.WriteOnly, 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));
|
||||
|
||||
GL.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();
|
||||
|
@ -171,29 +171,29 @@ void main()
|
|||
1 => SizedInternalFormat.R8ui,
|
||||
2 => SizedInternalFormat.R16ui,
|
||||
4 => SizedInternalFormat.R32ui,
|
||||
8 => SizedInternalFormat.Rg32ui,
|
||||
8 => SizedInternalFormat.RG32ui,
|
||||
16 => SizedInternalFormat.Rgba32ui,
|
||||
_ => throw new ArgumentException($"Invalid bytes per pixel {bytesPerPixel}."),
|
||||
};
|
||||
}
|
||||
|
||||
private static int CreateViewIfNeeded(ITextureInfo texture)
|
||||
private uint CreateViewIfNeeded(ITextureInfo texture)
|
||||
{
|
||||
// Binding sRGB textures as images doesn't work on NVIDIA,
|
||||
// we need to create and bind a RGBA view for it to work.
|
||||
if (texture.Info.Format == Format.R8G8B8A8Srgb)
|
||||
{
|
||||
int handle = GL.GenTexture();
|
||||
uint handle = _gd.Api.GenTexture();
|
||||
|
||||
GL.TextureView(
|
||||
_gd.Api.TextureView(
|
||||
handle,
|
||||
texture.Info.Target.Convert(),
|
||||
texture.Storage.Handle,
|
||||
PixelInternalFormat.Rgba8,
|
||||
SizedInternalFormat.Rgba8,
|
||||
texture.FirstLevel,
|
||||
1,
|
||||
texture.FirstLayer,
|
||||
texture.Info.GetLayers());
|
||||
(uint)texture.Info.GetLayers());
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
@ -201,49 +201,49 @@ void main()
|
|||
return texture.Handle;
|
||||
}
|
||||
|
||||
private static void DestroyViewIfNeeded(ITextureInfo info, int handle)
|
||||
private void DestroyViewIfNeeded(ITextureInfo info, uint handle)
|
||||
{
|
||||
if (info.Handle != handle)
|
||||
{
|
||||
GL.DeleteTexture(handle);
|
||||
_gd.Api.DeleteTexture(handle);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetMSToNonMSShader(int bytesPerPixel)
|
||||
private uint GetMSToNonMSShader(int bytesPerPixel)
|
||||
{
|
||||
return GetShader(ComputeShaderMSToNonMS, _msToNonMSProgramHandles, bytesPerPixel);
|
||||
}
|
||||
|
||||
private int GetNonMSToMSShader(int bytesPerPixel)
|
||||
private uint GetNonMSToMSShader(int bytesPerPixel)
|
||||
{
|
||||
return GetShader(ComputeShaderNonMSToMS, _nonMSToMSProgramHandles, bytesPerPixel);
|
||||
}
|
||||
|
||||
private static int GetShader(string code, int[] programHandles, int bytesPerPixel)
|
||||
private uint GetShader(string code, uint[] programHandles, int bytesPerPixel)
|
||||
{
|
||||
int index = BitOperations.Log2((uint)bytesPerPixel);
|
||||
|
||||
if (programHandles[index] == 0)
|
||||
{
|
||||
int csHandle = GL.CreateShader(ShaderType.ComputeShader);
|
||||
uint csHandle = _gd.Api.CreateShader(ShaderType.ComputeShader);
|
||||
|
||||
string format = new[] { "r8ui", "r16ui", "r32ui", "rg32ui", "rgba32ui" }[index];
|
||||
|
||||
GL.ShaderSource(csHandle, code.Replace("$FORMAT$", format));
|
||||
GL.CompileShader(csHandle);
|
||||
_gd.Api.ShaderSource(csHandle, code.Replace("$FORMAT$", format));
|
||||
_gd.Api.CompileShader(csHandle);
|
||||
|
||||
int programHandle = GL.CreateProgram();
|
||||
uint programHandle = _gd.Api.CreateProgram();
|
||||
|
||||
GL.AttachShader(programHandle, csHandle);
|
||||
GL.LinkProgram(programHandle);
|
||||
GL.DetachShader(programHandle, csHandle);
|
||||
GL.DeleteShader(csHandle);
|
||||
_gd.Api.AttachShader(programHandle, csHandle);
|
||||
_gd.Api.LinkProgram(programHandle);
|
||||
_gd.Api.DetachShader(programHandle, csHandle);
|
||||
_gd.Api.DeleteShader(csHandle);
|
||||
|
||||
GL.GetProgram(programHandle, GetProgramParameterName.LinkStatus, out int status);
|
||||
_gd.Api.GetProgram(programHandle, ProgramPropertyARB.LinkStatus, out int status);
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
throw new Exception(GL.GetProgramInfoLog(programHandle));
|
||||
throw new Exception(_gd.Api.GetProgramInfoLog(programHandle));
|
||||
}
|
||||
|
||||
programHandles[index] = programHandle;
|
||||
|
@ -258,7 +258,7 @@ void main()
|
|||
{
|
||||
if (_msToNonMSProgramHandles[i] != 0)
|
||||
{
|
||||
GL.DeleteProgram(_msToNonMSProgramHandles[i]);
|
||||
_gd.Api.DeleteProgram(_msToNonMSProgramHandles[i]);
|
||||
_msToNonMSProgramHandles[i] = 0;
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ void main()
|
|||
{
|
||||
if (_nonMSToMSProgramHandles[i] != 0)
|
||||
{
|
||||
GL.DeleteProgram(_nonMSToMSProgramHandles[i]);
|
||||
_gd.Api.DeleteProgram(_nonMSToMSProgramHandles[i]);
|
||||
_nonMSToMSProgramHandles[i] = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Image
|
||||
{
|
||||
class TextureStorage : ITextureInfo
|
||||
{
|
||||
public ITextureInfo Storage => this;
|
||||
public int Handle { get; private set; }
|
||||
public uint Handle { get; private set; }
|
||||
|
||||
public TextureCreateInfo Info { get; }
|
||||
|
||||
private readonly OpenGLRenderer _renderer;
|
||||
private readonly OpenGLRenderer _gd;
|
||||
|
||||
private int _viewsCount;
|
||||
|
||||
internal ITexture DefaultView { get; private set; }
|
||||
|
||||
public TextureStorage(OpenGLRenderer renderer, TextureCreateInfo info)
|
||||
public TextureStorage(OpenGLRenderer gd, TextureCreateInfo info)
|
||||
{
|
||||
_renderer = renderer;
|
||||
_gd = gd;
|
||||
Info = info;
|
||||
|
||||
Handle = GL.GenTexture();
|
||||
Handle = _gd.Api.GenTexture();
|
||||
|
||||
CreateImmutableStorage();
|
||||
}
|
||||
|
@ -31,9 +31,9 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
TextureTarget target = Info.Target.Convert();
|
||||
|
||||
GL.ActiveTexture(TextureUnit.Texture0);
|
||||
_gd.Api.ActiveTexture(TextureUnit.Texture0);
|
||||
|
||||
GL.BindTexture(target, Handle);
|
||||
_gd.Api.BindTexture(target, Handle);
|
||||
|
||||
FormatInfo format = FormatTable.GetFormatInfo(Info.Format);
|
||||
|
||||
|
@ -45,97 +45,97 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
}
|
||||
else
|
||||
{
|
||||
internalFormat = (SizedInternalFormat)format.PixelInternalFormat;
|
||||
internalFormat = (SizedInternalFormat)format.InternalFormat;
|
||||
}
|
||||
|
||||
int levels = Info.GetLevelsClamped();
|
||||
uint levels = (uint)Info.GetLevelsClamped();
|
||||
|
||||
switch (Info.Target)
|
||||
{
|
||||
case Target.Texture1D:
|
||||
GL.TexStorage1D(
|
||||
TextureTarget1d.Texture1D,
|
||||
_gd.Api.TexStorage1D(
|
||||
TextureTarget.Texture1D,
|
||||
levels,
|
||||
internalFormat,
|
||||
Info.Width);
|
||||
(uint)Info.Width);
|
||||
break;
|
||||
|
||||
case Target.Texture1DArray:
|
||||
GL.TexStorage2D(
|
||||
TextureTarget2d.Texture1DArray,
|
||||
_gd.Api.TexStorage2D(
|
||||
TextureTarget.Texture1DArray,
|
||||
levels,
|
||||
internalFormat,
|
||||
Info.Width,
|
||||
Info.Height);
|
||||
(uint)Info.Width,
|
||||
(uint)Info.Height);
|
||||
break;
|
||||
|
||||
case Target.Texture2D:
|
||||
GL.TexStorage2D(
|
||||
TextureTarget2d.Texture2D,
|
||||
_gd.Api.TexStorage2D(
|
||||
TextureTarget.Texture2D,
|
||||
levels,
|
||||
internalFormat,
|
||||
Info.Width,
|
||||
Info.Height);
|
||||
(uint)Info.Width,
|
||||
(uint)Info.Height);
|
||||
break;
|
||||
|
||||
case Target.Texture2DArray:
|
||||
GL.TexStorage3D(
|
||||
TextureTarget3d.Texture2DArray,
|
||||
_gd.Api.TexStorage3D(
|
||||
TextureTarget.Texture2DArray,
|
||||
levels,
|
||||
internalFormat,
|
||||
Info.Width,
|
||||
Info.Height,
|
||||
Info.Depth);
|
||||
(uint)Info.Width,
|
||||
(uint)Info.Height,
|
||||
(uint)Info.Depth);
|
||||
break;
|
||||
|
||||
case Target.Texture2DMultisample:
|
||||
GL.TexStorage2DMultisample(
|
||||
TextureTargetMultisample2d.Texture2DMultisample,
|
||||
Info.Samples,
|
||||
_gd.Api.TexStorage2DMultisample(
|
||||
TextureTarget.Texture2DMultisample,
|
||||
(uint)Info.Samples,
|
||||
internalFormat,
|
||||
Info.Width,
|
||||
Info.Height,
|
||||
(uint)Info.Width,
|
||||
(uint)Info.Height,
|
||||
true);
|
||||
break;
|
||||
|
||||
case Target.Texture2DMultisampleArray:
|
||||
GL.TexStorage3DMultisample(
|
||||
TextureTargetMultisample3d.Texture2DMultisampleArray,
|
||||
Info.Samples,
|
||||
_gd.Api.TexStorage3DMultisample(
|
||||
TextureTarget.Texture2DMultisampleArray,
|
||||
(uint)Info.Samples,
|
||||
internalFormat,
|
||||
Info.Width,
|
||||
Info.Height,
|
||||
Info.Depth,
|
||||
(uint)Info.Width,
|
||||
(uint)Info.Height,
|
||||
(uint)Info.Depth,
|
||||
true);
|
||||
break;
|
||||
|
||||
case Target.Texture3D:
|
||||
GL.TexStorage3D(
|
||||
TextureTarget3d.Texture3D,
|
||||
_gd.Api.TexStorage3D(
|
||||
TextureTarget.Texture3D,
|
||||
levels,
|
||||
internalFormat,
|
||||
Info.Width,
|
||||
Info.Height,
|
||||
Info.Depth);
|
||||
(uint)Info.Width,
|
||||
(uint)Info.Height,
|
||||
(uint)Info.Depth);
|
||||
break;
|
||||
|
||||
case Target.Cubemap:
|
||||
GL.TexStorage2D(
|
||||
TextureTarget2d.TextureCubeMap,
|
||||
_gd.Api.TexStorage2D(
|
||||
TextureTarget.TextureCubeMap,
|
||||
levels,
|
||||
internalFormat,
|
||||
Info.Width,
|
||||
Info.Height);
|
||||
(uint)Info.Width,
|
||||
(uint)Info.Height);
|
||||
break;
|
||||
|
||||
case Target.CubemapArray:
|
||||
GL.TexStorage3D(
|
||||
(TextureTarget3d)All.TextureCubeMapArray,
|
||||
_gd.Api.TexStorage3D(
|
||||
TextureTarget.TextureCubeMapArray,
|
||||
levels,
|
||||
internalFormat,
|
||||
Info.Width,
|
||||
Info.Height,
|
||||
Info.Depth);
|
||||
(uint)Info.Width,
|
||||
(uint)Info.Height,
|
||||
(uint)Info.Depth);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -151,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()
|
||||
|
@ -187,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()
|
||||
|
@ -201,7 +201,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
if (Handle != 0)
|
||||
{
|
||||
GL.DeleteTexture(Handle);
|
||||
_gd.Api.DeleteTexture(Handle);
|
||||
|
||||
Handle = 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Diagnostics;
|
||||
|
@ -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);
|
||||
|
||||
PixelInternalFormat pixelInternalFormat;
|
||||
SizedInternalFormat pixelInternalFormat;
|
||||
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
pixelInternalFormat = (PixelInternalFormat)format.PixelFormat;
|
||||
pixelInternalFormat = (SizedInternalFormat)format.PixelFormat;
|
||||
}
|
||||
else
|
||||
{
|
||||
pixelInternalFormat = format.PixelInternalFormat;
|
||||
pixelInternalFormat = (SizedInternalFormat)format.InternalFormat;
|
||||
}
|
||||
|
||||
int levels = Info.GetLevelsClamped();
|
||||
uint levels = (uint)Info.GetLevelsClamped();
|
||||
|
||||
GL.TextureView(
|
||||
_gd.Api.TextureView(
|
||||
Handle,
|
||||
target,
|
||||
_parent.Handle,
|
||||
|
@ -61,19 +58,19 @@ 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[]
|
||||
{
|
||||
int[] swizzleRgba =
|
||||
[
|
||||
(int)Info.SwizzleR.Convert(),
|
||||
(int)Info.SwizzleG.Convert(),
|
||||
(int)Info.SwizzleB.Convert(),
|
||||
(int)Info.SwizzleA.Convert(),
|
||||
};
|
||||
(int)Info.SwizzleA.Convert()
|
||||
];
|
||||
|
||||
if (Info.Format == Format.A1B5G5R5Unorm)
|
||||
{
|
||||
|
@ -91,25 +88,25 @@ 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)
|
||||
{
|
||||
firstLayer += FirstLayer;
|
||||
firstLevel += FirstLevel;
|
||||
firstLayer += (int)FirstLayer;
|
||||
firstLevel += (int)FirstLevel;
|
||||
|
||||
return _parent.CreateView(info, firstLayer, firstLevel);
|
||||
return _parent.CreateView(info, (uint)firstLayer, (uint)firstLevel);
|
||||
}
|
||||
|
||||
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
|
||||
|
@ -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 = (uint)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 = (uint)Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
|
||||
_gd.TextureCopyMS.CopyMSToNonMS(this, destinationView, 0, firstLayer, (int)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 = (uint)Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
|
||||
_gd.TextureCopyMS.CopyNonMSToMS(this, destinationView, 0, firstLayer, (int)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, (int)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, (int)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()
|
||||
|
@ -276,13 +273,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
ReadOnlySpan<byte> data;
|
||||
|
||||
if (HwCapabilities.UsePersistentBufferForFlush)
|
||||
if (_gd.Capabilities.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);
|
||||
|
||||
|
@ -301,13 +298,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
int size = Info.GetMipSize(level);
|
||||
|
||||
if (HwCapabilities.UsePersistentBufferForFlush)
|
||||
if (_gd.Capabilities.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(BufferTarget.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(BufferTarget.PixelPackBuffer, 0);
|
||||
_gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
|
||||
}
|
||||
|
||||
public void WriteToPbo(int offset, bool forceBgra)
|
||||
|
@ -347,7 +344,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
return WriteTo2D(IntPtr.Zero + offset, layer, level);
|
||||
}
|
||||
|
||||
private int WriteTo2D(IntPtr data, int layer, int level)
|
||||
private unsafe int WriteTo2D(IntPtr data, int layer, int level)
|
||||
{
|
||||
TextureTarget target = Target.Convert();
|
||||
|
||||
|
@ -367,15 +364,37 @@ 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,
|
||||
(uint)Math.Max(1, Info.Width >> level),
|
||||
(uint)Math.Max(1, Info.Height >> level),
|
||||
1,
|
||||
(uint)mipSize,
|
||||
(void*)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,
|
||||
(uint)Math.Max(1, Info.Width >> level),
|
||||
(uint)Math.Max(1, Info.Height >> level),
|
||||
1,
|
||||
pixelFormat,
|
||||
pixelType,
|
||||
(uint)mipSize,
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.GetTexImage(target, level, pixelFormat, pixelType, data);
|
||||
_gd.Api.GetTexImage(target, level, pixelFormat, pixelType, (void*)data);
|
||||
|
||||
// The GL function returns all layers. Must return the offset of the layer we're interested in.
|
||||
return target switch
|
||||
|
@ -390,7 +409,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
return 0;
|
||||
}
|
||||
|
||||
private void WriteTo(IntPtr data, bool forceBgra = false)
|
||||
private unsafe void WriteTo(IntPtr data, bool forceBgra = false)
|
||||
{
|
||||
TextureTarget target = Target.Convert();
|
||||
|
||||
|
@ -405,9 +424,9 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
if (pixelType == PixelType.UnsignedShort565)
|
||||
{
|
||||
pixelType = PixelType.UnsignedShort565Reversed;
|
||||
pixelType = PixelType.UnsignedShort565Rev;
|
||||
}
|
||||
else if (pixelType == PixelType.UnsignedShort565Reversed)
|
||||
else if (pixelType == PixelType.UnsignedShort565Rev)
|
||||
{
|
||||
pixelType = PixelType.UnsignedShort565;
|
||||
}
|
||||
|
@ -436,11 +455,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
GL.GetCompressedTexImage(target + face, level, data + faceOffset);
|
||||
_gd.Api.GetCompressedTexImage(target + face, level, (void*)(data + faceOffset));
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.GetTexImage(target + face, level, pixelFormat, pixelType, data + faceOffset);
|
||||
_gd.Api.GetTexImage(target + face, level, pixelFormat, pixelType, (void*)(data + faceOffset));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -535,7 +554,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
return data;
|
||||
}
|
||||
|
||||
private void ReadFrom2D(IntPtr data, int layer, int level, int x, int y, int width, int height, int mipSize)
|
||||
private unsafe void ReadFrom2D(IntPtr data, int layer, int level, int x, int y, int width, int height, int mipSize)
|
||||
{
|
||||
TextureTarget target = Target.Convert();
|
||||
|
||||
|
@ -548,83 +567,83 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
case Target.Texture1D:
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
GL.CompressedTexSubImage1D(
|
||||
_gd.Api.CompressedTexSubImage1D(
|
||||
target,
|
||||
level,
|
||||
x,
|
||||
width,
|
||||
format.PixelFormat,
|
||||
mipSize,
|
||||
data);
|
||||
(uint)width,
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.TexSubImage1D(
|
||||
_gd.Api.TexSubImage1D(
|
||||
target,
|
||||
level,
|
||||
x,
|
||||
width,
|
||||
(uint)width,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
case Target.Texture1DArray:
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
GL.CompressedTexSubImage2D(
|
||||
_gd.Api.CompressedTexSubImage2D(
|
||||
target,
|
||||
level,
|
||||
x,
|
||||
layer,
|
||||
width,
|
||||
(uint)width,
|
||||
1,
|
||||
format.PixelFormat,
|
||||
mipSize,
|
||||
data);
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.TexSubImage2D(
|
||||
_gd.Api.TexSubImage2D(
|
||||
target,
|
||||
level,
|
||||
x,
|
||||
layer,
|
||||
width,
|
||||
(uint)width,
|
||||
1,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
case Target.Texture2D:
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
GL.CompressedTexSubImage2D(
|
||||
_gd.Api.CompressedTexSubImage2D(
|
||||
target,
|
||||
level,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
format.PixelFormat,
|
||||
mipSize,
|
||||
data);
|
||||
(uint)width,
|
||||
(uint)height,
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.TexSubImage2D(
|
||||
_gd.Api.TexSubImage2D(
|
||||
target,
|
||||
level,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
(uint)width,
|
||||
(uint)height,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -633,77 +652,77 @@ 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,
|
||||
data);
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.TexSubImage3D(
|
||||
_gd.Api.TexSubImage3D(
|
||||
target,
|
||||
level,
|
||||
x,
|
||||
y,
|
||||
layer,
|
||||
width,
|
||||
height,
|
||||
(uint)width,
|
||||
(uint)height,
|
||||
1,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
case Target.Cubemap:
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
GL.CompressedTexSubImage2D(
|
||||
_gd.Api.CompressedTexSubImage2D(
|
||||
TextureTarget.TextureCubeMapPositiveX + layer,
|
||||
level,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
format.PixelFormat,
|
||||
mipSize,
|
||||
data);
|
||||
(uint)width,
|
||||
(uint)height,
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.TexSubImage2D(
|
||||
_gd.Api.TexSubImage2D(
|
||||
TextureTarget.TextureCubeMapPositiveX + layer,
|
||||
level,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
(uint)width,
|
||||
(uint)height,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadFrom(IntPtr data, int size)
|
||||
private unsafe 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)
|
||||
if (Target == Target.Cubemap && _gd.Capabilities.GpuVendor == 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
|
||||
|
@ -713,9 +732,9 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
FormatInfo format = FormatTable.GetFormatInfo(Info.Format);
|
||||
|
||||
int width = Info.Width;
|
||||
int height = Info.Height;
|
||||
int depth = Info.Depth;
|
||||
uint width = (uint)Info.Width;
|
||||
uint height = (uint)Info.Height;
|
||||
uint depth = (uint)Info.Depth;
|
||||
int levels = Info.GetLevelsClamped();
|
||||
|
||||
int offset = 0;
|
||||
|
@ -736,25 +755,25 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
case Target.Texture1D:
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
GL.CompressedTexSubImage1D(
|
||||
_gd.Api.CompressedTexSubImage1D(
|
||||
target,
|
||||
level,
|
||||
0,
|
||||
width,
|
||||
format.PixelFormat,
|
||||
mipSize,
|
||||
data);
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.TexSubImage1D(
|
||||
_gd.Api.TexSubImage1D(
|
||||
target,
|
||||
level,
|
||||
0,
|
||||
width,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -762,20 +781,20 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
case Target.Texture2D:
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
GL.CompressedTexSubImage2D(
|
||||
_gd.Api.CompressedTexSubImage2D(
|
||||
target,
|
||||
level,
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
format.PixelFormat,
|
||||
mipSize,
|
||||
data);
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.TexSubImage2D(
|
||||
_gd.Api.TexSubImage2D(
|
||||
target,
|
||||
level,
|
||||
0,
|
||||
|
@ -784,7 +803,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
height,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -793,7 +812,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
case Target.CubemapArray:
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
GL.CompressedTexSubImage3D(
|
||||
_gd.Api.CompressedTexSubImage3D(
|
||||
target,
|
||||
level,
|
||||
0,
|
||||
|
@ -802,13 +821,13 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
width,
|
||||
height,
|
||||
depth,
|
||||
format.PixelFormat,
|
||||
mipSize,
|
||||
data);
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.TexSubImage3D(
|
||||
_gd.Api.TexSubImage3D(
|
||||
target,
|
||||
level,
|
||||
0,
|
||||
|
@ -819,7 +838,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
depth,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -830,29 +849,29 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
GL.CompressedTexSubImage2D(
|
||||
_gd.Api.CompressedTexSubImage2D(
|
||||
TextureTarget.TextureCubeMapPositiveX + face,
|
||||
baseLevel + level,
|
||||
(int)baseLevel + level,
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
format.PixelFormat,
|
||||
mipSize / 6,
|
||||
data + faceOffset);
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize / 6,
|
||||
(void*)(data + faceOffset));
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.TexSubImage2D(
|
||||
_gd.Api.TexSubImage2D(
|
||||
TextureTarget.TextureCubeMapPositiveX + face,
|
||||
baseLevel + level,
|
||||
(int)baseLevel + level,
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data + faceOffset);
|
||||
(void*)(data + faceOffset));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -880,7 +899,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
if (Handle != 0)
|
||||
{
|
||||
GL.DeleteTexture(Handle);
|
||||
_gd.Api.DeleteTexture(Handle);
|
||||
|
||||
Handle = 0;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.OpenGL.Image;
|
||||
using Ryujinx.Graphics.OpenGL.Queries;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using Silk.NET.OpenGL.Legacy.Extensions.ARB;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
{
|
||||
public sealed class OpenGLRenderer : IRenderer
|
||||
{
|
||||
public readonly GL Api;
|
||||
private readonly Pipeline _pipeline;
|
||||
|
||||
public IPipeline Pipeline => _pipeline;
|
||||
|
@ -37,45 +41,46 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
internal int BufferCount { get; private set; }
|
||||
|
||||
internal HardwareCapabilities Capabilities;
|
||||
|
||||
public string GpuVendor { get; private set; }
|
||||
public string GpuRenderer { get; private set; }
|
||||
public string GpuVersion { get; private set; }
|
||||
|
||||
public bool PreferThreading => true;
|
||||
|
||||
public OpenGLRenderer()
|
||||
public OpenGLRenderer(GL api)
|
||||
{
|
||||
_pipeline = new Pipeline();
|
||||
_counters = new Counters();
|
||||
Api = api;
|
||||
_pipeline = new Pipeline(this);
|
||||
_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();
|
||||
PersistentBuffers = new PersistentBuffers();
|
||||
_sync = new Sync(this);
|
||||
PersistentBuffers = new PersistentBuffers(Api);
|
||||
ResourcePool = new ResourcePool();
|
||||
}
|
||||
|
||||
public BufferHandle CreateBuffer(int size, GAL.BufferAccess access)
|
||||
public BufferHandle CreateBuffer(int size, BufferAccess access)
|
||||
{
|
||||
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);
|
||||
|
||||
return handle;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Buffer.Create(size);
|
||||
}
|
||||
|
||||
return Buffer.Create(Api, size);
|
||||
}
|
||||
|
||||
public BufferHandle CreateBuffer(int size, GAL.BufferAccess access, BufferHandle storageHint)
|
||||
public BufferHandle CreateBuffer(int size, BufferAccess access, BufferHandle storageHint)
|
||||
{
|
||||
return CreateBuffer(size, access);
|
||||
}
|
||||
|
@ -92,17 +97,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(this, shaders, info.FragmentOutputMap);
|
||||
}
|
||||
|
||||
public ISampler CreateSampler(SamplerCreateInfo info)
|
||||
{
|
||||
return new Sampler(info);
|
||||
return new Sampler(this, info);
|
||||
}
|
||||
|
||||
public ITexture CreateTexture(TextureCreateInfo info)
|
||||
|
@ -111,22 +116,20 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
return new TextureBuffer(this, info);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ResourcePool.GetTextureOrNull(info) ?? new TextureStorage(this, info).CreateDefaultView();
|
||||
}
|
||||
|
||||
return ResourcePool.GetTextureOrNull(info) ?? new TextureStorage(this, info).CreateDefaultView();
|
||||
}
|
||||
|
||||
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()
|
||||
|
@ -141,9 +144,9 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
public Capabilities GetCapabilities()
|
||||
{
|
||||
bool intelWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelWindows;
|
||||
bool intelUnix = HwCapabilities.Vendor == HwCapabilities.GpuVendor.IntelUnix;
|
||||
bool amdWindows = HwCapabilities.Vendor == HwCapabilities.GpuVendor.AmdWindows;
|
||||
bool intelWindows = Capabilities.GpuVendor == OpenGL.GpuVendor.IntelWindows;
|
||||
bool intelUnix = Capabilities.GpuVendor == OpenGL.GpuVendor.IntelUnix;
|
||||
bool amdWindows = Capabilities.GpuVendor == OpenGL.GpuVendor.AmdWindows;
|
||||
|
||||
return new Capabilities(
|
||||
api: TargetApi.OpenGL,
|
||||
|
@ -152,9 +155,9 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
hasVectorIndexingBug: amdWindows,
|
||||
needsFragmentOutputSpecialization: false,
|
||||
reduceShaderPrecision: false,
|
||||
supportsAstcCompression: HwCapabilities.SupportsAstcCompression,
|
||||
supportsBc123Compression: HwCapabilities.SupportsTextureCompressionS3tc,
|
||||
supportsBc45Compression: HwCapabilities.SupportsTextureCompressionRgtc,
|
||||
supportsAstcCompression: Capabilities.SupportsAstcCompression,
|
||||
supportsBc123Compression: Capabilities.SupportsTextureCompressionS3tc,
|
||||
supportsBc45Compression: Capabilities.SupportsTextureCompressionRgtc,
|
||||
supportsBc67Compression: true, // Should check BPTC extension, but for some reason NVIDIA is not exposing the extension.
|
||||
supportsEtc2Compression: true,
|
||||
supports3DTextureCompression: false,
|
||||
|
@ -165,45 +168,45 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
supportsSnormBufferTextureFormat: false,
|
||||
supports5BitComponentFormat: true,
|
||||
supportsSparseBuffer: false,
|
||||
supportsBlendEquationAdvanced: HwCapabilities.SupportsBlendEquationAdvanced,
|
||||
supportsFragmentShaderInterlock: HwCapabilities.SupportsFragmentShaderInterlock,
|
||||
supportsFragmentShaderOrderingIntel: HwCapabilities.SupportsFragmentShaderOrdering,
|
||||
supportsBlendEquationAdvanced: Capabilities.SupportsBlendEquationAdvanced,
|
||||
supportsFragmentShaderInterlock: Capabilities.SupportsFragmentShaderInterlock,
|
||||
supportsFragmentShaderOrderingIntel: Capabilities.SupportsFragmentShaderOrdering,
|
||||
supportsGeometryShader: true,
|
||||
supportsGeometryShaderPassthrough: HwCapabilities.SupportsGeometryShaderPassthrough,
|
||||
supportsGeometryShaderPassthrough: Capabilities.SupportsGeometryShaderPassthrough,
|
||||
supportsTransformFeedback: true,
|
||||
supportsImageLoadFormatted: HwCapabilities.SupportsImageLoadFormatted,
|
||||
supportsLayerVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
|
||||
supportsMismatchingViewFormat: HwCapabilities.SupportsMismatchingViewFormat,
|
||||
supportsImageLoadFormatted: Capabilities.SupportsImageLoadFormatted,
|
||||
supportsLayerVertexTessellation: Capabilities.SupportsShaderViewportLayerArray,
|
||||
supportsMismatchingViewFormat: Capabilities.SupportsMismatchingViewFormat,
|
||||
supportsCubemapView: true,
|
||||
supportsNonConstantTextureOffset: HwCapabilities.SupportsNonConstantTextureOffset,
|
||||
supportsQuads: HwCapabilities.SupportsQuads,
|
||||
supportsNonConstantTextureOffset: Capabilities.SupportsNonConstantTextureOffset,
|
||||
supportsQuads: Capabilities.SupportsQuads,
|
||||
supportsSeparateSampler: false,
|
||||
supportsShaderBallot: HwCapabilities.SupportsShaderBallot,
|
||||
supportsShaderBallot: Capabilities.SupportsShaderBallot,
|
||||
supportsShaderBarrierDivergence: !(intelWindows || intelUnix),
|
||||
supportsShaderFloat64: true,
|
||||
supportsTextureGatherOffsets: true,
|
||||
supportsTextureShadowLod: HwCapabilities.SupportsTextureShadowLod,
|
||||
supportsTextureShadowLod: Capabilities.SupportsTextureShadowLod,
|
||||
supportsVertexStoreAndAtomics: true,
|
||||
supportsViewportIndexVertexTessellation: HwCapabilities.SupportsShaderViewportLayerArray,
|
||||
supportsViewportMask: HwCapabilities.SupportsViewportArray2,
|
||||
supportsViewportSwizzle: HwCapabilities.SupportsViewportSwizzle,
|
||||
supportsIndirectParameters: HwCapabilities.SupportsIndirectParameters,
|
||||
supportsViewportIndexVertexTessellation: Capabilities.SupportsShaderViewportLayerArray,
|
||||
supportsViewportMask: Capabilities.SupportsViewportArray2,
|
||||
supportsViewportSwizzle: Capabilities.SupportsViewportSwizzle,
|
||||
supportsIndirectParameters: Capabilities.SupportsIndirectParameters,
|
||||
supportsDepthClipControl: true,
|
||||
maximumUniformBuffersPerStage: 13, // TODO: Avoid hardcoding those limits here and get from driver?
|
||||
maximumStorageBuffersPerStage: 16,
|
||||
maximumTexturesPerStage: 32,
|
||||
maximumImagesPerStage: 8,
|
||||
maximumComputeSharedMemorySize: HwCapabilities.MaximumComputeSharedMemorySize,
|
||||
maximumSupportedAnisotropy: HwCapabilities.MaximumSupportedAnisotropy,
|
||||
maximumComputeSharedMemorySize: Capabilities.MaximumComputeSharedMemorySize,
|
||||
maximumSupportedAnisotropy: Capabilities.MaximumSupportedAnisotropy,
|
||||
shaderSubgroupSize: Constants.MaxSubgroupSize,
|
||||
storageBufferOffsetAlignment: HwCapabilities.StorageBufferOffsetAlignment,
|
||||
textureBufferOffsetAlignment: HwCapabilities.TextureBufferOffsetAlignment,
|
||||
storageBufferOffsetAlignment: Capabilities.StorageBufferOffsetAlignment,
|
||||
textureBufferOffsetAlignment: Capabilities.TextureBufferOffsetAlignment,
|
||||
gatherBiasPrecision: intelWindows || amdWindows ? 8 : 0); // Precision is 8 for these vendors on Vulkan.
|
||||
}
|
||||
|
||||
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,13 +227,17 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
public void Initialize(GraphicsDebugLevel glLogLevel)
|
||||
{
|
||||
Debugger.Initialize(glLogLevel);
|
||||
Debugger.Initialize(Api, glLogLevel);
|
||||
|
||||
LoadFeatures();
|
||||
|
||||
PrintGpuInformation();
|
||||
|
||||
if (HwCapabilities.SupportsParallelShaderCompile)
|
||||
if (Capabilities.SupportsParallelShaderCompile)
|
||||
{
|
||||
GL.Arb.MaxShaderCompilerThreads(Math.Min(Environment.ProcessorCount, 8));
|
||||
Api.TryGetExtension(out ArbParallelShaderCompile arbParallelShaderCompile);
|
||||
|
||||
arbParallelShaderCompile.MaxShaderCompilerThreads((uint)Math.Min(Environment.ProcessorCount, 8));
|
||||
}
|
||||
|
||||
_counters.Initialize();
|
||||
|
@ -238,15 +245,46 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
// This is required to disable [0, 1] clamping for SNorm outputs on compatibility profiles.
|
||||
// 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(ClampColorTarget.ClampFragmentColor, ClampColorMode.False);
|
||||
// should already have the desired behaviour when outputs are not clamped.
|
||||
Api.ClampColor(ClampColorTargetARB.FragmentColorArb, ClampColorModeARB.False);
|
||||
}
|
||||
|
||||
private void PrintGpuInformation()
|
||||
private void LoadFeatures()
|
||||
{
|
||||
GpuVendor = GL.GetString(StringName.Vendor);
|
||||
GpuRenderer = GL.GetString(StringName.Renderer);
|
||||
GpuVersion = GL.GetString(StringName.Version);
|
||||
Capabilities = new HardwareCapabilities(
|
||||
HardwareCapabilities.HasExtension(Api, "GL_NV_alpha_to_coverage_dither_control"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_KHR_texture_compression_astc_ldr"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_NV_blend_equation_advanced"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_NV_draw_texture"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_ARB_fragment_shader_interlock"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_INTEL_fragment_shader_ordering"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_NV_geometry_shader_passthrough"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_EXT_shader_image_load_formatted"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_ARB_indirect_parameters"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_ARB_parallel_shader_compile"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_EXT_polygon_offset_clamp"),
|
||||
HardwareCapabilities.SupportsQuadsCheck(Api),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_ARB_seamless_cubemap_per_texture"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_ARB_shader_ballot"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_ARB_shader_viewport_layer_array"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_NV_viewport_array2"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_EXT_texture_compression_bptc"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_EXT_texture_compression_rgtc"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_EXT_texture_compression_s3tc"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_EXT_texture_shadow_lod"),
|
||||
HardwareCapabilities.HasExtension(Api, "GL_NV_viewport_swizzle"),
|
||||
Api.GetInteger(GLEnum.MaxComputeSharedMemorySize),
|
||||
Api.GetInteger(GLEnum.ShaderStorageBufferOffsetAlignment),
|
||||
Api.GetInteger(GLEnum.TextureBufferOffsetAlignment),
|
||||
Api.GetFloat(GLEnum.MaxTextureMaxAnisotropy),
|
||||
HardwareCapabilities.GetGpuVendor(Api));
|
||||
}
|
||||
|
||||
private unsafe void PrintGpuInformation()
|
||||
{
|
||||
GpuVendor = Marshal.PtrToStringAnsi((IntPtr)Api.GetString(StringName.Vendor));
|
||||
GpuRenderer = Marshal.PtrToStringAnsi((IntPtr)Api.GetString(StringName.Renderer));
|
||||
GpuVersion = Marshal.PtrToStringAnsi((IntPtr)Api.GetString(StringName.Version));
|
||||
|
||||
Logger.Notice.Print(LogClass.Gpu, $"{GpuVendor} {GpuRenderer} ({GpuVersion})");
|
||||
}
|
||||
|
@ -290,7 +328,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
public IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info)
|
||||
{
|
||||
return new Program(programBinary, hasFragmentShader, info.FragmentOutputMap);
|
||||
return new Program(this, programBinary, hasFragmentShader, info.FragmentOutputMap);
|
||||
}
|
||||
|
||||
public void CreateSync(ulong id, bool strict)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.OpenGL.Image;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
@ -11,33 +11,41 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
class PersistentBuffers : IDisposable
|
||||
{
|
||||
private readonly PersistentBuffer _main = new();
|
||||
private readonly PersistentBuffer _background = new();
|
||||
private readonly GL _api;
|
||||
private readonly PersistentBuffer _main;
|
||||
private readonly PersistentBuffer _background;
|
||||
|
||||
private readonly Dictionary<BufferHandle, IntPtr> _maps = new();
|
||||
|
||||
public PersistentBuffer Default => BackgroundContextWorker.InBackground ? _background : _main;
|
||||
|
||||
public PersistentBuffers(GL api)
|
||||
{
|
||||
_api = api;
|
||||
_main = new(_api);
|
||||
_background = new(_api);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_main?.Dispose();
|
||||
_background?.Dispose();
|
||||
}
|
||||
|
||||
public void Map(BufferHandle handle, int size)
|
||||
public unsafe void Map(BufferHandle handle, int size)
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.CopyWriteBuffer, handle.ToInt32());
|
||||
IntPtr ptr = GL.MapBufferRange(BufferTarget.CopyWriteBuffer, IntPtr.Zero, size, BufferAccessMask.MapReadBit | BufferAccessMask.MapPersistentBit);
|
||||
_api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32());
|
||||
void* ptr = _api.MapBufferRange(BufferTargetARB.CopyWriteBuffer, IntPtr.Zero, (uint)size, MapBufferAccessMask.ReadBit | MapBufferAccessMask.PersistentBit);
|
||||
|
||||
_maps[handle] = ptr;
|
||||
_maps[handle] = (IntPtr)ptr;
|
||||
}
|
||||
|
||||
public void Unmap(BufferHandle handle)
|
||||
{
|
||||
if (_maps.ContainsKey(handle))
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.CopyWriteBuffer, handle.ToInt32());
|
||||
GL.UnmapBuffer(BufferTarget.CopyWriteBuffer);
|
||||
_api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32());
|
||||
_api.UnmapBuffer(BufferTargetARB.CopyWriteBuffer);
|
||||
|
||||
_maps.Remove(handle);
|
||||
}
|
||||
|
@ -51,31 +59,37 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
class PersistentBuffer : IDisposable
|
||||
{
|
||||
private readonly GL _api;
|
||||
private IntPtr _bufferMap;
|
||||
private int _copyBufferHandle;
|
||||
private uint _copyBufferHandle;
|
||||
private int _copyBufferSize;
|
||||
|
||||
private byte[] _data;
|
||||
private IntPtr _dataMap;
|
||||
|
||||
private void EnsureBuffer(int requiredSize)
|
||||
public PersistentBuffer(GL api)
|
||||
{
|
||||
_api = api;
|
||||
}
|
||||
|
||||
private unsafe void EnsureBuffer(int requiredSize)
|
||||
{
|
||||
if (_copyBufferSize < requiredSize && _copyBufferHandle != 0)
|
||||
{
|
||||
GL.DeleteBuffer(_copyBufferHandle);
|
||||
_api.DeleteBuffer(_copyBufferHandle);
|
||||
|
||||
_copyBufferHandle = 0;
|
||||
}
|
||||
|
||||
if (_copyBufferHandle == 0)
|
||||
{
|
||||
_copyBufferHandle = GL.GenBuffer();
|
||||
_copyBufferHandle = _api.GenBuffer();
|
||||
_copyBufferSize = requiredSize;
|
||||
|
||||
GL.BindBuffer(BufferTarget.CopyWriteBuffer, _copyBufferHandle);
|
||||
GL.BufferStorage(BufferTarget.CopyWriteBuffer, requiredSize, IntPtr.Zero, BufferStorageFlags.MapReadBit | BufferStorageFlags.MapPersistentBit);
|
||||
_api.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle);
|
||||
_api.BufferStorage(BufferStorageTarget.CopyWriteBuffer, (uint)requiredSize, null, BufferStorageMask.MapReadBit | BufferStorageMask.MapPersistentBit);
|
||||
|
||||
_bufferMap = GL.MapBufferRange(BufferTarget.CopyWriteBuffer, IntPtr.Zero, requiredSize, BufferAccessMask.MapReadBit | BufferAccessMask.MapPersistentBit);
|
||||
_bufferMap = (IntPtr)_api.MapBufferRange(BufferTargetARB.CopyWriteBuffer, IntPtr.Zero, (uint)requiredSize, MapBufferAccessMask.ReadBit | MapBufferAccessMask.PersistentBit);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,30 +105,30 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
return _dataMap;
|
||||
}
|
||||
|
||||
private static void Sync()
|
||||
private void Sync()
|
||||
{
|
||||
GL.MemoryBarrier(MemoryBarrierFlags.ClientMappedBufferBarrierBit);
|
||||
_api.MemoryBarrier(MemoryBarrierMask.ClientMappedBufferBarrierBit);
|
||||
|
||||
IntPtr sync = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None);
|
||||
WaitSyncStatus syncResult = GL.ClientWaitSync(sync, ClientWaitSyncFlags.SyncFlushCommandsBit, 1000000000);
|
||||
IntPtr sync = _api.FenceSync(SyncCondition.SyncGpuCommandsComplete, SyncBehaviorFlags.None);
|
||||
GLEnum syncResult = _api.ClientWaitSync(sync, SyncObjectMask.Bit, 1000000000);
|
||||
|
||||
if (syncResult == WaitSyncStatus.TimeoutExpired)
|
||||
if (syncResult == GLEnum.TimeoutExpired)
|
||||
{
|
||||
Logger.Error?.PrintMsg(LogClass.Gpu, $"Failed to sync persistent buffer state within 1000ms. Continuing...");
|
||||
}
|
||||
|
||||
GL.DeleteSync(sync);
|
||||
_api.DeleteSync(sync);
|
||||
}
|
||||
|
||||
public unsafe ReadOnlySpan<byte> GetTextureData(TextureView view, int size)
|
||||
{
|
||||
EnsureBuffer(size);
|
||||
|
||||
GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyBufferHandle);
|
||||
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle);
|
||||
|
||||
view.WriteToPbo(0, false);
|
||||
|
||||
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
|
||||
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
|
||||
|
||||
Sync();
|
||||
|
||||
|
@ -125,11 +139,11 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
EnsureBuffer(size);
|
||||
|
||||
GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyBufferHandle);
|
||||
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle);
|
||||
|
||||
int offset = view.WriteToPbo2D(0, layer, level);
|
||||
|
||||
GL.BindBuffer(BufferTarget.PixelPackBuffer, 0);
|
||||
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
|
||||
|
||||
Sync();
|
||||
|
||||
|
@ -140,12 +154,12 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
EnsureBuffer(size);
|
||||
|
||||
GL.BindBuffer(BufferTarget.CopyReadBuffer, buffer.ToInt32());
|
||||
GL.BindBuffer(BufferTarget.CopyWriteBuffer, _copyBufferHandle);
|
||||
_api.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32());
|
||||
_api.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle);
|
||||
|
||||
GL.CopyBufferSubData(BufferTarget.CopyReadBuffer, BufferTarget.CopyWriteBuffer, (IntPtr)offset, IntPtr.Zero, size);
|
||||
_api.CopyBufferSubData(CopyBufferSubDataTarget.CopyReadBuffer, CopyBufferSubDataTarget.CopyWriteBuffer, offset, IntPtr.Zero, (uint)size);
|
||||
|
||||
GL.BindBuffer(BufferTarget.CopyWriteBuffer, 0);
|
||||
_api.BindBuffer(BufferTargetARB.CopyWriteBuffer, 0);
|
||||
|
||||
Sync();
|
||||
|
||||
|
@ -156,7 +170,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
if (_copyBufferHandle != 0)
|
||||
{
|
||||
GL.DeleteBuffer(_copyBufferHandle);
|
||||
_api.DeleteBuffer(_copyBufferHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,9 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Ryujinx.Graphics.Shader.Translation;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using Silk.NET.OpenGL.Legacy.Extensions.ARB;
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
|
||||
|
@ -12,7 +13,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 +28,20 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
}
|
||||
}
|
||||
|
||||
private readonly OpenGLRenderer _gd;
|
||||
private ProgramLinkStatus _status = ProgramLinkStatus.Incomplete;
|
||||
private int[] _shaderHandles;
|
||||
private uint[] _shaderHandles;
|
||||
|
||||
public int FragmentOutputMap { get; }
|
||||
|
||||
public Program(ShaderSource[] shaders, int fragmentOutputMap)
|
||||
public unsafe Program(OpenGLRenderer gd, ShaderSource[] shaders, int fragmentOutputMap)
|
||||
{
|
||||
Handle = GL.CreateProgram();
|
||||
_gd = gd;
|
||||
Handle = _gd.Api.CreateProgram();
|
||||
|
||||
GL.ProgramParameter(Handle, ProgramParameterName.ProgramBinaryRetrievableHint, 1);
|
||||
_gd.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 +53,47 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
hasFragmentShader = true;
|
||||
}
|
||||
|
||||
int shaderHandle = GL.CreateShader(shader.Stage.Convert());
|
||||
uint shaderHandle = _gd.Api.CreateShader(shader.Stage.Convert());
|
||||
|
||||
switch (shader.Language)
|
||||
{
|
||||
case TargetLanguage.Glsl:
|
||||
GL.ShaderSource(shaderHandle, shader.Code);
|
||||
GL.CompileShader(shaderHandle);
|
||||
_gd.Api.ShaderSource(shaderHandle, shader.Code);
|
||||
_gd.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);
|
||||
fixed (byte* ptr = shader.BinaryCode)
|
||||
{
|
||||
_gd.Api.ShaderBinary(1, in shaderHandle, ShaderBinaryFormat.ShaderBinaryFormatSpirV, ptr, (uint)shader.BinaryCode.Length);
|
||||
}
|
||||
_gd.Api.SpecializeShader(shaderHandle, "main", 0, (uint[])null, (uint[])null);
|
||||
break;
|
||||
}
|
||||
|
||||
GL.AttachShader(Handle, shaderHandle);
|
||||
_gd.Api.AttachShader(Handle, shaderHandle);
|
||||
|
||||
_shaderHandles[index] = shaderHandle;
|
||||
}
|
||||
|
||||
GL.LinkProgram(Handle);
|
||||
_gd.Api.LinkProgram(Handle);
|
||||
|
||||
FragmentOutputMap = hasFragmentShader ? fragmentOutputMap : 0;
|
||||
}
|
||||
|
||||
public Program(ReadOnlySpan<byte> code, bool hasFragmentShader, int fragmentOutputMap)
|
||||
public Program(OpenGLRenderer gd, ReadOnlySpan<byte> code, bool hasFragmentShader, int fragmentOutputMap)
|
||||
{
|
||||
Handle = GL.CreateProgram();
|
||||
_gd = gd;
|
||||
Handle = _gd.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);
|
||||
_gd.Api.ProgramBinary(Handle, (GLEnum)binaryFormat, ptr, (uint)code.Length - 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -96,14 +103,14 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
public void Bind()
|
||||
{
|
||||
GL.UseProgram(Handle);
|
||||
_gd.Api.UseProgram(Handle);
|
||||
}
|
||||
|
||||
public ProgramLinkStatus CheckProgramLink(bool blocking)
|
||||
{
|
||||
if (!blocking && HwCapabilities.SupportsParallelShaderCompile)
|
||||
if (!blocking && _gd.Capabilities.SupportsParallelShaderCompile)
|
||||
{
|
||||
GL.GetProgram(Handle, (GetProgramParameterName)ArbParallelShaderCompile.CompletionStatusArb, out int completed);
|
||||
_gd.Api.GetProgram(Handle, (GLEnum)ARB.CompletionStatusArb, out int completed);
|
||||
|
||||
if (completed == 0)
|
||||
{
|
||||
|
@ -111,14 +118,14 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
}
|
||||
}
|
||||
|
||||
GL.GetProgram(Handle, GetProgramParameterName.LinkStatus, out int status);
|
||||
_gd.Api.GetProgram(Handle, ProgramPropertyARB.LinkStatus, out int status);
|
||||
DeleteShaders();
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
_status = ProgramLinkStatus.Failure;
|
||||
|
||||
string log = GL.GetProgramInfoLog(Handle);
|
||||
string log = _gd.Api.GetProgramInfoLog(Handle);
|
||||
|
||||
if (log.Length > MaxShaderLogLength)
|
||||
{
|
||||
|
@ -135,13 +142,17 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
return _status;
|
||||
}
|
||||
|
||||
public byte[] GetBinary()
|
||||
public unsafe byte[] GetBinary()
|
||||
{
|
||||
GL.GetProgram(Handle, (GetProgramParameterName)All.ProgramBinaryLength, out int size);
|
||||
_gd.Api.GetProgram(Handle, ProgramPropertyARB.ProgramBinaryLength, out int size);
|
||||
|
||||
byte[] data = new byte[size + 4];
|
||||
GLEnum binFormat;
|
||||
|
||||
GL.GetProgramBinary(Handle, size, out _, out BinaryFormat binFormat, data);
|
||||
fixed (byte* ptr = data)
|
||||
{
|
||||
_gd.Api.GetProgramBinary(Handle, (uint)size, out _, out binFormat, ptr);
|
||||
}
|
||||
|
||||
BinaryPrimitives.WriteInt32LittleEndian(data.AsSpan(size, 4), (int)binFormat);
|
||||
|
||||
|
@ -152,10 +163,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);
|
||||
_gd.Api.DetachShader(Handle, shaderHandle);
|
||||
_gd.Api.DeleteShader(shaderHandle);
|
||||
}
|
||||
|
||||
_shaderHandles = null;
|
||||
|
@ -167,7 +178,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
if (Handle != 0)
|
||||
{
|
||||
DeleteShaders();
|
||||
GL.DeleteProgram(Handle);
|
||||
_gd.Api.DeleteProgram(Handle);
|
||||
|
||||
Handle = 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
@ -12,50 +12,53 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
private const long DefaultValue = -1;
|
||||
private const ulong HighMask = 0xFFFFFFFF00000000;
|
||||
|
||||
public int Query { get; }
|
||||
public uint Query { get; }
|
||||
|
||||
private readonly int _buffer;
|
||||
private readonly uint _buffer;
|
||||
private readonly IntPtr _bufferMap;
|
||||
private readonly QueryTarget _type;
|
||||
private readonly GL _api;
|
||||
|
||||
public BufferedQuery(QueryTarget type)
|
||||
public BufferedQuery(GL api, QueryTarget type)
|
||||
{
|
||||
_buffer = GL.GenBuffer();
|
||||
Query = GL.GenQuery();
|
||||
_api = api;
|
||||
_buffer = _api.GenBuffer();
|
||||
Query = _api.GenQuery();
|
||||
_type = type;
|
||||
|
||||
GL.BindBuffer(BufferTarget.QueryBuffer, _buffer);
|
||||
_api.BindBuffer(BufferTargetARB.QueryBuffer, _buffer);
|
||||
|
||||
var defaultValue = DefaultValue;
|
||||
_api.BufferStorage(BufferStorageTarget.QueryBuffer, sizeof(long), in defaultValue, BufferStorageMask.MapReadBit | BufferStorageMask.MapWriteBit | BufferStorageMask.MapPersistentBit);
|
||||
|
||||
unsafe
|
||||
{
|
||||
long defaultValue = DefaultValue;
|
||||
GL.BufferStorage(BufferTarget.QueryBuffer, sizeof(long), (IntPtr)(&defaultValue), BufferStorageFlags.MapReadBit | BufferStorageFlags.MapWriteBit | BufferStorageFlags.MapPersistentBit);
|
||||
_bufferMap = (IntPtr)_api.MapBufferRange(BufferTargetARB.QueryBuffer, IntPtr.Zero, sizeof(long), MapBufferAccessMask.ReadBit | MapBufferAccessMask.WriteBit | MapBufferAccessMask.PersistentBit);
|
||||
}
|
||||
_bufferMap = GL.MapBufferRange(BufferTarget.QueryBuffer, IntPtr.Zero, sizeof(long), BufferAccessMask.MapReadBit | BufferAccessMask.MapWriteBit | BufferAccessMask.MapPersistentBit);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
GL.EndQuery(_type);
|
||||
GL.BeginQuery(_type, Query);
|
||||
_api.EndQuery(_type);
|
||||
_api.BeginQuery(_type, Query);
|
||||
}
|
||||
|
||||
public void Begin()
|
||||
{
|
||||
GL.BeginQuery(_type, Query);
|
||||
_api.BeginQuery(_type, Query);
|
||||
}
|
||||
|
||||
public unsafe void End(bool withResult)
|
||||
{
|
||||
GL.EndQuery(_type);
|
||||
_api.EndQuery(_type);
|
||||
|
||||
if (withResult)
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.QueryBuffer, _buffer);
|
||||
_api.BindBuffer(BufferTargetARB.QueryBuffer, _buffer);
|
||||
|
||||
Marshal.WriteInt64(_bufferMap, -1L);
|
||||
GL.GetQueryObject(Query, GetQueryObjectParam.QueryResult, (long*)0);
|
||||
GL.MemoryBarrier(MemoryBarrierFlags.QueryBufferBarrierBit | MemoryBarrierFlags.ClientMappedBufferBarrierBit);
|
||||
_api.GetQueryObject(Query, QueryObjectParameterName.Result, (long*)0);
|
||||
_api.MemoryBarrier(MemoryBarrierMask.QueryBufferBarrierBit | MemoryBarrierMask.ClientMappedBufferBarrierBit);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -111,10 +114,10 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.QueryBuffer, _buffer);
|
||||
GL.UnmapBuffer(BufferTarget.QueryBuffer);
|
||||
GL.DeleteBuffer(_buffer);
|
||||
GL.DeleteQuery(Query);
|
||||
_api.BindBuffer(BufferTargetARB.QueryBuffer, _buffer);
|
||||
_api.UnmapBuffer(BufferTargetARB.QueryBuffer);
|
||||
_api.DeleteBuffer(_buffer);
|
||||
_api.DeleteQuery(Query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
@ -28,7 +28,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
|
||||
private readonly Thread _consumerThread;
|
||||
|
||||
internal CounterQueue(CounterType type)
|
||||
internal CounterQueue(GL api, CounterType type)
|
||||
{
|
||||
Type = type;
|
||||
|
||||
|
@ -37,10 +37,10 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
_queryPool = new Queue<BufferedQuery>(QueryPoolInitialSize);
|
||||
for (int i = 0; i < QueryPoolInitialSize; i++)
|
||||
{
|
||||
_queryPool.Enqueue(new BufferedQuery(glType));
|
||||
_queryPool.Enqueue(new BufferedQuery(api, glType));
|
||||
}
|
||||
|
||||
_current = new CounterQueueEvent(this, glType, 0);
|
||||
_current = new CounterQueueEvent(api, this, glType, 0);
|
||||
|
||||
_consumerThread = new Thread(EventConsumer);
|
||||
_consumerThread.Start();
|
||||
|
@ -76,7 +76,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
}
|
||||
}
|
||||
|
||||
internal BufferedQuery GetQueryObject()
|
||||
internal BufferedQuery GetQueryObject(GL api)
|
||||
{
|
||||
// Creating/disposing query objects on a context we're sharing with will cause issues.
|
||||
// So instead, make a lot of query objects on the main thread and reuse them.
|
||||
|
@ -90,7 +90,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
}
|
||||
else
|
||||
{
|
||||
return new BufferedQuery(GetTarget(Type));
|
||||
return new BufferedQuery(api, GetTarget(Type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
}
|
||||
}
|
||||
|
||||
public CounterQueueEvent QueueReport(EventHandler<ulong> resultHandler, float divisor, ulong lastDrawIndex, bool hostReserved)
|
||||
public CounterQueueEvent QueueReport(GL api, EventHandler<ulong> resultHandler, float divisor, ulong lastDrawIndex, bool hostReserved)
|
||||
{
|
||||
CounterQueueEvent result;
|
||||
ulong draws = lastDrawIndex - _current.DrawIndex;
|
||||
|
@ -126,7 +126,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
|
||||
result = _current;
|
||||
|
||||
_current = new CounterQueueEvent(this, GetTarget(Type), lastDrawIndex);
|
||||
_current = new CounterQueueEvent(api, this, GetTarget(Type), lastDrawIndex);
|
||||
}
|
||||
|
||||
_queuedEvent.Set();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
|
@ -11,7 +11,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
|
||||
public QueryTarget Type { get; }
|
||||
public bool ClearCounter { get; private set; }
|
||||
public int Query => _counter.Query;
|
||||
public uint Query => _counter.Query;
|
||||
|
||||
public bool Disposed { get; private set; }
|
||||
public bool Invalid { get; set; }
|
||||
|
@ -28,11 +28,11 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
private ulong _result = ulong.MaxValue;
|
||||
private double _divisor = 1f;
|
||||
|
||||
public CounterQueueEvent(CounterQueue queue, QueryTarget type, ulong drawIndex)
|
||||
public CounterQueueEvent(GL api, CounterQueue queue, QueryTarget type, ulong drawIndex)
|
||||
{
|
||||
_queue = queue;
|
||||
|
||||
_counter = queue.GetQueryObject();
|
||||
_counter = queue.GetQueryObject(api);
|
||||
Type = type;
|
||||
|
||||
DrawIndex = drawIndex;
|
||||
|
@ -62,7 +62,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
return true;
|
||||
}
|
||||
|
||||
if (ClearCounter || Type == QueryTarget.Timestamp)
|
||||
if (ClearCounter || Type == (QueryTarget)GLEnum.Timestamp)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Queries
|
||||
|
@ -6,12 +7,14 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
class Counters : IDisposable
|
||||
{
|
||||
private readonly CounterQueue[] _counterQueues;
|
||||
private readonly GL _api;
|
||||
|
||||
public Counters()
|
||||
public Counters(GL api)
|
||||
{
|
||||
int count = Enum.GetNames<CounterType>().Length;
|
||||
|
||||
_counterQueues = new CounterQueue[count];
|
||||
_api = api;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
|
@ -19,13 +22,13 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
for (int index = 0; index < _counterQueues.Length; index++)
|
||||
{
|
||||
CounterType type = (CounterType)index;
|
||||
_counterQueues[index] = new CounterQueue(type);
|
||||
_counterQueues[index] = new CounterQueue(_api, type);
|
||||
}
|
||||
}
|
||||
|
||||
public CounterQueueEvent QueueReport(CounterType type, EventHandler<ulong> resultHandler, float divisor, ulong lastDrawIndex, bool hostReserved)
|
||||
{
|
||||
return _counterQueues[(int)type].QueueReport(resultHandler, divisor, lastDrawIndex, hostReserved);
|
||||
return _counterQueues[(int)type].QueueReport(_api, resultHandler, divisor, lastDrawIndex, hostReserved);
|
||||
}
|
||||
|
||||
public void QueueReset(CounterType type)
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OpenTK.Graphics" />
|
||||
<PackageReference Include="Silk.NET.OpenGL.Legacy" />
|
||||
<PackageReference Include="Silk.NET.OpenGL.Legacy.Extensions.ARB" />
|
||||
<PackageReference Include="Silk.NET.OpenGL.Legacy.Extensions.EXT" />
|
||||
<PackageReference Include="Silk.NET.OpenGL.Legacy.Extensions.NV" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -14,24 +14,30 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
public IntPtr Handle;
|
||||
}
|
||||
|
||||
private ulong _firstHandle = 0;
|
||||
private static ClientWaitSyncFlags SyncFlags => HwCapabilities.RequiresSyncFlush ? ClientWaitSyncFlags.None : ClientWaitSyncFlags.SyncFlushCommandsBit;
|
||||
private ulong _firstHandle;
|
||||
private SyncObjectMask SyncFlags => _gd.Capabilities.RequiresSyncFlush ? 0 : SyncObjectMask.Bit;
|
||||
|
||||
private readonly List<SyncHandle> _handles = new();
|
||||
private readonly OpenGLRenderer _gd;
|
||||
|
||||
public Sync(OpenGLRenderer gd)
|
||||
{
|
||||
_gd = gd;
|
||||
}
|
||||
|
||||
public void Create(ulong id)
|
||||
{
|
||||
SyncHandle handle = new()
|
||||
{
|
||||
ID = id,
|
||||
Handle = GL.FenceSync(SyncCondition.SyncGpuCommandsComplete, WaitSyncFlags.None),
|
||||
Handle = _gd.Api.FenceSync(SyncCondition.SyncGpuCommandsComplete, SyncBehaviorFlags.None),
|
||||
};
|
||||
|
||||
|
||||
if (HwCapabilities.RequiresSyncFlush)
|
||||
if (_gd.Capabilities.RequiresSyncFlush)
|
||||
{
|
||||
// Force commands to flush up to the syncpoint.
|
||||
GL.ClientWaitSync(handle.Handle, ClientWaitSyncFlags.SyncFlushCommandsBit, 0);
|
||||
_gd.Api.ClientWaitSync(handle.Handle, SyncObjectMask.Bit, 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 = _gd.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 = _gd.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 = _gd.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);
|
||||
_gd.Api.DeleteSync(first.Handle);
|
||||
first.Handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +166,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
lock (handle)
|
||||
{
|
||||
GL.DeleteSync(handle.Handle);
|
||||
_gd.Api.DeleteSync(handle.Handle);
|
||||
handle.Handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using Silk.NET.OpenGL.Legacy.Extensions.NV;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
@ -8,7 +9,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
class VertexArray : IDisposable
|
||||
{
|
||||
public int Handle { get; private set; }
|
||||
public uint Handle { get; private set; }
|
||||
|
||||
private readonly VertexAttribDescriptor[] _vertexAttribs;
|
||||
private readonly VertexBufferDescriptor[] _vertexBuffers;
|
||||
|
@ -23,20 +24,22 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
private readonly BufferHandle _tempIndexBuffer;
|
||||
private BufferHandle _tempVertexBuffer;
|
||||
private int _tempVertexBufferSize;
|
||||
private readonly GL _api;
|
||||
|
||||
public VertexArray()
|
||||
public VertexArray(GL api)
|
||||
{
|
||||
Handle = GL.GenVertexArray();
|
||||
_api = api;
|
||||
Handle = _api.GenVertexArray();
|
||||
|
||||
_vertexAttribs = new VertexAttribDescriptor[Constants.MaxVertexAttribs];
|
||||
_vertexBuffers = new VertexBufferDescriptor[Constants.MaxVertexBuffers];
|
||||
|
||||
_tempIndexBuffer = Buffer.Create();
|
||||
_tempIndexBuffer = Buffer.Create(_api);
|
||||
}
|
||||
|
||||
public void Bind()
|
||||
{
|
||||
GL.BindVertexArray(Handle);
|
||||
_api.BindVertexArray(Handle);
|
||||
}
|
||||
|
||||
public void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers)
|
||||
|
@ -56,15 +59,15 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
minVertexCount = vertexCount;
|
||||
}
|
||||
|
||||
GL.BindVertexBuffer(bindingIndex, vb.Buffer.Handle.ToInt32(), (IntPtr)vb.Buffer.Offset, vb.Stride);
|
||||
GL.VertexBindingDivisor(bindingIndex, vb.Divisor);
|
||||
_api.BindVertexBuffer((uint)bindingIndex, vb.Buffer.Handle.ToUInt32(), vb.Buffer.Offset, (uint)vb.Stride);
|
||||
_api.VertexBindingDivisor((uint)bindingIndex, (uint)vb.Divisor);
|
||||
_vertexBuffersInUse |= 1u << bindingIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((_vertexBuffersInUse & (1u << bindingIndex)) != 0)
|
||||
{
|
||||
GL.BindVertexBuffer(bindingIndex, 0, IntPtr.Zero, 0);
|
||||
_api.BindVertexBuffer((uint)bindingIndex, 0, 0, 0);
|
||||
_vertexBuffersInUse &= ~(1u << bindingIndex);
|
||||
}
|
||||
}
|
||||
|
@ -105,22 +108,22 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
int size = fmtInfo.Components;
|
||||
|
||||
bool isFloat = fmtInfo.PixelType == PixelType.Float ||
|
||||
fmtInfo.PixelType == PixelType.HalfFloat;
|
||||
fmtInfo.PixelType == (PixelType)NV.HalfFloatNV;
|
||||
|
||||
if (isFloat || fmtInfo.Normalized || fmtInfo.Scaled)
|
||||
{
|
||||
VertexAttribType type = (VertexAttribType)fmtInfo.PixelType;
|
||||
|
||||
GL.VertexAttribFormat(index, size, type, fmtInfo.Normalized, offset);
|
||||
_api.VertexAttribFormat((uint)index, size, type, fmtInfo.Normalized, (uint)offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
VertexAttribIntegerType type = (VertexAttribIntegerType)fmtInfo.PixelType;
|
||||
VertexAttribIType type = (VertexAttribIType)fmtInfo.PixelType;
|
||||
|
||||
GL.VertexAttribIFormat(index, size, type, offset);
|
||||
_api.VertexAttribIFormat((uint)index, size, type, (uint)offset);
|
||||
}
|
||||
|
||||
GL.VertexAttribBinding(index, attrib.BufferIndex);
|
||||
_api.VertexAttribBinding((uint)index, (uint)attrib.BufferIndex);
|
||||
|
||||
_vertexAttribs[index] = attrib;
|
||||
}
|
||||
|
@ -134,19 +137,19 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
public void SetIndexBuffer(BufferRange range)
|
||||
{
|
||||
_indexBuffer = range;
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, range.Handle.ToInt32());
|
||||
_api.BindBuffer(BufferTargetARB.ElementArrayBuffer, range.Handle.ToUInt32());
|
||||
}
|
||||
|
||||
public void SetRangeOfIndexBuffer()
|
||||
{
|
||||
Buffer.Resize(_tempIndexBuffer, _indexBuffer.Size);
|
||||
Buffer.Copy(_indexBuffer.Handle, _tempIndexBuffer, _indexBuffer.Offset, 0, _indexBuffer.Size);
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _tempIndexBuffer.ToInt32());
|
||||
Buffer.Resize(_api, _tempIndexBuffer, _indexBuffer.Size);
|
||||
Buffer.Copy(_api, _indexBuffer.Handle, _tempIndexBuffer, _indexBuffer.Offset, 0, _indexBuffer.Size);
|
||||
_api.BindBuffer(BufferTargetARB.ElementArrayBuffer, _tempIndexBuffer.ToUInt32());
|
||||
}
|
||||
|
||||
public void RestoreIndexBuffer()
|
||||
{
|
||||
GL.BindBuffer(BufferTarget.ElementArrayBuffer, _indexBuffer.Handle.ToInt32());
|
||||
_api.BindBuffer(BufferTargetARB.ElementArrayBuffer, _indexBuffer.Handle.ToUInt32());
|
||||
}
|
||||
|
||||
public void PreDraw(int vertexCount)
|
||||
|
@ -185,10 +188,10 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
BufferHandle tempVertexBuffer = EnsureTempVertexBufferSize(currentTempVbOffset + requiredSize);
|
||||
|
||||
Buffer.Copy(vb.Buffer.Handle, tempVertexBuffer, vb.Buffer.Offset, currentTempVbOffset, vb.Buffer.Size);
|
||||
Buffer.Clear(tempVertexBuffer, currentTempVbOffset + vb.Buffer.Size, requiredSize - vb.Buffer.Size, 0);
|
||||
Buffer.Copy(_api, vb.Buffer.Handle, tempVertexBuffer, vb.Buffer.Offset, currentTempVbOffset, vb.Buffer.Size);
|
||||
Buffer.Clear(_api, tempVertexBuffer, currentTempVbOffset + vb.Buffer.Size, (uint)(requiredSize - vb.Buffer.Size), 0);
|
||||
|
||||
GL.BindVertexBuffer(vbIndex, tempVertexBuffer.ToInt32(), (IntPtr)currentTempVbOffset, vb.Stride);
|
||||
_api.BindVertexBuffer((uint)vbIndex, tempVertexBuffer.ToUInt32(), currentTempVbOffset, (uint)vb.Stride);
|
||||
|
||||
currentTempVbOffset += requiredSize;
|
||||
_vertexBuffersLimited |= 1u << vbIndex;
|
||||
|
@ -208,12 +211,12 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
if (tempVertexBuffer == BufferHandle.Null)
|
||||
{
|
||||
tempVertexBuffer = Buffer.Create(size);
|
||||
tempVertexBuffer = Buffer.Create(_api, size);
|
||||
_tempVertexBuffer = tempVertexBuffer;
|
||||
return tempVertexBuffer;
|
||||
}
|
||||
|
||||
Buffer.Resize(_tempVertexBuffer, size);
|
||||
Buffer.Resize(_api, _tempVertexBuffer, size);
|
||||
}
|
||||
|
||||
return tempVertexBuffer;
|
||||
|
@ -234,7 +237,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
ref var vb = ref _vertexBuffers[vbIndex];
|
||||
|
||||
GL.BindVertexBuffer(vbIndex, vb.Buffer.Handle.ToInt32(), (IntPtr)vb.Buffer.Offset, vb.Stride);
|
||||
_api.BindVertexBuffer((uint)vbIndex, vb.Buffer.Handle.ToUInt32(), vb.Buffer.Offset, (uint)vb.Stride);
|
||||
|
||||
buffersLimited &= ~(1u << vbIndex);
|
||||
}
|
||||
|
@ -250,7 +253,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
if ((_vertexAttribsInUse & mask) == 0)
|
||||
{
|
||||
_vertexAttribsInUse |= mask;
|
||||
GL.EnableVertexAttribArray(index);
|
||||
_api.EnableVertexAttribArray((uint)index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,8 +265,8 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
if ((_vertexAttribsInUse & mask) != 0)
|
||||
{
|
||||
_vertexAttribsInUse &= ~mask;
|
||||
GL.DisableVertexAttribArray(index);
|
||||
GL.VertexAttrib4(index, 0f, 0f, 0f, 1f);
|
||||
_api.DisableVertexAttribArray((uint)index);
|
||||
_api.VertexAttrib4((uint)index, 0f, 0f, 0f, 1f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,7 +274,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
if (Handle != 0)
|
||||
{
|
||||
GL.DeleteVertexArray(Handle);
|
||||
_api.DeleteVertexArray(Handle);
|
||||
|
||||
Handle = 0;
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.OpenGL.Effects;
|
||||
using Ryujinx.Graphics.OpenGL.Effects.Smaa;
|
||||
using Ryujinx.Graphics.OpenGL.Image;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
|
||||
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,9 +81,9 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
if (viewConverted.Format.IsBgr())
|
||||
{
|
||||
var swappedView = _renderer.TextureCopy.BgraSwap(viewConverted);
|
||||
var swappedView = _gd.TextureCopy.BgraSwap(viewConverted);
|
||||
|
||||
viewConverted?.Dispose();
|
||||
viewConverted.Dispose();
|
||||
|
||||
viewConverted = swappedView;
|
||||
}
|
||||
|
@ -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,15 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
_initialized = true;
|
||||
}
|
||||
|
||||
public void CaptureFrame(int x, int y, int width, int height, bool isBgra, bool flipX, bool flipY)
|
||||
public unsafe void CaptureFrame(int x, int y, uint width, uint height, bool isBgra, bool flipX, bool flipY)
|
||||
{
|
||||
long size = Math.Abs(4 * width * height);
|
||||
byte[] bitmap = new byte[size];
|
||||
long size = 4 * width * height;
|
||||
|
||||
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, out int data);
|
||||
|
||||
_renderer.OnScreenCaptured(new ScreenCaptureImageInfo(width, height, isBgra, bitmap, flipX, flipY));
|
||||
var bitmap = new Span<byte>((void*)data, (int)size).ToArray();
|
||||
|
||||
_gd.OnScreenCaptured(new ScreenCaptureImageInfo((int)width, (int)height, isBgra, bitmap, flipX, flipY));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -273,7 +274,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
if (_copyFramebufferHandle != 0)
|
||||
{
|
||||
GL.DeleteFramebuffer(_copyFramebufferHandle);
|
||||
_gd.Api.DeleteFramebuffer(_copyFramebufferHandle);
|
||||
|
||||
_copyFramebufferHandle = 0;
|
||||
}
|
||||
|
@ -319,7 +320,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 +338,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
else
|
||||
{
|
||||
_antiAliasing?.Dispose();
|
||||
_antiAliasing = new SmaaPostProcessingEffect(_renderer, quality);
|
||||
_antiAliasing = new SmaaPostProcessingEffect(_gd, quality);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -368,7 +369,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 +402,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)
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'osx-x64' AND '$(RuntimeIdentifier)' != 'osx-arm64'" />
|
||||
<PackageReference Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'linux-arm64' AND '$(RuntimeIdentifier)' != 'win-x64'" />
|
||||
<PackageReference Include="OpenTK.Core" />
|
||||
<PackageReference Include="OpenTK.Graphics" />
|
||||
<PackageReference Include="SPB" />
|
||||
<PackageReference Include="SharpZipLib" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" />
|
||||
|
|
|
@ -504,7 +504,7 @@ namespace Ryujinx.UI
|
|||
}
|
||||
else
|
||||
{
|
||||
renderer = new Graphics.OpenGL.OpenGLRenderer();
|
||||
renderer = new Graphics.OpenGL.OpenGLRenderer(((OpenGLRenderer)RendererWidget).GetApi());
|
||||
}
|
||||
|
||||
BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Input.HLE;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using SPB.Graphics;
|
||||
using SPB.Graphics.Exceptions;
|
||||
using SPB.Graphics.OpenGL;
|
||||
|
@ -96,11 +96,18 @@ namespace Ryujinx.UI
|
|||
|
||||
_openGLContext.MakeCurrent(_nativeWindow);
|
||||
|
||||
GL.ClearColor(0, 0, 0, 1.0f);
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||
var api = GetApi();
|
||||
|
||||
api.ClearColor(0, 0, 0, 1.0f);
|
||||
api.Clear(ClearBufferMask.ColorBufferBit);
|
||||
SwapBuffers();
|
||||
}
|
||||
|
||||
public GL GetApi()
|
||||
{
|
||||
return GL.GetApi(_openGLContext.GetProcAddress);
|
||||
}
|
||||
|
||||
public override void SwapBuffers()
|
||||
{
|
||||
_nativeWindow.SwapBuffers();
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
using SPB.Graphics;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.UI
|
||||
{
|
||||
public class OpenToolkitBindingsContext : OpenTK.IBindingsContext
|
||||
{
|
||||
private readonly IBindingsContext _bindingContext;
|
||||
|
||||
public OpenToolkitBindingsContext(IBindingsContext bindingsContext)
|
||||
{
|
||||
_bindingContext = bindingsContext;
|
||||
}
|
||||
|
||||
public IntPtr GetProcAddress(string procName)
|
||||
{
|
||||
return _bindingContext.GetProcAddress(procName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using SPB.Graphics;
|
||||
using SPB.Graphics.OpenGL;
|
||||
|
@ -38,9 +37,6 @@ namespace Ryujinx.UI
|
|||
|
||||
context.Initialize(window);
|
||||
context.MakeCurrent(window);
|
||||
|
||||
GL.LoadBindings(new OpenToolkitBindingsContext(context));
|
||||
|
||||
context.MakeCurrent(null);
|
||||
|
||||
return new SPBOpenGLContext(context, window);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using OpenTK;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
// using OpenTK;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using Ryujinx.Input.HLE;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using static SDL2.SDL;
|
||||
|
||||
|
@ -38,22 +38,16 @@ namespace Ryujinx.Headless.SDL2.OpenGL
|
|||
CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_STEREO, 0));
|
||||
}
|
||||
|
||||
private class OpenToolkitBindingsContext : IBindingsContext
|
||||
{
|
||||
public IntPtr GetProcAddress(string procName)
|
||||
{
|
||||
return SDL_GL_GetProcAddress(procName);
|
||||
}
|
||||
}
|
||||
|
||||
private class SDL2OpenGLContext : IOpenGLContext
|
||||
{
|
||||
public readonly GL Api;
|
||||
private readonly IntPtr _context;
|
||||
private readonly IntPtr _window;
|
||||
private readonly bool _shouldDisposeWindow;
|
||||
|
||||
public SDL2OpenGLContext(IntPtr context, IntPtr window, bool shouldDisposeWindow = true)
|
||||
public SDL2OpenGLContext(GL api, IntPtr context, IntPtr window, bool shouldDisposeWindow = true)
|
||||
{
|
||||
Api = api;
|
||||
_context = context;
|
||||
_window = window;
|
||||
_shouldDisposeWindow = shouldDisposeWindow;
|
||||
|
@ -68,13 +62,13 @@ namespace Ryujinx.Headless.SDL2.OpenGL
|
|||
IntPtr windowHandle = SDL_CreateWindow("Ryujinx background context window", 0, 0, 1, 1, SDL_WindowFlags.SDL_WINDOW_OPENGL | SDL_WindowFlags.SDL_WINDOW_HIDDEN);
|
||||
IntPtr context = SDL_GL_CreateContext(windowHandle);
|
||||
|
||||
GL.LoadBindings(new OpenToolkitBindingsContext());
|
||||
GL api = GL.GetApi((_ => context));
|
||||
|
||||
CheckResult(SDL_GL_SetAttribute(SDL_GLattr.SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 0));
|
||||
|
||||
CheckResult(SDL_GL_MakeCurrent(windowHandle, IntPtr.Zero));
|
||||
|
||||
return new SDL2OpenGLContext(context, windowHandle);
|
||||
return new SDL2OpenGLContext(api, context, windowHandle);
|
||||
}
|
||||
|
||||
public void MakeCurrent()
|
||||
|
@ -111,6 +105,7 @@ namespace Ryujinx.Headless.SDL2.OpenGL
|
|||
|
||||
private readonly GraphicsDebugLevel _glLogLevel;
|
||||
private SDL2OpenGLContext _openGLContext;
|
||||
public GL Api => _openGLContext.Api;
|
||||
|
||||
public OpenGLWindow(
|
||||
InputManager inputManager,
|
||||
|
@ -142,15 +137,15 @@ namespace Ryujinx.Headless.SDL2.OpenGL
|
|||
}
|
||||
|
||||
// NOTE: The window handle needs to be disposed by the thread that created it and is handled separately.
|
||||
_openGLContext = new SDL2OpenGLContext(context, WindowHandle, false);
|
||||
_openGLContext = new SDL2OpenGLContext(GL.GetApi((_ => context)), context, WindowHandle, false);
|
||||
|
||||
// First take exclusivity on the OpenGL context.
|
||||
((OpenGLRenderer)Renderer).InitializeBackgroundContext(SDL2OpenGLContext.CreateBackgroundContext(_openGLContext));
|
||||
|
||||
_openGLContext.MakeCurrent();
|
||||
|
||||
GL.ClearColor(0, 0, 0, 1.0f);
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||
_openGLContext.Api.ClearColor(0, 0, 0, 1.0f);
|
||||
_openGLContext.Api.Clear(ClearBufferMask.ColorBufferBit);
|
||||
SwapBuffers();
|
||||
|
||||
if (IsExclusiveFullscreen)
|
||||
|
|
|
@ -532,7 +532,8 @@ namespace Ryujinx.Headless.SDL2
|
|||
preferredGpuId);
|
||||
}
|
||||
|
||||
return new OpenGLRenderer();
|
||||
var openGlWindow = window as OpenGLWindow;
|
||||
return new OpenGLRenderer(openGlWindow.Api);
|
||||
}
|
||||
|
||||
private static Switch InitializeEmulationContext(WindowBase window, IRenderer renderer, Options options)
|
||||
|
|
|
@ -823,7 +823,7 @@ namespace Ryujinx.Ava
|
|||
}
|
||||
else
|
||||
{
|
||||
renderer = new OpenGLRenderer();
|
||||
renderer = new OpenGLRenderer((RendererHost.EmbeddedWindow as EmbeddedWindowOpenGL).CreateApi());
|
||||
}
|
||||
|
||||
BackendThreading threadingMode = ConfigurationState.Instance.Graphics.BackendThreading;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using Ryujinx.UI.Common.Configuration;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using SPB.Graphics;
|
||||
using SPB.Graphics.Exceptions;
|
||||
using SPB.Graphics.OpenGL;
|
||||
|
@ -44,6 +44,13 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
Context.Initialize(_window);
|
||||
Context.MakeCurrent(_window);
|
||||
Context.MakeCurrent(null);
|
||||
}
|
||||
|
||||
public GL CreateApi()
|
||||
{
|
||||
var flags = OpenGLContextFlags.Compat;
|
||||
if (ConfigurationState.Instance.Logger.GraphicsDebugLevel != GraphicsDebugLevel.None)
|
||||
{
|
||||
|
@ -54,12 +61,7 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||
|
||||
Context = PlatformHelper.CreateOpenGLContext(graphicsMode, 3, 3, flags);
|
||||
|
||||
Context.Initialize(_window);
|
||||
Context.MakeCurrent(_window);
|
||||
|
||||
GL.LoadBindings(new OpenTKBindingsContext(Context.GetProcAddress));
|
||||
|
||||
Context.MakeCurrent(null);
|
||||
return GL.GetApi(Context.GetProcAddress);
|
||||
}
|
||||
|
||||
public void MakeCurrent(bool unbind = false, bool shouldThrow = true)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using SPB.Graphics;
|
||||
using SPB.Graphics.OpenGL;
|
||||
|
@ -38,9 +37,6 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||
|
||||
context.Initialize(window);
|
||||
context.MakeCurrent(window);
|
||||
|
||||
GL.LoadBindings(new OpenTKBindingsContext(context.GetProcAddress));
|
||||
|
||||
context.MakeCurrent(null);
|
||||
|
||||
return new SPBOpenGLContext(context, window);
|
||||
|
|
Loading…
Add table
Reference in a new issue