Buffer.cs 4.1 KB

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