[PATCH 1/3] wined3d: Check slice pitch against its size in wined3d_format_copy_data().

Jan Sikorski jsikorski at codeweavers.com
Wed Mar 10 08:10:43 CST 2021


If they don't match and there's more than one slice to copy, we can't use
a single memcpy.
Fixes blinking objects in Hellblade: Senua's Sacrifice.

Signed-off-by: Jan Sikorski <jsikorski at codeweavers.com>
---
 dlls/wined3d/utils.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 9df51872d42..1e1c899523d 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -5981,17 +5981,19 @@ void wined3d_format_copy_data(const struct wined3d_format *format, const uint8_t
         unsigned int dst_slice_pitch, unsigned int w, unsigned int h, unsigned int d)
 {
     unsigned int row_block_count, row_count, row_size, slice, row;
-    unsigned int slice_count = d;
+    unsigned int slice_count = d, slice_size;
     const uint8_t *src_row;
     uint8_t *dst_row;
 
     row_block_count = (w + format->block_width - 1) / format->block_width;
     row_count = (h + format->block_height - 1) / format->block_height;
     row_size = row_block_count * format->block_byte_count;
+    slice_size = row_size * row_count;
 
-    if (src_row_pitch == row_size && dst_row_pitch == row_size && src_slice_pitch == dst_slice_pitch)
+    if (src_row_pitch == row_size && dst_row_pitch == row_size
+            && ((src_slice_pitch == slice_size && dst_slice_pitch == slice_size) || slice_count == 1))
     {
-        memcpy(dst, src, slice_count * row_count * row_size);
+        memcpy(dst, src, slice_count * slice_size);
         return;
     }
 
-- 
2.30.1




More information about the wine-devel mailing list