diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2023-06-10 18:31:38 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-10 18:31:38 -0300 |
| commit | eb0bb36bbfc3a4f5f2ac1c8721e192239f899a1d (patch) | |
| tree | e43650855d28e8d49d7ad2d82466647263c3fe16 /src/Ryujinx.Graphics.Gpu/Engine | |
| parent | 0e95a8271ac96b2c54907858140e2511a25a2b10 (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.cs | 12 | ||||
| -rw-r--r-- | src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs | 18 |
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(); |
