diff options
author | gdkchan <gab.dark.100@gmail.com> | 2023-08-29 21:10:34 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-29 21:10:34 -0300 |
commit | f09bba82b9366e5912b639a610ae89cbb1cf352c (patch) | |
tree | 4811ffa52206eed7cf8aa200c64deb7410e5c56b /src/Ryujinx.Graphics.Gpu/Memory/BufferUpdater.cs | |
parent | 93d78f9ac4a37a50f0cc2e57addd330d072af742 (diff) |
Geometry shader emulation for macOS (#5551)1.1.1002
* Implement vertex and geometry shader conversion to compute
* Call InitializeReservedCounts for compute too
* PR feedback
* Set clip distance mask for geometry and tessellation shaders too
* Transform feedback emulation only for vertex
Diffstat (limited to 'src/Ryujinx.Graphics.Gpu/Memory/BufferUpdater.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Gpu/Memory/BufferUpdater.cs | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferUpdater.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferUpdater.cs new file mode 100644 index 00000000..02090c04 --- /dev/null +++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferUpdater.cs @@ -0,0 +1,123 @@ +using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.Shader; +using System; + +namespace Ryujinx.Graphics.Gpu.Memory +{ + /// <summary> + /// Buffer data updater. + /// </summary> + class BufferUpdater : IDisposable + { + private BufferHandle _handle; + + /// <summary> + /// Handle of the buffer. + /// </summary> + public BufferHandle Handle => _handle; + + private readonly IRenderer _renderer; + private int _startOffset = -1; + private int _endOffset = -1; + + /// <summary> + /// Creates a new instance of the buffer updater. + /// </summary> + /// <param name="renderer">Renderer that the buffer will be used with</param> + public BufferUpdater(IRenderer renderer) + { + _renderer = renderer; + } + + /// <summary> + /// Mark a region of the buffer as modified and needing to be sent to the GPU. + /// </summary> + /// <param name="startOffset">Start offset of the region in bytes</param> + /// <param name="byteSize">Size of the region in bytes</param> + protected void MarkDirty(int startOffset, int byteSize) + { + int endOffset = startOffset + byteSize; + + if (_startOffset == -1) + { + _startOffset = startOffset; + _endOffset = endOffset; + } + else + { + if (startOffset < _startOffset) + { + _startOffset = startOffset; + } + + if (endOffset > _endOffset) + { + _endOffset = endOffset; + } + } + } + + /// <summary> + /// Submits all pending buffer updates to the GPU. + /// </summary> + /// <param name="data">All data that should be sent to the GPU. Only the modified regions will be updated</param> + /// <param name="binding">Optional binding to bind the buffer if a new buffer was created</param> + protected void Commit(ReadOnlySpan<byte> data, int binding = -1) + { + if (_startOffset != -1) + { + if (_handle == BufferHandle.Null) + { + _handle = _renderer.CreateBuffer(data.Length, BufferAccess.Stream); + _renderer.Pipeline.ClearBuffer(_handle, 0, data.Length, 0); + + if (binding >= 0) + { + var range = new BufferRange(_handle, 0, data.Length); + _renderer.Pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, range) }); + } + }; + + _renderer.SetBufferData(_handle, _startOffset, data[_startOffset.._endOffset]); + + _startOffset = -1; + _endOffset = -1; + } + } + + /// <summary> + /// Gets a reference to a given element of a vector. + /// </summary> + /// <param name="vector">Vector to get the element reference from</param> + /// <param name="elementIndex">Element index</param> + /// <returns>Reference to the specified element</returns> + protected static ref T GetElementRef<T>(ref Vector4<T> vector, int elementIndex) + { + switch (elementIndex) + { + case 0: + return ref vector.X; + case 1: + return ref vector.Y; + case 2: + return ref vector.Z; + case 3: + return ref vector.W; + default: + throw new ArgumentOutOfRangeException(nameof(elementIndex)); + } + } + + /// <summary> + /// Destroys the buffer. + /// </summary> + public void Dispose() + { + if (_handle != BufferHandle.Null) + { + _renderer.DeleteBuffer(_handle); + _handle = BufferHandle.Null; + } + } + } +} |