From 4960ab85f81f48553b7217261f4181e31d812a10 Mon Sep 17 00:00:00 2001
From: mageven <62494521+mageven@users.noreply.github.com>
Date: Fri, 17 Apr 2020 06:46:49 +0530
Subject: [PATCH] Implement Depth Clamping (#1120)
* Implement Depth Clamping and add misc enums
* Fix formatting
---
Ryujinx.Graphics.GAL/IPipeline.cs | 1 +
Ryujinx.Graphics.Gpu/Engine/Methods.cs | 23 ++++++++++++++++---
Ryujinx.Graphics.Gpu/State/MethodOffset.cs | 1 +
.../State/ViewVolumeClipControl.cs | 12 ++++++++++
Ryujinx.Graphics.Gpu/State/YControl.cs | 11 +++++++++
Ryujinx.Graphics.OpenGL/Pipeline.cs | 15 ++++++++++++
6 files changed, 60 insertions(+), 3 deletions(-)
create mode 100644 Ryujinx.Graphics.Gpu/State/ViewVolumeClipControl.cs
create mode 100644 Ryujinx.Graphics.Gpu/State/YControl.cs
diff --git a/Ryujinx.Graphics.GAL/IPipeline.cs b/Ryujinx.Graphics.GAL/IPipeline.cs
index 5b663823..4c892bea 100644
--- a/Ryujinx.Graphics.GAL/IPipeline.cs
+++ b/Ryujinx.Graphics.GAL/IPipeline.cs
@@ -29,6 +29,7 @@ namespace Ryujinx.Graphics.GAL
void SetBlendColor(ColorF color);
void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp);
+ void SetDepthClamp(bool clampNear, bool clampFar);
void SetDepthMode(DepthMode mode);
void SetDepthTest(DepthTestDescriptor depthTest);
diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
index 50913801..b7f4e1d9 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
@@ -127,6 +127,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
UpdateScissorState(state);
}
+ if (state.QueryModified(MethodOffset.ViewVolumeClipControl))
+ {
+ UpdateDepthClampState(state);
+ }
+
if (state.QueryModified(MethodOffset.DepthTestEnable,
MethodOffset.DepthWriteEnable,
MethodOffset.DepthTestFunc))
@@ -134,7 +139,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
UpdateDepthTestState(state);
}
- if (state.QueryModified(MethodOffset.DepthMode, MethodOffset.ViewportTransform, MethodOffset.ViewportExtents))
+ if (state.QueryModified(MethodOffset.DepthMode,
+ MethodOffset.ViewportTransform,
+ MethodOffset.ViewportExtents))
{
UpdateViewportTransform(state);
}
@@ -362,6 +369,17 @@ namespace Ryujinx.Graphics.Gpu.Engine
}
}
+ ///
+ /// Updates host depth clamp state based on current GPU state.
+ ///
+ /// Current GPU state
+ private void UpdateDepthClampState(GpuState state)
+ {
+ ViewVolumeClipControl clip = state.Get(MethodOffset.ViewVolumeClipControl);
+ _context.Renderer.Pipeline.SetDepthClamp((clip & ViewVolumeClipControl.DepthClampNear) != 0,
+ (clip & ViewVolumeClipControl.DepthClampFar) != 0);
+ }
+
///
/// Updates host depth test state based on current GPU state.
///
@@ -384,8 +402,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
_context.Renderer.Pipeline.SetDepthMode(depthMode);
- bool flipY = (state.Get(MethodOffset.YControl) & 1) != 0;
-
+ bool flipY = (state.Get(MethodOffset.YControl) & YControl.NegateY) != 0;
float yFlip = flipY ? -1 : 1;
Viewport[] viewports = new Viewport[Constants.TotalViewports];
diff --git a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
index a178c2f8..b8ee7e91 100644
--- a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
+++ b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs
@@ -75,6 +75,7 @@ namespace Ryujinx.Graphics.Gpu.State
VertexBufferInstanced = 0x620,
FaceState = 0x646,
ViewportTransformEnable = 0x64b,
+ ViewVolumeClipControl = 0x64f,
Clear = 0x674,
RtColorMask = 0x680,
ReportState = 0x6c0,
diff --git a/Ryujinx.Graphics.Gpu/State/ViewVolumeClipControl.cs b/Ryujinx.Graphics.Gpu/State/ViewVolumeClipControl.cs
new file mode 100644
index 00000000..4e12c424
--- /dev/null
+++ b/Ryujinx.Graphics.Gpu/State/ViewVolumeClipControl.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace Ryujinx.Graphics.Gpu.State
+{
+ [Flags]
+ enum ViewVolumeClipControl
+ {
+ ForceDepthRangeZeroToOne = 1 << 0,
+ DepthClampNear = 1 << 3,
+ DepthClampFar = 1 << 4,
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/State/YControl.cs b/Ryujinx.Graphics.Gpu/State/YControl.cs
new file mode 100644
index 00000000..58e000d9
--- /dev/null
+++ b/Ryujinx.Graphics.Gpu/State/YControl.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace Ryujinx.Graphics.Gpu.State
+{
+ [Flags]
+ enum YControl
+ {
+ NegateY = 1 << 0,
+ TriangleRastFlip = 1 << 4
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index aef3383b..e32b5b85 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -546,6 +546,21 @@ namespace Ryujinx.Graphics.OpenGL
// GL.PolygonOffsetClamp(factor, units, clamp);
}
+ public void SetDepthClamp(bool clampNear, bool clampFar)
+ {
+ // TODO: Use GL_AMD_depth_clamp_separate or similar if available?
+ // Currently enables clamping if either is set.
+ bool clamp = clampNear || clampFar;
+
+ if (!clamp)
+ {
+ GL.Disable(EnableCap.DepthClamp);
+ return;
+ }
+
+ GL.Enable(EnableCap.DepthClamp);
+ }
+
public void SetDepthMode(DepthMode mode)
{
ClipDepthMode depthMode = mode.Convert();