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