mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-01-07 16:33:05 +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.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);
|
return new PinnedSpan<byte>(target.ToPointer(), size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Silk.NET.OpenGL.Legacy;
|
using Silk.NET.OpenGL.Legacy;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.OpenGL.Image;
|
using Ryujinx.Graphics.OpenGL.Image;
|
||||||
|
using Silk.NET.OpenGL.Legacy.Extensions.NV;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
|
|
@ -48,14 +48,14 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
public OpenGLRenderer(GL api)
|
public OpenGLRenderer(GL api)
|
||||||
{
|
{
|
||||||
Api = api;
|
Api = api;
|
||||||
_pipeline = new Pipeline();
|
_pipeline = new Pipeline(Api);
|
||||||
_counters = new Counters(Api);
|
_counters = new Counters(Api);
|
||||||
_window = new Window(this);
|
_window = new Window(this);
|
||||||
_textureCopy = new TextureCopy(this);
|
_textureCopy = new TextureCopy(this);
|
||||||
_backgroundTextureCopy = new TextureCopy(this);
|
_backgroundTextureCopy = new TextureCopy(this);
|
||||||
TextureCopyIncompatible = new TextureCopyIncompatible(this);
|
TextureCopyIncompatible = new TextureCopyIncompatible(this);
|
||||||
TextureCopyMS = new TextureCopyMS(this);
|
TextureCopyMS = new TextureCopyMS(this);
|
||||||
_sync = new Sync();
|
_sync = new Sync(Api);
|
||||||
PersistentBuffers = new PersistentBuffers();
|
PersistentBuffers = new PersistentBuffers();
|
||||||
ResourcePool = new ResourcePool();
|
ResourcePool = new ResourcePool();
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
|
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)
|
public ISampler CreateSampler(SamplerCreateInfo info)
|
||||||
|
@ -292,7 +292,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info)
|
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)
|
public void CreateSync(ulong id, bool strict)
|
||||||
|
|
|
@ -4,6 +4,7 @@ using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.OpenGL.Image;
|
using Ryujinx.Graphics.OpenGL.Image;
|
||||||
using Ryujinx.Graphics.OpenGL.Queries;
|
using Ryujinx.Graphics.OpenGL.Queries;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
|
using Silk.NET.OpenGL.Legacy.Extensions.NV;
|
||||||
using System;
|
using System;
|
||||||
using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler;
|
using Sampler = Ryujinx.Graphics.OpenGL.Image.Sampler;
|
||||||
|
|
||||||
|
@ -674,7 +675,9 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
if (HwCapabilities.SupportsDrawTexture)
|
if (HwCapabilities.SupportsDrawTexture)
|
||||||
{
|
{
|
||||||
GL.NV.DrawTexture(
|
_api.TryGetExtension(out NVDrawTexture drawTexture);
|
||||||
|
|
||||||
|
drawTexture.DrawTexture(
|
||||||
view.Handle,
|
view.Handle,
|
||||||
samp.Handle,
|
samp.Handle,
|
||||||
dstRegion.X1,
|
dstRegion.X1,
|
||||||
|
@ -689,25 +692,25 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static void Disable(EnableCap cap, bool enabled)
|
static void Disable(GL api, EnableCap cap, bool enabled)
|
||||||
{
|
{
|
||||||
if (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)
|
if (enabled)
|
||||||
{
|
{
|
||||||
_api.Enable(cap);
|
api.Enable(cap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Disable(EnableCap.CullFace, _cullEnable);
|
Disable(_api, EnableCap.CullFace, _cullEnable);
|
||||||
Disable(EnableCap.StencilTest, _stencilTestEnable);
|
Disable(_api, EnableCap.StencilTest, _stencilTestEnable);
|
||||||
Disable(EnableCap.DepthTest, _depthTestEnable);
|
Disable(_api, EnableCap.DepthTest, _depthTestEnable);
|
||||||
|
|
||||||
if (_depthMask)
|
if (_depthMask)
|
||||||
{
|
{
|
||||||
|
@ -779,10 +782,12 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
if (HwCapabilities.SupportsBlendEquationAdvanced)
|
if (HwCapabilities.SupportsBlendEquationAdvanced)
|
||||||
{
|
{
|
||||||
GL.BlendEquation((BlendEquationMode)blend.Op.Convert());
|
_api.BlendEquation((GLEnum)blend.Op.Convert());
|
||||||
GL.NV.BlendParameter(NvBlendEquationAdvanced.BlendOverlapNv, (int)blend.Overlap.Convert());
|
|
||||||
GL.NV.BlendParameter(NvBlendEquationAdvanced.BlendPremultipliedSrcNv, blend.SrcPreMultiplied ? 1 : 0);
|
_api.TryGetExtension(out NVBlendEquationAdvanced nvBlendEquationAdvanced);
|
||||||
GL.Enable(EnableCap.Blend);
|
nvBlendEquationAdvanced.BlendParameter(NV.BlendOverlapNV, (int)blend.Overlap.Convert());
|
||||||
|
nvBlendEquationAdvanced.BlendParameter(NV.BlendPremultipliedSrcNV, blend.SrcPreMultiplied ? 1 : 0);
|
||||||
|
_api.Enable(EnableCap.Blend);
|
||||||
_advancedBlendEnable = true;
|
_advancedBlendEnable = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -832,7 +837,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
blend.BlendConstant.Alpha);
|
blend.BlendConstant.Alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
GL.Enable(EnableCap.Blend, index);
|
_api.Enable(EnableCap.Blend, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp)
|
public void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp)
|
||||||
|
@ -1009,9 +1014,11 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
if (HwCapabilities.SupportsAlphaToCoverageDitherControl)
|
if (HwCapabilities.SupportsAlphaToCoverageDitherControl)
|
||||||
{
|
{
|
||||||
GL.NV.AlphaToCoverageDitherControl(multisample.AlphaToCoverageDitherEnable
|
_api.TryGetExtension(out NVAlphaToCoverageDitherControl nvAlphaToCoverageDitherControl);
|
||||||
? NvAlphaToCoverageDitherControl.AlphaToCoverageDitherEnableNv
|
|
||||||
: NvAlphaToCoverageDitherControl.AlphaToCoverageDitherDisableNv);
|
nvAlphaToCoverageDitherControl.AlphaToCoverageDitherControl(multisample.AlphaToCoverageDitherEnable
|
||||||
|
? NV.AlphaToCoverageDitherEnableNV
|
||||||
|
: NV.AlphaToCoverageDitherDisableNV);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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.
|
// As we don't know if the current context is core or compat, it's safer to keep this code.
|
||||||
if (enablePointSprite)
|
if (enablePointSprite)
|
||||||
{
|
{
|
||||||
_api.Enable(EnableCap.PointSprite);
|
_api.Enable(GLEnum.PointSprite);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_api.Disable(EnableCap.PointSprite);
|
_api.Disable(GLEnum.PointSprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isProgramPointSize)
|
if (isProgramPointSize)
|
||||||
|
@ -1390,11 +1397,11 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
float[] viewportArray = _viewportArray;
|
float[] viewportArray = _viewportArray;
|
||||||
double[] depthRangeArray = _depthRangeArray;
|
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 + 0] = viewport.Region.X;
|
||||||
viewportArray[viewportElemIndex + 1] = viewport.Region.Y + (viewport.Region.Height < 0 ? viewport.Region.Height : 0);
|
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)
|
if (HwCapabilities.SupportsViewportSwizzle)
|
||||||
{
|
{
|
||||||
GL.NV.ViewportSwizzle(
|
_api.TryGetExtension(out NVViewportSwizzle nvViewportSwizzle);
|
||||||
|
|
||||||
|
nvViewportSwizzle.ViewportSwizzle(
|
||||||
index,
|
index,
|
||||||
viewport.SwizzleX.Convert(),
|
viewport.SwizzleX.Convert(),
|
||||||
viewport.SwizzleY.Convert(),
|
viewport.SwizzleY.Convert(),
|
||||||
|
@ -1568,7 +1577,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
componentMask &= 0xfu;
|
componentMask &= 0xfu;
|
||||||
|
|
||||||
_api.ColorMask(
|
_api.ColorMask(
|
||||||
index,
|
(uint)index,
|
||||||
(componentMask & redMask) != 0,
|
(componentMask & redMask) != 0,
|
||||||
(componentMask & 2u) != 0,
|
(componentMask & 2u) != 0,
|
||||||
(componentMask & blueMask) != 0,
|
(componentMask & blueMask) != 0,
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
private const int MaxShaderLogLength = 2048;
|
private const int MaxShaderLogLength = 2048;
|
||||||
|
|
||||||
public int Handle { get; private set; }
|
public uint Handle { get; private set; }
|
||||||
|
|
||||||
public bool IsLinked
|
public bool IsLinked
|
||||||
{
|
{
|
||||||
|
@ -27,18 +27,20 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly GL _api;
|
||||||
private ProgramLinkStatus _status = ProgramLinkStatus.Incomplete;
|
private ProgramLinkStatus _status = ProgramLinkStatus.Incomplete;
|
||||||
private int[] _shaderHandles;
|
private uint[] _shaderHandles;
|
||||||
|
|
||||||
public int FragmentOutputMap { get; }
|
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;
|
bool hasFragmentShader = false;
|
||||||
|
|
||||||
for (int index = 0; index < shaders.Length; index++)
|
for (int index = 0; index < shaders.Length; index++)
|
||||||
|
@ -50,43 +52,44 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
hasFragmentShader = true;
|
hasFragmentShader = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int shaderHandle = GL.CreateShader(shader.Stage.Convert());
|
uint shaderHandle = _api.CreateShader(shader.Stage.Convert());
|
||||||
|
|
||||||
switch (shader.Language)
|
switch (shader.Language)
|
||||||
{
|
{
|
||||||
case TargetLanguage.Glsl:
|
case TargetLanguage.Glsl:
|
||||||
GL.ShaderSource(shaderHandle, shader.Code);
|
_api.ShaderSource(shaderHandle, shader.Code);
|
||||||
GL.CompileShader(shaderHandle);
|
_api.CompileShader(shaderHandle);
|
||||||
break;
|
break;
|
||||||
case TargetLanguage.Spirv:
|
case TargetLanguage.Spirv:
|
||||||
GL.ShaderBinary(1, ref shaderHandle, (BinaryFormat)All.ShaderBinaryFormatSpirVArb, shader.BinaryCode, shader.BinaryCode.Length);
|
_api.ShaderBinary(1, ref shaderHandle, ShaderBinaryFormat.ShaderBinaryFormatSpirV, shader.BinaryCode, shader.BinaryCode.Length);
|
||||||
GL.SpecializeShader(shaderHandle, "main", 0, (int[])null, (int[])null);
|
_api.SpecializeShader(shaderHandle, "main", 0, (int[])null, (int[])null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
GL.AttachShader(Handle, shaderHandle);
|
_api.AttachShader(Handle, shaderHandle);
|
||||||
|
|
||||||
_shaderHandles[index] = shaderHandle;
|
_shaderHandles[index] = shaderHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
GL.LinkProgram(Handle);
|
_api.LinkProgram(Handle);
|
||||||
|
|
||||||
FragmentOutputMap = hasFragmentShader ? fragmentOutputMap : 0;
|
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)
|
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
|
unsafe
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = code)
|
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()
|
public void Bind()
|
||||||
{
|
{
|
||||||
GL.UseProgram(Handle);
|
_api.UseProgram(Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProgramLinkStatus CheckProgramLink(bool blocking)
|
public ProgramLinkStatus CheckProgramLink(bool blocking)
|
||||||
{
|
{
|
||||||
if (!blocking && HwCapabilities.SupportsParallelShaderCompile)
|
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)
|
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();
|
DeleteShaders();
|
||||||
|
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
{
|
{
|
||||||
_status = ProgramLinkStatus.Failure;
|
_status = ProgramLinkStatus.Failure;
|
||||||
|
|
||||||
string log = GL.GetProgramInfoLog(Handle);
|
string log = _api.GetProgramInfoLog(Handle);
|
||||||
|
|
||||||
if (log.Length > MaxShaderLogLength)
|
if (log.Length > MaxShaderLogLength)
|
||||||
{
|
{
|
||||||
|
@ -137,11 +140,11 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
|
|
||||||
public byte[] GetBinary()
|
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];
|
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);
|
BinaryPrimitives.WriteInt32LittleEndian(data.AsSpan(size, 4), (int)binFormat);
|
||||||
|
|
||||||
|
@ -152,10 +155,10 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
{
|
{
|
||||||
if (_shaderHandles != null)
|
if (_shaderHandles != null)
|
||||||
{
|
{
|
||||||
foreach (int shaderHandle in _shaderHandles)
|
foreach (uint shaderHandle in _shaderHandles)
|
||||||
{
|
{
|
||||||
GL.DetachShader(Handle, shaderHandle);
|
_api.DetachShader(Handle, shaderHandle);
|
||||||
GL.DeleteShader(shaderHandle);
|
_api.DeleteShader(shaderHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
_shaderHandles = null;
|
_shaderHandles = null;
|
||||||
|
@ -167,7 +170,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
if (Handle != 0)
|
if (Handle != 0)
|
||||||
{
|
{
|
||||||
DeleteShaders();
|
DeleteShaders();
|
||||||
GL.DeleteProgram(Handle);
|
_api.DeleteProgram(Handle);
|
||||||
|
|
||||||
Handle = 0;
|
Handle = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue