[Mesa-dev] [PATCH] gallium: add condition parameter to render_condition

Jose Fonseca jfonseca at vmware.com
Mon Jun 17 07:28:47 PDT 2013


Looks good to me.

Jose

----- Original Message -----
> From: Roland Scheidegger <sroland at vmware.com>
> 
> 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).
> ---
>  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 de032b6..f8753fb 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 8c871fd..9f78576 100644
> --- a/src/gallium/auxiliary/util/u_blitter.c
> +++ b/src/gallium/auxiliary/util/u_blitter.c
> @@ -517,7 +517,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);
>     }
>  }
>  
> @@ -527,6 +527,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 1901584..c46f9e5 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;
>  };
>  
>  /**
> @@ -517,10 +518,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 aba92a0..255a024 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;
> @@ -686,6 +686,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);
> @@ -694,6 +695,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 abfe852..ab52001 100644
> --- a/src/gallium/drivers/llvmpipe/lp_context.h
> +++ b/src/gallium/drivers/llvmpipe/lp_context.h
> @@ -148,6 +148,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 058bf81..526847d 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 f11f110..2aa1f1f 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 431864a..e8de81a 100644
> --- a/src/gallium/drivers/softpipe/sp_context.h
> +++ b/src/gallium/drivers/softpipe/sp_context.h
> @@ -143,6 +143,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);
>  }
>  
>  
> --
> 1.7.9.5
> 


More information about the mesa-dev mailing list