[Mesa-dev] [PATCH] r600g: fix lockups with dual_src_blend v2

Marek Olšák maraeo at gmail.com
Tue Aug 21 11:23:41 PDT 2012


This looks good to me. Thanks.

Marek

On Tue, Aug 21, 2012 at 1:42 PM, Vadim Girlin <vadimgirlin at gmail.com> wrote:
> Disable blending when dual_src_blend is enabled and number of color exports
> in the current fragment shader is less than 2.
>
> Fixes lockups with ext_framebuffer_multisample-
> alpha-to-coverage-dual-src-blend piglit test.
>
> Signed-off-by: Vadim Girlin <vadimgirlin at gmail.com>
> ---
>
> Tested on evergreen only.
>
>  src/gallium/drivers/r600/r600_pipe.c         |  7 +++++
>  src/gallium/drivers/r600/r600_pipe.h         |  8 ++++++
>  src/gallium/drivers/r600/r600_state_common.c | 39 +++++++++++++++++++++-------
>  3 files changed, 45 insertions(+), 9 deletions(-)
>
> diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
> index cf29833..7936c47 100644
> --- a/src/gallium/drivers/r600/r600_pipe.c
> +++ b/src/gallium/drivers/r600/r600_pipe.c
> @@ -156,6 +156,9 @@ static void r600_destroy_context(struct pipe_context *context)
>  {
>         struct r600_context *rctx = (struct r600_context *)context;
>
> +       if (rctx->no_blend) {
> +               rctx->context.delete_blend_state(&rctx->context, rctx->no_blend);
> +       }
>         if (rctx->dummy_pixel_shader) {
>                 rctx->context.delete_fs_state(&rctx->context, rctx->dummy_pixel_shader);
>         }
> @@ -195,6 +198,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
>  {
>         struct r600_context *rctx = CALLOC_STRUCT(r600_context);
>         struct r600_screen* rscreen = (struct r600_screen *)screen;
> +       struct pipe_blend_state no_blend = {};
>
>         if (rctx == NULL)
>                 return NULL;
> @@ -296,6 +300,9 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
>                                                      TGSI_INTERPOLATE_CONSTANT);
>         rctx->context.bind_fs_state(&rctx->context, rctx->dummy_pixel_shader);
>
> +       no_blend.rt[0].colormask = 0xF;
> +       rctx->no_blend = rctx->context.create_blend_state(&rctx->context, &no_blend);
> +
>         return &rctx->context;
>
>  fail:
> diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
> index 7046573..3686521 100644
> --- a/src/gallium/drivers/r600/r600_pipe.h
> +++ b/src/gallium/drivers/r600/r600_pipe.h
> @@ -389,6 +389,14 @@ struct r600_context {
>         struct r600_cs_shader_state     cs_shader_state;
>         struct r600_sample_mask         sample_mask;
>
> +       /* current external blend state (from state tracker) */
> +       struct r600_pipe_blend          *blend;
> +       /* state with disabled blending - used internally with blend_override */
> +       struct r600_pipe_blend          *no_blend;
> +
> +       /* 1 - override current blend state with no_blend, 0 - use external state */
> +       unsigned        blend_override;
> +
>         struct radeon_winsys_cs *cs;
>
>         struct r600_range       *range;
> diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
> index ba5e26c..0870cc7 100644
> --- a/src/gallium/drivers/r600/r600_state_common.c
> +++ b/src/gallium/drivers/r600/r600_state_common.c
> @@ -165,19 +165,15 @@ static bool r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
>  }
>
>  /* common state between evergreen and r600 */
> -void r600_bind_blend_state(struct pipe_context *ctx, void *state)
> +
> +static void r600_bind_blend_state_internal(struct r600_context *rctx,
> +               struct r600_pipe_blend *blend)
>  {
> -       struct r600_context *rctx = (struct r600_context *)ctx;
> -       struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state;
>         struct r600_pipe_state *rstate;
>         bool update_cb = false;
>
> -       if (state == NULL)
> -               return;
>         rstate = &blend->rstate;
>         rctx->states[rstate->id] = rstate;
> -       rctx->dual_src_blend = blend->dual_src_blend;
> -       rctx->alpha_to_one = blend->alpha_to_one;
>         r600_context_pipe_state_set(rctx, rstate);
>
>         if (rctx->cb_misc_state.blend_colormask != blend->cb_target_mask) {
> @@ -198,6 +194,22 @@ void r600_bind_blend_state(struct pipe_context *ctx, void *state)
>         }
>  }
>
> +void r600_bind_blend_state(struct pipe_context *ctx, void *state)
> +{
> +       struct r600_context *rctx = (struct r600_context *)ctx;
> +       struct r600_pipe_blend *blend = (struct r600_pipe_blend *)state;
> +
> +       if (blend == NULL)
> +               return;
> +
> +       rctx->blend = blend;
> +       rctx->alpha_to_one = blend->alpha_to_one;
> +       rctx->dual_src_blend = blend->dual_src_blend;
> +
> +       if (!rctx->blend_override)
> +               r600_bind_blend_state_internal(rctx, blend);
> +}
> +
>  void r600_set_blend_color(struct pipe_context *ctx,
>                           const struct pipe_blend_color *state)
>  {
> @@ -1024,7 +1036,7 @@ void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
>  static void r600_update_derived_state(struct r600_context *rctx)
>  {
>         struct pipe_context * ctx = (struct pipe_context*)rctx;
> -       unsigned ps_dirty = 0;
> +       unsigned ps_dirty = 0, blend_override;
>
>         if (!rctx->blitter->running) {
>                 /* Flush depth textures which need to be flushed. */
> @@ -1052,7 +1064,16 @@ static void r600_update_derived_state(struct r600_context *rctx)
>
>         if (ps_dirty)
>                 r600_context_pipe_state_set(rctx, &rctx->ps_shader->current->rstate);
> -
> +
> +       blend_override = (rctx->dual_src_blend &&
> +                       rctx->ps_shader->current->nr_ps_color_outputs < 2);
> +
> +       if (blend_override != rctx->blend_override) {
> +               rctx->blend_override = blend_override;
> +               r600_bind_blend_state_internal(rctx,
> +                               blend_override ? rctx->no_blend : rctx->blend);
> +       }
> +
>         if (rctx->chip_class >= EVERGREEN) {
>                 evergreen_update_dual_export_state(rctx);
>         } else {
> --
> 1.7.11.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list