summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2009-08-04 09:22:15 -0600
committerBrian Paul <brianp@vmware.com>2009-08-04 09:22:15 -0600
commitf5f8be8bb2dae91e0eb748b6f062eeb345605063 (patch)
tree58c0b03d564d2c85a6b0cfbd5503dfea99237bcb /src
parent2bec909c69c127b4a29eedfcafed9f5f2e23c51e (diff)
intel: Wait on the last swapbuffers to complete before queuing a new one.
This fixes jerkiness in doom3 and other apps since the kernel change to throttle less absurdly, which led to a thundering herd of frames. Because this is a rather minimal fix, there is at least one downside: If the whole scene completes in one batchbuffer, we'll end up stalling the GPU. Thanks to Michel Dänzer for suggesting using glFlush to signal frame end instead of going to all the effort of adding a new DRI2 extension. (cherry picked from master, commit 0828579a658af01a64b5e699175dc9bbbedcd685)
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.c5
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c22
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h1
3 files changed, 28 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index 29dc05c518..82a92a9f45 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -197,6 +197,11 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
GLuint used = batch->ptr - batch->map;
GLboolean was_locked = intel->locked;
+ if (intel->first_post_swapbuffers_batch == NULL) {
+ intel->first_post_swapbuffers_batch = intel->batch->buf;
+ drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
+ }
+
if (used == 0) {
batch->cliprect_mode = IGNORE_CLIPRECTS;
return;
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 9db5b54643..a40951abe3 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -521,7 +521,27 @@ intelFlush(GLcontext * ctx)
static void
intel_glFlush(GLcontext *ctx)
{
+ struct intel_context *intel = intel_context(ctx);
+
intel_flush(ctx, GL_TRUE);
+
+ /* We're using glFlush as an indicator that a frame is done, which is
+ * what DRI2 does before calling SwapBuffers (and means we should catch
+ * people doing front-buffer rendering, as well)..
+ *
+ * Wait for the swapbuffers before the one we just emitted, so we don't
+ * get too many swaps outstanding for apps that are GPU-heavy but not
+ * CPU-heavy.
+ *
+ * Unfortunately, we don't have a handle to the batch containing the swap,
+ * and getting our hands on that doesn't seem worth it, so we just us the
+ * first batch we emitted after the last swap.
+ */
+ if (intel->first_post_swapbuffers_batch != NULL) {
+ drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
+ drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
+ intel->first_post_swapbuffers_batch = NULL;
+ }
}
void
@@ -787,6 +807,8 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
intel->prim.vb = NULL;
dri_bo_unreference(intel->prim.vb_bo);
intel->prim.vb_bo = NULL;
+ dri_bo_unreference(intel->first_post_swapbuffers_batch);
+ intel->first_post_swapbuffers_batch = NULL;
if (release_texture_heaps) {
/* This share group is about to go away, free our private
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index b5cf7e6648..b3db561fd5 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -191,6 +191,7 @@ struct intel_context
GLboolean ttm;
struct intel_batchbuffer *batch;
+ drm_intel_bo *first_post_swapbuffers_batch;
GLboolean no_batch_wrap;
unsigned batch_id;