[Mesa-dev] [PATCH] i965: Move need_throttle and first_post_swapbuffers_batch into the renderbuffer

Vivek Kasireddy vivek.kasireddy at intel.com
Thu Mar 5 18:51:22 PST 2015


If there are multiple EGL surfaces associated with one EGL context, for
any given surface, we unnecessarily have to wait for swapbuffers to
complete on other EGL surfaces because we throttle to the context.
By moving first_post_swapbuffers_batch from the brw context into
intel_renderuffer, we would no longer be throttled by other surface's
swapbuffers thereby leading to better performance.

Signed-off-by: Vivek Kasireddy <vivek.kasireddy at intel.com>
---
 src/mesa/drivers/dri/i965/brw_context.c       |   48 +++++++++++++++++++------
 src/mesa/drivers/dri/i965/brw_context.h       |    5 ---
 src/mesa/drivers/dri/i965/intel_batchbuffer.c |   15 ++++++--
 src/mesa/drivers/dri/i965/intel_fbo.h         |    5 +++
 src/mesa/drivers/dri/i965/intel_screen.c      |   11 +++++-
 5 files changed, 65 insertions(+), 19 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 786e6f5..1d08c65 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -229,11 +229,19 @@ static void
 intel_glFlush(struct gl_context *ctx)
 {
    struct brw_context *brw = brw_context(ctx);
+   struct intel_renderbuffer *rb = NULL;
+
+   if (ctx->DrawBuffer) {
+      if (brw_is_front_buffer_drawing(ctx->DrawBuffer))
+         rb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_FRONT_LEFT);
+      else
+         rb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_BACK_LEFT);
+   }
 
    intel_batchbuffer_flush(brw);
    intel_flush_front(ctx);
    if (brw_is_front_buffer_drawing(ctx->DrawBuffer))
-      brw->need_throttle = true;
+      rb->need_throttle = true;
 }
 
 static void
@@ -882,6 +890,7 @@ intelDestroyContext(__DRIcontext * driContextPriv)
    struct brw_context *brw =
       (struct brw_context *) driContextPriv->driverPrivate;
    struct gl_context *ctx = &brw->ctx;
+   struct intel_renderbuffer *front_rb = NULL, *back_rb = NULL;
 
    assert(brw); /* should never be null */
    if (!brw)
@@ -922,8 +931,20 @@ intelDestroyContext(__DRIcontext * driContextPriv)
 
    intel_batchbuffer_free(brw);
 
-   drm_intel_bo_unreference(brw->first_post_swapbuffers_batch);
-   brw->first_post_swapbuffers_batch = NULL;
+   if (ctx->DrawBuffer) {
+      front_rb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_FRONT_LEFT);
+      back_rb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_BACK_LEFT);
+   }
+
+   if (front_rb) {
+      drm_intel_bo_unreference(front_rb->first_post_swapbuffers_batch);
+      front_rb->first_post_swapbuffers_batch = NULL;
+   }
+
+   if (back_rb) {
+      drm_intel_bo_unreference(back_rb->first_post_swapbuffers_batch);
+      back_rb->first_post_swapbuffers_batch = NULL;
+   }
 
    driDestroyOptionCache(&brw->optionCache);
 
@@ -1195,6 +1216,7 @@ intel_prepare_render(struct brw_context *brw)
    struct gl_context *ctx = &brw->ctx;
    __DRIcontext *driContext = brw->driContext;
    __DRIdrawable *drawable;
