diff --git a/Ryujinx.Graphics/Gal/GalTextureFormat.cs b/Ryujinx.Graphics/Gal/GalTextureFormat.cs index 7e3e65e82f..125dba9d7b 100644 --- a/Ryujinx.Graphics/Gal/GalTextureFormat.cs +++ b/Ryujinx.Graphics/Gal/GalTextureFormat.cs @@ -3,6 +3,7 @@ namespace Ryujinx.Graphics.Gal public enum GalTextureFormat { R32G32B32A32 = 0x1, + R32G32B32 = 0x2, R16G16B16A16 = 0x3, A8B8G8R8 = 0x8, A2B10G10R10 = 0x9, diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 3c42e5d387..9869c8b7b5 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -130,6 +130,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL switch (Format) { case GalTextureFormat.R32G32B32A32: return (PixelFormat.Rgba, PixelType.Float); + case GalTextureFormat.R32G32B32: return (PixelFormat.Rgb, PixelType.Float); case GalTextureFormat.R16G16B16A16: return (PixelFormat.Rgba, PixelType.HalfFloat); case GalTextureFormat.A8B8G8R8: return (PixelFormat.Rgba, PixelType.UnsignedByte); case GalTextureFormat.A2B10G10R10: return (PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); diff --git a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs index 10a64f3641..f3e77f41ec 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs @@ -37,6 +37,9 @@ namespace Ryujinx.HLE.Gpu.Texture case GalTextureFormat.R32G32B32A32: return Texture.Width * Texture.Height * 16; + case GalTextureFormat.R32G32B32: + return Texture.Width * Texture.Height * 12; + case GalTextureFormat.R16G16B16A16: return Texture.Width * Texture.Height * 8; diff --git a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs index 0cf055db8b..5474f06b8c 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs @@ -11,6 +11,7 @@ namespace Ryujinx.HLE.Gpu.Texture switch (Texture.Format) { case GalTextureFormat.R32G32B32A32: return Read16Bpp (Memory, Texture); + case GalTextureFormat.R32G32B32: return Read12Bpp (Memory, Texture); case GalTextureFormat.R16G16B16A16: return Read8Bpp (Memory, Texture); case GalTextureFormat.A8B8G8R8: return Read4Bpp (Memory, Texture); case GalTextureFormat.A2B10G10R10: return Read4Bpp (Memory, Texture); @@ -257,6 +258,41 @@ namespace Ryujinx.HLE.Gpu.Texture return Output; } + private unsafe static byte[] Read12Bpp(IAMemory Memory, TextureInfo Texture) + { + int Width = Texture.Width; + int Height = Texture.Height; + + byte[] Output = new byte[Width * Height * 12]; + + ISwizzle Swizzle = TextureHelper.GetSwizzle(Texture, Width, 12); + + (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); + int PxHigh = CpuMem.ReadInt32Unchecked(Position + Offset + 8); + + *(long*)(BuffPtr + OutOffs) = PxLow; + *(int*)(BuffPtr + OutOffs + 8) = PxHigh; + + OutOffs += 12; + } + } + + return Output; + } + private unsafe static byte[] Read16Bpp(IAMemory Memory, TextureInfo Texture) { int Width = Texture.Width;