Better depth range detection (#2754)
* Better depth range detection * PR feedback * Move depth mode set out of the loop and to a separate method
This commit is contained in:
parent
02d786a086
commit
30b7aaefca
1 changed files with 41 additions and 20 deletions
|
@ -485,6 +485,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
var face = _state.State.FaceState;
|
var face = _state.State.FaceState;
|
||||||
|
|
||||||
UpdateFrontFace(yControl, face.FrontFace);
|
UpdateFrontFace(yControl, face.FrontFace);
|
||||||
|
UpdateDepthMode();
|
||||||
|
|
||||||
bool flipY = yControl.HasFlag(YControl.NegateY);
|
bool flipY = yControl.HasFlag(YControl.NegateY);
|
||||||
|
|
||||||
|
@ -492,8 +493,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
|
|
||||||
for (int index = 0; index < Constants.TotalViewports; index++)
|
for (int index = 0; index < Constants.TotalViewports; index++)
|
||||||
{
|
{
|
||||||
var transform = _state.State.ViewportTransform[index];
|
ref var transform = ref _state.State.ViewportTransform[index];
|
||||||
var extents = _state.State.ViewportExtents[index];
|
ref var extents = ref _state.State.ViewportExtents[index];
|
||||||
|
|
||||||
float scaleX = MathF.Abs(transform.ScaleX);
|
float scaleX = MathF.Abs(transform.ScaleX);
|
||||||
float scaleY = transform.ScaleY;
|
float scaleY = transform.ScaleY;
|
||||||
|
@ -508,24 +509,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
scaleY = -scaleY;
|
scaleY = -scaleY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index == 0)
|
|
||||||
{
|
|
||||||
// Try to guess the depth mode being used on the high level API
|
|
||||||
// based on current transform.
|
|
||||||
// It is setup like so by said APIs:
|
|
||||||
// If depth mode is ZeroToOne:
|
|
||||||
// TranslateZ = Near
|
|
||||||
// ScaleZ = Far - Near
|
|
||||||
// If depth mode is MinusOneToOne:
|
|
||||||
// TranslateZ = (Near + Far) / 2
|
|
||||||
// ScaleZ = (Far - Near) / 2
|
|
||||||
// DepthNear/Far are sorted such as that Near is always less than Far.
|
|
||||||
DepthMode depthMode = extents.DepthNear != transform.TranslateZ &&
|
|
||||||
extents.DepthFar != transform.TranslateZ ? DepthMode.MinusOneToOne : DepthMode.ZeroToOne;
|
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetDepthMode(depthMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
float x = transform.TranslateX - scaleX;
|
float x = transform.TranslateX - scaleX;
|
||||||
float y = transform.TranslateY - scaleY;
|
float y = transform.TranslateY - scaleY;
|
||||||
|
|
||||||
|
@ -564,6 +547,44 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||||
_context.Renderer.Pipeline.SetViewports(0, viewports);
|
_context.Renderer.Pipeline.SetViewports(0, viewports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the depth mode (0 to 1 or -1 to 1) based on the current viewport and depth mode register state.
|
||||||
|
/// </summary>
|
||||||
|
private void UpdateDepthMode()
|
||||||
|
{
|
||||||
|
ref var transform = ref _state.State.ViewportTransform[0];
|
||||||
|
ref var extents = ref _state.State.ViewportExtents[0];
|
||||||
|
|
||||||
|
DepthMode depthMode;
|
||||||
|
|
||||||
|
if (!float.IsInfinity(extents.DepthNear) &&
|
||||||
|
!float.IsInfinity(extents.DepthFar) &&
|
||||||
|
(extents.DepthFar - extents.DepthNear) != 0)
|
||||||
|
{
|
||||||
|
// Try to guess the depth mode being used on the high level API
|
||||||
|
// based on current transform.
|
||||||
|
// It is setup like so by said APIs:
|
||||||
|
// If depth mode is ZeroToOne:
|
||||||
|
// TranslateZ = Near
|
||||||
|
// ScaleZ = Far - Near
|
||||||
|
// If depth mode is MinusOneToOne:
|
||||||
|
// TranslateZ = (Near + Far) / 2
|
||||||
|
// ScaleZ = (Far - Near) / 2
|
||||||
|
// DepthNear/Far are sorted such as that Near is always less than Far.
|
||||||
|
depthMode = extents.DepthNear != transform.TranslateZ &&
|
||||||
|
extents.DepthFar != transform.TranslateZ
|
||||||
|
? DepthMode.MinusOneToOne
|
||||||
|
: DepthMode.ZeroToOne;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we can't guess from the viewport transform, then just use the depth mode register.
|
||||||
|
depthMode = (DepthMode)(_state.State.DepthMode & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_context.Renderer.Pipeline.SetDepthMode(depthMode);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates polygon mode state based on current GPU state.
|
/// Updates polygon mode state based on current GPU state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Reference in a new issue