WineD3D CopyRects
Roderick Colenbrander
thunderbird2k at gmx.net
Tue Feb 7 03:52:56 CST 2006
This patch is based on Oliver Stieber his D3D8->WineD3D work and adds the
CopyRects method required by D3D8 to WineD3D.
Roderick
-------------- next part --------------
Index: dlls/wined3d/device.c
===================================================================
RCS file: /home/wine/wine/dlls/wined3d/device.c,v
retrieving revision 1.123
diff -u -r1.123 device.c
--- dlls/wined3d/device.c 6 Feb 2006 21:03:00 -0000 1.123
+++ dlls/wined3d/device.c 7 Feb 2006 09:47:22 -0000
@@ -5448,6 +5448,119 @@
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;
+ int srcWidth, destWidth;
+ int srcHeight, destHeight;
+ int 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
@@ -6567,6 +6680,7 @@
IWineD3DDeviceImpl_ColorFill,
IWineD3DDeviceImpl_UpdateTexture,
IWineD3DDeviceImpl_UpdateSurface,
+ IWineD3DDeviceImpl_CopyRects,
IWineD3DDeviceImpl_StretchRect,
IWineD3DDeviceImpl_GetRenderTargetData,
IWineD3DDeviceImpl_GetFrontBufferData,
Index: include/wine/wined3d_interface.h
===================================================================
RCS file: /home/wine/wine/include/wine/wined3d_interface.h,v
retrieving revision 1.51
diff -u -r1.51 wined3d_interface.h
--- include/wine/wined3d_interface.h 6 Feb 2006 11:13:00 -0000 1.51
+++ include/wine/wined3d_interface.h 7 Feb 2006 09:47:22 -0000
@@ -421,6 +421,7 @@
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 @@
#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-patches
mailing list