From fdb9d53e0047b8b8b6899aec95e2688e8233921f Mon Sep 17 00:00:00 2001 From: gdkchan Date: Mon, 9 Jul 2018 15:23:38 -0300 Subject: [PATCH] Allow copy between frame buffers --- Ryujinx.Graphics/Gal/IGalFrameBuffer.cs | 12 ++++ Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs | 28 +++++++++ Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs | 59 ++++++++++--------- 3 files changed, 70 insertions(+), 29 deletions(-) diff --git a/Ryujinx.Graphics/Gal/IGalFrameBuffer.cs b/Ryujinx.Graphics/Gal/IGalFrameBuffer.cs index eaae0a492e..bf2feddb91 100644 --- a/Ryujinx.Graphics/Gal/IGalFrameBuffer.cs +++ b/Ryujinx.Graphics/Gal/IGalFrameBuffer.cs @@ -22,6 +22,18 @@ namespace Ryujinx.Graphics.Gal void Render(); + void Copy( + long SrcKey, + long DstKey, + int SrcX0, + int SrcY0, + int SrcX1, + int SrcY1, + int DstX0, + int DstY0, + int DstX1, + int DstY1); + void GetBufferData(long Key, Action Callback); } } \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs index 305fa37d8f..8b987d64a0 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs @@ -304,6 +304,34 @@ namespace Ryujinx.Graphics.Gal.OpenGL } } + public void Copy( + long SrcKey, + long DstKey, + int SrcX0, + int SrcY0, + int SrcX1, + int SrcY1, + int DstX0, + int DstY0, + int DstX1, + int DstY1) + { + if (Fbs.TryGetValue(SrcKey, out FrameBuffer SrcFb) && + Fbs.TryGetValue(DstKey, out FrameBuffer DstFb)) + { + GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, SrcFb.Handle); + GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, DstFb.Handle); + + GL.Clear(ClearBufferMask.ColorBufferBit); + + GL.BlitFramebuffer( + SrcX0, SrcY0, SrcX1, SrcY1, + DstX0, DstY0, DstX1, DstY1, + ClearBufferMask.ColorBufferBit, + BlitFramebufferFilter.Linear); + } + } + public void GetBufferData(long Key, Action Callback) { if (Fbs.TryGetValue(Key, out FrameBuffer Fb)) diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs index f150b3f5e9..6fc7b40cd9 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs @@ -77,14 +77,16 @@ namespace Ryujinx.HLE.Gpu.Engines int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf); - long Key = Vmm.GetPhysicalAddress(MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress)); - long SrcAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.SrcAddress); long DstAddress = MakeInt64From2xInt32(NvGpuEngine2dReg.DstAddress); - bool IsFbTexture = Gpu.Engine3d.IsFrameBufferPosition(Key); + long SrcKey = Vmm.GetPhysicalAddress(SrcAddress); + long DstKey = Vmm.GetPhysicalAddress(DstAddress); - if (IsFbTexture && DstLinear) + bool IsSrcFb = Gpu.Engine3d.IsFrameBufferPosition(SrcKey); + bool IsDstFb = Gpu.Engine3d.IsFrameBufferPosition(DstKey); + + if (IsSrcFb && DstLinear) { DstSwizzle = TextureSwizzle.BlockLinear; } @@ -93,26 +95,40 @@ namespace Ryujinx.HLE.Gpu.Engines DstAddress, DstWidth, DstHeight, - DstBlockHeight, + DstPitch, DstBlockHeight, DstSwizzle, GalTextureFormat.A8B8G8R8); - if (IsFbTexture) + if (IsSrcFb && IsDstFb) + { + //TODO: Change this when the correct frame buffer resolution is used. + //Currently, the frame buffer size is hardcoded to 1280x720. + DstWidth = 1280; + DstHeight = 720; + + Gpu.Renderer.FrameBuffer.Copy( + SrcKey, + DstKey, + 0, + 0, + SrcWidth, + SrcHeight, + 0, + 0, + DstWidth, + DstHeight); + } + else if (IsSrcFb) { //TODO: Change this when the correct frame buffer resolution is used. //Currently, the frame buffer size is hardcoded to 1280x720. SrcWidth = 1280; SrcHeight = 720; - Gpu.Renderer.FrameBuffer.GetBufferData(Key, (byte[] Buffer) => + Gpu.Renderer.FrameBuffer.GetBufferData(SrcKey, (byte[] Buffer) => { - CopyTexture( - Vmm, - DstTexture, - Buffer, - SrcWidth, - SrcHeight); + TextureWriter.Write(Vmm, DstTexture, Buffer, SrcWidth, SrcHeight); }); } else @@ -121,25 +137,10 @@ namespace Ryujinx.HLE.Gpu.Engines byte[] Buffer = Vmm.ReadBytes(SrcAddress, Size); - CopyTexture( - Vmm, - DstTexture, - Buffer, - SrcWidth, - SrcHeight); + TextureWriter.Write(Vmm, DstTexture, Buffer, SrcWidth, SrcHeight); } } - private void CopyTexture( - NvGpuVmm Vmm, - TextureInfo Texture, - byte[] Buffer, - int Width, - int Height) - { - TextureWriter.Write(Vmm, Texture, Buffer, Width, Height); - } - private long MakeInt64From2xInt32(NvGpuEngine2dReg Reg) { return