+   struct intel_renderbuffer *rb = NULL;
 
    drawable = driContext->driDrawablePriv;
    if (drawable && drawable->dri2.stamp != driContext->dri2.draw_stamp) {
@@ -1214,8 +1236,14 @@ intel_prepare_render(struct brw_context *brw)
     * that will happen next will probably dirty the front buffer.  So
     * mark it as dirty here.
     */
-   if (brw_is_front_buffer_drawing(ctx->DrawBuffer))
-      brw->front_buffer_dirty = true;
+   if (ctx->DrawBuffer) {
+      if (brw_is_front_buffer_drawing(ctx->DrawBuffer)) {
+         brw->front_buffer_dirty = true;
+         rb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_FRONT_LEFT);
+      } else {
+         rb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_BACK_LEFT);
+      }
+   }
 
    /* 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
@@ -1232,12 +1260,12 @@ intel_prepare_render(struct brw_context *brw)
     * 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 (brw->need_throttle && brw->first_post_swapbuffers_batch) {
+   if (rb && rb->need_throttle && rb->first_post_swapbuffers_batch) {
       if (!brw->disable_throttling)
-         drm_intel_bo_wait_rendering(brw->first_post_swapbuffers_batch);
-      drm_intel_bo_unreference(brw->first_post_swapbuffers_batch);
-      brw->first_post_swapbuffers_batch = NULL;
-      brw->need_throttle = false;
+         drm_intel_bo_wait_rendering(rb->first_post_swapbuffers_batch);
+      drm_intel_bo_unreference(rb->first_post_swapbuffers_batch);
+      rb->first_post_swapbuffers_batch = NULL;
+      rb->need_throttle = false;
    }
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 682fbe9..da89f08 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1029,11 +1029,6 @@ struct brw_context
     */
    bool front_buffer_dirty;
 
-   /** Framerate throttling: @{ */
-   drm_intel_bo *first_post_swapbuffers_batch;
-   bool need_throttle;
-   /** @} */
-
    GLuint stats_wm;
 
    /**
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index 5ac4d18..6070f67 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -285,13 +285,22 @@ _intel_batchbuffer_flush(struct brw_context *brw,
 			 const char *file, int line)
 {
    int ret;
+   struct gl_context *ctx = &brw->ctx;
+   struct intel_renderbuffer *rb = NULL;
 
    if (brw->batch.used == 0)
       return 0;
 
-   if (brw->first_post_swapbuffers_batch == NULL) {
-      brw->first_post_swapbuffers_batch = brw->batch.bo;
-      drm_intel_bo_reference(brw->first_post_swapbuffers_batch);
+   if (ctx->DrawBuffer) {
+      if (brw_is_front_buffer_drawing(ctx->DrawBuffer))
+         rb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_FRONT_LEFT);
+      else
+         rb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_BACK_LEFT);
+   }
+
+   if (rb && rb->first_post_swapbuffers_batch == NULL) {
+      rb->first_post_swapbuffers_batch = brw->batch.bo;
+      drm_intel_bo_reference(rb->first_post_swapbuffers_batch);
    }
 
    if (unlikely(INTEL_DEBUG & DEBUG_BATCH)) {
diff --git a/src/mesa/drivers/dri/i965/intel_fbo.h b/src/mesa/drivers/dri/i965/intel_fbo.h
index c7cc570..8a45045 100644
--- a/src/mesa/drivers/dri/i965/intel_fbo.h
+++ b/src/mesa/drivers/dri/i965/intel_fbo.h
@@ -114,6 +114,11 @@ struct intel_renderbuffer
     * for the duration of a mapping.
     */
    bool singlesample_mt_is_tmp;
+   drm_intel_bo *first_post_swapbuffers_batch;
+
+   /** Framerate throttling: @{ */
+   bool need_throttle;
+   /** @} */
 };
 
 
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index cea7ddf..3872ec6 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -168,6 +168,14 @@ intel_dri2_flush_with_flags(__DRIcontext *cPriv,
       return;
 
    struct gl_context *ctx = &brw->ctx;
+   struct intel_renderbuffer *rb = NULL;
+
+   if (ctx->DrawBuffer) {
+      if (brw_is_front_buffer_drawing(ctx->DrawBuffer))
+         rb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_FRONT_LEFT);
+      else
+         rb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_BACK_LEFT);
+   }
 
    FLUSH_VERTICES(ctx, 0);
 
@@ -176,7 +184,8 @@ intel_dri2_flush_with_flags(__DRIcontext *cPriv,
 
    if (reason == __DRI2_THROTTLE_SWAPBUFFER ||
        reason == __DRI2_THROTTLE_FLUSHFRONT) {
-      brw->need_throttle = true;
+      if (rb)
+         rb->need_throttle = true;
    }
 
    intel_batchbuffer_flush(brw);
-- 
1.7.10.1



More information about the mesa-dev mailing list