Framebuffer.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using OpenTK.Graphics.OpenGL;
  2. using Ryujinx.Graphics.GAL;
  3. using System;
  4. namespace Ryujinx.Graphics.OpenGL
  5. {
  6. class Framebuffer : IDisposable
  7. {
  8. public int Handle { get; private set; }
  9. private FramebufferAttachment _lastDsAttachment;
  10. private readonly TextureView[] _colors;
  11. public Framebuffer()
  12. {
  13. Handle = GL.GenFramebuffer();
  14. _colors = new TextureView[8];
  15. }
  16. public void Bind()
  17. {
  18. GL.BindFramebuffer(FramebufferTarget.Framebuffer, Handle);
  19. }
  20. public void AttachColor(int index, TextureView color)
  21. {
  22. FramebufferAttachment attachment = FramebufferAttachment.ColorAttachment0 + index;
  23. if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.Amd ||
  24. HwCapabilities.Vendor == HwCapabilities.GpuVendor.Intel)
  25. {
  26. GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.GetIncompatibleFormatViewHandle() ?? 0, 0);
  27. _colors[index] = color;
  28. }
  29. else
  30. {
  31. GL.FramebufferTexture(FramebufferTarget.Framebuffer, attachment, color?.Handle ?? 0, 0);
  32. }
  33. }
  34. public void AttachDepthStencil(TextureView depthStencil)
  35. {
  36. // Detach the last depth/stencil buffer if there is any.
  37. if (_lastDsAttachment != 0)
  38. {
  39. GL.FramebufferTexture(FramebufferTarget.Framebuffer, _lastDsAttachment, 0, 0);
  40. }
  41. if (depthStencil != null)
  42. {
  43. FramebufferAttachment attachment;
  44. if (IsPackedDepthStencilFormat(depthStencil.Format))
  45. {
  46. attachment = FramebufferAttachment.DepthStencilAttachment;
  47. }
  48. else if (IsDepthOnlyFormat(depthStencil.Format))
  49. {
  50. attachment = FramebufferAttachment.DepthAttachment;
  51. }
  52. else
  53. {
  54. attachment = FramebufferAttachment.StencilAttachment;
  55. }
  56. GL.FramebufferTexture(
  57. FramebufferTarget.Framebuffer,
  58. attachment,
  59. depthStencil.Handle,
  60. 0);
  61. _lastDsAttachment = attachment;
  62. }
  63. else
  64. {
  65. _lastDsAttachment = 0;
  66. }
  67. }
  68. public void SignalModified()
  69. {
  70. if (HwCapabilities.Vendor == HwCapabilities.GpuVendor.Amd ||
  71. HwCapabilities.Vendor == HwCapabilities.GpuVendor.Intel)
  72. {
  73. for (int i = 0; i < 8; i++)
  74. {
  75. if (_colors[i] != null)
  76. {
  77. _colors[i].SignalModified();
  78. }
  79. }
  80. }
  81. }
  82. public void SetDrawBuffers(int colorsCount)
  83. {
  84. DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[colorsCount];
  85. for (int index = 0; index < colorsCount; index++)
  86. {
  87. drawBuffers[index] = DrawBuffersEnum.ColorAttachment0 + index;
  88. }
  89. GL.DrawBuffers(colorsCount, drawBuffers);
  90. }
  91. private static bool IsPackedDepthStencilFormat(Format format)
  92. {
  93. return format == Format.D24UnormS8Uint ||
  94. format == Format.D32FloatS8Uint;
  95. }
  96. private static bool IsDepthOnlyFormat(Format format)
  97. {
  98. return format == Format.D16Unorm ||
  99. format == Format.D24X8Unorm ||
  100. format == Format.D32Float;
  101. }
  102. public void Dispose()
  103. {
  104. if (Handle != 0)
  105. {
  106. GL.DeleteFramebuffer(Handle);
  107. Handle = 0;
  108. }
  109. }
  110. }
  111. }