summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-11-05 09:58:45 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2010-11-05 10:07:46 +0000
commita44a63d2ff6c01c3dc61de6f736dd441ddd25e52 (patch)
treea8dd4f9bd6ff69261d447dc0f5f6976ddcc1d4ff
parent52b32436b9e14a3e13818f80102150ff5bc3c002 (diff)
Wait for any pending rendering before switching modes.
A perennial problem we have is the accursed WAIT_FOR_EVENT hangs, which occur when we switch the framebuffer before the WAIT_FOR_EVENT completes and upsets the GPU. We have tried more subtle approaches to detected these and fix them up in the kernel, to no avail. What we need to do is to delay the framebuffer flip until the WAIT completes, which is quite tricky in the kernel without new ioctls and round-trips. Instead, apply the big hammer from userspace and synchronise all rendering before changing the framebuffer. I expect this not to cause noticeable latency on switching modes (far less than the actual modeswitch) and should stop these hangs once and for all. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=31401 (...) Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/intel_batchbuffer.c3
-rw-r--r--src/intel_display.c2
2 files changed, 5 insertions, 0 deletions
diff --git a/src/intel_batchbuffer.c b/src/intel_batchbuffer.c
index fec52819..9f8ca6f3 100644
--- a/src/intel_batchbuffer.c
+++ b/src/intel_batchbuffer.c
@@ -283,6 +283,9 @@ void intel_batch_wait_last(ScrnInfoPtr scrn)
{
intel_screen_private *intel = intel_get_screen_private(scrn);
+ if (intel->last_batch_bo == NULL)
+ return;
+
/* Map it CPU write, which guarantees it's done. This is a completely
* non performance path, so we don't need anything better.
*/
diff --git a/src/intel_display.c b/src/intel_display.c
index d32224ec..7eef80bb 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -359,6 +359,8 @@ intel_crtc_apply(xf86CrtcPtr crtc)
crtc->gamma_blue, crtc->gamma_size);
#endif
+ /* drain any pending waits on the current framebuffer */
+ intel_batch_wait_last(crtc->scrn);
x = crtc->x;
y = crtc->y;