diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2018-06-26 02:10:54 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-06-26 02:10:54 -0300 |
| commit | 09dfefed1f84585e2b305cd16482f899b93fe629 (patch) | |
| tree | 2e24e24f969376056228e8679020f459f4f68dc1 /Ryujinx.Graphics/Gal/OpenGL/OGLStreamBuffer.cs | |
| parent | b8be89ab2dad2e2ba5145f64425fa49526f81596 (diff) | |
Implementation of UBOs instead of uniform constant arrays (#186)
* Sort uniform binding to avoid possible failures in drivers fewer bindings
* Throw exception for Cbuf overflow
* Search for free bindings instead of using locked ones
* EnsureAllocated when binding buffers
* Fix uniform bindings
* Remove spaces
* Use 64 KiB UBOs when available
* Remove double colon
* Use IdentationStr and avoid division in Cbuf offset
* Add spaces
Diffstat (limited to 'Ryujinx.Graphics/Gal/OpenGL/OGLStreamBuffer.cs')
| -rw-r--r-- | Ryujinx.Graphics/Gal/OpenGL/OGLStreamBuffer.cs | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLStreamBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLStreamBuffer.cs new file mode 100644 index 00000000..3d91b09f --- /dev/null +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLStreamBuffer.cs @@ -0,0 +1,113 @@ +using System; +using OpenTK.Graphics.OpenGL; + +namespace Ryujinx.Graphics.Gal.OpenGL +{ + abstract class OGLStreamBuffer : IDisposable + { + public int Handle { get; protected set; } + + public int Size { get; protected set; } + + protected BufferTarget Target { get; private set; } + + private bool Mapped = false; + + public OGLStreamBuffer(BufferTarget Target, int MaxSize) + { + Handle = 0; + Mapped = false; + + this.Target = Target; + this.Size = MaxSize; + } + + public static OGLStreamBuffer Create(BufferTarget Target, int MaxSize) + { + //TODO: Query here for ARB_buffer_storage and use when available + return new SubDataBuffer(Target, MaxSize); + } + + public byte[] Map(int Size) + { + if (Handle == 0 || Mapped || Size > this.Size) + { + throw new InvalidOperationException(); + } + + byte[] Memory = InternMap(Size); + + Mapped = true; + + return Memory; + } + + public void Unmap(int UsedSize) + { + if (Handle == 0 || !Mapped) + { + throw new InvalidOperationException(); + } + + InternUnmap(UsedSize); + + Mapped = false; + } + + protected abstract byte[] InternMap(int Size); + + protected abstract void InternUnmap(int UsedSize); + + public void Dispose() + { + Dispose(true); + } + + protected virtual void Dispose(bool Disposing) + { + if (Disposing && Handle != 0) + { + GL.DeleteBuffer(Handle); + + Handle = 0; + } + } + } + + class SubDataBuffer : OGLStreamBuffer + { + private byte[] Memory; + + public SubDataBuffer(BufferTarget Target, int MaxSize) + : base(Target, MaxSize) + { + Memory = new byte[MaxSize]; + + GL.CreateBuffers(1, out int Handle); + + GL.BindBuffer(Target, Handle); + + GL.BufferData(Target, Size, IntPtr.Zero, BufferUsageHint.StreamDraw); + + this.Handle = Handle; + } + + protected override byte[] InternMap(int Size) + { + return Memory; + } + + protected override void InternUnmap(int UsedSize) + { + GL.BindBuffer(Target, Handle); + + unsafe + { + fixed (byte* MemoryPtr = Memory) + { + GL.BufferSubData(Target, IntPtr.Zero, UsedSize, (IntPtr)MemoryPtr); + } + } + } + } +}
\ No newline at end of file |
