wined3d/CopyRects bug fix [new patch]

Christopher GAUTIER krys at via.ecp.fr
Thu Oct 5 02:40:19 CDT 2006


Hello there,

When IWineD3DDeviceImpl_CopyRects() is called to copy the source entirely 
into the destination surface, and that the sizes match, a plain memcpy() 
is done. However, this assumes that the surfaces have the same pitch, and 
this is not always the case.

I'm including Stefan Dösinger's patch which fixes the issue (with a few
trivial changes compared to his patch).

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

Changelog:
    * dlls/wined3d/device.c:
    wined3d: Make CopyRects use BltFast

--
krys

-------------- next part --------------
diff -ru dlls/wined3d/device.c dlls/wined3d_krys/device.c
--- dlls/wined3d/device.c	2006-10-05 09:25:17.000000000 +0200
+++ dlls/wined3d_krys/device.c	2006-10-05 00:47:04.000000000 +0200
@@ -6866,100 +6866,19 @@
 
     /* Quick if complete copy ... */
     if (cRects == 0 && pSourceRectsArray == NULL && pDestPointsArray == NULL) {
-
-        if (srcWidth == destWidth && srcHeight == destHeight) {
-            WINED3DLOCKED_RECT lrSrc;
-            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);
-
-            IWineD3DSurface_UnlockRect(pSourceSurface);
-            IWineD3DSurface_UnlockRect(pDestinationSurface);
-            TRACE("Unlocked src and dst\n");
-
-        } else {
-
-            FIXME("Wanted to copy all surfaces but size not compatible, returning WINED3DERR_INVALIDCALL\n");
-            hr = WINED3DERR_INVALIDCALL;
-         }
-
+        IWineD3DSurface_BltFast(pDestinationSurface, 0, 0, pSourceSurface, NULL, DDBLTFAST_NOCOLORKEY);
     } else {
-
+        unsigned int i;
+        /* Copy rect by rect */
         if (NULL != pSourceRectsArray && NULL != pDestPointsArray) {
-
-            int bytesPerPixel = ((IWineD3DSurfaceImpl *) pSourceSurface)->bytesPerPixel;
-            unsigned int i;
-
-            /* Copy rect by rect */
             for (i = 0; i < cRects; ++i) {
-                CONST RECT*  r = &pSourceRectsArray[i];
-                CONST POINT* p = &pDestPointsArray[i];
-                int copyperline;
-                int j;
-                WINED3DLOCKED_RECT lrSrc;
-                WINED3DLOCKED_RECT lrDst;
-                RECT dest_rect;
-
-                TRACE("Copying rect %d (%d,%d),(%d,%d) -> (%d,%d)\n", i, r->left, r->top, r->right, r->bottom, p->x, p->y);
-                if (srcFormat == WINED3DFMT_DXT1) {
-                    copyperline = ((r->right - r->left) * bytesPerPixel) / 2; /* DXT1 is half byte per pixel */
-                } else {
-                    copyperline = ((r->right - r->left) * bytesPerPixel);
-                }
-
-                IWineD3DSurface_LockRect(pSourceSurface, &lrSrc, r, WINED3DLOCK_READONLY);
-                dest_rect.left  = p->x;
-                dest_rect.top   = p->y;
-                dest_rect.right = p->x + (r->right - r->left);
-                dest_rect.bottom= p->y + (r->bottom - r->top);
-                IWineD3DSurface_LockRect(pDestinationSurface, &lrDst, &dest_rect, 0L);
-                TRACE("Locked src and dst\n");
-
-                /* Find where to start */
-                for (j = 0; j < (r->bottom - r->top - 1); ++j) {
-                    memcpy((char*) lrDst.pBits + (j * lrDst.Pitch), (char*) lrSrc.pBits + (j * lrSrc.Pitch), copyperline);
-                }
-                IWineD3DSurface_UnlockRect(pSourceSurface);
-                IWineD3DSurface_UnlockRect(pDestinationSurface);
-                TRACE("Unlocked src and dst\n");
+                IWineD3DSurface_BltFast(pDestinationSurface, pDestPointsArray[i].x, pDestPointsArray[i].y, pSourceSurface, (RECT *) &pSourceRectsArray[i], DDBLTFAST_NOCOLORKEY);
             }
         } else {
-		unsigned int i;
-		int bytesPerPixel = ((IWineD3DSurfaceImpl *) pSourceSurface)->bytesPerPixel;
-        	int copyperline;
-                int j;
-                WINED3DLOCKED_RECT lrSrc;
-                WINED3DLOCKED_RECT lrDst;
-                RECT dest_rect;
-										
-		for(i=0; i < cRects; i++) {
-		    CONST RECT*  r = &pSourceRectsArray[i];
-		    
-		    TRACE("Copying rect %d (%d,%d),(%d,%d) -> (0, 0)\n", i, r->left, r->top, r->right, r->bottom);
-            	    if (srcFormat == WINED3DFMT_DXT1) {
-		        copyperline = ((r->right - r->left) * bytesPerPixel) / 2; /* DXT1 is half byte per pixel */
-		    } else {
-			copyperline = ((r->right - r->left) * bytesPerPixel);
-		    }
-		    IWineD3DSurface_LockRect(pSourceSurface, &lrSrc, r, WINED3DLOCK_READONLY);
-		    dest_rect.left = 0;
-		    dest_rect.top = 0;
-		    dest_rect.right = r->right - r->left;
-		    dest_rect.bottom= r->bottom - r->top;
-		    IWineD3DSurface_LockRect(pDestinationSurface, &lrDst, &dest_rect, 0L);
-                    TRACE("Locked src and dst\n");
-                    /* Find where to start */
-                    for (j = 0; j < (r->bottom - r->top - 1); ++j) {
-                        memcpy((char*) lrDst.pBits + (j * lrDst.Pitch), (char*) lrSrc.pBits + (j * lrSrc.Pitch), copyperline);
-    	            }
-                    IWineD3DSurface_UnlockRect(pSourceSurface);
-	            IWineD3DSurface_UnlockRect(pDestinationSurface);
-		    TRACE("Unlocked src and dst\n");
+            for (i = 0; i < cRects; ++i) {
+                IWineD3DSurface_BltFast(pDestinationSurface, 0, 0, pSourceSurface, (RECT *) &pSourceRectsArray[i], DDBLTFAST_NOCOLORKEY);
+            }
 		}
-        }
     }
 
     return hr;


More information about the wine-patches mailing list