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