aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gpu/TextureReader.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-04-08 16:17:35 -0300
committergdkchan <gab.dark.100@gmail.com>2018-04-08 16:41:38 -0300
commitb9aa3966c00b4bb3ff0292dc28ed53ad26cf284b (patch)
treecd2ab3d65c61ac6c6ceb312116e5d138868a3e18 /Ryujinx.Graphics/Gpu/TextureReader.cs
parent7acd0e01226d64d05b2675f6ae07507039a31835 (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.cs127
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