Module: wine Branch: master Commit: 7d247ca676a16d503dcee1c2a105ec641b1ecf7e URL: https://gitlab.winehq.org/wine/wine/-/commit/7d247ca676a16d503dcee1c2a105ec6...
Author: Matteo Bruni mbruni@codeweavers.com Date: Fri Mar 11 18:18:53 2022 -0600
wined3d: Do a blocking wait for CS commands even when there are active queries.
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..61ea75c2776 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_COMMAND_WAIT_WITH_QUERIES_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..494d26ebd02 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 wait for commands when there are active queries, in µs. */ +#define WINED3D_CS_COMMAND_WAIT_WITH_QUERIES_TIMEOUT 100 #define WINED3D_CS_QUEUE_MASK (WINED3D_CS_QUEUE_SIZE - 1)
C_ASSERT(!(WINED3D_CS_QUEUE_SIZE & (WINED3D_CS_QUEUE_SIZE - 1)));