Mesa (swapbuffers-offload): r600g: offload flushing when the state tracker allows it

Marek Olšák mareko at kemper.freedesktop.org
Tue Nov 20 17:55:27 UTC 2012


Module: Mesa
Branch: swapbuffers-offload
Commit: 1b384733add0a90c295ad2d8775a6ed65e9300b3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1b384733add0a90c295ad2d8775a6ed65e9300b3

Author: Marek Olšák <maraeo at gmail.com>
Date:   Tue Nov 13 23:39:20 2012 +0100

r600g: offload flushing when the state tracker allows it

---

 src/gallium/drivers/r600/evergreen_compute.c  |    2 +-
 src/gallium/drivers/r600/r600.h               |    3 ++-
 src/gallium/drivers/r600/r600_hw_context.c    |    7 ++++---
 src/gallium/drivers/r600/r600_pipe.c          |   24 +++++++++++++++---------
 src/gallium/drivers/r600/r600_pipe.h          |    2 +-
 src/gallium/drivers/r600/r600_texture.c       |    2 +-
 src/gallium/winsys/radeon/drm/radeon_drm_cs.c |   18 +++++++++++++++++-
 src/gallium/winsys/radeon/drm/radeon_drm_cs.h |    3 +++
 src/gallium/winsys/radeon/drm/radeon_winsys.h |    9 +++++++--
 9 files changed, 51 insertions(+), 19 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
index 44831a7..999c81b 100644
--- a/src/gallium/drivers/r600/evergreen_compute.c
+++ b/src/gallium/drivers/r600/evergreen_compute.c
@@ -424,7 +424,7 @@ static void compute_emit_cs(struct r600_context *ctx, const uint *block_layout,
 		flush_flags |= RADEON_FLUSH_KEEP_TILING_FLAGS;
 	}
 
-	ctx->ws->cs_flush(ctx->cs, flush_flags);
+	ctx->ws->cs_flush(ctx->cs, flush_flags, NULL, NULL);
 
 	ctx->pm4_dirty_cdwords = 0;
 	ctx->flags = 0;
diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index 7d43416..a8336ce 100644
--- a/src/gallium/drivers/r600/r600.h
+++ b/src/gallium/drivers/r600/r600.h
@@ -200,7 +200,8 @@ int r600_context_init(struct r600_context *ctx);
 void r600_context_fini(struct r600_context *ctx);
 void r600_context_pipe_state_emit(struct r600_context *ctx, struct r600_pipe_state *state, unsigned pkt_flags);
 void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_state *state);
-void r600_context_flush(struct r600_context *ctx, unsigned flags);
+void r600_context_flush(struct r600_context *ctx, unsigned flags,
+			void (*finish)(void *user_ptr), void *finish_ptr);
 void r600_begin_new_cs(struct r600_context *ctx);
 
 void r600_context_emit_fence(struct r600_context *ctx, struct r600_resource *fence,
diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
index 97c7d6d..7329736 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -403,7 +403,7 @@ void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw,
 
 	/* Flush if there's not enough space. */
 	if (num_dw > RADEON_MAX_CMDBUF_DWORDS) {
-		r600_flush(&ctx->context, NULL, RADEON_FLUSH_ASYNC);
+		r600_flush(&ctx->context, NULL, RADEON_FLUSH_ASYNC, NULL, NULL);
 	}
 }
 
@@ -732,7 +732,8 @@ void r600_flush_emit(struct r600_context *rctx)
 	rctx->flags = 0;
 }
 
-void r600_context_flush(struct r600_context *ctx, unsigned flags)
+void r600_context_flush(struct r600_context *ctx, unsigned flags,
+			void (*finish)(void *user_ptr), void *finish_ptr)
 {
 	struct radeon_winsys_cs *cs = ctx->cs;
 
@@ -782,7 +783,7 @@ void r600_context_flush(struct r600_context *ctx, unsigned flags)
 	}
 
 	/* Flush the CS. */
-	ctx->ws->cs_flush(ctx->cs, flags);
+	ctx->ws->cs_flush(ctx->cs, flags, finish, finish_ptr);
 
 	r600_begin_new_cs(ctx);
 }
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 39929f7..2ca20d5 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -116,7 +116,7 @@ out:
 
 
 void r600_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
-		unsigned flags)
+		unsigned flags, void (*finish)(void *user_ptr), void *finish_ptr)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
 	struct r600_fence **rfence = (struct r600_fence**)fence;
@@ -133,7 +133,7 @@ void r600_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
 		ctx->render_condition(ctx, NULL, 0);
 	}
 
