diff options
author | Marek Olšák <[email protected]> | 2016-10-15 15:24:45 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2017-03-30 14:44:33 +0200 |
commit | d60f72a9f0e4a0ea04391731211c18e755e0346f (patch) | |
tree | 0b7a14bc0555db5bfa5de93b89b494bc46afcf4d /src/gallium/drivers/radeonsi | |
parent | dfd2b549488beb8af9c83255dfd5585b010ba4e3 (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/drivers/radeonsi')
-rw-r--r-- | src/gallium/drivers/radeonsi/si_pipe.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.c | 56 |
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); |