diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2022-11-16 14:53:04 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-16 14:53:04 -0300 |
| commit | f1d1670b0b1b5c08064df95dabd295f3cf5dcf7f (patch) | |
| tree | 082139cb80ee9776f3ea9083991fb3ed6618f7f4 /Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs | |
| parent | b8de72de8f25f0bb7f994bc07a0387c1c247b6fe (diff) | |
Implement HLE macro for DrawElementsIndirect (#3748)
* Implement HLE macro for DrawElementsIndirect
* Shader cache version bump
* Use GL_ARB_shader_draw_parameters extension on OpenGL
* Fix DrawIndexedIndirectCount on Vulkan when extension is not supported
* Implement DrawIndex
* Alignment
* Fix some validation errors
* Rename BaseIds to DrawParameters
* Fix incorrect index buffer and vertex buffer size in some cases
* Add HLE macros for DrawArraysInstanced and DrawElementsInstanced
* Perform a regular draw when indirect data is not modified
* Use non-indirect draw methods if indirect buffer was not GPU modified
* Only check if draw parameters match if the shader actually uses them
* Expose Macro HLE setting on GUI
* Reset FirstVertex and FirstInstance after draw
* Update shader cache version again since some people already tested this
* PR feedback
Co-authored-by: riperiperi <rhy3756547@hotmail.com>
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs index fdf8f822..3f71172c 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs @@ -34,10 +34,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed private ProgramPipelineState _pipeline; + private bool _vsUsesDrawParameters; private bool _vtgWritesRtLayer; private byte _vsClipDistancesWritten; private bool _prevDrawIndexed; + private bool _prevDrawIndirect; private IndexType _prevIndexType; private uint _prevFirstVertex; private bool _prevTfEnable; @@ -210,7 +212,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed // of the shader for the new state. if (_shaderSpecState != null) { - if (!_shaderSpecState.MatchesGraphics(_channel, GetPoolState(), GetGraphicsState(), false)) + if (!_shaderSpecState.MatchesGraphics(_channel, GetPoolState(), GetGraphicsState(), _vsUsesDrawParameters, false)) { ForceShaderUpdate(); } @@ -237,6 +239,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _prevDrawIndexed = _drawState.DrawIndexed; } + // Some draw parameters are used to restrict the vertex buffer size, + // but they can't be used on indirect draws because their values are unknown in this case. + // When switching between indirect and non-indirect draw, we need to + // make sure the vertex buffer sizes are still correct. + if (_drawState.DrawIndirect != _prevDrawIndirect) + { + _updateTracker.ForceDirty(VertexBufferStateIndex); + } + // In some cases, the index type is also used to guess the // vertex buffer size, so we must update it if the type changed too. if (_drawState.DrawIndexed && @@ -938,6 +949,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _drawState.IsAnyVbInstanced = false; + bool drawIndexed = _drawState.DrawIndexed; + bool drawIndirect = _drawState.DrawIndirect; + for (int index = 0; index < Constants.TotalVertexBuffers; index++) { var vertexBuffer = _state.State.VertexBufferState[index]; @@ -965,14 +979,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed ulong vbSize = endAddress.Pack() - address + 1; ulong size; - if (_drawState.IbStreamer.HasInlineIndexData || _drawState.DrawIndexed || stride == 0 || instanced) + if (_drawState.IbStreamer.HasInlineIndexData || drawIndexed || stride == 0 || instanced) { // This size may be (much) larger than the real vertex buffer size. // Avoid calculating it this way, unless we don't have any other option. size = vbSize; - if (stride > 0 && indexTypeSmall && _drawState.DrawIndexed && !instanced) + if (stride > 0 && indexTypeSmall && drawIndexed && !drawIndirect && !instanced) { // If the index type is a small integer type, then we might be still able // to reduce the vertex buffer size based on the maximum possible index value. @@ -1207,6 +1221,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed byte oldVsClipDistancesWritten = _vsClipDistancesWritten; _drawState.VsUsesInstanceId = gs.Shaders[1]?.Info.UsesInstanceId ?? false; + _vsUsesDrawParameters = gs.Shaders[1]?.Info.UsesDrawParameters ?? false; _vsClipDistancesWritten = gs.Shaders[1]?.Info.ClipDistancesWritten ?? 0; if (oldVsClipDistancesWritten != _vsClipDistancesWritten) @@ -1222,6 +1237,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _context.Renderer.Pipeline.SetProgram(gs.HostProgram); } + /// <summary> + /// Updates bindings consumed by the shader stage on the texture and buffer managers. + /// </summary> + /// <param name="stage">Shader stage to have the bindings updated</param> + /// <param name="info">Shader stage bindings info</param> private void UpdateStageBindings(int stage, ShaderProgramInfo info) { _currentProgramInfo[stage] = info; @@ -1340,7 +1360,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _state.State.AlphaTestEnable, _state.State.AlphaTestFunc, _state.State.AlphaTestRef, - ref attributeTypes); + ref attributeTypes, + _drawState.HasConstantBufferDrawParameters); } /// <summary> |
