| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- using Ryujinx.Common;
- using Ryujinx.Graphics.GAL;
- using System;
- using System.Runtime.InteropServices;
- namespace Ryujinx.Graphics.Gpu.Engine
- {
- /// <summary>
- /// Holds inline index buffer state.
- /// The inline index buffer data is sent to the GPU through the command buffer.
- /// </summary>
- struct IbStreamer
- {
- private BufferHandle _inlineIndexBuffer;
- private int _inlineIndexBufferSize;
- private int _inlineIndexCount;
- public bool HasInlineIndexData => _inlineIndexCount != 0;
- /// <summary>
- /// Gets the handle for the host buffer currently holding the inline index buffer data.
- /// </summary>
- /// <returns>Host buffer handle</returns>
- public BufferHandle GetInlineIndexBuffer()
- {
- return _inlineIndexBuffer;
- }
- /// <summary>
- /// Gets the number of elements on the current inline index buffer,
- /// while also reseting it to zero for the next draw.
- /// </summary>
- /// <returns>Inline index bufffer count</returns>
- public int GetAndResetInlineIndexCount()
- {
- int temp = _inlineIndexCount;
- _inlineIndexCount = 0;
- return temp;
- }
- /// <summary>
- /// Pushes four 8-bit index buffer elements.
- /// </summary>
- /// <param name="renderer">Host renderer</param>
- /// <param name="argument">Method call argument</param>
- public void VbElementU8(IRenderer renderer, int argument)
- {
- byte i0 = (byte)argument;
- byte i1 = (byte)(argument >> 8);
- byte i2 = (byte)(argument >> 16);
- byte i3 = (byte)(argument >> 24);
- Span<uint> data = stackalloc uint[4];
- data[0] = i0;
- data[1] = i1;
- data[2] = i2;
- data[3] = i3;
- int offset = _inlineIndexCount * 4;
- renderer.SetBufferData(GetInlineIndexBuffer(renderer, offset), offset, MemoryMarshal.Cast<uint, byte>(data));
- _inlineIndexCount += 4;
- }
- /// <summary>
- /// Pushes two 16-bit index buffer elements.
- /// </summary>
- /// <param name="renderer">Host renderer</param>
- /// <param name="argument">Method call argument</param>
- public void VbElementU16(IRenderer renderer, int argument)
- {
- ushort i0 = (ushort)argument;
- ushort i1 = (ushort)(argument >> 16);
- Span<uint> data = stackalloc uint[2];
- data[0] = i0;
- data[1] = i1;
- int offset = _inlineIndexCount * 4;
- renderer.SetBufferData(GetInlineIndexBuffer(renderer, offset), offset, MemoryMarshal.Cast<uint, byte>(data));
- _inlineIndexCount += 2;
- }
- /// <summary>
- /// Pushes one 32-bit index buffer element.
- /// </summary>
- /// <param name="renderer">Host renderer</param>
- /// <param name="argument">Method call argument</param>
- public void VbElementU32(IRenderer renderer, int argument)
- {
- uint i0 = (uint)argument;
- Span<uint> data = stackalloc uint[1];
- data[0] = i0;
- int offset = _inlineIndexCount++ * 4;
- renderer.SetBufferData(GetInlineIndexBuffer(renderer, offset), offset, MemoryMarshal.Cast<uint, byte>(data));
- }
- /// <summary>
- /// Gets the handle of a buffer large enough to hold the data that will be written to <paramref name="offset"/>.
- /// </summary>
- /// <param name="renderer">Host renderer</param>
- /// <param name="offset">Offset where the data will be written</param>
- /// <returns>Buffer handle</returns>
- private BufferHandle GetInlineIndexBuffer(IRenderer renderer, int offset)
- {
- // Calculate a reasonable size for the buffer that can fit all the data,
- // and that also won't require frequent resizes if we need to push more data.
- int size = BitUtils.AlignUp(offset + 0x10, 0x200);
- if (_inlineIndexBuffer == BufferHandle.Null)
- {
- _inlineIndexBuffer = renderer.CreateBuffer(size);
- _inlineIndexBufferSize = size;
- }
- else if (_inlineIndexBufferSize < size)
- {
- BufferHandle oldBuffer = _inlineIndexBuffer;
- int oldSize = _inlineIndexBufferSize;
- _inlineIndexBuffer = renderer.CreateBuffer(size);
- _inlineIndexBufferSize = size;
- renderer.Pipeline.CopyBuffer(oldBuffer, _inlineIndexBuffer, 0, 0, oldSize);
- renderer.DeleteBuffer(oldBuffer);
- }
- return _inlineIndexBuffer;
- }
- }
- }
|