Ryujinx/Ryujinx.Graphics.Gpu/Engine/MethodDraw.cs

141 lines
4 KiB
C#
Raw Normal View History

2019-10-13 08:02:07 +02:00
using Ryujinx.Graphics.Gpu.State;
using Ryujinx.Graphics.Gpu.Image;
namespace Ryujinx.Graphics.Gpu.Engine
{
partial class Methods
{
private bool _drawIndexed;
private int _firstIndex;
private int _indexCount;
private bool _instancedDrawPending;
2019-10-13 08:02:07 +02:00
private bool _instancedIndexed;
private int _instancedFirstIndex;
private int _instancedFirstVertex;
private int _instancedFirstInstance;
private int _instancedIndexCount;
private int _instancedDrawStateFirst;
private int _instancedDrawStateCount;
private int _instanceIndex;
public PrimitiveType PrimitiveType { get; private set; }
2019-11-22 03:46:14 +01:00
private void DrawEnd(GpuState state, int argument)
2019-10-13 08:02:07 +02:00
{
if (_instancedDrawPending)
{
_drawIndexed = false;
return;
}
2019-11-22 03:46:14 +01:00
UpdateState(state);
2019-10-13 08:02:07 +02:00
bool instanced = _vsUsesInstanceId || _isAnyVbInstanced;
if (instanced)
{
_instancedDrawPending = true;
2019-10-13 08:02:07 +02:00
_instancedIndexed = _drawIndexed;
2019-10-13 08:02:07 +02:00
_instancedFirstIndex = _firstIndex;
_instancedFirstVertex = state.Get<int>(MethodOffset.FirstVertex);
_instancedFirstInstance = state.Get<int>(MethodOffset.FirstInstance);
2019-10-13 08:02:07 +02:00
_instancedIndexCount = _indexCount;
2019-10-13 08:02:07 +02:00
var drawState = state.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
2019-10-13 08:02:07 +02:00
_instancedDrawStateFirst = drawState.First;
_instancedDrawStateCount = drawState.Count;
_drawIndexed = false;
2019-10-13 08:02:07 +02:00
return;
}
2019-11-22 03:46:14 +01:00
int firstInstance = state.Get<int>(MethodOffset.FirstInstance);
2019-10-13 08:02:07 +02:00
if (_drawIndexed)
{
_drawIndexed = false;
2019-11-22 03:46:14 +01:00
int firstVertex = state.Get<int>(MethodOffset.FirstVertex);
2019-10-13 08:02:07 +02:00
_context.Renderer.Pipeline.DrawIndexed(
2019-10-13 08:02:07 +02:00
_indexCount,
1,
_firstIndex,
firstVertex,
firstInstance);
}
else
{
2019-11-22 03:46:14 +01:00
var drawState = state.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
2019-10-13 08:02:07 +02:00
_context.Renderer.Pipeline.Draw(
2019-10-13 08:02:07 +02:00
drawState.Count,
1,
drawState.First,
firstInstance);
}
}
2019-11-22 03:46:14 +01:00
private void DrawBegin(GpuState state, int argument)
2019-10-13 08:02:07 +02:00
{
if ((argument & (1 << 26)) != 0)
{
_instanceIndex++;
}
else if ((argument & (1 << 27)) == 0)
{
PerformDeferredDraws();
2019-10-13 08:02:07 +02:00
_instanceIndex = 0;
}
PrimitiveType type = (PrimitiveType)(argument & 0xffff);
_context.Renderer.Pipeline.SetPrimitiveTopology(type.Convert());
PrimitiveType = type;
2019-10-13 08:02:07 +02:00
}
2019-11-22 03:46:14 +01:00
private void SetIndexBufferCount(GpuState state, int argument)
2019-10-13 08:02:07 +02:00
{
_drawIndexed = true;
}
public void PerformDeferredDraws()
{
// Perform any pending instanced draw.
if (_instancedDrawPending)
2019-10-13 08:02:07 +02:00
{
_instancedDrawPending = false;
2019-10-13 08:02:07 +02:00
if (_instancedIndexed)
{
_context.Renderer.Pipeline.DrawIndexed(
2019-10-13 08:02:07 +02:00
_instancedIndexCount,
_instanceIndex + 1,
_instancedFirstIndex,
_instancedFirstVertex,
_instancedFirstInstance);
}
else
{
_context.Renderer.Pipeline.Draw(
2019-10-13 08:02:07 +02:00
_instancedDrawStateCount,
_instanceIndex + 1,
_instancedDrawStateFirst,
_instancedFirstInstance);
}
}
}
}
}