diff options
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Framebuffer.cs')
-rw-r--r-- | Ryujinx.Graphics.OpenGL/Framebuffer.cs | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Framebuffer.cs b/Ryujinx.Graphics.OpenGL/Framebuffer.cs new file mode 100644 index 00000000..40913009 --- /dev/null +++ b/Ryujinx.Graphics.OpenGL/Framebuffer.cs @@ -0,0 +1,116 @@ +using OpenTK.Graphics.OpenGL; +using Ryujinx.Graphics.GAL; +using System; + +namespace Ryujinx.Graphics.OpenGL +{ + class Framebuffer : IDisposable + { + public int Handle { get; private set; } + + private FramebufferAttachment _lastDsAttachment; + + public Framebuffer() + { + Handle = GL.GenFramebuffer(); + } + + public void Bind() + { + GL.BindFramebuffer(FramebufferTarget.Framebuffer, Handle); + } + + public void AttachColor(int index, TextureView color) + { + GL.FramebufferTexture( + FramebufferTarget.Framebuffer, + FramebufferAttachment.ColorAttachment0 + index, + color?.Handle ?? 0, + 0); + } + + public void AttachColor(int index, TextureView color, int layer) + { + GL.FramebufferTextureLayer( + FramebufferTarget.Framebuffer, + FramebufferAttachment.ColorAttachment0 + index, + color?.Handle ?? 0, + 0, + layer); + } + + public void AttachDepthStencil(TextureView depthStencil) + { + // Detach the last depth/stencil buffer if there is any. + if (_lastDsAttachment != 0) + { + GL.FramebufferTexture(FramebufferTarget.Framebuffer, _lastDsAttachment, 0, 0); + } + + if (depthStencil != null) + { + FramebufferAttachment attachment; + + if (IsPackedDepthStencilFormat(depthStencil.Format)) + { + attachment = FramebufferAttachment.DepthStencilAttachment; + } + else if (IsDepthOnlyFormat(depthStencil.Format)) + { + attachment = FramebufferAttachment.DepthAttachment; + } + else + { + attachment = FramebufferAttachment.StencilAttachment; + } + + GL.FramebufferTexture( + FramebufferTarget.Framebuffer, + attachment, + depthStencil.Handle, + 0); + + _lastDsAttachment = attachment; + } + else + { + _lastDsAttachment = 0; + } + } + + public void SetDrawBuffers(int colorsCount) + { + DrawBuffersEnum[] drawBuffers = new DrawBuffersEnum[colorsCount]; + + for (int index = 0; index < colorsCount; index++) + { + drawBuffers[index] = DrawBuffersEnum.ColorAttachment0 + index; + } + + GL.DrawBuffers(colorsCount, drawBuffers); + } + + private static bool IsPackedDepthStencilFormat(Format format) + { + return format == Format.D24UnormS8Uint || + format == Format.D32FloatS8Uint; + } + + private static bool IsDepthOnlyFormat(Format format) + { + return format == Format.D16Unorm || + format == Format.D24X8Unorm || + format == Format.D32Float; + } + + public void Dispose() + { + if (Handle != 0) + { + GL.DeleteFramebuffer(Handle); + + Handle = 0; + } + } + } +} |