MethodDraw.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. using Ryujinx.Graphics.Gpu.State;
  2. using Ryujinx.Graphics.Gpu.Image;
  3. namespace Ryujinx.Graphics.Gpu.Engine
  4. {
  5. partial class Methods
  6. {
  7. private bool _drawIndexed;
  8. private int _firstIndex;
  9. private int _indexCount;
  10. private bool _instancedDrawPending;
  11. private bool _instancedIndexed;
  12. private int _instancedFirstIndex;
  13. private int _instancedFirstVertex;
  14. private int _instancedFirstInstance;
  15. private int _instancedIndexCount;
  16. private int _instancedDrawStateFirst;
  17. private int _instancedDrawStateCount;
  18. private int _instanceIndex;
  19. public PrimitiveType PrimitiveType { get; private set; }
  20. private void DrawEnd(GpuState state, int argument)
  21. {
  22. UpdateState(state);
  23. bool instanced = _vsUsesInstanceId || _isAnyVbInstanced;
  24. if (instanced)
  25. {
  26. if (!_instancedDrawPending)
  27. {
  28. _instancedDrawPending = true;
  29. _instancedIndexed = _drawIndexed;
  30. _instancedFirstIndex = _firstIndex;
  31. _instancedFirstVertex = state.Get<int>(MethodOffset.FirstVertex);
  32. _instancedFirstInstance = state.Get<int>(MethodOffset.FirstInstance);
  33. _instancedIndexCount = _indexCount;
  34. var drawState = state.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
  35. _instancedDrawStateFirst = drawState.First;
  36. _instancedDrawStateCount = drawState.Count;
  37. }
  38. return;
  39. }
  40. int firstInstance = state.Get<int>(MethodOffset.FirstInstance);
  41. if (_drawIndexed)
  42. {
  43. _drawIndexed = false;
  44. int firstVertex = state.Get<int>(MethodOffset.FirstVertex);
  45. _context.Renderer.Pipeline.DrawIndexed(
  46. _indexCount,
  47. 1,
  48. _firstIndex,
  49. firstVertex,
  50. firstInstance);
  51. }
  52. else
  53. {
  54. var drawState = state.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
  55. _context.Renderer.Pipeline.Draw(
  56. drawState.Count,
  57. 1,
  58. drawState.First,
  59. firstInstance);
  60. }
  61. }
  62. private void DrawBegin(GpuState state, int argument)
  63. {
  64. if ((argument & (1 << 26)) != 0)
  65. {
  66. _instanceIndex++;
  67. }
  68. else if ((argument & (1 << 27)) == 0)
  69. {
  70. PerformDeferredDraws();
  71. _instanceIndex = 0;
  72. }
  73. PrimitiveType type = (PrimitiveType)(argument & 0xffff);
  74. _context.Renderer.Pipeline.SetPrimitiveTopology(type.Convert());
  75. PrimitiveType = type;
  76. }
  77. private void SetIndexBufferCount(GpuState state, int argument)
  78. {
  79. _drawIndexed = true;
  80. }
  81. public void PerformDeferredDraws()
  82. {
  83. // Perform any pending instanced draw.
  84. if (_instancedDrawPending)
  85. {
  86. _instancedDrawPending = false;
  87. if (_instancedIndexed)
  88. {
  89. _context.Renderer.Pipeline.DrawIndexed(
  90. _instancedIndexCount,
  91. _instanceIndex + 1,
  92. _instancedFirstIndex,
  93. _instancedFirstVertex,
  94. _instancedFirstInstance);
  95. }
  96. else
  97. {
  98. _context.Renderer.Pipeline.Draw(
  99. _instancedDrawStateCount,
  100. _instanceIndex + 1,
  101. _instancedDrawStateFirst,
  102. _instancedFirstInstance);
  103. }
  104. }
  105. }
  106. }
  107. }