MethodDraw.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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. if (_instancedDrawPending)
  23. {
  24. _drawIndexed = false;
  25. return;
  26. }
  27. UpdateState(state);
  28. bool instanced = _vsUsesInstanceId || _isAnyVbInstanced;
  29. if (instanced)
  30. {
  31. _instancedDrawPending = true;
  32. _instancedIndexed = _drawIndexed;
  33. _instancedFirstIndex = _firstIndex;
  34. _instancedFirstVertex = state.Get<int>(MethodOffset.FirstVertex);
  35. _instancedFirstInstance = state.Get<int>(MethodOffset.FirstInstance);
  36. _instancedIndexCount = _indexCount;
  37. var drawState = state.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
  38. _instancedDrawStateFirst = drawState.First;
  39. _instancedDrawStateCount = drawState.Count;
  40. _drawIndexed = false;
  41. return;
  42. }
  43. int firstInstance = state.Get<int>(MethodOffset.FirstInstance);
  44. if (_drawIndexed)
  45. {
  46. _drawIndexed = false;
  47. int firstVertex = state.Get<int>(MethodOffset.FirstVertex);
  48. _context.Renderer.Pipeline.DrawIndexed(
  49. _indexCount,
  50. 1,
  51. _firstIndex,
  52. firstVertex,
  53. firstInstance);
  54. }
  55. else
  56. {
  57. var drawState = state.Get<VertexBufferDrawState>(MethodOffset.VertexBufferDrawState);
  58. _context.Renderer.Pipeline.Draw(
  59. drawState.Count,
  60. 1,
  61. drawState.First,
  62. firstInstance);
  63. }
  64. }
  65. private void DrawBegin(GpuState state, int argument)
  66. {
  67. if ((argument & (1 << 26)) != 0)
  68. {
  69. _instanceIndex++;
  70. }
  71. else if ((argument & (1 << 27)) == 0)
  72. {
  73. PerformDeferredDraws();
  74. _instanceIndex = 0;
  75. }
  76. PrimitiveType type = (PrimitiveType)(argument & 0xffff);
  77. _context.Renderer.Pipeline.SetPrimitiveTopology(type.Convert());
  78. PrimitiveType = type;
  79. }
  80. private void SetIndexBufferCount(GpuState state, int argument)
  81. {
  82. _drawIndexed = true;
  83. }
  84. public void PerformDeferredDraws()
  85. {
  86. // Perform any pending instanced draw.
  87. if (_instancedDrawPending)
  88. {
  89. _instancedDrawPending = false;
  90. if (_instancedIndexed)
  91. {
  92. _context.Renderer.Pipeline.DrawIndexed(
  93. _instancedIndexCount,
  94. _instanceIndex + 1,
  95. _instancedFirstIndex,
  96. _instancedFirstVertex,
  97. _instancedFirstInstance);
  98. }
  99. else
  100. {
  101. _context.Renderer.Pipeline.Draw(
  102. _instancedDrawStateCount,
  103. _instanceIndex + 1,
  104. _instancedDrawStateFirst,
  105. _instancedFirstInstance);
  106. }
  107. }
  108. }
  109. }
  110. }