From 0e1e094b7a8f0134831fc4cebdb0841b9c10fe6a Mon Sep 17 00:00:00 2001 From: gdkchan Date: Wed, 17 Oct 2018 18:02:23 -0300 Subject: [PATCH] Improve texture tables (#457) * Improve texture tables * More renaming and other tweaks * Minor tweaks --- Ryujinx.Graphics/Gal/GalImageFormat.cs | 120 +++----- Ryujinx.Graphics/Gal/GalPipelineState.cs | 29 +- Ryujinx.Graphics/Gal/GalTextureFormat.cs | 80 ++--- Ryujinx.Graphics/Gal/GalZetaFormat.cs | 20 +- Ryujinx.Graphics/Gal/IGalPipeline.cs | 3 + Ryujinx.Graphics/Gal/IGalRasterizer.cs | 5 +- .../Gal/OpenGL/OGLEnumConverter.cs | 119 ++++---- Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs | 38 ++- Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs | 26 +- .../Gal/OpenGL/OGLRenderTarget.cs | 13 +- Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs | 21 +- Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs | 75 ++--- Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs | 4 +- Ryujinx.Graphics/Gal/ShaderDumper.cs | 14 +- Ryujinx.Graphics/NvGpuEngine3d.cs | 47 +-- Ryujinx.Graphics/NvGpuEngine3dReg.cs | 3 +- Ryujinx.Graphics/Texture/ImageConverter.cs | 24 -- Ryujinx.Graphics/Texture/ImageUtils.cs | 275 +++++++++--------- Ryujinx.Graphics/Texture/TextureFactory.cs | 4 +- Ryujinx.HLE/HOS/Services/Vi/NvFlinger.cs | 2 +- 20 files changed, 445 insertions(+), 477 deletions(-) delete mode 100644 Ryujinx.Graphics/Texture/ImageConverter.cs diff --git a/Ryujinx.Graphics/Gal/GalImageFormat.cs b/Ryujinx.Graphics/Gal/GalImageFormat.cs index ba555684f..2712cbc25 100644 --- a/Ryujinx.Graphics/Gal/GalImageFormat.cs +++ b/Ryujinx.Graphics/Gal/GalImageFormat.cs @@ -5,89 +5,61 @@ namespace Ryujinx.Graphics.Gal [Flags] public enum GalImageFormat { - Snorm = 1 << 27, - Unorm = 1 << 28, - Sint = 1 << 29, - Uint = 1 << 30, - Sfloat = 1 << 31, + Astc2DStart, + Astc2D4x4, + Astc2D5x4, + Astc2D5x5, + Astc2D6x5, + Astc2D6x6, + Astc2D8x5, + Astc2D8x6, + Astc2D8x8, + Astc2D10x5, + Astc2D10x6, + Astc2D10x8, + Astc2D10x10, + Astc2D12x10, + Astc2D12x12, + Astc2DEnd, - TypeMask = Snorm | Unorm | Sint | Uint | Sfloat, - - FormatMask = ~TypeMask, - - ASTC_BEGIN = ASTC_4x4, - - ASTC_4x4 = 1, - ASTC_5x4, - ASTC_5x5, - ASTC_6x5, - ASTC_6x6, - ASTC_8x5, - ASTC_8x6, - ASTC_8x8, - ASTC_10x5, - ASTC_10x6, - ASTC_10x8, - ASTC_10x10, - ASTC_12x10, - ASTC_12x12, - - ASTC_END = ASTC_12x12, - - R4G4, - R4G4B4A4, - B4G4R4A4, - A4B4G4R4, - R5G6B5, - B5G6R5, - R5G5B5A1, - B5G5R5A1, - A1R5G5B5, + RGBA4, + RGB565, + BGR5A1, + RGB5A1, R8, - R8G8, - G8R8, - R8G8B8, - B8G8R8, - R8G8B8A8, - B8G8R8A8, - A8B8G8R8, - A8B8G8R8_SRGB, - A2R10G10B10, - A2B10G10R10, + RG8, + RGBA8, + BGRA8, + RGB10A2, R16, - R16G16, - R16G16B16, - R16G16B16A16, + RG16, + RGBA16, R32, - R32G32, - R32G32B32, - R32G32B32A32, - R64, - R64G64, - R64G64B64, - R64G64B64A64, - B10G11R11, - E5B9G9R9, + RG32, + RGBA32, + R11G11B10, D16, - X8_D24, D32, - S8, - D16_S8, - D24_S8, - D32_S8, - BC1_RGB, - BC1_RGBA, + D24S8, + D32S8, + BC1, BC2, BC3, BC4, BC5, - BC6H_SF16, - BC6H_UF16, - BC7, - ETC2_R8G8B8, - ETC2_R8G8B8A1, - ETC2_R8G8B8A8, - EAC_R11, - EAC_R11G11, + BptcSfloat, + BptcUfloat, + BptcUnorm, + + Snorm = 1 << 26, + Unorm = 1 << 27, + Sint = 1 << 28, + Uint = 1 << 39, + Float = 1 << 30, + Srgb = 1 << 31, + + TypeMask = Snorm | Unorm | Sint | Uint | Float | Srgb, + + FormatMask = ~TypeMask } } \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalPipelineState.cs b/Ryujinx.Graphics/Gal/GalPipelineState.cs index 1bfe2684f..56b0fbde3 100644 --- a/Ryujinx.Graphics/Gal/GalPipelineState.cs +++ b/Ryujinx.Graphics/Gal/GalPipelineState.cs @@ -1,9 +1,28 @@ namespace Ryujinx.Graphics.Gal { + public struct ColorMaskRgba + { + private static readonly ColorMaskRgba _Default = new ColorMaskRgba() + { + Red = true, + Green = true, + Blue = true, + Alpha = true + }; + + public static ColorMaskRgba Default => _Default; + + public bool Red; + public bool Green; + public bool Blue; + public bool Alpha; + } + public class GalPipelineState { - public const int Stages = 5; + public const int Stages = 5; public const int ConstBuffersPerStage = 18; + public const int RenderTargetsCount = 8; public long[][] ConstBufferKeys; @@ -53,10 +72,8 @@ public GalBlendFactor BlendFuncSrcAlpha; public GalBlendFactor BlendFuncDstAlpha; - public bool ColorMaskR; - public bool ColorMaskG; - public bool ColorMaskB; - public bool ColorMaskA; + public ColorMaskRgba ColorMask; + public ColorMaskRgba[] ColorMasks; public bool PrimitiveRestartEnabled; public uint PrimitiveRestartIndex; @@ -69,6 +86,8 @@ { ConstBufferKeys[Stage] = new long[ConstBuffersPerStage]; } + + ColorMasks = new ColorMaskRgba[RenderTargetsCount]; } } } \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/GalTextureFormat.cs b/Ryujinx.Graphics/Gal/GalTextureFormat.cs index 5ad769437..51ce57797 100644 --- a/Ryujinx.Graphics/Gal/GalTextureFormat.cs +++ b/Ryujinx.Graphics/Gal/GalTextureFormat.cs @@ -2,45 +2,45 @@ namespace Ryujinx.Graphics.Gal { public enum GalTextureFormat { - R32G32B32A32 = 0x1, - R16G16B16A16 = 0x3, - R32G32 = 0x4, - A8B8G8R8 = 0x8, - A2B10G10R10 = 0x9, - R16G16 = 0xc, - R32 = 0xf, - BC6H_SF16 = 0x10, - BC6H_UF16 = 0x11, - A4B4G4R4 = 0x12, - A1B5G5R5 = 0x14, - B5G6R5 = 0x15, - BC7U = 0x17, - G8R8 = 0x18, - R16 = 0x1b, - R8 = 0x1d, - BF10GF11RF11 = 0x21, - BC1 = 0x24, - BC2 = 0x25, - BC3 = 0x26, - BC4 = 0x27, - BC5 = 0x28, - Z24S8 = 0x29, - ZF32 = 0x2f, - ZF32_X24S8 = 0x30, - Z16 = 0x3a, - Astc2D4x4 = 0x40, - Astc2D5x5 = 0x41, - Astc2D6x6 = 0x42, - Astc2D8x8 = 0x44, - Astc2D10x10 = 0x45, - Astc2D12x12 = 0x46, - Astc2D5x4 = 0x50, - Astc2D6x5 = 0x51, - Astc2D8x6 = 0x52, - Astc2D10x8 = 0x53, - Astc2D12x10 = 0x54, - Astc2D8x5 = 0x55, - Astc2D10x5 = 0x56, - Astc2D10x6 = 0x57 + RGBA32 = 0x1, + RGBA16 = 0x3, + RG32 = 0x4, + RGBA8 = 0x8, + RGB10A2 = 0x9, + RG16 = 0xc, + R32 = 0xf, + BptcSfloat = 0x10, + BptcUfloat = 0x11, + RGBA4 = 0x12, + RGB5A1 = 0x14, + RGB565 = 0x15, + BptcUnorm = 0x17, + RG8 = 0x18, + R16 = 0x1b, + R8 = 0x1d, + R11G11B10F = 0x21, + BC1 = 0x24, + BC2 = 0x25, + BC3 = 0x26, + BC4 = 0x27, + BC5 = 0x28, + D24S8 = 0x29, + D32F = 0x2f, + D32FX24S8 = 0x30, + D16 = 0x3a, + Astc2D4x4 = 0x40, + Astc2D5x5 = 0x41, + Astc2D6x6 = 0x42, + Astc2D8x8 = 0x44, + Astc2D10x10 = 0x45, + Astc2D12x12 = 0x46, + Astc2D5x4 = 0x50, + Astc2D6x5 = 0x51, + Astc2D8x6 = 0x52, + Astc2D10x8 = 0x53, + Astc2D12x10 = 0x54, + Astc2D8x5 = 0x55, + Astc2D10x5 = 0x56, + Astc2D10x6 = 0x57 } } diff --git a/Ryujinx.Graphics/Gal/GalZetaFormat.cs b/Ryujinx.Graphics/Gal/GalZetaFormat.cs index 759e31217..2429249e5 100644 --- a/Ryujinx.Graphics/Gal/GalZetaFormat.cs +++ b/Ryujinx.Graphics/Gal/GalZetaFormat.cs @@ -2,15 +2,15 @@ { public enum GalZetaFormat { - Z32Float = 0x0a, - Z16Unorm = 0x13, - S8Z24Unorm = 0x14, - Z24X8Unorm = 0x15, - Z24S8Unorm = 0x16, - Z24C8Unorm = 0x18, - Z32S8X24Float = 0x19, - Z24X8S8C8X16Unorm = 0x1d, - Z32X8C8X16Float = 0x1e, - Z32S8C8X16Float = 0x1f + D32Float = 0x0a, + D16Unorm = 0x13, + S8D24Unorm = 0x14, + D24X8Unorm = 0x15, + D24S8Unorm = 0x16, + D24C8Unorm = 0x18, + D32S8X24Float = 0x19, + D24X8S8C8X16Unorm = 0x1d, + D32X8C8X16Float = 0x1e, + D32S8C8X16Float = 0x1f } } \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalPipeline.cs b/Ryujinx.Graphics/Gal/IGalPipeline.cs index d8cf266af..cba4e7dcc 100644 --- a/Ryujinx.Graphics/Gal/IGalPipeline.cs +++ b/Ryujinx.Graphics/Gal/IGalPipeline.cs @@ -3,5 +3,8 @@ public interface IGalPipeline { void Bind(GalPipelineState State); + + void ResetDepthMask(); + void ResetColorMask(int Index); } } \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/IGalRasterizer.cs b/Ryujinx.Graphics/Gal/IGalRasterizer.cs index 1572efa8f..052e3f35f 100644 --- a/Ryujinx.Graphics/Gal/IGalRasterizer.cs +++ b/Ryujinx.Graphics/Gal/IGalRasterizer.cs @@ -10,7 +10,10 @@ namespace Ryujinx.Graphics.Gal void ClearBuffers( GalClearBufferFlags Flags, int Attachment, - float Red, float Green, float Blue, float Alpha, + float Red, + float Green, + float Blue, + float Alpha, float Depth, int Stencil); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs index 9a3a1a98f..6b3d4fd69 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLEnumConverter.cs @@ -127,55 +127,54 @@ namespace Ryujinx.Graphics.Gal.OpenGL { switch (Format) { - case GalImageFormat.R32G32B32A32 | GalImageFormat.Sfloat: return (PixelInternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float); - case GalImageFormat.R32G32B32A32 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int); - case GalImageFormat.R32G32B32A32 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt); - case GalImageFormat.R16G16B16A16 | GalImageFormat.Sfloat: return (PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.HalfFloat); - case GalImageFormat.R16G16B16A16 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short); - case GalImageFormat.R16G16B16A16 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort); - case GalImageFormat.R32G32 | GalImageFormat.Sfloat: return (PixelInternalFormat.Rg32f, PixelFormat.Rg, PixelType.Float); - case GalImageFormat.R32G32 | GalImageFormat.Sint: return (PixelInternalFormat.Rg32i, PixelFormat.RgInteger, PixelType.Int); - case GalImageFormat.R32G32 | GalImageFormat.Uint: return (PixelInternalFormat.Rg32ui, PixelFormat.RgInteger, PixelType.UnsignedInt); - case GalImageFormat.A8B8G8R8 | GalImageFormat.Snorm: return (PixelInternalFormat.Rgba8Snorm, PixelFormat.Rgba, PixelType.Byte); - case GalImageFormat.A8B8G8R8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte); - case GalImageFormat.A8B8G8R8 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba8i, PixelFormat.RgbaInteger, PixelType.Byte); - case GalImageFormat.A8B8G8R8 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba8ui, PixelFormat.RgbaInteger, PixelType.UnsignedByte); - case GalImageFormat.A8B8G8R8_SRGB: return (PixelInternalFormat.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte); - case GalImageFormat.B8G8R8A8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba8, PixelFormat.Bgra, PixelType.UnsignedByte); - case GalImageFormat.A4B4G4R4 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba4, PixelFormat.Rgba, PixelType.UnsignedShort4444Reversed); - case GalImageFormat.A2B10G10R10 | GalImageFormat.Uint: return (PixelInternalFormat.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed); - case GalImageFormat.A2B10G10R10 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); - case GalImageFormat.R32 | GalImageFormat.Sfloat: return (PixelInternalFormat.R32f, PixelFormat.Red, PixelType.Float); - case GalImageFormat.R32 | GalImageFormat.Sint: return (PixelInternalFormat.R32i, PixelFormat.Red, PixelType.Int); - case GalImageFormat.R32 | GalImageFormat.Uint: return (PixelInternalFormat.R32ui, PixelFormat.Red, PixelType.UnsignedInt); - case GalImageFormat.A1R5G5B5 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort1555Reversed); - case GalImageFormat.B5G6R5 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565Reversed); - case GalImageFormat.R16G16 | GalImageFormat.Sfloat: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.HalfFloat); - case GalImageFormat.R16G16 | GalImageFormat.Sint: return (PixelInternalFormat.Rg16i, PixelFormat.RgInteger, PixelType.Short); - case GalImageFormat.R16G16 | GalImageFormat.Snorm: return (PixelInternalFormat.Rg16Snorm, PixelFormat.Rg, PixelType.Byte); - case GalImageFormat.R16G16 | GalImageFormat.Unorm: return (PixelInternalFormat.Rg16, PixelFormat.Rg, PixelType.UnsignedShort); - case GalImageFormat.R8G8 | GalImageFormat.Sint: return (PixelInternalFormat.Rg8i, PixelFormat.RgInteger, PixelType.Byte); - case GalImageFormat.R8G8 | GalImageFormat.Snorm: return (PixelInternalFormat.Rg8Snorm, PixelFormat.Rg, PixelType.Byte); - case GalImageFormat.R8G8 | GalImageFormat.Uint: return (PixelInternalFormat.Rg8ui, PixelFormat.RgInteger, PixelType.UnsignedByte); - case GalImageFormat.R8G8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rg8, PixelFormat.Rg, PixelType.UnsignedByte); - case GalImageFormat.G8R8 | GalImageFormat.Snorm: return (PixelInternalFormat.Rg8Snorm, PixelFormat.Rg, PixelType.Byte); - case GalImageFormat.G8R8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rg8, PixelFormat.Rg, PixelType.UnsignedByte); - case GalImageFormat.R16 | GalImageFormat.Sfloat: return (PixelInternalFormat.R16f, PixelFormat.Red, PixelType.HalfFloat); - case GalImageFormat.R16 | GalImageFormat.Sint: return (PixelInternalFormat.R16i, PixelFormat.RedInteger, PixelType.Short); - case GalImageFormat.R16 | GalImageFormat.Snorm: return (PixelInternalFormat.R16Snorm, PixelFormat.Red, PixelType.Byte); - case GalImageFormat.R16 | GalImageFormat.Uint: return (PixelInternalFormat.R16ui, PixelFormat.RedInteger, PixelType.UnsignedShort); - case GalImageFormat.R16 | GalImageFormat.Unorm: return (PixelInternalFormat.R16, PixelFormat.Red, PixelType.UnsignedShort); - case GalImageFormat.R8 | GalImageFormat.Sint: return (PixelInternalFormat.R8i, PixelFormat.RedInteger, PixelType.Byte); - case GalImageFormat.R8 | GalImageFormat.Snorm: return (PixelInternalFormat.R8Snorm, PixelFormat.Red, PixelType.Byte); - case GalImageFormat.R8 | GalImageFormat.Uint: return (PixelInternalFormat.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte); - case GalImageFormat.R8 | GalImageFormat.Unorm: return (PixelInternalFormat.R8, PixelFormat.Red, PixelType.UnsignedByte); - case GalImageFormat.B10G11R11 | GalImageFormat.Sfloat: return (PixelInternalFormat.R11fG11fB10f, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); + case GalImageFormat.RGBA32 | GalImageFormat.Float: return (PixelInternalFormat.Rgba32f, PixelFormat.Rgba, PixelType.Float); + case GalImageFormat.RGBA32 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba32i, PixelFormat.RgbaInteger, PixelType.Int); + case GalImageFormat.RGBA32 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba32ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt); + case GalImageFormat.RGBA16 | GalImageFormat.Float: return (PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.HalfFloat); + case GalImageFormat.RGBA16 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba16i, PixelFormat.RgbaInteger, PixelType.Short); + case GalImageFormat.RGBA16 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba16ui, PixelFormat.RgbaInteger, PixelType.UnsignedShort); + case GalImageFormat.RG32 | GalImageFormat.Float: return (PixelInternalFormat.Rg32f, PixelFormat.Rg, PixelType.Float); + case GalImageFormat.RG32 | GalImageFormat.Sint: return (PixelInternalFormat.Rg32i, PixelFormat.RgInteger, PixelType.Int); + case GalImageFormat.RG32 | GalImageFormat.Uint: return (PixelInternalFormat.Rg32ui, PixelFormat.RgInteger, PixelType.UnsignedInt); + case GalImageFormat.RGBA8 | GalImageFormat.Snorm: return (PixelInternalFormat.Rgba8Snorm, PixelFormat.Rgba, PixelType.Byte); + case GalImageFormat.RGBA8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba8, PixelFormat.Rgba, PixelType.UnsignedByte); + case GalImageFormat.RGBA8 | GalImageFormat.Sint: return (PixelInternalFormat.Rgba8i, PixelFormat.RgbaInteger, PixelType.Byte); + case GalImageFormat.RGBA8 | GalImageFormat.Uint: return (PixelInternalFormat.Rgba8ui, PixelFormat.RgbaInteger, PixelType.UnsignedByte); + case GalImageFormat.RGBA8 | GalImageFormat.Srgb: return (PixelInternalFormat.Srgb8Alpha8, PixelFormat.Rgba, PixelType.UnsignedByte); + case GalImageFormat.BGRA8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba8, PixelFormat.Bgra, PixelType.UnsignedByte); + case GalImageFormat.RGBA4 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba4, PixelFormat.Rgba, PixelType.UnsignedShort4444Reversed); + case GalImageFormat.RGB10A2 | GalImageFormat.Uint: return (PixelInternalFormat.Rgb10A2ui, PixelFormat.RgbaInteger, PixelType.UnsignedInt2101010Reversed); + case GalImageFormat.RGB10A2 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb10A2, PixelFormat.Rgba, PixelType.UnsignedInt2101010Reversed); + case GalImageFormat.R32 | GalImageFormat.Float: return (PixelInternalFormat.R32f, PixelFormat.Red, PixelType.Float); + case GalImageFormat.R32 | GalImageFormat.Sint: return (PixelInternalFormat.R32i, PixelFormat.Red, PixelType.Int); + case GalImageFormat.R32 | GalImageFormat.Uint: return (PixelInternalFormat.R32ui, PixelFormat.Red, PixelType.UnsignedInt); + case GalImageFormat.RGB5A1 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgb5A1, PixelFormat.Rgba, PixelType.UnsignedShort1555Reversed); + case GalImageFormat.RGB565 | GalImageFormat.Unorm: return (PixelInternalFormat.Rgba, PixelFormat.Rgb, PixelType.UnsignedShort565Reversed); + case GalImageFormat.RG16 | GalImageFormat.Float: return (PixelInternalFormat.Rg16f, PixelFormat.Rg, PixelType.HalfFloat); + case GalImageFormat.RG16 | GalImageFormat.Sint: return (PixelInternalFormat.Rg16i, PixelFormat.RgInteger, PixelType.Short); + case GalImageFormat.RG16 | GalImageFormat.Snorm: return (PixelInternalFormat.Rg16Snorm, PixelFormat.Rg, PixelType.Short); + case GalImageFormat.RG16 | GalImageFormat.Uint: return (PixelInternalFormat.Rg16ui, PixelFormat.RgInteger, PixelType.UnsignedShort); + case GalImageFormat.RG16 | GalImageFormat.Unorm: return (PixelInternalFormat.Rg16, PixelFormat.Rg, PixelType.UnsignedShort); + case GalImageFormat.RG8 | GalImageFormat.Sint: return (PixelInternalFormat.Rg8i, PixelFormat.RgInteger, PixelType.Byte); + case GalImageFormat.RG8 | GalImageFormat.Snorm: return (PixelInternalFormat.Rg8Snorm, PixelFormat.Rg, PixelType.Byte); + case GalImageFormat.RG8 | GalImageFormat.Uint: return (PixelInternalFormat.Rg8ui, PixelFormat.RgInteger, PixelType.UnsignedByte); + case GalImageFormat.RG8 | GalImageFormat.Unorm: return (PixelInternalFormat.Rg8, PixelFormat.Rg, PixelType.UnsignedByte); + case GalImageFormat.R16 | GalImageFormat.Float: return (PixelInternalFormat.R16f, PixelFormat.Red, PixelType.HalfFloat); + case GalImageFormat.R16 | GalImageFormat.Sint: return (PixelInternalFormat.R16i, PixelFormat.RedInteger, PixelType.Short); + case GalImageFormat.R16 | GalImageFormat.Snorm: return (PixelInternalFormat.R16Snorm, PixelFormat.Red, PixelType.Short); + case GalImageFormat.R16 | GalImageFormat.Uint: return (PixelInternalFormat.R16ui, PixelFormat.RedInteger, PixelType.UnsignedShort); + case GalImageFormat.R16 | GalImageFormat.Unorm: return (PixelInternalFormat.R16, PixelFormat.Red, PixelType.UnsignedShort); + case GalImageFormat.R8 | GalImageFormat.Sint: return (PixelInternalFormat.R8i, PixelFormat.RedInteger, PixelType.Byte); + case GalImageFormat.R8 | GalImageFormat.Snorm: return (PixelInternalFormat.R8Snorm, PixelFormat.Red, PixelType.Byte); + case GalImageFormat.R8 | GalImageFormat.Uint: return (PixelInternalFormat.R8ui, PixelFormat.RedInteger, PixelType.UnsignedByte); + case GalImageFormat.R8 | GalImageFormat.Unorm: return (PixelInternalFormat.R8, PixelFormat.Red, PixelType.UnsignedByte); + case GalImageFormat.R11G11B10 | GalImageFormat.Float: return (PixelInternalFormat.R11fG11fB10f, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev); - case GalImageFormat.D24_S8 | GalImageFormat.Uint: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); - case GalImageFormat.D24_S8 | GalImageFormat.Unorm: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); - case GalImageFormat.D32 | GalImageFormat.Sfloat: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); - case GalImageFormat.D16 | GalImageFormat.Unorm: return (PixelInternalFormat.DepthComponent16, PixelFormat.DepthComponent, PixelType.UnsignedShort); - case GalImageFormat.D32_S8 | GalImageFormat.Sfloat: return (PixelInternalFormat.Depth32fStencil8, PixelFormat.DepthStencil, PixelType.Float32UnsignedInt248Rev); + case GalImageFormat.D24S8 | GalImageFormat.Uint: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); + case GalImageFormat.D24S8 | GalImageFormat.Unorm: return (PixelInternalFormat.Depth24Stencil8, PixelFormat.DepthStencil, PixelType.UnsignedInt248); + case GalImageFormat.D32 | GalImageFormat.Float: return (PixelInternalFormat.DepthComponent32f, PixelFormat.DepthComponent, PixelType.Float); + case GalImageFormat.D16 | GalImageFormat.Unorm: return (PixelInternalFormat.DepthComponent16, PixelFormat.DepthComponent, PixelType.UnsignedShort); + case GalImageFormat.D32S8 | GalImageFormat.Float: return (PixelInternalFormat.Depth32fStencil8, PixelFormat.DepthStencil, PixelType.Float32UnsignedInt248Rev); } throw new NotImplementedException($"{Format & GalImageFormat.FormatMask} {Format & GalImageFormat.TypeMask}"); @@ -185,16 +184,20 @@ namespace Ryujinx.Graphics.Gal.OpenGL { switch (Format) { - case GalImageFormat.BC6H_UF16 | GalImageFormat.Sfloat: return InternalFormat.CompressedRgbBptcUnsignedFloat; - case GalImageFormat.BC6H_SF16 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbBptcSignedFloat; - case GalImageFormat.BC7 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaBptcUnorm; - case GalImageFormat.BC1_RGBA | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt1Ext; - case GalImageFormat.BC2 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt3Ext; - case GalImageFormat.BC3 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt5Ext; - case GalImageFormat.BC4 | GalImageFormat.Snorm: return InternalFormat.CompressedSignedRedRgtc1; - case GalImageFormat.BC4 | GalImageFormat.Unorm: return InternalFormat.CompressedRedRgtc1; - case GalImageFormat.BC5 | GalImageFormat.Snorm: return InternalFormat.CompressedSignedRgRgtc2; - case GalImageFormat.BC5 | GalImageFormat.Unorm: return InternalFormat.CompressedRgRgtc2; + case GalImageFormat.BptcSfloat | GalImageFormat.Float: return InternalFormat.CompressedRgbBptcSignedFloat; + case GalImageFormat.BptcUfloat | GalImageFormat.Float: return InternalFormat.CompressedRgbBptcUnsignedFloat; + case GalImageFormat.BptcUnorm | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaBptcUnorm; + case GalImageFormat.BptcUnorm | GalImageFormat.Srgb: return InternalFormat.CompressedSrgbAlphaBptcUnorm; + case GalImageFormat.BC1 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt1Ext; + case GalImageFormat.BC1 | GalImageFormat.Srgb: return InternalFormat.CompressedSrgbAlphaS3tcDxt1Ext; + case GalImageFormat.BC2 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt3Ext; + case GalImageFormat.BC2 | GalImageFormat.Srgb: return InternalFormat.CompressedSrgbAlphaS3tcDxt3Ext; + case GalImageFormat.BC3 | GalImageFormat.Unorm: return InternalFormat.CompressedRgbaS3tcDxt5Ext; + case GalImageFormat.BC3 | GalImageFormat.Srgb: return InternalFormat.CompressedSrgbAlphaS3tcDxt5Ext; + case GalImageFormat.BC4 | GalImageFormat.Snorm: return InternalFormat.CompressedSignedRedRgtc1; + case GalImageFormat.BC4 | GalImageFormat.Unorm: return InternalFormat.CompressedRedRgtc1; + case GalImageFormat.BC5 | GalImageFormat.Snorm: return InternalFormat.CompressedSignedRgRgtc2; + case GalImageFormat.BC5 | GalImageFormat.Unorm: return InternalFormat.CompressedRgRgtc2; } throw new NotImplementedException($"{Format & GalImageFormat.FormatMask} {Format & GalImageFormat.TypeMask}"); diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs index b7825996e..00699641f 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs @@ -129,9 +129,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL BlendFuncSrcAlpha = GalBlendFactor.One, BlendFuncDstAlpha = GalBlendFactor.Zero, + ColorMask = ColorMaskRgba.Default, + PrimitiveRestartEnabled = false, PrimitiveRestartIndex = 0 }; + + for (int Index = 0; Index < GalPipelineState.RenderTargetsCount; Index++) + { + Old.ColorMasks[Index] = ColorMaskRgba.Default; + } } public void Bind(GalPipelineState New) @@ -177,8 +184,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL if (New.DepthWriteEnabled != Old.DepthWriteEnabled) { - Rasterizer.DepthWriteEnabled = New.DepthWriteEnabled; - GL.DepthMask(New.DepthWriteEnabled); } @@ -303,16 +308,17 @@ namespace Ryujinx.Graphics.Gal.OpenGL } } - if (New.ColorMaskR != Old.ColorMaskR || - New.ColorMaskG != Old.ColorMaskG || - New.ColorMaskB != Old.ColorMaskB || - New.ColorMaskA != Old.ColorMaskA) + for (int Index = 0; Index < GalPipelineState.RenderTargetsCount; Index++) { - GL.ColorMask( - New.ColorMaskR, - New.ColorMaskG, - New.ColorMaskB, - New.ColorMaskA); + if (!New.ColorMasks[Index].Equals(Old.ColorMasks[Index])) + { + GL.ColorMask( + Index, + New.ColorMasks[Index].Red, + New.ColorMasks[Index].Green, + New.ColorMasks[Index].Blue, + New.ColorMasks[Index].Alpha); + } } if (New.PrimitiveRestartEnabled != Old.PrimitiveRestartEnabled) @@ -613,5 +619,15 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.Disable(Cap); } } + + public void ResetDepthMask() + { + Old.DepthWriteEnabled = true; + } + + public void ResetColorMask(int Index) + { + Old.ColorMasks[Index] = ColorMaskRgba.Default; + } } } \ No newline at end of file diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs index 7b435c455..cefbb2d2a 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRasterizer.cs @@ -5,8 +5,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL { class OGLRasterizer : IGalRasterizer { - public bool DepthWriteEnabled { set; private get; } - private int[] VertexBuffers; private OGLCachedResource VboCache; @@ -30,8 +28,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL IboCache = new OGLCachedResource(GL.DeleteBuffer); IndexBuffer = new IbInfo(); - - DepthWriteEnabled = true; } public void LockCaches() @@ -49,17 +45,15 @@ namespace Ryujinx.Graphics.Gal.OpenGL public void ClearBuffers( GalClearBufferFlags Flags, int Attachment, - float Red, float Green, float Blue, float Alpha, + float Red, + float Green, + float Blue, + float Alpha, float Depth, int Stencil) { - //OpenGL needs glDepthMask to be enabled to clear it - if (!DepthWriteEnabled) - { - GL.DepthMask(true); - } - GL.ColorMask( + Attachment, Flags.HasFlag(GalClearBufferFlags.ColorRed), Flags.HasFlag(GalClearBufferFlags.ColorGreen), Flags.HasFlag(GalClearBufferFlags.ColorBlue), @@ -67,6 +61,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL GL.ClearBuffer(ClearBuffer.Color, Attachment, new float[] { Red, Green, Blue, Alpha }); + GL.ColorMask(Attachment, true, true, true, true); + GL.DepthMask(true); + if (Flags.HasFlag(GalClearBufferFlags.Depth)) { GL.ClearBuffer(ClearBuffer.Depth, 0, ref Depth); @@ -76,13 +73,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL { GL.ClearBuffer(ClearBuffer.Stencil, 0, ref Stencil); } - - GL.ColorMask(true, true, true, true); - - if (!DepthWriteEnabled) - { - GL.DepthMask(false); - } } public bool IsVboCached(long Key, long DataSize) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs index 0de070b54..e0c4854ed 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLRenderTarget.cs @@ -59,9 +59,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL private const int NativeWidth = 1280; private const int NativeHeight = 720; - private const int RenderTargetsCount = 8; - - private const GalImageFormat RawFormat = GalImageFormat.A8B8G8R8 | GalImageFormat.Unorm; + private const int RenderTargetsCount = GalPipelineState.RenderTargetsCount; private OGLTexture Texture; @@ -115,15 +113,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL for (int Attachment = 0; Attachment < RenderTargetsCount; Attachment++) { - if (Attachments.Colors[Attachment] == OldAttachments.Colors[Attachment]) + long Key = Attachments.Colors[Attachment]; + + if (Key == OldAttachments.Colors[Attachment]) { continue; } int Handle = 0; - if (Attachments.Colors[Attachment] != 0 && - Texture.TryGetImageHandler(Attachments.Colors[Attachment], out CachedImage)) + if (Key != 0 && Texture.TryGetImageHandler(Key, out CachedImage)) { Handle = CachedImage.Handle; } @@ -178,7 +177,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL if (OGLExtension.ViewportArray) { - GL.ViewportArray(0, 8, Viewports); + GL.ViewportArray(0, RenderTargetsCount, Viewports); } else { diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs index efcb7e347..b45a3a3a5 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLShader.cs @@ -55,16 +55,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL GlslDecompiler Decompiler = new GlslDecompiler(); + int ShaderDumpIndex = ShaderDumper.DumpIndex; + if (IsDualVp) { ShaderDumper.Dump(Memory, Position, Type, "a"); ShaderDumper.Dump(Memory, PositionB, Type, "b"); - Program = Decompiler.Decompile( - Memory, - Position, - PositionB, - Type); + Program = Decompiler.Decompile(Memory, Position, PositionB, Type); } else { @@ -73,11 +71,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL Program = Decompiler.Decompile(Memory, Position, Type); } - return new OGLShaderStage( - Type, - Program.Code, - Program.Uniforms, - Program.Textures); + string Code = Program.Code; + + if (ShaderDumper.IsDumpEnabled()) + { + Code = "//Shader " + ShaderDumpIndex + Environment.NewLine + Code; + } + + return new OGLShaderStage(Type, Code, Program.Uniforms, Program.Textures); } public IEnumerable GetConstBufferUsage(long Key) diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs index 3347afbd1..6c6085280 100644 --- a/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs +++ b/Ryujinx.Graphics/Gal/OpenGL/OGLTexture.cs @@ -39,41 +39,25 @@ namespace Ryujinx.Graphics.Gal.OpenGL TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Size); - GalImageFormat TypeLess = Image.Format & GalImageFormat.FormatMask; - - bool IsASTC = TypeLess >= GalImageFormat.ASTC_BEGIN && TypeLess <= GalImageFormat.ASTC_END; - - if (ImageUtils.IsCompressed(Image.Format) && !IsASTC) + if (ImageUtils.IsCompressed(Image.Format)) { - InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format); - - GL.CompressedTexImage2D( - TextureTarget.Texture2D, - Level, - InternalFmt, - Image.Width, - Image.Height, - Border, - Size, - IntPtr.Zero); + throw new InvalidOperationException("Surfaces with compressed formats are not supported!"); } - else - { - (PixelInternalFormat InternalFmt, - PixelFormat Format, - PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format); - GL.TexImage2D( - TextureTarget.Texture2D, - Level, - InternalFmt, - Image.Width, - Image.Height, - Border, - Format, - Type, - IntPtr.Zero); - } + (PixelInternalFormat InternalFmt, + PixelFormat Format, + PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format); + + GL.TexImage2D( + TextureTarget.Texture2D, + Level, + InternalFmt, + Image.Width, + Image.Height, + Border, + Format, + Type, + IntPtr.Zero); } public void Create(long Key, byte[] Data, GalImage Image) @@ -87,11 +71,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Data.Length); - GalImageFormat TypeLess = Image.Format & GalImageFormat.FormatMask; - - bool IsASTC = TypeLess >= GalImageFormat.ASTC_BEGIN && TypeLess <= GalImageFormat.ASTC_END; - - if (ImageUtils.IsCompressed(Image.Format) && !IsASTC) + if (ImageUtils.IsCompressed(Image.Format) && !IsAstc(Image.Format)) { InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format); @@ -108,7 +88,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL else { //TODO: Use KHR_texture_compression_astc_hdr when available - if (IsASTC) + if (IsAstc(Image.Format)) { int TextureBlockWidth = ImageUtils.GetBlockWidth(Image.Format); int TextureBlockHeight = ImageUtils.GetBlockHeight(Image.Format); @@ -120,17 +100,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL Image.Width, Image.Height, 1); - Image.Format = GalImageFormat.A8B8G8R8 | GalImageFormat.Unorm; - } - else if (TypeLess == GalImageFormat.G8R8) - { - Data = ImageConverter.G8R8ToR8G8( - Data, - Image.Width, - Image.Height, - 1); - - Image.Format = GalImageFormat.R8G8 | (Image.Format & GalImageFormat.TypeMask); + Image.Format = GalImageFormat.RGBA8 | GalImageFormat.Unorm; } (PixelInternalFormat InternalFmt, @@ -150,6 +120,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL } } + private static bool IsAstc(GalImageFormat Format) + { + Format &= GalImageFormat.FormatMask; + + return Format > GalImageFormat.Astc2DStart && Format < GalImageFormat.Astc2DEnd; + } + public bool TryGetImage(long Key, out GalImage Image) { if (TextureCache.TryGetValue(Key, out ImageHandler CachedImage)) diff --git a/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs b/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs index ac6ae8d5d..f8c07f31a 100644 --- a/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs +++ b/Ryujinx.Graphics/Gal/Shader/ShaderDecoder.cs @@ -69,7 +69,7 @@ namespace Ryujinx.Graphics.Gal.Shader { int Target = ((ShaderIrOperImm)CurrOp.OperandA).Value; - Current.Branch = Enqueue(Target, Current); + Enqueue(Target, Current); } } @@ -165,7 +165,7 @@ namespace Ryujinx.Graphics.Gal.Shader DbgOpCode += (Decode?.Method.Name ?? "???"); - if (Decode == ShaderDecode.Bra) + if (Decode == ShaderDecode.Bra || Decode == ShaderDecode.Ssy) { int Offset = ((int)(OpCode >> 20) << 8) >> 8; diff --git a/Ryujinx.Graphics/Gal/ShaderDumper.cs b/Ryujinx.Graphics/Gal/ShaderDumper.cs index 541368e89..d3bcbf0d8 100644 --- a/Ryujinx.Graphics/Gal/ShaderDumper.cs +++ b/Ryujinx.Graphics/Gal/ShaderDumper.cs @@ -7,11 +7,11 @@ namespace Ryujinx.Graphics.Gal { private static string RuntimeDir; - private static int DumpIndex = 1; + public static int DumpIndex { get; private set; } = 1; public static void Dump(IGalMemory Memory, long Position, GalShaderType Type, string ExtSuffix = "") { - if (string.IsNullOrWhiteSpace(GraphicsConfig.ShadersDumpPath)) + if (!IsDumpEnabled()) { return; } @@ -25,9 +25,10 @@ namespace Ryujinx.Graphics.Gal using (FileStream FullFile = File.Create(FullPath)) using (FileStream CodeFile = File.Create(CodePath)) - using (BinaryWriter FullWriter = new BinaryWriter(FullFile)) - using (BinaryWriter CodeWriter = new BinaryWriter(CodeFile)) { + BinaryWriter FullWriter = new BinaryWriter(FullFile); + BinaryWriter CodeWriter = new BinaryWriter(CodeFile); + for (long i = 0; i < 0x50; i += 4) { FullWriter.Write(Memory.ReadInt32(Position + i)); @@ -69,6 +70,11 @@ namespace Ryujinx.Graphics.Gal } } + public static bool IsDumpEnabled() + { + return !string.IsNullOrWhiteSpace(GraphicsConfig.ShadersDumpPath); + } + private static string FullDir() { return CreateAndReturn(Path.Combine(DumpDir(), "Full")); diff --git a/Ryujinx.Graphics/NvGpuEngine3d.cs b/Ryujinx.Graphics/NvGpuEngine3d.cs index a2a969280..fd15d0b6a 100644 --- a/Ryujinx.Graphics/NvGpuEngine3d.cs +++ b/Ryujinx.Graphics/NvGpuEngine3d.cs @@ -141,7 +141,7 @@ namespace Ryujinx.Graphics { int Arg0 = PBEntry.Arguments[0]; - int FbIndex = (Arg0 >> 6) & 0xf; + int Attachment = (Arg0 >> 6) & 0xf; GalClearBufferFlags Flags = (GalClearBufferFlags)(Arg0 & 0x3f); @@ -154,7 +154,7 @@ namespace Ryujinx.Graphics int Stencil = ReadRegister(NvGpuEngine3dReg.ClearStencil); - SetFrameBuffer(Vmm, FbIndex); + SetFrameBuffer(Vmm, Attachment); SetZeta(Vmm); @@ -162,12 +162,10 @@ namespace Ryujinx.Graphics Gpu.Renderer.RenderTarget.Bind(); - Gpu.Renderer.Rasterizer.ClearBuffers( - Flags, - FbIndex, - Red, Green, Blue, Alpha, - Depth, - Stencil); + Gpu.Renderer.Rasterizer.ClearBuffers(Flags, Attachment, Red, Green, Blue, Alpha, Depth, Stencil); + + Gpu.Renderer.Pipeline.ResetDepthMask(); + Gpu.Renderer.Pipeline.ResetColorMask(Attachment); } private void SetFrameBuffer(NvGpuVmm Vmm, int FbIndex) @@ -345,13 +343,8 @@ namespace Ryujinx.Graphics { switch (FrontFace) { - case GalFrontFace.CW: - FrontFace = GalFrontFace.CCW; - break; - - case GalFrontFace.CCW: - FrontFace = GalFrontFace.CW; - break; + case GalFrontFace.CW: FrontFace = GalFrontFace.CCW; break; + case GalFrontFace.CCW: FrontFace = GalFrontFace.CW; break; } } @@ -426,10 +419,20 @@ namespace Ryujinx.Graphics { int ColorMask = ReadRegister(NvGpuEngine3dReg.ColorMask); - State.ColorMaskR = ((ColorMask >> 0) & 0xf) != 0; - State.ColorMaskG = ((ColorMask >> 4) & 0xf) != 0; - State.ColorMaskB = ((ColorMask >> 8) & 0xf) != 0; - State.ColorMaskA = ((ColorMask >> 12) & 0xf) != 0; + State.ColorMask.Red = ((ColorMask >> 0) & 0xf) != 0; + State.ColorMask.Green = ((ColorMask >> 4) & 0xf) != 0; + State.ColorMask.Blue = ((ColorMask >> 8) & 0xf) != 0; + State.ColorMask.Alpha = ((ColorMask >> 12) & 0xf) != 0; + + for (int Index = 0; Index < GalPipelineState.RenderTargetsCount; Index++) + { + ColorMask = ReadRegister(NvGpuEngine3dReg.ColorMaskN + Index); + + State.ColorMasks[Index].Red = ((ColorMask >> 0) & 0xf) != 0; + State.ColorMasks[Index].Green = ((ColorMask >> 4) & 0xf) != 0; + State.ColorMasks[Index].Blue = ((ColorMask >> 8) & 0xf) != 0; + State.ColorMasks[Index].Alpha = ((ColorMask >> 12) & 0xf) != 0; + } } private void SetPrimitiveRestart(GalPipelineState State) @@ -455,11 +458,11 @@ namespace Ryujinx.Graphics { int[] Map = new int[Count]; - for (int i = 0; i < Count; i++) + for (int Index = 0; Index < Count; Index++) { - int Shift = 4 + i * 3; + int Shift = 4 + Index * 3; - Map[i] = (int)((Control >> Shift) & 7); + Map[Index] = (int)((Control >> Shift) & 7); } Gpu.Renderer.RenderTarget.SetMap(Map); diff --git a/Ryujinx.Graphics/NvGpuEngine3dReg.cs b/Ryujinx.Graphics/NvGpuEngine3dReg.cs index ba211313e..ef74e4f67 100644 --- a/Ryujinx.Graphics/NvGpuEngine3dReg.cs +++ b/Ryujinx.Graphics/NvGpuEngine3dReg.cs @@ -23,6 +23,7 @@ namespace Ryujinx.Graphics StencilBackFuncRef = 0x3d5, StencilBackMask = 0x3d6, StencilBackFuncMask = 0x3d7, + ColorMask = 0x3e4, RTSeparateFragData = 0x3eb, ZetaAddress = 0x3f8, ZetaFormat = 0x3fa, @@ -78,7 +79,7 @@ namespace Ryujinx.Graphics CullFaceEnable = 0x646, FrontFace = 0x647, CullFace = 0x648, - ColorMask = 0x680, + ColorMaskN = 0x680, QueryAddress = 0x6c0, QuerySequence = 0x6c2, QueryControl = 0x6c3, diff --git a/Ryujinx.Graphics/Texture/ImageConverter.cs b/Ryujinx.Graphics/Texture/ImageConverter.cs deleted file mode 100644 index 89529061f..000000000 --- a/Ryujinx.Graphics/Texture/ImageConverter.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Ryujinx.Graphics.Texture -{ - static class ImageConverter - { - public static byte[] G8R8ToR8G8( - byte[] Data, - int Width, - int Height, - int Depth) - { - int Texels = Width * Height * Depth; - - byte[] Output = new byte[Texels * 2]; - - for (int Texel = 0; Texel < Texels; Texel++) - { - Output[Texel * 2 + 0] = Data[Texel * 2 + 1]; - Output[Texel * 2 + 1] = Data[Texel * 2 + 0]; - } - - return Output; - } - } -} \ No newline at end of file diff --git a/Ryujinx.Graphics/Texture/ImageUtils.cs b/Ryujinx.Graphics/Texture/ImageUtils.cs index 2c4e7b4b0..d2172c2ef 100644 --- a/Ryujinx.Graphics/Texture/ImageUtils.cs +++ b/Ryujinx.Graphics/Texture/ImageUtils.cs @@ -35,106 +35,105 @@ namespace Ryujinx.Graphics.Texture } } - private const GalImageFormat Snorm = GalImageFormat.Snorm; - private const GalImageFormat Unorm = GalImageFormat.Unorm; - private const GalImageFormat Sint = GalImageFormat.Sint; - private const GalImageFormat Uint = GalImageFormat.Uint; - private const GalImageFormat Sfloat = GalImageFormat.Sfloat; + private const GalImageFormat Snorm = GalImageFormat.Snorm; + private const GalImageFormat Unorm = GalImageFormat.Unorm; + private const GalImageFormat Sint = GalImageFormat.Sint; + private const GalImageFormat Uint = GalImageFormat.Uint; + private const GalImageFormat Float = GalImageFormat.Float; + private const GalImageFormat Srgb = GalImageFormat.Srgb; private static readonly Dictionary s_TextureTable = new Dictionary() - { - { GalTextureFormat.R32G32B32A32, GalImageFormat.R32G32B32A32 | Sint | Uint | Sfloat }, - { GalTextureFormat.R16G16B16A16, GalImageFormat.R16G16B16A16 | Snorm | Unorm | Sint | Uint | Sfloat }, - { GalTextureFormat.R32G32, GalImageFormat.R32G32 | Sint | Uint | Sfloat }, - { GalTextureFormat.A8B8G8R8, GalImageFormat.A8B8G8R8 | Snorm | Unorm | Sint | Uint }, - { GalTextureFormat.A2B10G10R10, GalImageFormat.A2B10G10R10 | Snorm | Unorm | Sint | Uint }, - { GalTextureFormat.G8R8, GalImageFormat.G8R8 | Snorm | Unorm | Sint | Uint }, - { GalTextureFormat.R16, GalImageFormat.R16 | Snorm | Unorm | Sint | Uint | Sfloat }, - { GalTextureFormat.R8, GalImageFormat.R8 | Snorm | Unorm | Sint | Uint }, - { GalTextureFormat.R16G16, GalImageFormat.R16G16 | Snorm | Unorm | Sfloat }, - { GalTextureFormat.R32, GalImageFormat.R32 | Sint | Uint | Sfloat }, - { GalTextureFormat.A4B4G4R4, GalImageFormat.A4B4G4R4 | Unorm }, - { GalTextureFormat.A1B5G5R5, GalImageFormat.A1R5G5B5 | Unorm }, - { GalTextureFormat.B5G6R5, GalImageFormat.B5G6R5 | Unorm }, - { GalTextureFormat.BF10GF11RF11, GalImageFormat.B10G11R11 | Sfloat }, - { GalTextureFormat.Z24S8, GalImageFormat.D24_S8 | Unorm | Uint }, - { GalTextureFormat.ZF32, GalImageFormat.D32 | Sfloat }, - { GalTextureFormat.ZF32_X24S8, GalImageFormat.D32_S8 | Unorm }, - { GalTextureFormat.Z16, GalImageFormat.D16 | Unorm }, + { + { GalTextureFormat.RGBA32, GalImageFormat.RGBA32 | Sint | Uint | Float }, + { GalTextureFormat.RGBA16, GalImageFormat.RGBA16 | Snorm | Unorm | Sint | Uint | Float }, + { GalTextureFormat.RG32, GalImageFormat.RG32 | Sint | Uint | Float }, + { GalTextureFormat.RGBA8, GalImageFormat.RGBA8 | Snorm | Unorm | Sint | Uint | Srgb }, + { GalTextureFormat.RGB10A2, GalImageFormat.RGB10A2 | Snorm | Unorm | Sint | Uint }, + { GalTextureFormat.RG8, GalImageFormat.RG8 | Snorm | Unorm | Sint | Uint }, + { GalTextureFormat.R16, GalImageFormat.R16 | Snorm | Unorm | Sint | Uint | Float }, + { GalTextureFormat.R8, GalImageFormat.R8 | Snorm | Unorm | Sint | Uint }, + { GalTextureFormat.RG16, GalImageFormat.RG16 | Snorm | Unorm | Float }, + { GalTextureFormat.R32, GalImageFormat.R32 | Sint | Uint | Float }, + { GalTextureFormat.RGBA4, GalImageFormat.RGBA4 | Unorm }, + { GalTextureFormat.RGB5A1, GalImageFormat.RGB5A1 | Unorm }, + { GalTextureFormat.RGB565, GalImageFormat.RGB565 | Unorm }, + { GalTextureFormat.R11G11B10F, GalImageFormat.R11G11B10 | Float }, + { GalTextureFormat.D24S8, GalImageFormat.D24S8 | Unorm | Uint }, + { GalTextureFormat.D32F, GalImageFormat.D32 | Float }, + { GalTextureFormat.D32FX24S8, GalImageFormat.D32S8 | Unorm }, + { GalTextureFormat.D16, GalImageFormat.D16 | Unorm }, - //Compressed formats - { GalTextureFormat.BC6H_SF16, GalImageFormat.BC6H_SF16 | Unorm }, - { GalTextureFormat.BC6H_UF16, GalImageFormat.BC6H_UF16 | Sfloat }, - { GalTextureFormat.BC7U, GalImageFormat.BC7 | Unorm }, - { GalTextureFormat.BC1, GalImageFormat.BC1_RGBA | Unorm }, - { GalTextureFormat.BC2, GalImageFormat.BC2 | Unorm }, - { GalTextureFormat.BC3, GalImageFormat.BC3 | Unorm }, - { GalTextureFormat.BC4, GalImageFormat.BC4 | Unorm | Snorm }, - { GalTextureFormat.BC5, GalImageFormat.BC5 | Unorm | Snorm }, - { GalTextureFormat.Astc2D4x4, GalImageFormat.ASTC_4x4 | Unorm }, - { GalTextureFormat.Astc2D5x5, GalImageFormat.ASTC_5x5 | Unorm }, - { GalTextureFormat.Astc2D6x6, GalImageFormat.ASTC_6x6 | Unorm }, - { GalTextureFormat.Astc2D8x8, GalImageFormat.ASTC_8x8 | Unorm }, - { GalTextureFormat.Astc2D10x10, GalImageFormat.ASTC_10x10 | Unorm }, - { GalTextureFormat.Astc2D12x12, GalImageFormat.ASTC_12x12 | Unorm }, - { GalTextureFormat.Astc2D5x4, GalImageFormat.ASTC_5x4 | Unorm }, - { GalTextureFormat.Astc2D6x5, GalImageFormat.ASTC_6x5 | Unorm }, - { GalTextureFormat.Astc2D8x6, GalImageFormat.ASTC_8x6 | Unorm }, - { GalTextureFormat.Astc2D10x8, GalImageFormat.ASTC_10x8 | Unorm }, - { GalTextureFormat.Astc2D12x10, GalImageFormat.ASTC_12x10 | Unorm }, - { GalTextureFormat.Astc2D8x5, GalImageFormat.ASTC_8x5 | Unorm }, - { GalTextureFormat.Astc2D10x5, GalImageFormat.ASTC_10x5 | Unorm }, - { GalTextureFormat.Astc2D10x6, GalImageFormat.ASTC_10x6 | Unorm } - }; + //Compressed formats + { GalTextureFormat.BptcSfloat, GalImageFormat.BptcSfloat | Float }, + { GalTextureFormat.BptcUfloat, GalImageFormat.BptcUfloat | Float }, + { GalTextureFormat.BptcUnorm, GalImageFormat.BptcUnorm | Unorm | Srgb }, + { GalTextureFormat.BC1, GalImageFormat.BC1 | Unorm | Srgb }, + { GalTextureFormat.BC2, GalImageFormat.BC2 | Unorm | Srgb }, + { GalTextureFormat.BC3, GalImageFormat.BC3 | Unorm | Srgb }, + { GalTextureFormat.BC4, GalImageFormat.BC4 | Unorm | Snorm }, + { GalTextureFormat.BC5, GalImageFormat.BC5 | Unorm | Snorm }, + { GalTextureFormat.Astc2D4x4, GalImageFormat.Astc2D4x4 | Unorm | Srgb }, + { GalTextureFormat.Astc2D5x5, GalImageFormat.Astc2D5x5 | Unorm | Srgb }, + { GalTextureFormat.Astc2D6x6, GalImageFormat.Astc2D6x6 | Unorm | Srgb }, + { GalTextureFormat.Astc2D8x8, GalImageFormat.Astc2D8x8 | Unorm | Srgb }, + { GalTextureFormat.Astc2D10x10, GalImageFormat.Astc2D10x10 | Unorm | Srgb }, + { GalTextureFormat.Astc2D12x12, GalImageFormat.Astc2D12x12 | Unorm | Srgb }, + { GalTextureFormat.Astc2D5x4, GalImageFormat.Astc2D5x4 | Unorm | Srgb }, + { GalTextureFormat.Astc2D6x5, GalImageFormat.Astc2D6x5 | Unorm | Srgb }, + { GalTextureFormat.Astc2D8x6, GalImageFormat.Astc2D8x6 | Unorm | Srgb }, + { GalTextureFormat.Astc2D10x8, GalImageFormat.Astc2D10x8 | Unorm | Srgb }, + { GalTextureFormat.Astc2D12x10, GalImageFormat.Astc2D12x10 | Unorm | Srgb }, + { GalTextureFormat.Astc2D8x5, GalImageFormat.Astc2D8x5 | Unorm | Srgb }, + { GalTextureFormat.Astc2D10x5, GalImageFormat.Astc2D10x5 | Unorm | Srgb }, + { GalTextureFormat.Astc2D10x6, GalImageFormat.Astc2D10x6 | Unorm | Srgb } + }; private static readonly Dictionary s_ImageTable = new Dictionary() { - { GalImageFormat.R32G32B32A32, new ImageDescriptor(16, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.R16G16B16A16, new ImageDescriptor(8, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.R32G32, new ImageDescriptor(8, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.B8G8R8A8, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.A8B8G8R8, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.A2B10G10R10, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.R32, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.A4B4G4R4, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.BC6H_SF16, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, - { GalImageFormat.BC6H_UF16, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, - { GalImageFormat.A1R5G5B5, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.B5G6R5, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.BC7, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, - { GalImageFormat.R16G16, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.R8G8, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.G8R8, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.R16, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.R8, new ImageDescriptor(1, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.B10G11R11, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.A8B8G8R8_SRGB, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, - { GalImageFormat.BC1_RGBA, new ImageDescriptor(8, 4, 4, TargetBuffer.Color) }, - { GalImageFormat.BC2, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, - { GalImageFormat.BC3, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, - { GalImageFormat.BC4, new ImageDescriptor(8, 4, 4, TargetBuffer.Color) }, - { GalImageFormat.BC5, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, - { GalImageFormat.ASTC_4x4, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, - { GalImageFormat.ASTC_5x5, new ImageDescriptor(16, 5, 5, TargetBuffer.Color) }, - { GalImageFormat.ASTC_6x6, new ImageDescriptor(16, 6, 6, TargetBuffer.Color) }, - { GalImageFormat.ASTC_8x8, new ImageDescriptor(16, 8, 8, TargetBuffer.Color) }, - { GalImageFormat.ASTC_10x10, new ImageDescriptor(16, 10, 10, TargetBuffer.Color) }, - { GalImageFormat.ASTC_12x12, new ImageDescriptor(16, 12, 12, TargetBuffer.Color) }, - { GalImageFormat.ASTC_5x4, new ImageDescriptor(16, 5, 4, TargetBuffer.Color) }, - { GalImageFormat.ASTC_6x5, new ImageDescriptor(16, 6, 5, TargetBuffer.Color) }, - { GalImageFormat.ASTC_8x6, new ImageDescriptor(16, 8, 6, TargetBuffer.Color) }, - { GalImageFormat.ASTC_10x8, new ImageDescriptor(16, 10, 8, TargetBuffer.Color) }, - { GalImageFormat.ASTC_12x10, new ImageDescriptor(16, 12, 10, TargetBuffer.Color) }, - { GalImageFormat.ASTC_8x5, new ImageDescriptor(16, 8, 5, TargetBuffer.Color) }, - { GalImageFormat.ASTC_10x5, new ImageDescriptor(16, 10, 5, TargetBuffer.Color) }, - { GalImageFormat.ASTC_10x6, new ImageDescriptor(16, 10, 6, TargetBuffer.Color) }, + { GalImageFormat.RGBA32, new ImageDescriptor(16, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.RGBA16, new ImageDescriptor(8, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.RG32, new ImageDescriptor(8, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.RGBA8, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.BGRA8, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.RGB10A2, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.R32, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.RGBA4, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.BptcSfloat, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.BptcUfloat, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.RGB5A1, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.RGB565, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.BptcUnorm, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.RG16, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.RG8, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.R16, new ImageDescriptor(2, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.R8, new ImageDescriptor(1, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.R11G11B10, new ImageDescriptor(4, 1, 1, TargetBuffer.Color) }, + { GalImageFormat.BC1, new ImageDescriptor(8, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.BC2, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.BC3, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.BC4, new ImageDescriptor(8, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.BC5, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.Astc2D4x4, new ImageDescriptor(16, 4, 4, TargetBuffer.Color) }, + { GalImageFormat.Astc2D5x5, new ImageDescriptor(16, 5, 5, TargetBuffer.Color) }, + { GalImageFormat.Astc2D6x6, new ImageDescriptor(16, 6, 6, TargetBuffer.Color) }, + { GalImageFormat.Astc2D8x8, new ImageDescriptor(16, 8, 8, TargetBuffer.Color) }, + { GalImageFormat.Astc2D10x10, new ImageDescriptor(16, 10, 10, TargetBuffer.Color) }, + { GalImageFormat.Astc2D12x12, new ImageDescriptor(16, 12, 12, TargetBuffer.Color) }, + { GalImageFormat.Astc2D5x4, new ImageDescriptor(16, 5, 4, TargetBuffer.Color) }, + { GalImageFormat.Astc2D6x5, new ImageDescriptor(16, 6, 5, TargetBuffer.Color) }, + { GalImageFormat.Astc2D8x6, new ImageDescriptor(16, 8, 6, TargetBuffer.Color) }, + { GalImageFormat.Astc2D10x8, new ImageDescriptor(16, 10, 8, TargetBuffer.Color) }, + { GalImageFormat.Astc2D12x10, new ImageDescriptor(16, 12, 10, TargetBuffer.Color) }, + { GalImageFormat.Astc2D8x5, new ImageDescriptor(16, 8, 5, TargetBuffer.Color) }, + { GalImageFormat.Astc2D10x5, new ImageDescriptor(16, 10, 5, TargetBuffer.Color) }, + { GalImageFormat.Astc2D10x6, new ImageDescriptor(16, 10, 6, TargetBuffer.Color) }, - { GalImageFormat.D24_S8, new ImageDescriptor(4, 1, 1, TargetBuffer.DepthStencil) }, - { GalImageFormat.D32, new ImageDescriptor(4, 1, 1, TargetBuffer.Depth) }, - { GalImageFormat.D16, new ImageDescriptor(2, 1, 1, TargetBuffer.Depth) }, - { GalImageFormat.D32_S8, new ImageDescriptor(8, 1, 1, TargetBuffer.DepthStencil) }, + { GalImageFormat.D24S8, new ImageDescriptor(4, 1, 1, TargetBuffer.DepthStencil) }, + { GalImageFormat.D32, new ImageDescriptor(4, 1, 1, TargetBuffer.Depth) }, + { GalImageFormat.D16, new ImageDescriptor(2, 1, 1, TargetBuffer.Depth) }, + { GalImageFormat.D32S8, new ImageDescriptor(8, 1, 1, TargetBuffer.DepthStencil) } }; public static GalImageFormat ConvertTexture( @@ -142,64 +141,62 @@ namespace Ryujinx.Graphics.Texture GalTextureType RType, GalTextureType GType, GalTextureType BType, - GalTextureType AType) + GalTextureType AType, + bool ConvSrgb) { if (RType != GType || RType != BType || RType != AType) { - throw new NotImplementedException("Per component types are not implemented"); + throw new NotImplementedException("Per component types are not implemented!"); } if (!s_TextureTable.TryGetValue(Format, out GalImageFormat ImageFormat)) { - throw new NotImplementedException("Texture with format " + ((int)Format).ToString("x2") + " not implemented"); + throw new NotImplementedException($"Format 0x{((int)Format):x} not implemented!"); } - GalTextureType Type = RType; + GalImageFormat FormatType = ConvSrgb ? Srgb : GetFormatType(RType); - GalImageFormat FormatType = GetFormatType(RType); + GalImageFormat CombinedFormat = (ImageFormat & GalImageFormat.FormatMask) | FormatType; - if (ImageFormat.HasFlag(FormatType)) + if (!ImageFormat.HasFlag(FormatType)) { - return (ImageFormat & GalImageFormat.FormatMask) | FormatType; - } - else - { - throw new NotImplementedException("Texture with format " + Format + - " and component type " + Type + " is not implemented"); + throw new NotImplementedException($"Format \"{CombinedFormat}\" not implemented!"); } + + return CombinedFormat; } public static GalImageFormat ConvertSurface(GalSurfaceFormat Format) { switch (Format) { - case GalSurfaceFormat.RGBA32Float: return GalImageFormat.R32G32B32A32 | Sfloat; - case GalSurfaceFormat.RGBA32Uint: return GalImageFormat.R32G32B32A32 | Uint; - case GalSurfaceFormat.RGBA16Float: return GalImageFormat.R16G16B16A16 | Sfloat; - case GalSurfaceFormat.RG32Float: return GalImageFormat.R32G32 | Sfloat; - case GalSurfaceFormat.RG32Sint: return GalImageFormat.R32G32 | Sint; - case GalSurfaceFormat.RG32Uint: return GalImageFormat.R32G32 | Uint; - case GalSurfaceFormat.BGRA8Unorm: return GalImageFormat.B8G8R8A8 | Unorm; - case GalSurfaceFormat.BGRA8Srgb: return GalImageFormat.A8B8G8R8_SRGB; //This one might be wrong - case GalSurfaceFormat.RGB10A2Unorm: return GalImageFormat.A2B10G10R10 | Unorm; - case GalSurfaceFormat.RGBA8Unorm: return GalImageFormat.A8B8G8R8 | Unorm; - case GalSurfaceFormat.RGBA8Srgb: return GalImageFormat.A8B8G8R8_SRGB; - case GalSurfaceFormat.RGBA8Snorm: return GalImageFormat.A8B8G8R8 | Snorm; - case GalSurfaceFormat.RG16Snorm: return GalImageFormat.R16G16 | Snorm; - case GalSurfaceFormat.RG16Unorm: return GalImageFormat.R16G16 | Unorm; - case GalSurfaceFormat.RG16Float: return GalImageFormat.R16G16 | Sfloat; - case GalSurfaceFormat.R11G11B10Float: return GalImageFormat.B10G11R11 | Sfloat; - case GalSurfaceFormat.R32Float: return GalImageFormat.R32 | Sfloat; - case GalSurfaceFormat.R32Uint: return GalImageFormat.R32 | Uint; - case GalSurfaceFormat.RG8Unorm: return GalImageFormat.R8G8 | Unorm; - case GalSurfaceFormat.RG8Snorm: return GalImageFormat.R8G8 | Snorm; - case GalSurfaceFormat.R16Float: return GalImageFormat.R16 | Sfloat; - case GalSurfaceFormat.R16Unorm: return GalImageFormat.R16 | Unorm; - case GalSurfaceFormat.R16Uint: return GalImageFormat.R16 | Uint; - case GalSurfaceFormat.R8Unorm: return GalImageFormat.R8 | Unorm; - case GalSurfaceFormat.R8Uint: return GalImageFormat.R8 | Uint; - case GalSurfaceFormat.B5G6R5Unorm: return GalImageFormat.B5G6R5 | Unorm; - case GalSurfaceFormat.BGR5A1Unorm: return GalImageFormat.A1R5G5B5 | Unorm; + case GalSurfaceFormat.RGBA32Float: return GalImageFormat.RGBA32 | Float; + case GalSurfaceFormat.RGBA32Uint: return GalImageFormat.RGBA32 | Uint; + case GalSurfaceFormat.RGBA16Float: return GalImageFormat.RGBA16 | Float; + case GalSurfaceFormat.RG32Float: return GalImageFormat.RG32 | Float; + case GalSurfaceFormat.RG32Sint: return GalImageFormat.RG32 | Sint; + case GalSurfaceFormat.RG32Uint: return GalImageFormat.RG32 | Uint; + case GalSurfaceFormat.BGRA8Unorm: return GalImageFormat.BGRA8 | Unorm; + case GalSurfaceFormat.BGRA8Srgb: return GalImageFormat.BGRA8 | Srgb; + case GalSurfaceFormat.RGB10A2Unorm: return GalImageFormat.RGB10A2 | Unorm; + case GalSurfaceFormat.RGBA8Unorm: return GalImageFormat.RGBA8 | Unorm; + case GalSurfaceFormat.RGBA8Srgb: return GalImageFormat.RGBA8 | Srgb; + case GalSurfaceFormat.RGBA8Snorm: return GalImageFormat.RGBA8 | Snorm; + case GalSurfaceFormat.RG16Snorm: return GalImageFormat.RG16 | Snorm; + case GalSurfaceFormat.RG16Unorm: return GalImageFormat.RG16 | Unorm; + case GalSurfaceFormat.RG16Float: return GalImageFormat.RG16 | Float; + case GalSurfaceFormat.R11G11B10Float: return GalImageFormat.R11G11B10 | Float; + case GalSurfaceFormat.R32Float: return GalImageFormat.R32 | Float; + case GalSurfaceFormat.R32Uint: return GalImageFormat.R32 | Uint; + case GalSurfaceFormat.RG8Unorm: return GalImageFormat.RG8 | Unorm; + case GalSurfaceFormat.RG8Snorm: return GalImageFormat.RG8 | Snorm; + case GalSurfaceFormat.R16Float: return GalImageFormat.R16 | Float; + case GalSurfaceFormat.R16Unorm: return GalImageFormat.R16 | Unorm; + case GalSurfaceFormat.R16Uint: return GalImageFormat.R16 | Uint; + case GalSurfaceFormat.R8Unorm: return GalImageFormat.R8 | Unorm; + case GalSurfaceFormat.R8Uint: return GalImageFormat.R8 | Uint; + case GalSurfaceFormat.B5G6R5Unorm: return GalImageFormat.RGB565 | Unorm; + case GalSurfaceFormat.BGR5A1Unorm: return GalImageFormat.BGR5A1 | Unorm; } throw new NotImplementedException(Format.ToString()); @@ -209,11 +206,11 @@ namespace Ryujinx.Graphics.Texture { switch (Format) { - case GalZetaFormat.Z32Float: return GalImageFormat.D32 | Sfloat; - case GalZetaFormat.S8Z24Unorm: return GalImageFormat.D24_S8 | Unorm; - case GalZetaFormat.Z16Unorm: return GalImageFormat.D16 | Unorm; - case GalZetaFormat.Z24S8Unorm: return GalImageFormat.D24_S8 | Unorm; - case GalZetaFormat.Z32S8X24Float: return GalImageFormat.D32_S8 | Sfloat; + case GalZetaFormat.D32Float: return GalImageFormat.D32 | Float; + case GalZetaFormat.S8D24Unorm: return GalImageFormat.D24S8 | Unorm; + case GalZetaFormat.D16Unorm: return GalImageFormat.D16 | Unorm; + case GalZetaFormat.D24S8Unorm: return GalImageFormat.D24S8 | Unorm; + case GalZetaFormat.D32S8X24Float: return GalImageFormat.D32S8 | Float; } throw new NotImplementedException(Format.ToString()); @@ -376,14 +373,14 @@ namespace Ryujinx.Graphics.Texture private static ImageDescriptor GetImageDescriptor(GalImageFormat Format) { - GalImageFormat TypeLess = (Format & GalImageFormat.FormatMask); + GalImageFormat PixelFormat = Format & GalImageFormat.FormatMask; - if (s_ImageTable.TryGetValue(TypeLess, out ImageDescriptor Descriptor)) + if (s_ImageTable.TryGetValue(PixelFormat, out ImageDescriptor Descriptor)) { return Descriptor; } - throw new NotImplementedException("Image with format " + TypeLess.ToString() + " not implemented"); + throw new NotImplementedException($"Format \"{PixelFormat}\" not implemented!"); } private static GalImageFormat GetFormatType(GalTextureType Type) @@ -394,7 +391,7 @@ namespace Ryujinx.Graphics.Texture case GalTextureType.Unorm: return Unorm; case GalTextureType.Sint: return Sint; case GalTextureType.Uint: return Uint; - case GalTextureType.Float: return Sfloat; + case GalTextureType.Float: return Float; default: throw new NotImplementedException(((int)Type).ToString()); } diff --git a/Ryujinx.Graphics/Texture/TextureFactory.cs b/Ryujinx.Graphics/Texture/TextureFactory.cs index c0c53b06e..1f2d625ec 100644 --- a/Ryujinx.Graphics/Texture/TextureFactory.cs +++ b/Ryujinx.Graphics/Texture/TextureFactory.cs @@ -97,7 +97,9 @@ namespace Ryujinx.Graphics.Texture GalTextureFormat Format = (GalTextureFormat)(Tic[0] & 0x7f); - return ImageUtils.ConvertTexture(Format, RType, GType, BType, AType); + bool ConvSrgb = ((Tic[4] >> 22) & 1) != 0; + + return ImageUtils.ConvertTexture(Format, RType, GType, BType, AType, ConvSrgb); } private static int[] ReadWords(NvGpuVmm Vmm, long Position, int Count) diff --git a/Ryujinx.HLE/HOS/Services/Vi/NvFlinger.cs b/Ryujinx.HLE/HOS/Services/Vi/NvFlinger.cs index 64cbad5c2..64e0b4a96 100644 --- a/Ryujinx.HLE/HOS/Services/Vi/NvFlinger.cs +++ b/Ryujinx.HLE/HOS/Services/Vi/NvFlinger.cs @@ -321,7 +321,7 @@ namespace Ryujinx.HLE.HOS.Services.Android FbWidth, FbHeight, 1, 16, GalMemoryLayout.BlockLinear, - GalImageFormat.A8B8G8R8 | GalImageFormat.Unorm); + GalImageFormat.RGBA8 | GalImageFormat.Unorm); } Context.Device.Gpu.ResourceManager.ClearPbCache();