From bdf17fe0ccacf8c59fdcd49528b649ad606b4462 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Mon, 13 Aug 2018 00:04:52 -0400
Subject: [PATCH] renderer_opengl: Implement RenderTargetFormat::RGBA16_UINT.

- Used by Breath of the Wild.
---
 src/video_core/gpu.cpp                        |  1 +
 src/video_core/gpu.h                          |  1 +
 .../renderer_opengl/gl_rasterizer_cache.cpp   |  3 +
 .../renderer_opengl/gl_rasterizer_cache.h     | 74 ++++++++++---------
 4 files changed, 45 insertions(+), 34 deletions(-)

diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 9c73d7546..6f0343888 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -46,6 +46,7 @@ u32 RenderTargetBytesPerPixel(RenderTargetFormat format) {
     case RenderTargetFormat::RGBA32_FLOAT:
     case RenderTargetFormat::RGBA32_UINT:
         return 16;
+    case RenderTargetFormat::RGBA16_UINT:
     case RenderTargetFormat::RGBA16_FLOAT:
     case RenderTargetFormat::RG32_FLOAT:
         return 8;
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 0b6521985..73abb7a18 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -20,6 +20,7 @@ enum class RenderTargetFormat : u32 {
     NONE = 0x0,
     RGBA32_FLOAT = 0xC0,
     RGBA32_UINT = 0xC2,
+    RGBA16_UINT = 0xC9,
     RGBA16_FLOAT = 0xCA,
     RG32_FLOAT = 0xCB,
     BGRA8_UNORM = 0xCF,
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index a74ca3595..d635550d2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -101,6 +101,7 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
     {GL_R8, GL_RED, GL_UNSIGNED_BYTE, ComponentType::UNorm, false},                    // R8
     {GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, ComponentType::UInt, false},           // R8UI
     {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, ComponentType::Float, false},                 // RGBA16F
+    {GL_RGBA16UI, GL_RGBA, GL_UNSIGNED_SHORT, ComponentType::UInt, false},             // RGBA16UI
     {GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, ComponentType::Float,
      false},                                                                     // R11FG11FB10F
     {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, ComponentType::UInt, false}, // RGBA32UI
@@ -244,6 +245,7 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU
         MortonCopy<true, PixelFormat::R8>,
         MortonCopy<true, PixelFormat::R8UI>,
         MortonCopy<true, PixelFormat::RGBA16F>,
+        MortonCopy<true, PixelFormat::RGBA16UI>,
         MortonCopy<true, PixelFormat::R11FG11FB10F>,
         MortonCopy<true, PixelFormat::RGBA32UI>,
         MortonCopy<true, PixelFormat::DXT1>,
@@ -293,6 +295,7 @@ static constexpr std::array<void (*)(u32, u32, u32, std::vector<u8>&, Tegra::GPU
         MortonCopy<false, PixelFormat::R8>,
         MortonCopy<false, PixelFormat::R8UI>,
         MortonCopy<false, PixelFormat::RGBA16F>,
+        MortonCopy<false, PixelFormat::RGBA16UI>,
         MortonCopy<false, PixelFormat::R11FG11FB10F>,
         MortonCopy<false, PixelFormat::RGBA32UI>,
         // TODO(Subv): Swizzling DXT1/DXT23/DXT45/DXN1/DXN2/BC7U/ASTC_2D_4X4 formats is not
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index ffed66394..4ab74342e 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -31,44 +31,45 @@ struct SurfaceParams {
         R8 = 5,
         R8UI = 6,
         RGBA16F = 7,
-        R11FG11FB10F = 8,
-        RGBA32UI = 9,
-        DXT1 = 10,
-        DXT23 = 11,
-        DXT45 = 12,
-        DXN1 = 13, // This is also known as BC4
-        DXN2UNORM = 14,
-        DXN2SNORM = 15,
-        BC7U = 16,
-        ASTC_2D_4X4 = 17,
-        G8R8 = 18,
-        BGRA8 = 19,
-        RGBA32F = 20,
-        RG32F = 21,
-        R32F = 22,
-        R16F = 23,
-        R16UNORM = 24,
-        R16S = 25,
-        R16UI = 26,
-        R16I = 27,
-        RG16 = 28,
-        RG16F = 29,
-        RG16UI = 30,
-        RG16I = 31,
-        RG16S = 32,
-        RGB32F = 33,
-        SRGBA8 = 34,
-        RG8U = 35,
-        RG8S = 36,
+        RGBA16UI = 8,
+        R11FG11FB10F = 9,
+        RGBA32UI = 10,
+        DXT1 = 11,
+        DXT23 = 12,
+        DXT45 = 13,
+        DXN1 = 14, // This is also known as BC4
+        DXN2UNORM = 15,
+        DXN2SNORM = 16,
+        BC7U = 17,
+        ASTC_2D_4X4 = 18,
+        G8R8 = 19,
+        BGRA8 = 20,
+        RGBA32F = 21,
+        RG32F = 22,
+        R32F = 23,
+        R16F = 24,
+        R16UNORM = 25,
+        R16S = 26,
+        R16UI = 27,
+        R16I = 28,
+        RG16 = 29,
+        RG16F = 30,
+        RG16UI = 31,
+        RG16I = 32,
+        RG16S = 33,
+        RGB32F = 34,
+        SRGBA8 = 35,
+        RG8U = 36,
+        RG8S = 37,
 
         MaxColorFormat,
 
         // DepthStencil formats
-        Z24S8 = 37,
-        S8Z24 = 38,
-        Z32F = 39,
-        Z16 = 40,
-        Z32FS8 = 41,
+        Z24S8 = 38,
+        S8Z24 = 39,
+        Z32F = 40,
+        Z16 = 41,
+        Z32FS8 = 42,
 
         MaxDepthStencilFormat,
 
@@ -114,6 +115,7 @@ struct SurfaceParams {
             1, // R8
             1, // R8UI
             1, // RGBA16F
+            1, // RGBA16UI
             1, // R11FG11FB10F
             1, // RGBA32UI
             4, // DXT1
@@ -167,6 +169,7 @@ struct SurfaceParams {
             8,   // R8
             8,   // R8UI
             64,  // RGBA16F
+            64,  // RGBA16UI
             32,  // R11FG11FB10F
             128, // RGBA32UI
             64,  // DXT1
@@ -244,6 +247,8 @@ struct SurfaceParams {
             return PixelFormat::A2B10G10R10;
         case Tegra::RenderTargetFormat::RGBA16_FLOAT:
             return PixelFormat::RGBA16F;
+        case Tegra::RenderTargetFormat::RGBA16_UINT:
+            return PixelFormat::RGBA16UI;
         case Tegra::RenderTargetFormat::RGBA32_FLOAT:
             return PixelFormat::RGBA32F;
         case Tegra::RenderTargetFormat::RG32_FLOAT:
@@ -453,6 +458,7 @@ struct SurfaceParams {
         case Tegra::RenderTargetFormat::R32_FLOAT:
             return ComponentType::Float;
         case Tegra::RenderTargetFormat::RGBA32_UINT:
+        case Tegra::RenderTargetFormat::RGBA16_UINT:
         case Tegra::RenderTargetFormat::RG16_UINT:
         case Tegra::RenderTargetFormat::R8_UINT:
         case Tegra::RenderTargetFormat::R16_UINT: