IndexBufferState.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. using Silk.NET.Vulkan;
  2. namespace Ryujinx.Graphics.Vulkan
  3. {
  4. internal struct IndexBufferState
  5. {
  6. public static IndexBufferState Null => new IndexBufferState(GAL.BufferHandle.Null, 0, 0);
  7. private readonly int _offset;
  8. private readonly int _size;
  9. private readonly IndexType _type;
  10. private readonly GAL.BufferHandle _handle;
  11. private Auto<DisposableBuffer> _buffer;
  12. public IndexBufferState(GAL.BufferHandle handle, int offset, int size, IndexType type)
  13. {
  14. _handle = handle;
  15. _offset = offset;
  16. _size = size;
  17. _type = type;
  18. _buffer = null;
  19. }
  20. public IndexBufferState(GAL.BufferHandle handle, int offset, int size)
  21. {
  22. _handle = handle;
  23. _offset = offset;
  24. _size = size;
  25. _type = IndexType.Uint16;
  26. _buffer = null;
  27. }
  28. public void BindIndexBuffer(VulkanRenderer gd, CommandBufferScoped cbs)
  29. {
  30. Auto<DisposableBuffer> autoBuffer;
  31. int offset, size;
  32. IndexType type = _type;
  33. if (_type == IndexType.Uint8Ext && !gd.Capabilities.SupportsIndexTypeUint8)
  34. {
  35. // Index type is not supported. Convert to I16.
  36. autoBuffer = gd.BufferManager.GetBufferI8ToI16(cbs, _handle, _offset, _size);
  37. type = IndexType.Uint16;
  38. offset = 0;
  39. size = _size * 2;
  40. }
  41. else
  42. {
  43. autoBuffer = gd.BufferManager.GetBuffer(cbs.CommandBuffer, _handle, false, out int bufferSize);
  44. if (_offset >= bufferSize)
  45. {
  46. autoBuffer = null;
  47. }
  48. offset = _offset;
  49. size = _size;
  50. }
  51. _buffer = autoBuffer;
  52. if (autoBuffer != null)
  53. {
  54. gd.Api.CmdBindIndexBuffer(cbs.CommandBuffer, autoBuffer.Get(cbs, offset, size).Value, (ulong)offset, type);
  55. }
  56. }
  57. public void BindConvertedIndexBuffer(
  58. VulkanRenderer gd,
  59. CommandBufferScoped cbs,
  60. int firstIndex,
  61. int indexCount,
  62. int convertedCount,
  63. IndexBufferPattern pattern)
  64. {
  65. Auto<DisposableBuffer> autoBuffer;
  66. // Convert the index buffer using the given pattern.
  67. int indexSize = GetIndexSize();
  68. int firstIndexOffset = firstIndex * indexSize;
  69. autoBuffer = gd.BufferManager.GetBufferTopologyConversion(cbs, _handle, _offset + firstIndexOffset, indexCount * indexSize, pattern, indexSize);
  70. int size = convertedCount * 4;
  71. _buffer = autoBuffer;
  72. if (autoBuffer != null)
  73. {
  74. gd.Api.CmdBindIndexBuffer(cbs.CommandBuffer, autoBuffer.Get(cbs, 0, size).Value, 0, IndexType.Uint32);
  75. }
  76. }
  77. public Auto<DisposableBuffer> BindConvertedIndexBufferIndirect(
  78. VulkanRenderer gd,
  79. CommandBufferScoped cbs,
  80. GAL.BufferRange indirectBuffer,
  81. GAL.BufferRange drawCountBuffer,
  82. IndexBufferPattern pattern,
  83. bool hasDrawCount,
  84. int maxDrawCount,
  85. int indirectDataStride)
  86. {
  87. // Convert the index buffer using the given pattern.
  88. int indexSize = GetIndexSize();
  89. (var indexBufferAuto, var indirectBufferAuto) = gd.BufferManager.GetBufferTopologyConversionIndirect(
  90. gd,
  91. cbs,
  92. new GAL.BufferRange(_handle, _offset, _size),
  93. indirectBuffer,
  94. drawCountBuffer,
  95. pattern,
  96. indexSize,
  97. hasDrawCount,
  98. maxDrawCount,
  99. indirectDataStride);
  100. int convertedCount = pattern.GetConvertedCount(_size / indexSize);
  101. int size = convertedCount * 4;
  102. _buffer = indexBufferAuto;
  103. if (indexBufferAuto != null)
  104. {
  105. gd.Api.CmdBindIndexBuffer(cbs.CommandBuffer, indexBufferAuto.Get(cbs, 0, size).Value, 0, IndexType.Uint32);
  106. }
  107. return indirectBufferAuto;
  108. }
  109. private int GetIndexSize()
  110. {
  111. return _type switch
  112. {
  113. IndexType.Uint32 => 4,
  114. IndexType.Uint16 => 2,
  115. _ => 1,
  116. };
  117. }
  118. public bool BoundEquals(Auto<DisposableBuffer> buffer)
  119. {
  120. return _buffer == buffer;
  121. }
  122. }
  123. }