summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/vc5/vc5_context.h3
-rw-r--r--src/gallium/drivers/vc5/vc5_draw.c21
-rw-r--r--src/gallium/drivers/vc5/vc5_query.c57
3 files changed, 64 insertions, 17 deletions
diff --git a/src/gallium/drivers/vc5/vc5_context.h b/src/gallium/drivers/vc5/vc5_context.h
index 2fec7a77da4..4917153fd46 100644
--- a/src/gallium/drivers/vc5/vc5_context.h
+++ b/src/gallium/drivers/vc5/vc5_context.h
@@ -363,6 +363,9 @@ struct vc5_context {
bool active_queries;
+ uint32_t tf_prims_generated;
+ uint32_t prims_generated;
+
struct pipe_poly_stipple stipple;
struct pipe_clip_state clip;
struct pipe_viewport_state viewport;
diff --git a/src/gallium/drivers/vc5/vc5_draw.c b/src/gallium/drivers/vc5/vc5_draw.c
index 8020e26802a..55a2e49b98d 100644
--- a/src/gallium/drivers/vc5/vc5_draw.c
+++ b/src/gallium/drivers/vc5/vc5_draw.c
@@ -270,6 +270,25 @@ vc5_emit_gl_shader_state(struct vc5_context *vc5,
job->shader_rec_count++;
}
+/**
+ * Computes the various transform feedback statistics, since they can't be
+ * recorded by CL packets.
+ */
+static void
+vc5_tf_statistics_record(struct vc5_context *vc5,
+ const struct pipe_draw_info *info,
+ bool prim_tf)
+{
+ uint32_t prims = u_prims_for_vertices(info->mode, info->count);
+
+ vc5->prims_generated += prims;
+
+ if (prim_tf) {
+ /* XXX: Only count if we didn't overflow. */
+ vc5->tf_prims_generated += prims;
+ }
+}
+
static void
vc5_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
{
@@ -363,6 +382,8 @@ vc5_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
if (vc5->prog.bind_vs->num_tf_outputs)
prim_tf_enable = (V3D_PRIM_POINTS_TF - V3D_PRIM_POINTS);
+ vc5_tf_statistics_record(vc5, info, prim_tf_enable);
+
/* Note that the primitive type fields match with OpenGL/gallium
* definitions, up to but not including QUADS.
*/
diff --git a/src/gallium/drivers/vc5/vc5_query.c b/src/gallium/drivers/vc5/vc5_query.c
index a412b384081..5ec9be2e356 100644
--- a/src/gallium/drivers/vc5/vc5_query.c
+++ b/src/gallium/drivers/vc5/vc5_query.c
@@ -24,12 +24,13 @@
/**
* Gallium query object support.
*
- * So far we just support occlusion queries. The HW has native support for
- * them, with the query result being loaded and stored by the TLB unit.
+ * The HW has native support for occlusion queries, with the query result
+ * being loaded and stored by the TLB unit. From a SW perspective, we have to
+ * be careful to make sure that the jobs that need to be tracking queries are
+ * bracketed by the start and end of counting, even across FBO transitions.
*
- * From a SW perspective, we have to be careful to make sure that the jobs
- * that need to be tracking queries are bracketed by the start and end of
- * counting, even across FBO transitions.
+ * For the transform feedback PRIMITIVES_GENERATED/WRITTEN queries, we have to
+ * do the calculations in software at draw time.
*/
#include "vc5_context.h"
@@ -39,6 +40,8 @@ struct vc5_query
{
enum pipe_query_type type;
struct vc5_bo *bo;
+
+ uint32_t start, end;
};
static struct pipe_query *
@@ -46,10 +49,6 @@ vc5_create_query(struct pipe_context *pctx, unsigned query_type, unsigned index)
{
struct vc5_query *q = calloc(1, sizeof(*q));
- assert(query_type == PIPE_QUERY_OCCLUSION_COUNTER ||
- query_type == PIPE_QUERY_OCCLUSION_PREDICATE ||
- query_type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE);
-
q->type = query_type;
/* Note that struct pipe_query isn't actually defined anywhere. */
@@ -71,13 +70,22 @@ vc5_begin_query(struct pipe_context *pctx, struct pipe_query *query)
struct vc5_context *vc5 = vc5_context(pctx);
struct vc5_query *q = (struct vc5_query *)query;
- q->bo = vc5_bo_alloc(vc5->screen, 4096, "query");
-
- uint32_t *map = vc5_bo_map(q->bo);
- *map = 0;
+ switch (q->type) {
+ case PIPE_QUERY_PRIMITIVES_GENERATED:
+ q->start = vc5->prims_generated;
+ break;
+ case PIPE_QUERY_PRIMITIVES_EMITTED:
+ q->start = vc5->tf_prims_generated;
+ break;
+ default:
+ q->bo = vc5_bo_alloc(vc5->screen, 4096, "query");
- vc5->current_oq = q->bo;
- vc5->dirty |= VC5_DIRTY_OQ;
+ uint32_t *map = vc5_bo_map(q->bo);
+ *map = 0;
+ vc5->current_oq = q->bo;
+ vc5->dirty |= VC5_DIRTY_OQ;
+ break;
+ }
return true;
}
@@ -86,9 +94,20 @@ static bool
vc5_end_query(struct pipe_context *pctx, struct pipe_query *query)
{
struct vc5_context *vc5 = vc5_context(pctx);
+ struct vc5_query *q = (struct vc5_query *)query;
- vc5->current_oq = NULL;
- vc5->dirty |= VC5_DIRTY_OQ;
+ switch (q->type) {
+ case PIPE_QUERY_PRIMITIVES_GENERATED:
+ q->end = vc5->prims_generated;
+ break;
+ case PIPE_QUERY_PRIMITIVES_EMITTED:
+ q->end = vc5->tf_prims_generated;
+ break;
+ default:
+ vc5->current_oq = NULL;
+ vc5->dirty |= VC5_DIRTY_OQ;
+ break;
+ }
return true;
}
@@ -127,6 +146,10 @@ vc5_get_query_result(struct pipe_context *pctx, struct pipe_query *query,
case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
vresult->b = result != 0;
break;
+ case PIPE_QUERY_PRIMITIVES_GENERATED:
+ case PIPE_QUERY_PRIMITIVES_EMITTED:
+ vresult->u64 = q->end - q->start;
+ break;
default:
unreachable("unsupported query type");
}