Calculate vertex buffer size from index buffer type (#3253)

* Calculate vertex buffer size from index buffer type

* We also need to update the size if first vertex changes
This commit is contained in:
gdkchan 2022-04-08 06:02:06 -03:00 committed by GitHub
parent d04ba51bb0
commit 952f6f8a65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -35,6 +35,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
private byte _vsClipDistancesWritten; private byte _vsClipDistancesWritten;
private bool _prevDrawIndexed; private bool _prevDrawIndexed;
private IndexType _prevIndexType;
private uint _prevFirstVertex;
private bool _prevTfEnable; private bool _prevTfEnable;
/// <summary> /// <summary>
@ -214,6 +216,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_prevDrawIndexed = _drawState.DrawIndexed; _prevDrawIndexed = _drawState.DrawIndexed;
} }
// 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 &&
(_prevIndexType != _state.State.IndexBufferState.Type ||
_prevFirstVertex != _state.State.FirstVertex))
{
_updateTracker.ForceDirty(VertexBufferStateIndex);
_prevIndexType = _state.State.IndexBufferState.Type;
_prevFirstVertex = _state.State.FirstVertex;
}
bool tfEnable = _state.State.TfEnable; bool tfEnable = _state.State.TfEnable;
if (!tfEnable && _prevTfEnable) if (!tfEnable && _prevTfEnable)
@ -867,6 +880,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
/// </summary> /// </summary>
private void UpdateVertexBufferState() private void UpdateVertexBufferState()
{ {
IndexType indexType = _state.State.IndexBufferState.Type;
bool indexTypeSmall = indexType == IndexType.UByte || indexType == IndexType.UShort;
_drawState.IsAnyVbInstanced = false; _drawState.IsAnyVbInstanced = false;
for (int index = 0; index < Constants.TotalVertexBuffers; index++) for (int index = 0; index < Constants.TotalVertexBuffers; index++)
@ -898,12 +914,27 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
{ {
// This size may be (much) larger than the real vertex buffer size. // 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. // Avoid calculating it this way, unless we don't have any other option.
size = endAddress.Pack() - address + 1; size = endAddress.Pack() - address + 1;
if (stride > 0 && indexTypeSmall)
{
// 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.
ulong maxVertexBufferSize = indexType == IndexType.UByte ? 0x100UL : 0x10000UL;
maxVertexBufferSize += _state.State.FirstVertex;
maxVertexBufferSize *= (uint)stride;
size = Math.Min(size, maxVertexBufferSize);
}
} }
else else
{ {
// For non-indexed draws, we can guess the size from the vertex count // For non-indexed draws, we can guess the size from the vertex count
// and stride. // and stride.
int firstInstance = (int)_state.State.FirstInstance; int firstInstance = (int)_state.State.FirstInstance;
var drawState = _state.State.VertexBufferDrawState; var drawState = _state.State.VertexBufferDrawState;