Matteo Bruni : wined3d: Allow forcing commands serialization in the CS thread.

Alexandre Julliard julliard at winehq.org
Fri Dec 4 14:36:04 CST 2020


Module: wine
Branch: master
Commit: d989d449c308e979ff46c23bb32be9720a6ce8b7
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=d989d449c308e979ff46c23bb32be9720a6ce8b7

Author: Matteo Bruni <mbruni at codeweavers.com>
Date:   Thu Dec  3 17:58:54 2020 +0100

wined3d: Allow forcing commands serialization in the CS thread.

Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/cs.c              | 20 +++++++++++++++++++-
 dlls/wined3d/wined3d_main.c    | 14 +++++++++++++-
 dlls/wined3d/wined3d_private.h |  6 ++++++
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 48b73a71fe4..0b9c5f70043 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -21,6 +21,7 @@
 #include "wined3d_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_sync);
 WINE_DECLARE_DEBUG_CHANNEL(fps);
 
 #define WINED3D_INITIAL_CS_SIZE 4096
@@ -2866,6 +2867,18 @@ static void wined3d_cs_wait_event(struct wined3d_cs *cs)
     WaitForSingleObject(cs->event, INFINITE);
 }
 
+static void wined3d_cs_command_lock(const struct wined3d_cs *cs)
+{
+    if (cs->serialize_commands)
+        EnterCriticalSection(&wined3d_command_cs);
+}
+
+static void wined3d_cs_command_unlock(const struct wined3d_cs *cs)
+{
+    if (cs->serialize_commands)
+        LeaveCriticalSection(&wined3d_command_cs);
+}
+
 static DWORD WINAPI wined3d_cs_run(void *ctx)
 {
     struct wined3d_cs_packet *packet;
@@ -2889,7 +2902,9 @@ static DWORD WINAPI wined3d_cs_run(void *ctx)
     {
         if (++poll == WINED3D_CS_QUERY_POLL_INTERVAL)
         {
+            wined3d_cs_command_lock(cs);
             poll_queries(cs);
+            wined3d_cs_command_unlock(cs);
             poll = 0;
         }
 
@@ -2920,7 +2935,9 @@ static DWORD WINAPI wined3d_cs_run(void *ctx)
                 break;
             }
 
+            wined3d_cs_command_lock(cs);
             wined3d_cs_op_handlers[opcode](cs, packet->data);
+            wined3d_cs_command_unlock(cs);
             TRACE("%s executed.\n", debug_cs_op(opcode));
         }
 
@@ -2945,6 +2962,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
 
     cs->ops = &wined3d_cs_st_ops;
     cs->device = device;
+    cs->serialize_commands = TRACE_ON(d3d_sync) || wined3d_settings.cs_multithreaded & WINED3D_CSMT_SERIALIZE;
 
     state_init(&cs->state, d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT);
 
@@ -2952,7 +2970,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
     if (!(cs->data = heap_alloc(cs->data_size)))
         goto fail;
 
-    if (wined3d_settings.cs_multithreaded
+    if (wined3d_settings.cs_multithreaded & WINED3D_CSMT_ENABLE
             && !RtlIsCriticalSectionLockedByThread(NtCurrentTeb()->Peb->LoaderLock))
     {
         cs->ops = &wined3d_cs_mt_ops;
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index e1ed86e80ed..7118d4b4b71 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -96,11 +96,21 @@ static CRITICAL_SECTION_DEBUG wined3d_wndproc_cs_debug =
 };
 static CRITICAL_SECTION wined3d_wndproc_cs = {&wined3d_wndproc_cs_debug, -1, 0, 0, 0, 0};
 
+CRITICAL_SECTION wined3d_command_cs;
+static CRITICAL_SECTION_DEBUG wined3d_command_cs_debug =
+{
+    0, 0, &wined3d_command_cs,
+    {&wined3d_command_cs_debug.ProcessLocksList,
+    &wined3d_command_cs_debug.ProcessLocksList},
+    0, 0, {(DWORD_PTR)(__FILE__ ": wined3d_command_cs")}
+};
+CRITICAL_SECTION wined3d_command_cs = {&wined3d_command_cs_debug, -1, 0, 0, 0, 0};
+
 /* When updating default value here, make sure to update winecfg as well,
  * where appropriate. */
 struct wined3d_settings wined3d_settings =
 {
-    TRUE,           /* Multithreaded CS by default. */
+    WINED3D_CSMT_ENABLE,     /* Multithreaded CS by default. */
     MAKEDWORD_VERSION(4, 4), /* Default to OpenGL 4.4 */
     ORM_FBO,        /* Use FBOs to do offscreen rendering */
     PCI_VENDOR_NONE,/* PCI Vendor ID */
@@ -436,6 +446,8 @@ static BOOL wined3d_dll_destroy(HINSTANCE hInstDLL)
     heap_free(wined3d_settings.logo);
     UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL);
 
+    DeleteCriticalSection(&wined3d_command_cs);
+
     DeleteCriticalSection(&wined3d_wndproc_cs);
     DeleteCriticalSection(&wined3d_cs);
     return TRUE;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a82defbbe7f..cf1a0bb0668 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -452,6 +452,9 @@ enum wined3d_shader_backend
     WINED3D_SHADER_BACKEND_NONE,
 };
 
+#define WINED3D_CSMT_ENABLE    0x00000001
+#define WINED3D_CSMT_SERIALIZE 0x00000002
+
 /* NOTE: When adding fields to this structure, make sure to update the default
  * values in wined3d_main.c as well. */
 struct wined3d_settings
@@ -4675,6 +4678,7 @@ struct wined3d_cs
     HMODULE wined3d_module;
     HANDLE thread;
     DWORD thread_id;
+    BOOL serialize_commands;
 
     struct wined3d_cs_queue queue[WINED3D_CS_QUEUE_COUNT];
     size_t data_size, start, end;
@@ -6365,4 +6369,6 @@ static inline void wined3d_context_gl_reference_bo(struct wined3d_context_gl *co
 /* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
 #define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
 
+extern CRITICAL_SECTION wined3d_command_cs;
+
 #endif




More information about the wine-cvs mailing list