diff options
author | gdk <gab.dark.100@gmail.com> | 2019-10-13 03:02:07 -0300 |
---|---|---|
committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
commit | 1876b346fea647e8284a66bb6d62c38801035cff (patch) | |
tree | 6eeff094298cda84d1613dc5ec0691e51d7b35f1 /Ryujinx.Graphics.OpenGL/TextureCopy.cs | |
parent | f617fb542a0e3d36012d77a4b5acbde7b08902f2 (diff) |
Initial work
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/TextureCopy.cs')
-rw-r--r-- | Ryujinx.Graphics.OpenGL/TextureCopy.cs | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.OpenGL/TextureCopy.cs b/Ryujinx.Graphics.OpenGL/TextureCopy.cs new file mode 100644 index 00000000..75ef07c1 --- /dev/null +++ b/Ryujinx.Graphics.OpenGL/TextureCopy.cs @@ -0,0 +1,128 @@ +using Ryujinx.Graphics.GAL; +using OpenTK.Graphics.OpenGL; + +namespace Ryujinx.Graphics.OpenGL +{ + class TextureCopy + { + private int _srcFramebuffer; + private int _dstFramebuffer; + + public void Copy( + TextureView src, + TextureView dst, + Extents2D srcRegion, + Extents2D dstRegion, + bool linearFilter) + { + GL.Disable(EnableCap.FramebufferSrgb); + + int oldReadFramebufferHandle = GL.GetInteger(GetPName.ReadFramebufferBinding); + int oldDrawFramebufferHandle = GL.GetInteger(GetPName.DrawFramebufferBinding); + + GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, GetSrcFramebufferLazy()); + GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, GetDstFramebufferLazy()); + + Attach(FramebufferTarget.ReadFramebuffer, src.Format, src.Handle); + Attach(FramebufferTarget.DrawFramebuffer, dst.Format, dst.Handle); + + ClearBufferMask mask = GetMask(src.Format); + + BlitFramebufferFilter filter = linearFilter + ? BlitFramebufferFilter.Linear + : BlitFramebufferFilter.Nearest; + + GL.ReadBuffer(ReadBufferMode.ColorAttachment0); + GL.DrawBuffer(DrawBufferMode.ColorAttachment0); + + GL.BlitFramebuffer( + srcRegion.X1, + srcRegion.Y1, + srcRegion.X2, + srcRegion.Y2, + dstRegion.X1, + dstRegion.Y1, + dstRegion.X2, + dstRegion.Y2, + mask, + filter); + + GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); + GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); + + GL.Enable(EnableCap.FramebufferSrgb); + } + + private static void Detach(FramebufferTarget target, Format format) + { + Attach(target, format, 0); + } + + private static void Attach(FramebufferTarget target, Format format, int handle) + { + if (format == Format.D24UnormS8Uint || format == Format.D32FloatS8Uint) + { + GL.FramebufferTexture(target, FramebufferAttachment.DepthStencilAttachment, handle, 0); + } + else if (IsDepthOnly(format)) + { + GL.FramebufferTexture(target, FramebufferAttachment.DepthAttachment, handle, 0); + } + else if (format == Format.S8Uint) + { + GL.FramebufferTexture(target, FramebufferAttachment.StencilAttachment, handle, 0); + } + else + { + GL.FramebufferTexture(target, FramebufferAttachment.ColorAttachment0, handle, 0); + } + } + + private static ClearBufferMask GetMask(Format format) + { + if (format == Format.D24UnormS8Uint || format == Format.D32FloatS8Uint) + { + return ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit; + } + else if (IsDepthOnly(format)) + { + return ClearBufferMask.DepthBufferBit; + } + else if (format == Format.S8Uint) + { + return ClearBufferMask.StencilBufferBit; + } + else + { + return ClearBufferMask.ColorBufferBit; + } + } + + private static bool IsDepthOnly(Format format) + { + return format == Format.D16Unorm || + format == Format.D24X8Unorm || + format == Format.D32Float; + } + + private int GetSrcFramebufferLazy() + { + if (_srcFramebuffer == 0) + { + _srcFramebuffer = GL.GenFramebuffer(); + } + + return _srcFramebuffer; + } + + private int GetDstFramebufferLazy() + { + if (_dstFramebuffer == 0) + { + _dstFramebuffer = GL.GenFramebuffer(); + } + + return _dstFramebuffer; + } + } +} |