Buffer.cs
  1  using OpenTK.Graphics.OpenGL;
  2  using Ryujinx.Graphics.GAL;
  3  using System;
  4  
  5  namespace Ryujinx.Graphics.OpenGL
  6  {
  7      static class Buffer
  8      {
  9          public static void Clear(BufferHandle destination, int offset, int size, uint value)
 10          {
 11              GL.BindBuffer(BufferTarget.CopyWriteBuffer, destination.ToInt32());
 12  
 13              unsafe
 14              {
 15                  uint* valueArr = stackalloc uint[1];
 16  
 17                  valueArr[0] = value;
 18  
 19                  GL.ClearBufferSubData(
 20                      BufferTarget.CopyWriteBuffer,
 21                      PixelInternalFormat.Rgba8ui,
 22                      (IntPtr)offset,
 23                      (IntPtr)size,
 24                      PixelFormat.RgbaInteger,
 25                      PixelType.UnsignedByte,
 26                      (IntPtr)valueArr);
 27              }
 28          }
 29  
 30          public static BufferHandle Create()
 31          {
 32              return Handle.FromInt32<BufferHandle>(GL.GenBuffer());
 33          }
 34  
 35          public static BufferHandle Create(int size)
 36          {
 37              int handle = GL.GenBuffer();
 38  
 39              GL.BindBuffer(BufferTarget.CopyWriteBuffer, handle);
 40              GL.BufferData(BufferTarget.CopyWriteBuffer, size, IntPtr.Zero, BufferUsageHint.DynamicDraw);
 41  
 42              return Handle.FromInt32<BufferHandle>(handle);
 43          }
 44  
 45          public static BufferHandle CreatePersistent(int size)
 46          {
 47              int handle = GL.GenBuffer();
 48  
 49              GL.BindBuffer(BufferTarget.CopyWriteBuffer, handle);
 50              GL.BufferStorage(BufferTarget.CopyWriteBuffer, size, IntPtr.Zero,
 51                  BufferStorageFlags.MapPersistentBit |
 52                  BufferStorageFlags.MapCoherentBit |
 53                  BufferStorageFlags.ClientStorageBit |
 54                  BufferStorageFlags.MapReadBit);
 55  
 56              return Handle.FromInt32<BufferHandle>(handle);
 57          }
 58  
 59          public static void Copy(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
 60          {
 61              GL.BindBuffer(BufferTarget.CopyReadBuffer, source.ToInt32());
 62              GL.BindBuffer(BufferTarget.CopyWriteBuffer, destination.ToInt32());
 63  
 64              GL.CopyBufferSubData(
 65                  BufferTarget.CopyReadBuffer,
 66                  BufferTarget.CopyWriteBuffer,
 67                  (IntPtr)srcOffset,
 68                  (IntPtr)dstOffset,
 69                  (IntPtr)size);
 70          }
 71  
 72          public static unsafe PinnedSpan<byte> GetData(OpenGLRenderer renderer, BufferHandle buffer, int offset, int size)
 73          {
 74              // Data in the persistent buffer and host array is guaranteed to be available
 75              // until the next time the host thread requests data.
 76  
 77              if (renderer.PersistentBuffers.TryGet(buffer, out IntPtr ptr))
 78              {
 79                  return new PinnedSpan<byte>(IntPtr.Add(ptr, offset).ToPointer(), size);
 80              }
 81              else if (HwCapabilities.UsePersistentBufferForFlush)
 82              {
 83                  return PinnedSpan<byte>.UnsafeFromSpan(renderer.PersistentBuffers.Default.GetBufferData(buffer, offset, size));
 84              }
 85              else
 86              {
 87                  IntPtr target = renderer.PersistentBuffers.Default.GetHostArray(size);
 88  
 89                  GL.BindBuffer(BufferTarget.CopyReadBuffer, buffer.ToInt32());
 90  
 91                  GL.GetBufferSubData(BufferTarget.CopyReadBuffer, (IntPtr)offset, size, target);
 92  
 93                  return new PinnedSpan<byte>(target.ToPointer(), size);
 94              }
 95          }
 96  
 97          public static void Resize(BufferHandle handle, int size)
 98          {
 99              GL.BindBuffer(BufferTarget.CopyWriteBuffer, handle.ToInt32());
100              GL.BufferData(BufferTarget.CopyWriteBuffer, size, IntPtr.Zero, BufferUsageHint.StreamCopy);
101          }
102  
103          public static void SetData(BufferHandle buffer, int offset, ReadOnlySpan<byte> data)
104          {
105              GL.BindBuffer(BufferTarget.CopyWriteBuffer, buffer.ToInt32());
106  
107              unsafe
108              {
109                  fixed (byte* ptr = data)
110                  {
111                      GL.BufferSubData(BufferTarget.CopyWriteBuffer, (IntPtr)offset, data.Length, (IntPtr)ptr);
112                  }
113              }
114          }
115  
116          public static void Delete(BufferHandle buffer)
117          {
118              GL.DeleteBuffer(buffer.ToInt32());
119          }
120      }
121  }