summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Berry <stereotype441@gmail.com>2011-12-15 14:57:57 -0800
committerPaul Berry <stereotype441@gmail.com>2011-12-20 15:22:28 -0800
commitc59393b7069f59ca2a13bfb6500f2a5360c38031 (patch)
treebf8d2c511d3ad886ef2eaf7719aa050c72017d41
parentc5e17a84983d7799fd842a62daaece3d97a670be (diff)
i965 gen6: Implement transform feedback queries.
This patch adds software-based PRIMITIVES_GENERATED and TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN queries that work by keeping track of the number of primitives that are sent down the pipeline, and adjusting as necessary to account for the way each primitive type is tessellated. In the long run we'll want to replace this with a hardware-based implementation, because the software approach won't work with geometry shaders or primitive restart. However, at the moment, we don't have the necessary kernel support to implement a hardware-based query (we would need the kernel to save GPU registers when context switching, so that drawing performed by another process doesn't get counted). Fixes Piglit tests EXT_transform_feedback/query-primitives_generated-* and EXT_transform_feedback/query-primitives-written-*. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_queryobj.c48
3 files changed, 54 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 8840a83d49..15a781b93a 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -988,6 +988,8 @@ struct brw_context
struct brw_sol_state {
uint32_t svbi_0_starting_index;
uint32_t svbi_0_max_index;
+ uint32_t primitives_generated;
+ uint32_t primitives_written;
} sol;
uint32_t render_target_format[MESA_FORMAT_COUNT];
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 774a5ca46e..082bb9aa24 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -388,6 +388,7 @@ brw_update_primitive_count(struct brw_context *brw,
const struct _mesa_prim *prim)
{
uint32_t count = count_tessellated_primitives(prim);
+ brw->sol.primitives_generated += count;
if (brw->intel.ctx.TransformFeedback.CurrentObject->Active) {
/* Update brw->sol.svbi_0_max_index to reflect the amount by which the
* hardware is going to increment SVBI 0 when this drawing operation
@@ -404,6 +405,9 @@ brw_update_primitive_count(struct brw_context *brw,
uint32_t primitives_written = MIN2 (space_avail, count);
brw->sol.svbi_0_starting_index +=
svbi_postincrement_value * primitives_written;
+
+ /* And update the TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN query. */
+ brw->sol.primitives_written += primitives_written;
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_queryobj.c b/src/mesa/drivers/dri/i965/brw_queryobj.c
index 3ad522da13..72b83f4570 100644
--- a/src/mesa/drivers/dri/i965/brw_queryobj.c
+++ b/src/mesa/drivers/dri/i965/brw_queryobj.c
@@ -75,6 +75,14 @@ brw_queryobj_get_results(struct gl_context *ctx,
}
break;
+ case GL_PRIMITIVES_GENERATED:
+ case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+ /* We don't actually query the hardware for this value, so query->bo
+ * should always be NULL and execution should never reach here.
+ */
+ assert(!"Unreachable");
+ break;
+
default:
assert(!"Unrecognized query target in brw_queryobj_get_results()");
break;
@@ -158,6 +166,20 @@ brw_begin_query(struct gl_context *ctx, struct gl_query_object *q)
intel->stats_wm++;
break;
+ case GL_PRIMITIVES_GENERATED:
+ /* We don't actually query the hardware for this value; we keep track of
+ * it a software counter. So just reset the counter.
+ */
+ brw->sol.primitives_generated = 0;
+ break;
+
+ case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+ /* We don't actually query the hardware for this value; we keep track of
+ * it a software counter. So just reset the counter.
+ */
+ brw->sol.primitives_written = 0;
+ break;
+
default:
assert(!"Unrecognized query target in brw_begin_query()");
break;
@@ -221,6 +243,32 @@ brw_end_query(struct gl_context *ctx, struct gl_query_object *q)
intel->stats_wm--;
break;
+ case GL_PRIMITIVES_GENERATED:
+ /* We don't actually query the hardware for this value; we keep track of
+ * it in a software counter. So just read the counter and store it in
+ * the query object.
+ */
+ query->Base.Result = brw->sol.primitives_generated;
+
+ /* And set brw->query.obj to NULL so that this query won't try to wait
+ * for any rendering to complete.
+ */
+ query->bo = NULL;
+ break;
+
+ case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
+ /* We don't actually query the hardware for this value; we keep track of
+ * it in a software counter. So just read the counter and store it in
+ * the query object.
+ */
+ query->Base.Result = brw->sol.primitives_written;
+
+ /* And set brw->query.obj to NULL so that this query won't try to wait
+ * for any rendering to complete.
+ */
+ query->bo = NULL;
+ break;
+
default:
assert(!"Unrecognized query target in brw_end_query()");
break;