summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/vc5/vc5_query.c
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2017-11-06 16:59:05 -0800
committerEric Anholt <[email protected]>2017-11-07 12:57:43 -0800
commit9ccb6621be2f40a74f75efe30d83b7813e3c3f56 (patch)
tree4b701f32ef19d24a6f7413c3913d211511612a1d /src/gallium/drivers/vc5/vc5_query.c
parent4f33344e7a6b988fbbc4a0802dacf5cab487e408 (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.c57
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");
}