Fix vertex buffer size when switching between inline and state draw parameters (#6101)

* Fix vertex buffer size when switching between inline and state draw parameters

* Format whitespace
This commit is contained in:
gdkchan 2024-01-14 05:37:19 -03:00 committed by GitHub
parent 4e19b36ad7
commit f4b74e9ce1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 11 deletions

View file

@ -103,6 +103,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// <param name="argument">Method call argument</param> /// <param name="argument">Method call argument</param>
public void DrawEnd(ThreedClass engine, int argument) public void DrawEnd(ThreedClass engine, int argument)
{ {
_drawState.DrawUsesEngineState = true;
DrawEnd( DrawEnd(
engine, engine,
_state.State.IndexBufferState.First, _state.State.IndexBufferState.First,
@ -205,10 +207,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
} }
else else
{ {
#pragma warning disable IDE0059 // Remove unnecessary value assignment
var drawState = _state.State.VertexBufferDrawState;
#pragma warning restore IDE0059
DrawImpl(engine, drawVertexCount, 1, 0, drawFirstVertex, firstInstance, indexed: false); DrawImpl(engine, drawVertexCount, 1, 0, drawFirstVertex, firstInstance, indexed: false);
} }
@ -379,6 +377,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
bool oldDrawIndexed = _drawState.DrawIndexed; bool oldDrawIndexed = _drawState.DrawIndexed;
_drawState.DrawIndexed = true; _drawState.DrawIndexed = true;
_drawState.DrawUsesEngineState = false;
engine.ForceStateDirty(IndexBufferCountMethodOffset * 4); engine.ForceStateDirty(IndexBufferCountMethodOffset * 4);
DrawEnd(engine, firstIndex, indexCount, 0, 0); DrawEnd(engine, firstIndex, indexCount, 0, 0);
@ -424,6 +423,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
bool oldDrawIndexed = _drawState.DrawIndexed; bool oldDrawIndexed = _drawState.DrawIndexed;
_drawState.DrawIndexed = false; _drawState.DrawIndexed = false;
_drawState.DrawUsesEngineState = false;
engine.ForceStateDirty(VertexBufferFirstMethodOffset * 4); engine.ForceStateDirty(VertexBufferFirstMethodOffset * 4);
DrawEnd(engine, 0, 0, firstVertex, vertexCount); DrawEnd(engine, 0, 0, firstVertex, vertexCount);
@ -544,6 +544,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_state.State.FirstInstance = (uint)firstInstance; _state.State.FirstInstance = (uint)firstInstance;
_drawState.DrawIndexed = indexed; _drawState.DrawIndexed = indexed;
_drawState.DrawUsesEngineState = true;
_currentSpecState.SetHasConstantBufferDrawParameters(true); _currentSpecState.SetHasConstantBufferDrawParameters(true);
engine.UpdateState(); engine.UpdateState();
@ -676,6 +677,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_drawState.DrawIndexed = indexed; _drawState.DrawIndexed = indexed;
_drawState.DrawIndirect = true; _drawState.DrawIndirect = true;
_drawState.DrawUsesEngineState = true;
_currentSpecState.SetHasConstantBufferDrawParameters(true); _currentSpecState.SetHasConstantBufferDrawParameters(true);
engine.UpdateState(); engine.UpdateState();

View file

@ -38,6 +38,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// </summary> /// </summary>
public bool DrawIndirect; public bool DrawIndirect;
/// <summary>
/// Indicates that the draw is using the draw parameters on the 3D engine state, rather than inline parameters submitted with the draw command.
/// </summary>
public bool DrawUsesEngineState;
/// <summary> /// <summary>
/// Indicates if any of the currently used vertex shaders reads the instance ID. /// Indicates if any of the currently used vertex shaders reads the instance ID.
/// </summary> /// </summary>
@ -48,11 +53,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// </summary> /// </summary>
public bool IsAnyVbInstanced; public bool IsAnyVbInstanced;
/// <summary>
/// Indicates that the draw is writing the base vertex, base instance and draw index to Constant Buffer 0.
/// </summary>
public bool HasConstantBufferDrawParameters;
/// <summary> /// <summary>
/// Primitive topology for the next draw. /// Primitive topology for the next draw.
/// </summary> /// </summary>

View file

@ -47,7 +47,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
private uint _vbEnableMask; private uint _vbEnableMask;
private bool _prevDrawIndexed; private bool _prevDrawIndexed;
private readonly bool _prevDrawIndirect; private bool _prevDrawIndirect;
private bool _prevDrawUsesEngineState;
private IndexType _prevIndexType; private IndexType _prevIndexType;
private uint _prevFirstVertex; private uint _prevFirstVertex;
private bool _prevTfEnable; private bool _prevTfEnable;
@ -236,7 +237,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
// method when doing indexed draws, so we need to make sure // method when doing indexed draws, so we need to make sure
// to update the vertex buffers if we are doing a regular // to update the vertex buffers if we are doing a regular
// draw after a indexed one and vice-versa. // draw after a indexed one and vice-versa.
if (_drawState.DrawIndexed != _prevDrawIndexed) // Some draws also do not update the engine state, so it is possible for it
// to not be dirty even if the vertex counts or other state changed. We need to force it to be dirty in this case.
if (_drawState.DrawIndexed != _prevDrawIndexed || _drawState.DrawUsesEngineState != _prevDrawUsesEngineState)
{ {
_updateTracker.ForceDirty(VertexBufferStateIndex); _updateTracker.ForceDirty(VertexBufferStateIndex);
@ -251,6 +254,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
} }
_prevDrawIndexed = _drawState.DrawIndexed; _prevDrawIndexed = _drawState.DrawIndexed;
_prevDrawUsesEngineState = _drawState.DrawUsesEngineState;
} }
// Some draw parameters are used to restrict the vertex buffer size, // Some draw parameters are used to restrict the vertex buffer size,
@ -260,6 +264,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
if (_drawState.DrawIndirect != _prevDrawIndirect) if (_drawState.DrawIndirect != _prevDrawIndirect)
{ {
_updateTracker.ForceDirty(VertexBufferStateIndex); _updateTracker.ForceDirty(VertexBufferStateIndex);
_prevDrawIndirect = _drawState.DrawIndirect;
} }
// In some cases, the index type is also used to guess the // In some cases, the index type is also used to guess the