Mesa (master): radeonsi: fix border color translation for integer textures

Nicolai Hähnle nh at kemper.freedesktop.org
Fri Sep 29 09:45:52 UTC 2017


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

Author: Nicolai Hähnle <nicolai.haehnle at amd.com>
Date:   Sat Sep 23 14:19:59 2017 +0200

radeonsi: fix border color translation for integer textures

This fixes the extremely unlikely case that an application uses
0x80000000 or 0x3f800000 as border color for an integer texture and
helps in the also, but perhaps slightly less, unlikely case that 1 is
used as a border color.

Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Tested-by: Dieter Nützel <Dieter at nuetzel-hh.de>

---

 src/gallium/drivers/radeonsi/si_descriptors.c | 37 ++++++++++++--------
 src/gallium/drivers/radeonsi/si_pipe.h        |  2 ++
 src/gallium/drivers/radeonsi/si_state.c       | 50 +++++++++++++++++++--------
 3 files changed, 60 insertions(+), 29 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index fbb72d900b..1afdfbe4f6 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -379,6 +379,20 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen,
 	}
 }
 
+static void si_set_sampler_state_desc(struct si_sampler_state *sstate,
+				      struct si_sampler_view *sview,
+				      struct r600_texture *tex,
+				      uint32_t *desc)
+{
+	if (sview && sview->is_integer)
+		memcpy(desc, sstate->integer_val, 4*4);
+	else if (tex && tex->upgraded_depth &&
+		 (!sview || !sview->is_stencil_sampler))
+		memcpy(desc, sstate->upgraded_depth_val, 4*4);
+	else
+		memcpy(desc, sstate->val, 4*4);
+}
+
 static void si_set_sampler_view_desc(struct si_context *sctx,
 				     struct si_sampler_view *sview,
 				     struct si_sampler_state *sstate,
@@ -422,13 +436,10 @@ static void si_set_sampler_view_desc(struct si_context *sctx,
 		/* Disable FMASK and bind sampler state in [12:15]. */
 		memcpy(desc + 8, null_texture_descriptor, 4*4);
 
-		if (sstate) {
-			if (!is_buffer && rtex->upgraded_depth &&
-			    !sview->is_stencil_sampler)
-				memcpy(desc + 12, sstate->upgraded_depth_val, 4*4);
-			else
-				memcpy(desc + 12, sstate->val, 4*4);
-		}
+		if (sstate)
+			si_set_sampler_state_desc(sstate, sview,
+						  is_buffer ? NULL : rtex,
+						  desc + 12);
 	}
 }
 
@@ -470,8 +481,8 @@ static void si_set_sampler_view(struct si_context *sctx,
 		memcpy(desc + 8, null_texture_descriptor, 4*4);
 		/* Re-set the sampler state if we are transitioning from FMASK. */
 		if (views->sampler_states[slot])
-			memcpy(desc + 12,
-			       views->sampler_states[slot]->val, 4*4);
+			si_set_sampler_state_desc(views->sampler_states[slot], NULL, NULL,
+						  desc + 12);
 
 		views->enabled_mask &= ~(1u << slot);
 	}
@@ -862,12 +873,8 @@ static void si_bind_sampler_states(struct pipe_context *ctx,
 		if (tex && tex->fmask.size)
 			continue;
 
-		if (tex && tex->upgraded_depth && !sview->is_stencil_sampler)
-			memcpy(desc->list + desc_slot * 16 + 12,
-			       sstates[i]->upgraded_depth_val, 4*4);
-		else
-			memcpy(desc->list + desc_slot * 16 + 12,
-			       sstates[i]->val, 4*4);
+		si_set_sampler_state_desc(sstates[i], sview, tex,
+					  desc->list + desc_slot * 16 + 12);
 
 		sctx->descriptors_dirty |= 1u << si_sampler_and_image_descriptors_idx(shader);
 	}
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index 80f38ea29b..46c89e2f38 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -157,6 +157,7 @@ struct si_sampler_view {
 	ubyte				base_level;
 	ubyte				block_width;
 	bool is_stencil_sampler;
+	bool is_integer;
 	bool dcc_incompatible;
 };
 
@@ -167,6 +168,7 @@ struct si_sampler_state {
 	unsigned			magic;
 #endif
 	uint32_t			val[4];
+	uint32_t			integer_val[4];
 	uint32_t			upgraded_depth_val[4];
 };
 
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 1463d3c9ca..e82ca6a694 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -3861,6 +3861,12 @@ si_create_sampler_view_custom(struct pipe_context *ctx,
 				   width, height, depth,
 				   view->state, view->fmask_state);
 
