Henri Verbeet : d3d8: Check for D3DPOOL_DEFAULT resources before doing a Reset().

Alexandre Julliard julliard at winehq.org
Wed May 4 13:47:40 CDT 2011


Module: wine
Branch: master
Commit: 693fb6d56cb11275ee8a6b96fbb01fc1ded82ff7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=693fb6d56cb11275ee8a6b96fbb01fc1ded82ff7

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Tue May  3 22:30:20 2011 +0200

d3d8: Check for D3DPOOL_DEFAULT resources before doing a Reset().

---

 dlls/d3d8/d3d8_private.h |    1 +
 dlls/d3d8/device.c       |   73 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/d3d8/tests/device.c |   12 ++++----
 3 files changed, 78 insertions(+), 8 deletions(-)

diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index 96b31d0..8039048 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -187,6 +187,7 @@ struct IDirect3DDevice8Impl
 
     /* Avoids recursion with nested ReleaseRef to 0 */
     BOOL                    inDestruction;
+    BOOL lost;
 };
 
 HRESULT device_init(IDirect3DDevice8Impl *device, struct wined3d *wined3d, UINT adapter,
diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index 0945632..6d0b247 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -334,8 +334,16 @@ static ULONG WINAPI IDirect3DDevice8Impl_Release(IDirect3DDevice8 *iface)
 /* IDirect3DDevice Interface follow: */
 static HRESULT WINAPI IDirect3DDevice8Impl_TestCooperativeLevel(IDirect3DDevice8 *iface)
 {
+    IDirect3DDevice8Impl *device = impl_from_IDirect3DDevice8(iface);
+
     TRACE("iface %p.\n", iface);
 
+    if (device->lost)
+    {
+        TRACE("Device is lost.\n");
+        return D3DERR_DEVICENOTRESET;
+    }
+
     return D3D_OK;
 }
 
@@ -542,15 +550,71 @@ static HRESULT WINAPI IDirect3DDevice8Impl_CreateAdditionalSwapChain(IDirect3DDe
     return D3D_OK;
 }
 
+static HRESULT WINAPI reset_enum_callback(struct wined3d_resource *resource, void *data)
+{
+    struct wined3d_resource_desc desc;
+    BOOL *resources_ok = data;
+
+    wined3d_resource_get_desc(resource, &desc);
+    if (desc.pool == WINED3DPOOL_DEFAULT)
+    {
+        IDirect3DSurface8 *surface;
+
+        if (desc.resource_type != WINED3DRTYPE_SURFACE)
+        {
+            WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource);
+            *resources_ok = FALSE;
+            return S_FALSE;
+        }
+
+        surface = wined3d_resource_get_parent(resource);
+
+        IDirect3DSurface8_AddRef(surface);
+        if (IDirect3DSurface8_Release(surface))
+        {
+            WARN("Surface %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface, resource);
+            *resources_ok = FALSE;
+            return S_FALSE;
+        }
+
+        WARN("Surface %p (resource %p) is an implicit resource with ref 0.\n", surface, resource);
+    }
+
+    return S_OK;
+}
+
 static HRESULT WINAPI IDirect3DDevice8Impl_Reset(IDirect3DDevice8 *iface,
         D3DPRESENT_PARAMETERS *pPresentationParameters)
 {
     IDirect3DDevice8Impl *This = impl_from_IDirect3DDevice8(iface);
     WINED3DPRESENT_PARAMETERS localParameters;
+    BOOL resources_ok = TRUE;
     HRESULT hr;
+    UINT i;
 
     TRACE("iface %p, present_parameters %p.\n", iface, pPresentationParameters);
 
+    wined3d_mutex_lock();
+    IWineD3DDevice_SetIndexBuffer(This->WineD3DDevice, NULL, WINED3DFMT_UNKNOWN);
+    for (i = 0; i < 16; ++i)
+    {
+        IWineD3DDevice_SetStreamSource(This->WineD3DDevice, i, NULL, 0, 0);
+    }
+    for (i = 0; i < 16; ++i)
+    {
+        IWineD3DDevice_SetTexture(This->WineD3DDevice, i, NULL);
+    }
+
+    IWineD3DDevice_EnumResources(This->WineD3DDevice, reset_enum_callback, &resources_ok);
+    if (!resources_ok)
+    {
+        WARN("The application is holding D3DPOOL_DEFAULT resources, rejecting reset.\n");
+        This->lost = TRUE;
+        wined3d_mutex_unlock();
+
+        return D3DERR_DEVICELOST;
+    }
+
     localParameters.BackBufferWidth                             = pPresentationParameters->BackBufferWidth;
     localParameters.BackBufferHeight                            = pPresentationParameters->BackBufferHeight;
     localParameters.BackBufferFormat                            = wined3dformat_from_d3dformat(pPresentationParameters->BackBufferFormat);
@@ -567,10 +631,15 @@ static HRESULT WINAPI IDirect3DDevice8Impl_Reset(IDirect3DDevice8 *iface,
     localParameters.PresentationInterval                        = pPresentationParameters->FullScreen_PresentationInterval;
     localParameters.AutoRestoreDisplayMode                      = TRUE;
 
-    wined3d_mutex_lock();
     hr = IWineD3DDevice_Reset(This->WineD3DDevice, &localParameters);
-    if(SUCCEEDED(hr)) {
+    if (SUCCEEDED(hr))
+    {
         hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, WINED3DRS_POINTSIZE_MIN, 0);
+        This->lost = FALSE;
+    }
+    else
+    {
+        This->lost = TRUE;
     }
     wined3d_mutex_unlock();
 
diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c
index 07aef02..bf2d4c3 100644
--- a/dlls/d3d8/tests/device.c
+++ b/dlls/d3d8/tests/device.c
@@ -1089,9 +1089,9 @@ static void test_reset(void)
     hr = IDirect3DDevice8_CreateTexture(device1, 16, 16, 1, 0, D3DFMT_R5G6B5, D3DPOOL_DEFAULT, &texture);
     ok(SUCCEEDED(hr), "CreateTexture failed, hr %#x.\n", hr);
     hr = IDirect3DDevice8_Reset(device1, &d3dpp);
-    todo_wine ok(hr == D3DERR_DEVICELOST, "Reset returned %#x, expected %#x.\n", hr, D3DERR_DEVICELOST);
+    ok(hr == D3DERR_DEVICELOST, "Reset returned %#x, expected %#x.\n", hr, D3DERR_DEVICELOST);
     hr = IDirect3DDevice8_TestCooperativeLevel(device1);
-    todo_wine ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n", hr, D3DERR_DEVICENOTRESET);
+    ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n", hr, D3DERR_DEVICENOTRESET);
     IDirect3DTexture8_Release(texture);
     /* Reset again to get the device out of the lost state. */
     hr = IDirect3DDevice8_Reset(device1, &d3dpp);
@@ -1177,9 +1177,9 @@ static void test_reset(void)
     hr = IDirect3DDevice8_GetBackBuffer(device1, 0, D3DBACKBUFFER_TYPE_MONO, &surface);
     ok(SUCCEEDED(hr), "GetBackBuffer failed, hr %#x.\n", hr);
     hr = IDirect3DDevice8_Reset(device1, &d3dpp);
-    todo_wine ok(hr == D3DERR_DEVICELOST, "Reset returned %#x, expected %#x.\n", hr, D3DERR_DEVICELOST);
+    ok(hr == D3DERR_DEVICELOST, "Reset returned %#x, expected %#x.\n", hr, D3DERR_DEVICELOST);
     hr = IDirect3DDevice8_TestCooperativeLevel(device1);
-    todo_wine ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n", hr, D3DERR_DEVICENOTRESET);
+    ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n", hr, D3DERR_DEVICENOTRESET);
     IDirect3DSurface8_Release(surface);
     hr = IDirect3DDevice8_Reset(device1, &d3dpp);
     ok(SUCCEEDED(hr), "Reset failed, hr %#x.\n", hr);
@@ -1204,7 +1204,7 @@ static void test_reset(void)
     hr = IDirect3DDevice8_Reset(device1, &d3dpp);
     ok(hr == D3DERR_INVALIDCALL, "Reset returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
     hr = IDirect3DDevice8_TestCooperativeLevel(device1);
-    todo_wine ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n", hr, D3DERR_DEVICENOTRESET);
+    ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n", hr, D3DERR_DEVICENOTRESET);
 
     memset(&d3dpp, 0, sizeof(d3dpp));
     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
@@ -1215,7 +1215,7 @@ static void test_reset(void)
     hr = IDirect3DDevice8_Reset(device1, &d3dpp);
     ok(hr == D3DERR_INVALIDCALL, "Reset returned %#x, expected %#x.\n", hr, D3DERR_INVALIDCALL);
     hr = IDirect3DDevice8_TestCooperativeLevel(device1);
-    todo_wine ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n", hr, D3DERR_DEVICENOTRESET);
+    ok(hr == D3DERR_DEVICENOTRESET, "TestCooperativeLevel returned %#x, expected %#x.\n", hr, D3DERR_DEVICENOTRESET);
 
     hr = IDirect3D8_GetAdapterDisplayMode(d3d8, D3DADAPTER_DEFAULT, &d3ddm);
     ok(SUCCEEDED(hr), "GetAdapterDisplayMode failed, hr %#x.\n", hr);




More information about the wine-cvs mailing list