Module: wine Branch: refs/heads/master Commit: c7b58749a19892972c47b54bc5557ca3eaadefc4 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=c7b58749a19892972c47b54b...
Author: Roderick Colenbrander thunderbird2k@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)