diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 5ae836acaeb8897d7f734401ecebf62428327e77..d1777b25bdcdd21fd9c0501112262017e641d98a 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -53,6 +53,19 @@ void Maxwell3D::InitializeRegisterDefaults() {
         regs.independent_blend[blend_index].factor_source_a = Regs::Blend::Factor::One;
         regs.independent_blend[blend_index].factor_dest_a = Regs::Blend::Factor::Zero;
     }
+    regs.stencil_front_op_fail = Regs::StencilOp::Keep;
+    regs.stencil_front_op_zfail = Regs::StencilOp::Keep;
+    regs.stencil_front_op_zpass = Regs::StencilOp::Keep;
+    regs.stencil_front_func_func = Regs::ComparisonOp::Always;
+    regs.stencil_front_func_mask = 0xFFFFFFFF;
+    regs.stencil_front_mask = 0xFFFFFFFF;
+    regs.stencil_two_side_enable = 1;
+    regs.stencil_back_op_fail = Regs::StencilOp::Keep;
+    regs.stencil_back_op_zfail = Regs::StencilOp::Keep;
+    regs.stencil_back_op_zpass = Regs::StencilOp::Keep;
+    regs.stencil_back_func_func = Regs::ComparisonOp::Always;
+    regs.stencil_back_func_mask = 0xFFFFFFFF;
+    regs.stencil_back_mask = 0xFFFFFFFF;
 }
 
 void Maxwell3D::CallMacroMethod(u32 method, std::vector<u32> parameters) {
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 557795d0f7a51b0c3e630cb67c8c6483417ba654..91ca5788303ebcf0e9a8b68d6837982665ddb461 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -345,6 +345,14 @@ public:
             Invert = 6,
             IncrWrap = 7,
             DecrWrap = 8,
+            KeepOGL = 0x1E00,
+            ZeroOGL = 0,
+            ReplaceOGL = 0x1E01,
+            IncrOGL = 0x1E02,
+            DecrOGL = 0x1E03,
+            InvertOGL = 0x150A,
+            IncrWrapOGL = 0x8507,
+            DecrWrapOGL = 0x8508,
         };
 
         enum class MemoryLayout : u32 {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index a99f2b1f95c769b4a65511f6c873ac5a0ee93d40..54cc47a9bb7f8cd4e2aee95a91b76d92bf82b736 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -140,7 +140,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
     if (is_cache_miss) {
         VAO.Create();
         state.draw.vertex_array = VAO.handle;
-        state.Apply();
+        state.ApplyVertexBufferState();
 
         // The index buffer binding is stored within the VAO. Stupid OpenGL, but easy to work
         // around.
@@ -182,7 +182,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
         }
     }
     state.draw.vertex_array = VAO.handle;
-    state.Apply();
+    state.ApplyVertexBufferState();
 }
 
 void RasterizerOpenGL::SetupVertexBuffer() {
@@ -342,8 +342,6 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
             index++;
         }
     }
-
-    state.Apply();
 }
 
 std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
@@ -412,8 +410,8 @@ void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
         cached_pages.add({pages_interval, delta});
 }
 
