diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-09-18 01:30:35 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-09-18 01:30:35 -0300 |
| commit | d4187aaa9d7194aa26d04aee838edbc3a38f1862 (patch) | |
| tree | 06fe725c1067b4aeca21749799b835d85e7d2787 /Ryujinx.Graphics/Texture | |
| parent | bec95cacc1061f91373a1e3a1411981af7fe2e4e (diff) | |
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
Diffstat (limited to 'Ryujinx.Graphics/Texture')
| -rw-r--r-- | Ryujinx.Graphics/Texture/ImageUtils.cs | 364 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Texture/TextureFactory.cs | 52 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Texture/TextureHelper.cs | 29 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Texture/TextureInfo.cs | 60 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Texture/TextureReader.cs | 398 | ||||
| -rw-r--r-- | Ryujinx.Graphics/Texture/TextureWriter.cs | 35 |
6 files changed, 222 insertions, 716 deletions
diff --git a/Ryujinx.Graphics/Texture/ImageUtils.cs b/Ryujinx.Graphics/Texture/ImageUtils.cs index f6db0894..7d3dde49 100644 --- a/Ryujinx.Graphics/Texture/ImageUtils.cs +++ b/Ryujinx.Graphics/Texture/ImageUtils.cs @@ -1,33 +1,37 @@ -using Ryujinx.Graphics.Gal; +using ChocolArm64.Memory; +using Ryujinx.Graphics.Gal; +using Ryujinx.Graphics.Memory; using System; using System.Collections.Generic; namespace Ryujinx.Graphics.Texture { - static class ImageUtils + public static class ImageUtils { - struct ImageDescriptor + [Flags] + private enum TargetBuffer { - public TextureReaderDelegate Reader; + Color = 1 << 0, + Depth = 1 << 1, + Stencil = 1 << 2, - public bool HasColor; - public bool HasDepth; - public bool HasStencil; + DepthStencil = Depth | Stencil + } + + private struct ImageDescriptor + { + public int BytesPerPixel { get; private set; } + public int BlockWidth { get; private set; } + public int BlockHeight { get; private set; } - public bool Compressed; + public TargetBuffer Target { get; private set; } - public ImageDescriptor( - TextureReaderDelegate Reader, - bool HasColor, - bool HasDepth, - bool HasStencil, - bool Compressed) + public ImageDescriptor(int BytesPerPixel, int BlockWidth, int BlockHeight, TargetBuffer Target) { - this.Reader = Reader; - this.HasColor = HasColor; - this.HasDepth = HasDepth; - this.HasStencil = HasStencil; - this.Compressed = Compressed; + this.BytesPerPixel = BytesPerPixel; + this.BlockWidth = BlockWidth; + this.BlockHeight = BlockHeight; + this.Target = Target; } } @@ -48,6 +52,7 @@ namespace Ryujinx.Graphics.Texture { GalTextureFormat.G8R8, GalImageFormat.G8R8 | Snorm | Unorm | Sint | Uint }, { GalTextureFormat.R16, GalImageFormat.R16 | Snorm | Unorm | Sint | Uint | Sfloat }, { GalTextureFormat.R8, GalImageFormat.R8 | Snorm | Unorm | Sint | Uint }, + { GalTextureFormat.R16G16, GalImageFormat.R16G16 | Snorm }, { GalTextureFormat.R32, GalImageFormat.R32 | Sint | Uint | Sfloat }, { GalTextureFormat.A4B4G4R4, GalImageFormat.A4B4G4R4 | Unorm }, { GalTextureFormat.A1B5G5R5, GalImageFormat.A1R5G5B5 | Unorm }, @@ -85,58 +90,58 @@ namespace Ryujinx.Graphics.Texture private static readonly Dictionary<GalImageFormat, ImageDescriptor> s_ImageTable = new Dictionary<GalImageFormat, ImageDescriptor>() - { - { GalImageFormat.R32G32B32A32, new ImageDescriptor(TextureReader.Read16Bpp, true, false, false, false) }, - { GalImageFormat.R16G16B16A16, new ImageDescriptor(TextureReader.Read8Bpp, true, false, false, false) }, - { GalImageFormat.R32G32, new ImageDescriptor(TextureReader.Read8Bpp, true, false, false, false) }, - { GalImageFormat.A8B8G8R8, new ImageDescriptor(TextureReader.Read4Bpp, true, false, false, false) }, - { GalImageFormat.A2B10G10R10, new ImageDescriptor(TextureReader.Read4Bpp, true, false, false, false) }, - { GalImageFormat.R32, new ImageDescriptor(TextureReader.Read4Bpp, true, false, false, false) }, - { GalImageFormat.A4B4G4R4, new ImageDescriptor(TextureReader.Read2Bpp, true, false, false, false) }, - { GalImageFormat.BC6H_SF16, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) }, - { GalImageFormat.BC6H_UF16, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) }, - { GalImageFormat.A1R5G5B5, new ImageDescriptor(TextureReader.Read5551, true, false, false, false) }, - { GalImageFormat.B5G6R5, new ImageDescriptor(TextureReader.Read565, true, false, false, false) }, - { GalImageFormat.BC7, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) }, - { GalImageFormat.R16G16, new ImageDescriptor(TextureReader.Read4Bpp, true, false, false, false) }, - { GalImageFormat.R8G8, new ImageDescriptor(TextureReader.Read2Bpp, true, false, false, false) }, - { GalImageFormat.G8R8, new ImageDescriptor(TextureReader.Read2Bpp, true, false, false, false) }, - { GalImageFormat.R16, new ImageDescriptor(TextureReader.Read2Bpp, true, false, false, false) }, - { GalImageFormat.R8, new ImageDescriptor(TextureReader.Read1Bpp, true, false, false, false) }, - { GalImageFormat.B10G11R11, new ImageDescriptor(TextureReader.Read4Bpp, true, false, false, false) }, - { GalImageFormat.A8B8G8R8_SRGB, new ImageDescriptor(TextureReader.Read4Bpp, true, false, false, false) }, - { GalImageFormat.BC1_RGBA, new ImageDescriptor(TextureReader.Read8Bpt4x4, true, false, false, true) }, - { GalImageFormat.BC2, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) }, - { GalImageFormat.BC3, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) }, - { GalImageFormat.BC4, new ImageDescriptor(TextureReader.Read8Bpt4x4, true, false, false, true) }, - { GalImageFormat.BC5, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) }, - { GalImageFormat.ASTC_4x4, new ImageDescriptor(TextureReader.Read16BptCompressedTexture4x4, true, false, false, true) }, - { GalImageFormat.ASTC_5x5, new ImageDescriptor(TextureReader.Read16BptCompressedTexture5x5, true, false, false, true) }, - { GalImageFormat.ASTC_6x6, new ImageDescriptor(TextureReader.Read16BptCompressedTexture6x6, true, false, false, true) }, - { GalImageFormat.ASTC_8x8, new ImageDescriptor(TextureReader.Read16BptCompressedTexture8x8, true, false, false, true) }, - { GalImageFormat.ASTC_10x10, new ImageDescriptor(TextureReader.Read16BptCompressedTexture10x10, true, false, false, true) }, - { GalImageFormat.ASTC_12x12, new ImageDescriptor(TextureReader.Read16BptCompressedTexture12x12, true, false, false, true) }, - { GalImageFormat.ASTC_5x4, new ImageDescriptor(TextureReader.Read16BptCompressedTexture5x4, true, false, false, true) }, - { GalImageFormat.ASTC_6x5, new ImageDescriptor(TextureReader.Read16BptCompressedTexture6x5, true, false, false, true) }, - { GalImageFormat.ASTC_8x6, new ImageDescriptor(TextureReader.Read16BptCompressedTexture8x6, true, false, false, true) }, - { GalImageFormat.ASTC_10x8, new ImageDescriptor(TextureReader.Read16BptCompressedTexture10x8, true, false, false, true) }, - { GalImageFormat.ASTC_12x10, new ImageDescriptor(TextureReader.Read16BptCompressedTexture12x10, true, false, false, true) }, - { GalImageFormat.ASTC_8x5, new ImageDescriptor(TextureReader.Read16BptCompressedTexture8x5, true, false, false, true) }, - { GalImageFormat.ASTC_10x5, new ImageDescriptor(TextureReader.Read16BptCompressedTexture10x5, true, false, false, true) }, - { GalImageFormat.ASTC_10x6, new ImageDescriptor(TextureReader.Read16BptCompressedTexture10x6, true, false, false, true) }, - - { GalImageFormat.D24_S8, new ImageDescriptor(TextureReader.Read4Bpp, false, true, true, false) }, - { GalImageFormat.D32, new ImageDescriptor(TextureReader.Read4Bpp, false, true, false, false) }, - { GalImageFormat.D16, new ImageDescriptor(TextureReader.Read2Bpp, false, true, false, false) }, - { GalImageFormat.D32_S8, new ImageDescriptor(TextureReader.Read8Bpp, false, true, true, false) }, - }; + { + { GalImageFormat.R32G32B32A32, new ImageDescriptor(16, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.R16G16B16A16, new ImageDescriptor(8, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.R32G32, new ImageDescriptor(8, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.A8B8G8R8, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.A2B10G10R10, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.R32, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.A4B4G4R4, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.BC6H_SF16, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.BC6H_UF16, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.A1R5G5B5, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.B5G6R5, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.BC7, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.R16G16, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.R8G8, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.G8R8, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.R16, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.R8, new ImageDescriptor(1, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.B10G11R11, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.A8B8G8R8_SRGB, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.BC1_RGBA, new ImageDescriptor(8, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.BC2, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.BC3, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.BC4, new ImageDescriptor(8, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.BC5, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.ASTC_4x4, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.ASTC_5x5, new ImageDescriptor(16, 5, 5, TargetBuffer.Color) }, + { GalImageFormat.ASTC_6x6, new ImageDescriptor(16, 6, 6, TargetBuffer.Color) }, + { GalImageFormat.ASTC_8x8, new ImageDescriptor(16, 8, 8, TargetBuffer.Color) }, + { GalImageFormat.ASTC_10x10, new ImageDescriptor(16, 10, 10, TargetBuffer.Color) }, + { GalImageFormat.ASTC_12x12, new ImageDescriptor(16, 12, 12, TargetBuffer.Color) }, + { GalImageFormat.ASTC_5x4, new ImageDescriptor(16, 5, 4, TargetBuffer.Color) }, + { GalImageFormat.ASTC_6x5, new ImageDescriptor(16, 6, 5, TargetBuffer.Color) }, + { GalImageFormat.ASTC_8x6, new ImageDescriptor(16, 8, 6, TargetBuffer.Color) }, + { GalImageFormat.ASTC_10x8, new ImageDescriptor(16, 10, 8, TargetBuffer.Color) }, + { GalImageFormat.ASTC_12x10, new ImageDescriptor(16, 12, 10, TargetBuffer.Color) }, + { GalImageFormat.ASTC_8x5, new ImageDescriptor(16, 8, 5, TargetBuffer.Color) }, + { GalImageFormat.ASTC_10x5, new ImageDescriptor(16, 10, 5, TargetBuffer.Color) }, + { GalImageFormat.ASTC_10x6, new ImageDescriptor(16, 10, 6, TargetBuffer.Color) }, + + { GalImageFormat.D24_S8, new ImageDescriptor(4, 1, 1, TargetBuffer.DepthStencil) }, + { GalImageFormat.D32, new ImageDescriptor(4, 1, 1, TargetBuffer.Depth) }, + { GalImageFormat.D16, new ImageDescriptor(2, 1, 1, TargetBuffer.Depth) }, + { GalImageFormat.D32_S8, new ImageDescriptor(8, 1, 1, TargetBuffer.DepthStencil) }, + }; public static GalImageFormat ConvertTexture( GalTextureFormat Format, - GalTextureType RType, - GalTextureType GType, - GalTextureType BType, - GalTextureType AType) + GalTextureType RType, + GalTextureType GType, + GalTextureType BType, + GalTextureType AType) { if (RType != GType || RType != BType || RType != AType) { @@ -202,128 +207,157 @@ namespace Ryujinx.Graphics.Texture case GalZetaFormat.Z32Float: return GalImageFormat.D32 | Sfloat; case GalZetaFormat.S8Z24Unorm: return GalImageFormat.D24_S8 | Unorm; case GalZetaFormat.Z16Unorm: return GalImageFormat.D16 | Unorm; - //This one might not be Uint, change when a texture uses this format - case GalZetaFormat.Z32S8X24Float: return GalImageFormat.D32_S8 | Uint; + case GalZetaFormat.Z24S8Unorm: return GalImageFormat.D24_S8 | Unorm; + case GalZetaFormat.Z32S8X24Float: return GalImageFormat.D32_S8 | Sfloat; } throw new NotImplementedException(Format.ToString()); } - public static TextureReaderDelegate GetReader(GalImageFormat Format) + public static byte[] ReadTexture(IAMemory Memory, GalImage Image, long Position) + { + AMemory CpuMemory; + + if (Memory is NvGpuVmm Vmm) + { + CpuMemory = Vmm.Memory; + } + else + { + CpuMemory = (AMemory)Memory; + } + + ISwizzle Swizzle = TextureHelper.GetSwizzle(Image); + + ImageDescriptor Desc = GetImageDescriptor(Image.Format); + + (int Width, int Height) = GetImageSizeInBlocks(Image); + + int BytesPerPixel = Desc.BytesPerPixel; + + int OutOffs = 0; + + byte[] Data = new byte[Width * Height * BytesPerPixel]; + + for (int Y = 0; Y < Height; Y++) + for (int X = 0; X < Width; X++) + { + long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); + + CpuMemory.ReadBytes(Position + Offset, Data, OutOffs, BytesPerPixel); + + OutOffs += BytesPerPixel; + } + + return Data; + } + + public static void WriteTexture(NvGpuVmm Vmm, GalImage Image, long Position, byte[] Data) { - return GetImageDescriptor(Format).Reader; + ISwizzle Swizzle = TextureHelper.GetSwizzle(Image); + + ImageDescriptor Desc = GetImageDescriptor(Image.Format); + + (int Width, int Height) = ImageUtils.GetImageSizeInBlocks(Image); + + int BytesPerPixel = Desc.BytesPerPixel; + + int InOffs = 0; + + for (int Y = 0; Y < Height; Y++) + for (int X = 0; X < Width; X++) + { + long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); + + Vmm.Memory.WriteBytes(Position + Offset, Data, InOffs, BytesPerPixel); + + InOffs += BytesPerPixel; + } } public static int GetSize(GalImage Image) { - switch (Image.Format & GalImageFormat.FormatMask) + ImageDescriptor Desc = GetImageDescriptor(Image.Format); + + int Width = DivRoundUp(Image.Width, Desc.BlockWidth); + int Height = DivRoundUp(Image.Height, Desc.BlockHeight); + + return Desc.BytesPerPixel * Width * Height; + } + + public static int GetPitch(GalImageFormat Format, int Width) + { + ImageDescriptor Desc = GetImageDescriptor(Format); + + return Desc.BytesPerPixel * DivRoundUp(Width, Desc.BlockWidth); + } + + public static int GetBlockWidth(GalImageFormat Format) + { + return GetImageDescriptor(Format).BlockWidth; + } + + public static int GetBlockHeight(GalImageFormat Format) + { + return GetImageDescriptor(Format).BlockHeight; + } + + public static int GetAlignedWidth(GalImage Image) + { + ImageDescriptor Desc = GetImageDescriptor(Image.Format); + + int AlignMask; + + if (Image.Layout == GalMemoryLayout.BlockLinear) { - case GalImageFormat.R32G32B32A32: - return Image.Width * Image.Height * 16; - - case GalImageFormat.R16G16B16A16: - case GalImageFormat.D32_S8: - case GalImageFormat.R32G32: - return Image.Width * Image.Height * 8; - - case GalImageFormat.A8B8G8R8: - case GalImageFormat.A8B8G8R8_SRGB: - case GalImageFormat.A2B10G10R10: - case GalImageFormat.R16G16: - case GalImageFormat.R32: - case GalImageFormat.D32: - case GalImageFormat.B10G11R11: - case GalImageFormat.D24_S8: - return Image.Width * Image.Height * 4; - - case GalImageFormat.B4G4R4A4: - case GalImageFormat.A1R5G5B5: - case GalImageFormat.B5G6R5: - case GalImageFormat.R8G8: - case GalImageFormat.G8R8: - case GalImageFormat.R16: - case GalImageFormat.D16: - return Image.Width * Image.Height * 2; - - case GalImageFormat.R8: - return Image.Width * Image.Height; - - case GalImageFormat.BC1_RGBA: - case GalImageFormat.BC4: - { - return CompressedTextureSize(Image.Width, Image.Height, 4, 4, 8); - } - - case GalImageFormat.BC6H_SF16: - case GalImageFormat.BC6H_UF16: - case GalImageFormat.BC7: - case GalImageFormat.BC2: - case GalImageFormat.BC3: - case GalImageFormat.BC5: - case GalImageFormat.ASTC_4x4: - return CompressedTextureSize(Image.Width, Image.Height, 4, 4, 16); - - case GalImageFormat.ASTC_5x5: - return CompressedTextureSize(Image.Width, Image.Height, 5, 5, 16); - - case GalImageFormat.ASTC_6x6: - return CompressedTextureSize(Image.Width, Image.Height, 6, 6, 16); - - case GalImageFormat.ASTC_8x8: - return CompressedTextureSize(Image.Width, Image.Height, 8, 8, 16); - - case GalImageFormat.ASTC_10x10: - return CompressedTextureSize(Image.Width, Image.Height, 10, 10, 16); - - case GalImageFormat.ASTC_12x12: - return CompressedTextureSize(Image.Width, Image.Height, 12, 12, 16); - - case GalImageFormat.ASTC_5x4: - return CompressedTextureSize(Image.Width, Image.Height, 5, 4, 16); - - case GalImageFormat.ASTC_6x5: - return CompressedTextureSize(Image.Width, Image.Height, 6, 5, 16); - - case GalImageFormat.ASTC_8x6: - return CompressedTextureSize(Image.Width, Image.Height, 8, 6, 16); - - case GalImageFormat.ASTC_10x8: - return CompressedTextureSize(Image.Width, Image.Height, 10, 8, 16); - - case GalImageFormat.ASTC_12x10: - return CompressedTextureSize(Image.Width, Image.Height, 12, 10, 16); - - case GalImageFormat.ASTC_8x5: - return CompressedTextureSize(Image.Width, Image.Height, 8, 5, 16); - - case GalImageFormat.ASTC_10x5: - return CompressedTextureSize(Image.Width, Image.Height, 10, 5, 16); - - case GalImageFormat.ASTC_10x6: - return CompressedTextureSize(Image.Width, Image.Height, 10, 6, 16); + AlignMask = Image.TileWidth * (64 / Desc.BytesPerPixel) - 1; + } + else + { + AlignMask = (32 / Desc.BytesPerPixel) - 1; } - throw new NotImplementedException((Image.Format & GalImageFormat.FormatMask).ToString()); + return (Image.Width + AlignMask) & ~AlignMask; + } + + public static (int Width, int Height) GetImageSizeInBlocks(GalImage Image) + { + ImageDescriptor Desc = GetImageDescriptor(Image.Format); + + return (DivRoundUp(Image.Width, Desc.BlockWidth), + DivRoundUp(Image.Height, Desc.BlockHeight)); + } + + public static int GetBytesPerPixel(GalImageFormat Format) + { + return GetImageDescriptor(Format).BytesPerPixel; + } + + private static int DivRoundUp(int LHS, int RHS) + { + return (LHS + (RHS - 1)) / RHS; } public static bool HasColor(GalImageFormat Format) { - return GetImageDescriptor(Format).HasColor; + return (GetImageDescriptor(Format).Target & TargetBuffer.Color) != 0; } public static bool HasDepth(GalImageFormat Format) { - return GetImageDescriptor(Format).HasDepth; + return (GetImageDescriptor(Format).Target & TargetBuffer.Depth) != 0; } public static bool HasStencil(GalImageFormat Format) { - return GetImageDescriptor(Format).HasStencil; + return (GetImageDescriptor(Format).Target & TargetBuffer.Stencil) != 0; } public static bool IsCompressed(GalImageFormat Format) { - return GetImageDescriptor(Format).Compressed; + ImageDescriptor Desc = GetImageDescriptor(Format); + + return (Desc.BlockWidth | Desc.BlockHeight) != 1; } private static ImageDescriptor GetImageDescriptor(GalImageFormat Format) @@ -351,13 +385,5 @@ namespace Ryujinx.Graphics.Texture default: throw new NotImplementedException(((int)Type).ToString()); } } - - private static int CompressedTextureSize(int TextureWidth, int TextureHeight, int BlockWidth, int BlockHeight, int Bpb) - { - int W = (TextureWidth + (BlockWidth - 1)) / BlockWidth; - int H = (TextureHeight + (BlockHeight - 1)) / BlockHeight; - - return W * H * Bpb; - } } }
\ No newline at end of file diff --git a/Ryujinx.Graphics/Texture/TextureFactory.cs b/Ryujinx.Graphics/Texture/TextureFactory.cs index fa7a0f80..766c53da 100644 --- a/Ryujinx.Graphics/Texture/TextureFactory.cs +++ b/Ryujinx.Graphics/Texture/TextureFactory.cs @@ -17,44 +17,20 @@ namespace Ryujinx.Graphics.Texture GalTextureSource ZSource = (GalTextureSource)((Tic[0] >> 25) & 7); GalTextureSource WSource = (GalTextureSource)((Tic[0] >> 28) & 7); - int Width = (Tic[4] & 0xffff) + 1; - int Height = (Tic[5] & 0xffff) + 1; - - return new GalImage( - Width, - Height, - Format, - XSource, - YSource, - ZSource, - WSource); - } - - public static byte[] GetTextureData(NvGpuVmm Vmm, long TicPosition) - { - int[] Tic = ReadWords(Vmm, TicPosition, 8); - - GalImageFormat Format = GetImageFormat(Tic); - - long TextureAddress = (uint)Tic[1]; - - TextureAddress |= (long)((ushort)Tic[2]) << 32; - TextureSwizzle Swizzle = (TextureSwizzle)((Tic[2] >> 21) & 7); + GalMemoryLayout Layout; + if (Swizzle == TextureSwizzle.BlockLinear || Swizzle == TextureSwizzle.BlockLinearColorKey) { - TextureAddress &= ~0x1ffL; + Layout = GalMemoryLayout.BlockLinear; } - else if (Swizzle == TextureSwizzle.Pitch || - Swizzle == TextureSwizzle.PitchColorKey) + else { - TextureAddress &= ~0x1fL; + Layout = GalMemoryLayout.Pitch; } - int Pitch = (Tic[3] & 0xffff) << 5; - int BlockHeightLog2 = (Tic[3] >> 3) & 7; int TileWidthLog2 = (Tic[3] >> 10) & 7; @@ -64,17 +40,17 @@ namespace Ryujinx.Graphics.Texture int Width = (Tic[4] & 0xffff) + 1; int Height = (Tic[5] & 0xffff) + 1; - TextureInfo Texture = new TextureInfo( - TextureAddress, + return new GalImage( Width, Height, - Pitch, - BlockHeight, TileWidth, - Swizzle, - Format); - - return TextureReader.Read(Vmm, Texture); + BlockHeight, + Layout, + Format, + XSource, + YSource, + ZSource, + WSource); } public static GalTextureSampler MakeSampler(NvGpu Gpu, NvGpuVmm Vmm, long TscPosition) @@ -107,7 +83,7 @@ namespace Ryujinx.Graphics.Texture private static GalImageFormat GetImageFormat(int[] Tic) { - GalTextureType RType = (GalTextureType)((Tic[0] >> 7) & 7); + GalTextureType RType = (GalTextureType)((Tic[0] >> 7) & 7); GalTextureType GType = (GalTextureType)((Tic[0] >> 10) & 7); GalTextureType BType = (GalTextureType)((Tic[0] >> 13) & 7); GalTextureType AType = (GalTextureType)((Tic[0] >> 16) & 7); diff --git a/Ryujinx.Graphics/Texture/TextureHelper.cs b/Ryujinx.Graphics/Texture/TextureHelper.cs index 8130ab41..9e966e6b 100644 --- a/Ryujinx.Graphics/Texture/TextureHelper.cs +++ b/Ryujinx.Graphics/Texture/TextureHelper.cs @@ -1,33 +1,30 @@ using ChocolArm64.Memory; using Ryujinx.Graphics.Gal; using Ryujinx.Graphics.Memory; -using System; namespace Ryujinx.Graphics.Texture { static class TextureHelper { - public static ISwizzle GetSwizzle(TextureInfo Texture, int BlockWidth, int Bpp) + public static ISwizzle GetSwizzle(GalImage Image) { - int Width = (Texture.Width + (BlockWidth - 1)) / BlockWidth; + int BlockWidth = ImageUtils.GetBlockWidth (Image.Format); + int BytesPerPixel = ImageUtils.GetBytesPerPixel(Image.Format); - int AlignMask = Texture.TileWidth * (64 / Bpp) - 1; + int Width = (Image.Width + (BlockWidth - 1)) / BlockWidth; - Width = (Width + AlignMask) & ~AlignMask; - - switch (Texture.Swizzle) + if (Image.Layout == GalMemoryLayout.BlockLinear) { - case TextureSwizzle._1dBuffer: - case TextureSwizzle.Pitch: - case TextureSwizzle.PitchColorKey: - return new LinearSwizzle(Texture.Pitch, Bpp); + int AlignMask = Image.TileWidth * (64 / BytesPerPixel) - 1; - case TextureSwizzle.BlockLinear: - case TextureSwizzle.BlockLinearColorKey: - return new BlockLinearSwizzle(Width, Bpp, Texture.BlockHeight); - } + Width = (Width + AlignMask) & ~AlignMask; - throw new NotImplementedException(Texture.Swizzle.ToString()); + return new BlockLinearSwizzle(Width, BytesPerPixel, Image.GobBlockHeight); + } + else + { + return new LinearSwizzle(Image.Pitch, BytesPerPixel); + } } public static (AMemory Memory, long Position) GetMemoryAndPosition( diff --git a/Ryujinx.Graphics/Texture/TextureInfo.cs b/Ryujinx.Graphics/Texture/TextureInfo.cs deleted file mode 100644 index 66445dcc..00000000 --- a/Ryujinx.Graphics/Texture/TextureInfo.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Ryujinx.Graphics.Gal; - -namespace Ryujinx.Graphics.Texture -{ - public struct TextureInfo - { - public long Position { get; private set; } - - public int Width { get; private set; } - public int Height { get; private set; } - public int Pitch { get; private set; } - - public int BlockHeight { get; private set; } - public int TileWidth { get; private set; } - - public TextureSwizzle Swizzle { get; private set; } - - public GalImageFormat Format { get; private set; } - - public TextureInfo( - long Position, - int Width, - int Height) - { - this.Position = Position; - this.Width = Width; - this.Height = Height; - - Pitch = 0; - - BlockHeight = 16; - - TileWidth = 1; - - Swizzle = TextureSwizzle.BlockLinear; - - Format = GalImageFormat.A8B8G8R8 | GalImageFormat.Unorm; - } - - public TextureInfo( - long Position, - int Width, - int Height, - int Pitch, - int BlockHeight, - int TileWidth, - TextureSwizzle Swizzle, - GalImageFormat 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.Graphics/Texture/TextureReader.cs b/Ryujinx.Graphics/Texture/TextureReader.cs deleted file mode 100644 index dbaed1a8..00000000 --- a/Ryujinx.Graphics/Texture/TextureReader.cs +++ /dev/null @@ -1,398 +0,0 @@ -using ChocolArm64.Memory; -using Ryujinx.Graphics.Gal; -using System; - -namespace Ryujinx.Graphics.Texture -{ - delegate byte[] TextureReaderDelegate(IAMemory Memory, TextureInfo Texture); - - public static class TextureReader - { - public static byte[] Read(IAMemory Memory, TextureInfo Texture) - { - TextureReaderDelegate Reader = ImageUtils.GetReader(Texture.Format); - - return Reader(Memory, Texture); - } - - internal unsafe static byte[] Read1Bpp(IAMemory Memory, TextureInfo Texture) - { - int Width = Texture.Width; - int Height = Texture.Height; - - byte[] Output = new byte[Width * Height]; - - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 1); - - (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( - Memory, - Texture.Position); - - fixed (byte* BuffPtr = Output) - { - long OutOffs = 0; - - for (int Y = 0; Y < Height; Y++) - for (int X = 0; X < Width; X++) - { - long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - - byte Pixel = CpuMem.ReadByte(Position + Offset); - - *(BuffPtr + OutOffs) = Pixel; - - OutOffs++; - } - } - - return Output; - } - - internal unsafe static byte[] Read5551(IAMemory Memory, TextureInfo Texture) - { - int Width = Texture.Width; - int Height = Texture.Height; - - byte[] Output = new byte[Width * Height * 2]; - - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 2); - - (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( - Memory, - Texture.Position); - - fixed (byte* BuffPtr = Output) - { - long OutOffs = 0; - - for (int Y = 0; Y < Height; Y++) - for (int X = 0; X < Width; X++) - { - long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - - uint Pixel = (uint)CpuMem.ReadInt16(Position + Offset); - - Pixel = (Pixel & 0x001f) << 11 | - (Pixel & 0x03e0) << 1 | - (Pixel & 0x7c00) >> 9 | - (Pixel & 0x8000) >> 15; - - *(short*)(BuffPtr + OutOffs) = (short)Pixel; - - OutOffs += 2; - } - } - - return Output; - } - - internal unsafe static byte[] Read565(IAMemory Memory, TextureInfo Texture) - { - int Width = Texture.Width; - int Height = Texture.Height; - - byte[] Output = new byte[Width * Height * 2]; - - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 2); - - (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( - Memory, - Texture.Position); - - fixed (byte* BuffPtr = Output) - { - long OutOffs = 0; - - for (int Y = 0; Y < Height; Y++) - for (int X = 0; X < Width; X++) - { - long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - - uint Pixel = (uint)CpuMem.ReadInt16(Position + Offset); - - Pixel = (Pixel & 0x001f) << 11 | - (Pixel & 0x07e0) | - (Pixel & 0xf800) >> 11; - - *(short*)(BuffPtr + OutOffs) = (short)Pixel; - - OutOffs += 2; - } - } - - return Output; - } - - internal unsafe static byte[] Read2Bpp(IAMemory Memory, TextureInfo Texture) - { - int Width = Texture.Width; - int Height = Texture.Height; - - byte[] Output = new byte[Width * Height * 2]; - - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 2); - - (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( - Memory, - Texture.Position); - - fixed (byte* BuffPtr = Output) - { - long OutOffs = 0; - - for (int Y = 0; Y < Height; Y++) - for (int X = 0; X < Width; X++) - { - long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - - short Pixel = CpuMem.ReadInt16(Position + Offset); - - *(short*)(BuffPtr + OutOffs) = Pixel; - - OutOffs += 2; - } - } - - return Output; - } - - internal unsafe static byte[] Read4Bpp(IAMemory Memory, TextureInfo Texture) - { - int Width = Texture.Width; - int Height = Texture.Height; - - byte[] Output = new byte[Width * Height * 4]; - - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 4); - - (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( - Memory, - Texture.Position); - - fixed (byte* BuffPtr = Output) - { - long OutOffs = 0; - - for (int Y = 0; Y < Height; Y++) - for (int X = 0; X < Width; X++) - { - long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - - int Pixel = CpuMem.ReadInt32(Position + Offset); - - *(int*)(BuffPtr + OutOffs) = Pixel; - - OutOffs += 4; - } - } - - return Output; - } - - internal unsafe static byte[] Read8Bpp(IAMemory Memory, TextureInfo Texture) - { - int Width = Texture.Width; - int Height = Texture.Height; - - byte[] Output = new byte[Width * Height * 8]; - - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 8); - - (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( - Memory, - Texture.Position); - - fixed (byte* BuffPtr = Output) - { - long OutOffs = 0; - - for (int Y = 0; Y < Height; Y++) - for (int X = 0; X < Width; X++) - { - long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - - long Pixel = CpuMem.ReadInt64(Position + Offset); - - *(long*)(BuffPtr + OutOffs) = Pixel; - - OutOffs += 8; - } - } - - return Output; - } - - internal unsafe static byte[] Read16Bpp(IAMemory Memory, TextureInfo Texture) - { - int Width = Texture.Width; - int Height = Texture.Height; - - byte[] Output = new byte[Width * Height * 16]; - - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 16); - - (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( - Memory, - Texture.Position); - - fixed (byte* BuffPtr = Output) - { - long OutOffs = 0; - - for (int Y = 0; Y < Height; Y++) - for (int X = 0; X < Width; X++) - { - long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - - long PxLow = CpuMem.ReadInt64(Position + Offset + 0); - long PxHigh = CpuMem.ReadInt64(Position + Offset + 8); - - *(long*)(BuffPtr + OutOffs + 0) = PxLow; - *(long*)(BuffPtr + OutOffs + 8) = PxHigh; - - OutOffs += 16; - } - } - - return Output; - } - - internal unsafe static byte[] Read8Bpt4x4(IAMemory Memory, TextureInfo Texture) - { - int Width = (Texture.Width + 3) / 4; - int Height = (Texture.Height + 3) / 4; - - byte[] Output = new byte[Width * Height * 8]; - - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 4, 8); - - (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( - Memory, - Texture.Position); - - fixed (byte* BuffPtr = Output) - { - long OutOffs = 0; - - for (int Y = 0; Y < Height; Y++) - for (int X = 0; X < Width; X++) - { - long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - - long Tile = CpuMem.ReadInt64(Position + Offset); - - *(long*)(BuffPtr + OutOffs) = Tile; - - OutOffs += 8; - } - } - - return Output; - } - - internal unsafe static byte[] Read16BptCompressedTexture(IAMemory Memory, TextureInfo Texture, int BlockWidth, int BlockHeight) - { - int Width = (Texture.Width + (BlockWidth - 1)) / BlockWidth; - int Height = (Texture.Height + (BlockHeight - 1)) / BlockHeight; - - byte[] Output = new byte[Width * Height * 16]; - - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, BlockWidth, 16); - - (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( - Memory, - Texture.Position); - - fixed (byte* BuffPtr = Output) - { - long OutOffs = 0; - - for (int Y = 0; Y < Height; Y++) - for (int X = 0; X < Width; X++) - { - long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - - long Tile0 = CpuMem.ReadInt64(Position + Offset + 0); - long Tile1 = CpuMem.ReadInt64(Position + Offset + 8); - - *(long*)(BuffPtr + OutOffs + 0) = Tile0; - *(long*)(BuffPtr + OutOffs + 8) = Tile1; - - OutOffs += 16; - } - } - - return Output; - } - - internal static byte[] Read16BptCompressedTexture4x4(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 4, 4); - } - - internal static byte[] Read16BptCompressedTexture5x5(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 5, 5); - } - - internal static byte[] Read16BptCompressedTexture6x6(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 6, 6); - } - - internal static byte[] Read16BptCompressedTexture8x8(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 8, 8); - } - - internal static byte[] Read16BptCompressedTexture10x10(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 10, 10); - } - - internal static byte[] Read16BptCompressedTexture12x12(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 12, 12); - } - - internal static byte[] Read16BptCompressedTexture5x4(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 5, 4); - } - - internal static byte[] Read16BptCompressedTexture6x5(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 6, 5); - } - - internal static byte[] Read16BptCompressedTexture8x6(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 8, 6); - } - - internal static byte[] Read16BptCompressedTexture10x8(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 10, 8); - } - - internal static byte[] Read16BptCompressedTexture12x10(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 12, 10); - } - - internal static byte[] Read16BptCompressedTexture8x5(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 5, 5); - } - - internal static byte[] Read16BptCompressedTexture10x5(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 10, 5); - } - - internal static byte[] Read16BptCompressedTexture10x6(IAMemory Memory, TextureInfo Texture) - { - return Read16BptCompressedTexture(Memory, Texture, 10, 6); - } - } -} diff --git a/Ryujinx.Graphics/Texture/TextureWriter.cs b/Ryujinx.Graphics/Texture/TextureWriter.cs deleted file mode 100644 index 16e78c56..00000000 --- a/Ryujinx.Graphics/Texture/TextureWriter.cs +++ /dev/null @@ -1,35 +0,0 @@ -using ChocolArm64.Memory; -using Ryujinx.Graphics.Gal; -using Ryujinx.Graphics.Memory; - -namespace Ryujinx.Graphics.Texture -{ - static class TextureWriter - { - public unsafe static void Write(IAMemory Memory, TextureInfo Texture, byte[] Data) - { - ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, 1, 4); - - (AMemory CpuMem, long Position) = TextureHelper.GetMemoryAndPosition( - Memory, - Texture.Position); - - fixed (byte* BuffPtr = Data) - { - long InOffs = 0; - - for (int Y = 0; Y < Texture.Height; Y++) - for (int X = 0; X < Texture.Width; X++) - { - long Offset = (uint)Swizzle.GetSwizzleOffset(X, Y); - - int Pixel = *(int*)(BuffPtr + InOffs); - - CpuMem.WriteInt32(Position + Offset, Pixel); - - InOffs += 4; - } - } - } - } -} |
