Mesa (master): gallium: add condition parameter to render_condition

Roland Scheidegger sroland at kemper.freedesktop.org
Tue Jun 18 16:06:32 UTC 2013


Module: Mesa
Branch: master
Commit: 793e8e3d7ed816cc9a066245dde798afdcf8b581
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=793e8e3d7ed816cc9a066245dde798afdcf8b581

Author: Roland Scheidegger <sroland at vmware.com>
Date:   Fri Jun 14 19:48:57 2013 +0200

gallium: add condition parameter to render_condition

For conditional rendering this makes it possible to skip rendering
if either the predicate is true or false, as supported by d3d10
(in fact previously it was sort of implied skip rendering if predicate
is false for occlusion predicate, and true for so_overflow predicate).
There's no cap bit for this as presumably all drivers could do it trivially
(but this patch does not implement it for the drivers using true
hw predicates, nvxx, r600, radeonsi, no change is expected for OpenGL
functionality).

Reviewed-by: Jose Fonseca <jfonseca at vmware.com>

---

 src/gallium/auxiliary/cso_cache/cso_context.c |   13 ++++++++++---
 src/gallium/auxiliary/cso_cache/cso_context.h |    3 ++-
 src/gallium/auxiliary/hud/hud_context.c       |    2 +-
 src/gallium/auxiliary/postprocess/pp_run.c    |    2 +-
 src/gallium/auxiliary/util/u_blit.c           |    2 +-
 src/gallium/auxiliary/util/u_blitter.c        |    3 ++-
 src/gallium/auxiliary/util/u_blitter.h        |    3 +++
 src/gallium/auxiliary/util/u_gen_mipmap.c     |    2 +-
 src/gallium/docs/source/context.rst           |   14 +++++++++-----
 src/gallium/drivers/galahad/glhd_context.c    |    3 ++-
 src/gallium/drivers/ilo/ilo_3d.c              |    4 +++-
 src/gallium/drivers/ilo/ilo_3d.h              |    1 +
 src/gallium/drivers/llvmpipe/lp_context.c     |    2 ++
 src/gallium/drivers/llvmpipe/lp_context.h     |    1 +
 src/gallium/drivers/llvmpipe/lp_query.c       |    3 ++-
 src/gallium/drivers/llvmpipe/lp_surface.c     |    2 +-
 src/gallium/drivers/nv30/nv30_context.h       |    1 +
 src/gallium/drivers/nv30/nv30_miptree.c       |    2 +-
 src/gallium/drivers/nv30/nv30_query.c         |    4 +++-
 src/gallium/drivers/nv50/nv50_context.h       |    1 +
 src/gallium/drivers/nv50/nv50_query.c         |    4 +++-
 src/gallium/drivers/nv50/nv50_surface.c       |    2 +-
 src/gallium/drivers/nvc0/nvc0_context.h       |    1 +
 src/gallium/drivers/nvc0/nvc0_query.c         |    4 +++-
 src/gallium/drivers/nvc0/nvc0_surface.c       |    2 +-
 src/gallium/drivers/r300/r300_query.c         |    7 ++++---
 src/gallium/drivers/r600/r600_blit.c          |    1 +
 src/gallium/drivers/r600/r600_pipe.c          |    6 ++++--
 src/gallium/drivers/r600/r600_pipe.h          |    1 +
 src/gallium/drivers/r600/r600_query.c         |    2 ++
 src/gallium/drivers/radeonsi/r600_blit.c      |    4 +++-
 src/gallium/drivers/radeonsi/r600_query.c     |    4 +++-
 src/gallium/drivers/radeonsi/radeonsi_pipe.c  |    6 ++++--
 src/gallium/drivers/radeonsi/radeonsi_pipe.h  |    2 ++
 src/gallium/drivers/softpipe/sp_context.c     |    2 ++
 src/gallium/drivers/softpipe/sp_context.h     |    1 +
 src/gallium/drivers/softpipe/sp_query.c       |    2 +-
 src/gallium/drivers/softpipe/sp_surface.c     |    2 +-
 src/gallium/drivers/svga/svga_pipe_blit.c     |    2 +-
 src/gallium/drivers/trace/tr_context.c        |    4 +++-
 src/gallium/include/pipe/p_context.h          |    2 ++
 src/mesa/state_tracker/st_cb_condrender.c     |    6 +++---
 42 files changed, 95 insertions(+), 40 deletions(-)

diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c
index b06a070..6805427 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.c
+++ b/src/gallium/auxiliary/cso_cache/cso_context.c
@@ -111,6 +111,7 @@ struct cso_context {
    void *velements, *velements_saved;
    struct pipe_query *render_condition, *render_condition_saved;
    uint render_condition_mode, render_condition_mode_saved;
+   boolean render_condition_cond, render_condition_cond_saved;
 
    struct pipe_clip_state clip;
    struct pipe_clip_state clip_saved;
@@ -723,13 +724,17 @@ void cso_restore_stencil_ref(struct cso_context *ctx)
 }
 
 void cso_set_render_condition(struct cso_context *ctx,
-                              struct pipe_query *query, uint mode)
+                              struct pipe_query *query,
+                              boolean condition, uint mode)
 {
    struct pipe_context *pipe = ctx->pipe;
 
-   if (ctx->render_condition != query || ctx->render_condition_mode != mode) {
-      pipe->render_condition(pipe, query, mode);
+   if (ctx->render_condition != query ||
+       ctx->render_condition_mode != mode ||
+       ctx->render_condition_cond != condition) {
+      pipe->render_condition(pipe, query, condition, mode);
       ctx->render_condition = query;
+      ctx->render_condition_cond = condition;
       ctx->render_condition_mode = mode;
    }
 }
@@ -737,12 +742,14 @@ void cso_set_render_condition(struct cso_context *ctx,
 void cso_save_render_condition(struct cso_context *ctx)
 {
    ctx->render_condition_saved = ctx->render_condition;
+   ctx->render_condition_cond_saved = ctx->render_condition_cond;
    ctx->render_condition_mode_saved = ctx->render_condition_mode;
 }
 
 void cso_restore_render_condition(struct cso_context *ctx)
 {
    cso_set_render_condition(ctx, ctx->render_condition_saved,
+                            ctx->render_condition_cond_saved,
                             ctx->render_condition_mode_saved);
 }
 
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h
index 20ab4ef..82c8e18 100644
--- a/src/gallium/auxiliary/cso_cache/cso_context.h
+++ b/src/gallium/auxiliary/cso_cache/cso_context.h
@@ -170,7 +170,8 @@ void cso_save_stencil_ref(struct cso_context *cso);
 void cso_restore_stencil_ref(struct cso_context *cso);
 
 void cso_set_render_condition(struct cso_context *cso,
-                              struct pipe_query *query, uint mode);
+                              struct pipe_query *query,
+                              boolean condition, uint mode);
 void cso_save_render_condition(struct cso_context *cso);
 void cso_restore_render_condition(struct cso_context *cso);
 
diff --git a/src/gallium/auxiliary/hud/hud_context.c b/src/gallium/auxiliary/hud/hud_context.c
index cbd00a9..9817083 100644
--- a/src/gallium/auxiliary/hud/hud_context.c
+++ b/src/gallium/auxiliary/hud/hud_context.c
@@ -456,7 +456,7 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
    cso_set_geometry_shader_handle(cso, NULL);
    cso_set_vertex_shader_handle(cso, hud->vs);
    cso_set_vertex_elements(cso, 2, hud->velems);
-   cso_set_render_condition(cso, NULL, 0);
+   cso_set_render_condition(cso, NULL, FALSE, 0);
    cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, 1,
                          &hud->font_sampler_view);
    cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, 1, sampler_states);
diff --git a/src/gallium/auxiliary/postprocess/pp_run.c b/src/gallium/auxiliary/postprocess/pp_run.c
index 8b3f451..54253f4 100644
--- a/src/gallium/auxiliary/postprocess/pp_run.c
+++ b/src/gallium/auxiliary/postprocess/pp_run.c
@@ -90,7 +90,7 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in,
    cso_set_sample_mask(cso, ~0);
    cso_set_stream_outputs(cso, 0, NULL, 0);
    cso_set_geometry_shader_handle(cso, NULL);
-   cso_set_render_condition(cso, NULL, 0);
+   cso_set_render_condition(cso, NULL, FALSE, 0);
 
    // Kept only for this frame.
    pipe_resource_reference(&ppq->depth, indepth);
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index cda66d1..07418be 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -679,7 +679,7 @@ util_blit_pixels(struct blit_state *ctx,
    cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
    cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
    cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
-   cso_set_render_condition(ctx->cso, NULL, 0);
+   cso_set_render_condition(ctx->cso, NULL, FALSE, 0);
 
    /* default sampler state */
    ctx->sampler.normalized_coords = normalized;
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index e9ac170..be839d4 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -492,7 +492,7 @@ static void blitter_disable_render_cond(struct blitter_context_priv *ctx)
    struct pipe_context *pipe = ctx->base.pipe;
 
    if (ctx->base.saved_render_cond_query) {
-      pipe->render_condition(pipe, NULL, 0);
+      pipe->render_condition(pipe, NULL, FALSE, 0);
    }
 }
 
