From 914f6d6af33721b1e71dfdb7c3f2b0e41623818f Mon Sep 17 00:00:00 2001 From: Isaac Marovitz Date: Thu, 9 May 2024 12:38:23 -0400 Subject: [PATCH] NV Usage --- src/Ryujinx.Graphics.OpenGL/Buffer.cs | 2 +- src/Ryujinx.Graphics.OpenGL/Framebuffer.cs | 1 + src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs | 8 +-- src/Ryujinx.Graphics.OpenGL/Pipeline.cs | 55 ++++++++++-------- src/Ryujinx.Graphics.OpenGL/Program.cs | 57 ++++++++++--------- 5 files changed, 68 insertions(+), 55 deletions(-) diff --git a/src/Ryujinx.Graphics.OpenGL/Buffer.cs b/src/Ryujinx.Graphics.OpenGL/Buffer.cs index a8b4501ea..722b28abc 100644 --- a/src/Ryujinx.Graphics.OpenGL/Buffer.cs +++ b/src/Ryujinx.Graphics.OpenGL/Buffer.cs @@ -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(target.ToPointer(), size); } diff --git a/src/Ryujinx.Graphics.OpenGL/Framebuffer.cs b/src/Ryujinx.Graphics.OpenGL/Framebuffer.cs index 80cb4348e..7aa720eac 100644 --- a/src/Ryujinx.Graphics.OpenGL/Framebuffer.cs +++ b/src/Ryujinx.Graphics.OpenGL/Framebuffer.cs @@ -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; diff --git a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs index 5b0825520..176b3527b 100644 --- a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs +++ b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs @@ -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) diff --git a/src/Ryujinx.Graphics.OpenGL/Pipeline.cs b/src/Ryujinx.Graphics.OpenGL/Pipeline.cs index cf74a4523..a652d8c2c 100644 --- a/src/Ryujinx.Graphics.OpenGL/Pipeline.cs +++ b/src/Ryujinx.Graphics.OpenGL/Pipeline.cs @@ -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, diff --git a/src/Ryujinx.Graphics.OpenGL/Program.cs b/src/Ryujinx.Graphics.OpenGL/Program.cs index a0d88ecc5..602032baf 100644 --- a/src/Ryujinx.Graphics.OpenGL/Program.cs +++ b/src/Ryujinx.Graphics.OpenGL/Program.cs @@ -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 code, bool hasFragmentShader, int fragmentOutputMap) + public Program(GL api, ReadOnlySpan 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; }