Roderick Colenbrander : wined3d: Added CopyRects method ( based on a patch by Oliver Stieber).

Alexandre Julliard julliard at wine.codeweavers.com
Tue Feb 7 09:57:43 CST 2006


Module: wine
Branch: refs/heads/master
Commit: c7b58749a19892972c47b54bc5557ca3eaadefc4
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=c7b58749a19892972c47b54bc5557ca3eaadefc4

Author: Roderick Colenbrander <thunderbird2k at gmx.net>
Date:   Tue Feb  7 16:51:39 2006 +0100

wined3d: Added CopyRects method (based on a patch by Oliver Stieber).

---

 dlls/wined3d/device.c            |  114 ++++++++++++++++++++++++++++++++++++++
 include/wine/wined3d_interface.h |    2 +
 2 files changed, 116 insertions(+), 0 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index f814973..aff60cf 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -5449,6 +5449,119 @@ HRESULT  WINAPI  IWineD3DDeviceImpl_Upda
     return D3D_OK;
 }
 
+/* Used by DirectX 8 */
+HRESULT  WINAPI  IWineD3DDeviceImpl_CopyRects(IWineD3DDevice *iface,
+                                                IWineD3DSurface* pSourceSurface,      CONST RECT* pSourceRectsArray, UINT cRects,
+                                                IWineD3DSurface* pDestinationSurface, CONST POINT* pDestPointsArray) {
+
+    IWineD3DDeviceImpl  *This = (IWineD3DDeviceImpl *)iface;
+    HRESULT              hr = D3D_OK;
+    WINED3DFORMAT        srcFormat, destFormat;
+    UINT                 srcWidth,  destWidth;
+    UINT                 srcHeight, destHeight;
+    UINT                 srcSize;
+    WINED3DSURFACE_DESC  winedesc;
+
+    TRACE("(%p) pSrcSur=%p, pSourceRects=%p, cRects=%d, pDstSur=%p, pDestPtsArr=%p\n", This,
+          pSourceSurface, pSourceRectsArray, cRects, pDestinationSurface, pDestPointsArray);
+
+
+    /* Check that the source texture is in D3DPOOL_SYSTEMMEM and the destination texture is in D3DPOOL_DEFAULT */
+    memset(&winedesc, 0, sizeof(winedesc));
+
+    winedesc.Format = &srcFormat;
+    winedesc.Width  = &srcWidth;
+    winedesc.Height = &srcHeight;
+    winedesc.Size   = &srcSize;
+    IWineD3DSurface_GetDesc(pSourceSurface, &winedesc);
+
+    winedesc.Format = &destFormat;
+    winedesc.Width  = &destWidth;
+    winedesc.Height = &destHeight;
+    winedesc.Size   = NULL;
+    IWineD3DSurface_GetDesc(pDestinationSurface, &winedesc);
+
+    /* Check that the source and destination formats match */
+    if (srcFormat != destFormat && WINED3DFMT_UNKNOWN != destFormat) {
+        WARN("(%p) source %p format must match the dest %p format, returning D3DERR_INVALIDCALL\n", This, pSourceSurface, pDestinationSurface);
+        return D3DERR_INVALIDCALL;
+    } else if (WINED3DFMT_UNKNOWN == destFormat) {
+        TRACE("(%p) : Converting destination surface from WINED3DFMT_UNKNOWN to the source format\n", This);
+        IWineD3DSurface_SetFormat(pDestinationSurface, srcFormat);
+        destFormat = srcFormat;
+    }
+
+    /* Quick if complete copy ... */
+    if (cRects == 0 && pSourceRectsArray == NULL && pDestPointsArray == NULL) {
+
+        if (srcWidth == destWidth && srcHeight == destHeight) {
+            D3DLOCKED_RECT lrSrc;
+            D3DLOCKED_RECT lrDst;
+            IWineD3DSurface_LockRect(pSourceSurface,      &lrSrc, NULL, D3DLOCK_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 D3DERR_INVALIDCALL\n");
+            hr = D3DERR_INVALIDCALL;
+         }
+
+    } 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;
+                D3DLOCKED_RECT lrSrc;
+                D3DLOCKED_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, D3DLOCK_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");
+            }
+        } else {
+            FIXME("Wanted to copy partial surfaces not implemented, returning D3DERR_INVALIDCALL\n");
+            hr = D3DERR_INVALIDCALL;
+        }
+    }
+
+    return hr;
+}
+
 /* Implementation details at http://developer.nvidia.com/attach/6494
 and
 http://oss.sgi.com/projects/ogl-sample/registry/NV/evaluators.txt
@@ -6568,6 +6681,7 @@ const IWineD3DDeviceVtbl IWineD3DDevice_
     IWineD3DDeviceImpl_ColorFill,
     IWineD3DDeviceImpl_UpdateTexture,
     IWineD3DDeviceImpl_UpdateSurface,
+    IWineD3DDeviceImpl_CopyRects,
     IWineD3DDeviceImpl_StretchRect,
     IWineD3DDeviceImpl_GetRenderTargetData,
     IWineD3DDeviceImpl_GetFrontBufferData,
diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h
index dac1d3a..6947183 100644
--- a/include/wine/wined3d_interface.h
+++ b/include/wine/wined3d_interface.h
@@ -421,6 +421,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD
     STDMETHOD(ColorFill)(THIS_ struct IWineD3DSurface* pSurface, CONST D3DRECT* pRect, D3DCOLOR color) PURE;
     STDMETHOD(UpdateTexture)(THIS_ struct IWineD3DBaseTexture *pSourceTexture, struct IWineD3DBaseTexture *pDestinationTexture) PURE;
     STDMETHOD(UpdateSurface)(THIS_ struct IWineD3DSurface* pSourceSurface, CONST RECT* pSourceRect, struct IWineD3DSurface* pDestinationSurface, CONST POINT* pDestPoint) PURE;
+    STDMETHOD(CopyRects)(THIS_ struct IWineD3DSurface* pSourceSurface, CONST RECT* pSourceRectsArray, UINT cRects, struct IWineD3DSurface* pDestinationSurface, CONST POINT* pDestPointsArray);
     STDMETHOD(StretchRect)(THIS_ struct IWineD3DSurface* pSourceSurface, CONST RECT* pSourceRect, struct IWineD3DSurface* pDestinationSurface, CONST RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter) PURE;
     STDMETHOD(GetRenderTargetData)(THIS_ struct IWineD3DSurface* pRenderTarget, struct IWineD3DSurface* pSurface) PURE;
     STDMETHOD(GetFrontBufferData)(THIS_ UINT iSwapChain,struct IWineD3DSurface* pSurface) PURE;
@@ -558,6 +559,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD
 #define IWineD3DDevice_ColorFill(p,a,b,c)                       (p)->lpVtbl->ColorFill(p,a,b,c)
 #define IWineD3DDevice_UpdateTexture(p,a,b)                     (p)->lpVtbl->UpdateTexture(p,a,b)
 #define IWineD3DDevice_UpdateSurface(p,a,b,c,d)                 (p)->lpVtbl->UpdateSurface(p,a,b,c,d)
+#define IWineD3DDevice_CopyRects(p,a,b,c,d,e)                   (p)->lpVtbl->CopyRects(p,a,b,c,d,e)
 #define IWineD3DDevice_StretchRect(p,a,b,c,d,e)                 (p)->lpVtbl->StretchRect(p,a,b,c,d,e)
 #define IWineD3DDevice_GetRenderTargetData(p,a,b)               (p)->lpVtbl->GetRenderTargetData(p,a,b)
 #define IWineD3DDevice_GetFrontBufferData(p,a,b)                (p)->lpVtbl->GetFrontBufferData(p,a,b)




More information about the wine-cvs mailing list