@@ -502,6 +502,7 @@ static void blitter_restore_render_cond(struct blitter_context_priv *ctx)
 
    if (ctx->base.saved_render_cond_query) {
       pipe->render_condition(pipe, ctx->base.saved_render_cond_query,
+                             ctx->base.saved_render_cond_cond,
                              ctx->base.saved_render_cond_mode);
       ctx->base.saved_render_cond_query = NULL;
    }
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index e52d5ac..d9cefde 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -125,6 +125,7 @@ struct blitter_context
 
    struct pipe_query *saved_render_cond_query;
    uint saved_render_cond_mode;
+   boolean saved_render_cond_cond;
 };
 
 /**
@@ -515,10 +516,12 @@ util_blitter_save_sample_mask(struct blitter_context *blitter,
 static INLINE void
 util_blitter_save_render_condition(struct blitter_context *blitter,
                                    struct pipe_query *query,
+                                   boolean condition,
                                    uint mode)
 {
    blitter->saved_render_cond_query = query;
    blitter->saved_render_cond_mode = mode;
+   blitter->saved_render_cond_cond = condition;
 }
 
 #ifdef __cplusplus
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 7974b1d..a885f2b 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -1578,7 +1578,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
    cso_set_sample_mask(ctx->cso, ~0);
    cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
    cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
-   cso_set_render_condition(ctx->cso, NULL, 0);
+   cso_set_render_condition(ctx->cso, NULL, FALSE, 0);
 
    set_fragment_shader(ctx, type, is_depth);
    set_vertex_shader(ctx);
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
index 6a8238e..ede89be 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -382,15 +382,19 @@ Conditional Rendering
 ^^^^^^^^^^^^^^^^^^^^^
 
 A drawing command can be skipped depending on the outcome of a query
-(typically an occlusion query).  The ``render_condition`` function specifies
-the query which should be checked prior to rendering anything.
+(typically an occlusion query, or streamout overflow predicate).
+The ``render_condition`` function specifies the query which should be checked
+prior to rendering anything. Functions honoring render_condition include
+(and are limited to) draw_vbo, clear, clear_render_target, clear_depth_stencil.
 
 If ``render_condition`` is called with ``query`` = NULL, conditional
 rendering is disabled and drawing takes place normally.
 
 If ``render_condition`` is called with a non-null ``query`` subsequent
-drawing commands will be predicated on the outcome of the query.  If
-the query result is zero subsequent drawing commands will be skipped.
+drawing commands will be predicated on the outcome of the query.
+Commands will be skipped if ``condition`` is equal to the predicate result
+(for non-boolean queries such as OCCLUSION_QUERY, zero counts as FALSE,
+non-zero as TRUE).
 
 If ``mode`` is PIPE_RENDER_COND_WAIT the driver will wait for the
 query to complete before deciding whether to render.
@@ -401,7 +405,7 @@ has completed, drawing will be predicated on the outcome of the query.
 
 If ``mode`` is PIPE_RENDER_COND_BY_REGION_WAIT or
 PIPE_RENDER_COND_BY_REGION_NO_WAIT rendering will be predicated as above
-for the non-REGION modes but in the case that an occulusion query returns
+for the non-REGION modes but in the case that an occlusion query returns
 a non-zero result, regions which were occluded may be ommitted by subsequent
 drawing commands.  This can result in better performance with some GPUs.
 Normally, if the occlusion query returned a non-zero result subsequent
diff --git a/src/gallium/drivers/galahad/glhd_context.c b/src/gallium/drivers/galahad/glhd_context.c
index 7e8af56..ee9de05 100644
--- a/src/gallium/drivers/galahad/glhd_context.c
+++ b/src/gallium/drivers/galahad/glhd_context.c
@@ -1011,12 +1011,13 @@ galahad_context_transfer_inline_write(struct pipe_context *_context,
 static void
 galahad_context_render_condition(struct pipe_context *_context,
                                  struct pipe_query *query,
+                                 boolean condition,
                                  uint mode)
 {
    struct galahad_context *glhd_context = galahad_context(_context);
    struct pipe_context *context = glhd_context->pipe;
 
-   context->render_condition(context, query, mode);
+   context->render_condition(context, query, condition, mode);
 }
 
 
diff --git a/src/gallium/drivers/ilo/ilo_3d.c b/src/gallium/drivers/ilo/ilo_3d.c
index b2cbcf0..17dd5b1 100644
--- a/src/gallium/drivers/ilo/ilo_3d.c
+++ b/src/gallium/drivers/ilo/ilo_3d.c
@@ -445,7 +445,7 @@ pass_render_condition(struct ilo_3d *hw3d, struct pipe_context *pipe)
 
    if (pipe->get_query_result(pipe, hw3d->render_condition.query,
             wait, (union pipe_query_result *) &result)) {
-      return (result > 0);
+      return (!result == hw3d->render_condition.cond);
    }
    else {
       return true;
@@ -679,6 +679,7 @@ ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 static void
 ilo_render_condition(struct pipe_context *pipe,
                      struct pipe_query *query,
+                     boolean condition,
                      uint mode)
 {
    struct ilo_context *ilo = ilo_context(pipe);
@@ -687,6 +688,7 @@ ilo_render_condition(struct pipe_context *pipe,
    /* reference count? */
    hw3d->render_condition.query = query;
    hw3d->render_condition.mode = mode;
