aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Core
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-05-29 20:37:10 -0300
committergdkchan <gab.dark.100@gmail.com>2018-05-29 20:37:10 -0300
commitf43dd080641b3c2508e35bc7651fb0adcb282a2e (patch)
tree9a4fb60454e558817a0eee9fd3bfe594e438d45f /Ryujinx.Core
parent9670c096e410add36314a247b77334c0c1d61256 (diff)
Added support for more shader instructions and texture formats, fix swapped channels in RGB565 and RGBA5551? texture formats, allow zero values on blending registers, initial work to build CFG on the shader decoder, update the BRA instruction to work with it (WIP)
Diffstat (limited to 'Ryujinx.Core')
-rw-r--r--Ryujinx.Core/Gpu/TextureReader.cs197
1 files changed, 189 insertions, 8 deletions
diff --git a/Ryujinx.Core/Gpu/TextureReader.cs b/Ryujinx.Core/Gpu/TextureReader.cs
index f3e41046..0c1c83d5 100644
--- a/Ryujinx.Core/Gpu/TextureReader.cs
+++ b/Ryujinx.Core/Gpu/TextureReader.cs
@@ -10,19 +10,132 @@ namespace Ryujinx.Core.Gpu
{
switch (Texture.Format)
{
- case GalTextureFormat.A8B8G8R8: return Read4Bpp (Memory, Texture);
- case GalTextureFormat.A1B5G5R5: return Read2Bpp (Memory, Texture);
- case GalTextureFormat.B5G6R5: return Read2Bpp (Memory, Texture);
- case GalTextureFormat.BC1: return Read8Bpt4x4 (Memory, Texture);
- case GalTextureFormat.BC2: return Read16Bpt4x4(Memory, Texture);
- case GalTextureFormat.BC3: return Read16Bpt4x4(Memory, Texture);
- case GalTextureFormat.BC4: return Read8Bpt4x4 (Memory, Texture);
- case GalTextureFormat.BC5: return Read16Bpt4x4(Memory, Texture);
+ case GalTextureFormat.R32G32B32A32: return Read16Bpp (Memory, Texture);
+ case GalTextureFormat.R16G16B16A16: return Read8Bpp (Memory, Texture);
+ case GalTextureFormat.A8B8G8R8: return Read4Bpp (Memory, Texture);
+ case GalTextureFormat.R32: return Read4Bpp (Memory, Texture);
+ case GalTextureFormat.A1B5G5R5: return Read5551 (Memory, Texture);
+ case GalTextureFormat.B5G6R5: return Read565 (Memory, Texture);
+ case GalTextureFormat.G8R8: return Read2Bpp (Memory, Texture);
+ case GalTextureFormat.R8: return Read1Bpp (Memory, Texture);
+ case GalTextureFormat.BC1: return Read8Bpt4x4 (Memory, Texture);
+ case GalTextureFormat.BC2: return Read16Bpt4x4(Memory, Texture);
+ case GalTextureFormat.BC3: return Read16Bpt4x4(Memory, Texture);
+ case GalTextureFormat.BC4: return Read8Bpt4x4 (Memory, Texture);
+ case GalTextureFormat.BC5: return Read16Bpt4x4(Memory, Texture);
}
throw new NotImplementedException(Texture.Format.ToString());
}
+ private unsafe static byte[] Read1Bpp(IAMemory Memory, Texture Texture)
+ {
+ int Width = Texture.Width;
+ int Height = Texture.Height;
+
+ byte[] Output = new byte[Width * Height];
+
+ ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 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.ReadByteUnchecked(Position + Offset);
+
+ *(BuffPtr + OutOffs) = Pixel;
+
+ OutOffs++;
+ }
+ }
+
+ return Output;
+ }
+
+ private unsafe static byte[] Read5551(IAMemory Memory, Texture Texture)
+ {
+ int Width = Texture.Width;
+ int Height = Texture.Height;
+
+ byte[] Output = new byte[Width * Height * 2];
+
+ ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 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.ReadInt16Unchecked(Position + Offset);
+
+ Pixel = (Pixel & 0x001f) << 11 |
+ (Pixel & 0x03e0) << 1 |
+ (Pixel & 0x7c00) >> 9 |
+ (Pixel & 0x8000) >> 15;
+
+ *(short*)(BuffPtr + OutOffs) = (short)Pixel;
+
+ OutOffs += 2;
+ }
+ }
+
+ return Output;
+ }
+
+ private unsafe static byte[] Read565(IAMemory Memory, Texture Texture)
+ {
+ int Width = Texture.Width;
+ int Height = Texture.Height;
+
+ byte[] Output = new byte[Width * Height * 2];
+
+ ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 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.ReadInt16Unchecked(Position + Offset);
+
+ Pixel = (Pixel & 0x001f) << 11 |
+ (Pixel & 0x07e0) |
+ (Pixel & 0xf800) >> 11;
+
+ *(short*)(BuffPtr + OutOffs) = (short)Pixel;
+
+ OutOffs += 2;
+ }
+ }
+
+ return Output;
+ }
+
private unsafe static byte[] Read2Bpp(IAMemory Memory, Texture Texture)
{
int Width = Texture.Width;
@@ -89,6 +202,74 @@ namespace Ryujinx.Core.Gpu
return Output;
}
+ private unsafe static byte[] Read8Bpp(IAMemory Memory, Texture Texture)
+ {
+ int Width = Texture.Width;
+ int Height = Texture.Height;
+
+ byte[] Output = new byte[Width * Height * 8];
+
+ ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 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.ReadInt64Unchecked(Position + Offset);
+
+ *(long*)(BuffPtr + OutOffs) = Pixel;
+
+ OutOffs += 8;
+ }
+ }
+
+ return Output;
+ }
+
+ private unsafe static byte[] Read16Bpp(IAMemory Memory, Texture Texture)
+ {
+ int Width = Texture.Width;
+ int Height = Texture.Height;
+
+ byte[] Output = new byte[Width * Height * 16];
+
+ ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 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.ReadInt64Unchecked(Position + Offset + 0);
+ long PxHigh = CpuMem.ReadInt64Unchecked(Position + Offset + 8);
+
+ *(long*)(BuffPtr + OutOffs + 0) = PxLow;
+ *(long*)(BuffPtr + OutOffs + 8) = PxHigh;
+
+ OutOffs += 16;
+ }
+ }
+
+ return Output;
+ }
+
private unsafe static byte[] Read8Bpt4x4(IAMemory Memory, Texture Texture)
{
int Width = (Texture.Width + 3) / 4;