[Mesa-dev] [PATCH] i965: Move first_post_swapbuffers_batch from the context into the renderbuffer (v2)

Vivek Kasireddy vivek.kasireddy at intel.com
Fri Dec 19 18:17:25 PST 2014


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.

v2: Unref both the front and back renderbuffers inside intelDestroyContext
to address situations where applications switch rendering to back and
front buffers back and forth.

Signed-off-by: Vivek Kasireddy <vivek.kasireddy at intel.com>
---
 src/mesa/drivers/dri/i965/brw_context.c       |   36 +++++++++++++++++++------
 src/mesa/drivers/dri/i965/brw_context.h       |    1 -
 src/mesa/drivers/dri/i965/intel_batchbuffer.c |   15 ++++++++---
 src/mesa/drivers/dri/i965/intel_fbo.h         |    1 +
 4 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 860ee22d..04ecca3 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -870,6 +870,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)
@@ -910,8 +911,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);
 
@@ -1183,6 +1196,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) {
@@ -1202,8 +1216,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
@@ -1220,11 +1240,11 @@ 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 (brw->need_throttle && rb && 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;
+         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;
       brw->need_throttle = false;
    }
 }
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index a63c483..3a84cb4 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1028,7 +1028,6 @@ struct brw_context
    bool front_buffer_dirty;
 
    /** Framerate throttling: @{ */
-   drm_intel_bo *first_post_swapbuffers_batch;
    bool need_throttle;
    /** @} */
 
diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
index 2bd11d7..c3ac5c2 100644
--- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
@@ -291,13 +291,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..96fb53c 100644
--- a/src/mesa/drivers/dri/i965/intel_fbo.h
+++ b/src/mesa/drivers/dri/i965/intel_fbo.h
@@ -114,6 +114,7 @@ struct intel_renderbuffer
     * for the duration of a mapping.
     */
    bool singlesample_mt_is_tmp;
+   drm_intel_bo *first_post_swapbuffers_batch;
 };
 
 
-- 
1.7.10.1



More information about the mesa-dev mailing list