Henri Verbeet : wined3d: Disable strict draw ordering by default.

Alexandre Julliard julliard at winehq.org
Wed Apr 14 11:24:56 CDT 2010


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

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Tue Apr 13 20:46:26 2010 +0200

wined3d: Disable strict draw ordering by default.

While some performance hit from the extra flushes was expected and would be
acceptable, the performance hit can be over 50% on some configurations, which
clearly isn't acceptable. This patch introduces a "StrictDrawOrdering"
registry key for applications affected by this, until we have a more
structural solution.

---

 dlls/wined3d/arb_program_shader.c |   13 +++++++------
 dlls/wined3d/device.c             |    8 +++++---
 dlls/wined3d/drawprim.c           |    2 +-
 dlls/wined3d/surface.c            |   18 +++++++++++++-----
 dlls/wined3d/wined3d_main.c       |    9 ++++++++-
 dlls/wined3d/wined3d_private.h    |    1 +
 6 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 44c4ab0..b939213 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -6899,8 +6899,8 @@ HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_
                            IWineD3DSurfaceImpl *dst_surface, const RECT *dst_rect_in, enum blit_operation blit_op,
                            DWORD Filter)
 {
+    IWineD3DSwapChainImpl *dst_swapchain;
     struct wined3d_context *context;
-    IWineD3DSwapChainImpl *dst_swapchain = NULL;
     RECT dst_rect = *dst_rect_in;
 
     /* Now load the surface */
@@ -6913,10 +6913,8 @@ HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_
      * while OpenGL coordinates are window relative.
      * Also beware of the origin difference(top left vs bottom left).
      * Also beware that the front buffer's surface size is screen width x screen height,
-     * whereas the real gl drawable size is the size of the window.
-     */
-    IWineD3DSurface_GetContainer((IWineD3DSurface *)dst_surface, &IID_IWineD3DSwapChain, (void **)&dst_swapchain);
-    if (dst_swapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)dst_swapchain);
+     * whereas the real gl drawable size is the size of the window. */
+    dst_swapchain = (dst_surface->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)dst_surface->container : NULL;
     if (dst_swapchain && (IWineD3DSurface *)dst_surface == dst_swapchain->frontBuffer)
     {
         RECT windowsize;
@@ -6942,7 +6940,10 @@ HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_
     /* Leave the opengl state valid for blitting */
     arbfp_blit_unset((IWineD3DDevice *)device);
 
-    wglFlush(); /* Flush to ensure ordering across contexts. */
+    if (wined3d_settings.strict_draw_ordering || (dst_swapchain
+            && ((IWineD3DSurface *)dst_surface == dst_swapchain->frontBuffer
+            || dst_swapchain->num_contexts > 1)))
+        wglFlush(); /* Flush to ensure ordering across contexts. */
 
     context_release(context);
 
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index f8f7df4..6cd2831 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -4496,7 +4496,9 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfac
 
     LEAVE_GL();
 
-    wglFlush(); /* Flush to ensure ordering across contexts. */
+    if (wined3d_settings.strict_draw_ordering || ((target->Flags & SFLAG_SWAPCHAIN)
+            && ((IWineD3DSwapChainImpl *)target->container)->frontBuffer == (IWineD3DSurface *)target))
+        wglFlush(); /* Flush to ensure ordering across contexts. */
 
     context_release(context);
 
@@ -5467,7 +5469,7 @@ static void color_fill_fbo(IWineD3DDevice *iface, IWineD3DSurface *surface,
 
     LEAVE_GL();
 
-    wglFlush(); /* Flush to ensure ordering across contexts. */
+    if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
 
     context_release(context);
 }
@@ -5811,7 +5813,7 @@ void stretch_rect_fbo(IWineD3DDevice *iface, IWineD3DSurface *src_surface, const
 
     LEAVE_GL();
 
-    wglFlush(); /* Flush to ensure ordering across contexts. */
+    if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
 
     context_release(context);
 
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 201aa54..dafdd93 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -694,7 +694,7 @@ void drawPrimitive(IWineD3DDevice *iface, UINT index_count, UINT StartIdx, UINT
         wined3d_event_query_issue(This->buffer_queries[i], This);
     }
 
-    wglFlush(); /* Flush to ensure ordering across contexts. */
+    if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
 
     context_release(context);
 
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 25967b3..1dbbeeb 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -3406,7 +3406,7 @@ static inline void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *This, IWine
 
     LEAVE_GL();
 
-    wglFlush(); /* Flush to ensure ordering across contexts. */
+    if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
 
     context_release(context);
 
@@ -3793,7 +3793,10 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *This, const
         /* Leave the opengl state valid for blitting */
         myDevice->blitter->unset_shader((IWineD3DDevice *) myDevice);
 
-        wglFlush(); /* Flush to ensure ordering across contexts. */
+        if (wined3d_settings.strict_draw_ordering || (dstSwapchain
+                && ((IWineD3DSurface *)This == dstSwapchain->frontBuffer
+                || dstSwapchain->num_contexts > 1)))
+            wglFlush(); /* Flush to ensure ordering across contexts. */
 
         context_release(context);
 
@@ -4266,7 +4269,7 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co
 
             LEAVE_GL();
 
-            wglFlush(); /* Flush to ensure ordering across contexts. */
+            if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
         }
         else
         {
@@ -4287,7 +4290,7 @@ void surface_load_ds_location(IWineD3DSurface *iface, struct wined3d_context *co
 
             LEAVE_GL();
 
-            wglFlush(); /* Flush to ensure ordering across contexts. */
+            if (wined3d_settings.strict_draw_ordering) wglFlush(); /* Flush to ensure ordering across contexts. */
         }
         else
         {
@@ -4357,6 +4360,7 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW
 static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT *rect_in)
 {
     IWineD3DDeviceImpl *device = This->resource.device;
+    IWineD3DSwapChainImpl *swapchain;
     struct wined3d_context *context;
     RECT src_rect, dst_rect;
 
@@ -4383,7 +4387,11 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT
 
     device->blitter->set_shader((IWineD3DDevice *) device, This);
 
-    wglFlush(); /* Flush to ensure ordering across contexts. */
+    swapchain = (This->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)This->container : NULL;
+    if (wined3d_settings.strict_draw_ordering || (swapchain
+            && ((IWineD3DSurface *)This == swapchain->frontBuffer
+            || swapchain->num_contexts > 1)))
+        wglFlush(); /* Flush to ensure ordering across contexts. */
 
     context_release(context);
 }
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index 2a96698..6330eba 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -72,7 +72,8 @@ wined3d_settings_t wined3d_settings =
     PCI_DEVICE_NONE,/* PCI Device ID */
     0,              /* The default of memory is set in FillGLCaps */
     NULL,           /* No wine logo by default */
-    FALSE           /* Disable multisampling for now due to Nvidia driver bugs which happens for some users */
+    FALSE,          /* Disable multisampling for now due to Nvidia driver bugs which happens for some users */
+    FALSE,          /* No strict draw ordering. */
 };
 
 IWineD3D * WINAPI WineDirect3DCreate(UINT version, IUnknown *parent)
@@ -319,6 +320,12 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
                 wined3d_settings.allow_multisampling = TRUE;
             }
         }
+        if (!get_config_key(hkey, appkey, "StrictDrawOrdering", buffer, size)
+                && !strcmp(buffer,"enabled"))
+        {
+            TRACE("Enforcing strict draw ordering.\n");
+            wined3d_settings.strict_draw_ordering = TRUE;
+        }
     }
     if (wined3d_settings.vs_mode == VS_HW)
         TRACE("Allow HW vertex shaders\n");
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 511a348..981f580 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -268,6 +268,7 @@ typedef struct wined3d_settings_s {
   unsigned int emulated_textureram;
   char *logo;
   int allow_multisampling;
+  BOOL strict_draw_ordering;
 } wined3d_settings_t;
 
 extern wined3d_settings_t wined3d_settings DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list