|
|
@@ -37,6 +37,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|
|
|
|
|
private ProgramPipelineState _pipeline;
|
|
|
|
|
|
+ private bool _fsReadsFragCoord;
|
|
|
private bool _vsUsesDrawParameters;
|
|
|
private bool _vtgWritesRtLayer;
|
|
|
private byte _vsClipDistancesWritten;
|
|
|
@@ -692,12 +693,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|
|
var face = _state.State.FaceState;
|
|
|
|
|
|
bool disableTransform = _state.State.ViewportTransformEnable == 0;
|
|
|
+ bool yNegate = yControl.HasFlag(YControl.NegateY);
|
|
|
|
|
|
UpdateFrontFace(yControl, face.FrontFace);
|
|
|
UpdateDepthMode();
|
|
|
|
|
|
- bool flipY = yControl.HasFlag(YControl.NegateY);
|
|
|
-
|
|
|
Span<Viewport> viewports = stackalloc Viewport[Constants.TotalViewports];
|
|
|
|
|
|
for (int index = 0; index < Constants.TotalViewports; index++)
|
|
|
@@ -719,7 +719,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|
|
float scaleX = MathF.Abs(transform.ScaleX);
|
|
|
float scaleY = transform.ScaleY;
|
|
|
|
|
|
- if (flipY)
|
|
|
+ if (yNegate)
|
|
|
{
|
|
|
scaleY = -scaleY;
|
|
|
}
|
|
|
@@ -771,8 +771,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|
|
_channel.TextureManager.RenderTargetScale,
|
|
|
disableTransform);
|
|
|
|
|
|
+ // Viewport size is only used on the shader when YNegate is enabled,
|
|
|
+ // and if the fragment shader accesses gl_FragCoord,
|
|
|
+ // so there's no need to update it in other cases.
|
|
|
+ if (yNegate && _fsReadsFragCoord)
|
|
|
+ {
|
|
|
+ UpdateSupportBufferViewportSize();
|
|
|
+ }
|
|
|
+
|
|
|
_currentSpecState.SetViewportTransformDisable(disableTransform);
|
|
|
_currentSpecState.SetDepthMode(GetDepthMode() == DepthMode.MinusOneToOne);
|
|
|
+ _currentSpecState.SetYNegateEnabled(yNegate);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -1415,9 +1424,41 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
|
|
_currentProgramInfo[stageIndex] = info;
|
|
|
}
|
|
|
|
|
|
+ if (gs.Shaders[5]?.Info.UsesFragCoord == true)
|
|
|
+ {
|
|
|
+ // Make sure we update the viewport size on the support buffer if it will be consumed on the new shader.
|
|
|
+
|
|
|
+ if (!_fsReadsFragCoord && _state.State.YControl.HasFlag(YControl.NegateY))
|
|
|
+ {
|
|
|
+ UpdateSupportBufferViewportSize();
|
|
|
+ }
|
|
|
+
|
|
|
+ _fsReadsFragCoord = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _fsReadsFragCoord = false;
|
|
|
+ }
|
|
|
+
|
|
|
_context.Renderer.Pipeline.SetProgram(gs.HostProgram);
|
|
|
}
|
|
|
|
|
|
+ /// <summary>
|
|
|
+ /// Updates the viewport size on the support buffer for fragment shader access.
|
|
|
+ /// </summary>
|
|
|
+ private void UpdateSupportBufferViewportSize()
|
|
|
+ {
|
|
|
+ ref var transform = ref _state.State.ViewportTransform[0];
|
|
|
+
|
|
|
+ float scaleX = MathF.Abs(transform.ScaleX);
|
|
|
+ float scaleY = transform.ScaleY;
|
|
|
+
|
|
|
+ float width = scaleX * 2;
|
|
|
+ float height = scaleY * 2;
|
|
|
+
|
|
|
+ _context.SupportBufferUpdater.SetViewportSize(width, MathF.Abs(height));
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Updates bindings consumed by the shader on the texture and buffer managers.
|
|
|
/// </summary>
|