Hi all, Optimize the BltFast case (when no fast path exists) to only lock the rectangle that will actually be used and not the full surface. Gets Populous a bit faster when moving the mouse cursor. The same should be done for Blt, but well, I have no game using the slow path for Blt, so did not do it. Changelog: - fix FPS computation - some TRACEing fixes - optimize BltFast locking rectangles -- Lionel Ulmer - http://www.bbrox.org/
--- dlls/ddraw_CVS/d3ddevice/mesa.c Mon Jun 30 19:32:20 2003 +++ dlls/ddraw/d3ddevice/mesa.c Sat Jul 5 14:24:09 2003 @@ -212,8 +212,8 @@ #ifdef COMPUTE_FPS -#define MEASUREMENT_WINDOW 20 -#define NUMBER_OF_WINDOWS 4 +#define MEASUREMENT_WINDOW 5 +#define NUMBER_OF_WINDOWS 10 static LONGLONG perf_freq; static LONGLONG perf_storage[NUMBER_OF_WINDOWS]; @@ -279,6 +279,7 @@ current_window = 0; } perf_storage[current_window] = 0; + measurements_in_window = 0; } } else { prev_time = current_time; --- dlls/ddraw_CVS/dsurface/main.c Wed Jun 18 23:14:02 2003 +++ dlls/ddraw/dsurface/main.c Sat Jul 5 13:32:00 2003 @@ -1015,7 +1015,7 @@ * (Not documented.) */ if (prect != NULL) { TRACE(" lprect: %ldx%ld-%ldx%ld\n", - prect->top,prect->left,prect->bottom,prect->right); + prect->left,prect->top,prect->right,prect->bottom); /* First do some sanity checkings on the rectangle we receive. DungeonSiege seems to gives us once a very bad rectangle for example */ if ((prect->top < 0) || --- dlls/ddraw_CVS/dsurface/dib.c Mon Jun 30 19:32:20 2003 +++ dlls/ddraw/dsurface/dib.c Sat Jul 5 13:35:22 2003 @@ -816,7 +816,7 @@ HRESULT ret = DD_OK; LPBYTE sbuf, dbuf; RECT rsrc2; - + RECT lock_src, lock_dst; if (TRACE_ON(ddraw)) { TRACE("(%p)->(%ld,%ld,%p,%p,%08lx)\n", @@ -836,35 +836,49 @@ if (This->aux_bltfast(This, dstx, dsty, src, rsrc, trans) == DD_OK) return DD_OK; } - /* We need to lock the surfaces, or we won't get refreshes when done. */ - sdesc.dwSize = sizeof(sdesc); - IDirectDrawSurface7_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0); - ddesc.dwSize = sizeof(ddesc); - IDirectDrawSurface7_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0); - - if (!rsrc) { - WARN("rsrc is NULL!\n"); - rsrc = &rsrc2; - rsrc->left = rsrc->top = 0; - rsrc->right = sdesc.dwWidth; - rsrc->bottom = sdesc.dwHeight; - } - - bpp = GET_BPP(This->surface_desc); - sbuf = (BYTE *)sdesc.lpSurface+(rsrc->top*sdesc.u1.lPitch)+rsrc->left*bpp; - dbuf = (BYTE *)ddesc.lpSurface+(dsty*ddesc.u1.lPitch)+dstx* bpp; - + /* Get the surface description without locking to first compute the width / height */ + ddesc = This->surface_desc; + sdesc = (ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, src))->surface_desc; + + if (!rsrc) { + WARN("rsrc is NULL!\n"); + rsrc = &rsrc2; + rsrc->left = rsrc->top = 0; + rsrc->right = sdesc.dwWidth; + rsrc->bottom = sdesc.dwHeight; + } h=rsrc->bottom-rsrc->top; if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty; if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top; - if (h<0) h=0; + if (h<=0) return DDERR_INVALIDRECT; w=rsrc->right-rsrc->left; if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx; if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left; - if (w<0) w=0; + if (w<=0) return DDERR_INVALIDRECT; + /* Now compute the locking rectangle... */ + lock_src.left = rsrc->left; + lock_src.top = rsrc->top; + lock_src.right = lock_src.left + w; + lock_src.bottom = lock_src.top + h; + + lock_dst.left = dstx; + lock_dst.top = dsty; + lock_dst.right = dstx + w; + lock_dst.bottom = dsty + h; + + /* We need to lock the surfaces, or we won't get refreshes when done. */ + sdesc.dwSize = sizeof(sdesc); + IDirectDrawSurface7_Lock(src, &lock_src, &sdesc, DDLOCK_READONLY, 0); + ddesc.dwSize = sizeof(ddesc); + IDirectDrawSurface7_Lock(iface, &lock_dst, &ddesc, DDLOCK_WRITEONLY, 0); + + bpp = GET_BPP(This->surface_desc); + sbuf = (BYTE *) sdesc.lpSurface; + dbuf = (BYTE *) ddesc.lpSurface; + if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) { DWORD keylow, keyhigh; if (trans & DDBLTFAST_SRCCOLORKEY) { @@ -878,28 +892,28 @@ } #define COPYBOX_COLORKEY(type) { \ - type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \ - s = (type *) ((BYTE *) sdesc.lpSurface + (rsrc->top * sdesc.u1.lPitch) + rsrc->left * bpp); \ - d = (type *) ((BYTE *) ddesc.lpSurface + (dsty * ddesc.u1.lPitch) + dstx * bpp); \ - for (y = 0; y < h; y++) { \ - for (x = 0; x < w; x++) { \ - tmp = s[x]; \ - if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \ - } \ - (LPBYTE)s += sdesc.u1.lPitch; \ - (LPBYTE)d += ddesc.u1.lPitch; \ - } \ - break; \ -} - - switch (bpp) { - case 1: COPYBOX_COLORKEY(BYTE) - case 2: COPYBOX_COLORKEY(WORD) - case 4: COPYBOX_COLORKEY(DWORD) - default: - FIXME("Source color key blitting not supported for bpp %d\n",bpp*8); - ret = DDERR_UNSUPPORTED; - goto error; + type *d, *s, tmp; \ + s = (type *) sdesc.lpSurface; \ + d = (type *) ddesc.lpSurface; \ + for (y = 0; y < h; y++) { \ + for (x = 0; x < w; x++) { \ + tmp = s[x]; \ + if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \ + } \ + (LPBYTE)s += sdesc.u1.lPitch; \ + (LPBYTE)d += ddesc.u1.lPitch; \ + } \ + break; \ + } + + switch (bpp) { + case 1: COPYBOX_COLORKEY(BYTE) + case 2: COPYBOX_COLORKEY(WORD) + case 4: COPYBOX_COLORKEY(DWORD) + default: + FIXME("Source color key blitting not supported for bpp %d\n",bpp*8); + ret = DDERR_UNSUPPORTED; + goto error; } #undef COPYBOX_COLORKEY } else { @@ -911,9 +925,10 @@ dbuf += ddesc.u1.lPitch; } } + error: - IDirectDrawSurface7_Unlock(iface, NULL); - IDirectDrawSurface7_Unlock(src, NULL); + IDirectDrawSurface7_Unlock(iface, &lock_dst); + IDirectDrawSurface7_Unlock(src, &lock_src); return ret; } --- dlls/ddraw_CVS/mesa.c Mon Jun 30 19:32:20 2003 +++ dlls/ddraw/mesa.c Sat Jul 5 12:53:48 2003 @@ -106,6 +106,11 @@ 0, ICOM_INTERFACE(tex, IDirectDrawSurface7)); } break; + + case D3DRENDERSTATE_ANTIALIAS: /* 2 */ + if (dwRenderState) + ERR("D3DRENDERSTATE_ANTIALIAS not supported yet !\n"); + break; case D3DRENDERSTATE_TEXTUREADDRESSU: /* 44 */ case D3DRENDERSTATE_TEXTUREADDRESSV: /* 45 */