aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-11-16 14:53:04 -0300
committerGitHub <noreply@github.com>2022-11-16 14:53:04 -0300
commitf1d1670b0b1b5c08064df95dabd295f3cf5dcf7f (patch)
tree082139cb80ee9776f3ea9083991fb3ed6618f7f4 /Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
parentb8de72de8f25f0bb7f994bc07a0387c1c247b6fe (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.cs29
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>