+   hw3d->render_condition.cond = condition;
 }
 
 static void
diff --git a/src/gallium/drivers/ilo/ilo_3d.h b/src/gallium/drivers/ilo/ilo_3d.h
index 3e67c85..a1a0efc 100644
--- a/src/gallium/drivers/ilo/ilo_3d.h
+++ b/src/gallium/drivers/ilo/ilo_3d.h
@@ -49,6 +49,7 @@ struct ilo_3d {
    struct {
       struct pipe_query *query;
       unsigned mode;
+      boolean cond;
    } render_condition;
 
    struct list_head occlusion_queries;
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index a6d7e59..9a6d13b 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -112,12 +112,14 @@ do_flush( struct pipe_context *pipe,
 static void
 llvmpipe_render_condition ( struct pipe_context *pipe,
                             struct pipe_query *query,
+                            boolean condition,
                             uint mode )
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
 
    llvmpipe->render_cond_query = query;
    llvmpipe->render_cond_mode = mode;
+   llvmpipe->render_cond_cond = condition;
 }
 
 struct pipe_context *
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 0515968..27e8b01 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -149,6 +149,7 @@ struct llvmpipe_context {
    /** Conditional query object and mode */
    struct pipe_query *render_cond_query;
    uint render_cond_mode;
+   boolean render_cond_cond;
 };
 
 
diff --git a/src/gallium/drivers/llvmpipe/lp_query.c b/src/gallium/drivers/llvmpipe/lp_query.c
index 0fd91c0..973c689 100644
--- a/src/gallium/drivers/llvmpipe/lp_query.c
+++ b/src/gallium/drivers/llvmpipe/lp_query.c
@@ -284,12 +284,13 @@ llvmpipe_check_render_cond(struct llvmpipe_context *lp)
 
    if (!lp->render_cond_query)
       return TRUE; /* no query predicate, draw normally */
+
    wait = (lp->render_cond_mode == PIPE_RENDER_COND_WAIT ||
            lp->render_cond_mode == PIPE_RENDER_COND_BY_REGION_WAIT);
 
    b = pipe->get_query_result(pipe, lp->render_cond_query, wait, (void*)&result);
    if (b)
-      return result > 0;
+      return (!result == lp->render_cond_cond);
    else
       return TRUE;
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index a40fe1b..7b1f939 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -227,7 +227,7 @@ static void lp_blit(struct pipe_context *pipe,
                      lp->num_sampler_views[PIPE_SHADER_FRAGMENT],
                      lp->sampler_views[PIPE_SHADER_FRAGMENT]);
    util_blitter_save_render_condition(lp->blitter, lp->render_cond_query,
-                                      lp->render_cond_mode);
+                                      lp->render_cond_cond, lp->render_cond_mode);
    util_blitter_blit(lp->blitter, &info);
 }
 
diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h
index c90dd3c..3009a0c 100644
--- a/src/gallium/drivers/nv30/nv30_context.h
+++ b/src/gallium/drivers/nv30/nv30_context.h
@@ -129,6 +129,7 @@ struct nv30_context {
 
    struct pipe_query *render_cond_query;
    unsigned render_cond_mode;
+   boolean render_cond_cond;
 };
 
 static INLINE struct nv30_context *
diff --git a/src/gallium/drivers/nv30/nv30_miptree.c b/src/gallium/drivers/nv30/nv30_miptree.c
index 4f5c445..c038d70 100644
--- a/src/gallium/drivers/nv30/nv30_miptree.c
+++ b/src/gallium/drivers/nv30/nv30_miptree.c
@@ -213,7 +213,7 @@ nv30_blit(struct pipe_context *pipe,
    util_blitter_save_fragment_sampler_views(nv30->blitter,
                      nv30->fragprog.num_textures, nv30->fragprog.textures);
    util_blitter_save_render_condition(nv30->blitter, nv30->render_cond_query,
-                                      nv30->render_cond_mode);
+                                      nv30->render_cond_cond, nv30->render_cond_mode);
    util_blitter_blit(nv30->blitter, &info);
 }
 
