Henri Verbeet : d3d9: Avoid resetting device state for d3d9ex resets.

Alexandre Julliard julliard at winehq.org
Tue Nov 20 13:52:22 CST 2012


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

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Mon Nov 19 22:04:12 2012 +0100

d3d9: Avoid resetting device state for d3d9ex resets.

---

 dlls/d3d8/device.c        |    3 +-
 dlls/d3d9/device.c        |   11 ++----
 dlls/ddraw/ddraw.c        |    2 +-
 dlls/wined3d/device.c     |   70 ++++++++++++++++++++++++++++++---------------
 dlls/wined3d/wined3d.spec |    2 +-
 include/wine/wined3d.h    |    2 +-
 6 files changed, 56 insertions(+), 34 deletions(-)

diff --git a/dlls/d3d8/device.c b/dlls/d3d8/device.c
index c73f065..b4bd3f9 100644
--- a/dlls/d3d8/device.c
+++ b/dlls/d3d8/device.c
@@ -597,7 +597,8 @@ static HRESULT WINAPI d3d8_device_Reset(IDirect3DDevice8 *iface,
 
     wined3d_mutex_lock();
     wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters);
-    if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc, NULL, reset_enum_callback)))
+    if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc,
+            NULL, reset_enum_callback, TRUE)))
     {
         wined3d_device_set_render_state(device->wined3d_device, WINED3D_RS_POINTSIZE_MIN, 0);
         device->lost = FALSE;
diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
index ce5bf1a..0c70f96 100644
--- a/dlls/d3d9/device.c
+++ b/dlls/d3d9/device.c
@@ -582,8 +582,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_Reset(IDirect3DDevice9Ex *if
 
     wined3d_mutex_lock();
     wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters);
-    hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc, NULL, reset_enum_callback);
-    if (FAILED(hr))
+    hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc,
+            NULL, reset_enum_callback, !device->d3d_parent->extended);
+    if (FAILED(hr) && !device->d3d_parent->extended)
         device->not_reset = TRUE;
     else
         device->not_reset = FALSE;
@@ -2907,11 +2908,7 @@ static HRESULT WINAPI d3d9_device_ResetEx(IDirect3DDevice9Ex *iface,
     wined3d_mutex_lock();
     wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters);
     hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc,
-            mode ? &wined3d_mode : NULL, reset_enum_callback);
-    if (FAILED(hr))
-        device->not_reset = TRUE;
-    else
-        device->not_reset = FALSE;
+            mode ? &wined3d_mode : NULL, reset_enum_callback, FALSE);
     wined3d_mutex_unlock();
 
     return hr;
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 376db17..14fc73d 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -2867,7 +2867,7 @@ static HRESULT CreateSurface(struct ddraw *ddraw, DDSURFACEDESC2 *DDSD,
         swapchain_desc.backbuffer_format = mode.format_id;
 
         hr = wined3d_device_reset(ddraw->wined3d_device,
-                &swapchain_desc, NULL, ddraw_reset_enum_callback);
+                &swapchain_desc, NULL, ddraw_reset_enum_callback, TRUE);
         if (FAILED(hr))
         {
             ERR("Failed to reset device.\n");
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 16287ad..ea11f70 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4974,15 +4974,15 @@ static HRESULT create_primary_opengl_context(struct wined3d_device *device, stru
 /* Do not call while under the GL lock. */
 HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode,
-        wined3d_device_reset_cb callback)
+        wined3d_device_reset_cb callback, BOOL reset_state)
 {
     struct wined3d_resource *resource, *cursor;
     struct wined3d_swapchain *swapchain;
     struct wined3d_display_mode m;
     BOOL DisplayModeChanged = FALSE;
     BOOL update_desc = FALSE;
+    HRESULT hr = WINED3D_OK;
     unsigned int i;
-    HRESULT hr;
 
     TRACE("device %p, swapchain_desc %p, mode %p, callback %p.\n", device, swapchain_desc, mode, callback);
 
@@ -4992,7 +4992,9 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         return WINED3DERR_INVALIDCALL;
     }
 
-    stateblock_unbind_resources(device->stateBlock);
+    if (reset_state)
+        stateblock_unbind_resources(device->stateBlock);
+
     if (device->fb.render_targets)
     {
         if (swapchain->back_buffers && swapchain->back_buffers[0])
@@ -5012,11 +5014,14 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         device->onscreen_depth_stencil = NULL;
     }
 
