diff options
author | gdkchan <gab.dark.100@gmail.com> | 2020-07-15 00:01:10 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-15 13:01:10 +1000 |
commit | 788ca6a411762035a6a7a88100c4b582b47ee82d (patch) | |
tree | d48bfb91aecaead2906ec2d390357546f8c0611f /Ryujinx.Graphics.Gpu/Engine/Methods.cs | |
parent | 16dafe63166d065f40b57a9b7cf8017a6ba0b1ef (diff) |
Initial transform feedback support (#1370)
* Initial transform feedback support
* Some nits and fixes
* Update ReportCounterType and Write method
* Can't change shader or TFB bindings while TFB is active
* Fix geometry shader input names with new naming
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine/Methods.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/Methods.cs | 44 |
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> |