-	r600_context_flush(rctx, flags);
+	r600_context_flush(rctx, flags, finish, finish_ptr);
 
 	/* Re-enable render condition. */
 	if (render_cond) {
@@ -143,19 +143,24 @@ void r600_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
 
 static void r600_flush_from_st(struct pipe_context *ctx,
 			       struct pipe_fence_handle **fence,
-                               enum pipe_flush_flags flags,
-                               void (*finish)(void *user_ptr), void *finish_ptr)
+			       enum pipe_flush_flags flags,
+			       void (*finish)(void *user_ptr), void *finish_ptr)
 {
-	r600_flush(ctx, fence, 0);
+	r600_flush(ctx, fence,
+		   flags & PIPE_FLUSH_ASYNC ? RADEON_FLUSH_ASYNC : 0,
+		   finish, finish_ptr);
+}
+
+static void r600_sync_with_flush(struct pipe_context *ctx)
+{
+   struct r600_context *rctx = (struct r600_context *)ctx;
 
-        if (finish) {
-           finish(finish_ptr);
-        }
+   rctx->ws->cs_sync_with_flush(rctx->cs);
 }
 
 static void r600_flush_from_winsys(void *ctx, unsigned flags)
 {
-	r600_flush((struct pipe_context*)ctx, NULL, flags);
+	r600_flush((struct pipe_context*)ctx, NULL, flags, NULL, NULL);
 }
 
 static void r600_destroy_context(struct pipe_context *context)
@@ -218,6 +223,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
 	rctx->context.priv = priv;
 	rctx->context.destroy = r600_destroy_context;
 	rctx->context.flush = r600_flush_from_st;
+        rctx->context.sync_with_flush = r600_sync_with_flush;
 
 	/* Easy accessing of screen/winsys. */
 	rctx->screen = rscreen;
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 33ccefa..3be4082 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -596,7 +596,7 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
 
 /* r600_pipe.c */
 void r600_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
-		unsigned flags);
+		unsigned flags, void (*finish)(void *user_ptr), void *finish_ptr);
 
 /* r600_query.c */
 void r600_init_query_functions(struct r600_context *rctx);
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 0054c5b..6312c7a 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -764,7 +764,7 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
 		if (usage & PIPE_TRANSFER_READ) {
 			r600_copy_to_staging_texture(ctx, trans);
 			/* Always referenced in the blit. */
-			r600_flush(ctx, NULL, 0);
+			r600_flush(ctx, NULL, 0, NULL, NULL);
 		}
 	} else {
 		trans->transfer.stride = rtex->surface.level[level].pitch_bytes;
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
index c6498ef..d49d463 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
@@ -406,6 +406,10 @@ static void radeon_drm_cs_emit_ioctl_oneshot(struct radeon_cs_context *csc)
         p_atomic_dec(&csc->relocs_bo[i]->num_active_ioctls);
 
     radeon_cs_context_cleanup(csc);
+
+    if (csc->finish) {
+        csc->finish(csc->finish_ptr);
+    }
 }
 
 static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param)
@@ -432,7 +436,13 @@ void radeon_drm_cs_sync_flush(struct radeon_drm_cs *cs)
     }
 }
 
-static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags)
+static void radeon_drm_cs_sync_flush_wrapper(struct radeon_winsys_cs *rcs)
+{
+    radeon_drm_cs_sync_flush(radeon_drm_cs(rcs));
+}
+
+static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags,
+				void (*finish)(void *user_ptr), void *finish_ptr)
 {
     struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
     struct radeon_cs_context *tmp;
@@ -474,6 +484,8 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags)
             cs->cst->flags[1] = RADEON_CS_RING_COMPUTE;
             cs->cst->cs.num_chunks = 3;
         }
+	cs->cst->finish = finish;
+	cs->cst->finish_ptr = finish_ptr;
 
         if (cs->thread &&
             (flags & RADEON_FLUSH_ASYNC)) {
@@ -484,6 +496,9 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags)
         }
     } else {
         radeon_cs_context_cleanup(cs->cst);
+	if (finish) {
+            finish(finish_ptr);
+	}
     }
 
     /* Prepare a new CS. */
@@ -551,6 +566,7 @@ void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws)
     ws->base.cs_validate = radeon_drm_cs_validate;
     ws->base.cs_write_reloc = radeon_drm_cs_write_reloc;
     ws->base.cs_flush = radeon_drm_cs_flush;
+    ws->base.cs_sync_with_flush = radeon_drm_cs_sync_flush_wrapper;
     ws->base.cs_set_flush_callback = radeon_drm_cs_set_flush;
     ws->base.cs_is_buffer_referenced = radeon_bo_is_referenced;
 }
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
index 6336d3a..51c940a 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h
@@ -52,6 +52,9 @@ struct radeon_cs_context {
 
     unsigned                    used_vram;
     unsigned                    used_gart;
+
+    void (*finish)(void *user_ptr);
+    void *finish_ptr;
 };
 
 struct radeon_drm_cs {
diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index 8e4693b..d9b6504 100644
--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -326,9 +326,14 @@ struct radeon_winsys {
      * Flush a command stream.
      *
      * \param cs        A command stream to flush.
-     * \param flags,    RADEON_FLUSH_ASYNC or 0.
+     * \param flags     RADEON_FLUSH_ASYNC or 0.
+     * \param finish    the function to call after flushing is done
+     * \param finish_ptr the parameter to the finish function
      */
-    void (*cs_flush)(struct radeon_winsys_cs *cs, unsigned flags);
+    void (*cs_flush)(struct radeon_winsys_cs *cs, unsigned flags,
+		     void (*finish)(void *user_ptr), void *finish_ptr);
+
+    void (*cs_sync_with_flush)(struct radeon_winsys_cs *cs);
 
     /**
      * Set a flush callback which is called from winsys when flush is




More information about the mesa-commit mailing list