From: Matteo Bruni mbruni@codeweavers.com
Make sure we poll queries before we go to sleep, to e.g. avoid hangs in Rocket League.
With significant contributions by Zebediah Figura. --- dlls/wined3d/cs.c | 16 +++++++++++----- dlls/wined3d/wined3d_private.h | 2 ++ 2 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index edc2feeaab2..59bcd67cb2f 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -3322,6 +3322,12 @@ static void poll_queries(struct wined3d_cs *cs)
static void wined3d_cs_wait_event(struct wined3d_cs *cs) { + static const LARGE_INTEGER query_timeout = {.QuadPart = WINED3D_CS_WAIT_TIMEOUT * -10}; + const LARGE_INTEGER *timeout = NULL; + + if (!list_empty(&cs->query_poll_list)) + timeout = &query_timeout; + InterlockedExchange(&cs->waiting_for_event, TRUE);
/* The main thread might have enqueued a command and blocked on it after @@ -3337,9 +3343,9 @@ static void wined3d_cs_wait_event(struct wined3d_cs *cs) return;
if (pNtWaitForAlertByThreadId) - pNtWaitForAlertByThreadId(NULL, NULL); + pNtWaitForAlertByThreadId(NULL, timeout); else - WaitForSingleObject(cs->event, INFINITE); + NtWaitForSingleObject(cs->event, FALSE, timeout); }
static void wined3d_cs_command_lock(const struct wined3d_cs *cs) @@ -3451,10 +3457,10 @@ static DWORD WINAPI wined3d_cs_run(void *ctx) YieldProcessor(); if (++spin_count >= WINED3D_CS_SPIN_COUNT) { - if (list_empty(&cs->query_poll_list)) - wined3d_cs_wait_event(cs); + if (poll) + poll = WINED3D_CS_QUERY_POLL_INTERVAL - 1; else - Sleep(0); + wined3d_cs_wait_event(cs); } continue; } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ea78312fef3..e812e5846e0 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3564,6 +3564,8 @@ enum wined3d_cs_queue_id #define WINED3D_CS_QUEUE_SIZE 0x400000u #endif #define WINED3D_CS_SPIN_COUNT 2000u +/* How long to block waiting, in µs. */ +#define WINED3D_CS_WAIT_TIMEOUT 100 #define WINED3D_CS_QUEUE_MASK (WINED3D_CS_QUEUE_SIZE - 1)
C_ASSERT(!(WINED3D_CS_QUEUE_SIZE & (WINED3D_CS_QUEUE_SIZE - 1)));