diff options
author | Eric Anholt <[email protected]> | 2017-11-06 15:41:40 -0800 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2017-11-07 12:56:40 -0800 |
commit | 4f33344e7a6b988fbbc4a0802dacf5cab487e408 (patch) | |
tree | 5c489236b7b2e50098015f4e04879533f3933505 /src/gallium/drivers/vc5/vc5_query.c | |
parent | d002950e5491f971cbaa77ac80a698e5d746295a (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.c | 97 |
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 |