forked from Mirror/Ryujinx
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:
parent
d04ba51bb0
commit
952f6f8a65
1 changed files with 31 additions and 0 deletions
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue