wined3d/CopyRects bug fix

Christopher GAUTIER krys at via.ecp.fr
Mon Sep 18 03:12:57 CDT 2006


Hello there,

I've identified a bug in IWineD3DDeviceImpl_CopyRects. When CopyRects() 
is called to copy the source entirely into the destination surface, and
that the sizes matches, a plain memcpy() is done. However, this assumes
that the surfaces have the same pitch, and this is not always the case.

Patch included. It fixes the backgrounds for the menus of a japanese shmup
(Imperishable Night).

Changelog:
    * dlls/wined3d/device.c:
    wined3d: Fixed CopyRects when sizes match, but pitches do not

--
krys

-------------- next part --------------
Index: dlls/wined3d/device.c
===================================================================
RCS file: /home/wine/wine/dlls/wined3d/device.c,v
retrieving revision 1.288
diff -u -r1.288 device.c
--- dlls/wined3d/device.c	10 Sep 2006 08:33:19 -0000	1.288
+++ dlls/wined3d/device.c	18 Sep 2006 08:10:49 -0000
@@ -6846,9 +6846,26 @@
             WINED3DLOCKED_RECT lrDst;
             IWineD3DSurface_LockRect(pSourceSurface,      &lrSrc, NULL, WINED3DLOCK_READONLY);
             IWineD3DSurface_LockRect(pDestinationSurface, &lrDst, NULL, 0L);
-            TRACE("Locked src and dst, Direct copy as surfaces are equal, w=%d, h=%d\n", srcWidth, srcHeight);
 
-            memcpy(lrDst.pBits, lrSrc.pBits, srcSize);
+            if (lrSrc.Pitch == lrDst.Pitch) {
+                TRACE("Locked src and dst, Direct copy as surfaces are equal, w=%d, h=%d\n", srcWidth, srcHeight);
+                memcpy(lrDst.pBits, lrSrc.pBits, srcSize);
+            } else {
+                unsigned int i;
+                char* pDst = lrDst.pBits;
+                char* pSrc = lrSrc.pBits;
+                unsigned copyperline = srcWidth * 
+                    ((IWineD3DSurfaceImpl *) pSourceSurface)->bytesPerPixel /
+                    ((srcFormat == WINED3DFMT_DXT1) ? 2 : 1);
+
+                TRACE("Locked src and dst, surfaces are equal (w=%d, h=%d) but pitches are not (src=%d, dest=%d)\n", srcWidth, srcHeight, lrSrc.Pitch, lrDst.Pitch);
+
+                for (i = 0; i < srcHeight; i++) {
+                    memcpy(pDst, pSrc, copyperline);
+                    pDst += lrDst.Pitch;
+                    pSrc += lrSrc.Pitch;
+                }
+            }
 
             IWineD3DSurface_UnlockRect(pSourceSurface);
             IWineD3DSurface_UnlockRect(pDestinationSurface);


More information about the wine-patches mailing list