diff options
author | Eric Anholt <[email protected]> | 2017-11-06 16:59:05 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2017-11-07 12:57:43 -0800 |
commit | 9ccb6621be2f40a74f75efe30d83b7813e3c3f56 (patch) | |
tree | 4b701f32ef19d24a6f7413c3913d211511612a1d /src/gallium/drivers/vc5/vc5_query.c | |
parent | 4f33344e7a6b988fbbc4a0802dacf5cab487e408 (diff) |
broadcom/vc5: Add partial transform feedback query support.
We have to compute the queries in software, so we're counting the
primitives by hand. We still need to make sure to not increment the
PRIMITIVES_EMITTED if we overflowed, but leave that for later.
Diffstat (limited to 'src/gallium/drivers/vc5/vc5_query.c')
-rw-r--r-- | src/gallium/drivers/vc5/vc5_query.c | 57 |
1 files changed, 40 insertions, 17 deletions
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"); } |