aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Engine/Methods.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine/Methods.cs')
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Methods.cs44
1 files changed, 43 insertions, 1 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
index d5b11c2c..093f9048 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
@@ -40,6 +40,8 @@ namespace Ryujinx.Graphics.Gpu.Engine
private bool _forceShaderUpdate;
+ private bool _prevTfEnable;
+
/// <summary>
/// Creates a new instance of the GPU methods class.
/// </summary>
@@ -124,6 +126,14 @@ namespace Ryujinx.Graphics.Gpu.Engine
/// <param name="state">Guest GPU state</param>
private void UpdateState(GpuState state)
{
+ bool tfEnable = state.Get<Boolean32>(MethodOffset.TfEnable);
+
+ if (!tfEnable && _prevTfEnable)
+ {
+ _context.Renderer.Pipeline.EndTransformFeedback();
+ _prevTfEnable = false;
+ }
+
// Shaders must be the first one to be updated if modified, because
// some of the other state depends on information from the currently
// bound shaders.
@@ -134,6 +144,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
UpdateShaderState(state);
}
+ if (state.QueryModified(MethodOffset.TfBufferState))
+ {
+ UpdateTfBufferState(state);
+ }
+
if (state.QueryModified(MethodOffset.ClipDistanceEnable))
{
UpdateUserClipState(state);
@@ -258,6 +273,12 @@ namespace Ryujinx.Graphics.Gpu.Engine
}
CommitBindings();
+
+ if (tfEnable && !_prevTfEnable)
+ {
+ _context.Renderer.Pipeline.BeginTransformFeedback(PrimitiveType.Convert());
+ _prevTfEnable = true;
+ }
}
/// <summary>
@@ -318,7 +339,7 @@ namespace Ryujinx.Graphics.Gpu.Engine
/// </summary>
/// <param name="state">Current GPU state</param>
/// <param name="useControl">Use draw buffers information from render target control register</param>
- /// <param name="singleUse">If this is not -1, it indicates that only the given indexed target will be used.</param>
+ /// <param name="singleUse">If this is not -1, it indicates that only the given indexed target will be used.</param>
private void UpdateRenderTargetState(GpuState state, bool useControl, int singleUse = -1)
{
var rtControl = state.Get<RtControl>(MethodOffset.RtControl);
@@ -1004,6 +1025,27 @@ namespace Ryujinx.Graphics.Gpu.Engine
}
/// <summary>
+ /// Updates transform feedback buffer state based on the guest GPU state.
+ /// </summary>
+ /// <param name="state">Current GPU state</param>
+ private void UpdateTfBufferState(GpuState state)
+ {
+ for (int index = 0; index < Constants.TotalTransformFeedbackBuffers; index++)
+ {
+ TfBufferState tfb = state.Get<TfBufferState>(MethodOffset.TfBufferState, index);
+
+ if (!tfb.Enable)
+ {
+ BufferManager.SetTransformFeedbackBuffer(index, 0, 0);
+
+ continue;
+ }
+
+ BufferManager.SetTransformFeedbackBuffer(index, tfb.Address.Pack(), (uint)tfb.Size);
+ }
+ }
+
+ /// <summary>
/// Updates user-defined clipping based on the guest GPU state.
/// </summary>
/// <param name="state">Current GPU state</param>