[PATCH 1/5] wined3d: Implement wined3d_surface_bltfast() on top of wined3d_surface_blt().
Henri Verbeet
hverbeet at codeweavers.com
Thu Aug 4 12:53:27 CDT 2011
---
dlls/wined3d/surface.c | 358 ++--------------------------------------
dlls/wined3d/wined3d_private.h | 2 -
2 files changed, 18 insertions(+), 342 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 6dfb72b..4afcf66 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -36,8 +36,6 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d);
static HRESULT surface_cpu_blt(struct wined3d_surface *dst_surface, const RECT *dst_rect,
struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags,
const WINEDDBLTFX *fx, WINED3DTEXTUREFILTERTYPE filter);
-static HRESULT surface_cpu_bltfast(struct wined3d_surface *dst_surface, DWORD dst_x, DWORD dst_y,
- struct wined3d_surface *src_surface, const RECT *src_rect, DWORD trans);
static HRESULT IWineD3DSurfaceImpl_BltOverride(struct wined3d_surface *dst_surface, const RECT *dst_rect,
struct wined3d_surface *src_surface, const RECT *src_rect, DWORD flags, const WINEDDBLTFX *fx,
WINED3DTEXTUREFILTERTYPE filter);
@@ -1484,58 +1482,32 @@ cpu:
}
/* Do not call while under the GL lock. */
-static HRESULT surface_bltfast(struct wined3d_surface *dst_surface, DWORD dst_x, DWORD dst_y,
+HRESULT CDECL wined3d_surface_bltfast(struct wined3d_surface *dst_surface, DWORD dst_x, DWORD dst_y,
struct wined3d_surface *src_surface, const RECT *src_rect_in, DWORD trans)
{
- struct wined3d_device *device = dst_surface->resource.device;
+ RECT src_rect, dst_rect;
+ DWORD flags = 0;
- TRACE("dst_surface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n",
+ TRACE("dst_surface %p, dst_x %u, dst_y %u, src_surface %p, src_rect_in %s, trans %#x.\n",
dst_surface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect_in), trans);
- if ((dst_surface->flags & SFLAG_LOCKED) || (src_surface->flags & SFLAG_LOCKED))
- {
- WARN("Surface is busy, returning WINEDDERR_SURFACEBUSY.\n");
- return WINEDDERR_SURFACEBUSY;
- }
+ surface_get_rect(src_surface, src_rect_in, &src_rect);
- if (device->inScene && (dst_surface == device->fb.depth_stencil || src_surface == device->fb.depth_stencil))
- {
- WARN("Attempt to access the depth / stencil surface while in a scene.\n");
- return WINED3DERR_INVALIDCALL;
- }
+ dst_rect.left = dst_x;
+ dst_rect.top = dst_y;
+ dst_rect.right = dst_x + src_rect.right - src_rect.left;
+ dst_rect.bottom = dst_y + src_rect.bottom - src_rect.top;
- /* Special cases for RenderTargets */
- if ((dst_surface->resource.usage & WINED3DUSAGE_RENDERTARGET)
- || (src_surface->resource.usage & WINED3DUSAGE_RENDERTARGET))
- {
-
- RECT src_rect, dst_rect;
- DWORD flags = 0;
-
- surface_get_rect(src_surface, src_rect_in, &src_rect);
+ if (trans & WINEDDBLTFAST_SRCCOLORKEY)
+ flags |= WINEDDBLT_KEYSRC;
+ if (trans & WINEDDBLTFAST_DESTCOLORKEY)
+ flags |= WINEDDBLT_KEYDEST;
+ if (trans & WINEDDBLTFAST_WAIT)
+ flags |= WINEDDBLT_WAIT;
+ if (trans & WINEDDBLTFAST_DONOTWAIT)
+ flags |= WINEDDBLT_DONOTWAIT;
- dst_rect.left = dst_x;
- dst_rect.top = dst_y;
- dst_rect.right = dst_x + src_rect.right - src_rect.left;
- dst_rect.bottom = dst_y + src_rect.bottom - src_rect.top;
-
- /* Convert BltFast flags into Blt ones because BltOverride is called
- * from Blt as well. */
- if (trans & WINEDDBLTFAST_SRCCOLORKEY)
- flags |= WINEDDBLT_KEYSRC;
- if (trans & WINEDDBLTFAST_DESTCOLORKEY)
- flags |= WINEDDBLT_KEYDEST;
- if (trans & WINEDDBLTFAST_WAIT)
- flags |= WINEDDBLT_WAIT;
- if (trans & WINEDDBLTFAST_DONOTWAIT)
- flags |= WINEDDBLT_DONOTWAIT;
-
- if (SUCCEEDED(IWineD3DSurfaceImpl_BltOverride(dst_surface,
- &dst_rect, src_surface, &src_rect, flags, NULL, WINED3DTEXF_POINT)))
- return WINED3D_OK;
- }
-
- return surface_cpu_bltfast(dst_surface, dst_x, dst_y, src_surface, src_rect_in, trans);
+ return wined3d_surface_blt(dst_surface, &dst_rect, src_surface, &src_rect, flags, NULL, WINED3DTEXF_POINT);
}
static HRESULT surface_set_mem(struct wined3d_surface *surface, void *mem)
@@ -1709,7 +1681,6 @@ static const struct wined3d_surface_ops surface_ops =
surface_unmap,
surface_getdc,
surface_flip,
- surface_bltfast,
surface_set_mem,
};
@@ -1893,15 +1864,6 @@ static HRESULT gdi_surface_flip(struct wined3d_surface *surface, struct wined3d_
return WINED3D_OK;
}
-static HRESULT gdi_surface_bltfast(struct wined3d_surface *dst_surface, DWORD dst_x, DWORD dst_y,
- struct wined3d_surface *src_surface, const RECT *src_rect, DWORD trans)
-{
- TRACE("dst_surface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n",
- dst_surface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect), trans);
-
- return surface_cpu_bltfast(dst_surface, dst_x, dst_y, src_surface, src_rect, trans);
-}
-
static HRESULT gdi_surface_set_mem(struct wined3d_surface *surface, void *mem)
{
TRACE("surface %p, mem %p.\n", surface, mem);
@@ -1960,7 +1922,6 @@ static const struct wined3d_surface_ops gdi_surface_ops =
gdi_surface_unmap,
gdi_surface_getdc,
gdi_surface_flip,
- gdi_surface_bltfast,
gdi_surface_set_mem,
};
@@ -3496,17 +3457,6 @@ do { \
return WINED3D_OK;
}
-/* Do not call while under the GL lock. */
-HRESULT CDECL wined3d_surface_bltfast(struct wined3d_surface *dst_surface, DWORD dst_x, DWORD dst_y,
- struct wined3d_surface *src_surface, const RECT *src_rect, DWORD trans)
-{
- TRACE("dst_surface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, trans %#x.\n",
- dst_surface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect), trans);
-
- return dst_surface->surface_ops->surface_bltfast(dst_surface,
- dst_x, dst_y, src_surface, src_rect, trans);
-}
-
HRESULT CDECL wined3d_surface_unmap(struct wined3d_surface *surface)
{
TRACE("surface %p.\n", surface);
@@ -7031,278 +6981,6 @@ release:
return hr;
}
-static HRESULT surface_cpu_bltfast(struct wined3d_surface *dst_surface, DWORD dst_x, DWORD dst_y,
- struct wined3d_surface *src_surface, const RECT *src_rect, DWORD trans)
-{
- const struct wined3d_format *src_format, *dst_format;
- RECT lock_src, lock_dst, lock_union;
- WINED3DLOCKED_RECT dlock, slock;
- HRESULT hr = WINED3D_OK;
- int bpp, w, h, x, y;
- const BYTE *sbuf;
- BYTE *dbuf;
- RECT rsrc2;
-
- TRACE("dst_surface %p, dst_x %u, dst_y %u, src_surface %p, src_rect %s, flags %#x.\n",
- dst_surface, dst_x, dst_y, src_surface, wine_dbgstr_rect(src_rect), trans);
-
- if ((dst_surface->flags & SFLAG_LOCKED) || (src_surface->flags & SFLAG_LOCKED))
- {
- WARN(" Surface is busy, returning DDERR_SURFACEBUSY\n");
- return WINEDDERR_SURFACEBUSY;
- }
-
- if (!src_rect)
- {
- WARN("src_rect is NULL!\n");
- rsrc2.left = 0;
- rsrc2.top = 0;
- rsrc2.right = src_surface->resource.width;
- rsrc2.bottom = src_surface->resource.height;
- src_rect = &rsrc2;
- }
-
- /* Check source rect for validity. Copied from normal Blt. Fixes Baldur's Gate. */
- if ((src_rect->bottom > src_surface->resource.height) || (src_rect->bottom < 0)
- || (src_rect->top > src_surface->resource.height) || (src_rect->top < 0)
- || (src_rect->left > src_surface->resource.width) || (src_rect->left < 0)
- || (src_rect->right > src_surface->resource.width) || (src_rect->right < 0)
- || (src_rect->right < src_rect->left) || (src_rect->bottom < src_rect->top))
- {
- WARN("Application gave us bad source rectangle for BltFast.\n");
- return WINEDDERR_INVALIDRECT;
- }
-
- h = src_rect->bottom - src_rect->top;
- if (h > dst_surface->resource.height - dst_y)
- h = dst_surface->resource.height - dst_y;
- if (h > src_surface->resource.height - src_rect->top)
- h = src_surface->resource.height - src_rect->top;
- if (h <= 0)
- return WINEDDERR_INVALIDRECT;
-
- w = src_rect->right - src_rect->left;
- if (w > dst_surface->resource.width - dst_x)
- w = dst_surface->resource.width - dst_x;
- if (w > src_surface->resource.width - src_rect->left)
- w = src_surface->resource.width - src_rect->left;
- if (w <= 0)
- return WINEDDERR_INVALIDRECT;
-
- /* Now compute the locking rectangle... */
- lock_src.left = src_rect->left;
- lock_src.top = src_rect->top;
- lock_src.right = lock_src.left + w;
- lock_src.bottom = lock_src.top + h;
-
- lock_dst.left = dst_x;
- lock_dst.top = dst_y;
- lock_dst.right = dst_x + w;
- lock_dst.bottom = dst_y + h;
-
- bpp = dst_surface->resource.format->byte_count;
-
- /* We need to lock the surfaces, or we won't get refreshes when done. */
- if (src_surface == dst_surface)
- {
- int pitch;
-
- UnionRect(&lock_union, &lock_src, &lock_dst);
-
- /* Lock the union of the two rectangles. */
- hr = wined3d_surface_map(dst_surface, &dlock, &lock_union, 0);
- if (FAILED(hr))
- goto error;
-
- pitch = dlock.Pitch;
- slock.Pitch = dlock.Pitch;
-
- /* Since slock was originally copied from this surface's description, we can just reuse it. */
- sbuf = dst_surface->resource.allocatedMemory + lock_src.top * pitch + lock_src.left * bpp;
- dbuf = dst_surface->resource.allocatedMemory + lock_dst.top * pitch + lock_dst.left * bpp;
- src_format = src_surface->resource.format;
- dst_format = src_format;
- }
- else
- {
- hr = wined3d_surface_map(src_surface, &slock, &lock_src, WINED3DLOCK_READONLY);
- if (FAILED(hr))
- goto error;
- hr = wined3d_surface_map(dst_surface, &dlock, &lock_dst, 0);
- if (FAILED(hr))
- goto error;
-
- sbuf = slock.pBits;
- dbuf = dlock.pBits;
- TRACE("Dst is at %p, Src is at %p.\n", dbuf, sbuf);
-
- src_format = src_surface->resource.format;
- dst_format = dst_surface->resource.format;
- }
-
- /* Handle compressed surfaces first... */
- if (src_format->flags & dst_format->flags & WINED3DFMT_FLAG_COMPRESSED)
- {
- UINT row_block_count;
-
- TRACE("compressed -> compressed copy\n");
- if (trans)
- FIXME("trans arg not supported when a compressed surface is involved\n");
- if (dst_x || dst_y)
- FIXME("offset for destination surface is not supported\n");
- if (src_surface->resource.format->id != dst_surface->resource.format->id)
- {
- FIXME("compressed -> compressed copy only supported for the same type of surface\n");
- hr = WINED3DERR_WRONGTEXTUREFORMAT;
- goto error;
- }
-
- row_block_count = (w + dst_format->block_width - 1) / dst_format->block_width;
- for (y = 0; y < h; y += dst_format->block_height)
- {
- memcpy(dbuf, sbuf, row_block_count * dst_format->block_byte_count);
- dbuf += dlock.Pitch;
- sbuf += slock.Pitch;
- }
-
- goto error;
- }
- if ((src_format->flags & WINED3DFMT_FLAG_COMPRESSED) && !(dst_format->flags & WINED3DFMT_FLAG_COMPRESSED))
- {
- /* TODO: Use the libtxc_dxtn.so shared library to do software
- * decompression. */
- ERR("Software decompression not supported.\n");
- goto error;
- }
-
- if (trans & (WINEDDBLTFAST_SRCCOLORKEY | WINEDDBLTFAST_DESTCOLORKEY))
- {
- DWORD keylow, keyhigh;
- DWORD mask = src_surface->resource.format->red_mask
- | src_surface->resource.format->green_mask
- | src_surface->resource.format->blue_mask;
-
- /* For some 8-bit formats like L8 and P8 color masks don't make sense */
- if (!mask && bpp == 1)
- mask = 0xff;
-
- TRACE("Color keyed copy.\n");
- if (trans & WINEDDBLTFAST_SRCCOLORKEY)
- {
- keylow = src_surface->SrcBltCKey.dwColorSpaceLowValue;
- keyhigh = src_surface->SrcBltCKey.dwColorSpaceHighValue;
- }
- else
- {
- /* I'm not sure if this is correct. */
- FIXME("WINEDDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
- keylow = dst_surface->DestBltCKey.dwColorSpaceLowValue;
- keyhigh = dst_surface->DestBltCKey.dwColorSpaceHighValue;
- }
-
-#define COPYBOX_COLORKEY(type) \
-do { \
- const type *s = (const type *)sbuf; \
- type *d = (type *)dbuf; \
- type tmp; \
- for (y = 0; y < h; y++) \
- { \
- for (x = 0; x < w; x++) \
- { \
- tmp = s[x]; \
- if ((tmp & mask) < keylow || (tmp & mask) > keyhigh) d[x] = tmp; \
- } \
- s = (const type *)((const BYTE *)s + slock.Pitch); \
- d = (type *)((BYTE *)d + dlock.Pitch); \
- } \
-} while(0)
-
- switch (bpp)
- {
- case 1:
- COPYBOX_COLORKEY(BYTE);
- break;
- case 2:
- COPYBOX_COLORKEY(WORD);
- break;
- case 4:
- COPYBOX_COLORKEY(DWORD);
- break;
- case 3:
- {
- const BYTE *s;
- DWORD tmp;
- BYTE *d;
- s = sbuf;
- d = dbuf;
- for (y = 0; y < h; ++y)
- {
- for (x = 0; x < w * 3; x += 3)
- {
- tmp = (DWORD)s[x] + ((DWORD)s[x + 1] << 8) + ((DWORD)s[x + 2] << 16);
- if (tmp < keylow || tmp > keyhigh)
- {
- d[x + 0] = s[x + 0];
- d[x + 1] = s[x + 1];
- d[x + 2] = s[x + 2];
- }
- }
- s += slock.Pitch;
- d += dlock.Pitch;
- }
- break;
- }
- default:
- FIXME("Source color key blitting not supported for bpp %u.\n", bpp * 8);
- hr = WINED3DERR_NOTAVAILABLE;
- goto error;
- }
-#undef COPYBOX_COLORKEY
- TRACE("Copy done.\n");
- }
- else
- {
- int width = w * bpp;
- INT sbufpitch, dbufpitch;
-
- TRACE("No color key copy.\n");
- /* Handle overlapping surfaces. */
- if (sbuf < dbuf)
- {
- sbuf += (h - 1) * slock.Pitch;
- dbuf += (h - 1) * dlock.Pitch;
- sbufpitch = -slock.Pitch;
- dbufpitch = -dlock.Pitch;
- }
- else
- {
- sbufpitch = slock.Pitch;
- dbufpitch = dlock.Pitch;
- }
- for (y = 0; y < h; ++y)
- {
- /* This is pretty easy, a line for line memcpy. */
- memmove(dbuf, sbuf, width);
- sbuf += sbufpitch;
- dbuf += dbufpitch;
- }
- TRACE("Copy done.\n");
- }
-
-error:
- if (src_surface == dst_surface)
- {
- wined3d_surface_unmap(dst_surface);
- }
- else
- {
- wined3d_surface_unmap(dst_surface);
- wined3d_surface_unmap(src_surface);
- }
-
- return hr;
-}
-
/* Do not call while under the GL lock. */
static HRESULT cpu_blit_color_fill(struct wined3d_device *device, struct wined3d_surface *dst_surface,
const RECT *dst_rect, const WINED3DCOLORVALUE *color)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 1702046..d340049 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1984,8 +1984,6 @@ struct wined3d_surface_ops
void (*surface_unmap)(struct wined3d_surface *surface);
HRESULT (*surface_getdc)(struct wined3d_surface *surface);
HRESULT (*surface_flip)(struct wined3d_surface *surface, struct wined3d_surface *override);
- HRESULT (*surface_bltfast)(struct wined3d_surface *dst_surface, DWORD dst_x, DWORD dst_y,
- struct wined3d_surface *src_surface, const RECT *src_rect, DWORD trans);
HRESULT (*surface_set_mem)(struct wined3d_surface *surface, void *mem);
};
--
1.7.3.4
More information about the wine-patches
mailing list