Implement Depth Clamping (#1120)

* Implement Depth Clamping and add misc enums

* Fix formatting
This commit is contained in:
mageven 2020-04-17 06:46:49 +05:30 committed by GitHub
parent 0a7c6caedf
commit 4960ab85f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 3 deletions

View file

@ -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);

View file

@ -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
}
}
/// <summary>
/// Updates host depth clamp state based on current GPU state.
/// </summary>
/// <param name="state">Current GPU state</param>
private void UpdateDepthClampState(GpuState state)
{
ViewVolumeClipControl clip = state.Get<ViewVolumeClipControl>(MethodOffset.ViewVolumeClipControl);
_context.Renderer.Pipeline.SetDepthClamp((clip & ViewVolumeClipControl.DepthClampNear) != 0,
(clip & ViewVolumeClipControl.DepthClampFar) != 0);
}
/// <summary>
/// Updates host depth test state based on current GPU state.
/// </summary>
@ -384,8 +402,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
_context.Renderer.Pipeline.SetDepthMode(depthMode);
bool flipY = (state.Get<int>(MethodOffset.YControl) & 1) != 0;
bool flipY = (state.Get<YControl>(MethodOffset.YControl) & YControl.NegateY) != 0;
float yFlip = flipY ? -1 : 1;
Viewport[] viewports = new Viewport[Constants.TotalViewports];

View file

@ -75,6 +75,7 @@ namespace Ryujinx.Graphics.Gpu.State
VertexBufferInstanced = 0x620,
FaceState = 0x646,
ViewportTransformEnable = 0x64b,
ViewVolumeClipControl = 0x64f,
Clear = 0x674,
RtColorMask = 0x680,
ReportState = 0x6c0,

View file

@ -0,0 +1,12 @@
using System;
namespace Ryujinx.Graphics.Gpu.State
{
[Flags]
enum ViewVolumeClipControl
{
ForceDepthRangeZeroToOne = 1 << 0,
DepthClampNear = 1 << 3,
DepthClampFar = 1 << 4,
}
}

View file

@ -0,0 +1,11 @@
using System;
namespace Ryujinx.Graphics.Gpu.State
{
[Flags]
enum YControl
{
NegateY = 1 << 0,
TriangleRastFlip = 1 << 4
}
}

View file

@ -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();