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<int> VboCache;
@@ -30,8 +28,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
             IboCache = new OGLCachedResource<int>(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<ShaderDeclInfo> 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<GalTextureFormat, GalImageFormat> s_TextureTable =
                             new Dictionary<GalTextureFormat, GalImageFormat>()
-            {
-                { 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<GalImageFormat, ImageDescriptor> s_ImageTable =
                             new Dictionary<GalImageFormat, ImageDescriptor>()
         {
-            { 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();