From 06e84b40f4228d5d5651be4ddeaa9cd92b6e3ed7 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sun, 15 Jul 2018 22:46:05 -0300 Subject: [PATCH] Attempt to support deswizzle of sparse tiled textures --- Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs | 21 ++++++++++++--------- Ryujinx.HLE/Gpu/Texture/TextureFactory.cs | 5 ++++- Ryujinx.HLE/Gpu/Texture/TextureHelper.cs | 10 ++++++++-- Ryujinx.HLE/Gpu/Texture/TextureInfo.cs | 19 ++++++++++++------- Ryujinx.HLE/Gpu/Texture/TextureReader.cs | 18 +++++++++--------- Ryujinx.HLE/Gpu/Texture/TextureWriter.cs | 2 +- 6 files changed, 46 insertions(+), 29 deletions(-) diff --git a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs index f150b3f5e9..70bad73c57 100644 --- a/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs +++ b/Ryujinx.HLE/Gpu/Engines/NvGpuEngine2d.cs @@ -89,22 +89,25 @@ namespace Ryujinx.HLE.Gpu.Engines DstSwizzle = TextureSwizzle.BlockLinear; } - TextureInfo DstTexture = new TextureInfo( - DstAddress, - DstWidth, - DstHeight, - DstBlockHeight, - DstBlockHeight, - DstSwizzle, - GalTextureFormat.A8B8G8R8); - if (IsFbTexture) { //TODO: Change this when the correct frame buffer resolution is used. //Currently, the frame buffer size is hardcoded to 1280x720. SrcWidth = 1280; SrcHeight = 720; + } + TextureInfo DstTexture = new TextureInfo( + DstAddress, + SrcWidth, + SrcHeight, + DstPitch, + DstBlockHeight, 1, + DstSwizzle, + GalTextureFormat.A8B8G8R8); + + if (IsFbTexture) + { Gpu.Renderer.FrameBuffer.GetBufferData(Key, (byte[] Buffer) => { CopyTexture( diff --git a/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs b/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs index 9df0b60002..4db0b6f106 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureFactory.cs @@ -55,9 +55,11 @@ namespace Ryujinx.HLE.Gpu.Texture int Pitch = (Tic[3] & 0xffff) << 5; - int BlockHeightLog2 = (Tic[3] >> 3) & 7; + int BlockHeightLog2 = (Tic[3] >> 3) & 7; + int TileWidthLog2 = (Tic[3] >> 10) & 7; int BlockHeight = 1 << BlockHeightLog2; + int TileWidth = 1 << TileWidthLog2; int Width = (Tic[4] & 0xffff) + 1; int Height = (Tic[5] & 0xffff) + 1; @@ -68,6 +70,7 @@ namespace Ryujinx.HLE.Gpu.Texture Height, Pitch, BlockHeight, + TileWidth, Swizzle, Format); diff --git a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs index c0749d6a25..55173595a4 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs @@ -7,8 +7,14 @@ namespace Ryujinx.HLE.Gpu.Texture { static class TextureHelper { - public static ISwizzle GetSwizzle(TextureInfo Texture, int Width, int Bpp) + public static ISwizzle GetSwizzle(TextureInfo Texture, int BlockWidth, int Bpp) { + int AlignMask = Texture.TileWidth * 64 - 1; + + int WidthAligned = (Texture.Width + AlignMask) & ~AlignMask; + + WidthAligned = (WidthAligned + (BlockWidth - 1)) / BlockWidth; + switch (Texture.Swizzle) { case TextureSwizzle._1dBuffer: @@ -18,7 +24,7 @@ namespace Ryujinx.HLE.Gpu.Texture case TextureSwizzle.BlockLinear: case TextureSwizzle.BlockLinearColorKey: - return new BlockLinearSwizzle(Width, Bpp, Texture.BlockHeight); + return new BlockLinearSwizzle(WidthAligned, Bpp, Texture.BlockHeight); } throw new NotImplementedException(Texture.Swizzle.ToString()); diff --git a/Ryujinx.HLE/Gpu/Texture/TextureInfo.cs b/Ryujinx.HLE/Gpu/Texture/TextureInfo.cs index 31784bbc58..2a98ce00fd 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureInfo.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureInfo.cs @@ -11,6 +11,7 @@ namespace Ryujinx.HLE.Gpu.Texture public int Pitch { get; private set; } public int BlockHeight { get; private set; } + public int TileWidth { get; private set; } public TextureSwizzle Swizzle { get; private set; } @@ -29,6 +30,8 @@ namespace Ryujinx.HLE.Gpu.Texture BlockHeight = 16; + TileWidth = 1; + Swizzle = TextureSwizzle.BlockLinear; Format = GalTextureFormat.A8B8G8R8; @@ -40,16 +43,18 @@ namespace Ryujinx.HLE.Gpu.Texture int Height, int Pitch, int BlockHeight, + int TileWidth, TextureSwizzle Swizzle, GalTextureFormat Format) { - this.Position = Position; - this.Width = Width; - this.Height = Height; - this.Pitch = Pitch; - this.BlockHeight = BlockHeight; - this.Swizzle = Swizzle; - this.Format = Format; + this.Position = Position; + this.Width = Width; + this.Height = Height; + this.Pitch = Pitch; + this.BlockHeight = BlockHeight; + this.TileWidth = TileWidth; + this.Swizzle = Swizzle; + this.Format = Format; } } } \ No newline at end of file diff --git a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs index 6c08cd6c4d..8bbf1ec484 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs @@ -52,7 +52,7 @@ namespace Ryujinx.HLE.Gpu.Texture byte[] Output = new byte[Width * Height]; - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 1); + ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 1); (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( Memory, @@ -85,7 +85,7 @@ namespace Ryujinx.HLE.Gpu.Texture byte[] Output = new byte[Width * Height * 2]; - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 2); + ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 2); (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( Memory, @@ -123,7 +123,7 @@ namespace Ryujinx.HLE.Gpu.Texture byte[] Output = new byte[Width * Height * 2]; - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 2); + ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 2); (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( Memory, @@ -160,7 +160,7 @@ namespace Ryujinx.HLE.Gpu.Texture byte[] Output = new byte[Width * Height * 2]; - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 2); + ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 2); (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( Memory, @@ -193,7 +193,7 @@ namespace Ryujinx.HLE.Gpu.Texture byte[] Output = new byte[Width * Height * 4]; - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 4); + ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 4); (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( Memory, @@ -226,7 +226,7 @@ namespace Ryujinx.HLE.Gpu.Texture byte[] Output = new byte[Width * Height * 8]; - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 8); + ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 8); (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( Memory, @@ -259,7 +259,7 @@ namespace Ryujinx.HLE.Gpu.Texture byte[] Output = new byte[Width * Height * 16]; - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 16); + ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 16); (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( Memory, @@ -294,7 +294,7 @@ namespace Ryujinx.HLE.Gpu.Texture byte[] Output = new byte[Width * Height * 8]; - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 8); + ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 4, 8); (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( Memory, @@ -327,7 +327,7 @@ namespace Ryujinx.HLE.Gpu.Texture byte[] Output = new byte[Width * Height * 16]; - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 16); + ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, BlockWidth, 16); (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( Memory, diff --git a/Ryujinx.HLE/Gpu/Texture/TextureWriter.cs b/Ryujinx.HLE/Gpu/Texture/TextureWriter.cs index b64302a5ab..bb819a3103 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureWriter.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureWriter.cs @@ -28,7 +28,7 @@ namespace Ryujinx.HLE.Gpu.Texture int Width, int Height) { - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 4); + ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 4); (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( Memory,