From 146c2b7c28ad62e837a9ca8123c2829bd07ca77a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Nicolai=20H=C3=A4hnle?= Date: Tue, 26 Sep 2017 20:36:10 +0200 Subject: [PATCH] radeonsi: adjust clip discard based on line width / point size MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Marek Olšák --- src/gallium/drivers/radeonsi/si_state.c | 7 ++++- src/gallium/drivers/radeonsi/si_state.h | 2 ++ .../drivers/radeonsi/si_state_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 @@ -858,6 +858,7 @@ static void *si_create_rs_state(struct pipe_context *ctx, 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; @@ -897,6 +898,8 @@ static void *si_create_rs_state(struct pipe_context *ctx, 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)) | @@ -1007,7 +1010,9 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state) 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); } 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 @@ -68,6 +68,8 @@ struct si_state_rasterizer { 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; diff --git a/src/gallium/drivers/radeonsi/si_state_viewport.c b/src/gallium/drivers/radeonsi/si_state_viewport.c index 1201be8779e..a96eb8adc13 100644 --- a/src/gallium/drivers/radeonsi/si_state_viewport.c +++ b/src/gallium/drivers/radeonsi/si_state_viewport.c @@ -187,17 +187,26 @@ static void si_emit_guardband(struct si_context *ctx, 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. */ -- 2.30.2