diff --git a/src/video_core/host_shaders/texture_filtering/nearest_neighbor.frag b/src/video_core/host_shaders/texture_filtering/nearest_neighbor.frag
index 5413e7409..e2db96f91 100644
--- a/src/video_core/host_shaders/texture_filtering/nearest_neighbor.frag
+++ b/src/video_core/host_shaders/texture_filtering/nearest_neighbor.frag
@@ -8,7 +8,7 @@ precision mediump float;
 layout(location = 0) in vec2 tex_coord;
 layout(location = 0) out vec4 frag_color;
 
-layout(binding = 0) uniform sampler2D input_texture;
+layout(binding = 2) uniform sampler2D input_texture;
 
 void main() {
     frag_color = texture(input_texture, tex_coord);
diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.cpp b/src/video_core/rasterizer_cache/rasterizer_cache.cpp
index b5577f80e..c9464cc63 100644
--- a/src/video_core/rasterizer_cache/rasterizer_cache.cpp
+++ b/src/video_core/rasterizer_cache/rasterizer_cache.cpp
@@ -725,8 +725,8 @@ void RasterizerCache::DuplicateSurface(const SurfaceRef& src_surface,
     const TextureCopy copy = {
         .src_level = 0,
         .dst_level = 0,
-        .src_offset = {0, 0},
-        .dst_offset = {0, 0},
+        .src_offset = {src_rect.left, src_rect.bottom},
+        .dst_offset = {dst_rect.left, dst_rect.bottom},
         .extent = {src_rect.GetWidth(), src_rect.GetHeight()},
     };
     runtime.CopyTextures(*src_surface, *dest_surface, copy);
diff --git a/src/video_core/rasterizer_cache/surface_params.cpp b/src/video_core/rasterizer_cache/surface_params.cpp
index cdd5f3a55..bbd3e38ce 100644
--- a/src/video_core/rasterizer_cache/surface_params.cpp
+++ b/src/video_core/rasterizer_cache/surface_params.cpp
@@ -11,7 +11,7 @@ bool SurfaceParams::ExactMatch(const SurfaceParams& other_surface) const {
     return std::tie(other_surface.addr, other_surface.width, other_surface.height,
                     other_surface.stride, other_surface.pixel_format, other_surface.is_tiled) ==
                std::tie(addr, width, height, stride, pixel_format, is_tiled) &&
-           pixel_format != PixelFormat::Invalid;
+           pixel_format != PixelFormat::Invalid && levels >= other_surface.levels;
 }
 
 bool SurfaceParams::CanSubRect(const SurfaceParams& sub_surface) const {
diff --git a/src/video_core/rasterizer_cache/texture_codec.h b/src/video_core/rasterizer_cache/texture_codec.h
index 3c136724d..c64ffedcd 100644
--- a/src/video_core/rasterizer_cache/texture_codec.h
+++ b/src/video_core/rasterizer_cache/texture_codec.h
@@ -305,7 +305,9 @@ static constexpr void MortonCopy(u32 width, u32 height, u32 start_offset, u32 en
 
     // If the copy spans multiple tiles, copy the fully aligned tiles in between.
     if (aligned_start_offset < aligned_end_offset) {
-        const u32 buffer_end = tiled_offset + aligned_end_offset - aligned_start_offset;
+        const u32 tile_buffer_size = static_cast<u32>(tiled_buffer.size());
+        const u32 buffer_end =
+            std::min(tiled_offset + aligned_end_offset - aligned_start_offset, tile_buffer_size);
         while (tiled_offset < buffer_end) {
             auto linear_data = linear_buffer.subspan(linear_offset, linear_tile_stride);
             auto tiled_data = tiled_buffer.subspan(tiled_offset, tile_size);
diff --git a/src/video_core/renderer_opengl/gl_blit_helper.cpp b/src/video_core/renderer_opengl/gl_blit_helper.cpp
index 2adc92c32..e41dda81d 100644
--- a/src/video_core/renderer_opengl/gl_blit_helper.cpp
+++ b/src/video_core/renderer_opengl/gl_blit_helper.cpp
@@ -166,6 +166,7 @@ void BlitHelper::FilterBicubic(Surface& surface, const VideoCore::TextureBlit& b
 }
 
 void BlitHelper::FilterNearest(Surface& surface, const VideoCore::TextureBlit& blit) {
+    state.texture_units[2].texture_2d = surface.Handle(false);
     SetParams(nearest_program, surface.width, surface.height, blit.src_rect);
     Draw(nearest_program, surface.Handle(), filter_fbo.handle, blit.dst_level, blit.dst_rect);
 }
diff --git a/src/video_core/renderer_opengl/gl_texture_runtime.cpp b/src/video_core/renderer_opengl/gl_texture_runtime.cpp
index cf64780a0..3ab3b475e 100644
--- a/src/video_core/renderer_opengl/gl_texture_runtime.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_runtime.cpp
@@ -199,7 +199,7 @@ Allocation TextureRuntime::Allocate(const VideoCore::SurfaceParams& params) {
         handles[1] = textures[1].handle;
     }
 
-    glBindTexture(target, old_tex);
+    glBindTexture(GL_TEXTURE_2D, old_tex);
 
     return Allocation{
         .textures = std::move(textures),