d3dx9: Ignore filter in D3DXLoadSurfaceFromSurface() when rects match.
This allows us to use IDirect3DDevice9_StretchRect and avoid GPU synchronization. It massively improves performance in Dead Space 1 which calls LoadSurfaceFromSurface every frame before presenting. Signed-off-by: Robin Kertels <robin.kertels@gmail.com> Signed-off-by: Matteo Bruni <mbruni@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
99aa8b5ddc
commit
625622ad41
|
@ -2142,11 +2142,14 @@ HRESULT WINAPI D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_surface,
|
||||||
const PALETTEENTRY *dst_palette, const RECT *dst_rect, IDirect3DSurface9 *src_surface,
|
const PALETTEENTRY *dst_palette, const RECT *dst_rect, IDirect3DSurface9 *src_surface,
|
||||||
const PALETTEENTRY *src_palette, const RECT *src_rect, DWORD filter, D3DCOLOR color_key)
|
const PALETTEENTRY *src_palette, const RECT *src_rect, DWORD filter, D3DCOLOR color_key)
|
||||||
{
|
{
|
||||||
|
const struct pixel_format_desc *src_format_desc, *dst_format_desc;
|
||||||
|
D3DSURFACE_DESC src_desc, dst_desc;
|
||||||
|
struct volume src_size, dst_size;
|
||||||
IDirect3DSurface9 *temp_surface;
|
IDirect3DSurface9 *temp_surface;
|
||||||
D3DTEXTUREFILTERTYPE d3d_filter;
|
D3DTEXTUREFILTERTYPE d3d_filter;
|
||||||
IDirect3DDevice9 *device;
|
IDirect3DDevice9 *device;
|
||||||
D3DSURFACE_DESC src_desc;
|
|
||||||
D3DLOCKED_RECT lock;
|
D3DLOCKED_RECT lock;
|
||||||
|
RECT dst_rect_temp;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
RECT s;
|
RECT s;
|
||||||
|
|
||||||
|
@ -2158,7 +2161,70 @@ HRESULT WINAPI D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_surface,
|
||||||
if (!dst_surface || !src_surface)
|
if (!dst_surface || !src_surface)
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
|
IDirect3DSurface9_GetDesc(src_surface, &src_desc);
|
||||||
|
src_format_desc = get_format_info(src_desc.Format);
|
||||||
|
if (!src_rect)
|
||||||
|
{
|
||||||
|
SetRect(&s, 0, 0, src_desc.Width, src_desc.Height);
|
||||||
|
src_rect = &s;
|
||||||
|
}
|
||||||
|
else if (src_rect->left == src_rect->right || src_rect->top == src_rect->bottom)
|
||||||
|
{
|
||||||
|
WARN("Empty src_rect specified.\n");
|
||||||
|
return filter == D3DX_FILTER_NONE ? D3D_OK : E_FAIL;
|
||||||
|
}
|
||||||
|
else if (src_rect->left > src_rect->right || src_rect->right > src_desc.Width
|
||||||
|
|| src_rect->left < 0 || src_rect->left > src_desc.Width
|
||||||
|
|| src_rect->top > src_rect->bottom || src_rect->bottom > src_desc.Height
|
||||||
|
|| src_rect->top < 0 || src_rect->top > src_desc.Height)
|
||||||
|
{
|
||||||
|
WARN("Invalid src_rect specified.\n");
|
||||||
|
return D3DERR_INVALIDCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
src_size.width = src_rect->right - src_rect->left;
|
||||||
|
src_size.height = src_rect->bottom - src_rect->top;
|
||||||
|
src_size.depth = 1;
|
||||||
|
|
||||||
|
IDirect3DSurface9_GetDesc(dst_surface, &dst_desc);
|
||||||
|
dst_format_desc = get_format_info(dst_desc.Format);
|
||||||
|
if (!dst_rect)
|
||||||
|
{
|
||||||
|
SetRect(&dst_rect_temp, 0, 0, dst_desc.Width, dst_desc.Height);
|
||||||
|
dst_rect = &dst_rect_temp;
|
||||||
|
}
|
||||||
|
else if (dst_rect->left == dst_rect->right || dst_rect->top == dst_rect->bottom)
|
||||||
|
{
|
||||||
|
WARN("Empty dst_rect specified.\n");
|
||||||
|
return filter == D3DX_FILTER_NONE ? D3D_OK : E_FAIL;
|
||||||
|
}
|
||||||
|
else if (dst_rect->left > dst_rect->right || dst_rect->right > dst_desc.Width
|
||||||
|
|| dst_rect->left < 0 || dst_rect->left > dst_desc.Width
|
||||||
|
|| dst_rect->top > dst_rect->bottom || dst_rect->bottom > dst_desc.Height
|
||||||
|
|| dst_rect->top < 0 || dst_rect->top > dst_desc.Height)
|
||||||
|
{
|
||||||
|
WARN("Invalid dst_rect specified.\n");
|
||||||
|
return D3DERR_INVALIDCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst_size.width = dst_rect->right - dst_rect->left;
|
||||||
|
dst_size.height = dst_rect->bottom - dst_rect->top;
|
||||||
|
dst_size.depth = 1;
|
||||||
|
|
||||||
if (!dst_palette && !src_palette && !color_key)
|
if (!dst_palette && !src_palette && !color_key)
|
||||||
|
{
|
||||||
|
if (src_desc.Format == dst_desc.Format
|
||||||
|
&& dst_size.width == src_size.width
|
||||||
|
&& dst_size.height == src_size.height
|
||||||
|
&& color_key == 0
|
||||||
|
&& !(src_rect->left & (src_format_desc->block_width - 1))
|
||||||
|
&& !(src_rect->top & (src_format_desc->block_height - 1))
|
||||||
|
&& !(dst_rect->left & (dst_format_desc->block_width - 1))
|
||||||
|
&& !(dst_rect->top & (dst_format_desc->block_height - 1)))
|
||||||
|
{
|
||||||
|
d3d_filter = D3DTEXF_NONE;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
switch (filter)
|
switch (filter)
|
||||||
{
|
{
|
||||||
|
@ -2175,11 +2241,12 @@ HRESULT WINAPI D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_surface,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
d3d_filter = ~0u;
|
d3d_filter = D3DTEXF_FORCE_DWORD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (d3d_filter != ~0u)
|
if (d3d_filter != D3DTEXF_FORCE_DWORD)
|
||||||
{
|
{
|
||||||
IDirect3DSurface9_GetDevice(src_surface, &device);
|
IDirect3DSurface9_GetDevice(src_surface, &device);
|
||||||
hr = IDirect3DDevice9_StretchRect(device, src_surface, src_rect, dst_surface, dst_rect, d3d_filter);
|
hr = IDirect3DDevice9_StretchRect(device, src_surface, src_rect, dst_surface, dst_rect, d3d_filter);
|
||||||
|
@ -2189,14 +2256,6 @@ HRESULT WINAPI D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_surface,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IDirect3DSurface9_GetDesc(src_surface, &src_desc);
|
|
||||||
|
|
||||||
if (!src_rect)
|
|
||||||
{
|
|
||||||
SetRect(&s, 0, 0, src_desc.Width, src_desc.Height);
|
|
||||||
src_rect = &s;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(lock_surface(src_surface, NULL, &lock, &temp_surface, FALSE)))
|
if (FAILED(lock_surface(src_surface, NULL, &lock, &temp_surface, FALSE)))
|
||||||
return D3DXERR_INVALIDDATA;
|
return D3DXERR_INVALIDDATA;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue