Stefan Dösinger : wined3d: Reject unsupported modes when restting the device.
Alexandre Julliard
julliard at winehq.org
Thu Feb 7 07:59:37 CST 2008
Module: wine
Branch: master
Commit: b322f81b758b88d2a060c3d1408b827cf7885735
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b322f81b758b88d2a060c3d1408b827cf7885735
Author: Stefan Dösinger <stefan at 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.
*
More information about the wine-cvs
mailing list