diff --git a/Ryujinx.Graphics/Gal/GalTextureFormat.cs b/Ryujinx.Graphics/Gal/GalTextureFormat.cs index 5ab7be89b..ff5c08d38 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,8 @@ namespace Ryujinx.Graphics.Gal BC5 = 0x28, Z24S8 = 0x29, ZF32 = 0x2f, + ZF32_X24S8 = 0x30, + Z16 = 0x3a, Astc2D4x4 = 0x40, Astc2D5x5 = 0x41, Astc2D6x6 = 0x42, diff --git a/Ryujinx.Graphics/Gal/ImageFormatConverter.cs b/Ryujinx.Graphics/Gal/ImageFormatConverter.cs index 2d20a8a0e..ee76f4ce4 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; @@ -53,6 +55,8 @@ namespace Ryujinx.Graphics.Gal case GalTextureFormat.BC4: return GalImageFormat.BC4_UNORM_BLOCK; case GalTextureFormat.BC5: return GalImageFormat.BC5_UNORM_BLOCK; case GalTextureFormat.Z24S8: return GalImageFormat.D24_UNORM_S8_UINT; + case GalTextureFormat.ZF32_X24S8: return GalImageFormat.D32_SFLOAT_S8_UINT; + case GalTextureFormat.Z16: return GalImageFormat.D16_UNORM; case GalTextureFormat.Astc2D4x4: return GalImageFormat.ASTC_4x4_UNORM_BLOCK; case GalTextureFormat.Astc2D5x5: return GalImageFormat.ASTC_5x5_UNORM_BLOCK; case GalTextureFormat.Astc2D6x6: return GalImageFormat.ASTC_6x6_UNORM_BLOCK; @@ -74,7 +78,9 @@ namespace Ryujinx.Graphics.Gal switch (Format) { case GalTextureFormat.R32G32B32A32: return GalImageFormat.R32G32B32A32_SINT; + case GalTextureFormat.R32G32B32: return GalImageFormat.R32G32B32_SINT; case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_SINT; + case GalTextureFormat.R16G16: return GalImageFormat.R16G16_SINT; case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8_SINT_PACK32; case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10_SINT_PACK32; case GalTextureFormat.R32: return GalImageFormat.R32_SINT; @@ -88,7 +94,9 @@ namespace Ryujinx.Graphics.Gal switch (Format) { case GalTextureFormat.R32G32B32A32: return GalImageFormat.R32G32B32A32_UINT; + case GalTextureFormat.R32G32B32: return GalImageFormat.R32G32B32_UINT; case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_UINT; + case GalTextureFormat.R16G16: return GalImageFormat.R16G16_UINT; case GalTextureFormat.A8B8G8R8: return GalImageFormat.A8B8G8R8_UINT_PACK32; case GalTextureFormat.A2B10G10R10: return GalImageFormat.A2B10G10R10_UINT_PACK32; case GalTextureFormat.R32: return GalImageFormat.R32_UINT; @@ -110,7 +118,9 @@ namespace Ryujinx.Graphics.Gal switch (Format) { case GalTextureFormat.R32G32B32A32: return GalImageFormat.R32G32B32A32_SFLOAT; + case GalTextureFormat.R32G32B32: return GalImageFormat.R32G32B32_SFLOAT; case GalTextureFormat.R16G16B16A16: return GalImageFormat.R16G16B16A16_SFLOAT; + case GalTextureFormat.R16G16: return GalImageFormat.R16G16_SFLOAT; case GalTextureFormat.R32: return GalImageFormat.R32_SFLOAT; case GalTextureFormat.BC6H_SF16: return GalImageFormat.BC6H_SFLOAT_BLOCK; case GalTextureFormat.BC6H_UF16: return GalImageFormat.BC6H_UFLOAT_BLOCK; @@ -138,10 +148,15 @@ 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; case GalFrameBufferFormat.RG8Unorm: return GalImageFormat.R8G8_UNORM; + case GalFrameBufferFormat.BGRA8Unorm: return GalImageFormat.A8B8G8R8_UNORM_PACK32; + case GalFrameBufferFormat.BGRA8Srgb: return GalImageFormat.A8B8G8R8_SRGB_PACK32; } throw new NotImplementedException(Format.ToString()); @@ -151,9 +166,10 @@ namespace Ryujinx.Graphics.Gal { switch (Format) { - case GalZetaFormat.Z32Float: return GalImageFormat.D32_SFLOAT; - case GalZetaFormat.S8Z24Unorm: return GalImageFormat.D24_UNORM_S8_UINT; - case GalZetaFormat.Z16Unorm: return GalImageFormat.D16_UNORM; + case GalZetaFormat.Z32Float: return GalImageFormat.D32_SFLOAT; + case GalZetaFormat.S8Z24Unorm: return GalImageFormat.D24_UNORM_S8_UINT; + case GalZetaFormat.Z16Unorm: return GalImageFormat.D16_UNORM; + case GalZetaFormat.Z32S8X24Float: return GalImageFormat.D32_SFLOAT_S8_UINT; } throw new NotImplementedException(Format.ToString()); @@ -166,6 +182,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: @@ -185,10 +204,11 @@ namespace Ryujinx.Graphics.Gal case GalImageFormat.A1R5G5B5_UNORM_PACK16: case GalImageFormat.B5G6R5_UNORM_PACK16: case GalImageFormat.BC7_UNORM_BLOCK: - case GalImageFormat.R16G16_SFLOAT: - case GalImageFormat.R16G16_SINT: case GalImageFormat.R16G16_SNORM: case GalImageFormat.R16G16_UNORM: + case GalImageFormat.R16G16_SINT: + case GalImageFormat.R16G16_UINT: + case GalImageFormat.R16G16_SFLOAT: case GalImageFormat.R8G8_SINT: case GalImageFormat.R8G8_SNORM: case GalImageFormat.R8G8_UINT: @@ -228,6 +248,7 @@ namespace Ryujinx.Graphics.Gal case GalImageFormat.D24_UNORM_S8_UINT: case GalImageFormat.D32_SFLOAT: case GalImageFormat.D16_UNORM: + case GalImageFormat.D32_SFLOAT_S8_UINT: return true; } @@ -241,6 +262,7 @@ namespace Ryujinx.Graphics.Gal case GalImageFormat.D24_UNORM_S8_UINT: case GalImageFormat.D32_SFLOAT: case GalImageFormat.D16_UNORM: + case GalImageFormat.D32_SFLOAT_S8_UINT: return true; } @@ -254,6 +276,7 @@ namespace Ryujinx.Graphics.Gal switch (Format) { case GalImageFormat.D24_UNORM_S8_UINT: + case GalImageFormat.D32_SFLOAT_S8_UINT: return true; } diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index e04a59d44..3c447589a 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); @@ -168,9 +172,10 @@ namespace Ryujinx.Graphics.Gal.OpenGL case GalImageFormat.R4G4B4A4_UNORM_PACK16_REVERSED: return (PixelInternalFormat.Rgba4, PixelFormat.Rgba, PixelType.UnsignedShort4444Reversed); - case GalImageFormat.D24_UNORM_S8_UINT: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); - case GalImageFormat.D32_SFLOAT: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); - case GalImageFormat.D16_UNORM: return (PixelInternalFormat.DepthComponent16, PixelFormat.DepthComponent, PixelType.UnsignedShort); + case GalImageFormat.D24_UNORM_S8_UINT: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); + case GalImageFormat.D32_SFLOAT: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); + case GalImageFormat.D16_UNORM: return (PixelInternalFormat.DepthComponent16, PixelFormat.DepthComponent, PixelType.UnsignedShort); + case GalImageFormat.D32_SFLOAT_S8_UINT: return (PixelInternalFormat.Depth32fStencil8, PixelFormat.DepthStencil, PixelType.Float32UnsignedInt248Rev); } throw new NotImplementedException(Format.ToString()); diff --git a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs index 92b608a95..be24579c3 100644 --- a/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs +++ b/Ryujinx.HLE/Gpu/Texture/TextureHelper.cs @@ -39,11 +39,17 @@ 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: case GalImageFormat.R16G16B16A16_UINT: case GalImageFormat.R16G16B16A16_UNORM: + case GalImageFormat.D32_SFLOAT_S8_UINT: return Image.Width * Image.Height * 8; case GalImageFormat.A8B8G8R8_SINT_PACK32: diff --git a/Ryujinx.HLE/Gpu/Texture/TextureReader.cs b/Ryujinx.HLE/Gpu/Texture/TextureReader.cs index 19aa25d74..106369c9c 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,8 @@ 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.ZF32_X24S8: return Read8Bpp (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 +262,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;