From 1d8eabe4da73d5cffa704326a7b10a840b912ce1 Mon Sep 17 00:00:00 2001 From: HorrorTroll Date: Thu, 23 Aug 2018 22:05:00 +0700 Subject: [PATCH] Add R32G32B32, R16G16, Z16 texture format --- Ryujinx.Graphics/Gal/GalTextureFormat.cs | 3 ++ Ryujinx.Graphics/Gal/ImageFormatConverter.cs | 12 ++++++ .../Gal/OpenGL/OGLEnumConverter.cs | 4 ++ Ryujinx.HLE/Gpu/Texture/TextureHelper.cs | 5 +++ Ryujinx.HLE/Gpu/Texture/TextureReader.cs | 38 +++++++++++++++++++ 5 files changed, 62 insertions(+) diff --git a/Ryujinx.Graphics/Gal/GalTextureFormat.cs b/Ryujinx.Graphics/Gal/GalTextureFormat.cs index 5ab7be89b2..8eb1a60e56 100644 --- a/Ryujinx.Graphics/Gal/GalTextureFormat.cs +++ b/Ryujinx.Graphics/Gal/GalTextureFormat.cs @@ -3,9 +3,11 @@ namespace Ryujinx.Graphics.Gal public enum GalTextureFormat { R32G32B32A32 = 0x1, + R32G32B32 = 0x2, R16G16B16A16 = 0x3, A8B8G8R8 = 0x8, A2B10G10R10 = 0x9, + R16G16 = 0xc, R32 = 0xf, BC6H_SF16 = 0x10, BC6H_UF16 = 0x11, @@ -24,6 +26,7 @@ namespace Ryujinx.Graphics.Gal BC5 = 0x28, Z24S8 = 0x29, ZF32 = 0x2f, + Z16 = 0x3a, Astc2D4x4 = 0x40, Astc2D5x5 = 0x41, Astc2D6x6 = 0x42, diff --git a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs index 2d20a8a0e0..ce21f4d85a 100644 --- a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs +++ b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs @@ -26,6 +26,7 @@ namespace Ryujinx.Graphics.Gal case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_SNORM; case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8_SNORM_PACK32; case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10_SNORM_PACK32; + case GalTextureFormat.R16G16: return GalImageFormat.R16G16_SNORM; case GalTextureFormat.G8R8: return GalImageFormat.R8G8_SNORM; case GalTextureFormat.R16: return GalImageFormat.R16_SNORM; case GalTextureFormat.R8: return GalImageFormat.R8_SNORM; @@ -40,6 +41,7 @@ namespace Ryujinx.Graphics.Gal case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_UNORM; case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8_UNORM_PACK32; case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10_UNORM_PACK32; + case GalTextureFormat.R16G16: return GalImageFormat.R16G16_UNORM; case GalTextureFormat.A4B4G4R4: return GalImageFormat.R4G4B4A4_UNORM_PACK16_REVERSED; case GalTextureFormat.A1B5G5R5: return GalImageFormat.A1R5G5B5_UNORM_PACK16; case GalTextureFormat.B5G6R5: return GalImageFormat.B5G6R5_UNORM_PACK16; @@ -77,6 +79,7 @@ namespace Ryujinx.Graphics.Gal case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_SINT; case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8_SINT_PACK32; case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10_SINT_PACK32; + case GalTextureFormat.R16G16: return GalImageFormat.R16G16_SINT; case GalTextureFormat.R32: return GalImageFormat.R32_SINT; case GalTextureFormat.G8R8: return GalImageFormat.R8G8_SINT; case GalTextureFormat.R16: return GalImageFormat.R16_SINT; @@ -91,6 +94,7 @@ namespace Ryujinx.Graphics.Gal case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_UINT; case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8_UINT_PACK32; case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10_UINT_PACK32; + case GalTextureFormat.R16G16: return GalImageFormat.R16G16_UINT; case GalTextureFormat.R32: return GalImageFormat.R32_UINT; case GalTextureFormat.G8R8: return GalImageFormat.R8G8_UINT; case GalTextureFormat.R16: return GalImageFormat.R16_UINT; @@ -112,6 +116,7 @@ namespace Ryujinx.Graphics.Gal case GalTextureFormat.R32G32B32A32: return GalImageFormat.R32G32B32A32_SFLOAT; case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_SFLOAT; case GalTextureFormat.R32: return GalImageFormat.R32_SFLOAT; + case GalTextureFormat.R16G16: return GalImageFormat.R16G16_SFLOAT; case GalTextureFormat.BC6H_SF16: return GalImageFormat.BC6H_SFLOAT_BLOCK; case GalTextureFormat.BC6H_UF16: return GalImageFormat.BC6H_UFLOAT_BLOCK; case GalTextureFormat.R16: return GalImageFormat.R16_SFLOAT; @@ -138,6 +143,9 @@ namespace Ryujinx.Graphics.Gal case GalFrameBufferFormat.R11G11B10Float: return GalImageFormat.B10G11R11_UFLOAT_PACK32; case GalFrameBufferFormat.RGBA32Float: return GalImageFormat.R32G32B32A32_SFLOAT; case GalFrameBufferFormat.RG16Snorm: return GalImageFormat.R16G16_SNORM; + case GalFrameBufferFormat.RG16Unorm: return GalImageFormat.R16G16_UNORM; + case GalFrameBufferFormat.RG16Sint: return GalImageFormat.R16G16_SINT; + case GalFrameBufferFormat.RG16Uint: return GalImageFormat.R16G16_UINT; case GalFrameBufferFormat.RG16Float: return GalImageFormat.R16G16_SFLOAT; case GalFrameBufferFormat.RG8Snorm: return GalImageFormat.R8_SNORM; case GalFrameBufferFormat.RGBA8Snorm: return GalImageFormat.A8B8G8R8_SNORM_PACK32; @@ -166,6 +174,9 @@ namespace Ryujinx.Graphics.Gal case GalImageFormat.R32G32B32A32_SFLOAT: case GalImageFormat.R32G32B32A32_SINT: case GalImageFormat.R32G32B32A32_UINT: + case GalImageFormat.R32G32B32_SFLOAT: + case GalImageFormat.R32G32B32_SINT: + case GalImageFormat.R32G32B32_UINT: case GalImageFormat.R16G16B16A16_SFLOAT: case GalImageFormat.R16G16B16A16_SINT: case GalImageFormat.R16G16B16A16_UINT: @@ -187,6 +198,7 @@ namespace Ryujinx.Graphics.Gal case GalImageFormat.BC7_UNORM_BLOCK: case GalImageFormat.R16G16_SFLOAT: case GalImageFormat.R16G16_SINT: + case GalImageFormat.R16G16_UINT: case GalImageFormat.R16G16_SNORM: case GalImageFormat.R16G16_UNORM: case GalImageFormat.R8G8_SINT: diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index e04a59d444..299d4ebc3c 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -132,6 +132,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL case GalImageFormat.R32G32B32A32_SFLOAT: return (PixelInternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float); case GalImageFormat.R32G32B32A32_SINT: return (PixelInternalFormat.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int); case GalImageFormat.R32G32B32A32_UINT: return (PixelInternalFormat.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt); + case GalImageFormat.R32G32B32_SFLOAT: return (PixelInternalFormat.Rgb32f, PixelFormat.Rgb, PixelType.Float); + case GalImageFormat.R32G32B32_SINT: return (PixelInternalFormat.Rgb32i, PixelFormat.RgbInteger, PixelType.Int); + case GalImageFormat.R32G32B32_UINT: return (PixelInternalFormat.Rgb32ui, PixelFormat.RgbInteger, PixelType.UnsignedInt); case GalImageFormat.R16G16B16A16_SFLOAT: return (PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.HalfFloat); case GalImageFormat.R16G16B16A16_SINT: return (PixelInternalFormat.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short); case GalImageFormat.R16G16B16A16_UINT: return (PixelInternalFormat.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort); @@ -149,6 +152,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL case GalImageFormat.B5G6R5_UNORM_PACK16: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565); case GalImageFormat.R16G16_SFLOAT: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.HalfFloat); case GalImageFormat.R16G16_SINT: return (PixelInternalFormat.Rg16i, PixelFormat.RgInteger, PixelType.Short); + case GalImageFormat.R16G16_UINT: return (PixelInternalFormat.Rg16ui, PixelFormat.RgInteger, PixelType.UnsignedShort); case GalImageFormat.R16G16_SNORM: return (PixelInternalFormat.Rg16Snorm, PixelFormat.Rg, PixelType.Byte); case GalImageFormat.R16G16_UNORM: return (PixelInternalFormat.Rg16, PixelFormat.Rg, PixelType.UnsignedShort); case GalImageFormat.R8G8_SINT: return (PixelInternalFormat.Rg8i, PixelFormat.RgInteger, PixelType.Byte); diff --git a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs index 92b608a952..52cbf33491 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs @@ -39,6 +39,11 @@ namespace Ryujinx.HLE.Gpu.Texture case GalImageFormat.R32G32B32A32_UINT: return Image.Width * Image.Height * 16; + case GalImageFormat.R32G32B32_SFLOAT: + case GalImageFormat.R32G32B32_SINT: + case GalImageFormat.R32G32B32_UINT: + return Image.Width * Image.Height * 12; + case GalImageFormat.R16G16B16A16_SFLOAT: case GalImageFormat.R16G16B16A16_SINT: case GalImageFormat.R16G16B16A16_SNORM: diff --git a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs index 19aa25d74d..7cd1696fe7 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs @@ -11,9 +11,11 @@ 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); + case GalTextureFormat.R16G16: return Read4Bpp (Memory, Texture); case GalTextureFormat.R32: return Read4Bpp (Memory, Texture); case GalTextureFormat.BF10GF11RF11: return Read4Bpp (Memory, Texture); case GalTextureFormat.Z24S8: return Read4Bpp (Memory, Texture); @@ -32,6 +34,7 @@ namespace Ryujinx.HLE.Gpu.Texture case GalTextureFormat.BC4: return Read8Bpt4x4 (Memory, Texture); case GalTextureFormat.BC5: return Read16BptCompressedTexture(Memory, Texture, 4, 4); case GalTextureFormat.ZF32: return Read4Bpp (Memory, Texture); + case GalTextureFormat.Z16: return Read2Bpp (Memory, Texture); case GalTextureFormat.Astc2D4x4: return Read16BptCompressedTexture(Memory, Texture, 4, 4); case GalTextureFormat.Astc2D5x5: return Read16BptCompressedTexture(Memory, Texture, 5, 5); case GalTextureFormat.Astc2D6x6: return Read16BptCompressedTexture(Memory, Texture, 6, 6); @@ -258,6 +261,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.ReadInt64(Position + Offset); + int PxHigh = CpuMem.ReadInt32(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;