diff options
author | gdkchan <gab.dark.100@gmail.com> | 2020-07-26 00:03:40 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-26 00:03:40 -0300 |
commit | 8dbcae1ff88927dc0734d5f0e24fbf8781d68590 (patch) | |
tree | d884544af874f385a7a374c8889683db2e4c1ccc /Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs | |
parent | 2678bf0010166e683364102221b52caebea8747e (diff) |
Implement BGRA texture support (#1418)
* Implement BGRA texture support
* Missing AppendLine
* Remove empty lines
* Address PR feedback
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs')
-rw-r--r-- | Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs b/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs index e89d5614..edfbec5f 100644 --- a/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs +++ b/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs @@ -11,6 +11,9 @@ namespace Ryujinx.Graphics.OpenGL.Image private int _srcFramebuffer; private int _dstFramebuffer; + private int _copyPboHandle; + private int _copyPboSize; + public TextureCopy(Renderer renderer) { _renderer = renderer; @@ -23,12 +26,14 @@ namespace Ryujinx.Graphics.OpenGL.Image Extents2D dstRegion, bool linearFilter) { + TextureView srcConverted = src.Format.IsBgra8() != dst.Format.IsBgra8() ? BgraSwap(src) : src; + (int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers(); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, GetSrcFramebufferLazy()); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, GetDstFramebufferLazy()); - Attach(FramebufferTarget.ReadFramebuffer, src.Format, src.Handle); + Attach(FramebufferTarget.ReadFramebuffer, src.Format, srcConverted.Handle); Attach(FramebufferTarget.DrawFramebuffer, dst.Format, dst.Handle); ClearBufferMask mask = GetMask(src.Format); @@ -68,6 +73,11 @@ namespace Ryujinx.Graphics.OpenGL.Image ((Pipeline)_renderer.Pipeline).RestoreScissor0Enable(); ((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard(); + + if (srcConverted != src) + { + srcConverted.Dispose(); + } } private static void Attach(FramebufferTarget target, Format format, int handle) @@ -117,6 +127,52 @@ namespace Ryujinx.Graphics.OpenGL.Image format == Format.D32Float; } + public TextureView BgraSwap(TextureView from) + { + TextureView to = (TextureView)_renderer.CreateTexture(from.Info, 1f); + + EnsurePbo(from); + + GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyPboHandle); + + from.WriteToPbo(0, forceBgra: true); + + GL.BindBuffer(BufferTarget.PixelPackBuffer, 0); + GL.BindBuffer(BufferTarget.PixelUnpackBuffer, _copyPboHandle); + + to.ReadFromPbo(0, _copyPboSize); + + GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); + + return to; + } + + private void EnsurePbo(TextureView view) + { + int requiredSize = 0; + + for (int level = 0; level < view.Info.Levels; level++) + { + requiredSize += view.Info.GetMipSize(level); + } + + if (_copyPboSize < requiredSize && _copyPboHandle != 0) + { + GL.DeleteBuffer(_copyPboHandle); + + _copyPboHandle = 0; + } + + if (_copyPboHandle == 0) + { + _copyPboHandle = GL.GenBuffer(); + _copyPboSize = requiredSize; + + GL.BindBuffer(BufferTarget.PixelPackBuffer, _copyPboHandle); + GL.BufferData(BufferTarget.PixelPackBuffer, requiredSize, IntPtr.Zero, BufferUsageHint.DynamicCopy); + } + } + private int GetSrcFramebufferLazy() { if (_srcFramebuffer == 0) @@ -152,6 +208,13 @@ namespace Ryujinx.Graphics.OpenGL.Image _dstFramebuffer = 0; } + + if (_copyPboHandle != 0) + { + GL.DeleteBuffer(_copyPboHandle); + + _copyPboHandle = 0; + } } } } |