diff options
-rw-r--r-- | src/gallium/drivers/vc5/vc5_context.h | 3 | ||||
-rw-r--r-- | src/gallium/drivers/vc5/vc5_draw.c | 21 | ||||
-rw-r--r-- | src/gallium/drivers/vc5/vc5_query.c | 57 |
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"); } |