This commit is contained in:
Isaac Marovitz 2024-05-09 12:38:23 -04:00
parent 21c3dd3bcb
commit 914f6d6af3
No known key found for this signature in database
GPG key ID: 97250B2B09A132E1
5 changed files with 68 additions and 55 deletions

View file

@ -88,7 +88,7 @@ namespace Ryujinx.Graphics.OpenGL
gd.Api.BindBuffer(BufferTargetARB.CopyReadBuffer, buffer.ToUInt32());
gd.Api.GetBufferSubData(BufferTargetARB.CopyReadBuffer, offset, (uint)size, target);
gd.Api.GetBufferSubData(BufferTargetARB.CopyReadBuffer, offset, (uint)size, (void*)target);
return new PinnedSpan<byte>(target.ToPointer(), size);
}

View file

@ -1,6 +1,7 @@
using Silk.NET.OpenGL.Legacy;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.OpenGL.Image;
using Silk.NET.OpenGL.Legacy.Extensions.NV;
using System;
using System.Runtime.CompilerServices;

View file

@ -48,14 +48,14 @@ namespace Ryujinx.Graphics.OpenGL
public OpenGLRenderer(GL api)
{
Api = api;
_pipeline = new Pipeline();
_pipeline = new Pipeline(Api);
_counters = new Counters(Api);
_window = new Window(this);
_textureCopy = new TextureCopy(this);
_backgroundTextureCopy = new TextureCopy(this);
TextureCopyIncompatible = new TextureCopyIncompatible(this);
TextureCopyMS = new TextureCopyMS(this);
_sync = new Sync();
_sync = new Sync(Api);
PersistentBuffers = new PersistentBuffers();
ResourcePool = new ResourcePool();
}
@ -100,7 +100,7 @@ namespace Ryujinx.Graphics.OpenGL
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
{
return new Program(shaders, info.FragmentOutputMap);
return new Program(Api, shaders, info.FragmentOutputMap);
}
public ISampler CreateSampler(SamplerCreateInfo info)
@ -292,7 +292,7 @@ namespace Ryujinx.Graphics.OpenGL
public IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info)
{
return new Program(programBinary, hasFragmentShader, info.FragmentOutputMap);
return new Program(Api, programBinary, hasFragmentShader, info.FragmentOutputMap);
}
public void CreateSync(ulong id, bool strict)

View file

