https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a5f345390cca9992f523cfe66eac6979f9f09b64

commit a5f345390cca9992f523cfe66eac6979f9f09b64
Author:     winesync <[email protected]>
AuthorDate: Mon Sep 21 23:07:40 2020 +0200
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Thu Feb 4 16:37:07 2021 +0100

    [WINESYNC] 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 <[email protected]>
    Signed-off-by: Matteo Bruni <[email protected]>
    Signed-off-by: Alexandre Julliard <[email protected]>
    
    wine commit id 625622ad4182061ee3111032ab0ae4a494b74e73 by Robin Kertels 
<[email protected]>
---
 dll/directx/wine/d3dx9_36/surface.c | 105 ++++++++++++++++++++++++++++--------
 sdk/tools/winesync/d3dx9.cfg        |   2 +-
 2 files changed, 83 insertions(+), 24 deletions(-)

diff --git a/dll/directx/wine/d3dx9_36/surface.c 
b/dll/directx/wine/d3dx9_36/surface.c
index 24b19b6b37f..0deca8c01a0 100644
--- a/dll/directx/wine/d3dx9_36/surface.c
+++ b/dll/directx/wine/d3dx9_36/surface.c
@@ -2146,11 +2146,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 *src_format_desc, *dst_format_desc;
+    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;
 
@@ -2162,28 +2165,92 @@ HRESULT WINAPI 
D3DXLoadSurfaceFromSurface(IDirect3DSurface9 *dst_surface,
     if (!dst_surface || !src_surface)
         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)
     {
-        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 & (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)))
         {
-            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 = D3DTEXF_FORCE_DWORD;
+                    break;
+            }
         }
 
-        if (d3d_filter != ~0u)
+        if (d3d_filter != D3DTEXF_FORCE_DWORD)
         {
             IDirect3DSurface9_GetDevice(src_surface, &device);
             hr = IDirect3DDevice9_StretchRect(device, src_surface, src_rect, 
dst_surface, dst_rect, d3d_filter);
@@ -2193,14 +2260,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;
 
diff --git a/sdk/tools/winesync/d3dx9.cfg b/sdk/tools/winesync/d3dx9.cfg
index b8c926c44aa..3bc87510483 100644
--- a/sdk/tools/winesync/d3dx9.cfg
+++ b/sdk/tools/winesync/d3dx9.cfg
@@ -15,4 +15,4 @@ files: {include/d3dx9.h: sdk/include/dxsdk/d3dx9.h, 
include/d3dx9anim.h: sdk/inc
   include/d3dx9mesh.h: sdk/include/dxsdk/d3dx9mesh.h, include/d3dx9of.h: 
sdk/include/dxsdk/d3dx9of.h,
   include/d3dx9shader.h: sdk/include/dxsdk/d3dx9shader.h, 
include/d3dx9shape.h: sdk/include/dxsdk/d3dx9shape.h,
   include/d3dx9tex.h: sdk/include/dxsdk/d3dx9tex.h, include/d3dx9xof.h: 
sdk/include/dxsdk/d3dx9xof.h}
-tags: {wine: 35a4093eff75e5bf7fee0dc8d2a708d960b03768}
+tags: {wine: 625622ad4182061ee3111032ab0ae4a494b74e73}

Reply via email to