summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2014-09-19 13:42:08 +0800
committerChia-I Wu <[email protected]>2014-09-19 16:02:11 +0800
commit270667472fa3e406b4748488718fdb3a7ef24e28 (patch)
treea226545260ccfc434370a57d3f8c4530396a6de7 /src/gallium
parent26ee6f23a9aec6b1f392baa0e3f1f2c62c038a57 (diff)
ilo: simplify ilo_cp_set_owner()
The simplification allows us to get rid of ilo_cp_set_ring() and ilo_cp_implicit_flush(). The 3D query code is refactored for the simplification.
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/ilo/ilo_3d.c101
-rw-r--r--src/gallium/drivers/ilo/ilo_3d.h1
-rw-r--r--src/gallium/drivers/ilo/ilo_blitter_blt.c5
-rw-r--r--src/gallium/drivers/ilo/ilo_cp.c53
-rw-r--r--src/gallium/drivers/ilo/ilo_cp.h90
5 files changed, 121 insertions, 129 deletions
diff --git a/src/gallium/drivers/ilo/ilo_3d.c b/src/gallium/drivers/ilo/ilo_3d.c
index 413d15a9cbe..fbfaef1517e 100644
--- a/src/gallium/drivers/ilo/ilo_3d.c
+++ b/src/gallium/drivers/ilo/ilo_3d.c
@@ -200,21 +200,26 @@ ilo_3d_pause_queries(struct ilo_3d *hw3d)
}
}
-static void
-ilo_3d_release_render_ring(struct ilo_cp *cp, void *data)
+void
+ilo_3d_own_render_ring(struct ilo_3d *hw3d)
{
- struct ilo_3d *hw3d = data;
-
- ilo_3d_pause_queries(hw3d);
+ ilo_cp_set_owner(hw3d->cp, INTEL_RING_RENDER, &hw3d->owner);
}
-void
-ilo_3d_own_render_ring(struct ilo_3d *hw3d)
+static void
+ilo_3d_reserve_for_query(struct ilo_3d *hw3d, struct ilo_query *q,
+ enum ilo_3d_pipeline_action act)
{
- ilo_cp_set_ring(hw3d->cp, INTEL_RING_RENDER);
+ q->reg_cmd_size = ilo_3d_pipeline_estimate_size(hw3d->pipeline, act, NULL);
- if (ilo_cp_set_owner(hw3d->cp, &hw3d->owner, hw3d->owner_reserve))
- ilo_3d_resume_queries(hw3d);
+ /* XXX we should check the aperture size */
+ if (ilo_cp_space(hw3d->cp) < q->reg_cmd_size * 2) {
+ ilo_cp_flush(hw3d->cp, "out of space");
+ assert(ilo_cp_space(hw3d->cp) >= q->reg_cmd_size * 2);
+ }
+
+ /* reserve space for pausing the query */
+ hw3d->owner.reserve += q->reg_cmd_size;
}
/**
@@ -229,21 +234,10 @@ ilo_3d_begin_query(struct ilo_context *ilo, struct ilo_query *q)
switch (q->type) {
case PIPE_QUERY_OCCLUSION_COUNTER:
- /* reserve some space for pausing the query */
- q->reg_cmd_size = ilo_3d_pipeline_estimate_size(hw3d->pipeline,
- ILO_3D_PIPELINE_WRITE_DEPTH_COUNT, NULL);
- hw3d->owner_reserve += q->reg_cmd_size;
- ilo_cp_set_owner(hw3d->cp, &hw3d->owner, hw3d->owner_reserve);
-
+ ilo_3d_reserve_for_query(hw3d, q, ILO_3D_PIPELINE_WRITE_DEPTH_COUNT);
q->data.u64 = 0;
if (ilo_query_alloc_bo(q, 2, -1, hw3d->cp->winsys)) {
- /* XXX we should check the aperture size */
- if (q->reg_cmd_size > ilo_cp_space(hw3d->cp)) {
- ilo_cp_flush(hw3d->cp, "out of space");
- assert(q->reg_cmd_size <= ilo_cp_space(hw3d->cp));
- }
-
ilo_3d_pipeline_emit_write_depth_count(hw3d->pipeline,
q->bo, q->reg_read++);
@@ -254,21 +248,10 @@ ilo_3d_begin_query(struct ilo_context *ilo, struct ilo_query *q)
/* nop */
break;
case PIPE_QUERY_TIME_ELAPSED:
- /* reserve some space for pausing the query */
- q->reg_cmd_size = ilo_3d_pipeline_estimate_size(hw3d->pipeline,
- ILO_3D_PIPELINE_WRITE_TIMESTAMP, NULL);
- hw3d->owner_reserve += q->reg_cmd_size;
- ilo_cp_set_owner(hw3d->cp, &hw3d->owner, hw3d->owner_reserve);
-
+ ilo_3d_reserve_for_query(hw3d, q, ILO_3D_PIPELINE_WRITE_TIMESTAMP);
q->data.u64 = 0;
if (ilo_query_alloc_bo(q, 2, -1, hw3d->cp->winsys)) {
- /* XXX we should check the aperture size */
- if (q->reg_cmd_size > ilo_cp_space(hw3d->cp)) {
- ilo_cp_flush(hw3d->cp, "out of space");
- assert(q->reg_cmd_size <= ilo_cp_space(hw3d->cp));
- }
-
ilo_3d_pipeline_emit_write_timestamp(hw3d->pipeline,
q->bo, q->reg_read++);
@@ -284,22 +267,11 @@ ilo_3d_begin_query(struct ilo_context *ilo, struct ilo_query *q)
list_add(&q->list, &hw3d->prim_emitted_queries);
break;
case PIPE_QUERY_PIPELINE_STATISTICS:
- /* reserve some space for pausing the query */
- q->reg_cmd_size = ilo_3d_pipeline_estimate_size(hw3d->pipeline,
- ILO_3D_PIPELINE_WRITE_STATISTICS, NULL);
- hw3d->owner_reserve += q->reg_cmd_size;
- ilo_cp_set_owner(hw3d->cp, &hw3d->owner, hw3d->owner_reserve);
-
+ ilo_3d_reserve_for_query(hw3d, q, ILO_3D_PIPELINE_WRITE_STATISTICS);
memset(&q->data.pipeline_statistics, 0,
sizeof(q->data.pipeline_statistics));
if (ilo_query_alloc_bo(q, 11 * 2, -1, hw3d->cp->winsys)) {
- /* XXX we should check the aperture size */
- if (q->reg_cmd_size > ilo_cp_space(hw3d->cp)) {
- ilo_cp_flush(hw3d->cp, "out of space");
- assert(q->reg_cmd_size <= ilo_cp_space(hw3d->cp));
- }
-
ilo_3d_pipeline_emit_write_statistics(hw3d->pipeline,
q->bo, q->reg_read);
q->reg_read += 11;
@@ -328,8 +300,9 @@ ilo_3d_end_query(struct ilo_context *ilo, struct ilo_query *q)
list_del(&q->list);
assert(q->reg_read < q->reg_total);
- hw3d->owner_reserve -= q->reg_cmd_size;
- ilo_cp_set_owner(hw3d->cp, &hw3d->owner, hw3d->owner_reserve);
+ assert(hw3d->owner.reserve >= q->reg_cmd_size);
+ hw3d->owner.reserve -= q->reg_cmd_size;
+
ilo_3d_pipeline_emit_write_depth_count(hw3d->pipeline,
q->bo, q->reg_read++);
break;
@@ -345,8 +318,9 @@ ilo_3d_end_query(struct ilo_context *ilo, struct ilo_query *q)
list_del(&q->list);
assert(q->reg_read < q->reg_total);
- hw3d->owner_reserve -= q->reg_cmd_size;
- ilo_cp_set_owner(hw3d->cp, &hw3d->owner, hw3d->owner_reserve);
+ assert(hw3d->owner.reserve >= q->reg_cmd_size);
+ hw3d->owner.reserve -= q->reg_cmd_size;
+
ilo_3d_pipeline_emit_write_timestamp(hw3d->pipeline,
q->bo, q->reg_read++);
break;
@@ -358,8 +332,9 @@ ilo_3d_end_query(struct ilo_context *ilo, struct ilo_query *q)
list_del(&q->list);
assert(q->reg_read + 11 <= q->reg_total);
- hw3d->owner_reserve -= q->reg_cmd_size;
- ilo_cp_set_owner(hw3d->cp, &hw3d->owner, hw3d->owner_reserve);
+ assert(hw3d->owner.reserve >= q->reg_cmd_size);
+ hw3d->owner.reserve -= q->reg_cmd_size;
+
ilo_3d_pipeline_emit_write_statistics(hw3d->pipeline,
q->bo, q->reg_read);
q->reg_read += 11;
@@ -422,6 +397,22 @@ ilo_3d_cp_flushed(struct ilo_3d *hw3d)
hw3d->new_batch = true;
}
+static void
+ilo_3d_own_cp(struct ilo_cp *cp, void *data)
+{
+ struct ilo_3d *hw3d = data;
+
+ ilo_3d_resume_queries(hw3d);
+}
+
+static void
+ilo_3d_release_cp(struct ilo_cp *cp, void *data)
+{
+ struct ilo_3d *hw3d = data;
+
+ ilo_3d_pause_queries(hw3d);
+}
+
/**
* Create a 3D context.
*/
@@ -435,8 +426,10 @@ ilo_3d_create(struct ilo_cp *cp, const struct ilo_dev_info *dev)
return NULL;
hw3d->cp = cp;
- hw3d->owner.release_callback = ilo_3d_release_render_ring;
- hw3d->owner.release_data = hw3d;
+ hw3d->owner.own = ilo_3d_own_cp;
+ hw3d->owner.release = ilo_3d_release_cp;
+ hw3d->owner.data = hw3d;
+ hw3d->owner.reserve = 0;
hw3d->new_batch = true;
diff --git a/src/gallium/drivers/ilo/ilo_3d.h b/src/gallium/drivers/ilo/ilo_3d.h
index 2ea3d99e884..c0e23265a1b 100644
--- a/src/gallium/drivers/ilo/ilo_3d.h
+++ b/src/gallium/drivers/ilo/ilo_3d.h
@@ -41,7 +41,6 @@ struct ilo_query;
struct ilo_3d {
struct ilo_cp *cp;
struct ilo_cp_owner owner;
- int owner_reserve;
bool new_batch;
diff --git a/src/gallium/drivers/ilo/ilo_blitter_blt.c b/src/gallium/drivers/ilo/ilo_blitter_blt.c
index 0320eeb70fa..b55327bda9a 100644
--- a/src/gallium/drivers/ilo/ilo_blitter_blt.c
+++ b/src/gallium/drivers/ilo/ilo_blitter_blt.c
@@ -47,9 +47,8 @@ ilo_blitter_blt_begin(struct ilo_blitter *blitter, int max_cmd_size,
int count;
uint32_t swctrl;
- /* change ring */
- ilo_cp_set_ring(ilo->cp, INTEL_RING_BLT);
- ilo_cp_set_owner(ilo->cp, NULL, 0);
+ /* change owner */
+ ilo_cp_set_owner(ilo->cp, INTEL_RING_BLT, NULL);
/* check aperture space */
aper_check[0] = dst;
diff --git a/src/gallium/drivers/ilo/ilo_cp.c b/src/gallium/drivers/ilo/ilo_cp.c
index dddd5a31c81..fd4f49e54a2 100644
--- a/src/gallium/drivers/ilo/ilo_cp.c
+++ b/src/gallium/drivers/ilo/ilo_cp.c
@@ -31,12 +31,62 @@
#include "ilo_shader.h"
#include "ilo_cp.h"
+static const struct ilo_cp_owner ilo_cp_default_owner;
+
+static void
+ilo_cp_release_owner(struct ilo_cp *cp)
+{
+ if (cp->owner != &ilo_cp_default_owner) {
+ const struct ilo_cp_owner *owner = cp->owner;
+
+ cp->owner = &ilo_cp_default_owner;
+
+ assert(ilo_cp_space(cp) >= owner->reserve);
+ owner->release(cp, owner->data);
+ }
+}
+
+/**
+ * Set the parser owner. If this is a new owner or a new ring, the old owner
+ * is released and the new owner's own() is called.
+ *
+ * The parser may be implicitly flushed if there is a ring change or there is
+ * not enough space for the new owner.
+ */
+void
+ilo_cp_set_owner(struct ilo_cp *cp, enum intel_ring_type ring,
+ const struct ilo_cp_owner *owner)
+{
+ if (!owner)
+ owner = &ilo_cp_default_owner;
+
+ if (cp->ring != ring) {
+ ilo_cp_flush(cp, "ring change");
+ cp->ring = ring;
+ }
+
+ if (cp->owner != owner) {
+ ilo_cp_release_owner(cp);
+
+ /* multiply by 2 because there are own() and release() */
+ if (ilo_cp_space(cp) < owner->reserve * 2) {
+ ilo_cp_flush(cp, "new owner");
+ assert(ilo_cp_space(cp) >= owner->reserve * 2);
+ }
+
+ cp->owner = owner;
+
+ assert(ilo_cp_space(cp) >= owner->reserve);
+ cp->owner->own(cp, cp->owner->data);
+ }
+}
+
static struct intel_bo *
ilo_cp_end_batch(struct ilo_cp *cp, unsigned *used)
{
struct intel_bo *bo;
- ilo_cp_set_owner(cp, NULL, 0);
+ ilo_cp_release_owner(cp);
if (!ilo_builder_batch_used(&cp->builder)) {
ilo_builder_batch_discard(&cp->builder);
@@ -130,6 +180,7 @@ ilo_cp_create(const struct ilo_dev_info *dev,
}
cp->ring = INTEL_RING_RENDER;
+ cp->owner = &ilo_cp_default_owner;
ilo_builder_init(&cp->builder, dev, winsys);
diff --git a/src/gallium/drivers/ilo/ilo_cp.h b/src/gallium/drivers/ilo/ilo_cp.h
index f6a0bf02a50..0f27e8e590d 100644
--- a/src/gallium/drivers/ilo/ilo_cp.h
+++ b/src/gallium/drivers/ilo/ilo_cp.h
@@ -38,9 +38,20 @@ struct ilo_shader_cache;
typedef void (*ilo_cp_callback)(struct ilo_cp *cp, void *data);
+/**
+ * Parser owners are notified when they gain or lose the ownership of the
+ * parser. This gives owners a chance to emit prolog or epilog.
+ */
struct ilo_cp_owner {
- ilo_cp_callback release_callback;
- void *release_data;
+ ilo_cp_callback own;
+ ilo_cp_callback release;
+ void *data;
+
+ /*
+ * Space reserved for own() and release(). This can be modified at any
+ * time, as long as it is never increased by more than ilo_cp_space().
+ */
+ int reserve;
};
/**
@@ -54,10 +65,9 @@ struct ilo_cp {
ilo_cp_callback flush_callback;
void *flush_callback_data;
+ enum intel_ring_type ring;
const struct ilo_cp_owner *owner;
- int owner_reserve;
- enum intel_ring_type ring;
unsigned one_off_flags;
struct ilo_builder builder;
@@ -87,6 +97,10 @@ ilo_cp_flush(struct ilo_cp *cp, const char *reason)
ilo_cp_flush_internal(cp);
}
+void
+ilo_cp_set_owner(struct ilo_cp *cp, enum intel_ring_type ring,
+ const struct ilo_cp_owner *owner);
+
/**
* Return true if the parser buffer is empty.
*/
@@ -105,30 +119,9 @@ ilo_cp_space(struct ilo_cp *cp)
const int space = ilo_builder_batch_space(&cp->builder);
const int mi_batch_buffer_end_space = 2;
- assert(space >= cp->owner_reserve + mi_batch_buffer_end_space);
-
- return space - cp->owner_reserve - mi_batch_buffer_end_space;
-}
-
-/**
- * Internal function called by functions that flush implicitly.
- */
-static inline void
-ilo_cp_implicit_flush(struct ilo_cp *cp)
-{
- ilo_cp_flush(cp, "out of space (implicit)");
-}
+ assert(space >= cp->owner->reserve + mi_batch_buffer_end_space);
-/**
- * Set the ring buffer.
- */
-static inline void
-ilo_cp_set_ring(struct ilo_cp *cp, enum intel_ring_type ring)
-{
- if (cp->ring != ring) {
- ilo_cp_implicit_flush(cp);
- cp->ring = ring;
- }
+ return space - cp->owner->reserve - mi_batch_buffer_end_space;
}
/**
@@ -152,47 +145,4 @@ ilo_cp_set_flush_callback(struct ilo_cp *cp, ilo_cp_callback callback,
cp->flush_callback_data = data;
}
-/**
- * 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 bool
-ilo_cp_set_owner(struct ilo_cp *cp, const struct ilo_cp_owner *owner,
- int reserve)
-{
- const bool new_owner = (cp->owner != owner);
-
- /* release current owner */
- if (new_owner && cp->owner) {
- /* reclaim the reserved space */
- cp->owner_reserve = 0;
-
- /* invoke the release callback */
- cp->owner->release_callback(cp, cp->owner->release_data);
-
- cp->owner = NULL;
- }
-
- if (cp->owner_reserve != reserve) {
- const int extra = reserve - cp->owner_reserve;
-
- if (ilo_cp_space(cp) < extra) {
- ilo_cp_implicit_flush(cp);
-
- assert(ilo_cp_space(cp) >= reserve);
- cp->owner_reserve = reserve;
- }
- else {
- cp->owner_reserve += extra;
- }
- }
-
- /* set owner last because of the possible flush above */
- cp->owner = owner;
-
- return new_owner;
-}
-
#endif /* ILO_CP_H */