radeonsi/gfx9: image descriptor changes in immutable fields
authorMarek Olšák <marek.olsak@amd.com>
Sat, 15 Oct 2016 13:24:45 +0000 (15:24 +0200)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 30 Mar 2017 12:44:33 +0000 (14:44 +0200)
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 <nicolai.haehnle@amd.com>
src/amd/common/gfx9d.h
src/gallium/drivers/radeonsi/si_pipe.c
src/gallium/drivers/radeonsi/si_state.c

index 797bdcc2876b9dbe8f5b7dc1c2b00a35237d4a6d..e295a1da820b8e0c7f881cc0e160f084e8f77ec9 100644 (file)
 #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)
index 8904b9df95232c21026733de6ae1e52c5a759aba..5d3cbc5bc37587f4a193a49d1ce0c31e216e57c1 100644 (file)
@@ -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:
index 1e17840d64f678e2a7aa9b79437040a4c3e45e5b..0b0e25fb1f953fa73f2326713f6404d275e2728d 100644 (file)
@@ -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);