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