summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/ilo/ilo_cp.h
diff options
context:
space:
mode:
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;
}
/**