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 }