diff --git a/src/gallium/drivers/nv30/nv30_query.c b/src/gallium/drivers/nv30/nv30_query.c
index 8774086..a0a4c67 100644
--- a/src/gallium/drivers/nv30/nv30_query.c
+++ b/src/gallium/drivers/nv30/nv30_query.c
@@ -232,7 +232,8 @@ nv30_query_result(struct pipe_context *pipe, struct pipe_query *pq,
 
 static void
 nv40_query_render_condition(struct pipe_context *pipe,
-                            struct pipe_query *pq, uint mode)
+                            struct pipe_query *pq,
+                            boolean condition, uint mode)
 {
    struct nv30_context *nv30 = nv30_context(pipe);
    struct nv30_query *q = nv30_query(pq);
@@ -240,6 +241,7 @@ nv40_query_render_condition(struct pipe_context *pipe,
 
    nv30->render_cond_query = pq;
    nv30->render_cond_mode = mode;
+   nv30->render_cond_cond = condition;
 
    if (!pq) {
       BEGIN_NV04(push, SUBC_3D(0x1e98), 1);
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 043ed89..0a83131 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -156,6 +156,7 @@ struct nv50_context {
    boolean vbo_push_hint;
 
    struct pipe_query *cond_query;
+   boolean cond_cond;
    uint cond_mode;
 
    struct nv50_blitctx *blit;
diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c
index f434f5f..656ff9d 100644
--- a/src/gallium/drivers/nv50/nv50_query.c
+++ b/src/gallium/drivers/nv50/nv50_query.c
@@ -321,13 +321,15 @@ nv84_query_fifo_wait(struct nouveau_pushbuf *push, struct pipe_query *pq)
 
 static void
 nv50_render_condition(struct pipe_context *pipe,
-                      struct pipe_query *pq, uint mode)
+                      struct pipe_query *pq,
+                      boolean condition, uint mode)
 {
    struct nv50_context *nv50 = nv50_context(pipe);
    struct nouveau_pushbuf *push = nv50->base.pushbuf;
    struct nv50_query *q;
 
    nv50->cond_query = pq;
+   nv50->cond_cond = condition;
    nv50->cond_mode = mode;
 
    PUSH_SPACE(push, 6);
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index 2bfd855..d6066f2 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -902,7 +902,7 @@ nv50_blitctx_post_blit(struct nv50_blitctx *blit)
 
    if (nv50->cond_query)
       nv50->base.pipe.render_condition(&nv50->base.pipe, nv50->cond_query,
-                                       nv50->cond_mode);
+                                       nv50->cond_cond, nv50->cond_mode);
 
    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_FB);
    nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_TEXTURES);
diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h
index 799d9b9..0431b89 100644
--- a/src/gallium/drivers/nvc0/nvc0_context.h
+++ b/src/gallium/drivers/nvc0/nvc0_context.h
@@ -189,6 +189,7 @@ struct nvc0_context {
    unsigned num_tfbbufs;
 
    struct pipe_query *cond_query;
+   boolean cond_cond;
    uint cond_mode;
 
    struct nvc0_blitctx *blit;
diff --git a/src/gallium/drivers/nvc0/nvc0_query.c b/src/gallium/drivers/nvc0/nvc0_query.c
index d905f1a..8e584c9 100644
--- a/src/gallium/drivers/nvc0/nvc0_query.c
+++ b/src/gallium/drivers/nvc0/nvc0_query.c
@@ -518,7 +518,8 @@ nvc0_query_fifo_wait(struct nouveau_pushbuf *push, struct pipe_query *pq)
 
 static void
 nvc0_render_condition(struct pipe_context *pipe,
-                      struct pipe_query *pq, uint mode)
+                      struct pipe_query *pq,
+                      boolean condition, uint mode)
 {
    struct nvc0_context *nvc0 = nvc0_context(pipe);
    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
@@ -530,6 +531,7 @@ nvc0_render_condition(struct pipe_context *pipe,
       mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT;
 
    nvc0->cond_query = pq;
+   nvc0->cond_cond = condition;
    nvc0->cond_mode = mode;
 
    if (!pq) {
diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c
index e02cf22..c8d26f5 100644
--- a/src/gallium/drivers/nvc0/nvc0_surface.c
+++ b/src/gallium/drivers/nvc0/nvc0_surface.c
@@ -801,7 +801,7 @@ nvc0_blitctx_post_blit(struct nvc0_blitctx *blit)
 
    if (nvc0->cond_query)
       nvc0->base.pipe.render_condition(&nvc0->base.pipe, nvc0->cond_query,
-                                       nvc0->cond_mode);
+                                       nvc0->cond_cond, nvc0->cond_mode);
 
    nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_FB);
    nouveau_bufctx_reset(nvc0->bufctx_3d, NVC0_BIND_TEX(4, 0));
diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c
index e338c57..fbf44c6 100644
--- a/src/gallium/drivers/r300/r300_query.c
+++ b/src/gallium/drivers/r300/r300_query.c
@@ -178,6 +178,7 @@ static boolean r300_get_query_result(struct pipe_context* pipe,
 
 static void r300_render_condition(struct pipe_context *pipe,
                                   struct pipe_query *query,
+                                  boolean condition,
                                   uint mode)
 {
     struct r300_context *r300 = r300_context(pipe);
@@ -192,10 +193,10 @@ static void r300_render_condition(struct pipe_context *pipe,
 
         if (r300_get_query_result(pipe, query, wait, &result)) {
             if (r300_query(query)->type == PIPE_QUERY_OCCLUSION_PREDICATE) {
-                r300->skip_rendering = !result.b;
+                r300->skip_rendering = condition == result.b;
             } else {
-                r300->skip_rendering = !result.u64;
-	    }
+                r300->skip_rendering = condition == !!result.u64;
+            }
         }
     }
 }
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index 660f4f9..dcc3978 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -88,6 +88,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
 	if ((op & R600_DISABLE_RENDER_COND) && rctx->current_render_cond) {
            util_blitter_save_render_condition(rctx->blitter,
                                               rctx->current_render_cond,
+                                              rctx->current_render_cond_cond,
                                               rctx->current_render_cond_mode);
         }
 }
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 71f555b..74a650a 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -162,13 +162,15 @@ static void r600_flush(struct pipe_context *ctx, unsigned flags)
 	struct r600_context *rctx = (struct r600_context *)ctx;
 	struct pipe_query *render_cond = NULL;
 	unsigned render_cond_mode = 0;
+	boolean render_cond_cond = FALSE;
 
 	rctx->rings.gfx.flushing = true;
 	/* Disable render condition. */
 	if (rctx->current_render_cond) {
 		render_cond = rctx->current_render_cond;
+		render_cond_cond = rctx->current_render_cond_cond;
 		render_cond_mode = rctx->current_render_cond_mode;
-		ctx->render_condition(ctx, NULL, 0);
+		ctx->render_condition(ctx, NULL, FALSE, 0);
 	}
 
 	r600_context_flush(rctx, flags);
@@ -177,7 +179,7 @@ static void r600_flush(struct pipe_context *ctx, unsigned flags)
 
 	/* Re-enable render condition. */
 	if (render_cond) {
-		ctx->render_condition(ctx, render_cond, render_cond_mode);
+		ctx->render_condition(ctx, render_cond, render_cond_cond, render_cond_mode);
 	}
 }
 
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 2a81434..1dc346f 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -629,6 +629,7 @@ struct r600_context {
 	/* Render condition. */
 	struct pipe_query		*current_render_cond;
 	unsigned			current_render_cond_mode;
+	boolean				current_render_cond_cond;
 	boolean				predicate_drawing;
 
 	void				*sb_context;
diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c
index d264b7f..f77e1a8 100644
--- a/src/gallium/drivers/r600/r600_query.c
+++ b/src/gallium/drivers/r600/r600_query.c
@@ -669,6 +669,7 @@ static boolean r600_get_query_result(struct pipe_context *ctx,
 
 static void r600_render_condition(struct pipe_context *ctx,
 				  struct pipe_query *query,
+				  boolean condition,
 				  uint mode)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
@@ -676,6 +677,7 @@ static void r600_render_condition(struct pipe_context *ctx,
 	bool wait_flag = false;
 
 	rctx->current_render_cond = query;
+	rctx->current_render_cond_cond = condition;
 	rctx->current_render_cond_mode = mode;
 
 	if (query == NULL) {
diff --git a/src/gallium/drivers/radeonsi/r600_blit.c b/src/gallium/drivers/radeonsi/r600_blit.c
index 724d481..34f14ba 100644
--- a/src/gallium/drivers/radeonsi/r600_blit.c
+++ b/src/gallium/drivers/radeonsi/r600_blit.c
@@ -80,8 +80,9 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
 
 	if ((op & R600_DISABLE_RENDER_COND) && rctx->current_render_cond) {
 		rctx->saved_render_cond = rctx->current_render_cond;
+		rctx->saved_render_cond_cond = rctx->current_render_cond_cond;
 		rctx->saved_render_cond_mode = rctx->current_render_cond_mode;
-		rctx->context.render_condition(&rctx->context, NULL, 0);
+		rctx->context.render_condition(&rctx->context, NULL, FALSE, 0);
 	}
 
 }
@@ -92,6 +93,7 @@ static void r600_blitter_end(struct pipe_context *ctx)
 	if (rctx->saved_render_cond) {
 		rctx->context.render_condition(&rctx->context,
 					       rctx->saved_render_cond,
+					       rctx->saved_render_cond_cond,
 					       rctx->saved_render_cond_mode);
 		rctx->saved_render_cond = NULL;
 	}
diff --git a/src/gallium/drivers/radeonsi/r600_query.c b/src/gallium/drivers/radeonsi/r600_query.c
index bbf7c04..0162cce 100644
--- a/src/gallium/drivers/radeonsi/r600_query.c
+++ b/src/gallium/drivers/radeonsi/r600_query.c
@@ -69,6 +69,7 @@ static boolean r600_get_query_result(struct pipe_context *ctx,
 
 static void r600_render_condition(struct pipe_context *ctx,
 				  struct pipe_query *query,
+				  boolean condition,
 				  uint mode)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
@@ -78,12 +79,13 @@ static void r600_render_condition(struct pipe_context *ctx,
 	/* If we already have nonzero result, render unconditionally */
 	if (query != NULL && rquery->result.u64 != 0) {
 		if (rctx->current_render_cond) {
-			r600_render_condition(ctx, NULL, 0);
+			r600_render_condition(ctx, NULL, FALSE, 0);
 		}
 		return;
 	}
 
 	rctx->current_render_cond = query;
+	rctx->current_render_cond_cond = condition;
 	rctx->current_render_cond_mode = mode;
 
 	if (query == NULL) {
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
index 382311f..3f4cd78 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
@@ -139,6 +139,7 @@ void radeonsi_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
 	struct r600_context *rctx = (struct r600_context *)ctx;
 	struct r600_fence **rfence = (struct r600_fence**)fence;
 	struct pipe_query *render_cond = NULL;
+	boolean render_cond_cond = FALSE;
 	unsigned render_cond_mode = 0;
 
 	if (rfence)
@@ -147,15 +148,16 @@ void radeonsi_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
 	/* Disable render condition. */
 	if (rctx->current_render_cond) {
 		render_cond = rctx->current_render_cond;
+		render_cond_cond = rctx->current_render_cond_cond;
 		render_cond_mode = rctx->current_render_cond_mode;
-		ctx->render_condition(ctx, NULL, 0);
+		ctx->render_condition(ctx, NULL, FALSE, 0);
 	}
 
 	si_context_flush(rctx, flags);
 
 	/* Re-enable render condition. */
 	if (render_cond) {
-		ctx->render_condition(ctx, render_cond, render_cond_mode);
+		ctx->render_condition(ctx, render_cond, render_cond_cond, render_cond_mode);
 	}
 }
 
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
index 67cb14b..90d67e2 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
@@ -153,8 +153,10 @@ struct r600_context {
 	struct si_cs_shader_state	cs_shader_state;
 	struct pipe_query		*current_render_cond;
 	unsigned			current_render_cond_mode;
+	boolean				current_render_cond_cond;
 	struct pipe_query		*saved_render_cond;
 	unsigned			saved_render_cond_mode;
+	boolean				saved_render_cond_cond;
 	/* shader information */
 	unsigned			sprite_coord_enable;
 	unsigned			export_16bpc;
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index 141b7a8..14cfdc8 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -175,12 +175,14 @@ softpipe_is_resource_referenced( struct pipe_context *pipe,
 static void
 softpipe_render_condition( struct pipe_context *pipe,
                            struct pipe_query *query,
+                           boolean condition,
                            uint mode )
 {
    struct softpipe_context *softpipe = softpipe_context( pipe );
 
    softpipe->render_cond_query = query;
    softpipe->render_cond_mode = mode;
+   softpipe->render_cond_cond = condition;
 }
 
 
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index ea6c0f9..d7a00b9 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -144,6 +144,7 @@ struct softpipe_context {
    /** Conditional query object and mode */
    struct pipe_query *render_cond_query;
    uint render_cond_mode;
+   boolean render_cond_cond;
 
    /** Polygon stipple items */
    struct {
diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c
index b444e37..b5bc0db 100644
--- a/src/gallium/drivers/softpipe/sp_query.c
+++ b/src/gallium/drivers/softpipe/sp_query.c
@@ -261,7 +261,7 @@ softpipe_check_render_cond(struct softpipe_context *sp)
    b = pipe->get_query_result(pipe, sp->render_cond_query, wait,
                               (void*)&result);
    if (b)
-      return result > 0;
+      return (!result == sp->render_cond_cond);
    else
       return TRUE;
 }
diff --git a/src/gallium/drivers/softpipe/sp_surface.c b/src/gallium/drivers/softpipe/sp_surface.c
index 911c34d..52c85be 100644
--- a/src/gallium/drivers/softpipe/sp_surface.c
+++ b/src/gallium/drivers/softpipe/sp_surface.c
@@ -78,7 +78,7 @@ static void sp_blit(struct pipe_context *pipe,
                      sp->num_sampler_views[PIPE_SHADER_FRAGMENT],
                      sp->sampler_views[PIPE_SHADER_FRAGMENT]);
    util_blitter_save_render_condition(sp->blitter, sp->render_cond_query,
-                                      sp->render_cond_mode);
+                                      sp->render_cond_cond, sp->render_cond_mode);
    util_blitter_blit(sp->blitter, info);
 }
 
diff --git a/src/gallium/drivers/svga/svga_pipe_blit.c b/src/gallium/drivers/svga/svga_pipe_blit.c
index a44ed12..05930d0 100644
--- a/src/gallium/drivers/svga/svga_pipe_blit.c
+++ b/src/gallium/drivers/svga/svga_pipe_blit.c
@@ -206,7 +206,7 @@ static void svga_blit(struct pipe_context *pipe,
                      svga->curr.num_sampler_views,
                      svga->curr.sampler_views);
    /*util_blitter_save_render_condition(svga->blitter, svga->render_cond_query,
-                                      svga->render_cond_mode);*/
+                                      svga->render_cond_cond, svga->render_cond_mode);*/
    util_blitter_blit(svga->blitter, &info);
 }
 
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index ee23077..d78dd3e 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -1482,6 +1482,7 @@ trace_context_transfer_inline_write(struct pipe_context *_context,
 
 static void trace_context_render_condition(struct pipe_context *_context,
                                            struct pipe_query *query,
+                                           boolean condition,
                                            uint mode)
 {
    struct trace_context *tr_context = trace_context(_context);
@@ -1491,11 +1492,12 @@ static void trace_context_render_condition(struct pipe_context *_context,
 
    trace_dump_arg(ptr, context);
    trace_dump_arg(ptr, query);
+   trace_dump_arg(bool, condition);
    trace_dump_arg(uint, mode);
 
    trace_dump_call_end();
 
-   context->render_condition(context, query, mode);
+   context->render_condition(context, query, condition, mode);
 }
 
 
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index 0403d3b..aa18cbf 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -96,10 +96,12 @@ struct pipe_context {
    /**
     * Predicate subsequent rendering on occlusion query result
     * \param query  the query predicate, or NULL if no predicate
+    * \param condition whether to skip on FALSE or TRUE query results
     * \param mode  one of PIPE_RENDER_COND_x
     */
    void (*render_condition)( struct pipe_context *pipe,
                              struct pipe_query *query,
+                             boolean condition,
                              uint mode );
 
    /**
diff --git a/src/mesa/state_tracker/st_cb_condrender.c b/src/mesa/state_tracker/st_cb_condrender.c
index 3a5835e..8776985 100644
--- a/src/mesa/state_tracker/st_cb_condrender.c
+++ b/src/mesa/state_tracker/st_cb_condrender.c
@@ -76,12 +76,12 @@ st_BeginConditionalRender(struct gl_context *ctx, struct gl_query_object *q,
       m = PIPE_RENDER_COND_WAIT;
    }
 
-   cso_set_render_condition(st->cso_context, stq->pq, m);
+   cso_set_render_condition(st->cso_context, stq->pq, FALSE, m);
 }
 
 
 /**
- * Called via ctx->Driver.BeginConditionalRender()
+ * Called via ctx->Driver.EndConditionalRender()
  */
 static void
 st_EndConditionalRender(struct gl_context *ctx, struct gl_query_object *q)
@@ -91,7 +91,7 @@ st_EndConditionalRender(struct gl_context *ctx, struct gl_query_object *q)
 
    st_flush_bitmap_cache(st);
 
-   cso_set_render_condition(st->cso_context, NULL, 0);
+   cso_set_render_condition(st->cso_context, NULL, FALSE, 0);
 }
 
 




More information about the mesa-commit mailing list