OGLStreamBuffer.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. using System;
  2. using OpenTK.Graphics.OpenGL;
  3. namespace Ryujinx.Graphics.Gal.OpenGL
  4. {
  5. abstract class OGLStreamBuffer : IDisposable
  6. {
  7. public int Handle { get; protected set; }
  8. public int Size { get; protected set; }
  9. protected BufferTarget Target { get; private set; }
  10. private bool Mapped = false;
  11. public OGLStreamBuffer(BufferTarget Target, int MaxSize)
  12. {
  13. Handle = 0;
  14. Mapped = false;
  15. this.Target = Target;
  16. this.Size = MaxSize;
  17. }
  18. public static OGLStreamBuffer Create(BufferTarget Target, int MaxSize)
  19. {
  20. //TODO: Query here for ARB_buffer_storage and use when available
  21. return new SubDataBuffer(Target, MaxSize);
  22. }
  23. public byte[] Map(int Size)
  24. {
  25. if (Handle == 0 || Mapped || Size > this.Size)
  26. {
  27. throw new InvalidOperationException();
  28. }
  29. byte[] Memory = InternMap(Size);
  30. Mapped = true;
  31. return Memory;
  32. }
  33. public void Unmap(int UsedSize)
  34. {
  35. if (Handle == 0 || !Mapped)
  36. {
  37. throw new InvalidOperationException();
  38. }
  39. InternUnmap(UsedSize);
  40. Mapped = false;
  41. }
  42. protected abstract byte[] InternMap(int Size);
  43. protected abstract void InternUnmap(int UsedSize);
  44. public void Dispose()
  45. {
  46. Dispose(true);
  47. }
  48. protected virtual void Dispose(bool Disposing)
  49. {
  50. if (Disposing && Handle != 0)
  51. {
  52. GL.DeleteBuffer(Handle);
  53. Handle = 0;
  54. }
  55. }
  56. }
  57. class SubDataBuffer : OGLStreamBuffer
  58. {
  59. private byte[] Memory;
  60. public SubDataBuffer(BufferTarget Target, int MaxSize)
  61. : base(Target, MaxSize)
  62. {
  63. Memory = new byte[MaxSize];
  64. GL.GenBuffers(1, out int Handle);
  65. GL.BindBuffer(Target, Handle);
  66. GL.BufferData(Target, Size, IntPtr.Zero, BufferUsageHint.StreamDraw);
  67. this.Handle = Handle;
  68. }
  69. protected override byte[] InternMap(int Size)
  70. {
  71. return Memory;
  72. }
  73. protected override void InternUnmap(int UsedSize)
  74. {
  75. GL.BindBuffer(Target, Handle);
  76. unsafe
  77. {
  78. fixed (byte* MemoryPtr = Memory)
  79. {
  80. GL.BufferSubData(Target, IntPtr.Zero, UsedSize, (IntPtr)MemoryPtr);
  81. }
  82. }
  83. }
  84. }
  85. }