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

This commit is contained in:
Henri Verbeet 2011-05-03 22:30:20 +02:00 committed by Alexandre Julliard
parent 7db1ebb853
commit 693fb6d56c
3 changed files with 78 additions and 8 deletions

View File

@ -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,

View File

@ -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();

View File

@ -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);