[Mesa-dev] [PATCH 11/11] radeonsi: adjust clip discard based on line width / point size

Marek Olšák maraeo at gmail.com
Fri Sep 29 16:06:13 UTC 2017


For the series:

Reviewed-by: Marek Olšák <marek.olsak at amd.com>

Marek

On Fri, Sep 29, 2017 at 1:01 PM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> ---
>  src/gallium/drivers/radeonsi/si_state.c    |  7 ++++++-
>  src/gallium/drivers/radeonsi/si_state.h    |  2 ++
>  src/gallium/drivers/radeonsi/si_viewport.c | 29 +++++++++++++++++++----------
>  3 files changed, 27 insertions(+), 11 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
> index 78a3fbd086e..4965a8374ff 100644
> --- a/src/gallium/drivers/radeonsi/si_state.c
> +++ b/src/gallium/drivers/radeonsi/si_state.c
> @@ -851,20 +851,21 @@ static void *si_create_rs_state(struct pipe_context *ctx,
>
>         rs->scissor_enable = state->scissor;
>         rs->clip_halfz = state->clip_halfz;
>         rs->two_side = state->light_twoside;
>         rs->multisample_enable = state->multisample;
>         rs->force_persample_interp = state->force_persample_interp;
>         rs->clip_plane_enable = state->clip_plane_enable;
>         rs->line_stipple_enable = state->line_stipple_enable;
>         rs->poly_stipple_enable = state->poly_stipple_enable;
>         rs->line_smooth = state->line_smooth;
> +       rs->line_width = state->line_width;
>         rs->poly_smooth = state->poly_smooth;
>         rs->uses_poly_offset = state->offset_point || state->offset_line ||
>                                state->offset_tri;
>         rs->clamp_fragment_color = state->clamp_fragment_color;
>         rs->clamp_vertex_color = state->clamp_vertex_color;
>         rs->flatshade = state->flatshade;
>         rs->sprite_coord_enable = state->sprite_coord_enable;
>         rs->rasterizer_discard = state->rasterizer_discard;
>         rs->pa_sc_line_stipple = state->line_stipple_enable ?
>                                 S_028A0C_LINE_PATTERN(state->line_stipple_pattern) |
> @@ -890,20 +891,22 @@ static void *si_create_rs_state(struct pipe_context *ctx,
>         si_pm4_set_reg(pm4, R_028A00_PA_SU_POINT_SIZE, S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp));
>
>         if (state->point_size_per_vertex) {
>                 psize_min = util_get_min_point_size(state);
>                 psize_max = 8192;
>         } else {
>                 /* Force the point size to be as if the vertex output was disabled. */
>                 psize_min = state->point_size;
>                 psize_max = state->point_size;
>         }
> +       rs->max_point_size = psize_max;
> +
>         /* Divide by two, because 0.5 = 1 pixel. */
>         si_pm4_set_reg(pm4, R_028A04_PA_SU_POINT_MINMAX,
>                         S_028A04_MIN_SIZE(si_pack_float_12p4(psize_min/2)) |
>                         S_028A04_MAX_SIZE(si_pack_float_12p4(psize_max/2)));
>
>         si_pm4_set_reg(pm4, R_028A08_PA_SU_LINE_CNTL,
>                        S_028A08_WIDTH(si_pack_float_12p4(state->line_width/2)));
>         si_pm4_set_reg(pm4, R_028A48_PA_SC_MODE_CNTL_0,
>                        S_028A48_LINE_STIPPLE_ENABLE(state->line_stipple_enable) |
>                        S_028A48_MSAA_ENABLE(state->multisample ||
> @@ -1000,21 +1003,23 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
>                         si_mark_atom_dirty(sctx, &sctx->msaa_sample_locs.atom);
>         }
>
>         sctx->current_vs_state &= C_VS_STATE_CLAMP_VERTEX_COLOR;
>         sctx->current_vs_state |= S_VS_STATE_CLAMP_VERTEX_COLOR(rs->clamp_vertex_color);
>
>         si_pm4_bind_state(sctx, rasterizer, rs);
>         si_update_poly_offset_state(sctx);
>
>         if (!old_rs ||
> -           old_rs->scissor_enable != rs->scissor_enable) {
> +           (old_rs->scissor_enable != rs->scissor_enable ||
> +            old_rs->line_width != rs->line_width ||
> +            old_rs->max_point_size != rs->max_point_size)) {
>                 sctx->scissors.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
>                 si_mark_atom_dirty(sctx, &sctx->scissors.atom);
>         }
>
>         if (!old_rs ||
>             old_rs->clip_halfz != rs->clip_halfz) {
>                 sctx->viewports.depth_range_dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
>                 si_mark_atom_dirty(sctx, &sctx->viewports.atom);
>         }
>
> diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
> index 4388ea99daf..8e414a0817c 100644
> --- a/src/gallium/drivers/radeonsi/si_state.h
> +++ b/src/gallium/drivers/radeonsi/si_state.h
> @@ -61,20 +61,22 @@ struct si_state_blend {
>         bool                    dual_src_blend:1;
>         bool                    logicop_enable:1;
>  };
>
>  struct si_state_rasterizer {
>         struct si_pm4_state     pm4;
>         /* poly offset states for 16-bit, 24-bit, and 32-bit zbuffers */
>         struct si_pm4_state     *pm4_poly_offset;
>         unsigned                pa_sc_line_stipple;
>         unsigned                pa_cl_clip_cntl;
> +       float                   line_width;
> +       float                   max_point_size;
>         unsigned                sprite_coord_enable:8;
>         unsigned                clip_plane_enable:8;
>         unsigned                flatshade:1;
>         unsigned                two_side:1;
>         unsigned                multisample_enable:1;
>         unsigned                force_persample_interp:1;
>         unsigned                line_stipple_enable:1;
>         unsigned                poly_stipple_enable:1;
>         unsigned                line_smooth:1;
>         unsigned                poly_smooth:1;
> diff --git a/src/gallium/drivers/radeonsi/si_viewport.c b/src/gallium/drivers/radeonsi/si_viewport.c
> index 6a6b0823e13..a1b34b16df5 100644
> --- a/src/gallium/drivers/radeonsi/si_viewport.c
> +++ b/src/gallium/drivers/radeonsi/si_viewport.c
> @@ -181,31 +181,40 @@ static void si_emit_guardband(struct si_context *ctx,
>         bottom = ( max_range - vp.translate[1]) / vp.scale[1];
>
>         assert(left <= -1 && top <= -1 && right >= 1 && bottom >= 1);
>
>         guardband_x = MIN2(-left, right);
>         guardband_y = MIN2(-top, bottom);
>
>         discard_x = 1.0;
>         discard_y = 1.0;
>
> -       if (ctx->current_rast_prim < PIPE_PRIM_TRIANGLES) {
> +       if (unlikely(ctx->current_rast_prim < PIPE_PRIM_TRIANGLES) &&
> +           ctx->queued.named.rasterizer) {
>                 /* When rendering wide points or lines, we need to be more
> -                * conservative about when to discard them entirely. Since
> -                * point size can be determined by the VS output, we basically
> -                * disable discard completely completely here.
> -                *
> -                * TODO: This can hurt performance when rendering lines and
> -                * points with fixed size, and could be improved.
> -                */
> -               discard_x = guardband_x;
> -               discard_y = guardband_y;
> +                * conservative about when to discard them entirely. */
> +               const struct si_state_rasterizer *rs = ctx->queued.named.rasterizer;
> +               float pixels;
> +
> +               if (ctx->current_rast_prim == PIPE_PRIM_POINTS)
> +                       pixels = rs->max_point_size;
> +               else
> +                       pixels = rs->line_width;
> +
> +               /* Add half the point size / line width */
> +               discard_x += pixels / (2.0 * vp.scale[0]);
> +               discard_y += pixels / (2.0 * vp.scale[1]);
> +
> +               /* Discard primitives that would lie entirely outside the clip
> +                * region. */
> +               discard_x = MIN2(discard_x, guardband_x);
> +               discard_y = MIN2(discard_y, guardband_y);
>         }
>
>         /* If any of the GB registers is updated, all of them must be updated. */
>         radeon_set_context_reg_seq(cs, R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, 4);
>
>         radeon_emit(cs, fui(guardband_y)); /* R_028BE8_PA_CL_GB_VERT_CLIP_ADJ */
>         radeon_emit(cs, fui(discard_y));   /* R_028BEC_PA_CL_GB_VERT_DISC_ADJ */
>         radeon_emit(cs, fui(guardband_x)); /* R_028BF0_PA_CL_GB_HORZ_CLIP_ADJ */
>         radeon_emit(cs, fui(discard_x));   /* R_028BF4_PA_CL_GB_HORZ_DISC_ADJ */
>  }
> --
> 2.11.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list