Module: wine Branch: master Commit: d989d449c308e979ff46c23bb32be9720a6ce8b7 URL: https://source.winehq.org/git/wine.git/?a=commit;h=d989d449c308e979ff46c23bb...
Author: Matteo Bruni mbruni@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@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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