[PATCH 1/5] wined3d: Relax depth blit requirements (try 2)

Stefan Dösinger stefan at codeweavers.com
Sun Jan 22 09:32:19 CST 2012


This fixes bug 10636.

This is a resend of my patches from a few weeks ago. Patches 1 and 2 are rebased,
but otherwise unmodified, patch 3 uses create_device now.
---
 dlls/d3d9/d3d9_private.h |    1 +
 dlls/d3d9/device.c       |   63 ++++++++++++++++++++++++++++++++++++++++------
 dlls/wined3d/surface.c   |   32 -----------------------
 3 files changed, 56 insertions(+), 40 deletions(-)

diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index 9feda66..5886618 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -173,6 +173,7 @@ typedef struct IDirect3DDevice9Impl
     unsigned int                 numConvertedDecls, declArraySize;
 
     BOOL                          notreset;
+    BOOL                          in_scene;
 } IDirect3DDevice9Impl;
 
 HRESULT device_init(IDirect3DDevice9Impl *device, IDirect3D9Impl *parent, struct wined3d *wined3d, UINT adapter, D3DDEVTYPE device_type,
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index 631ba5a..39cd740 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -1035,22 +1035,67 @@ static HRESULT WINAPI IDirect3DDevice9Impl_GetFrontBufferData(IDirect3DDevice9Ex
     return hr;
 }
 
-static HRESULT WINAPI IDirect3DDevice9Impl_StretchRect(IDirect3DDevice9Ex *iface, IDirect3DSurface9 *pSourceSurface,
-        const RECT *pSourceRect, IDirect3DSurface9 *pDestSurface, const RECT *pDestRect, D3DTEXTUREFILTERTYPE Filter)
+static HRESULT WINAPI IDirect3DDevice9Impl_StretchRect(IDirect3DDevice9Ex *iface, IDirect3DSurface9 *src_surface,
+        const RECT *src_rect, IDirect3DSurface9 *dst_surface, const RECT *dst_rect, D3DTEXTUREFILTERTYPE filter)
 {
-    IDirect3DSurface9Impl *src = unsafe_impl_from_IDirect3DSurface9(pSourceSurface);
-    IDirect3DSurface9Impl *dst = unsafe_impl_from_IDirect3DSurface9(pDestSurface);
-    HRESULT hr;
+    IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
+    IDirect3DSurface9Impl *src = unsafe_impl_from_IDirect3DSurface9(src_surface);
+    IDirect3DSurface9Impl *dst = unsafe_impl_from_IDirect3DSurface9(dst_surface);
+    HRESULT hr = D3DERR_INVALIDCALL;
+    struct wined3d_resource_desc src_desc, dst_desc;
+    struct wined3d_resource *wined3d_resource;
 
     TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %#x.\n",
-            iface, pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter);
+            iface, src_surface, src_rect, dst_surface, dst_rect, filter);
 
     wined3d_mutex_lock();
-    hr = wined3d_surface_blt(dst->wined3d_surface, pDestRect, src->wined3d_surface, pSourceRect, 0, NULL, Filter);
+    wined3d_resource = wined3d_surface_get_resource(dst->wined3d_surface);
+    wined3d_resource_get_desc(wined3d_resource, &dst_desc);
+
+    wined3d_resource = wined3d_surface_get_resource(src->wined3d_surface);
+    wined3d_resource_get_desc(wined3d_resource, &src_desc);
+
+    if (src_desc.usage & WINED3DUSAGE_DEPTHSTENCIL)
+    {
+        if (This->in_scene)
+        {
+            WARN("Rejecting depth / stencil blit while in scene.\n");
+            goto done;
+        }
+
+        if (src_rect)
+        {
+            if (src_rect->left || src_rect->top || src_rect->right != src_desc.width
+                    || src_rect->bottom != src_desc.height)
+            {
+                WARN("Rejecting depth / stencil blit with invalid source rect %s.\n",
+                        wine_dbgstr_rect(src_rect));
+                goto done;
+            }
+        }
+        if (dst_rect)
+        {
+            if (dst_rect->left || dst_rect->top || dst_rect->right != dst_desc.width
+                    || dst_rect->bottom != dst_desc.height)
+            {
+                WARN("Rejecting depth / stencil blit with invalid destination rect %s.\n",
+                        wine_dbgstr_rect(dst_rect));
+                goto done;
+            }
+        }
+        if (src_desc.width != dst_desc.width || src_desc.height != dst_desc.height)
+        {
+            WARN("Rejecting depth / stencil blit with mismatched surface sizes.\n");
+            goto done;
+        }
+    }
+
+    hr = wined3d_surface_blt(dst->wined3d_surface, dst_rect, src->wined3d_surface, src_rect, 0, NULL, filter);
     if (hr == WINEDDERR_INVALIDRECT)
         hr = D3DERR_INVALIDCALL;
-    wined3d_mutex_unlock();
 
+done:
+    wined3d_mutex_unlock();
     return hr;
 }
 
@@ -1245,6 +1290,7 @@ static HRESULT WINAPI IDirect3DDevice9Impl_BeginScene(IDirect3DDevice9Ex *iface)
 
     wined3d_mutex_lock();
     hr = wined3d_device_begin_scene(This->wined3d_device);
+    if (SUCCEEDED(hr)) This->in_scene = TRUE;
     wined3d_mutex_unlock();
 
     return hr;
@@ -1259,6 +1305,7 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_EndScene(IDirect3DD
 
     wined3d_mutex_lock();
     hr = wined3d_device_end_scene(This->wined3d_device);
+    if (SUCCEEDED(hr)) This->in_scene = FALSE;
     wined3d_mutex_unlock();
 
     return hr;
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 023bf6a..e6b4cd8 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -1590,44 +1590,12 @@ HRESULT CDECL wined3d_surface_blt(struct wined3d_surface *dst_surface, const REC
         }
         else
         {
-            /* Accessing depth / stencil surfaces is supposed to fail while in
-             * a scene, except for fills, which seem to work. */
-            if (device->inScene)
-            {
-                WARN("Rejecting depth / stencil access while in scene.\n");
-                return WINED3DERR_INVALIDCALL;
-            }
-
             if (src_ds_flags != dst_ds_flags)
             {
                 WARN("Rejecting depth / stencil blit between incompatible formats.\n");
                 return WINED3DERR_INVALIDCALL;
             }
 
-            if (src_rect.top || src_rect.left
-                    || src_rect.bottom != src_surface->resource.height
-                    || src_rect.right != src_surface->resource.width)
-            {
-                WARN("Rejecting depth / stencil blit with invalid source rect %s.\n",
-                        wine_dbgstr_rect(&src_rect));
-                return WINED3DERR_INVALIDCALL;
-            }
-
-            if (dst_rect.top || dst_rect.left
-                    || dst_rect.bottom != dst_surface->resource.height
-                    || dst_rect.right != dst_surface->resource.width)
-            {
-                WARN("Rejecting depth / stencil blit with invalid destination rect %s.\n",
-                        wine_dbgstr_rect(&src_rect));
-                return WINED3DERR_INVALIDCALL;
-            }
-
-            if (scale)
-            {
-                WARN("Rejecting depth / stencil blit with mismatched surface sizes.\n");
-                return WINED3DERR_INVALIDCALL;
-            }
-
             if (SUCCEEDED(wined3d_surface_depth_blt(src_surface, &src_rect, dst_surface, &dst_rect)))
                 return WINED3D_OK;
         }
-- 
1.7.3.4




More information about the wine-patches mailing list