From d4187aaa9d7194aa26d04aee838edbc3a38f1862 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 18 Sep 2018 01:30:35 -0300 Subject: Allow "reinterpretation" of framebuffer/zeta formats (#418) * (Re)Implement format reinterpretation, other changes * Implement writeback to guest memory, some refactoring * More refactoring, implement reinterpretation the old way again * Clean up * Some fixes on M2MF (old Dma engine), added partial support for P2MF, fix conditional ssy, add Z24S8 zeta format, other fixes * nit: Formatting * Address PR feedback --- Ryujinx.Graphics/NvGpuEngine2d.cs | 131 ++++++++++++-------------------------- 1 file changed, 40 insertions(+), 91 deletions(-) (limited to 'Ryujinx.Graphics/NvGpuEngine2d.cs') diff --git a/Ryujinx.Graphics/NvGpuEngine2d.cs b/Ryujinx.Graphics/NvGpuEngine2d.cs index f26b0020..4bf7c1e8 100644 --- a/Ryujinx.Graphics/NvGpuEngine2d.cs +++ b/Ryujinx.Graphics/NvGpuEngine2d.cs @@ -1,7 +1,6 @@ using Ryujinx.Graphics.Gal; using Ryujinx.Graphics.Memory; using Ryujinx.Graphics.Texture; -using System; using System.Collections.Generic; namespace Ryujinx.Graphics @@ -62,25 +61,25 @@ namespace Ryujinx.Graphics { CopyOperation Operation = (CopyOperation)ReadRegister(NvGpuEngine2dReg.CopyOperation); + int SrcFormat = ReadRegister(NvGpuEngine2dReg.SrcFormat); bool SrcLinear = ReadRegister(NvGpuEngine2dReg.SrcLinear) != 0; int SrcWidth = ReadRegister(NvGpuEngine2dReg.SrcWidth); int SrcHeight = ReadRegister(NvGpuEngine2dReg.SrcHeight); int SrcPitch = ReadRegister(NvGpuEngine2dReg.SrcPitch); int SrcBlkDim = ReadRegister(NvGpuEngine2dReg.SrcBlockDimensions); + int DstFormat = ReadRegister(NvGpuEngine2dReg.DstFormat); bool DstLinear = ReadRegister(NvGpuEngine2dReg.DstLinear) != 0; int DstWidth = ReadRegister(NvGpuEngine2dReg.DstWidth); int DstHeight = ReadRegister(NvGpuEngine2dReg.DstHeight); int DstPitch = ReadRegister(NvGpuEngine2dReg.DstPitch); int DstBlkDim = ReadRegister(NvGpuEngine2dReg.DstBlockDimensions); - TextureSwizzle SrcSwizzle = SrcLinear - ? TextureSwizzle.Pitch - : TextureSwizzle.BlockLinear; + GalImageFormat SrcImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)SrcFormat); + GalImageFormat DstImgFormat = ImageUtils.ConvertSurface((GalSurfaceFormat)DstFormat); - TextureSwizzle DstSwizzle = DstLinear - ? TextureSwizzle.Pitch - : TextureSwizzle.BlockLinear; + GalMemoryLayout SrcLayout = GetLayout(SrcLinear); + GalMemoryLayout DstLayout = GetLayout(DstLinear); int SrcBlockHeight = 1 << ((SrcBlkDim >> 4) & 0xf); int DstBlockHeight = 1 << ((DstBlkDim >> 4) & 0xf); @@ -91,91 +90,41 @@ namespace Ryujinx.Graphics long SrcKey = Vmm.GetPhysicalAddress(SrcAddress); long DstKey = Vmm.GetPhysicalAddress(DstAddress); - bool IsSrcFb = Gpu.Engine3d.IsFrameBufferPosition(SrcKey); - bool IsDstFb = Gpu.Engine3d.IsFrameBufferPosition(DstKey); - - TextureInfo SrcTexture() - { - return new TextureInfo( - SrcAddress, - SrcWidth, - SrcHeight, - SrcPitch, - SrcBlockHeight, 1, - SrcSwizzle, - GalImageFormat.A8B8G8R8 | GalImageFormat.Unorm); - } - - TextureInfo DstTexture() - { - return new TextureInfo( - DstAddress, - DstWidth, - DstHeight, - DstPitch, - DstBlockHeight, 1, - DstSwizzle, - GalImageFormat.A8B8G8R8 | GalImageFormat.Unorm); - } - - //TODO: fb -> fb copies, tex -> fb copies, formats other than RGBA8, - //make it throw for unimpl stuff (like the copy mode)... - if (IsSrcFb && IsDstFb) - { - //Frame Buffer -> Frame Buffer copy. - Gpu.Renderer.RenderTarget.Copy( - SrcKey, - DstKey, - 0, - 0, - SrcWidth, - SrcHeight, - 0, - 0, - DstWidth, - DstHeight); - } - if (IsSrcFb) - { - //Frame Buffer -> Texture copy. - Gpu.Renderer.RenderTarget.GetBufferData(SrcKey, (byte[] Buffer) => - { - TextureInfo Src = SrcTexture(); - TextureInfo Dst = DstTexture(); - - if (Src.Width != Dst.Width || - Src.Height != Dst.Height) - { - throw new NotImplementedException("Texture resizing is not supported"); - } - - TextureWriter.Write(Vmm, Dst, Buffer); - }); - } - else if (IsDstFb) - { - byte[] Buffer = TextureReader.Read(Vmm, SrcTexture()); - - Gpu.Renderer.RenderTarget.SetBufferData( - DstKey, - DstWidth, - DstHeight, - Buffer); - } - else - { - //Texture -> Texture copy. - TextureInfo Src = SrcTexture(); - TextureInfo Dst = DstTexture(); - - if (Src.Width != Dst.Width || - Src.Height != Dst.Height) - { - throw new NotImplementedException("Texture resizing is not supported"); - } + GalImage SrcTexture = new GalImage( + SrcWidth, + SrcHeight, 1, + SrcBlockHeight, + SrcLayout, + SrcImgFormat); + + GalImage DstTexture = new GalImage( + DstWidth, + DstHeight, 1, + DstBlockHeight, + DstLayout, + DstImgFormat); + + Gpu.ResourceManager.SendTexture(Vmm, SrcKey, SrcTexture); + Gpu.ResourceManager.SendTexture(Vmm, DstKey, DstTexture); + + Gpu.Renderer.RenderTarget.Copy( + SrcKey, + DstKey, + 0, + 0, + SrcWidth, + SrcHeight, + 0, + 0, + DstWidth, + DstHeight); + } - TextureWriter.Write(Vmm, Dst, TextureReader.Read(Vmm, Src)); - } + private static GalMemoryLayout GetLayout(bool Linear) + { + return Linear + ? GalMemoryLayout.Pitch + : GalMemoryLayout.BlockLinear; } private long MakeInt64From2xInt32(NvGpuEngine2dReg Reg) -- cgit v1.2.3