[PATCH] d3dx9: Ignore filter in LoadSurfaceFromSurface when rects match

Matteo Bruni matteo.mystral at gmail.com
Tue Jul 7 16:16:45 CDT 2020


On Mon, Jul 6, 2020 at 3:53 PM Robin Kertels <robin.kertels at gmail.com> wrote:
>
> 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>

Nice! Do you know which surface it's copying around?

> ---
>  dlls/d3dx9_36/surface.c | 100 +++++++++++++++++++++++++++++++---------
>  1 file changed, 78 insertions(+), 22 deletions(-)

Patch looks pretty good but there are a couple of edge cases that need
tests. Comments inline.

> diff --git a/dlls/d3dx9_36/surface.c b/dlls/d3dx9_36/surface.c
> index a5143cbee4..c351fe58cd 100644
> --- a/dlls/d3dx9_36/surface.c
> +++ b/dlls/d3dx9_36/surface.c
> @@ -2142,10 +2142,13 @@ 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;
> +    struct volume src_size, dst_size;
> +    RECT dst_rect_temp;
>      IDirect3DSurface9 *temp_surface;
>      D3DTEXTUREFILTERTYPE d3d_filter;
>      IDirect3DDevice9 *device;
> -    D3DSURFACE_DESC src_desc;
> +    D3DSURFACE_DESC src_desc, dst_desc;
>      D3DLOCKED_RECT lock;
>      HRESULT hr;
>      RECT s;
> @@ -2158,25 +2161,86 @@ HRESULT WINAPI D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_surface,
>      if (!dst_surface || !src_surface)
>          return D3DERR_INVALIDCALL;
>
> +
> +    IDirect3DSurface9_GetDesc(src_surface, &src_desc);
> +
> +    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("Invalid src_rect.\n");
> +        return E_FAIL;
> +    }

It looks like we don't have d3dx9 tests for this. Care to add one?

> +
>      if (!dst_palette && !src_palette && !color_key)
>      {
> -        switch (filter)
> +        srcformatdesc = get_format_info(src_desc.Format);
> +
> +        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)
>          {
> -            case D3DX_FILTER_NONE:
> -                d3d_filter = D3DTEXF_NONE;
> -                break;
> +            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->right > dst_desc.Width
> +                    || dst_rect->top > dst_rect->bottom || dst_rect->bottom > dst_desc.Height
> +                    || dst_rect->left < 0 || dst_rect->top < 0)
> +            {
> +                WARN("Invalid dst_rect specified.\n");
> +                return D3DERR_INVALIDCALL;
> +            }
> +            if (dst_rect->left == dst_rect->right || dst_rect->top == dst_rect->bottom)
> +            {
> +                WARN("Empty dst_rect specified.\n");
> +                return D3D_OK;
> +            }

Same for these.



More information about the wine-devel mailing list