Mesa (master): radeonsi: adjust clip discard based on line width / point size

Nicolai Hähnle nh at kemper.freedesktop.org
Mon Oct 2 13:07:59 UTC 2017


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

Author: Nicolai Hähnle <nicolai.haehnle at amd.com>
Date:   Tue Sep 26 20:36:10 2017 +0200

radeonsi: adjust clip discard based on line width / point size

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

---

 src/gallium/drivers/radeonsi/si_state.c          |  7 +++++-
 src/gallium/drivers/radeonsi/si_state.h          |  2 ++
 src/gallium/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 78a3fbd086..4965a8374f 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 4388ea99da..8e414a0817 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 1201be8779..a96eb8adc1 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. */




More information about the mesa-commit mailing list