[PATCH 2/2] wined3d: do not call queue_is_empty in wined3d_cs_mt_finish.
Stefan Dösinger
stefan at codeweavers.com
Fri Aug 4 03:21:52 CDT 2017
Queue_is_empty assumes it is called from the CS thread because it only
reads queue->head in a cache-safe manner. This breaks on ARM, which has
less strict cache coherency rules than x86.
Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>
---
Making finish a special case instead of reading both head and tail
through volatile * in queue_is_empty is slightly but measurably faster
on ARM (260 vs 240 fps in a CPU limited test case based on the dx9 sdk).
I did not measure a performance difference on x86.
To reproduce the bug run d3d9 make test on ARM.
---
dlls/wined3d/cs.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 2c6b572..a1c19ee 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -2346,6 +2346,7 @@ static const struct wined3d_cs_ops wined3d_cs_st_ops =
wined3d_cs_st_push_constants,
};
+/* This function assumes that it is called from the command stream thread. */
static BOOL wined3d_cs_queue_is_empty(const struct wined3d_cs_queue *queue)
{
return *(volatile LONG *)&queue->head == queue->tail;
@@ -2446,7 +2447,7 @@ static void wined3d_cs_mt_finish(struct wined3d_cs *cs, enum wined3d_cs_queue_id
if (cs->thread_id == GetCurrentThreadId())
return wined3d_cs_st_finish(cs, queue_id);
- while (!wined3d_cs_queue_is_empty(&cs->queue[queue_id]))
+ while (cs->queue[queue_id].head != *(volatile LONG *)&cs->queue[queue_id].tail)
wined3d_pause();
}
--
2.10.2
More information about the wine-patches
mailing list