#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)
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.
*/
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);