gallium: add PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Tue, 12 Sep 2017 16:46:46 +0000 (18:46 +0200)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Mon, 18 Sep 2017 09:25:18 +0000 (11:25 +0200)
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 <marek.olsak@amd.com>
24 files changed:
src/gallium/auxiliary/util/u_dump_defines.c
src/gallium/auxiliary/util/u_inlines.h
src/gallium/docs/source/context.rst
src/gallium/drivers/freedreno/a3xx/fd3_query.c
src/gallium/drivers/freedreno/a4xx/fd4_query.c
src/gallium/drivers/freedreno/a5xx/fd5_query.c
src/gallium/drivers/freedreno/freedreno_query.h
src/gallium/drivers/llvmpipe/lp_query.c
src/gallium/drivers/llvmpipe/lp_rast.c
src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/nouveau/nv30/nv30_query.c
src/gallium/drivers/nouveau/nv50/nv50_query.c
src/gallium/drivers/nouveau/nv50/nv50_query_hw.c
src/gallium/drivers/nouveau/nvc0/nvc0_query.c
src/gallium/drivers/nouveau/nvc0/nvc0_query_hw.c
src/gallium/drivers/r300/r300_query.c
src/gallium/drivers/radeon/r600_pipe_common.c
src/gallium/drivers/radeon/r600_query.c
src/gallium/drivers/softpipe/sp_query.c
src/gallium/drivers/svga/svga_pipe_query.c
src/gallium/drivers/swr/swr_query.cpp
src/gallium/drivers/trace/tr_dump_state.c
src/gallium/include/pipe/p_defines.h
src/mesa/state_tracker/st_cb_queryobj.c

index 5032974a880767bded9a54758ba3f70c86aee75d..e87e530160040d421cfdfff2fff682a4be0d50c4 100644 (file)
@@ -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",
index e0ed594c9fedc5b88c4ef6f524e04509e3826c31..79f62c322666f95ccd4cc49396eb3f5c0f657fc0 100644 (file)
@@ -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:
index 6ac45819a66b18af6a9570a643ca1b5a67ddd161..ba7fef8301da839115cc36d44f9de40719f2f2e1 100644 (file)
@@ -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.
index cde42c37313d63a2b5853eb318a2197389a05e06..97a95b215465cd32830843a09b0812a7323803f5 100644 (file)
@@ -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);
 }
index f7b385d552d4b0d2ea864f689bfc04d10c18cddf..809e7570b487c163b5b4bb0e55e175ec4d2d0c18 100644 (file)
@@ -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);
 }
index 80b84ce54ba5d188b943da08f1ce50dd886fa40a..87417f1f96eef937c9edc3eb58af495208788852 100644 (file)
@@ -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);
index 49a86803c4d43de48174a694ff5aa87c39983764..b8fa0951ded4acdb3a3c515c33e4a739c5cef032 100644 (file)
@@ -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.
index 6f8ce94e5d8e0700384fbcbd7e24c0d12f0bedc3..7b81903b413f5fdc73859df54d7f12e3169cad4d 100644 (file)
@@ -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;
index b25ade3d2ecf4f96cfc77e1c357925eedb2f2110..0050655d9e32645f518c5216f89a402821129471 100644 (file)
@@ -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;
index 32387ab553204795a3c3b1f82156636b776d2cb1..2be6fc033d1d21e324f2f38e183988cbdd7e2b72 100644 (file)
@@ -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;
 
index 83ea3afec021046179f78426fe13807ee37ece75..f26728868af1aec671695ceb7699c2c9310e18a4 100644 (file)
@@ -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;
index ec6ee0f5eb327a1f7ac9ce1f325753e3cc6e72b1..e30380cd84d7cf301e10a3dc46e4ea0ae20baf5e 100644 (file)
@@ -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 :
index 727b509372dead54a75ec015dc25cc7ba196ecd1..ac3e409b2d5ef4e7a761831c6c5178b5e56f875c 100644 (file)
@@ -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:
index e3090745e3b75c9c56526cc818a226578d952017..d0a9e0c2c04b368eadf05d09e715be1a0c61df9f 100644 (file)
@@ -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 :
index d8d82de8650904aa3029dac771a274de4020661b..f2fdb0cd99976437cd11d763cf80501f8f3adc24 100644 (file)
@@ -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;
index d2dc7b73c05b96271bbddc006f610957dd894044..a84c941768fcb3016203b4bc456aca3981e6125d 100644 (file)
@@ -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;
index b283bc65b5b6bcac38bddfe3fa910a2d7a805feb..1183e181a828b5585745c10b79b54efbaf3b2d0f 100644 (file)
@@ -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 <=
index 76307ca06623ecf0b4d597948deea591d252b06d..e655bbdaa23a147601e67324c1bdb9385df0d89d 100644 (file)
@@ -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)
index 63f6c4be04298fac9362c867dcf66148123ddb87..267c99977fe528ac3e8aff8dccfb249aa38884d7 100644 (file)
@@ -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:
index 0490a4ab5fc604efbc975a6add6f0560ff620885..269245243723f72bfd8beeeab562bd570279e5fc 100644 (file)
@@ -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,
index 4c14c5206b05a6a4f65e6a57758fa4eb3039b79c..e3697304e0566779a8b0ed77768a569edf0f631b 100644 (file)
@@ -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:
index 0650f63d26627d3a6ff2ba072ec5aac65ec8f7c7..e7e32237c4c4450b2d4c8774a07dbffc76a0ab39 100644 (file)
@@ -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:
index 1a6e6bd7a707165d1a51a5e120a033b4e8a62a58..cadafe7f8c8123ad27bf35d40d43e9d32e2022a5 100644 (file)
@@ -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 */
index 4c25724b5dc4f87d1e2499ef32da66ef25008234..a470ff6b8b570ca01cc7cb444d9bf28efdbd011d 100644 (file)
@@ -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;