[Mesa-dev] [PATCH 3/5] radeonsi: implement the simple case of force_persample_interp

Marek Olšák maraeo at gmail.com
Mon Sep 28 17:38:17 PDT 2015


From: Marek Olšák <marek.olsak at amd.com>

---
 src/gallium/drivers/radeonsi/si_pipe.h          |  1 +
 src/gallium/drivers/radeonsi/si_state.c         |  1 +
 src/gallium/drivers/radeonsi/si_state.h         |  1 +
 src/gallium/drivers/radeonsi/si_state_shaders.c | 35 ++++++++++++++++++++++++-
 4 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 11e8ce4..c0497ea 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -208,6 +208,7 @@ struct si_context {
 	struct si_vertex_element	*vertex_elements;
 	unsigned			sprite_coord_enable;
 	bool				flatshade;
+	bool				force_persample_interp;
 
 	/* shader descriptors */
 	struct si_descriptors		vertex_buffers;
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index d74f6e8..5c293a2 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -686,6 +686,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
 
 	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;
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index 2257499..6a56768 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -50,6 +50,7 @@ struct si_state_rasterizer {
 	bool			flatshade;
 	bool			two_side;
 	bool			multisample_enable;
+	bool			force_persample_interp;
 	bool			line_stipple_enable;
 	unsigned		sprite_coord_enable;
 	unsigned		pa_sc_line_stipple;
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index dd5fdc0..f7c258e 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -1067,6 +1067,36 @@ static void si_emit_spi_ps_input(struct si_context *sctx, struct r600_atom *atom
 	    G_0286CC_LINEAR_CENTROID_ENA(input_ena) ||
 	    G_0286CC_LINE_STIPPLE_TEX_ENA(input_ena));
 
+	if (sctx->force_persample_interp) {
+		unsigned num_persp = G_0286CC_PERSP_SAMPLE_ENA(input_ena) +
+				     G_0286CC_PERSP_CENTER_ENA(input_ena) +
+				     G_0286CC_PERSP_CENTROID_ENA(input_ena);
+		unsigned num_linear = G_0286CC_LINEAR_SAMPLE_ENA(input_ena) +
+				      G_0286CC_LINEAR_CENTER_ENA(input_ena) +
+				      G_0286CC_LINEAR_CENTROID_ENA(input_ena);
+
+		/* If only one set of (i,j) coordinates is used, we can disable
+		 * CENTER/CENTROID, enable SAMPLE and it will load SAMPLE coordinates
+		 * where CENTER/CENTROID are expected, effectively forcing per-sample
+		 * interpolation.
+		 */
+		if (num_persp == 1) {
+			input_ena &= C_0286CC_PERSP_CENTER_ENA;
+			input_ena &= C_0286CC_PERSP_CENTROID_ENA;
+			input_ena |= G_0286CC_PERSP_SAMPLE_ENA(1);
+		}
+		if (num_linear == 1) {
+			input_ena &= C_0286CC_LINEAR_CENTER_ENA;
+			input_ena &= C_0286CC_LINEAR_CENTROID_ENA;
+			input_ena |= G_0286CC_LINEAR_SAMPLE_ENA(1);
+		}
+
+		/* If at least 2 sets of coordinates are used, we can't use this
+		 * trick and have to select SAMPLE using a conditional assignment
+		 * in the shader with "force_persample_interp" being a shader constant.
+		 */
+	}
+
 	radeon_set_context_reg_seq(cs, R_0286CC_SPI_PS_INPUT_ENA, 2);
 	radeon_emit(cs, input_ena);
 	radeon_emit(cs, input_ena);
@@ -1543,8 +1573,11 @@ bool si_update_shaders(struct si_context *sctx)
 		si_mark_atom_dirty(sctx, &sctx->spi_map);
 	}
 
-	if (si_pm4_state_changed(sctx, ps))
+	if (si_pm4_state_changed(sctx, ps) ||
+	    sctx->force_persample_interp != rs->force_persample_interp) {
+		sctx->force_persample_interp = rs->force_persample_interp;
 		si_mark_atom_dirty(sctx, &sctx->spi_ps_input);
+	}
 
 	if (si_pm4_state_changed(sctx, ls) ||
 	    si_pm4_state_changed(sctx, hs) ||
-- 
2.1.4



More information about the mesa-dev mailing list