r600g: properly implement S8Z24 depth-stencil format for Evergreen
authorMarek Olšák <maraeo@gmail.com>
Tue, 12 Feb 2013 22:09:44 +0000 (23:09 +0100)
committerMarek Olšák <maraeo@gmail.com>
Thu, 14 Feb 2013 13:51:46 +0000 (14:51 +0100)
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 <jglisse@redhat.com>
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_texture.c

index 29b22ab4c3483fe4c35f852b5b097cb2e4023e32..4d34d8ba1dd0ba84f670c0b6fea41912ab74e16a 100644 (file)
@@ -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:
index 3f359fb0dd79425bb7bf90d98344f429661d5ae4..ec06be6ae46b36eee52e2610604b9cd4eb6ccead 100644 (file)
@@ -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;
 
index 85fc887971dd48e186143043fe3f7747fec0631c..7f5752d81e6c401d719fd264d1f86f06fb319f57 100644 (file)
@@ -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