aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/ilo/ilo_cp.h
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.h
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.h')
-rw-r--r--src/gallium/drivers/ilo/ilo_cp.h101
1 files changed, 64 insertions, 37 deletions
diff --git a/src/gallium/drivers/ilo/ilo_cp.h b/src/gallium/drivers/ilo/ilo_cp.h
index 2e9b0e3d715..9df9a521caa 100644
--- a/src/gallium/drivers/ilo/ilo_cp.h
+++ b/src/gallium/drivers/ilo/ilo_cp.h
@@ -41,16 +41,13 @@ enum ilo_cp_ring {
ILO_CP_RING_COUNT,
};
-enum ilo_cp_hook {
- ILO_CP_HOOK_NEW_BATCH,
- ILO_CP_HOOK_PRE_FLUSH,
- ILO_CP_HOOK_POST_FLUSH,
+typedef void (*ilo_cp_callback)(struct ilo_cp *cp, void *data);
- ILO_CP_HOOK_COUNT,
+struct ilo_cp_owner {
+ ilo_cp_callback release_callback;
+ void *release_data;
};
-typedef void (*ilo_cp_hook_func)(struct ilo_cp *cp, void *data);
-
/**
* Command parser.
*/
@@ -58,16 +55,16 @@ struct ilo_cp {
struct intel_winsys *winsys;
struct intel_context *render_ctx;
+ ilo_cp_callback flush_callback;
+ void *flush_callback_data;
+
+ const struct ilo_cp_owner *owner;
+ int owner_reserve;
+
enum ilo_cp_ring ring;
bool no_implicit_flush;
- int reserve_for_pre_flush;
unsigned one_off_flags;
- struct {
- ilo_cp_hook_func func;
- void *data;
- } hooks[ILO_CP_HOOK_COUNT];
-
int bo_size;
struct intel_bo *bo;
uint32_t *sys;
@@ -160,44 +157,74 @@ ilo_cp_assert_no_implicit_flush(struct ilo_cp *cp, bool enable)
}
/**
- * Reserve the given size of space from the parser buffer. The reserved space
- * will be made available temporarily for the pre-flush hook.
- *
- * \param reserve size in dwords to reserve. It may be negative.
+ * Set one-off flags. They will be cleared after flushing.
*/
static inline void
-ilo_cp_reserve_for_pre_flush(struct ilo_cp *cp, int reserve)
+ilo_cp_set_one_off_flags(struct ilo_cp *cp, unsigned flags)
{
- assert(cp->reserve_for_pre_flush + reserve >= 0);
-
- if (cp->used > cp->size - reserve) {
- ilo_cp_implicit_flush(cp);
- assert(cp->used <= cp->size - reserve);
- }
-
- cp->size -= reserve;
- cp->reserve_for_pre_flush += reserve;
+ cp->one_off_flags |= flags;
}
/**
- * Set one-off flags. They will be cleared after flushing.
+ * Set flush callback. The callback is invoked after the bo has been
+ * successfully executed, and before the bo is reallocated.
*/
static inline void
-ilo_cp_set_one_off_flags(struct ilo_cp *cp, unsigned flags)
+ilo_cp_set_flush_callback(struct ilo_cp *cp, ilo_cp_callback callback,
+ void *data)
{
- cp->one_off_flags |= flags;
+ cp->flush_callback = callback;
+ cp->flush_callback_data = data;
}
-
/**
- * Set a command parser hook.
+ * Set the parser owner. If this is a new owner, the previous owner is
+ * notified and the space it reserved is reclaimed.
+ *
+ * \return true if this is a new owner
*/
-static inline void
-ilo_cp_set_hook(struct ilo_cp *cp, enum ilo_cp_hook hook,
- ilo_cp_hook_func func, void *data)
+static inline bool
+ilo_cp_set_owner(struct ilo_cp *cp, const struct ilo_cp_owner *owner,
+ int reserve)
{
- cp->hooks[hook].func = func;
- cp->hooks[hook].data = data;
+ const bool new_owner = (cp->owner != owner);
+
+ /* release current owner */
+ if (new_owner && cp->owner) {
+ const bool no_implicit_flush = cp->no_implicit_flush;
+
+ /* reclaim the reserved space */
+ cp->size += cp->owner_reserve;
+ cp->owner_reserve = 0;
+
+ /* invoke the release callback */
+ cp->no_implicit_flush = true;
+ cp->owner->release_callback(cp, cp->owner->release_data);
+ cp->no_implicit_flush = no_implicit_flush;
+
+ cp->owner = NULL;
+ }
+
+ if (cp->owner_reserve != reserve) {
+ const int extra = reserve - cp->owner_reserve;
+
+ if (cp->used > cp->size - extra) {
+ ilo_cp_implicit_flush(cp);
+ assert(cp->used <= cp->size - reserve);
+
+ cp->size -= reserve;
+ cp->owner_reserve = reserve;
+ }
+ else {
+ cp->size -= extra;
+ cp->owner_reserve += extra;
+ }
+ }
+
+ /* set owner last because of the possible flush above */
+ cp->owner = owner;
+
+ return new_owner;
}
/**