Am Montag 18 September 2006 10:12 schrieb Christopher GAUTIER:
> 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.
Welcome to Wine :-)

IWineD3DDevice::CopyRects is a subset of IWineD3DSurface::BltFast(from 
DirectDraw), and I thought some time ago I sent a patch which makes CopyRects 
call BltFast. This patch apparently wasn't applied, and I did a google search 
for it and couldn't find it either. Looks like I moved it to /dev/null 
accidentally. We should call BltFast to avoid duplicating code. BltFast is 
also able to handle corner cases like bad rectangles.

Can you test the attached patch? I have no game which uses CopyRects, so I 
can't test my patch. This is just a quick per-msdn implementation.

Thanks,
Stefan
From 239b0592953abb21d27a13e2febc64788c7ae5c1 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Stefan_D=F6singer?= <[EMAIL PROTECTED]>
Date: Tue, 19 Sep 2006 19:57:37 +0200
Subject: [PATCH] WineD3D: Make CopyRects use BltFast
---
 dlls/wined3d/device.c |   89 ++++---------------------------------------------
 1 files changed, 7 insertions(+), 82 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 34026db..1a90615 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -6840,99 +6840,24 @@ static HRESULT  WINAPI  IWineD3DDeviceIm
 
     /* 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 {
 
         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 (%ld,%ld),(%ld,%ld) -> (%ld,%ld)\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 (%ld,%ld),(%ld,%ld) -> (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");
-               }
+            unsigned int i;
+
+            for(i=0; i < cRects; i++) {
+                IWineD3DSurface_BltFast(pDestinationSurface, 0, 0, 
pSourceSurface, (RECT *) &pSourceRectsArray[i], DDBLTFAST_NOCOLORKEY);
+            }
         }
     }
 
-- 
1.4.1.1

Attachment: pgpqtu2eG9B0Y.pgp
Description: PGP signature



Reply via email to