aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gal/OpenGL/OGLStreamBuffer.cs
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2018-06-26 02:10:54 -0300
committergdkchan <gab.dark.100@gmail.com>2018-06-26 02:10:54 -0300
commit09dfefed1f84585e2b305cd16482f899b93fe629 (patch)
tree2e24e24f969376056228e8679020f459f4f68dc1 /Ryujinx.Graphics/Gal/OpenGL/OGLStreamBuffer.cs
parentb8be89ab2dad2e2ba5145f64425fa49526f81596 (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.cs113
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