summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2017-09-12 18:46:46 +0200
committerNicolai Hähnle <[email protected]>2017-09-18 11:25:18 +0200
commit3f6b3d9db72c45e648c8c5943ef949273b110005 (patch)
tree42a40a28274ee27bc0878a7414aaa6670ba56ee6
parent94736d31c364635a76a11e0bd4f046a42d2221d5 (diff)
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 <[email protected]>
-rw-r--r--src/gallium/auxiliary/util/u_dump_defines.c1
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h1
-rw-r--r--src/gallium/docs/source/context.rst6
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_query.c8
-rw-r--r--src/gallium/drivers/freedreno/a4xx/fd4_query.c8
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_query.c10
-rw-r--r--src/gallium/drivers/freedreno/freedreno_query.h1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_query.c3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c3
-rw-r--r--src/gallium/drivers/nouveau/nv30/nv30_query.c4
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_query.c1
-rw-r--r--src/gallium/drivers/nouveau/nv50/nv50_query_hw.c4
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_query.c1
-rw-r--r--src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c7
-rw-r--r--src/gallium/drivers/r300/r300_query.c7
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.c3
-rw-r--r--src/gallium/drivers/radeon/r600_query.c19
-rw-r--r--src/gallium/drivers/softpipe/sp_query.c4
-rw-r--r--src/gallium/drivers/svga/svga_pipe_query.c7
-rw-r--r--src/gallium/drivers/swr/swr_query.cpp1
-rw-r--r--src/gallium/drivers/trace/tr_dump_state.c1
-rw-r--r--src/gallium/include/pipe/p_defines.h2
-rw-r--r--src/mesa/state_tracker/st_cb_queryobj.c5
24 files changed, 97 insertions, 12 deletions
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, &timestamp);
}
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, &timestamp);
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;