summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/ilo/ilo_cp.c
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2013-05-20 12:13:34 +0800
committerChia-I Wu <[email protected]>2013-05-21 11:47:20 +0800
commit0d42a9e9414a1c015e1ceced4d773a455e5b39d1 (patch)
tree14557a6a80f12047f813d2e7d610d9e70733a7bc /src/gallium/drivers/ilo/ilo_cp.c
parenta04d8574c61f286fd9ec51f667648f73e332462f (diff)
ilo: replace cp hooks by cp owner and flush callback
The problem with cp hooks is that when we switch from 3D ring to 2D ring, and when there are active queries, we will emit 3D commands to 2D ring because the new-batch hook is called. This commit introduces the idea of cp owner. When the cp is flushed, or when another owner takes place, the current owner is notified, giving it a chance to emit whatever commands there need to be. With this mechanism, we can resume queries when the 3D pipeline owns the cp, and pause queries when it loses the cp. Ring switch will just work. As we still need to know when the cp bo is reallocated, a flush callback is added.
Diffstat (limited to 'src/gallium/drivers/ilo/ilo_cp.c')
-rw-r--r--src/gallium/drivers/ilo/ilo_cp.c77
1 files changed, 27 insertions, 50 deletions
diff --git a/src/gallium/drivers/ilo/ilo_cp.c b/src/gallium/drivers/ilo/ilo_cp.c
index b67c872e2af..1fd47410bcd 100644
--- a/src/gallium/drivers/ilo/ilo_cp.c
+++ b/src/gallium/drivers/ilo/ilo_cp.c
@@ -34,8 +34,8 @@
static const int ilo_cp_private = 2;
/**
- * Dump the contents of the parser bo. This must be called in a post-flush
- * hook.
+ * Dump the contents of the parser bo. This can only be called in the flush
+ * callback.
*/
void
ilo_cp_dump(struct ilo_cp *cp)
@@ -94,10 +94,10 @@ ilo_cp_clear_buffer(struct ilo_cp *cp)
/*
* Recalculate cp->size. This is needed not only because cp->stolen is
- * reset above, but also that we added cp->reserve_for_pre_flush and
- * ilo_cp_private to cp->size in ilo_cp_flush().
+ * reset above, but also that ilo_cp_private are added to cp->size in
+ * ilo_cp_end_buffer().
*/
- cp->size = cp->bo_size - (cp->reserve_for_pre_flush + ilo_cp_private);
+ cp->size = cp->bo_size - ilo_cp_private;
}
/**
@@ -131,6 +131,11 @@ ilo_cp_upload_buffer(struct ilo_cp *cp)
{
int err;
+ if (!cp->sys) {
+ cp->bo->unmap(cp->bo);
+ return 0;
+ }
+
err = cp->bo->pwrite(cp->bo, 0, cp->used * 4, cp->ptr);
if (likely(!err && cp->stolen)) {
const int offset = cp->bo_size - cp->stolen;
@@ -156,8 +161,11 @@ ilo_cp_realloc_bo(struct ilo_cp *cp)
*/
bo = cp->winsys->alloc_buffer(cp->winsys,
"batch buffer", cp->bo_size * 4, 0);
- if (unlikely(!bo))
- return;
+ if (unlikely(!bo)) {
+ /* reuse the old one */
+ bo = cp->bo;
+ bo->reference(bo);
+ }
if (cp->bo)
cp->bo->unreference(cp->bo);
@@ -207,67 +215,39 @@ ilo_cp_exec_bo(struct ilo_cp *cp)
return err;
}
-static void
-ilo_cp_call_hook(struct ilo_cp *cp, enum ilo_cp_hook hook)
-{
- const bool no_implicit_flush = cp->no_implicit_flush;
-
- if (!cp->hooks[hook].func)
- return;
-
- /* no implicit flush in hooks */
- cp->no_implicit_flush = true;
- cp->hooks[hook].func(cp, cp->hooks[hook].data);
-
- cp->no_implicit_flush = no_implicit_flush;
-}
-
/**
* Flush the command parser and execute the commands. When the parser buffer
- * is empty, the hooks are not invoked.
+ * is empty, the callback is not invoked.
*/
void
ilo_cp_flush(struct ilo_cp *cp)
{
int err;
+ ilo_cp_set_owner(cp, NULL, 0);
+
/* sanity check */
- assert(cp->bo_size == cp->size +
- cp->reserve_for_pre_flush + ilo_cp_private + cp->stolen);
+ assert(cp->bo_size == cp->size + cp->stolen + ilo_cp_private);
if (!cp->used) {
+ /* return the space stolen and etc. */
ilo_cp_clear_buffer(cp);
+
return;
}
- /* make the reserved space available temporarily */
- cp->size += cp->reserve_for_pre_flush;
- ilo_cp_call_hook(cp, ILO_CP_HOOK_PRE_FLUSH);
-
ilo_cp_end_buffer(cp);
- if (cp->sys) {
- err = ilo_cp_upload_buffer(cp);
- if (likely(!err))
- err = ilo_cp_exec_bo(cp);
- }
- else {
- cp->bo->unmap(cp->bo);
+ /* upload and execute */
+ err = ilo_cp_upload_buffer(cp);
+ if (likely(!err))
err = ilo_cp_exec_bo(cp);
- }
- if (likely(!err)) {
- ilo_cp_call_hook(cp, ILO_CP_HOOK_POST_FLUSH);
- ilo_cp_clear_buffer(cp);
- }
- else {
- /* reset first so that post-flush hook knows nothing was executed */
- ilo_cp_clear_buffer(cp);
- ilo_cp_call_hook(cp, ILO_CP_HOOK_POST_FLUSH);
- }
+ if (likely(!err && cp->flush_callback))
+ cp->flush_callback(cp, cp->flush_callback_data);
+ ilo_cp_clear_buffer(cp);
ilo_cp_realloc_bo(cp);
- ilo_cp_call_hook(cp, ILO_CP_HOOK_NEW_BATCH);
}
/**
@@ -302,9 +282,6 @@ ilo_cp_create(struct intel_winsys *winsys, bool direct_map)
cp->ring = ILO_CP_RING_RENDER;
cp->no_implicit_flush = false;
- cp->reserve_for_pre_flush = 0;
-
- memset(cp->hooks, 0, sizeof(cp->hooks));
cp->bo_size = 8192;