From f43dd080641b3c2508e35bc7651fb0adcb282a2e Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 29 May 2018 20:37:10 -0300 Subject: 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) --- Ryujinx.Core/Gpu/TextureReader.cs | 197 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 189 insertions(+), 8 deletions(-) (limited to 'Ryujinx.Core') 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; -- cgit v1.2.3