summaryrefslogtreecommitdiffstats
path: root/src/gallium
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/gallium
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/gallium')
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.c3
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c56
2 files changed, 54 insertions, 5 deletions
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);