Module: wine Branch: master Commit: b322f81b758b88d2a060c3d1408b827cf7885735 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b322f81b758b88d2a060c3d140...
Author: Stefan Dösinger stefan@codeweavers.com Date: Wed Feb 6 20:16:13 2008 +0100
wined3d: Reject unsupported modes when restting the device.
---
dlls/d3d9/tests/device.c | 42 +++++++++++++++++++++++++++++++++++++++++- dlls/wined3d/device.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletions(-)
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index bba4eb2..4c6f82e 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -716,7 +716,7 @@ static void test_reset(void) IDirect3D9 *pD3d = NULL; IDirect3DDevice9 *pDevice = NULL; D3DPRESENT_PARAMETERS d3dpp; - D3DDISPLAYMODE d3ddm; + D3DDISPLAYMODE d3ddm, d3ddm2; D3DVIEWPORT9 vp; DWORD width, orig_width = GetSystemMetrics(SM_CXSCREEN); DWORD height, orig_height = GetSystemMetrics(SM_CYSCREEN); @@ -724,6 +724,8 @@ static void test_reset(void) IDirect3DSurface9 *surface; IDirect3DTexture9 *texture; IDirect3DVertexShader9 *shader; + BOOL support_800x600 = FALSE; + UINT i;
pD3d = pDirect3DCreate9( D3D_SDK_VERSION ); ok(pD3d != NULL, "Failed to create IDirect3D9 object\n"); @@ -739,6 +741,27 @@ static void test_reset(void) d3dpp.BackBufferHeight = 600; d3dpp.BackBufferFormat = d3ddm.Format;
+ for(i = 0; i < IDirect3D9_GetAdapterModeCount(pD3d, D3DADAPTER_DEFAULT, d3ddm.Format); i++) { + ZeroMemory( &d3ddm2, sizeof(d3ddm2) ); + hr = IDirect3D9_EnumAdapterModes(pD3d, D3DADAPTER_DEFAULT, d3ddm.Format, i, &d3ddm2); + ok(hr == D3D_OK, "IDirect3D9Impl_EnumAdapterModes returned %#x\n", hr); + + if(d3ddm2.Width == 800 && d3ddm2.Height == 600) { + support_800x600 = TRUE; + } + /* We use them as invalid modes */ + if((d3ddm2.Width == 801 && d3ddm2.Height == 600) || + (d3ddm2.Width == 32 && d3ddm2.Height == 32)) { + skip("This system supports a screen resolution of %dx%d, not running mode tests\n", + d3ddm2.Width, d3ddm2.Height); + goto cleanup; + } + } + if(!support_800x600) { + skip("Mode 800x600 not supported, skipping mode tests\n"); + goto cleanup; + } + hr = IDirect3D9_CreateDevice( pD3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL /* no NULLREF here */, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pDevice );
@@ -903,6 +926,22 @@ static void test_reset(void) ok(hr == D3D_OK, "IDirect3DDevice9_Reset failed with %s\n", DXGetErrorString9(hr)); IDirect3DVertexShader9_Release(shader);
+ /* Try setting invalid modes */ + ZeroMemory( &d3dpp, sizeof(d3dpp) ); + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.Windowed = FALSE; + d3dpp.BackBufferWidth = 32; + d3dpp.BackBufferHeight = 32; + hr = IDirect3DDevice9_Reset(pDevice, &d3dpp); + ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=32, h=32, windowed=FALSE failed with %s\n", DXGetErrorString9(hr)); + ZeroMemory( &d3dpp, sizeof(d3dpp) ); + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.Windowed = FALSE; + d3dpp.BackBufferWidth = 801; + d3dpp.BackBufferHeight = 600; + hr = IDirect3DDevice9_Reset(pDevice, &d3dpp); + ok(hr == D3DERR_INVALIDCALL, "IDirect3DDevice9_Reset to w=801, h=600, windowed=FALSE failed with %s\n", DXGetErrorString9(hr)); + cleanup: if(pD3d) IDirect3D9_Release(pD3d); if(pDevice) IDirect3D9_Release(pDevice); @@ -1820,6 +1859,7 @@ START_TEST(device) test_mipmap_levels(); test_cursor(); test_reset(); + test_reset(); test_scene(); test_limits(); test_depthstenciltest(); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 10d11b8..c504e50 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -6769,6 +6769,32 @@ static void reset_fbo_state(IWineD3DDevice *iface) { This->fbo_depth_attachment = NULL; }
+static BOOL is_display_mode_supported(IWineD3DDeviceImpl *This, WINED3DPRESENT_PARAMETERS *pp) { + UINT i, count; + WINED3DDISPLAYMODE m; + HRESULT hr; + + /* All Windowed modes are supported, as is leaving the current mode */ + if(pp->Windowed) return TRUE; + if(!pp->BackBufferWidth) return TRUE; + if(!pp->BackBufferHeight) return TRUE; + + count = IWineD3D_GetAdapterModeCount(This->wineD3D, This->adapter->num, WINED3DFMT_UNKNOWN); + for(i = 0; i < count; i++) { + memset(&m, 0, sizeof(m)); + hr = IWineD3D_EnumAdapterModes(This->wineD3D, This->adapter->num, WINED3DFMT_UNKNOWN, i, &m); + if(FAILED(hr)) { + ERR("EnumAdapterModes failed\n"); + } + if(m.Width == pp->BackBufferWidth && m.Height == pp->BackBufferHeight) { + /* Mode found, it is supported */ + return TRUE; + } + } + /* Mode not found -> not supported */ + return FALSE; +} + static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters) { IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; IWineD3DSwapChainImpl *swapchain; @@ -6786,6 +6812,13 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE return hr; }
+ if(!is_display_mode_supported(This, pPresentationParameters)) { + WARN("Rejecting Reset() call because the requested display mode is not supported\n"); + WARN("Requested mode: %d, %d\n", pPresentationParameters->BackBufferWidth, + pPresentationParameters->BackBufferHeight); + return WINED3DERR_INVALIDCALL; + } + /* Is it necessary to recreate the gl context? Actually every setting can be changed * on an existing gl context, so there's no real need for recreation. *