From c56a0e3c34f29a439daa3b0df867480fac9780c3 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Sun, 12 Aug 2018 23:02:34 -0400
Subject: [PATCH] renderer_opengl: Implement RenderTargetFormat::RG8_UNORM.

- Used by Breath of the Wild.
---
 src/video_core/gpu.cpp                        |  1 +
 src/video_core/gpu.h                          |  1 +
 .../renderer_opengl/gl_rasterizer_cache.cpp   | 67 +++++++++++++------
 .../renderer_opengl/gl_rasterizer_cache.h     | 18 +++--
 4 files changed, 61 insertions(+), 26 deletions(-)

diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 19e7f11613..9c73d7546f 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -67,6 +67,7 @@ u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
     case RenderTargetFormat::R16_UINT:
     case RenderTargetFormat::R16_SINT:
     case RenderTargetFormat::R16_FLOAT:
+    case RenderTargetFormat::RG8_UNORM:
     case RenderTargetFormat::RG8_SNORM:
         return 2;
     case RenderTargetFormat::R8_UNORM:
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index e008d8f262..0b6521985d 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -35,6 +35,7 @@ enum class RenderTargetFormat : u32 {
     R11G11B10_FLOAT = 0xE0,
     R32_FLOAT = 0xE5,
     B5G6R5_UNORM = 0xE8,
+    RG8_UNORM = 0xEA,
     RG8_SNORM = 0xEB,
     R16_UNORM = 0xEE,
     R16_SNORM = 0xEF,
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 84c250c631..a74ca35956 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -134,6 +134,7 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
     {GL_RG16_SNORM, GL_RG, GL_SHORT, ComponentType::SNorm, false},             // RG16S
     {GL_RGB32F, GL_RGB, GL_FLOAT, ComponentType::Float, false},                // RGB32F
     {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // SRGBA8
+    {GL_RG8, GL_RG, GL_UNSIGNED_BYTE, ComponentType::UNorm, false},                       // RG8U
     {GL_RG8, GL_RG, GL_BYTE, ComponentType::SNorm, false},                                // RG8S
 
     // DepthStencil formats
@@ -234,32 +235,56 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_bu
 static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPUVAddr),
                             SurfaceParams::MaxPixelFormat>
     morton_to_gl_fns = {
-        MortonCopy<true, PixelFormat::ABGR8U>,       MortonCopy<true, PixelFormat::ABGR8S>,
-        MortonCopy<true, PixelFormat::B5G6R5>,       MortonCopy<true, PixelFormat::A2B10G10R10>,
-        MortonCopy<true, PixelFormat::A1B5G5R5>,     MortonCopy<true, PixelFormat::R8>,
-        MortonCopy<true, PixelFormat::R8UI>,         MortonCopy<true, PixelFormat::RGBA16F>,
-        MortonCopy<true, PixelFormat::R11FG11FB10F>, MortonCopy<true, PixelFormat::RGBA32UI>,
-        MortonCopy<true, PixelFormat::DXT1>,         MortonCopy<true, PixelFormat::DXT23>,
-        MortonCopy<true, PixelFormat::DXT45>,        MortonCopy<true, PixelFormat::DXN1>,
-        MortonCopy<true, PixelFormat::DXN2UNORM>,    MortonCopy<true, PixelFormat::DXN2SNORM>,
-        MortonCopy<true, PixelFormat::BC7U>,         MortonCopy<true, PixelFormat::ASTC_2D_4X4>,
-        MortonCopy<true, PixelFormat::G8R8>,         MortonCopy<true, PixelFormat::BGRA8>,
-        MortonCopy<true, PixelFormat::RGBA32F>,      MortonCopy<true, PixelFormat::RG32F>,
-        MortonCopy<true, PixelFormat::R32F>,         MortonCopy<true, PixelFormat::R16F>,
-        MortonCopy<true, PixelFormat::R16UNORM>,     MortonCopy<true, PixelFormat::R16S>,
-        MortonCopy<true, PixelFormat::R16UI>,        MortonCopy<true, PixelFormat::R16I>,
-        MortonCopy<true, PixelFormat::RG16>,         MortonCopy<true, PixelFormat::RG16F>,
-        MortonCopy<true, PixelFormat::RG16UI>,       MortonCopy<true, PixelFormat::RG16I>,
-        MortonCopy<true, PixelFormat::RG16S>,        MortonCopy<true, PixelFormat::RGB32F>,
-        MortonCopy<true, PixelFormat::SRGBA8>,       MortonCopy<true, PixelFormat::RG8S>,
-        MortonCopy<true, PixelFormat::Z24S8>,        MortonCopy<true, PixelFormat::S8Z24>,
-        MortonCopy<true, PixelFormat::Z32F>,         MortonCopy<true, PixelFormat::Z16>,
+        // clang-format off
+        MortonCopy<true, PixelFormat::ABGR8U>,
+        MortonCopy<true, PixelFormat::ABGR8S>,
+        MortonCopy<true, PixelFormat::B5G6R5>,
+        MortonCopy<true, PixelFormat::A2B10G10R10>,
+        MortonCopy<true, PixelFormat::A1B5G5R5>,
+        MortonCopy<true, PixelFormat::R8>,
+        MortonCopy<true, PixelFormat::R8UI>,
+        MortonCopy<true, PixelFormat::RGBA16F>,
+        MortonCopy<true, PixelFormat::R11FG11FB10F>,
+        MortonCopy<true, PixelFormat::RGBA32UI>,
+        MortonCopy<true, PixelFormat::DXT1>,
+        MortonCopy<true, PixelFormat::DXT23>,
+        MortonCopy<true, PixelFormat::DXT45>,
+        MortonCopy<true, PixelFormat::DXN1>,
+        MortonCopy<true, PixelFormat::DXN2UNORM>,
+        MortonCopy<true, PixelFormat::DXN2SNORM>,
+        MortonCopy<true, PixelFormat::BC7U>,
+        MortonCopy<true, PixelFormat::ASTC_2D_4X4>,
+        MortonCopy<true, PixelFormat::G8R8>,
+        MortonCopy<true, PixelFormat::BGRA8>,
+        MortonCopy<true, PixelFormat::RGBA32F>,
+        MortonCopy<true, PixelFormat::RG32F>,
+        MortonCopy<true, PixelFormat::R32F>,
+        MortonCopy<true, PixelFormat::R16F>,
+        MortonCopy<true, PixelFormat::R16UNORM>,
+        MortonCopy<true, PixelFormat::R16S>,
+        MortonCopy<true, PixelFormat::R16UI>,
+        MortonCopy<true, PixelFormat::R16I>,
+        MortonCopy<true, PixelFormat::RG16>,
+        MortonCopy<true, PixelFormat::RG16F>,
+        MortonCopy<true, PixelFormat::RG16UI>,
+        MortonCopy<true, PixelFormat::RG16I>,
+        MortonCopy<true, PixelFormat::RG16S>,
+        MortonCopy<true, PixelFormat::RGB32F>,
+        MortonCopy<true, PixelFormat::SRGBA8>,
+        MortonCopy<true, PixelFormat::RG8U>,
+        MortonCopy<true, PixelFormat::RG8S>,
+        MortonCopy<true, PixelFormat::Z24S8>,
+        MortonCopy<true, PixelFormat::S8Z24>,
+        MortonCopy<true, PixelFormat::Z32F>,
+        MortonCopy<true, PixelFormat::Z16>,
         MortonCopy<true, PixelFormat::Z32FS8>,
+        // clang-format on
 };
 
 static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPUVAddr),
                             SurfaceParams::MaxPixelFormat>
     gl_to_morton_fns = {
+        // clang-format off
         MortonCopy<false, PixelFormat::ABGR8U>,
         MortonCopy<false, PixelFormat::ABGR8S>,
         MortonCopy<false, PixelFormat::B5G6R5>,
@@ -297,12 +322,14 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU
         MortonCopy<false, PixelFormat::RG16S>,
         MortonCopy<false, PixelFormat::RGB32F>,
         MortonCopy<false, PixelFormat::SRGBA8>,
+        MortonCopy<false, PixelFormat::RG8U>,
         MortonCopy<false, PixelFormat::RG8S>,
         MortonCopy<false, PixelFormat::Z24S8>,
         MortonCopy<false, PixelFormat::S8Z24>,
         MortonCopy<false, PixelFormat::Z32F>,
         MortonCopy<false, PixelFormat::Z16>,
         MortonCopy<false, PixelFormat::Z32FS8>,
+        // clang-format on
 };
 
 // Allocate an uninitialized texture of appropriate size and format for the surface
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 202257b582..ffed663947 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -58,16 +58,17 @@ struct SurfaceParams {
         RG16S = 32,
         RGB32F = 33,
         SRGBA8 = 34,
-        RG8S = 35,
+        RG8U = 35,
+        RG8S = 36,
 
         MaxColorFormat,
 
         // DepthStencil formats
-        Z24S8 = 36,
-        S8Z24 = 37,
-        Z32F = 38,
-        Z16 = 39,
-        Z32FS8 = 40,
+        Z24S8 = 37,
+        S8Z24 = 38,
+        Z32F = 39,
+        Z16 = 40,
+        Z32FS8 = 41,
 
         MaxDepthStencilFormat,
 
@@ -140,6 +141,7 @@ struct SurfaceParams {
             1, // RG16S
             1, // RGB32F
             1, // SRGBA8
+            1, // RG8U
             1, // RG8S
             1, // Z24S8
             1, // S8Z24
@@ -192,6 +194,7 @@ struct SurfaceParams {
             32,  // RG16S
             96,  // RGB32F
             32,  // SRGBA8
+            16,  // RG8U
             16,  // RG8S
             32,  // Z24S8
             32,  // S8Z24
@@ -265,6 +268,8 @@ struct SurfaceParams {
             return PixelFormat::RG16;
         case Tegra::RenderTargetFormat::RG16_SNORM:
             return PixelFormat::RG16S;
+        case Tegra::RenderTargetFormat::RG8_UNORM:
+            return PixelFormat::RG8U;
         case Tegra::RenderTargetFormat::RG8_SNORM:
             return PixelFormat::RG8S;
         case Tegra::RenderTargetFormat::R16_FLOAT:
@@ -432,6 +437,7 @@ struct SurfaceParams {
         case Tegra::RenderTargetFormat::RG16_UNORM:
         case Tegra::RenderTargetFormat::R16_UNORM:
         case Tegra::RenderTargetFormat::B5G6R5_UNORM:
+        case Tegra::RenderTargetFormat::RG8_UNORM:
             return ComponentType::UNorm;
         case Tegra::RenderTargetFormat::RGBA8_SNORM:
         case Tegra::RenderTargetFormat::RG16_SNORM: