From 2b9659c9e627ad03160899b8be04f96307d098eb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 12 Feb 2013 23:09:44 +0100 Subject: [PATCH] r600g: properly implement S8Z24 depth-stencil format for Evergreen I should say "fix", but it has never been used until now. S8Z24 is the format equivalent to the GL_UNSIGNED_INT_24_8 packing, so we'll start to see it more often with st/mesa now making smart decisions about formats. The DB<->CB copy can change the channel ordering for transfers, other than that, the internal DB format doesn't really matter. R600-R700 support is possible except shadow mapping. FMT_24_8 is broken if the SAMPLE_C instruction is used (no idea why). Also the sampler swizzling was broken in theory and the fact it worked was a lucky coincidence. radeonsi might need to port this. Reviewed-by: Jerome Glisse --- src/gallium/drivers/r600/evergreen_state.c | 13 ++++++++- src/gallium/drivers/r600/r600_state.c | 8 ------ src/gallium/drivers/r600/r600_texture.c | 44 ++++++++++++++++++++++++------ 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 29b22ab..4d34d8b 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -200,6 +200,8 @@ static uint32_t r600_translate_dbformat(enum pipe_format format) return V_028040_Z_16; case PIPE_FORMAT_Z24X8_UNORM: case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8_UINT_Z24_UNORM: return V_028040_Z_24; case PIPE_FORMAT_Z32_FLOAT: case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: @@ -339,7 +341,7 @@ static uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_X8Z24_UNORM: case PIPE_FORMAT_S8_UINT_Z24_UNORM: - return V_028C70_SWAP_STD; + return V_028C70_SWAP_STD_REV; case PIPE_FORMAT_R10G10B10A2_UNORM: case PIPE_FORMAT_R10G10B10X2_SNORM: @@ -1106,6 +1108,11 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx, case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: pipe_format = PIPE_FORMAT_Z32_FLOAT; break; + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8_UINT_Z24_UNORM: + /* Z24 is always stored like this. */ + pipe_format = PIPE_FORMAT_Z24X8_UNORM; + break; case PIPE_FORMAT_X24S8_UINT: case PIPE_FORMAT_S8X24_UINT: case PIPE_FORMAT_X32_S8X24_UINT: @@ -1603,6 +1610,8 @@ static void evergreen_init_depth_surface(struct r600_context *rctx, switch (surf->base.format) { case PIPE_FORMAT_Z24X8_UNORM: case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8_UINT_Z24_UNORM: surf->pa_su_poly_offset_db_fmt_cntl = S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS((char)-24); break; @@ -2179,6 +2188,8 @@ static void evergreen_emit_polygon_offset(struct r600_context *rctx, struct r600 switch (state->zs_format) { case PIPE_FORMAT_Z24X8_UNORM: case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8_UINT_Z24_UNORM: offset_units *= 2.0f; break; case PIPE_FORMAT_Z16_UNORM: diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 3f359fb..ec06be6 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -270,10 +270,6 @@ static uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_Z24_UNORM_S8_UINT: return V_0280A0_SWAP_STD; - case PIPE_FORMAT_X8Z24_UNORM: - case PIPE_FORMAT_S8_UINT_Z24_UNORM: - return V_0280A0_SWAP_STD; - case PIPE_FORMAT_R10G10B10A2_UNORM: case PIPE_FORMAT_R10G10B10X2_SNORM: case PIPE_FORMAT_R10SG10SB10SA2U_NORM: @@ -440,10 +436,6 @@ static uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_Z24_UNORM_S8_UINT: return V_0280A0_COLOR_8_24; - case PIPE_FORMAT_X8Z24_UNORM: - case PIPE_FORMAT_S8_UINT_Z24_UNORM: - return V_0280A0_COLOR_24_8; - case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: return V_0280A0_COLOR_X24_8_32_FLOAT; diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 85fc887..7f5752d 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -985,11 +985,14 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, const unsigned char *swizzle_view, uint32_t *word4_p, uint32_t *yuv_format_p) { + struct r600_screen *rscreen = (struct r600_screen *)screen; uint32_t result = 0, word4 = 0, yuv_format = 0; const struct util_format_description *desc; boolean uniform = TRUE; static int r600_enable_s3tc = -1; bool is_srgb_valid = FALSE; + const unsigned char swizzle_xxxx[4] = {0, 0, 0, 0}; + const unsigned char swizzle_yyyy[4] = {1, 1, 1, 1}; int i; const uint32_t sign_bit[4] = { @@ -1000,38 +1003,62 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, }; desc = util_format_description(format); - word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view, FALSE); + /* Depth and stencil swizzling is handled separately. */ + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) { + word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view, FALSE); + } /* Colorspace (return non-RGB formats directly). */ switch (desc->colorspace) { /* Depth stencil formats */ case UTIL_FORMAT_COLORSPACE_ZS: switch (format) { + /* Depth sampler formats. */ case PIPE_FORMAT_Z16_UNORM: + word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); result = FMT_16; goto out_word4; - case PIPE_FORMAT_X24S8_UINT: - word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); case PIPE_FORMAT_Z24X8_UNORM: case PIPE_FORMAT_Z24_UNORM_S8_UINT: + word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); result = FMT_8_24; goto out_word4; - case PIPE_FORMAT_S8X24_UINT: - word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); case PIPE_FORMAT_X8Z24_UNORM: case PIPE_FORMAT_S8_UINT_Z24_UNORM: + if (rscreen->chip_class < EVERGREEN) + goto out_unknown; + word4 |= r600_get_swizzle_combined(swizzle_yyyy, swizzle_view, FALSE); result = FMT_24_8; goto out_word4; + case PIPE_FORMAT_Z32_FLOAT: + word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); + result = FMT_32_FLOAT; + goto out_word4; + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); + result = FMT_X24_8_32_FLOAT; + goto out_word4; + /* Stencil sampler formats. */ case PIPE_FORMAT_S8_UINT: + word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); + word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); result = FMT_8; + goto out_word4; + case PIPE_FORMAT_X24S8_UINT: word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); + word4 |= r600_get_swizzle_combined(swizzle_yyyy, swizzle_view, FALSE); + result = FMT_8_24; goto out_word4; - case PIPE_FORMAT_Z32_FLOAT: - result = FMT_32_FLOAT; + case PIPE_FORMAT_S8X24_UINT: + if (rscreen->chip_class < EVERGREEN) + goto out_unknown; + word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); + word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); + result = FMT_24_8; goto out_word4; case PIPE_FORMAT_X32_S8X24_UINT: word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); - case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + word4 |= r600_get_swizzle_combined(swizzle_yyyy, swizzle_view, FALSE); result = FMT_X24_8_32_FLOAT; goto out_word4; default: @@ -1057,7 +1084,6 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, } if (r600_enable_s3tc == -1) { - struct r600_screen *rscreen = (struct r600_screen *)screen; if (rscreen->info.drm_minor >= 9) r600_enable_s3tc = 1; else -- 2.7.4