From d8fd3ef4fea6f2e1c3b08105b02f383b11e9c17b Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Tue, 14 Aug 2018 20:31:19 -0400
Subject: [PATCH] gl_rasterizer_cache: Implement G8R8S format.

- Used by Super Mario Odyssey.
---
 .../renderer_opengl/gl_rasterizer_cache.cpp   | 14 ++--
 .../renderer_opengl/gl_rasterizer_cache.h     | 69 +++++++++++--------
 2 files changed, 49 insertions(+), 34 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 5d58ebd4f..05f153599 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -119,7 +119,8 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
     {GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ComponentType::UNorm,
      true},                                                                    // BC7U
     {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false},        // ASTC_2D_4X4
-    {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false},            // G8R8
+    {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false},            // G8R8U
+    {GL_RG8, GL_RG, GL_BYTE, ComponentType::SNorm, false},                     // G8R8S
     {GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, ComponentType::UNorm, false},        // BGRA8
     {GL_RGBA32F, GL_RGBA, GL_FLOAT, ComponentType::Float, false},              // RGBA32F
     {GL_RG32F, GL_RG, GL_FLOAT, ComponentType::Float, false},                  // RG32F
@@ -260,7 +261,8 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU
         MortonCopy<true, PixelFormat::DXN2SNORM>,
         MortonCopy<true, PixelFormat::BC7U>,
         MortonCopy<true, PixelFormat::ASTC_2D_4X4>,
-        MortonCopy<true, PixelFormat::G8R8>,
+        MortonCopy<true, PixelFormat::G8R8U>,
+        MortonCopy<true, PixelFormat::G8R8S>,
         MortonCopy<true, PixelFormat::BGRA8>,
         MortonCopy<true, PixelFormat::RGBA32F>,
         MortonCopy<true, PixelFormat::RG32F>,
@@ -315,7 +317,8 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU
         nullptr,
         nullptr,
         nullptr,
-        MortonCopy<false, PixelFormat::G8R8>,
+        MortonCopy<false, PixelFormat::G8R8U>,
+        MortonCopy<false, PixelFormat::G8R8S>,
         MortonCopy<false, PixelFormat::BGRA8>,
         MortonCopy<false, PixelFormat::RGBA32F>,
         MortonCopy<false, PixelFormat::RG32F>,
@@ -461,7 +464,7 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height) {
 }
 
 static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) {
-    const auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::G8R8)};
+    const auto bpp{CachedSurface::GetGLBytesPerPixel(PixelFormat::G8R8U)};
     for (size_t y = 0; y < height; ++y) {
         for (size_t x = 0; x < width; ++x) {
             const size_t offset{bpp * (y * width + x)};
@@ -493,7 +496,8 @@ static void ConvertFormatAsNeeded_LoadGLBuffer(std::vector<u8>& data, PixelForma
         ConvertS8Z24ToZ24S8(data, width, height);
         break;
 
-    case PixelFormat::G8R8:
+    case PixelFormat::G8R8U:
+    case PixelFormat::G8R8S:
         // Convert the G8R8 color format to R8G8, as OpenGL does not support G8R8.
         ConvertG8R8ToR8G8(data, width, height);
         break;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 36a41522b..b6fb235e3 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -43,36 +43,37 @@ struct SurfaceParams {
         DXN2SNORM = 17,
         BC7U = 18,
         ASTC_2D_4X4 = 19,
-        G8R8 = 20,
-        BGRA8 = 21,
-        RGBA32F = 22,
-        RG32F = 23,
-        R32F = 24,
-        R16F = 25,
-        R16UNORM = 26,
-        R16S = 27,
-        R16UI = 28,
-        R16I = 29,
-        RG16 = 30,
-        RG16F = 31,
-        RG16UI = 32,
-        RG16I = 33,
-        RG16S = 34,
-        RGB32F = 35,
-        SRGBA8 = 36,
-        RG8U = 37,
-        RG8S = 38,
-        RG32UI = 39,
-        R32UI = 40,
+        G8R8U = 20,
+        G8R8S = 21,
+        BGRA8 = 22,
+        RGBA32F = 23,
+        RG32F = 24,
+        R32F = 25,
+        R16F = 26,
+        R16UNORM = 27,
+        R16S = 28,
+        R16UI = 29,
+        R16I = 30,
+        RG16 = 31,
+        RG16F = 32,
+        RG16UI = 33,
+        RG16I = 34,
+        RG16S = 35,
+        RGB32F = 36,
+        SRGBA8 = 37,
+        RG8U = 38,
+        RG8S = 39,
+        RG32UI = 40,
+        R32UI = 41,
 
         MaxColorFormat,
 
         // DepthStencil formats
-        Z24S8 = 41,
-        S8Z24 = 42,
-        Z32F = 43,
-        Z16 = 44,
-        Z32FS8 = 45,
+        Z24S8 = 42,
+        S8Z24 = 43,
+        Z32F = 44,
+        Z16 = 45,
+        Z32FS8 = 46,
 
         MaxDepthStencilFormat,
 
@@ -130,7 +131,8 @@ struct SurfaceParams {
             4, // DXN2SNORM
             4, // BC7U
             4, // ASTC_2D_4X4
-            1, // G8R8
+            1, // G8R8U
+            1, // G8R8S
             1, // BGRA8
             1, // RGBA32F
             1, // RG32F
@@ -187,7 +189,8 @@ struct SurfaceParams {
             128, // DXN2SNORM
             128, // BC7U
             32,  // ASTC_2D_4X4
-            16,  // G8R8
+            16,  // G8R8U
+            16,  // G8R8S
             32,  // BGRA8
             128, // RGBA32F
             64,  // RG32F
@@ -341,7 +344,15 @@ struct SurfaceParams {
                          static_cast<u32>(component_type));
             UNREACHABLE();
         case Tegra::Texture::TextureFormat::G8R8:
-            return PixelFormat::G8R8;
+            switch (component_type) {
+            case Tegra::Texture::ComponentType::UNORM:
+                return PixelFormat::G8R8U;
+            case Tegra::Texture::ComponentType::SNORM:
+                return PixelFormat::G8R8S;
+            }
+            LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
+                         static_cast<u32>(component_type));
+            UNREACHABLE();
         case Tegra::Texture::TextureFormat::R16_G16_B16_A16:
             return PixelFormat::RGBA16F;
         case Tegra::Texture::TextureFormat::BF10GF11RF11: