From: Nicolai Hähnle Date: Tue, 12 Sep 2017 16:46:46 +0000 (+0200) Subject: gallium: add PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3f6b3d9db72c45e648c8c5943ef949273b110005;p=mesa.git gallium: add PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE To be able to properly distinguish between GL_ANY_SAMPLES_PASSED and GL_ANY_SAMPLES_PASSED_CONSERVATIVE. This patch goes through all drivers, having them treat the two query types identically, except: 1. radeon incorrectly enabled conservative mode on PIPE_QUERY_OCCLUSION_PREDICATE. We now do it correctly, only on PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE. 2. st/mesa uses the new query type. Fixes dEQP-GLES31.functional.fbo.no_attachments.* Reviewed-by: Marek Olšák --- diff --git a/src/gallium/auxiliary/util/u_dump_defines.c b/src/gallium/auxiliary/util/u_dump_defines.c index 5032974a880..e87e5301600 100644 --- a/src/gallium/auxiliary/util/u_dump_defines.c +++ b/src/gallium/auxiliary/util/u_dump_defines.c @@ -365,6 +365,7 @@ static const char * util_query_type_names[] = { "PIPE_QUERY_OCCLUSION_COUNTER", "PIPE_QUERY_OCCLUSION_PREDICATE", + "PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE", "PIPE_QUERY_TIMESTAMP", "PIPE_QUERY_TIMESTAMP_DISJOINT", "PIPE_QUERY_TIME_ELAPSED", diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index e0ed594c9fe..79f62c32266 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -536,6 +536,7 @@ util_query_clear_result(union pipe_query_result *result, unsigned type) { switch (type) { case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: case PIPE_QUERY_SO_OVERFLOW_PREDICATE: case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: case PIPE_QUERY_GPU_FINISHED: diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst index 6ac45819a66..ba7fef8301d 100644 --- a/src/gallium/docs/source/context.rst +++ b/src/gallium/docs/source/context.rst @@ -394,6 +394,12 @@ value of FALSE for cases where COUNTER would result in 0 and TRUE for all other cases. This query can be used with ``render_condition``. +In cases where a conservative approximation of an occlusion query is enough, +``PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE`` should be used. It behaves +like ``PIPE_QUERY_OCCLUSION_PREDICATE``, except that it may return TRUE in +additional, implementation-dependent cases. +This query can be used with ``render_condition``. + ``PIPE_QUERY_TIME_ELAPSED`` returns the amount of time, in nanoseconds, the context takes to perform operations. The result is an unsigned 64-bit integer. diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_query.c b/src/gallium/drivers/freedreno/a3xx/fd3_query.c index cde42c37313..97a95b21546 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_query.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_query.c @@ -131,6 +131,13 @@ static const struct fd_hw_sample_provider occlusion_predicate = { .accumulate_result = occlusion_predicate_accumulate_result, }; +static const struct fd_hw_sample_provider occlusion_predicate_conservative = { + .query_type = PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE, + .active = FD_STAGE_DRAW, + .get_sample = occlusion_get_sample, + .accumulate_result = occlusion_predicate_accumulate_result, +}; + void fd3_query_context_init(struct pipe_context *pctx) { struct fd_context *ctx = fd_context(pctx); @@ -142,4 +149,5 @@ void fd3_query_context_init(struct pipe_context *pctx) fd_hw_query_register_provider(pctx, &occlusion_counter); fd_hw_query_register_provider(pctx, &occlusion_predicate); + fd_hw_query_register_provider(pctx, &occlusion_predicate_conservative); } diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_query.c b/src/gallium/drivers/freedreno/a4xx/fd4_query.c index f7b385d552d..809e7570b48 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_query.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_query.c @@ -251,6 +251,13 @@ static const struct fd_hw_sample_provider occlusion_predicate = { .accumulate_result = occlusion_predicate_accumulate_result, }; +static const struct fd_hw_sample_provider occlusion_predicate = { + .query_type = PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE, + .active = FD_STAGE_DRAW, + .get_sample = occlusion_get_sample, + .accumulate_result = occlusion_predicate_accumulate_result, +}; + static const struct fd_hw_sample_provider time_elapsed = { .query_type = PIPE_QUERY_TIME_ELAPSED, .active = FD_STAGE_DRAW | FD_STAGE_CLEAR, @@ -284,6 +291,7 @@ void fd4_query_context_init(struct pipe_context *pctx) fd_hw_query_register_provider(pctx, &occlusion_counter); fd_hw_query_register_provider(pctx, &occlusion_predicate); + fd_hw_query_register_provider(pctx, &occlusion_predicate_conservative); fd_hw_query_register_provider(pctx, &time_elapsed); fd_hw_query_register_provider(pctx, ×tamp); } diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_query.c b/src/gallium/drivers/freedreno/a5xx/fd5_query.c index 80b84ce54ba..87417f1f96e 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_query.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_query.c @@ -144,6 +144,15 @@ static const struct fd_acc_sample_provider occlusion_predicate = { .result = occlusion_predicate_result, }; +static const struct fd_acc_sample_provider occlusion_predicate_conservative = { + .query_type = PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE, + .active = FD_STAGE_DRAW, + .size = sizeof(struct fd5_query_sample), + .resume = occlusion_resume, + .pause = occlusion_pause, + .result = occlusion_predicate_result, +}; + /* * Timestamp Queries: */ @@ -247,6 +256,7 @@ fd5_query_context_init(struct pipe_context *pctx) fd_acc_query_register_provider(pctx, &occlusion_counter); fd_acc_query_register_provider(pctx, &occlusion_predicate); + fd_acc_query_register_provider(pctx, &occlusion_predicate_conservative); fd_acc_query_register_provider(pctx, &time_elapsed); fd_acc_query_register_provider(pctx, ×tamp); diff --git a/src/gallium/drivers/freedreno/freedreno_query.h b/src/gallium/drivers/freedreno/freedreno_query.h index 49a86803c4d..b8fa0951ded 100644 --- a/src/gallium/drivers/freedreno/freedreno_query.h +++ b/src/gallium/drivers/freedreno/freedreno_query.h @@ -85,6 +85,7 @@ int pidx(unsigned query_type) case PIPE_QUERY_OCCLUSION_COUNTER: return 0; case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: return 1; /* TODO currently queries only emitted in main pass (not in binning pass).. * which is fine for occlusion query, but pretty much not anything else. diff --git a/src/gallium/drivers/llvmpipe/lp_query.c b/src/gallium/drivers/llvmpipe/lp_query.c index 6f8ce94e5d8..7b81903b413 100644 --- a/src/gallium/drivers/llvmpipe/lp_query.c +++ b/src/gallium/drivers/llvmpipe/lp_query.c @@ -125,6 +125,7 @@ llvmpipe_get_query_result(struct pipe_context *pipe, } break; case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: for (i = 0; i < num_threads; i++) { /* safer (still not guaranteed) when there's an overflow */ vresult->b = vresult->b || pq->end[i]; @@ -231,6 +232,7 @@ llvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q) break; case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: llvmpipe->active_occlusion_queries++; llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY; break; @@ -294,6 +296,7 @@ llvmpipe_end_query(struct pipe_context *pipe, struct pipe_query *q) break; case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: assert(llvmpipe->active_occlusion_queries); llvmpipe->active_occlusion_queries--; llvmpipe->dirty |= LP_NEW_OCCLUSION_QUERY; diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index b25ade3d2ec..0050655d9e3 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -486,6 +486,7 @@ lp_rast_begin_query(struct lp_rasterizer_task *task, switch (pq->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: pq->start[task->thread_index] = task->thread_data.vis_counter; break; case PIPE_QUERY_PIPELINE_STATISTICS: @@ -512,6 +513,7 @@ lp_rast_end_query(struct lp_rasterizer_task *task, switch (pq->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: pq->end[task->thread_index] += task->thread_data.vis_counter - pq->start[task->thread_index]; pq->start[task->thread_index] = 0; diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 32387ab5532..2be6fc033d1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -1380,6 +1380,7 @@ lp_setup_begin_query(struct lp_setup_context *setup, if (!(pq->type == PIPE_QUERY_OCCLUSION_COUNTER || pq->type == PIPE_QUERY_OCCLUSION_PREDICATE || + pq->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE || pq->type == PIPE_QUERY_PIPELINE_STATISTICS)) return; @@ -1430,6 +1431,7 @@ lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq) if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER || pq->type == PIPE_QUERY_OCCLUSION_PREDICATE || + pq->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE || pq->type == PIPE_QUERY_PIPELINE_STATISTICS || pq->type == PIPE_QUERY_TIMESTAMP) { if (pq->type == PIPE_QUERY_TIMESTAMP && @@ -1466,6 +1468,7 @@ fail: */ if (pq->type == PIPE_QUERY_OCCLUSION_COUNTER || pq->type == PIPE_QUERY_OCCLUSION_PREDICATE || + pq->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE || pq->type == PIPE_QUERY_PIPELINE_STATISTICS) { unsigned i; diff --git a/src/gallium/drivers/nouveau/nv30/nv30_query.c b/src/gallium/drivers/nouveau/nv30/nv30_query.c index 83ea3afec02..f26728868af 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_query.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_query.c @@ -121,6 +121,7 @@ nv30_query_create(struct pipe_context *pipe, unsigned type, unsigned index) break; case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: q->enable = NV30_3D_QUERY_ENABLE; q->report = 1; break; @@ -228,7 +229,8 @@ nv30_query_result(struct pipe_context *pipe, struct pipe_query *pq, nv30_query_object_del(screen, &q->qo[1]); } - if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE) + if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE || + q->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) result->b = !!q->result; else result->u64 = q->result; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query.c b/src/gallium/drivers/nouveau/nv50/nv50_query.c index ec6ee0f5eb3..e30380cd84d 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_query.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_query.c @@ -97,6 +97,7 @@ nv50_render_condition(struct pipe_context *pipe, break; case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: if (likely(!condition)) { if (unlikely(hq->nesting)) cond = wait ? NV50_3D_COND_MODE_NOT_EQUAL : diff --git a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c index 727b509372d..ac3e409b2d5 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_query_hw.c @@ -157,6 +157,7 @@ nv50_hw_begin_query(struct nv50_context *nv50, struct nv50_query *q) switch (q->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: hq->nesting = nv50->screen->num_occlusion_queries_active++; if (hq->nesting) { nv50_hw_query_get(push, q, 0x10, 0x0100f002); @@ -215,6 +216,7 @@ nv50_hw_end_query(struct nv50_context *nv50, struct nv50_query *q) switch (q->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: nv50_hw_query_get(push, q, 0, 0x0100f002); if (--nv50->screen->num_occlusion_queries_active == 0) { PUSH_SPACE(push, 2); @@ -307,6 +309,7 @@ nv50_hw_get_query_result(struct nv50_context *nv50, struct nv50_query *q, res64[0] = hq->data[1] - hq->data[5]; break; case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: res8[0] = hq->data[1] != hq->data[5]; break; case PIPE_QUERY_PRIMITIVES_GENERATED: /* u64 count, u64 time */ @@ -378,6 +381,7 @@ nv50_hw_create_query(struct nv50_context *nv50, unsigned type, unsigned index) switch (q->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: hq->rotate = 32; break; case PIPE_QUERY_PRIMITIVES_GENERATED: diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query.c index e3090745e3b..d0a9e0c2c04 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_query.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query.c @@ -119,6 +119,7 @@ nvc0_render_condition(struct pipe_context *pipe, break; case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: if (likely(!condition)) { if (unlikely(hq->nesting)) cond = wait ? NVC0_3D_COND_MODE_NOT_EQUAL : diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c index d8d82de8650..f2fdb0cd999 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c @@ -157,6 +157,7 @@ nvc0_hw_begin_query(struct nvc0_context *nvc0, struct nvc0_query *q) switch (q->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: hq->nesting = nvc0->screen->num_occlusion_queries_active++; if (hq->nesting) { nvc0_hw_query_get(push, q, 0x10, 0x0100f002); @@ -224,6 +225,7 @@ nvc0_hw_end_query(struct nvc0_context *nvc0, struct nvc0_query *q) switch (q->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: nvc0_hw_query_get(push, q, 0, 0x0100f002); if (--nvc0->screen->num_occlusion_queries_active == 0) { PUSH_SPACE(push, 1); @@ -320,6 +322,7 @@ nvc0_hw_get_query_result(struct nvc0_context *nvc0, struct nvc0_query *q, res64[0] = hq->data[1] - hq->data[5]; break; case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: res8[0] = hq->data[1] != hq->data[5]; break; case PIPE_QUERY_PRIMITIVES_GENERATED: /* u64 count, u64 time */ @@ -408,7 +411,8 @@ nvc0_hw_get_query_result_resource(struct nvc0_context *nvc0, PUSH_REFN (push, hq->bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD); PUSH_REFN (push, buf->bo, buf->domain | NOUVEAU_BO_WR); BEGIN_1IC0(push, NVC0_3D(MACRO_QUERY_BUFFER_WRITE), 9); - if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE) /* XXX what if 64-bit? */ + if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE || + q->type ++ PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) /* XXX what if 64-bit? */ PUSH_DATA(push, 0x00000001); else if (result_type == PIPE_QUERY_TYPE_I32) PUSH_DATA(push, 0x7fffffff); @@ -513,6 +517,7 @@ nvc0_hw_create_query(struct nvc0_context *nvc0, unsigned type, unsigned index) switch (q->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: hq->rotate = 32; space = NVC0_HW_QUERY_ALLOC_SPACE; break; diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c index d2dc7b73c05..a84c941768f 100644 --- a/src/gallium/drivers/r300/r300_query.c +++ b/src/gallium/drivers/r300/r300_query.c @@ -39,6 +39,7 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe, if (query_type != PIPE_QUERY_OCCLUSION_COUNTER && query_type != PIPE_QUERY_OCCLUSION_PREDICATE && + query_type != PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE && query_type != PIPE_QUERY_GPU_FINISHED) { return NULL; } @@ -171,7 +172,8 @@ static boolean r300_get_query_result(struct pipe_context* pipe, map++; } - if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE) { + if (q->type == PIPE_QUERY_OCCLUSION_PREDICATE || + q->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) { vresult->b = temp != 0; } else { vresult->u64 = temp; @@ -195,7 +197,8 @@ static void r300_render_condition(struct pipe_context *pipe, mode == PIPE_RENDER_COND_BY_REGION_WAIT; if (r300_get_query_result(pipe, query, wait, &result)) { - if (r300_query(query)->type == PIPE_QUERY_OCCLUSION_PREDICATE) { + if (r300_query(query)->type == PIPE_QUERY_OCCLUSION_PREDICATE || + r300_query(query)->type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) { r300->skip_rendering = condition == result.b; } else { r300->skip_rendering = condition == !!result.u64; diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c index b283bc65b5b..1183e181a82 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.c +++ b/src/gallium/drivers/radeon/r600_pipe_common.c @@ -126,7 +126,8 @@ void r600_gfx_write_event_eop(struct r600_common_context *ctx, */ if (ctx->chip_class == GFX9 && query_type != PIPE_QUERY_OCCLUSION_COUNTER && - query_type != PIPE_QUERY_OCCLUSION_PREDICATE) { + query_type != PIPE_QUERY_OCCLUSION_PREDICATE && + query_type != PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) { struct r600_resource *scratch = ctx->eop_bug_scratch; assert(16 * ctx->screen->info.num_render_backends <= diff --git a/src/gallium/drivers/radeon/r600_query.c b/src/gallium/drivers/radeon/r600_query.c index 76307ca0662..e655bbdaa23 100644 --- a/src/gallium/drivers/radeon/r600_query.c +++ b/src/gallium/drivers/radeon/r600_query.c @@ -551,7 +551,8 @@ static bool r600_query_hw_prepare_buffer(struct r600_common_screen *rscreen, memset(results, 0, buffer->b.b.width0); if (query->b.type == PIPE_QUERY_OCCLUSION_COUNTER || - query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE) { + query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE || + query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) { unsigned max_rbs = rscreen->info.num_render_backends; unsigned enabled_rb_mask = rscreen->info.enabled_rb_mask; unsigned num_results; @@ -636,6 +637,7 @@ static struct pipe_query *r600_query_hw_create(struct r600_common_screen *rscree switch (query_type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: query->result_size = 16 * rscreen->info.num_render_backends; query->result_size += 16; /* for the fence + alignment */ query->num_cs_dw_begin = 6; @@ -692,7 +694,8 @@ static void r600_update_occlusion_query_state(struct r600_common_context *rctx, unsigned type, int diff) { if (type == PIPE_QUERY_OCCLUSION_COUNTER || - type == PIPE_QUERY_OCCLUSION_PREDICATE) { + type == PIPE_QUERY_OCCLUSION_PREDICATE || + type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) { bool old_enable = rctx->num_occlusion_queries != 0; bool old_perfect_enable = rctx->num_perfect_occlusion_queries != 0; @@ -701,7 +704,7 @@ static void r600_update_occlusion_query_state(struct r600_common_context *rctx, rctx->num_occlusion_queries += diff; assert(rctx->num_occlusion_queries >= 0); - if (type == PIPE_QUERY_OCCLUSION_COUNTER) { + if (type != PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) { rctx->num_perfect_occlusion_queries += diff; assert(rctx->num_perfect_occlusion_queries >= 0); } @@ -745,6 +748,7 @@ static void r600_query_hw_do_emit_start(struct r600_common_context *ctx, switch (query->b.type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 2, 0)); radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1)); radeon_emit(cs, va); @@ -839,6 +843,7 @@ static void r600_query_hw_do_emit_stop(struct r600_common_context *ctx, switch (query->b.type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: va += 8; radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 2, 0)); radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_ZPASS_DONE) | EVENT_INDEX(1)); @@ -961,6 +966,7 @@ static void r600_emit_query_predication(struct r600_common_context *ctx, switch (query->b.type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: op = PRED_OP(PREDICATION_OP_ZPASS); break; case PIPE_QUERY_SO_OVERFLOW_PREDICATE: @@ -1139,6 +1145,7 @@ static void r600_get_hw_query_params(struct r600_common_context *rctx, switch (rquery->b.type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: params->start_offset = 0; params->end_offset = 8; params->fence_offset = max_rbs * 16; @@ -1231,7 +1238,8 @@ static void r600_query_hw_add_result(struct r600_common_screen *rscreen, } break; } - case PIPE_QUERY_OCCLUSION_PREDICATE: { + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: { for (unsigned i = 0; i < max_rbs; ++i) { unsigned results_base = i * 16; result->b = result->b || @@ -1711,7 +1719,8 @@ static void r600_query_hw_get_result_resource(struct r600_common_context *rctx, consts.config = 0; if (index < 0) consts.config |= 4; - if (query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE) + if (query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE || + query->b.type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) consts.config |= 8; else if (query->b.type == PIPE_QUERY_SO_OVERFLOW_PREDICATE || query->b.type == PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE) diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c index 63f6c4be042..267c99977fe 100644 --- a/src/gallium/drivers/softpipe/sp_query.c +++ b/src/gallium/drivers/softpipe/sp_query.c @@ -60,6 +60,7 @@ softpipe_create_query(struct pipe_context *pipe, assert(type == PIPE_QUERY_OCCLUSION_COUNTER || type == PIPE_QUERY_OCCLUSION_PREDICATE || + type == PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE || type == PIPE_QUERY_TIME_ELAPSED || type == PIPE_QUERY_SO_STATISTICS || type == PIPE_QUERY_SO_OVERFLOW_PREDICATE || @@ -93,6 +94,7 @@ softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q) switch (sq->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: sq->start = softpipe->occlusion_count; break; case PIPE_QUERY_TIME_ELAPSED: @@ -147,6 +149,7 @@ softpipe_end_query(struct pipe_context *pipe, struct pipe_query *q) switch (sq->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: sq->end = softpipe->occlusion_count; break; case PIPE_QUERY_TIMESTAMP: @@ -252,6 +255,7 @@ softpipe_get_query_result(struct pipe_context *pipe, *result = sq->so.primitives_storage_needed; break; case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: vresult->b = sq->end - sq->start != 0; break; default: diff --git a/src/gallium/drivers/svga/svga_pipe_query.c b/src/gallium/drivers/svga/svga_pipe_query.c index 0490a4ab5fc..26924524372 100644 --- a/src/gallium/drivers/svga/svga_pipe_query.c +++ b/src/gallium/drivers/svga/svga_pipe_query.c @@ -707,6 +707,7 @@ svga_create_query(struct pipe_context *pipe, } break; case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: if (svga_have_vgpu10(svga)) { sq->svga_type = SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE; define_query_vgpu10(svga, sq, sizeof(SVGADXOcclusionPredicateQueryResult)); @@ -789,6 +790,7 @@ svga_destroy_query(struct pipe_context *pipe, struct pipe_query *q) switch (sq->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: if (svga_have_vgpu10(svga)) { /* make sure to also destroy any associated predicate query */ if (sq->predicate) @@ -864,6 +866,7 @@ svga_begin_query(struct pipe_context *pipe, struct pipe_query *q) switch (sq->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: if (svga_have_vgpu10(svga)) { ret = begin_query_vgpu10(svga, sq); /* also need to start the associated occlusion predicate query */ @@ -977,6 +980,7 @@ svga_end_query(struct pipe_context *pipe, struct pipe_query *q) switch (sq->type) { case PIPE_QUERY_OCCLUSION_COUNTER: case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: if (svga_have_vgpu10(svga)) { ret = end_query_vgpu10(svga, sq); /* also need to end the associated occlusion predicate query */ @@ -1093,7 +1097,8 @@ svga_get_query_result(struct pipe_context *pipe, ret = get_query_result_vgpu9(svga, sq, wait, result); } break; - case PIPE_QUERY_OCCLUSION_PREDICATE: { + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: { if (svga_have_vgpu10(svga)) { SVGADXOcclusionPredicateQueryResult occResult; ret = get_query_result_vgpu10(svga, sq, wait, diff --git a/src/gallium/drivers/swr/swr_query.cpp b/src/gallium/drivers/swr/swr_query.cpp index 4c14c5206b0..e3697304e05 100644 --- a/src/gallium/drivers/swr/swr_query.cpp +++ b/src/gallium/drivers/swr/swr_query.cpp @@ -94,6 +94,7 @@ swr_get_query_result(struct pipe_context *pipe, switch (pq->type) { /* Booleans */ case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: result->b = pq->result.core.DepthPassCount != 0; break; case PIPE_QUERY_GPU_FINISHED: diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index 0650f63d266..e7e32237c4c 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -878,6 +878,7 @@ trace_dump_query_result(unsigned query_type, switch (query_type) { case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: case PIPE_QUERY_SO_OVERFLOW_PREDICATE: case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: case PIPE_QUERY_GPU_FINISHED: diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 1a6e6bd7a70..cadafe7f8c8 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -530,6 +530,7 @@ enum pipe_tess_spacing { enum pipe_query_type { PIPE_QUERY_OCCLUSION_COUNTER, PIPE_QUERY_OCCLUSION_PREDICATE, + PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE, PIPE_QUERY_TIMESTAMP, PIPE_QUERY_TIMESTAMP_DISJOINT, PIPE_QUERY_TIME_ELAPSED, @@ -946,6 +947,7 @@ union pipe_numeric_type_union union pipe_query_result { /* PIPE_QUERY_OCCLUSION_PREDICATE */ + /* PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE */ /* PIPE_QUERY_SO_OVERFLOW_PREDICATE */ /* PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE */ /* PIPE_QUERY_GPU_FINISHED */ diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c index 4c25724b5dc..a470ff6b8b5 100644 --- a/src/mesa/state_tracker/st_cb_queryobj.c +++ b/src/mesa/state_tracker/st_cb_queryobj.c @@ -102,9 +102,11 @@ st_BeginQuery(struct gl_context *ctx, struct gl_query_object *q) /* convert GL query type to Gallium query type */ switch (q->Target) { case GL_ANY_SAMPLES_PASSED: - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: type = PIPE_QUERY_OCCLUSION_PREDICATE; break; + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + type = PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE; + break; case GL_SAMPLES_PASSED_ARB: type = PIPE_QUERY_OCCLUSION_COUNTER; break; @@ -260,6 +262,7 @@ get_query_result(struct pipe_context *pipe, default: switch (stq->type) { case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: case PIPE_QUERY_SO_OVERFLOW_PREDICATE: case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: stq->base.Result = !!data.b;