From 53369e79bdc34440a48e932e7024bab92f30f957 Mon Sep 17 00:00:00 2001
From: mageven <62494521+mageven@users.noreply.github.com>
Date: Mon, 4 May 2020 07:34:49 +0530
Subject: [PATCH] Implement user-defined clipping on GL state pipeline (#1118)
---
Ryujinx.Graphics.GAL/IPipeline.cs | 2 ++
Ryujinx.Graphics.Gpu/Constants.cs | 5 +++++
Ryujinx.Graphics.Gpu/Engine/Methods.cs | 19 +++++++++++++++++++
Ryujinx.Graphics.Gpu/State/MethodOffset.cs | 1 +
Ryujinx.Graphics.OpenGL/Pipeline.cs | 11 +++++++++++
5 files changed, 38 insertions(+)
diff --git a/Ryujinx.Graphics.GAL/IPipeline.cs b/Ryujinx.Graphics.GAL/IPipeline.cs
index 51b8d91ab..290462fa8 100644
--- a/Ryujinx.Graphics.GAL/IPipeline.cs
+++ b/Ryujinx.Graphics.GAL/IPipeline.cs
@@ -66,6 +66,8 @@ namespace Ryujinx.Graphics.GAL
void SetUniformBuffer(int index, ShaderStage stage, BufferRange buffer);
+ void SetUserClipDistance(int index, bool enableClip);
+
void SetVertexAttribs(VertexAttribDescriptor[] vertexAttribs);
void SetVertexBuffers(VertexBufferDescriptor[] vertexBuffers);
diff --git a/Ryujinx.Graphics.Gpu/Constants.cs b/Ryujinx.Graphics.Gpu/Constants.cs
index 3175ebd2f..1ae902731 100644
--- a/Ryujinx.Graphics.Gpu/Constants.cs
+++ b/Ryujinx.Graphics.Gpu/Constants.cs
@@ -54,5 +54,10 @@ namespace Ryujinx.Graphics.Gpu
/// Maximum number of viewports.
///
public const int TotalViewports = 16;
+
+ ///
+ /// Maximum size of gl_ClipDistance array in shaders.
+ ///
+ public const int TotalClipDistances = 8;
}
}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
index a517ae05d..59678be59 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
@@ -125,6 +125,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
UpdateShaderState(state);
}
+ if (state.QueryModified(MethodOffset.ClipDistanceEnable))
+ {
+ UpdateUserClipState(state);
+ }
+
if (state.QueryModified(MethodOffset.RasterizeEnable))
{
UpdateRasterizerState(state);
@@ -902,6 +907,20 @@ namespace Ryujinx.Graphics.Gpu.Engine
_context.Renderer.Pipeline.SetProgram(gs.HostProgram);
}
+ ///
+ /// Updates user-defined clipping based on the guest GPU state.
+ ///
+ /// Current GPU state
+ private void UpdateUserClipState(GpuState state)
+ {
+ int clipMask = state.Get(MethodOffset.ClipDistanceEnable);
+
+ for (int i = 0; i < Constants.TotalClipDistances; ++i)
+ {
+ _context.Renderer.Pipeline.SetUserClipDistance(i, (clipMask & (1 << i)) != 0);
+ }
+ }
+
///
/// Gets texture target from a sampler type.
///
diff --git a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
index 077b09c27..b39ff9b5e 100644
--- a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
+++ b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
@@ -66,6 +66,7 @@ namespace Ryujinx.Graphics.Gpu.State
YControl = 0x4eb,
FirstVertex = 0x50d,
FirstInstance = 0x50e,
+ ClipDistanceEnable = 0x544,
PointSize = 0x546,
ResetCounter = 0x54c,
RtDepthStencilEnable = 0x54e,
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index 604d0ba30..dc04805da 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -811,6 +811,17 @@ namespace Ryujinx.Graphics.OpenGL
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)
{
EnsureVertexArray();