aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Gpu/Engine
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2023-06-10 18:31:38 -0300
committerGitHub <noreply@github.com>2023-06-10 18:31:38 -0300
commiteb0bb36bbfc3a4f5f2ac1c8721e192239f899a1d (patch)
treee43650855d28e8d49d7ad2d82466647263c3fe16 /src/Ryujinx.Graphics.Gpu/Engine
parent0e95a8271ac96b2c54907858140e2511a25a2b10 (diff)
Implement transform feedback emulation for hardware without native support (#5080)
* Implement transform feedback emulation for hardware without native support * Stop doing some useless buffer updates and account for non-zero base instance * Reduce redundant updates even more * Update descriptor init logic to account for ResourceLayout * Fix transform feedback and storage buffers not being updated in some cases * Shader cache version bump * PR feedback * SetInstancedDrawVertexCount must be always called after UpdateState * Minor typo
Diffstat (limited to 'src/Ryujinx.Graphics.Gpu/Engine')
-rw-r--r--src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs12
-rw-r--r--src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs18
2 files changed, 29 insertions, 1 deletions
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs
index 7438ba03..9c4921c8 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs
@@ -539,6 +539,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
engine.UpdateState();
+ if (instanceCount > 1)
+ {
+ // Must be called after UpdateState as it assumes the shader state
+ // has already been set, and that bindings have been updated already.
+
+ _channel.BufferManager.SetInstancedDrawVertexCount(count);
+ }
+
if (indexed)
{
_context.Renderer.Pipeline.DrawIndexed(count, instanceCount, firstIndex, firstVertex, firstInstance);
@@ -676,6 +684,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_channel.BufferManager.SetIndexBuffer(br, IndexType.UInt);
}
+ _channel.BufferManager.SetInstancedDrawVertexCount(_instancedIndexCount);
+
_context.Renderer.Pipeline.DrawIndexed(
_instancedIndexCount,
_instanceIndex + 1,
@@ -685,6 +695,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
}
else
{
+ _channel.BufferManager.SetInstancedDrawVertexCount(_instancedDrawStateCount);
+
_context.Renderer.Pipeline.Draw(
_instancedDrawStateCount,
_instanceIndex + 1,
diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
index 5fa4702b..92e980ce 100644
--- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
+++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
@@ -269,7 +269,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_prevFirstVertex = _state.State.FirstVertex;
}
- bool tfEnable = _state.State.TfEnable;
+ bool tfEnable = _state.State.TfEnable && _context.Capabilities.SupportsTransformFeedback;
if (!tfEnable && _prevTfEnable)
{
@@ -1367,6 +1367,22 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_vsUsesDrawParameters = gs.Shaders[1]?.Info.UsesDrawParameters ?? false;
_vsClipDistancesWritten = gs.Shaders[1]?.Info.ClipDistancesWritten ?? 0;
+ bool hasTransformFeedback = gs.SpecializationState.TransformFeedbackDescriptors != null;
+ if (hasTransformFeedback != _channel.BufferManager.HasTransformFeedbackOutputs)
+ {
+ if (!_context.Capabilities.SupportsTransformFeedback)
+ {
+ // If host does not support transform feedback, and the shader changed,
+ // we might need to update bindings as transform feedback emulation
+ // uses storage buffer bindings that might have been used for something
+ // else in a previous draw.
+
+ _channel.BufferManager.ForceTransformFeedbackAndStorageBuffersDirty();
+ }
+
+ _channel.BufferManager.HasTransformFeedbackOutputs = hasTransformFeedback;
+ }
+
if (oldVsClipDistancesWritten != _vsClipDistancesWritten)
{
UpdateUserClipState();