wined3d: Keep surfaces in sysmem if they're both already there in wined3d_surface_blt().

The idea is to avoid bouncing surfaces between the CPU and GPU when doing both
locks and blits on a surface. This is mostly an issue for ddraw applications.
This commit is contained in:
Henri Verbeet 2011-10-17 21:06:20 +02:00 committed by Alexandre Julliard
parent 42db0c0593
commit ca43c49968
1 changed files with 20 additions and 2 deletions

View File

@ -1469,6 +1469,7 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC
struct wined3d_device *device = dst_surface->resource.device; struct wined3d_device *device = dst_surface->resource.device;
DWORD src_ds_flags, dst_ds_flags; DWORD src_ds_flags, dst_ds_flags;
RECT src_rect, dst_rect; RECT src_rect, dst_rect;
BOOL scale, convert;
static const DWORD simple_blit = WINEDDBLT_ASYNC static const DWORD simple_blit = WINEDDBLT_ASYNC
| WINEDDBLT_COLORFILL | WINEDDBLT_COLORFILL
@ -1621,6 +1622,11 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC
goto fallback; goto fallback;
} }
scale = src_surface
&& (src_rect.right - src_rect.left != dst_rect.right - dst_rect.left
|| src_rect.bottom - src_rect.top != dst_rect.bottom - dst_rect.top);
convert = src_surface && src_surface->resource.format->id != dst_surface->resource.format->id;
dst_ds_flags = dst_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); dst_ds_flags = dst_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
if (src_surface) if (src_surface)
src_ds_flags = src_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL); src_ds_flags = src_surface->resource.format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL);
@ -1675,8 +1681,7 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
if (src_surface->resource.height != dst_surface->resource.height if (scale)
|| src_surface->resource.width != dst_surface->resource.width)
{ {
WARN("Rejecting depth / stencil blit with mismatched surface sizes.\n"); WARN("Rejecting depth / stencil blit with mismatched surface sizes.\n");
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
@ -1688,6 +1693,19 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC
} }
else else
{ {
/* In principle this would apply to depth blits as well, but we don't
* implement those in the CPU blitter at the moment. */
if ((dst_surface->flags & SFLAG_INSYSMEM)
&& (!src_surface || (src_surface->flags & SFLAG_INSYSMEM)))
{
if (scale)
TRACE("Not doing sysmem blit because of scaling.\n");
else if (convert)
TRACE("Not doing sysmem blit because of format conversion.\n");
else
return surface_cpu_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, fx, filter);
}
if (flags & WINEDDBLT_COLORFILL) if (flags & WINEDDBLT_COLORFILL)
{ {
WINED3DCOLORVALUE color; WINED3DCOLORVALUE color;