From 1876b346fea647e8284a66bb6d62c38801035cff Mon Sep 17 00:00:00 2001
From: gdk <gab.dark.100@gmail.com>
Date: Sun, 13 Oct 2019 03:02:07 -0300
Subject: Initial work

---
 Ryujinx.Graphics.OpenGL/Framebuffer.cs | 116 +++++++++++++++++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 Ryujinx.Graphics.OpenGL/Framebuffer.cs

(limited to 'Ryujinx.Graphics.OpenGL/Framebuffer.cs')

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;
+            }
+        }
+    }
+}
-- 
cgit v1.2.3-70-g09d2