+	unsigned num_format = G_008F14_NUM_FORMAT_GFX6(view->state[1]);
+	view->is_integer =
+		num_format == V_008F14_IMG_NUM_FORMAT_USCALED ||
+		num_format == V_008F14_IMG_NUM_FORMAT_SSCALED ||
+		num_format == V_008F14_IMG_NUM_FORMAT_UINT ||
+		num_format == V_008F14_IMG_NUM_FORMAT_SINT;
 	view->base_level_info = &surflevel[base_level];
 	view->base_level = base_level;
 	view->block_width = util_format_get_blockwidth(pipe_format);
@@ -3897,24 +3903,36 @@ static bool wrap_mode_uses_border_color(unsigned wrap, bool linear_filter)
 
 static uint32_t si_translate_border_color(struct si_context *sctx,
 					  const struct pipe_sampler_state *state,
-					  const union pipe_color_union *color)
+					  const union pipe_color_union *color,
+					  bool is_integer)
 {
 	bool linear_filter = state->min_img_filter != PIPE_TEX_FILTER_NEAREST ||
 			     state->mag_img_filter != PIPE_TEX_FILTER_NEAREST;
 
-	if ((color->f[0] == 0 && color->f[1] == 0 &&
-	     color->f[2] == 0 && color->f[3] == 0) ||
-	    (!wrap_mode_uses_border_color(state->wrap_s, linear_filter) &&
-	     !wrap_mode_uses_border_color(state->wrap_t, linear_filter) &&
-	     !wrap_mode_uses_border_color(state->wrap_r, linear_filter)))
+	if (!wrap_mode_uses_border_color(state->wrap_s, linear_filter) &&
+	    !wrap_mode_uses_border_color(state->wrap_t, linear_filter) &&
+	    !wrap_mode_uses_border_color(state->wrap_r, linear_filter))
 		return S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK);
 
-	if (color->f[0] == 0 && color->f[1] == 0 &&
-	    color->f[2] == 0 && color->f[3] == 1)
-		return S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK);
-	if (color->f[0] == 1 && color->f[1] == 1 &&
-	    color->f[2] == 1 && color->f[3] == 1)
-		return S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE);
+#define simple_border_types(elt) \
+do { \
+	if (color->elt[0] == 0 && color->elt[1] == 0 &&                         \
+	    color->elt[2] == 0 && color->elt[3] == 0)                           \
+		return S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK); \
+	if (color->elt[0] == 0 && color->elt[1] == 0 &&                         \
+	    color->elt[2] == 0 && color->elt[3] == 1)                           \
+		return S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK); \
+	if (color->elt[0] == 1 && color->elt[1] == 1 &&                         \
+	    color->elt[2] == 1 && color->elt[3] == 1)                           \
+		return S_008F3C_BORDER_COLOR_TYPE(V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE); \
+} while (false)
+
+	if (is_integer)
+		simple_border_types(ui);
+	else
+		simple_border_types(f);
+
+#undef simple_border_types
 
 	int i;
 
@@ -3984,7 +4002,11 @@ static void *si_create_sampler_state(struct pipe_context *ctx,
 			  S_008F38_DISABLE_LSB_CEIL(sctx->b.chip_class <= VI) |
 			  S_008F38_FILTER_PREC_FIX(1) |
 			  S_008F38_ANISO_OVERRIDE(sctx->b.chip_class >= VI));
-	rstate->val[3] = si_translate_border_color(sctx, state, &state->border_color);
+	rstate->val[3] = si_translate_border_color(sctx, state, &state->border_color, false);
+
+	/* Create sampler resource for integer textures. */
+	memcpy(rstate->integer_val, rstate->val, sizeof(rstate->val));
+	rstate->integer_val[3] = si_translate_border_color(sctx, state, &state->border_color, true);
 
 	/* Create sampler resource for upgraded depth textures. */
 	memcpy(rstate->upgraded_depth_val, rstate->val, sizeof(rstate->val));
@@ -3999,7 +4021,7 @@ static void *si_create_sampler_state(struct pipe_context *ctx,
 		rstate->upgraded_depth_val[3] |= S_008F3C_UPGRADED_DEPTH(1);
 	else
 		rstate->upgraded_depth_val[3] =
-			si_translate_border_color(sctx, state, &clamped_border_color) |
+			si_translate_border_color(sctx, state, &clamped_border_color, false) |
 			S_008F3C_UPGRADED_DEPTH(1);
 
 	return rstate;




More information about the mesa-commit mailing list