@ -4,6 +4,7 @@ using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.OpenGL.Image;
using Ryujinx.Graphics.OpenGL.Queries;
using Ryujinx.Graphics.Shader;
using Silk.NET.OpenGL.Legacy.Extensions.NV;
using System;
using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler;
@ -674,7 +675,9 @@ namespace Ryujinx.Graphics.OpenGL
{
if (HwCapabilities.SupportsDrawTexture)
{
GL.NV.DrawTexture(
_api.TryGetExtension(out NVDrawTexture drawTexture);
drawTexture.DrawTexture(
view.Handle,
samp.Handle,
dstRegion.X1,
@ -689,25 +692,25 @@ namespace Ryujinx.Graphics.OpenGL
}
else
{
static void Disable(EnableCap cap, bool enabled)
static void Disable(GL api, EnableCap cap, bool enabled)
{
if (enabled)
{
_api.Disable(cap);
api.Disable(cap);
}
}
static void Enable(EnableCap cap, bool enabled)
static void Enable(GL api, EnableCap cap, bool enabled)
{
if (enabled)
{
_api.Enable(cap);
api.Enable(cap);
}
}
Disable(EnableCap.CullFace, _cullEnable);
Disable(EnableCap.StencilTest, _stencilTestEnable);
Disable(EnableCap.DepthTest, _depthTestEnable);
Disable(_api, EnableCap.CullFace, _cullEnable);
Disable(_api, EnableCap.StencilTest, _stencilTestEnable);
Disable(_api, EnableCap.DepthTest, _depthTestEnable);
if (_depthMask)
{
@ -779,10 +782,12 @@ namespace Ryujinx.Graphics.OpenGL
{
if (HwCapabilities.SupportsBlendEquationAdvanced)
{
GL.BlendEquation((BlendEquationMode)blend.Op.Convert());
GL.NV.BlendParameter(NvBlendEquationAdvanced.BlendOverlapNv, (int)blend.Overlap.Convert());
GL.NV.BlendParameter(NvBlendEquationAdvanced.BlendPremultipliedSrcNv, blend.SrcPreMultiplied ? 1 : 0);
GL.Enable(EnableCap.Blend);
_api.BlendEquation((GLEnum)blend.Op.Convert());
_api.TryGetExtension(out NVBlendEquationAdvanced nvBlendEquationAdvanced);
nvBlendEquationAdvanced.BlendParameter(NV.BlendOverlapNV, (int)blend.Overlap.Convert());
nvBlendEquationAdvanced.BlendParameter(NV.BlendPremultipliedSrcNV, blend.SrcPreMultiplied ? 1 : 0);
_api.Enable(EnableCap.Blend);
_advancedBlendEnable = true;
}
}
@ -832,7 +837,7 @@ namespace Ryujinx.Graphics.OpenGL
blend.BlendConstant.Alpha);
}
GL.Enable(EnableCap.Blend, index);
_api.Enable(EnableCap.Blend, index);
}
public void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp)
@ -1009,9 +1014,11 @@ namespace Ryujinx.Graphics.OpenGL
if (HwCapabilities.SupportsAlphaToCoverageDitherControl)
{
GL.NV.AlphaToCoverageDitherControl(multisample.AlphaToCoverageDitherEnable
? NvAlphaToCoverageDitherControl.AlphaToCoverageDitherEnableNv
: NvAlphaToCoverageDitherControl.AlphaToCoverageDitherDisableNv);
_api.TryGetExtension(out NVAlphaToCoverageDitherControl nvAlphaToCoverageDitherControl);
nvAlphaToCoverageDitherControl.AlphaToCoverageDitherControl(multisample.AlphaToCoverageDitherEnable
? NV.AlphaToCoverageDitherEnableNV
: NV.AlphaToCoverageDitherDisableNV);
}
}
else
@ -1055,11 +1062,11 @@ namespace Ryujinx.Graphics.OpenGL
// As we don't know if the current context is core or compat, it's safer to keep this code.
if (enablePointSprite)
{
_api.Enable(EnableCap.PointSprite);
_api.Enable(GLEnum.PointSprite);
}
else
{
_api.Disable(EnableCap.PointSprite);
_api.Disable(GLEnum.PointSprite);
}
if (isProgramPointSize)
@ -1390,11 +1397,11 @@ namespace Ryujinx.Graphics.OpenGL
float[] viewportArray = _viewportArray;
double[] depthRangeArray = _depthRangeArray;
for (int index = 0; index < viewports.Length; index++)
for (uint index = 0; index < viewports.Length; index++)
{
int viewportElemIndex = index * 4;
uint viewportElemIndex = index * 4;
Viewport viewport = viewports[index];
Viewport viewport = viewports[(int)index];
viewportArray[viewportElemIndex + 0] = viewport.Region.X;
viewportArray[viewportElemIndex + 1] = viewport.Region.Y + (viewport.Region.Height < 0 ? viewport.Region.Height : 0);
@ -1403,7 +1410,9 @@ namespace Ryujinx.Graphics.OpenGL
if (HwCapabilities.SupportsViewportSwizzle)
{
GL.NV.ViewportSwizzle(
_api.TryGetExtension(out NVViewportSwizzle nvViewportSwizzle);
nvViewportSwizzle.ViewportSwizzle(
index,
viewport.SwizzleX.Convert(),
viewport.SwizzleY.Convert(),
@ -1568,7 +1577,7 @@ namespace Ryujinx.Graphics.OpenGL
componentMask &= 0xfu;
_api.ColorMask(
index,
(uint)index,
(componentMask & redMask) != 0,
(componentMask & 2u) != 0,
(componentMask & blueMask) != 0,

View file

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