-    LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
+    if (reset_state)
     {
-        TRACE("Enumerating resource %p.\n", resource);
-        if (FAILED(hr = callback(resource)))
-            return hr;
+        LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
+        {
+            TRACE("Enumerating resource %p.\n", resource);
+            if (FAILED(hr = callback(resource)))
+                return hr;
+        }
     }
 
     /* Is it necessary to recreate the gl context? Actually every setting can be changed
@@ -5067,8 +5072,6 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
 
     if (swapchain_desc->enable_auto_depth_stencil && !device->auto_depth_stencil)
     {
-        HRESULT hr;
-
         TRACE("Creating the depth stencil buffer\n");
 
         if (FAILED(hr = device->device_parent->ops->create_swapchain_surface(device->device_parent,
@@ -5222,28 +5225,49 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
         device->exStyle = exStyle;
     }
 
-    TRACE("Resetting stateblock.\n");
-    wined3d_stateblock_decref(device->updateStateBlock);
-    wined3d_stateblock_decref(device->stateBlock);
+    if (reset_state)
+    {
+        TRACE("Resetting stateblock.\n");
+        wined3d_stateblock_decref(device->updateStateBlock);
+        wined3d_stateblock_decref(device->stateBlock);
 
-    if (device->d3d_initialized)
-        delete_opengl_contexts(device, swapchain);
+        if (device->d3d_initialized)
+            delete_opengl_contexts(device, swapchain);
 
-    /* Note: No parent needed for initial internal stateblock */
-    hr = wined3d_stateblock_create(device, WINED3D_SBT_INIT, &device->stateBlock);
-    if (FAILED(hr))
-        ERR("Resetting the stateblock failed with error %#x.\n", hr);
+        /* Note: No parent needed for initial internal stateblock */
+        hr = wined3d_stateblock_create(device, WINED3D_SBT_INIT, &device->stateBlock);
+        if (FAILED(hr))
+            ERR("Resetting the stateblock failed with error %#x.\n", hr);
+        else
+            TRACE("Created stateblock %p.\n", device->stateBlock);
+        device->updateStateBlock = device->stateBlock;
+        wined3d_stateblock_incref(device->updateStateBlock);
+
+        stateblock_init_default_state(device->stateBlock);
+    }
     else
-        TRACE("Created stateblock %p.\n", device->stateBlock);
-    device->updateStateBlock = device->stateBlock;
-    wined3d_stateblock_incref(device->updateStateBlock);
+    {
+        struct wined3d_surface *rt = device->fb.render_targets[0];
+        struct wined3d_state *state = &device->stateBlock->state;
 
-    stateblock_init_default_state(device->stateBlock);
+        /* Note the min_z / max_z is not reset. */
+        state->viewport.x = 0;
+        state->viewport.y = 0;
+        state->viewport.width = rt->resource.width;
+        state->viewport.height = rt->resource.height;
+        device_invalidate_state(device, STATE_VIEWPORT);
+
+        state->scissor_rect.top = 0;
+        state->scissor_rect.left = 0;
+        state->scissor_rect.right = rt->resource.width;
+        state->scissor_rect.bottom = rt->resource.height;
+        device_invalidate_state(device, STATE_SCISSORRECT);
+    }
 
     swapchain_update_render_to_fbo(swapchain);
     swapchain_update_draw_bindings(swapchain);
 
-    if (device->d3d_initialized)
+    if (reset_state && device->d3d_initialized)
         hr = create_primary_opengl_context(device, swapchain);
 
     /* All done. There is no need to reload resources or shaders, this will happen automatically on the
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index f8364e1..e97c102 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -102,7 +102,7 @@
 @ cdecl wined3d_device_present(ptr ptr ptr ptr ptr long)
 @ cdecl wined3d_device_process_vertices(ptr long long long ptr ptr long long)
 @ cdecl wined3d_device_release_focus_window(ptr)
-@ cdecl wined3d_device_reset(ptr ptr ptr ptr)
+@ cdecl wined3d_device_reset(ptr ptr ptr ptr long)
 @ cdecl wined3d_device_restore_fullscreen_window(ptr ptr)
 @ cdecl wined3d_device_set_base_vertex_index(ptr long)
 @ cdecl wined3d_device_set_clip_plane(ptr long ptr)
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 7169a25..329698a 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2184,7 +2184,7 @@ HRESULT __cdecl wined3d_device_process_vertices(struct wined3d_device *device,
 void __cdecl wined3d_device_release_focus_window(struct wined3d_device *device);
 HRESULT __cdecl wined3d_device_reset(struct wined3d_device *device,
         const struct wined3d_swapchain_desc *swapchain_desc, const struct wined3d_display_mode *mode,
-        wined3d_device_reset_cb callback);
+        wined3d_device_reset_cb callback, BOOL reset_state);
 void __cdecl wined3d_device_restore_fullscreen_window(struct wined3d_device *device, HWND window);
 void __cdecl wined3d_device_set_base_vertex_index(struct wined3d_device *device, INT base_index);
 HRESULT __cdecl wined3d_device_set_clip_plane(struct wined3d_device *device,




More information about the wine-cvs mailing list