[PATCH v2 1/2] d3dx9: Ignore filter in LoadSurfaceFromSurface when rects match
Robin Kertels
robin.kertels at gmail.com
Tue Jul 7 18:24:05 CDT 2020
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 at gmail.com>
---
dlls/d3dx9_36/surface.c | 106 +++++++++++++++++++++++++++++++---------
1 file changed, 84 insertions(+), 22 deletions(-)
diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
index a5143cbee4..fdf0ce28da 100644
--- a/dlls/d3dx9_36/surface.c
+++ b/dlls/d3dx9_36/surface.c
@@ -2142,11 +2142,14 @@ HRESULT WINAPI D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_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 struct pixel_format_desc *srcformatdesc, *destformatdesc;
+ D3DSURFACE_DESC src_desc, dst_desc;
+ struct volume src_size, dst_size;
IDirect3DSurface9 *temp_surface;
D3DTEXTUREFILTERTYPE d3d_filter;
IDirect3DDevice9 *device;
- D3DSURFACE_DESC src_desc;
D3DLOCKED_RECT lock;
+ RECT dst_rect_temp;
HRESULT hr;
RECT s;
@@ -2158,25 +2161,92 @@ HRESULT WINAPI D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_surface,
if (!dst_surface || !src_surface)
return D3DERR_INVALIDCALL;
+ IDirect3DSurface9_GetDesc(src_surface, &src_desc);
+ srcformatdesc = 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 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);
+ destformatdesc = get_format_info(dst_desc.Format);
+ if (!dst_rect)
+ {
+ dst_rect = &dst_rect_temp;
+ dst_rect_temp.left = 0;
+ dst_rect_temp.top = 0;
+ dst_rect_temp.right = dst_desc.Width;
+ dst_rect_temp.bottom = dst_desc.Height;
+ }
+ else if (dst_rect->left == dst_rect->right || dst_rect->top == dst_rect->bottom)
+ {
+ WARN("Empty dst_rect specified.\n");
+ return 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)
{
- switch (filter)
+ 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 & (srcformatdesc->block_width - 1))
+ && !(src_rect->top & (srcformatdesc->block_height - 1))
+ && !(dst_rect->left & (destformatdesc->block_width - 1))
+ && !(dst_rect->top & (destformatdesc->block_height - 1)))
{
- case D3DX_FILTER_NONE:
- d3d_filter = D3DTEXF_NONE;
- break;
+ d3d_filter = D3DTEXF_NONE;
+ }
+ else
+ {
+ switch (filter)
+ {
+ case D3DX_FILTER_NONE:
+ d3d_filter = D3DTEXF_NONE;
+ break;
- case D3DX_FILTER_POINT:
- d3d_filter = D3DTEXF_POINT;
- break;
+ case D3DX_FILTER_POINT:
+ d3d_filter = D3DTEXF_POINT;
+ break;
- case D3DX_FILTER_LINEAR:
- d3d_filter = D3DTEXF_LINEAR;
- break;
+ case D3DX_FILTER_LINEAR:
+ d3d_filter = D3DTEXF_LINEAR;
+ break;
- default:
- d3d_filter = ~0u;
- break;
+ default:
+ d3d_filter = ~0u;
+ break;
+ }
}
if (d3d_filter != ~0u)
@@ -2189,14 +2259,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)))
return D3DXERR_INVALIDDATA;
--
2.27.0
More information about the wine-devel
mailing list