summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2016-10-15 15:24:45 +0200
committerMarek Olšák <[email protected]>2017-03-30 14:44:33 +0200
commitd60f72a9f0e4a0ea04391731211c18e755e0346f (patch)
tree0b7a14bc0555db5bfa5de93b89b494bc46afcf4d /src
parentdfd2b549488beb8af9c83255dfd5585b010ba4e3 (diff)
radeonsi/gfx9: image descriptor changes in immutable fields
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. Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/amd/common/gfx9d.h6
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.c3
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c56
3 files changed, 60 insertions, 5 deletions
diff --git a/src/amd/common/gfx9d.h b/src/amd/common/gfx9d.h
index 797bdcc2876..e295a1da820 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 8904b9df952..5d3cbc5bc37 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 1e17840d64f..0b0e25fb1f9 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);