[Mesa-dev,109/140] radeonsi/gfx9: image descriptor changes in immutable fields

Submitted by Marek Olšák on March 20, 2017, 10:48 p.m.

Details

Message ID 1490050166-6119-18-git-send-email-maraeo@gmail.com
State Accepted
Commit d60f72a9f0e4a0ea04391731211c18e755e0346f
Headers show
Series "RadeonSI: Initial Vega10 support" ( rev: 28 ) in Mesa

Not browsing as part of any series.

Commit Message

Marek Olšák March 20, 2017, 10:48 p.m.
From: Marek Olšák <marek.olsak@amd.com>

The border color swizzle logic was copied from Vulkan. It doesn't make any
sense to me, but it passes all piglits except the stencil ones.
---
 src/amd/common/gfx9d.h                  |  6 ++++
 src/gallium/drivers/radeonsi/si_pipe.c  |  3 +-
 src/gallium/drivers/radeonsi/si_state.c | 56 ++++++++++++++++++++++++++++++---
 3 files changed, 60 insertions(+), 5 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/amd/common/gfx9d.h b/src/amd/common/gfx9d.h
index 797bdcc..e295a1d 100644
--- a/src/amd/common/gfx9d.h
+++ b/src/amd/common/gfx9d.h
@@ -1466,6 +1466,12 @@ 
 #define   S_008F20_BC_SWIZZLE(x)                                      (((unsigned)(x) & 0x07) << 29)
 #define   G_008F20_BC_SWIZZLE(x)                                      (((x) >> 29) & 0x07)
 #define   C_008F20_BC_SWIZZLE                                         0x1FFFFFFF
+#define     V_008F20_BC_SWIZZLE_XYZW					0
+#define     V_008F20_BC_SWIZZLE_XWYZ					1
+#define     V_008F20_BC_SWIZZLE_WZYX					2
+#define     V_008F20_BC_SWIZZLE_WXYZ					3
+#define     V_008F20_BC_SWIZZLE_ZYXW					4
+#define     V_008F20_BC_SWIZZLE_YXWZ					5
 #define R_008F24_SQ_IMG_RSRC_WORD5                                      0x008F24
 #define   S_008F24_BASE_ARRAY(x)                                      (((unsigned)(x) & 0x1FFF) << 0)
 #define   G_008F24_BASE_ARRAY(x)                                      (((x) >> 0) & 0x1FFF)
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index 8904b9d..5d3cbc5 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -497,7 +497,8 @@  static int si_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 		return 30;
 
 	case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
-		return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600;
+		return sscreen->b.chip_class <= VI ?
+			PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600 : 0;
 
 	/* Stream output. */
 	case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index f880c31..90f5c77 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -2932,6 +2932,35 @@  si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf,
 		   S_008F0C_DATA_FORMAT(data_format);
 }
 
+static unsigned gfx9_border_color_swizzle(const unsigned char swizzle[4])
+{
+	unsigned bc_swizzle = V_008F20_BC_SWIZZLE_XYZW;
+
+	if (swizzle[3] == PIPE_SWIZZLE_X) {
+		/* For the pre-defined border color values (white, opaque
+		 * black, transparent black), the only thing that matters is
+		 * that the alpha channel winds up in the correct place
+		 * (because the RGB channels are all the same) so either of
+		 * these enumerations will work.
+		 */
+		if (swizzle[2] == PIPE_SWIZZLE_Y)
+			bc_swizzle = V_008F20_BC_SWIZZLE_WZYX;
+		else
+			bc_swizzle = V_008F20_BC_SWIZZLE_WXYZ;
+	} else if (swizzle[0] == PIPE_SWIZZLE_X) {
+		if (swizzle[1] == PIPE_SWIZZLE_Y)
+			bc_swizzle = V_008F20_BC_SWIZZLE_XYZW;
+		else
+			bc_swizzle = V_008F20_BC_SWIZZLE_XWYZ;
+	} else if (swizzle[1] == PIPE_SWIZZLE_X) {
+		bc_swizzle = V_008F20_BC_SWIZZLE_YXWZ;
+	} else if (swizzle[2] == PIPE_SWIZZLE_X) {
+		bc_swizzle = V_008F20_BC_SWIZZLE_ZYXW;
+	}
+
+	return bc_swizzle;
+}
+
 /**
  * Build the sampler view descriptor for a texture.
  */
@@ -3097,14 +3126,33 @@  si_make_texture_descriptor(struct si_screen *screen,
 		    S_008F1C_LAST_LEVEL(res->nr_samples > 1 ?
 					util_logbase2(res->nr_samples) :
 					last_level) |
-		    S_008F1C_POW2_PAD(res->last_level > 0) |
 		    S_008F1C_TYPE(type));
-	state[4] = S_008F20_DEPTH(depth - 1);
-	state[5] = (S_008F24_BASE_ARRAY(first_layer) |
-		    S_008F24_LAST_ARRAY(last_layer));
+	state[4] = 0;
+	state[5] = S_008F24_BASE_ARRAY(first_layer);
 	state[6] = 0;
 	state[7] = 0;
 
+	if (screen->b.chip_class >= GFX9) {
+		unsigned bc_swizzle = gfx9_border_color_swizzle(desc->swizzle);
+
+		/* Depth is the the last accessible layer on Gfx9.
+		 * The hw doesn't need to know the total number of layers.
+		 */
+		if (type == V_008F1C_SQ_RSRC_IMG_3D)
+			state[4] |= S_008F20_DEPTH(depth - 1);
+		else
+			state[4] |= S_008F20_DEPTH(last_layer);
+
+		state[4] |= S_008F20_BC_SWIZZLE(bc_swizzle);
+		state[5] |= S_008F24_MAX_MIP(res->nr_samples > 1 ?
+					     util_logbase2(res->nr_samples) :
+					     tex->resource.b.b.last_level);
+	} else {
+		state[3] |= S_008F1C_POW2_PAD(res->last_level > 0);
+		state[4] |= S_008F20_DEPTH(depth - 1);
+		state[5] |= S_008F24_LAST_ARRAY(last_layer);
+	}
+
 	if (tex->dcc_offset) {
 		unsigned swap = r600_translate_colorswap(pipe_format, false);