-void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_depth_fb,
-                                             bool preserve_contents,
+void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool using_color_fb,
+                                             bool using_depth_fb, bool preserve_contents,
                                              std::optional<std::size_t> single_color_target) {
     MICROPROFILE_SCOPE(OpenGL_Framebuffer);
     const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
@@ -429,9 +427,9 @@ void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_dep
     ASSERT_MSG(regs.rt_separate_frag_data == 0, "Unimplemented");
 
     // Bind the framebuffer surfaces
-    state.draw.draw_framebuffer = framebuffer.handle;
-    state.Apply();
-    state.framebuffer_srgb.enabled = regs.framebuffer_srgb != 0;
+    current_state.draw.draw_framebuffer = framebuffer.handle;
+    current_state.ApplyFramebufferState();
+    current_state.framebuffer_srgb.enabled = regs.framebuffer_srgb != 0;
 
     if (using_color_fb) {
         if (single_color_target) {
@@ -509,10 +507,7 @@ void RasterizerOpenGL::ConfigureFramebuffers(bool using_color_fb, bool using_dep
         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
                                0);
     }
-
-    SyncViewport();
-
-    state.Apply();
+    SyncViewport(current_state);
 }
 
 void RasterizerOpenGL::Clear() {
@@ -525,22 +520,23 @@ void RasterizerOpenGL::Clear() {
     bool use_stencil{};
 
     OpenGLState clear_state;
-    clear_state.draw.draw_framebuffer = framebuffer.handle;
-    clear_state.color_mask[0].red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE;
-    clear_state.color_mask[0].green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE;
-    clear_state.color_mask[0].blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE;
-    clear_state.color_mask[0].alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE;
-
     if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
         regs.clear_buffers.A) {
         use_color = true;
     }
+    if (use_color) {
+        clear_state.color_mask[0].red_enabled = regs.clear_buffers.R ? GL_TRUE : GL_FALSE;
+        clear_state.color_mask[0].green_enabled = regs.clear_buffers.G ? GL_TRUE : GL_FALSE;
+        clear_state.color_mask[0].blue_enabled = regs.clear_buffers.B ? GL_TRUE : GL_FALSE;
+        clear_state.color_mask[0].alpha_enabled = regs.clear_buffers.A ? GL_TRUE : GL_FALSE;
+    }
     if (regs.clear_buffers.Z) {
         ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!");
         use_depth = true;
 
         // Always enable the depth write when clearing the depth buffer. The depth write mask is
-        // ignored when clearing the buffer in the Switch, but OpenGL obeys it so we set it to true.
+        // ignored when clearing the buffer in the Switch, but OpenGL obeys it so we set it to
+        // true.
         clear_state.depth.test_enabled = true;
         clear_state.depth.test_func = GL_ALWAYS;
     }
@@ -557,11 +553,8 @@ void RasterizerOpenGL::Clear() {
 
     ScopeAcquireGLContext acquire_context{emu_window};
 
-    ConfigureFramebuffers(use_color, use_depth || use_stencil, false,
+    ConfigureFramebuffers(clear_state, use_color, use_depth || use_stencil, false,
                           regs.clear_buffers.RT.Value());
-    // Copy the sRGB setting to the clear state to avoid problem with
-    // specific driver implementations
-    clear_state.framebuffer_srgb.enabled = state.framebuffer_srgb.enabled;
     clear_state.Apply();
 
     if (use_color) {
@@ -587,7 +580,7 @@ void RasterizerOpenGL::DrawArrays() {
 
     ScopeAcquireGLContext acquire_context{emu_window};
 
-    ConfigureFramebuffers();
+    ConfigureFramebuffers(state);
     SyncColorMask();
     SyncDepthTestState();
     SyncStencilTestState();
@@ -608,7 +601,7 @@ void RasterizerOpenGL::DrawArrays() {
     const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
 
     state.draw.vertex_buffer = buffer_cache.GetHandle();
-    state.Apply();
+    state.ApplyVertexBufferState();
 
     std::size_t buffer_size = CalculateVertexArraysSize();
 
@@ -740,9 +733,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 +786,22 @@ 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) {
+        if (GLAD_GL_ARB_texture_filter_anisotropic) {
+            glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY,
+                                static_cast<float>(1 << info.tic.max_anisotropy.Value()));
+        } else if (GLAD_GL_EXT_texture_filter_anisotropic) {
+            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 +899,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;
@@ -912,11 +921,11 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,
     return current_unit + static_cast<u32>(entries.size());
 }
 
-void RasterizerOpenGL::SyncViewport() {
+void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
     const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
     for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
         const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()};
-        auto& viewport = state.viewports[i];
+        auto& viewport = current_state.viewports[i];
         viewport.x = viewport_rect.left;
         viewport.y = viewport_rect.bottom;
         viewport.width = static_cast<GLfloat>(viewport_rect.GetWidth());
@@ -985,9 +994,6 @@ void RasterizerOpenGL::SyncStencilTestState() {
         return;
     }
 
-    // TODO(bunnei): Verify behavior when this is not set
-    ASSERT(regs.stencil_two_side_enable);
-
     state.stencil.front.test_func = MaxwellToGL::ComparisonOp(regs.stencil_front_func_func);
     state.stencil.front.test_ref = regs.stencil_front_func_ref;
     state.stencil.front.test_mask = regs.stencil_front_func_mask;
@@ -995,14 +1001,23 @@ void RasterizerOpenGL::SyncStencilTestState() {
     state.stencil.front.action_depth_fail = MaxwellToGL::StencilOp(regs.stencil_front_op_zfail);
     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;
+    if (regs.stencil_two_side_enable) {
+        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;
+    } else {
+        state.stencil.back.test_func = GL_ALWAYS;
+        state.stencil.back.test_ref = 0;
+        state.stencil.back.test_mask = 0xFFFFFFFF;
+        state.stencil.back.write_mask = 0xFFFFFFFF;
+        state.stencil.back.action_stencil_fail = GL_KEEP;
+        state.stencil.back.action_depth_fail = GL_KEEP;
+        state.stencil.back.action_depth_pass = GL_KEEP;
+    }
 }
 
 void RasterizerOpenGL::SyncColorMask() {
@@ -1114,9 +1129,8 @@ void RasterizerOpenGL::CheckAlphaTests() {
     const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
 
     if (regs.alpha_test_enabled != 0 && regs.rt_control.count > 1) {
-        LOG_CRITICAL(
-            Render_OpenGL,
-            "Alpha Testing is enabled with Multiple Render Targets, this behavior is undefined.");
+        LOG_CRITICAL(Render_OpenGL, "Alpha Testing is enabled with Multiple Render Targets, "
+                                    "this behavior is undefined.");
         UNREACHABLE();
     }
 }
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 5eee5f0888f03c02ecee463acb70ed5d1e219a58..8ef0f6c129d7fedc7a5c65694b4e800dbf7fa8d6 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;
@@ -109,8 +109,8 @@ private:
      * @param preserve_contents If true, tries to preserve data from a previously used framebuffer.
      * @param single_color_target Specifies if a single color buffer target should be used.
      */
-    void ConfigureFramebuffers(bool use_color_fb = true, bool using_depth_fb = true,
-                               bool preserve_contents = true,
+    void ConfigureFramebuffers(OpenGLState& current_state, bool use_color_fb = true,
+                               bool using_depth_fb = true, bool preserve_contents = true,
                                std::optional<std::size_t> single_color_target = {});
 
     /*
@@ -134,7 +134,7 @@ private:
                       GLenum primitive_mode, u32 current_unit);
 
     /// Syncs the viewport and depth range to match the guest state
-    void SyncViewport();
+    void SyncViewport(OpenGLState& current_state);
 
     /// Syncs the clip enabled status to match the guest state
     void SyncClipEnabled();
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index c8864cce89745b9685f45c10ed44b52a4090d4ef..894f4f2944a3f69b699cc1d9db14054ba8ceff1c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -580,7 +580,7 @@ static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
     state.draw.draw_framebuffer = draw_fb_handle;
     // Set sRGB enabled if the destination surfaces need it
     state.framebuffer_srgb.enabled = dst_params.srgb_conversion;
-    state.Apply();
+    state.ApplyFramebufferState();
 
     u32 buffers{};
 
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 9517285e560908f0280be39bb62f4c8bee1c604e..2635f2b0cdef8b49a776b3db8002e0e0869ca9e5 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -427,7 +427,7 @@ void OpenGLState::ApplySamplers() const {
     }
 }
 
-void OpenGLState::Apply() const {
+void OpenGLState::ApplyFramebufferState() const {
     // Framebuffer
     if (draw.read_framebuffer != cur_state.draw.read_framebuffer) {
         glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer);
@@ -435,7 +435,9 @@ void OpenGLState::Apply() const {
     if (draw.draw_framebuffer != cur_state.draw.draw_framebuffer) {
         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw.draw_framebuffer);
     }
+}
 
+void OpenGLState::ApplyVertexBufferState() const {
     // Vertex array
     if (draw.vertex_array != cur_state.draw.vertex_array) {
         glBindVertexArray(draw.vertex_array);
@@ -445,7 +447,11 @@ void OpenGLState::Apply() const {
     if (draw.vertex_buffer != cur_state.draw.vertex_buffer) {
         glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer);
     }
+}
 
+void OpenGLState::Apply() const {
+    ApplyFramebufferState();
+    ApplyVertexBufferState();
     // Uniform buffer
     if (draw.uniform_buffer != cur_state.draw.uniform_buffer) {
         glBindBuffer(GL_UNIFORM_BUFFER, draw.uniform_buffer);
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index b8cf1f637c376ae39e6a150d1a188c44ed1e4477..eacca0b9cdb50dbdb600fcc4f2c07421c5a87096 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -181,6 +181,10 @@ public:
     }
     /// Apply this state as the current OpenGL state
     void Apply() const;
+    /// Apply only the state afecting the framebuffer
+    void ApplyFramebufferState() const;
+    /// Apply only the state afecting the vertex buffer
+    void ApplyVertexBufferState() const;
     /// Set the initial OpenGL state
     static void ApplyDefaultState();
     /// Resets any references to the given resource
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index 87d511c381901cb2a4e01d6a2b268173cdda39cf..3ce2cc6d2733e73b6d0bbb59a4a5e8e41dde6b64 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -159,10 +159,8 @@ inline GLenum TextureFilterMode(Tegra::Texture::TextureFilter filter_mode,
         }
     }
     }
-    LOG_CRITICAL(Render_OpenGL, "Unimplemented texture filter mode={}",
-                 static_cast<u32>(filter_mode));
-    UNREACHABLE();
-    return {};
+    LOG_ERROR(Render_OpenGL, "Unimplemented texture filter mode={}", static_cast<u32>(filter_mode));
+    return GL_LINEAR;
 }
 
 inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) {
@@ -183,9 +181,8 @@ inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) {
     case Tegra::Texture::WrapMode::MirrorOnceClampToEdge:
         return GL_MIRROR_CLAMP_TO_EDGE;
     }
-    LOG_CRITICAL(Render_OpenGL, "Unimplemented texture wrap mode={}", static_cast<u32>(wrap_mode));
-    UNREACHABLE();
-    return {};
+    LOG_ERROR(Render_OpenGL, "Unimplemented texture wrap mode={}", static_cast<u32>(wrap_mode));
+    return GL_REPEAT;
 }
 
 inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) {
@@ -207,10 +204,9 @@ inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) {
     case Tegra::Texture::DepthCompareFunc::Always:
         return GL_ALWAYS;
     }
-    LOG_CRITICAL(Render_OpenGL, "Unimplemented texture depth compare function ={}",
-                 static_cast<u32>(func));
-    UNREACHABLE();
-    return {};
+    LOG_ERROR(Render_OpenGL, "Unimplemented texture depth compare function ={}",
+              static_cast<u32>(func));
+    return GL_GREATER;
 }
 
 inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
@@ -226,9 +222,8 @@ inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
     case Maxwell::Blend::Equation::Max:
         return GL_MAX;
     }
-    LOG_CRITICAL(Render_OpenGL, "Unimplemented blend equation={}", static_cast<u32>(equation));
-    UNREACHABLE();
-    return {};
+    LOG_ERROR(Render_OpenGL, "Unimplemented blend equation={}", static_cast<u32>(equation));
+    return GL_FUNC_ADD;
 }
 
 inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
@@ -291,9 +286,8 @@ inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
     case Maxwell::Blend::Factor::OneMinusConstantAlphaGL:
         return GL_ONE_MINUS_CONSTANT_ALPHA;
     }
-    LOG_CRITICAL(Render_OpenGL, "Unimplemented blend factor={}", static_cast<u32>(factor));
-    UNREACHABLE();
-    return {};
+    LOG_ERROR(Render_OpenGL, "Unimplemented blend factor={}", static_cast<u32>(factor));
+    return GL_ZERO;
 }
 
 inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) {
@@ -312,9 +306,8 @@ inline GLenum SwizzleSource(Tegra::Texture::SwizzleSource source) {
     case Tegra::Texture::SwizzleSource::OneFloat:
         return GL_ONE;
     }
-    LOG_CRITICAL(Render_OpenGL, "Unimplemented swizzle source={}", static_cast<u32>(source));
-    UNREACHABLE();
-    return {};
+    LOG_ERROR(Render_OpenGL, "Unimplemented swizzle source={}", static_cast<u32>(source));
+    return GL_ZERO;
 }
 
 inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
@@ -344,33 +337,39 @@ inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
     case Maxwell::ComparisonOp::AlwaysOld:
         return GL_ALWAYS;
     }
-    LOG_CRITICAL(Render_OpenGL, "Unimplemented comparison op={}", static_cast<u32>(comparison));
-    UNREACHABLE();
-    return {};
+    LOG_ERROR(Render_OpenGL, "Unimplemented comparison op={}", static_cast<u32>(comparison));
+    return GL_ALWAYS;
 }
 
 inline GLenum StencilOp(Maxwell::StencilOp stencil) {
     switch (stencil) {
     case Maxwell::StencilOp::Keep:
+    case Maxwell::StencilOp::KeepOGL:
         return GL_KEEP;
     case Maxwell::StencilOp::Zero:
+    case Maxwell::StencilOp::ZeroOGL:
         return GL_ZERO;
     case Maxwell::StencilOp::Replace:
+    case Maxwell::StencilOp::ReplaceOGL:
         return GL_REPLACE;
     case Maxwell::StencilOp::Incr:
+    case Maxwell::StencilOp::IncrOGL:
         return GL_INCR;
     case Maxwell::StencilOp::Decr:
+    case Maxwell::StencilOp::DecrOGL:
         return GL_DECR;
     case Maxwell::StencilOp::Invert:
+    case Maxwell::StencilOp::InvertOGL:
         return GL_INVERT;
     case Maxwell::StencilOp::IncrWrap:
+    case Maxwell::StencilOp::IncrWrapOGL:
         return GL_INCR_WRAP;
     case Maxwell::StencilOp::DecrWrap:
+    case Maxwell::StencilOp::DecrWrapOGL:
         return GL_DECR_WRAP;
     }
-    LOG_CRITICAL(Render_OpenGL, "Unimplemented stencil op={}", static_cast<u32>(stencil));
-    UNREACHABLE();
-    return {};
+    LOG_ERROR(Render_OpenGL, "Unimplemented stencil op={}", static_cast<u32>(stencil));
+    return GL_KEEP;
 }
 
 inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) {
@@ -380,9 +379,8 @@ inline GLenum FrontFace(Maxwell::Cull::FrontFace front_face) {
     case Maxwell::Cull::FrontFace::CounterClockWise:
         return GL_CCW;
     }
-    LOG_CRITICAL(Render_OpenGL, "Unimplemented front face cull={}", static_cast<u32>(front_face));
-    UNREACHABLE();
-    return {};
+    LOG_ERROR(Render_OpenGL, "Unimplemented front face cull={}", static_cast<u32>(front_face));
+    return GL_CCW;
 }
 
 inline GLenum CullFace(Maxwell::Cull::CullFace cull_face) {
@@ -394,9 +392,8 @@ inline GLenum CullFace(Maxwell::Cull::CullFace cull_face) {
     case Maxwell::Cull::CullFace::FrontAndBack:
         return GL_FRONT_AND_BACK;
     }
-    LOG_CRITICAL(Render_OpenGL, "Unimplemented cull face={}", static_cast<u32>(cull_face));
-    UNREACHABLE();
-    return {};
+    LOG_ERROR(Render_OpenGL, "Unimplemented cull face={}", static_cast<u32>(cull_face));
+    return GL_BACK;
 }
 
 inline GLenum LogicOp(Maxwell::LogicOperation operation) {
@@ -434,9 +431,8 @@ inline GLenum LogicOp(Maxwell::LogicOperation operation) {
     case Maxwell::LogicOperation::Set:
         return GL_SET;
     }
-    LOG_CRITICAL(Render_OpenGL, "Unimplemented logic operation={}", static_cast<u32>(operation));
-    UNREACHABLE();
-    return {};
+    LOG_ERROR(Render_OpenGL, "Unimplemented logic operation={}", static_cast<u32>(operation));
+    return GL_COPY;
 }
 
 } // namespace MaxwellToGL
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h
index d12d2ecb8808f183a9d09bb658b1b6fed7478935..e199d019a6630817992c9d04dd969c0ffac40151 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);