summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/vc5/vc5_query.c
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2017-11-06 15:41:40 -0800
committerEric Anholt <[email protected]>2017-11-07 12:56:40 -0800
commit4f33344e7a6b988fbbc4a0802dacf5cab487e408 (patch)
tree5c489236b7b2e50098015f4e04879533f3933505 /src/gallium/drivers/vc5/vc5_query.c
parentd002950e5491f971cbaa77ac80a698e5d746295a (diff)
broadcom/vc5: Add occlusion query support.
Fixes all of piglit's OQ tests.
Diffstat (limited to 'src/gallium/drivers/vc5/vc5_query.c')
-rw-r--r--src/gallium/drivers/vc5/vc5_query.c97
1 files changed, 81 insertions, 16 deletions
diff --git a/src/gallium/drivers/vc5/vc5_query.c b/src/gallium/drivers/vc5/vc5_query.c
index c114e76eef0..a412b384081 100644
--- a/src/gallium/drivers/vc5/vc5_query.c
+++ b/src/gallium/drivers/vc5/vc5_query.c
@@ -22,60 +22,125 @@
*/
/**
- * Stub support for occlusion queries.
+ * Gallium query object support.
*
- * Since we expose support for GL 2.0, we have to expose occlusion queries,
- * but the spec allows you to expose 0 query counter bits, so we just return 0
- * as the result of all our queries.
+ * 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.
+ *
+ * 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.
*/
+
#include "vc5_context.h"
+#include "broadcom/cle/v3d_packet_v33_pack.h"
struct vc5_query
{
- uint8_t pad;
+ enum pipe_query_type type;
+ struct vc5_bo *bo;
};
static struct pipe_query *
-vc5_create_query(struct pipe_context *ctx, unsigned query_type, unsigned index)
+vc5_create_query(struct pipe_context *pctx, unsigned query_type, unsigned index)
{
- struct vc5_query *query = calloc(1, sizeof(*query));
+ 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. */
- return (struct pipe_query *)query;
+ return (struct pipe_query *)q;
}
static void
-vc5_destroy_query(struct pipe_context *ctx, struct pipe_query *query)
+vc5_destroy_query(struct pipe_context *pctx, struct pipe_query *query)
{
- free(query);
+ struct vc5_query *q = (struct vc5_query *)query;
+
+ vc5_bo_unreference(&q->bo);
+ free(q);
}
static boolean
-vc5_begin_query(struct pipe_context *ctx, struct pipe_query *query)
+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;
+
+ vc5->current_oq = q->bo;
+ vc5->dirty |= VC5_DIRTY_OQ;
+
return true;
}
static bool
-vc5_end_query(struct pipe_context *ctx, struct pipe_query *query)
+vc5_end_query(struct pipe_context *pctx, struct pipe_query *query)
{
+ struct vc5_context *vc5 = vc5_context(pctx);
+
+ vc5->current_oq = NULL;
+ vc5->dirty |= VC5_DIRTY_OQ;
+
return true;
}
static boolean
-vc5_get_query_result(struct pipe_context *ctx, struct pipe_query *query,
+vc5_get_query_result(struct pipe_context *pctx, struct pipe_query *query,
boolean wait, union pipe_query_result *vresult)
{
- uint64_t *result = &vresult->u64;
+ struct vc5_query *q = (struct vc5_query *)query;
+ uint32_t result = 0;
+
+ if (q->bo) {
+ /* XXX: Only flush the jobs using this BO. */
+ vc5_flush(pctx);
- *result = 0;
+ if (wait) {
+ if (!vc5_bo_wait(q->bo, 0, "query"))
+ return false;
+ } else {
+ if (!vc5_bo_wait(q->bo, ~0ull, "query"))
+ return false;
+ }
+
+ /* XXX: Sum up per-core values. */
+ uint32_t *map = vc5_bo_map(q->bo);
+ result = *map;
+
+ vc5_bo_unreference(&q->bo);
+ }
+
+ switch (q->type) {
+ case PIPE_QUERY_OCCLUSION_COUNTER:
+ vresult->u64 = result;
+ break;
+ case PIPE_QUERY_OCCLUSION_PREDICATE:
+ case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE:
+ vresult->b = result != 0;
+ break;
+ default:
+ unreachable("unsupported query type");
+ }
return true;
}
static void
-vc5_set_active_query_state(struct pipe_context *pipe, boolean enable)
+vc5_set_active_query_state(struct pipe_context *pctx, boolean enable)
{
+ struct vc5_context *vc5 = vc5_context(pctx);
+
+ vc5->active_queries = enable;
+ vc5->dirty |= VC5_DIRTY_OQ;
}
void