diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-04-08 16:17:35 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-04-08 16:41:38 -0300 |
| commit | b9aa3966c00b4bb3ff0292dc28ed53ad26cf284b (patch) | |
| tree | cd2ab3d65c61ac6c6ceb312116e5d138868a3e18 /Ryujinx.Graphics/Gpu/TextureReader.cs | |
| parent | 7acd0e01226d64d05b2675f6ae07507039a31835 (diff) | |
Merge shader branch, adding support for GLSL decompilation, a macro
interpreter, and a rewrite of the GPU code.
Diffstat (limited to 'Ryujinx.Graphics/Gpu/TextureReader.cs')
| -rw-r--r-- | Ryujinx.Graphics/Gpu/TextureReader.cs | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/Ryujinx.Graphics/Gpu/TextureReader.cs b/Ryujinx.Graphics/Gpu/TextureReader.cs new file mode 100644 index 00000000..ce66e991 --- /dev/null +++ b/Ryujinx.Graphics/Gpu/TextureReader.cs @@ -0,0 +1,127 @@ +using ChocolArm64.Memory; +using Ryujinx.Graphics.Gal; +using System; + +namespace Ryujinx.Graphics.Gpu +{ + static class TextureReader + { + public static byte[] Read(AMemory Memory, Texture Texture) + { + switch (Texture.Format) + { + case GalTextureFormat.A8B8G8R8: return Read4Bpp (Memory, Texture); + case GalTextureFormat.BC1: return Read8Bpt4x4 (Memory, Texture); + case GalTextureFormat.BC2: return Read16Bpt4x4(Memory, Texture); + case GalTextureFormat.BC3: return Read16Bpt4x4(Memory, Texture); + } + + throw new NotImplementedException(Texture.Format.ToString()); + } + + private unsafe static byte[] Read4Bpp(AMemory Memory, Texture Texture) + { + int Width = Texture.Width; + int Height = Texture.Height; + + byte[] Output = new byte[Width * Height * 4]; + + ISwizzle Swizzle = GetSwizzle(Texture.Swizzle, Width, 4, Texture.BlockHeight); + + 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 = Memory.ReadInt32Unchecked(Texture.Position + Offset); + + *(int*)(BuffPtr + OutOffs) = Pixel; + + OutOffs += 4; + } + } + + return Output; + } + + private unsafe static byte[] Read8Bpt4x4(AMemory Memory, Texture Texture) + { + int Width = (Texture.Width + 3) / 4; + int Height = (Texture.Height + 3) / 4; + + byte[] Output = new byte[Width * Height * 8]; + + ISwizzle Swizzle = GetSwizzle(Texture.Swizzle, Width, 8, Texture.BlockHeight); + + 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 = Memory.ReadInt64Unchecked(Texture.Position + Offset); + + *(long*)(BuffPtr + OutOffs) = Tile; + + OutOffs += 8; + } + } + + return Output; + } + + private unsafe static byte[] Read16Bpt4x4(AMemory Memory, Texture Texture) + { + int Width = (Texture.Width + 3) / 4; + int Height = (Texture.Height + 3) / 4; + + byte[] Output = new byte[Width * Height * 16]; + + ISwizzle Swizzle = GetSwizzle(Texture.Swizzle, Width, 16, Texture.BlockHeight); + + 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 = Memory.ReadInt64Unchecked(Texture.Position + Offset + 0); + long Tile1 = Memory.ReadInt64Unchecked(Texture.Position + Offset + 8); + + *(long*)(BuffPtr + OutOffs + 0) = Tile0; + *(long*)(BuffPtr + OutOffs + 8) = Tile1; + + OutOffs += 16; + } + } + + return Output; + } + + private static ISwizzle GetSwizzle(TextureSwizzle Swizzle, int Width, int Bpp, int BlockHeight) + { + switch (Swizzle) + { + case TextureSwizzle.Pitch: + case TextureSwizzle.PitchColorKey: + return new LinearSwizzle(Width, Bpp); + + case TextureSwizzle.BlockLinear: + case TextureSwizzle.BlockLinearColorKey: + return new BlockLinearSwizzle(Width, Bpp, BlockHeight); + } + + throw new NotImplementedException(Swizzle.ToString()); + } + } +}
\ No newline at end of file |
