From 009e34f08af52478148984bbf740784f3b068151 Mon Sep 17 00:00:00 2001
From: Subv <subv2112@gmail.com>
Date: Tue, 21 Jul 2015 16:26:09 -0500
Subject: [PATCH] GPU: Added registers for min and mag texture filters and
 implemented them in the hw renderer.

---
 src/video_core/pica.h                         |  7 +++++
 src/video_core/rasterizer.cpp                 |  1 +
 .../renderer_opengl/gl_rasterizer_cache.cpp   |  5 ++--
 src/video_core/renderer_opengl/pica_to_gl.h   | 27 +++++++++++++++++++
 4 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/src/video_core/pica.h b/src/video_core/pica.h
index 628e73213..6359471c7 100644
--- a/src/video_core/pica.h
+++ b/src/video_core/pica.h
@@ -119,6 +119,11 @@ struct Regs {
             MirroredRepeat = 3,
         };
 
+        enum TextureFilter : u32 {
+            Nearest = 0,
+            Linear  = 1
+        };
+
         union {
             BitField< 0, 8, u32> r;
             BitField< 8, 8, u32> g;
@@ -132,6 +137,8 @@ struct Regs {
         };
 
         union {
+            BitField< 1, 1, TextureFilter> mag_filter;
+            BitField< 2, 1, TextureFilter> min_filter;
             BitField< 8, 2, WrapMode> wrap_t;
             BitField<12, 2, WrapMode> wrap_s;
         };
diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp
index a6b7997ce..e2b90ad1c 100644
--- a/src/video_core/rasterizer.cpp
+++ b/src/video_core/rasterizer.cpp
@@ -460,6 +460,7 @@ static void ProcessTriangleInternal(const VertexShader::OutputVertex& v0,
                     u8* texture_data = Memory::GetPhysicalPointer(texture.config.GetPhysicalAddress());
                     auto info = DebugUtils::TextureInfo::FromPicaRegister(texture.config, texture.format);
 
+                    // TODO: Apply the min and mag filters to the texture
                     texture_color[i] = DebugUtils::LookupTexture(texture_data, s, t, info);
                     DebugUtils::DumpTexture(texture.config, texture_data);
                 }
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 2e4110a88..0e4f8e1ec 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -31,9 +31,8 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text
         state.texture_units[texture_unit].texture_2d = new_texture->texture.handle;
         state.Apply();
 
-        // TODO: Need to choose filters that correspond to PICA once register is declared
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, PicaToGL::TextureFilterMode(config.config.mag_filter));
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, PicaToGL::TextureFilterMode(config.config.min_filter));
 
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, PicaToGL::WrapMode(config.config.wrap_s));
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, PicaToGL::WrapMode(config.config.wrap_t));
diff --git a/src/video_core/renderer_opengl/pica_to_gl.h b/src/video_core/renderer_opengl/pica_to_gl.h
index 73f63c55d..3b562da86 100644
--- a/src/video_core/renderer_opengl/pica_to_gl.h
+++ b/src/video_core/renderer_opengl/pica_to_gl.h
@@ -12,6 +12,33 @@
 
 namespace PicaToGL {
 
+inline GLenum TextureFilterMode(Pica::Regs::TextureConfig::TextureFilter mode) {
+    static const GLenum filter_mode_table[] = {
+        GL_NEAREST,  // TextureFilter::Nearest
+        GL_LINEAR    // TextureFilter::Linear
+    };
+
+    // Range check table for input
+    if (mode >= ARRAY_SIZE(filter_mode_table)) {
+        LOG_CRITICAL(Render_OpenGL, "Unknown texture filtering mode %d", mode);
+        UNREACHABLE();
+
+        return GL_LINEAR;
+    }
+
+    GLenum gl_mode = filter_mode_table[mode];
+
+    // Check for dummy values indicating an unknown mode
+    if (gl_mode == 0) {
+        LOG_CRITICAL(Render_OpenGL, "Unknown texture filtering mode %d", mode);
+        UNIMPLEMENTED();
+
+        return GL_LINEAR;
+    }
+
+    return gl_mode;
+}
+
 inline GLenum WrapMode(Pica::Regs::TextureConfig::WrapMode mode) {
     static const GLenum wrap_mode_table[] = {
         GL_CLAMP_TO_EDGE,  // WrapMode::ClampToEdge