Henri Verbeet : ddraw: Maintain D3D state across cooperative level changes.

Alexandre Julliard julliard at winehq.org
Wed Jan 18 14:03:37 CST 2012


Module: wine
Branch: master
Commit: 992dbc10786b79959d8b0a790974f6630aa81e3b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=992dbc10786b79959d8b0a790974f6630aa81e3b

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Tue Jan 17 21:13:35 2012 +0100

ddraw: Maintain D3D state across cooperative level changes.

---

 dlls/ddraw/ddraw.c        |   59 +++++++++++++++++++++++++++++++++++++++++++++
 dlls/ddraw/tests/ddraw1.c |    2 +-
 dlls/ddraw/tests/ddraw2.c |    6 ++--
 dlls/ddraw/tests/ddraw4.c |    6 ++--
 dlls/ddraw/tests/ddraw7.c |    6 ++--
 5 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index e413ae6..c3f5387 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -759,6 +759,9 @@ static HRESULT ddraw_create_swapchain(IDirectDrawImpl *ddraw, HWND window, BOOL
 static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND hwnd, DWORD cooplevel)
 {
     IDirectDrawImpl *This = impl_from_IDirectDraw7(iface);
+    struct wined3d_stateblock *stateblock;
+    struct wined3d_surface *rt, *ds;
+    BOOL restore_state = FALSE;
     HWND window;
     HRESULT hr;
 
@@ -914,10 +917,66 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND hwnd,
         wined3d_device_set_multithreaded(This->wined3d_device);
 
     if (This->wined3d_swapchain)
+    {
+        if (DefaultSurfaceType != SURFACE_GDI)
+        {
+            restore_state = TRUE;
+
+            if (FAILED(hr = wined3d_stateblock_create(This->wined3d_device, WINED3DSBT_ALL, &stateblock)))
+            {
+                ERR("Failed to create stateblock, hr %#x.\n", hr);
+                wined3d_mutex_unlock();
+                return hr;
+            }
+
+            if (FAILED(hr = wined3d_stateblock_capture(stateblock)))
+            {
+                ERR("Failed to capture stateblock, hr %#x.\n", hr);
+                wined3d_stateblock_decref(stateblock);
+                wined3d_mutex_unlock();
+                return hr;
+            }
+
+            wined3d_device_get_render_target(This->wined3d_device, 0, &rt);
+            if (rt == This->wined3d_frontbuffer)
+            {
+                wined3d_surface_decref(rt);
+                rt = NULL;
+            }
+
+            wined3d_device_get_depth_stencil(This->wined3d_device, &ds);
+        }
+
         ddraw_destroy_swapchain(This);
+    }
+
     if (FAILED(hr = ddraw_create_swapchain(This, This->dest_window, !(cooplevel & DDSCL_FULLSCREEN))))
         ERR("Failed to create swapchain, hr %#x.\n", hr);
 
+    if (restore_state)
+    {
+        if (ds)
+        {
+            wined3d_device_set_depth_stencil(This->wined3d_device, ds);
+            wined3d_surface_decref(ds);
+        }
+
+        if (rt)
+        {
+            wined3d_device_set_render_target(This->wined3d_device, 0, rt, FALSE);
+            wined3d_surface_decref(rt);
+        }
+
+        hr = wined3d_stateblock_apply(stateblock);
+        wined3d_stateblock_decref(stateblock);
+        if (FAILED(hr))
+        {
+            ERR("Failed to apply stateblock, hr %#x.\n", hr);
+            wined3d_mutex_unlock();
+            return hr;
+        }
+    }
+
     /* Unhandled flags */
     if(cooplevel & DDSCL_ALLOWREBOOT)
         WARN("(%p) Unhandled flag DDSCL_ALLOWREBOOT, harmless\n", This);
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index d9620d2..7981c84 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -575,7 +575,7 @@ static void test_coop_level_d3d_state(void)
     hr = IDirect3DViewport_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
     ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
     color = get_surface_color(rt, 320, 240);
-    todo_wine ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
+    ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
 
     hr = IDirect3DDevice_DeleteViewport(device, viewport);
     ok(SUCCEEDED(hr), "Failed to delete viewport, hr %#x.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index f6b5538..824ddb1 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -593,14 +593,14 @@ static void test_coop_level_d3d_state(void)
     ok(surface == rt, "Got unexpected surface %p.\n", surface);
     hr = IDirect3DDevice2_GetRenderState(device, D3DRENDERSTATE_ZENABLE, &value);
     ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
-    todo_wine ok(!!value, "Got unexpected z-enable state %#x.\n", value);
+    ok(!!value, "Got unexpected z-enable state %#x.\n", value);
     hr = IDirect3DDevice2_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
     ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
-    todo_wine ok(!!value, "Got unexpected alpha blend enable state %#x.\n", value);
+    ok(!!value, "Got unexpected alpha blend enable state %#x.\n", value);
     hr = IDirect3DViewport2_Clear(viewport, 1, &clear_rect, D3DCLEAR_TARGET);
     ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
     color = get_surface_color(rt, 320, 240);
-    todo_wine ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
+    ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
 
     hr = IDirect3DDevice2_DeleteViewport(device, viewport);
     ok(SUCCEEDED(hr), "Failed to delete viewport, hr %#x.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 9e263fe..68a478f 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -784,14 +784,14 @@ static void test_coop_level_d3d_state(void)
     ok(surface == rt, "Got unexpected surface %p.\n", surface);
     hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_ZENABLE, &value);
     ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
-    todo_wine ok(!!value, "Got unexpected z-enable state %#x.\n", value);
+    ok(!!value, "Got unexpected z-enable state %#x.\n", value);
     hr = IDirect3DDevice3_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
     ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
-    todo_wine ok(!!value, "Got unexpected alpha blend enable state %#x.\n", value);
+    ok(!!value, "Got unexpected alpha blend enable state %#x.\n", value);
     hr = IDirect3DViewport3_Clear2(viewport, 1, &clear_rect, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
     ok(SUCCEEDED(hr), "Failed to clear viewport, hr %#x.\n", hr);
     color = get_surface_color(rt, 320, 240);
-    todo_wine ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
+    ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
 
     hr = IDirect3DDevice3_DeleteViewport(device, viewport);
     ok(SUCCEEDED(hr), "Failed to delete viewport, hr %#x.\n", hr);
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 51fd618..d5477f0 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -754,14 +754,14 @@ static void test_coop_level_d3d_state(void)
     ok(surface == rt, "Got unexpected surface %p.\n", surface);
     hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_ZENABLE, &value);
     ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
-    todo_wine ok(!!value, "Got unexpected z-enable state %#x.\n", value);
+    ok(!!value, "Got unexpected z-enable state %#x.\n", value);
     hr = IDirect3DDevice7_GetRenderState(device, D3DRENDERSTATE_ALPHABLENDENABLE, &value);
     ok(SUCCEEDED(hr), "Failed to get render state, hr %#x.\n", hr);
-    todo_wine ok(!!value, "Got unexpected alpha blend enable state %#x.\n", value);
+    ok(!!value, "Got unexpected alpha blend enable state %#x.\n", value);
     hr = IDirect3DDevice7_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff00ff00, 0.0f, 0);
     ok(SUCCEEDED(hr), "Failed to clear render target, hr %#x.\n", hr);
     color = get_surface_color(rt, 320, 240);
-    todo_wine ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
+    ok(compare_color(color, 0x0000ff00, 1), "Got unexpected color 0x%08x.\n", color);
 
     IDirectDrawSurface7_Release(surface);
     IDirectDrawSurface7_Release(rt);




More information about the wine-cvs mailing list