diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp
index eb4b041c18..746b7b459c 100644
--- a/Source/Core/VideoCommon/TextureCacheBase.cpp
+++ b/Source/Core/VideoCommon/TextureCacheBase.cpp
@@ -307,28 +307,35 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::DoPartialTextureUpdates(Tex
 		TCacheEntryBase* entry = iter->second;
 		if (entry != entry_to_update
 			&& entry->IsEfbCopy()
-			&& entry_to_update->addr <= entry->addr
-			&& entry->addr + entry->size_in_bytes <= entry_to_update->addr + entry_to_update->size_in_bytes
+			&& entry->OverlapsMemoryRange(entry_to_update->addr, entry_to_update->size_in_bytes)
 			&& entry->frameCount == FRAMECOUNT_INVALID
 			&& entry->memory_stride == numBlocksX * block_size)
 		{
 			if (entry->hash == entry->CalculateHash())
 			{
-				u32 block_offset = (entry->addr - entry_to_update->addr) / block_size;
-				u32 block_x = block_offset % numBlocksX;
-				u32 block_y = block_offset / numBlocksX;
+				u32 src_x, src_y, dst_x, dst_y;
 
-				u32 dst_x = block_x * block_width;
-				u32 dst_y = block_y * block_height;
-				u32 src_x = 0;
-				u32 src_y = 0;
-
-				// If the EFB copy doesn't fully fit, cancel the copy process
-				if (entry->native_width - src_x > entry_to_update->native_width - dst_x
-					|| entry->native_height - src_y > entry_to_update->native_height - dst_y)
+				// Note for understanding the math:
+				// Normal textures can't be strided, so the 2 missing cases with src_x > 0 don't exist
+				if (entry->addr >= entry_to_update->addr)
 				{
-					iter++;
-					continue;
+					u32 block_offset = (entry->addr - entry_to_update->addr) / block_size;
+					u32 block_x = block_offset % numBlocksX;
+					u32 block_y = block_offset / numBlocksX;
+					src_x = 0;
+					src_y = 0;
+					dst_x = block_x * block_width;
+					dst_y = block_y * block_height;
+				}
+				else
+				{
+					u32 block_offset = (entry_to_update->addr - entry->addr) / block_size;
+					u32 block_x = (~block_offset + 1) % numBlocksX;
+					u32 block_y = (block_offset + block_x) / numBlocksX;
+					src_x = 0;
+					src_y = block_y * block_height;
+					dst_x = block_x * block_width;
+					dst_y = 0;
 				}
 
 				u32 copy_width = std::min(entry->native_width - src_x, entry_to_update->native_width - dst_x);