From d60f72a9f0e4a0ea04391731211c18e755e0346f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 15 Oct 2016 15:24:45 +0200 Subject: [PATCH] radeonsi/gfx9: image descriptor changes in immutable fields MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- 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(-) 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); -- 2.30.2