| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- using Ryujinx.Graphics.GAL;
- using System;
- using System.Collections.Generic;
- using System.Runtime.InteropServices;
- namespace Ryujinx.Graphics.Vulkan
- {
- internal class IndexBufferPattern : IDisposable
- {
- public int PrimitiveVertices { get; }
- public int PrimitiveVerticesOut { get; }
- public int BaseIndex { get; }
- public int[] OffsetIndex { get; }
- public int IndexStride { get; }
- public bool RepeatStart { get; }
- private VulkanRenderer _gd;
- private int _currentSize;
- private BufferHandle _repeatingBuffer;
- public IndexBufferPattern(VulkanRenderer gd,
- int primitiveVertices,
- int primitiveVerticesOut,
- int baseIndex,
- int[] offsetIndex,
- int indexStride,
- bool repeatStart)
- {
- PrimitiveVertices = primitiveVertices;
- PrimitiveVerticesOut = primitiveVerticesOut;
- BaseIndex = baseIndex;
- OffsetIndex = offsetIndex;
- IndexStride = indexStride;
- RepeatStart = repeatStart;
- _gd = gd;
- }
- public int GetPrimitiveCount(int vertexCount)
- {
- return Math.Max(0, ((vertexCount - BaseIndex) + IndexStride - 1) / IndexStride);
- }
- public int GetConvertedCount(int indexCount)
- {
- int primitiveCount = GetPrimitiveCount(indexCount);
- return primitiveCount * OffsetIndex.Length;
- }
- public IEnumerable<int> GetIndexMapping(int indexCount)
- {
- int primitiveCount = GetPrimitiveCount(indexCount);
- int index = BaseIndex;
- for (int i = 0; i < primitiveCount; i++)
- {
- if (RepeatStart)
- {
- // Used for triangle fan
- yield return 0;
- }
- for (int j = RepeatStart ? 1 : 0; j < OffsetIndex.Length; j++)
- {
- yield return index + OffsetIndex[j];
- }
- index += IndexStride;
- }
- }
- public BufferHandle GetRepeatingBuffer(int vertexCount, out int indexCount)
- {
- int primitiveCount = GetPrimitiveCount(vertexCount);
- indexCount = primitiveCount * PrimitiveVerticesOut;
- int expectedSize = primitiveCount * OffsetIndex.Length;
- if (expectedSize <= _currentSize && _repeatingBuffer != BufferHandle.Null)
- {
- return _repeatingBuffer;
- }
- // Expand the repeating pattern to the number of requested primitives.
- BufferHandle newBuffer = _gd.CreateBuffer(expectedSize * sizeof(int));
- // Copy the old data to the new one.
- if (_repeatingBuffer != BufferHandle.Null)
- {
- _gd.Pipeline.CopyBuffer(_repeatingBuffer, newBuffer, 0, 0, _currentSize * sizeof(int));
- _gd.DeleteBuffer(_repeatingBuffer);
- }
- _repeatingBuffer = newBuffer;
- // Add the additional repeats on top.
- int newPrimitives = primitiveCount;
- int oldPrimitives = (_currentSize) / OffsetIndex.Length;
- int[] newData;
- newPrimitives -= oldPrimitives;
- newData = new int[expectedSize - _currentSize];
- int outOffset = 0;
- int index = oldPrimitives * IndexStride + BaseIndex;
- for (int i = 0; i < newPrimitives; i++)
- {
- if (RepeatStart)
- {
- // Used for triangle fan
- newData[outOffset++] = 0;
- }
- for (int j = RepeatStart ? 1 : 0; j < OffsetIndex.Length; j++)
- {
- newData[outOffset++] = index + OffsetIndex[j];
- }
- index += IndexStride;
- }
- _gd.SetBufferData(newBuffer, _currentSize * sizeof(int), MemoryMarshal.Cast<int, byte>(newData));
- _currentSize = expectedSize;
- return newBuffer;
- }
- public void Dispose()
- {
- if (_repeatingBuffer != BufferHandle.Null)
- {
- _gd.DeleteBuffer(_repeatingBuffer);
- _repeatingBuffer = BufferHandle.Null;
- }
- }
- }
- }
|