mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-01-05 23:43:04 +00:00
NV Usage
This commit is contained in:
parent
21c3dd3bcb
commit
914f6d6af3
5 changed files with 68 additions and 55 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue