aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Texture
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-09-18 01:30:35 -0300
committerGitHub <noreply@github.com>2018-09-18 01:30:35 -0300
commitd4187aaa9d7194aa26d04aee838edbc3a38f1862 (patch)
tree06fe725c1067b4aeca21749799b835d85e7d2787 /Ryujinx.Graphics/Texture
parentbec95cacc1061f91373a1e3a1411981af7fe2e4e (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.cs364
-rw-r--r--Ryujinx.Graphics/Texture/TextureFactory.cs52
-rw-r--r--Ryujinx.Graphics/Texture/TextureHelper.cs29
-rw-r--r--Ryujinx.Graphics/Texture/TextureInfo.cs60
-rw-r--r--Ryujinx.Graphics/Texture/TextureReader.cs398
-rw-r--r--Ryujinx.Graphics/Texture/TextureWriter.cs35
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;
- }
- }
- }
- }
-}