Compare commits
15 Commits
65abc70edc
...
4ec9793602
Author | SHA1 | Date |
---|---|---|
Isaac Marovitz | 4ec9793602 | |
Isaac Marovitz | bab7457b99 | |
Isaac Marovitz | 2b07d783c8 | |
Isaac Marovitz | 3e422f020c | |
IsaacMarovitz | e72bf35c03 | |
Isaac Marovitz | e584f8d37d | |
Isaac Marovitz | 5db3568305 | |
Isaac Marovitz | 15978d9c55 | |
Isaac Marovitz | 0c88c23b30 | |
Isaac Marovitz | 1d18ed2ba2 | |
Isaac Marovitz | a9d0dd3893 | |
Isaac Marovitz | 8df23211f6 | |
Isaac Marovitz | e46b671875 | |
Isaac Marovitz | 38d900c932 | |
Isaac Marovitz | 740842d600 |
|
@ -39,6 +39,7 @@
|
|||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||
<PackageVersion Include="Silk.NET.OpenGL.Legacy" Version="2.21.0" />
|
||||
<PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.ARB" Version="2.21.0" />
|
||||
<PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.EXT" Version="2.21.0" />
|
||||
<PackageVersion Include="Silk.NET.OpenGL.Legacy.Extensions.NV" Version="2.21.0" />
|
||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.16.0" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
|
@ -23,7 +23,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
size,
|
||||
PixelFormat.RgbaInteger,
|
||||
PixelType.UnsignedByte,
|
||||
(IntPtr)valueArr);
|
||||
valueArr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
uint handle = api.GenBuffer();
|
||||
|
||||
api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle);
|
||||
api.BufferData(BufferTargetARB.CopyWriteBuffer, (uint)size, UIntPtr.Zero, BufferUsageARB.DynamicDraw);
|
||||
api.BufferData(BufferTargetARB.CopyWriteBuffer, (uint)size, in UIntPtr.Zero, BufferUsageARB.DynamicDraw);
|
||||
|
||||
return Handle.FromUInt32<BufferHandle>(handle);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
uint handle = api.GenBuffer();
|
||||
|
||||
api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle);
|
||||
api.BufferStorage(BufferStorageTarget.CopyWriteBuffer, (uint)size, UIntPtr.Zero,
|
||||
api.BufferStorage(BufferStorageTarget.CopyWriteBuffer, (uint)size, in UIntPtr.Zero,
|
||||
BufferStorageMask.MapPersistentBit |
|
||||
BufferStorageMask.MapCoherentBit |
|
||||
BufferStorageMask.ClientStorageBit |
|
||||
|
@ -78,7 +78,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
return new PinnedSpan<byte>(IntPtr.Add(ptr, offset).ToPointer(), size);
|
||||
}
|
||||
else if (HwCapabilities.UsePersistentBufferForFlush)
|
||||
else if (gd.Capabilities.UsePersistentBufferForFlush)
|
||||
{
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(gd.PersistentBuffers.Default.GetBufferData(buffer, offset, size));
|
||||
}
|
||||
|
@ -97,20 +97,13 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
public static void Resize(GL api, BufferHandle handle, int size)
|
||||
{
|
||||
api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32());
|
||||
api.BufferData(BufferTargetARB.CopyWriteBuffer, (uint)size, UIntPtr.Zero, BufferUsageARB.StreamCopy);
|
||||
api.BufferData(BufferTargetARB.CopyWriteBuffer, (uint)size, in UIntPtr.Zero, BufferUsageARB.StreamCopy);
|
||||
}
|
||||
|
||||
public static void SetData(GL api, BufferHandle buffer, int offset, ReadOnlySpan<byte> data)
|
||||
{
|
||||
api.BindBuffer(BufferTargetARB.CopyWriteBuffer, buffer.ToUInt32());
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* ptr = data)
|
||||
{
|
||||
api.BufferSubData(BufferTargetARB.CopyWriteBuffer, offset, (uint)data.Length, (IntPtr)ptr);
|
||||
}
|
||||
}
|
||||
api.BufferSubData(BufferTargetARB.CopyWriteBuffer, offset, (uint)data.Length, data);
|
||||
}
|
||||
|
||||
public static void Delete(GL api, BufferHandle buffer)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Common.Configuration;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
@ -16,12 +16,12 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
public static void Initialize(GL gl, GraphicsDebugLevel logLevel)
|
||||
{
|
||||
// Disable everything
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DontCare, DebugSeverity.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.DebugMessageCallback(null, in IntPtr.Zero);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -30,22 +30,22 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
if (logLevel == GraphicsDebugLevel.Error)
|
||||
{
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypeError, DebugSeverity.DontCare, 0, (int[])null, true);
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypeError, DebugSeverity.DontCare, 0, (uint[])null, true);
|
||||
}
|
||||
else if (logLevel == GraphicsDebugLevel.Slowdowns)
|
||||
{
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypeError, DebugSeverity.DontCare, 0, (int[])null, true);
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypePerformance, DebugSeverity.DontCare, 0, (int[])null, true);
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypeError, DebugSeverity.DontCare, 0, (uint[])null, true);
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DebugTypePerformance, DebugSeverity.DontCare, 0, (uint[])null, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DontCare, DebugSeverity.DontCare, 0, (int[])null, true);
|
||||
gl.DebugMessageControl(DebugSource.DontCare, DebugType.DontCare, DebugSeverity.DontCare, 0, (uint[])null, true);
|
||||
}
|
||||
|
||||
_counter = 0;
|
||||
_debugCallback = GLDebugHandler;
|
||||
|
||||
gl.DebugMessageCallback(_debugCallback, IntPtr.Zero);
|
||||
gl.DebugMessageCallback(_debugCallback, in IntPtr.Zero);
|
||||
|
||||
Logger.Warning?.Print(LogClass.Gpu, "OpenGL Debugging is enabled. Performance will be negatively impacted.");
|
||||
}
|
||||
|
@ -61,7 +61,10 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
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");
|
||||
}
|
||||
|
@ -93,7 +96,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
int counter = Interlocked.Increment(ref _counter);
|
||||
|
||||
gl.PushDebugGroup(DebugSource.DebugSourceApplication, counter, dbgMsg.Length, dbgMsg);
|
||||
gl.PushDebugGroup(DebugSource.DebugSourceApplication, (uint)counter, (uint)dbgMsg.Length, dbgMsg);
|
||||
}
|
||||
|
||||
public static void PopGroup(GL gl)
|
||||
|
@ -103,7 +106,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
public static void Print(GL gl, string dbgMsg, DebugType type = DebugType.DebugTypeMarker, DebugSeverity severity = DebugSeverity.DebugSeverityNotification, int id = 999999)
|
||||
{
|
||||
gl.DebugMessageInsert(DebugSource.DebugSourceApplication, type, id, severity, dbgMsg.Length, dbgMsg);
|
||||
gl.DebugMessageInsert(DebugSource.DebugSourceApplication, type, (uint)id, severity, (uint)dbgMsg.Length, dbgMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Graphics.OpenGL.Image;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
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;
|
||||
|
||||
|
@ -123,13 +123,13 @@ namespace Ryujinx.Graphics.OpenGL.Effects
|
|||
uint previousProgram = (uint)_gd.Api.GetInteger(GetPName.CurrentProgram);
|
||||
int previousUnit = _gd.Api.GetInteger(GetPName.ActiveTexture);
|
||||
_gd.Api.ActiveTexture(TextureUnit.Texture0);
|
||||
int previousTextureBinding = _gd.Api.GetInteger(GetPName.TextureBinding2D);
|
||||
uint previousTextureBinding = (uint)_gd.Api.GetInteger(GetPName.TextureBinding2D);
|
||||
|
||||
_gd.Api.BindImageTexture(0, textureView.Handle, 0, false, 0, BufferAccessARB.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);
|
||||
|
@ -156,7 +156,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects
|
|||
|
||||
// Sharpening Pass
|
||||
_gd.Api.UseProgram(_sharpeningShaderProgram);
|
||||
_gd.Api.BindImageTexture(0, destinationTexture.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
_gd.Api.BindImageTexture(0, destinationTexture.Handle, 0, false, 0, BufferAccessARB.ReadWrite, InternalFormat.Rgba8);
|
||||
textureView.Bind(0);
|
||||
_gd.Api.Uniform1(_inputUniform, 0);
|
||||
_gd.Api.Uniform1(_outputUniform, 0);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.OpenGL.Image;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Effects
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects
|
|||
|
||||
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 = _gd.Api.GetUniformLocation(_shaderProgram, "invResolution");
|
||||
_inputUniform = _gd.Api.GetUniformLocation(_shaderProgram, "inputTexture");
|
||||
|
@ -49,21 +49,21 @@ namespace Ryujinx.Graphics.OpenGL.Effects
|
|||
|
||||
var textureView = _textureStorage.CreateView(view.Info, 0, 0) as TextureView;
|
||||
|
||||
int previousProgram = _gd.Api.GetInteger(GetPName.CurrentProgram);
|
||||
uint previousProgram = (uint)_gd.Api.GetInteger(GetPName.CurrentProgram);
|
||||
int previousUnit = _gd.Api.GetInteger(GetPName.ActiveTexture);
|
||||
_gd.Api.ActiveTexture(TextureUnit.Texture0);
|
||||
int previousTextureBinding = _gd.Api.GetInteger(GetPName.TextureBinding2D);
|
||||
uint previousTextureBinding = (uint)_gd.Api.GetInteger(GetPName.TextureBinding2D);
|
||||
|
||||
_gd.Api.BindImageTexture(0, textureView.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
_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);
|
||||
_gd.Api.Uniform1(_inputUniform, 0);
|
||||
_gd.Api.Uniform1(_outputUniform, 0);
|
||||
_gd.Api.Uniform2(_resolutionUniform, (float)view.Width, (float)view.Height);
|
||||
_gd.Api.Uniform2(_resolutionUniform, view.Width, view.Height);
|
||||
_gd.Api.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
_gd.Api.UseProgram(previousProgram);
|
||||
_gd.Api.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
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
|
||||
|
@ -93,13 +93,13 @@ 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;
|
||||
|
@ -184,14 +184,14 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
|
|||
var areaTexture = _areaTexture.DefaultView as TextureView;
|
||||
var searchTexture = _searchTexture.DefaultView as TextureView;
|
||||
|
||||
var previousFramebuffer = _gd.Api.GetInteger(GetPName.DrawFramebufferBinding);
|
||||
uint previousFramebuffer = (uint)_gd.Api.GetInteger(GetPName.DrawFramebufferBinding);
|
||||
int previousUnit = _gd.Api.GetInteger(GetPName.ActiveTexture);
|
||||
_gd.Api.ActiveTexture(TextureUnit.Texture0);
|
||||
int previousTextureBinding0 = _gd.Api.GetInteger(GetPName.TextureBinding2D);
|
||||
uint previousTextureBinding0 = (uint)_gd.Api.GetInteger(GetPName.TextureBinding2D);
|
||||
_gd.Api.ActiveTexture(TextureUnit.Texture1);
|
||||
int previousTextureBinding1 = _gd.Api.GetInteger(GetPName.TextureBinding2D);
|
||||
uint previousTextureBinding1 = (uint)_gd.Api.GetInteger(GetPName.TextureBinding2D);
|
||||
_gd.Api.ActiveTexture(TextureUnit.Texture2);
|
||||
int previousTextureBinding2 = _gd.Api.GetInteger(GetPName.TextureBinding2D);
|
||||
uint previousTextureBinding2 = (uint)_gd.Api.GetInteger(GetPName.TextureBinding2D);
|
||||
|
||||
var framebuffer = new Framebuffer(_gd.Api);
|
||||
framebuffer.Bind();
|
||||
|
@ -206,11 +206,11 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
|
|||
|
||||
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);
|
||||
|
||||
uint previousProgram = (uint)_gd.Api.GetInteger(GetPName.CurrentProgram);
|
||||
_gd.Api.BindImageTexture(0, edgeOutput.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
_gd.Api.BindImageTexture(0, edgeOutput.Handle, 0, false, 0, BufferAccessARB.ReadWrite, InternalFormat.Rgba8);
|
||||
_gd.Api.UseProgram(_edgeShaderPrograms[Quality]);
|
||||
view.Bind(0);
|
||||
_gd.Api.Uniform1(_inputUniform, 0);
|
||||
|
@ -219,7 +219,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
|
|||
_gd.Api.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
_gd.Api.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit);
|
||||
|
||||
_gd.Api.BindImageTexture(0, blendOutput.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
_gd.Api.BindImageTexture(0, blendOutput.Handle, 0, false, 0, BufferAccessARB.ReadWrite, InternalFormat.Rgba8);
|
||||
_gd.Api.UseProgram(_blendShaderPrograms[Quality]);
|
||||
edgeOutput.Bind(0);
|
||||
areaTexture.Bind(1);
|
||||
|
@ -232,7 +232,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa
|
|||
_gd.Api.DispatchCompute(dispatchX, dispatchY, 1);
|
||||
_gd.Api.MemoryBarrier(MemoryBarrierMask.ShaderImageAccessBarrierBit);
|
||||
|
||||
_gd.Api.BindImageTexture(0, textureView.Handle, 0, false, 0, BufferAccessARB.ReadWrite, SizedInternalFormat.Rgba8);
|
||||
_gd.Api.BindImageTexture(0, textureView.Handle, 0, false, 0, BufferAccessARB.ReadWrite, InternalFormat.Rgba8);
|
||||
_gd.Api.UseProgram(_neighbourShaderPrograms[Quality]);
|
||||
view.Bind(0);
|
||||
blendOutput.Bind(1);
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Silk.NET.OpenGL.Legacy.Extensions.NV;
|
||||
using Silk.NET.OpenGL.Legacy.Extensions.EXT;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using Silk.NET.OpenGL.Legacy.Extensions.EXT;
|
||||
using Silk.NET.OpenGL.Legacy.Extensions.NV;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
{
|
||||
|
@ -14,7 +14,9 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
switch (mode)
|
||||
{
|
||||
case AddressMode.Clamp:
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
return TextureWrapMode.Clamp;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
case AddressMode.Repeat:
|
||||
return TextureWrapMode.Repeat;
|
||||
case AddressMode.MirrorClamp:
|
||||
|
@ -33,7 +35,9 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {nameof(AddressMode)} enum value: {mode}.");
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
return TextureWrapMode.Clamp;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
}
|
||||
|
||||
public static NV Convert(this AdvancedBlendOp op)
|
||||
|
@ -451,7 +455,9 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
case PrimitiveTopology.Quads:
|
||||
return PrimitiveType.Quads;
|
||||
case PrimitiveTopology.QuadStrip:
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
return PrimitiveType.QuadStrip;
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
case PrimitiveTopology.Polygon:
|
||||
return PrimitiveType.TriangleFan;
|
||||
case PrimitiveTopology.LinesAdjacency:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
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;
|
||||
|
@ -20,7 +20,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
private int _colorsCount;
|
||||
private bool _dualSourceBlend;
|
||||
private GL _api;
|
||||
private readonly GL _api;
|
||||
|
||||
public Framebuffer(GL api)
|
||||
{
|
||||
|
|
|
@ -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(GetPName.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 Silk.NET.OpenGL.Legacy;
|
||||
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(GLEnum.MaxComputeSharedMemorySize));
|
||||
private static readonly Lazy<int> _storageBufferOffsetAlignment = new(() => GetLimit(GLEnum.ShaderStorageBufferOffsetAlignment));
|
||||
private static readonly Lazy<int> _textureBufferOffsetAlignment = new(() => GetLimit(GLEnum.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)GLEnum.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(GLEnum 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 api)
|
||||
{
|
||||
api.GetError(); // Clear any existing error.
|
||||
api.Begin(PrimitiveType.Quads);
|
||||
api.End();
|
||||
|
||||
return api.GetError() == ErrorCode.NoError;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
using Ryujinx.Graphics.OpenGL.Helper;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Image
|
||||
{
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Image
|
||||
{
|
||||
class Sampler : ISampler
|
||||
{
|
||||
public uint Handle { get; private set; }
|
||||
private readonly GL _api;
|
||||
private readonly OpenGLRenderer _gd;
|
||||
|
||||
public Sampler(GL api, SamplerCreateInfo info)
|
||||
public Sampler(OpenGLRenderer gd, SamplerCreateInfo info)
|
||||
{
|
||||
_api = api;
|
||||
Handle = _api.GenSampler();
|
||||
_gd = gd;
|
||||
Handle = _gd.Api.GenSampler();
|
||||
|
||||
_api.SamplerParameter(Handle, SamplerParameterI.MinFilter, (int)info.MinFilter.Convert());
|
||||
_api.SamplerParameter(Handle, SamplerParameterI.MagFilter, (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)
|
||||
{
|
||||
_api.SamplerParameter(Handle, GLEnum.TextureCubeMapSeamless, info.SeamlessCubemap ? 1 : 0);
|
||||
_gd.Api.SamplerParameter(Handle, GLEnum.TextureCubeMapSeamless, info.SeamlessCubemap ? 1 : 0);
|
||||
}
|
||||
|
||||
_api.SamplerParameter(Handle, SamplerParameterI.WrapS, (int)info.AddressU.Convert());
|
||||
_api.SamplerParameter(Handle, SamplerParameterI.WrapT, (int)info.AddressV.Convert());
|
||||
_api.SamplerParameter(Handle, SamplerParameterI.WrapR, (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());
|
||||
|
||||
_api.SamplerParameter(Handle, SamplerParameterI.CompareMode, (int)info.CompareMode.Convert());
|
||||
_api.SamplerParameter(Handle, SamplerParameterI.CompareFunc, (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
|
||||
{
|
||||
|
@ -38,26 +38,26 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
info.BorderColor.Alpha,
|
||||
};
|
||||
|
||||
_api.SamplerParameter(Handle, SamplerParameterF.BorderColor, borderColor);
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterF.BorderColor, borderColor);
|
||||
}
|
||||
|
||||
_api.SamplerParameter(Handle, SamplerParameterF.MinLod, info.MinLod);
|
||||
_api.SamplerParameter(Handle, SamplerParameterF.MaxLod, info.MaxLod);
|
||||
_api.SamplerParameter(Handle, SamplerParameterF.LodBias, 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);
|
||||
|
||||
_api.SamplerParameter(Handle, SamplerParameterF.MaxAnisotropy, info.MaxAnisotropy);
|
||||
_gd.Api.SamplerParameter(Handle, SamplerParameterF.MaxAnisotropy, info.MaxAnisotropy);
|
||||
}
|
||||
|
||||
public void Bind(uint unit)
|
||||
{
|
||||
_api.BindSampler(unit, Handle);
|
||||
_gd.Api.BindSampler(unit, Handle);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Handle != 0)
|
||||
{
|
||||
_api.DeleteSampler(Handle);
|
||||
_gd.Api.DeleteSampler(Handle);
|
||||
|
||||
Handle = 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Image
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Image
|
||||
|
@ -238,7 +238,7 @@ 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)
|
||||
{
|
||||
_gd.Api.CopyImageSubData(
|
||||
src.Storage.Handle,
|
||||
|
@ -464,7 +464,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
_copyPboSize = requiredSize;
|
||||
|
||||
_gd.Api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyPboHandle);
|
||||
_gd.Api.BufferData(BufferTargetARB.PixelPackBuffer, (uint)requiredSize, IntPtr.Zero, BufferUsageARB.DynamicCopy);
|
||||
_gd.Api.BufferData(BufferTargetARB.PixelPackBuffer, (uint)requiredSize, in IntPtr.Zero, BufferUsageARB.DynamicCopy);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
|
||||
namespace Ryujinx.Graphics.OpenGL.Image
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Common;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Diagnostics;
|
||||
|
@ -101,15 +101,15 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
_gd.Api.TexParameter(target, TextureParameterName.DepthStencilTextureMode, (int)Info.DepthStencilMode.Convert());
|
||||
}
|
||||
|
||||
public ITexture CreateView(TextureCreateInfo info, uint firstLayer, uint firstLevel)
|
||||
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, uint firstLayer, uint firstLevel)
|
||||
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
|
||||
{
|
||||
TextureView destinationView = (TextureView)destination;
|
||||
|
||||
|
@ -118,18 +118,18 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
if (dstIsMultisample != srcIsMultisample && Info.Format.IsDepthOrStencil())
|
||||
{
|
||||
uint 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)
|
||||
{
|
||||
uint layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
|
||||
_gd.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)
|
||||
{
|
||||
uint layers = Math.Min(Info.GetLayers(), destinationView.Info.GetLayers() - firstLayer);
|
||||
_gd.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)
|
||||
{
|
||||
|
@ -228,7 +228,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
1);
|
||||
|
||||
_gd.TextureCopy.Copy(this, intermmediate, srcRegion, dstRegion, false);
|
||||
_gd.TextureCopy.Copy(intermmediate, destinationView, dstRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1);
|
||||
_gd.TextureCopy.Copy(intermmediate, destinationView, dstRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, (int)layers, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -252,7 +252,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
1);
|
||||
|
||||
_gd.TextureCopy.Copy(this, intermmediate, srcRegion, srcRegion, false);
|
||||
_gd.TextureCopy.Copy(intermmediate, destinationView, srcRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, layers, 1);
|
||||
_gd.TextureCopy.Copy(intermmediate, destinationView, srcRegion, dstRegion, false, srcLayer, dstLayer, 0, 0, (int)layers, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,7 +273,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
ReadOnlySpan<byte> data;
|
||||
|
||||
if (HwCapabilities.UsePersistentBufferForFlush)
|
||||
if (_gd.Capabilities.UsePersistentBufferForFlush)
|
||||
{
|
||||
data = _gd.PersistentBuffers.Default.GetTextureData(this, size);
|
||||
}
|
||||
|
@ -298,7 +298,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
int size = Info.GetMipSize(level);
|
||||
|
||||
if (HwCapabilities.UsePersistentBufferForFlush)
|
||||
if (_gd.Capabilities.UsePersistentBufferForFlush)
|
||||
{
|
||||
return PinnedSpan<byte>.UnsafeFromSpan(_gd.PersistentBuffers.Default.GetTextureData(this, size, layer, level));
|
||||
}
|
||||
|
@ -344,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();
|
||||
|
||||
|
@ -364,15 +364,37 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
_gd.Api.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)
|
||||
{
|
||||
_gd.Api.GetTextureSubImage(Handle, level, 0, 0, layer, Math.Max(1, Info.Width >> level), Math.Max(1, Info.Height >> level), 1, pixelFormat, pixelType, mipSize, data);
|
||||
_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
|
||||
{
|
||||
_gd.Api.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
|
||||
|
@ -387,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();
|
||||
|
||||
|
@ -433,11 +455,11 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
|
||||
if (format.IsCompressed)
|
||||
{
|
||||
_gd.Api.GetCompressedTexImage(target + face, level, data + faceOffset);
|
||||
_gd.Api.GetCompressedTexImage(target + face, level, (void*)(data + faceOffset));
|
||||
}
|
||||
else
|
||||
{
|
||||
_gd.Api.GetTexImage(target + face, level, pixelFormat, pixelType, data + faceOffset);
|
||||
_gd.Api.GetTexImage(target + face, level, pixelFormat, pixelType, (void*)(data + faceOffset));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -532,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();
|
||||
|
||||
|
@ -552,7 +574,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
(uint)width,
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -563,7 +585,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
(uint)width,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -579,7 +601,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
1,
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -592,7 +614,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
1,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -608,7 +630,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
(uint)height,
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -621,7 +643,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
(uint)height,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -641,7 +663,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
1,
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -656,7 +678,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
1,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -672,7 +694,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
(uint)height,
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -685,19 +707,19 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
(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();
|
||||
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)
|
||||
{
|
||||
_gd.Api.ActiveTexture(TextureUnit.Texture0);
|
||||
_gd.Api.BindTexture(target, Storage.Handle);
|
||||
|
@ -710,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;
|
||||
|
@ -738,9 +760,9 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
level,
|
||||
0,
|
||||
width,
|
||||
format.PixelFormat,
|
||||
mipSize,
|
||||
data);
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -751,7 +773,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
width,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -766,9 +788,9 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
0,
|
||||
width,
|
||||
height,
|
||||
format.PixelFormat,
|
||||
mipSize,
|
||||
data);
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -781,7 +803,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
height,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -799,9 +821,9 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
width,
|
||||
height,
|
||||
depth,
|
||||
format.PixelFormat,
|
||||
mipSize,
|
||||
data);
|
||||
(InternalFormat)format.PixelFormat,
|
||||
(uint)mipSize,
|
||||
(void*)data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -816,7 +838,7 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
depth,
|
||||
format.PixelFormat,
|
||||
format.PixelType,
|
||||
data);
|
||||
(void*)data);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -829,27 +851,27 @@ namespace Ryujinx.Graphics.OpenGL.Image
|
|||
{
|
||||
_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
|
||||
{
|
||||
_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;
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
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
|
||||
|
@ -39,6 +41,8 @@ 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; }
|
||||
|
@ -48,15 +52,15 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
public OpenGLRenderer(GL api)
|
||||
{
|
||||
Api = api;
|
||||
_pipeline = new Pipeline(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(Api);
|
||||
PersistentBuffers = new PersistentBuffers();
|
||||
_sync = new Sync(this);
|
||||
PersistentBuffers = new PersistentBuffers(Api);
|
||||
ResourcePool = new ResourcePool();
|
||||
}
|
||||
|
||||
|
@ -100,12 +104,12 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
|
||||
{
|
||||
return new Program(Api, shaders, info.FragmentOutputMap);
|
||||
return new Program(this, shaders, info.FragmentOutputMap);
|
||||
}
|
||||
|
||||
public ISampler CreateSampler(SamplerCreateInfo info)
|
||||
{
|
||||
return new Sampler(Api, info);
|
||||
return new Sampler(this, info);
|
||||
}
|
||||
|
||||
public ITexture CreateTexture(TextureCreateInfo info)
|
||||
|
@ -144,9 +148,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,
|
||||
|
@ -155,9 +159,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,
|
||||
|
@ -167,39 +171,39 @@ 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,
|
||||
supportsNonConstantTextureOffset: Capabilities.SupportsNonConstantTextureOffset,
|
||||
supportsScaledVertexFormats: true,
|
||||
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.
|
||||
}
|
||||
|
||||
|
@ -228,11 +232,15 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
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();
|
||||
|
@ -240,15 +248,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.
|
||||
// should already have the desired behaviour when outputs are not clamped.
|
||||
Api.ClampColor(ClampColorTargetARB.FragmentColorArb, ClampColorModeARB.False);
|
||||
}
|
||||
|
||||
private void PrintGpuInformation()
|
||||
private void LoadFeatures()
|
||||
{
|
||||
GpuVendor = Api.GetString(StringName.Vendor);
|
||||
GpuRenderer = Api.GetString(StringName.Renderer);
|
||||
GpuVersion = Api.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})");
|
||||
}
|
||||
|
@ -292,7 +331,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
public IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info)
|
||||
{
|
||||
return new Program(Api, programBinary, hasFragmentShader, info.FragmentOutputMap);
|
||||
return new Program(this, programBinary, hasFragmentShader, info.FragmentOutputMap);
|
||||
}
|
||||
|
||||
public void CreateSync(ulong id, bool strict)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
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(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32());
|
||||
IntPtr ptr = GL.MapBufferRange(BufferTargetARB.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(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32());
|
||||
GL.UnmapBuffer(BufferTargetARB.CopyWriteBuffer);
|
||||
_api.BindBuffer(BufferTargetARB.CopyWriteBuffer, handle.ToUInt32());
|
||||
_api.UnmapBuffer(BufferTargetARB.CopyWriteBuffer);
|
||||
|
||||
_maps.Remove(handle);
|
||||
}
|
||||
|
@ -51,6 +59,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
class PersistentBuffer : IDisposable
|
||||
{
|
||||
private readonly GL _api;
|
||||
private IntPtr _bufferMap;
|
||||
private uint _copyBufferHandle;
|
||||
private int _copyBufferSize;
|
||||
|
@ -58,24 +67,29 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
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(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle);
|
||||
GL.BufferStorage(BufferTargetARB.CopyWriteBuffer, requiredSize, IntPtr.Zero, BufferStorageFlags.MapReadBit | BufferStorageFlags.MapPersistentBit);
|
||||
_api.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle);
|
||||
_api.BufferStorage(BufferStorageTarget.CopyWriteBuffer, (uint)requiredSize, in IntPtr.Zero, BufferStorageMask.MapReadBit | BufferStorageMask.MapPersistentBit);
|
||||
|
||||
_bufferMap = GL.MapBufferRange(BufferTargetARB.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(MemoryBarrierMask.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(BufferTargetARB.PixelPackBuffer, _copyBufferHandle);
|
||||
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle);
|
||||
|
||||
view.WriteToPbo(0, false);
|
||||
|
||||
GL.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
|
||||
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
|
||||
|
||||
Sync();
|
||||
|
||||
|
@ -125,11 +139,11 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
EnsureBuffer(size);
|
||||
|
||||
GL.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle);
|
||||
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, _copyBufferHandle);
|
||||
|
||||
int offset = view.WriteToPbo2D(0, layer, level);
|
||||
|
||||
GL.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
|
||||
_api.BindBuffer(BufferTargetARB.PixelPackBuffer, 0);
|
||||
|
||||
Sync();
|
||||
|
||||
|
@ -140,12 +154,12 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
EnsureBuffer(size);
|
||||
|
||||
GL.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32());
|
||||
GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle);
|
||||
_api.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32());
|
||||
_api.BindBuffer(BufferTargetARB.CopyWriteBuffer, _copyBufferHandle);
|
||||
|
||||
GL.CopyBufferSubData(BufferTargetARB.CopyReadBuffer, BufferTargetARB.CopyWriteBuffer, (IntPtr)offset, IntPtr.Zero, size);
|
||||
_api.CopyBufferSubData(CopyBufferSubDataTarget.CopyReadBuffer, CopyBufferSubDataTarget.CopyWriteBuffer, offset, IntPtr.Zero, (uint)size);
|
||||
|
||||
GL.BindBuffer(BufferTargetARB.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 Silk.NET.OpenGL.Legacy;
|
||||
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;
|
||||
|
||||
|
@ -27,18 +28,18 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
}
|
||||
}
|
||||
|
||||
private readonly GL _api;
|
||||
private readonly OpenGLRenderer _gd;
|
||||
private ProgramLinkStatus _status = ProgramLinkStatus.Incomplete;
|
||||
private uint[] _shaderHandles;
|
||||
|
||||
public int FragmentOutputMap { get; }
|
||||
|
||||
public Program(GL api, ShaderSource[] shaders, int fragmentOutputMap)
|
||||
public unsafe Program(OpenGLRenderer gd, ShaderSource[] shaders, int fragmentOutputMap)
|
||||
{
|
||||
_api = api;
|
||||
Handle = _api.CreateProgram();
|
||||
_gd = gd;
|
||||
Handle = _gd.Api.CreateProgram();
|
||||
|
||||
_api.ProgramParameter(Handle, ProgramParameterPName.BinaryRetrievableHint, 1);
|
||||
_gd.Api.ProgramParameter(Handle, ProgramParameterPName.BinaryRetrievableHint, 1);
|
||||
|
||||
_shaderHandles = new uint[shaders.Length];
|
||||
bool hasFragmentShader = false;
|
||||
|
@ -52,34 +53,37 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
hasFragmentShader = true;
|
||||
}
|
||||
|
||||
uint shaderHandle = _api.CreateShader(shader.Stage.Convert());
|
||||
uint shaderHandle = _gd.Api.CreateShader(shader.Stage.Convert());
|
||||
|
||||
switch (shader.Language)
|
||||
{
|
||||
case TargetLanguage.Glsl:
|
||||
_api.ShaderSource(shaderHandle, shader.Code);
|
||||
_api.CompileShader(shaderHandle);
|
||||
_gd.Api.ShaderSource(shaderHandle, shader.Code);
|
||||
_gd.Api.CompileShader(shaderHandle);
|
||||
break;
|
||||
case TargetLanguage.Spirv:
|
||||
_api.ShaderBinary(1, ref shaderHandle, ShaderBinaryFormat.ShaderBinaryFormatSpirV, shader.BinaryCode, shader.BinaryCode.Length);
|
||||
_api.SpecializeShader(shaderHandle, "main", 0, (int[])null, (int[])null);
|
||||
fixed (byte* ptr = shader.BinaryCode.AsSpan())
|
||||
{
|
||||
_gd.Api.ShaderBinary(1, in shaderHandle, ShaderBinaryFormat.ShaderBinaryFormatSpirV, ptr, (uint)shader.BinaryCode.Length);
|
||||
}
|
||||
_gd.Api.SpecializeShader(shaderHandle, "main", 0, (uint[])null, (uint[])null);
|
||||
break;
|
||||
}
|
||||
|
||||
_api.AttachShader(Handle, shaderHandle);
|
||||
_gd.Api.AttachShader(Handle, shaderHandle);
|
||||
|
||||
_shaderHandles[index] = shaderHandle;
|
||||
}
|
||||
|
||||
_api.LinkProgram(Handle);
|
||||
_gd.Api.LinkProgram(Handle);
|
||||
|
||||
FragmentOutputMap = hasFragmentShader ? fragmentOutputMap : 0;
|
||||
}
|
||||
|
||||
public Program(GL api, ReadOnlySpan<byte> code, bool hasFragmentShader, int fragmentOutputMap)
|
||||
public Program(OpenGLRenderer gd, ReadOnlySpan<byte> code, bool hasFragmentShader, int fragmentOutputMap)
|
||||
{
|
||||
_api = api;
|
||||
Handle = _api.CreateProgram();
|
||||
_gd = gd;
|
||||
Handle = _gd.Api.CreateProgram();
|
||||
|
||||
if (code.Length >= 4)
|
||||
{
|
||||
|
@ -89,7 +93,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
fixed (byte* ptr = code)
|
||||
{
|
||||
_api.ProgramBinary(Handle, binaryFormat, (IntPtr)ptr, code.Length - 4);
|
||||
_gd.Api.ProgramBinary(Handle, (GLEnum)binaryFormat, ptr, (uint)code.Length - 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,14 +103,14 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
public void Bind()
|
||||
{
|
||||
_api.UseProgram(Handle);
|
||||
_gd.Api.UseProgram(Handle);
|
||||
}
|
||||
|
||||
public ProgramLinkStatus CheckProgramLink(bool blocking)
|
||||
{
|
||||
if (!blocking && HwCapabilities.SupportsParallelShaderCompile)
|
||||
if (!blocking && _gd.Capabilities.SupportsParallelShaderCompile)
|
||||
{
|
||||
_api.GetProgram(Handle, (GetProgramParameterName)ArbParallelShaderCompile.CompletionStatusArb, out int completed);
|
||||
_gd.Api.GetProgram(Handle, (GLEnum)ARB.CompletionStatusArb, out int completed);
|
||||
|
||||
if (completed == 0)
|
||||
{
|
||||
|
@ -114,14 +118,14 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
}
|
||||
}
|
||||
|
||||
_api.GetProgram(Handle, ProgramPropertyARB.LinkStatus, out int status);
|
||||
_gd.Api.GetProgram(Handle, ProgramPropertyARB.LinkStatus, out int status);
|
||||
DeleteShaders();
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
_status = ProgramLinkStatus.Failure;
|
||||
|
||||
string log = _api.GetProgramInfoLog(Handle);
|
||||
string log = _gd.Api.GetProgramInfoLog(Handle);
|
||||
|
||||
if (log.Length > MaxShaderLogLength)
|
||||
{
|
||||
|
@ -138,15 +142,19 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
return _status;
|
||||
}
|
||||
|
||||
public byte[] GetBinary()
|
||||
public unsafe byte[] GetBinary()
|
||||
{
|
||||
_api.GetProgram(Handle, ProgramPropertyARB.ProgramBinaryLength, out int size);
|
||||
_gd.Api.GetProgram(Handle, ProgramPropertyARB.ProgramBinaryLength, out int size);
|
||||
|
||||
byte[] data = new byte[size + 4];
|
||||
byte[] data = new byte[size];
|
||||
GLEnum binFormat;
|
||||
|
||||
_api.GetProgramBinary(Handle, (uint)size, out _, out GLEnum binFormat, data);
|
||||
fixed (byte* ptr = data)
|
||||
{
|
||||
_gd.Api.GetProgramBinary(Handle, (uint)size, out _, out binFormat, ptr);
|
||||
}
|
||||
|
||||
BinaryPrimitives.WriteInt32LittleEndian(data.AsSpan(size, 4), (int)binFormat);
|
||||
BinaryPrimitives.WriteInt32LittleEndian(data, (int)binFormat);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -157,8 +165,8 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
foreach (uint shaderHandle in _shaderHandles)
|
||||
{
|
||||
_api.DetachShader(Handle, shaderHandle);
|
||||
_api.DeleteShader(shaderHandle);
|
||||
_gd.Api.DetachShader(Handle, shaderHandle);
|
||||
_gd.Api.DeleteShader(shaderHandle);
|
||||
}
|
||||
|
||||
_shaderHandles = null;
|
||||
|
@ -170,7 +178,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
if (Handle != 0)
|
||||
{
|
||||
DeleteShaders();
|
||||
_api.DeleteProgram(Handle);
|
||||
_gd.Api.DeleteProgram(Handle);
|
||||
|
||||
Handle = 0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
@ -27,16 +27,11 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
_type = type;
|
||||
|
||||
_api.BindBuffer(BufferTargetARB.QueryBuffer, _buffer);
|
||||
_api.BufferStorage(BufferStorageTarget.QueryBuffer, sizeof(long), DefaultValue, BufferStorageMask.MapReadBit | BufferStorageMask.MapWriteBit | BufferStorageMask.MapPersistentBit);
|
||||
|
||||
unsafe
|
||||
{
|
||||
long defaultValue = DefaultValue;
|
||||
_api.BufferStorage(BufferStorageTarget.QueryBuffer, sizeof(long), (IntPtr)(&defaultValue), BufferStorageMask.MapReadBit | BufferStorageMask.MapWriteBit | BufferStorageMask.MapPersistentBit);
|
||||
}
|
||||
|
||||
unsafe
|
||||
{
|
||||
_bufferMap = new IntPtr(_api.MapBufferRange(BufferTargetARB.QueryBuffer, IntPtr.Zero, sizeof(long), MapBufferAccessMask.ReadBit | MapBufferAccessMask.WriteBit | MapBufferAccessMask.PersistentBit));
|
||||
_bufferMap = (IntPtr)_api.MapBufferRange(BufferTargetARB.QueryBuffer, IntPtr.Zero, sizeof(long), MapBufferAccessMask.ReadBit | MapBufferAccessMask.WriteBit | MapBufferAccessMask.PersistentBit);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +55,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
|
|||
_api.BindBuffer(BufferTargetARB.QueryBuffer, _buffer);
|
||||
|
||||
Marshal.WriteInt64(_bufferMap, -1L);
|
||||
_api.GetQueryObject(Query,QueryObjectParameterName.Result, (long*)0);
|
||||
_api.GetQueryObject(Query, QueryObjectParameterName.Result, (long*)0);
|
||||
_api.MemoryBarrier(MemoryBarrierMask.QueryBufferBarrierBit | MemoryBarrierMask.ClientMappedBufferBarrierBit);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<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>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Common.Logging;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -14,15 +14,15 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
public IntPtr Handle;
|
||||
}
|
||||
|
||||
private ulong _firstHandle = 0;
|
||||
private static SyncBehaviorFlags SyncFlags => HwCapabilities.RequiresSyncFlush ? SyncBehaviorFlags.None : SyncBehaviorFlags.SyncFlushCommandsBit;
|
||||
private ulong _firstHandle;
|
||||
private SyncObjectMask SyncFlags => _gd.Capabilities.RequiresSyncFlush ? 0 : SyncObjectMask.Bit;
|
||||
|
||||
private readonly List<SyncHandle> _handles = new();
|
||||
private readonly GL _api;
|
||||
private readonly OpenGLRenderer _gd;
|
||||
|
||||
public Sync(GL api)
|
||||
public Sync(OpenGLRenderer gd)
|
||||
{
|
||||
_api = api;
|
||||
_gd = gd;
|
||||
}
|
||||
|
||||
public void Create(ulong id)
|
||||
|
@ -30,14 +30,14 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
SyncHandle handle = new()
|
||||
{
|
||||
ID = id,
|
||||
Handle = _api.FenceSync(SyncCondition.SyncGpuCommandsComplete, SyncBehaviorFlags.None),
|
||||
Handle = _gd.Api.FenceSync(SyncCondition.SyncGpuCommandsComplete, SyncBehaviorFlags.None),
|
||||
};
|
||||
|
||||
|
||||
if (HwCapabilities.RequiresSyncFlush)
|
||||
if (_gd.Capabilities.RequiresSyncFlush)
|
||||
{
|
||||
// Force commands to flush up to the syncpoint.
|
||||
_api.ClientWaitSync(handle.Handle, SyncBehaviorFlags.SyncFlushCommandsBit, 0);
|
||||
_gd.Api.ClientWaitSync(handle.Handle, SyncObjectMask.Bit, 0);
|
||||
}
|
||||
|
||||
lock (_handles)
|
||||
|
@ -63,7 +63,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
|
||||
if (handle.ID > lastHandle)
|
||||
{
|
||||
GLEnum syncResult = _api.ClientWaitSync(handle.Handle, SyncFlags, 0);
|
||||
GLEnum syncResult = _gd.Api.ClientWaitSync(handle.Handle, SyncFlags, 0);
|
||||
|
||||
if (syncResult == GLEnum.AlreadySignaled)
|
||||
{
|
||||
|
@ -107,7 +107,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
return;
|
||||
}
|
||||
|
||||
GLEnum syncResult = _api.ClientWaitSync(result.Handle, SyncFlags, 1000000000);
|
||||
GLEnum syncResult = _gd.Api.ClientWaitSync(result.Handle, SyncFlags, 1000000000);
|
||||
|
||||
if (syncResult == GLEnum.TimeoutExpired)
|
||||
{
|
||||
|
@ -134,7 +134,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
break;
|
||||
}
|
||||
|
||||
GLEnum syncResult = _api.ClientWaitSync(first.Handle, SyncFlags, 0);
|
||||
GLEnum syncResult = _gd.Api.ClientWaitSync(first.Handle, SyncFlags, 0);
|
||||
|
||||
if (syncResult == GLEnum.AlreadySignaled)
|
||||
{
|
||||
|
@ -145,7 +145,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
_firstHandle = first.ID + 1;
|
||||
_handles.RemoveAt(0);
|
||||
_api.DeleteSync(first.Handle);
|
||||
_gd.Api.DeleteSync(first.Handle);
|
||||
first.Handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ namespace Ryujinx.Graphics.OpenGL
|
|||
{
|
||||
lock (handle)
|
||||
{
|
||||
_api.DeleteSync(handle.Handle);
|
||||
_gd.Api.DeleteSync(handle.Handle);
|
||||
handle.Handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
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
|
||||
|
|
|
@ -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 Silk.NET.OpenGL.Legacy;
|
||||
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,5 +1,5 @@
|
|||
using Silk.NET.OpenGL.Legacy;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using SPB.Graphics;
|
||||
using SPB.Graphics.OpenGL;
|
||||
using SPB.Platform;
|
||||
|
@ -39,7 +39,7 @@ namespace Ryujinx.UI
|
|||
context.Initialize(window);
|
||||
context.MakeCurrent(window);
|
||||
|
||||
GL.LoadBindings(new OpenToolkitBindingsContext(context));
|
||||
GL api = GL.GetApi(context.GetProcAddress);
|
||||
|
||||
context.MakeCurrent(null);
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using OpenTK;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
// 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,5 +1,5 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using Ryujinx.Graphics.OpenGL;
|
||||
using Silk.NET.OpenGL.Legacy;
|
||||
using SPB.Graphics;
|
||||
using SPB.Graphics.OpenGL;
|
||||
using SPB.Platform;
|
||||
|
@ -39,7 +39,7 @@ namespace Ryujinx.Ava.UI.Renderer
|
|||
context.Initialize(window);
|
||||
context.MakeCurrent(window);
|
||||
|
||||
GL.LoadBindings(new OpenTKBindingsContext(context.GetProcAddress));
|
||||
GL api = GL.GetApi(context.GetProcAddress);
|
||||
|
||||
context.MakeCurrent(null);
|
||||
|
||||
|
|
Loading…
Reference in New Issue