Module: wine Branch: master Commit: 693fb6d56cb11275ee8a6b96fbb01fc1ded82ff7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=693fb6d56cb11275ee8a6b96fb...
Author: Henri Verbeet hverbeet@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);