From e9610ec0dd3d47ae7dc2b14932faef0318d36125 Mon Sep 17 00:00:00 2001
From: Rodolfo Bogado <rodolfoosvaldobogado@gmail.com>
Date: Wed, 7 Nov 2018 00:25:16 -0300
Subject: [PATCH] set sampler max lod, min lod, lod bias and max anisotropy

---
 .../renderer_opengl/gl_rasterizer.cpp         | 31 +++++++++++++------
 .../renderer_opengl/gl_rasterizer.h           |  2 +-
 src/video_core/textures/texture.h             | 13 ++++++--
 3 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index a404764f5..40f474e07 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -740,9 +740,9 @@ void RasterizerOpenGL::SamplerInfo::Create() {
     glSamplerParameteri(sampler.handle, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
 }
 
-void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) {
+void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::FullTextureInfo& info) {
     const GLuint s = sampler.handle;
-
+    const Tegra::Texture::TSCEntry& config = info.tsc;
     if (mag_filter != config.mag_filter) {
         mag_filter = config.mag_filter;
         glSamplerParameteri(
@@ -793,6 +793,17 @@ void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntr
             glSamplerParameterfv(s, GL_TEXTURE_BORDER_COLOR, border_color.data());
         }
     }
+    if (info.tic.use_header_opt_control == 0) {
+        glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY_EXT,
+                            static_cast<float>(1 << info.tic.max_anisotropy.Value()));
+        glSamplerParameterf(s, GL_TEXTURE_MIN_LOD,
+                            static_cast<float>(info.tic.res_min_mip_level.Value()));
+        glSamplerParameterf(s, GL_TEXTURE_MAX_LOD,
+                            static_cast<float>(info.tic.res_max_mip_level.Value() == 0
+                                                   ? 16
+                                                   : info.tic.res_max_mip_level.Value()));
+        glSamplerParameterf(s, GL_TEXTURE_LOD_BIAS, info.tic.mip_lod_bias.Value() / 256.f);
+    }
 }
 
 u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, Shader& shader,
@@ -890,7 +901,7 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,
             continue;
         }
 
-        texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc);
+        texture_samplers[current_bindpoint].SyncWithConfig(texture);
         Surface surface = res_cache.GetTextureSurface(texture, entry);
         if (surface != nullptr) {
             state.texture_units[current_bindpoint].texture = surface->Texture().handle;
@@ -996,13 +1007,13 @@ void RasterizerOpenGL::SyncStencilTestState() {
     state.stencil.front.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_front_op_zpass);
     state.stencil.front.write_mask = regs.stencil_front_mask;
 
-    state.stencil.back.test_func = MaxwellToGL::ComparisonOp(regs.stencil_back_func_func);
-    state.stencil.back.test_ref = regs.stencil_back_func_ref;
-    state.stencil.back.test_mask = regs.stencil_back_func_mask;
-    state.stencil.back.action_stencil_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_fail);
-    state.stencil.back.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_zfail);
-    state.stencil.back.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_back_op_zpass);
-    state.stencil.back.write_mask = regs.stencil_back_mask;
+        state.stencil.back.test_func = MaxwellToGL::ComparisonOp(regs.stencil_back_func_func);
+        state.stencil.back.test_ref = regs.stencil_back_func_ref;
+        state.stencil.back.test_mask = regs.stencil_back_func_mask;
+        state.stencil.back.action_stencil_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_fail);
+        state.stencil.back.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_back_op_zfail);
+        state.stencil.back.action_depth_pass = MaxwellToGL::StencilOp(regs.stencil_back_op_zpass);
+        state.stencil.back.write_mask = regs.stencil_back_mask;
 }
 
 void RasterizerOpenGL::SyncColorMask() {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 5eee5f088..aa793caf2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -88,7 +88,7 @@ private:
         /// SamplerInfo struct.
         void Create();
         /// Syncs the sampler object with the config, updating any necessary state.
-        void SyncWithConfig(const Tegra::Texture::TSCEntry& config);
+        void SyncWithConfig(const Tegra::Texture::FullTextureInfo& info);
 
     private:
         Tegra::Texture::TextureFilter mag_filter;
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h
index d12d2ecb8..e199d019a 100644
--- a/src/video_core/textures/texture.h
+++ b/src/video_core/textures/texture.h
@@ -168,20 +168,29 @@ struct TICEntry {
 
         // High 16 bits of the pitch value
         BitField<0, 16, u32> pitch_high;
-
+        BitField<26, 1, u32> use_header_opt_control;
+        BitField<27, 1, u32> depth_texture;
         BitField<28, 4, u32> max_mip_level;
     };
     union {
         BitField<0, 16, u32> width_minus_1;
         BitField<22, 1, u32> srgb_conversion;
         BitField<23, 4, TextureType> texture_type;
+        BitField<29, 3, u32> border_size;
     };
     union {
         BitField<0, 16, u32> height_minus_1;
         BitField<16, 15, u32> depth_minus_1;
     };
+    union {
+        BitField<6, 13, u32> mip_lod_bias;
+        BitField<27, 3, u32> max_anisotropy;
+    };
 
-    INSERT_PADDING_BYTES(8);
+    union {
+        BitField<0, 4, u32> res_min_mip_level;
+        BitField<4, 4, u32> res_max_mip_level;
+    };
 
     GPUVAddr Address() const {
         return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | address_low);