Implement user-defined clipping on GL state pipeline (#1118)

This commit is contained in:
mageven 2020-05-04 07:34:49 +05:30 committed by GitHub
parent 12399b8aea
commit 53369e79bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 0 deletions

View file

@ -66,6 +66,8 @@ namespace Ryujinx.Graphics.GAL
void SetUniformBuffer(int index, ShaderStage stage, BufferRange buffer); void SetUniformBuffer(int index, ShaderStage stage, BufferRange buffer);
void SetUserClipDistance(int index, bool enableClip);
void SetVertexAttribs(VertexAttribDescriptor[] vertexAttribs); void SetVertexAttribs(VertexAttribDescriptor[] vertexAttribs);
void SetVertexBuffers(VertexBufferDescriptor[] vertexBuffers); void SetVertexBuffers(VertexBufferDescriptor[] vertexBuffers);

View file

@ -54,5 +54,10 @@ namespace Ryujinx.Graphics.Gpu
/// Maximum number of viewports. /// Maximum number of viewports.
/// </summary> /// </summary>
public const int TotalViewports = 16; public const int TotalViewports = 16;
/// <summary>
/// Maximum size of gl_ClipDistance array in shaders.
/// </summary>
public const int TotalClipDistances = 8;
} }
} }

View file

@ -125,6 +125,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
UpdateShaderState(state); UpdateShaderState(state);
} }
if (state.QueryModified(MethodOffset.ClipDistanceEnable))
{
UpdateUserClipState(state);
}
if (state.QueryModified(MethodOffset.RasterizeEnable)) if (state.QueryModified(MethodOffset.RasterizeEnable))
{ {
UpdateRasterizerState(state); UpdateRasterizerState(state);
@ -902,6 +907,20 @@ namespace Ryujinx.Graphics.Gpu.Engine
_context.Renderer.Pipeline.SetProgram(gs.HostProgram); _context.Renderer.Pipeline.SetProgram(gs.HostProgram);
} }
/// <summary>
/// Updates user-defined clipping based on the guest GPU state.
/// </summary>
/// <param name="state">Current GPU state</param>
private void UpdateUserClipState(GpuState state)
{
int clipMask = state.Get<int>(MethodOffset.ClipDistanceEnable);
for (int i = 0; i < Constants.TotalClipDistances; ++i)
{
_context.Renderer.Pipeline.SetUserClipDistance(i, (clipMask & (1 << i)) != 0);
}
}
/// <summary> /// <summary>
/// Gets texture target from a sampler type. /// Gets texture target from a sampler type.
/// </summary> /// </summary>

View file

@ -66,6 +66,7 @@ namespace Ryujinx.Graphics.Gpu.State
YControl = 0x4eb, YControl = 0x4eb,
FirstVertex = 0x50d, FirstVertex = 0x50d,
FirstInstance = 0x50e, FirstInstance = 0x50e,
ClipDistanceEnable = 0x544,
PointSize = 0x546, PointSize = 0x546,
ResetCounter = 0x54c, ResetCounter = 0x54c,
RtDepthStencilEnable = 0x54e, RtDepthStencilEnable = 0x54e,

View file

@ -811,6 +811,17 @@ namespace Ryujinx.Graphics.OpenGL
SetBuffer(index, stage, buffer, isStorage: false); SetBuffer(index, stage, buffer, isStorage: false);
} }
public void SetUserClipDistance(int index, bool enableClip)
{
if (!enableClip)
{
GL.Disable(EnableCap.ClipDistance0 + index);
return;
}
GL.Enable(EnableCap.ClipDistance0 + index);
}
public void SetVertexAttribs(VertexAttribDescriptor[] vertexAttribs) public void SetVertexAttribs(VertexAttribDescriptor[] vertexAttribs)
{ {
EnsureVertexArray(); EnsureVertexArray();