summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/TextureCacheBase.cpp
diff options
context:
space:
mode:
authorStenzek <stenzek@gmail.com>2019-02-15 11:58:59 +1000
committerStenzek <stenzek@gmail.com>2019-02-17 16:35:43 +1000
commit933f3ba008942cba96ed623c25e61d6ea86582fe (patch)
treeed70f774d2eba24ec21bf1fda926eedc9d100c0f /Source/Core/VideoCommon/TextureCacheBase.cpp
parent2165523fdcdaf5a27110f92ae86d773293458343 (diff)
TextureCache: Don't copy out-of-range rectangles when stitching textures
This can cause driver crashes or GPU hangs if we do.
Diffstat (limited to 'Source/Core/VideoCommon/TextureCacheBase.cpp')
-rw-r--r--Source/Core/VideoCommon/TextureCacheBase.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp
index d0355b724b..90abc01c65 100644
--- a/Source/Core/VideoCommon/TextureCacheBase.cpp
+++ b/Source/Core/VideoCommon/TextureCacheBase.cpp
@@ -384,6 +384,17 @@ TextureCacheBase::DoPartialTextureUpdates(TCacheEntry* entry_to_update, u8* pale
dst_y = 0;
}
+ // If the source rectangle is outside of what we actually have in VRAM, skip the copy.
+ // The backend doesn't do any clamping, so if we don't, we'd pass out-of-range coordinates
+ // to the graphics driver, which can cause GPU resets.
+ if (static_cast<u32>(src_x) >= entry->native_width ||
+ static_cast<u32>(src_y) >= entry->native_height ||
+ static_cast<u32>(dst_x) >= entry_to_update->native_width ||
+ static_cast<u32>(dst_y) >= entry_to_update->native_height)
+ {
+ continue;
+ }
+
u32 copy_width =
std::min(entry->native_width - src_x, entry_to_update->native_width - dst_x);
u32 copy_height =
@@ -1453,6 +1464,17 @@ TextureCacheBase::GetTextureFromOverlappingTextures(const TextureLookupInformati
dst_y = 0;
}
+ // If the source rectangle is outside of what we actually have in VRAM, skip the copy.
+ // The backend doesn't do any clamping, so if we don't, we'd pass out-of-range coordinates
+ // to the graphics driver, which can cause GPU resets.
+ if (static_cast<u32>(src_x) >= entry->native_width ||
+ static_cast<u32>(src_y) >= entry->native_height ||
+ static_cast<u32>(dst_x) >= stitched_entry->native_width ||
+ static_cast<u32>(dst_y) >= stitched_entry->native_height)
+ {
+ continue;
+ }
+
u32 copy_width = std::min(entry->native_width - src_x, stitched_entry->native_width - dst_x);
u32 copy_height = std::min(entry->native_height - src_y, stitched_entry->native_height - dst_y);