OSDN Git Service

r600: refactor out CB setup.
authorDave Airlie <airlied@redhat.com>
Thu, 31 Mar 2016 05:27:42 +0000 (15:27 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 15 Mar 2017 04:33:23 +0000 (14:33 +1000)
This moves the code to create CB info out into
a separate function so it can be reused in images
code to create RATs.

Reviewed-by: Edward O'Callaghan <funfunctor@folklore1984.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r600/evergreen_state.c

index 5cb95f8..4d86570 100644 (file)
@@ -997,95 +997,63 @@ static void evergreen_get_scissor_rect(struct r600_context *rctx,
        *br = S_028244_BR_X(scissor.maxx) | S_028244_BR_Y(scissor.maxy);
 }
 
-/**
- * This function intializes the CB* register values for RATs.  It is meant
- * to be used for 1D aligned buffers that do not have an associated
- * radeon_surf.
- */
-void evergreen_init_color_surface_rat(struct r600_context *rctx,
-                                       struct r600_surface *surf)
-{
-       struct pipe_resource *pipe_buffer = surf->base.texture;
-       unsigned format = r600_translate_colorformat(rctx->b.chip_class,
-                                                    surf->base.format, FALSE);
-       unsigned endian = r600_colorformat_endian_swap(format, FALSE);
-       unsigned swap = r600_translate_colorswap(surf->base.format, FALSE);
-       unsigned block_size =
-               align(util_format_get_blocksize(pipe_buffer->format), 4);
-       unsigned pitch_alignment =
-               MAX2(64, rctx->screen->b.info.pipe_interleave_bytes / block_size);
-       unsigned pitch = align(pipe_buffer->width0, pitch_alignment);
-
-       surf->cb_color_base = r600_resource(pipe_buffer)->gpu_address >> 8;
-
-       surf->cb_color_pitch = (pitch / 8) - 1;
-
-       surf->cb_color_slice = 0;
-
-       surf->cb_color_view = 0;
-
-       surf->cb_color_info =
-                 S_028C70_ENDIAN(endian)
-               | S_028C70_FORMAT(format)
-               | S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED)
-               | S_028C70_NUMBER_TYPE(V_028C70_NUMBER_UINT)
-               | S_028C70_COMP_SWAP(swap)
-               | S_028C70_BLEND_BYPASS(1) /* We must set this bit because we
-                                           * are using NUMBER_UINT */
-               | S_028C70_RAT(1)
-               ;
-
-       surf->cb_color_attrib = S_028C74_NON_DISP_TILING_ORDER(1);
-
-       /* For buffers, CB_COLOR0_DIM needs to be set to the number of
-        * elements. */
-       surf->cb_color_dim = pipe_buffer->width0;
-
-       /* Set the buffer range the GPU will have access to: */
-       util_range_add(&r600_resource(pipe_buffer)->valid_buffer_range,
-                      0, pipe_buffer->width0);
-
-       surf->cb_color_fmask = surf->cb_color_base;
-       surf->cb_color_fmask_slice = 0;
-}
+struct r600_tex_color_info {
+       unsigned info;
+       unsigned view;
+       unsigned dim;
+       unsigned pitch;
+       unsigned slice;
+       unsigned attrib;
+       unsigned ntype;
+       unsigned fmask;
+       unsigned fmask_slice;
+       uint64_t offset;
+       boolean export_16bpc;
+};
 
-void evergreen_init_color_surface(struct r600_context *rctx,
-                                 struct r600_surface *surf)
+static void evergreen_set_color_surface_common(struct r600_context *rctx,
+                                              struct r600_texture *rtex,
+                                              unsigned level,
+                                              unsigned first_layer,
+                                              unsigned last_layer,
+                                              enum pipe_format pformat,
+                                              struct r600_tex_color_info *color)
 {
        struct r600_screen *rscreen = rctx->screen;
-       struct r600_texture *rtex = (struct r600_texture*)surf->base.texture;
-       unsigned level = surf->base.u.tex.level;
        unsigned pitch, slice;
-       unsigned color_info, color_attrib, color_dim = 0, color_view;
-       unsigned format, swap, ntype, endian;
-       uint64_t offset, base_offset;
        unsigned non_disp_tiling, macro_aspect, tile_split, bankh, bankw, fmask_bankh, nbanks;
+       unsigned format, swap, ntype, endian;
        const struct util_format_description *desc;
-       int i;
        bool blend_clamp = 0, blend_bypass = 0, do_endian_swap = FALSE;
+       int i;
+
+       color->offset = rtex->surface.level[level].offset;
+       color->view = S_028C6C_SLICE_START(first_layer) |
+                       S_028C6C_SLICE_MAX(last_layer);
 
-       offset = rtex->surface.level[level].offset;
-       color_view = S_028C6C_SLICE_START(surf->base.u.tex.first_layer) |
-                    S_028C6C_SLICE_MAX(surf->base.u.tex.last_layer);
+       color->offset += rtex->resource.gpu_address;
+       color->offset >>= 8;
 
+       color->dim = 0;
        pitch = (rtex->surface.level[level].nblk_x) / 8 - 1;
        slice = (rtex->surface.level[level].nblk_x * rtex->surface.level[level].nblk_y) / 64;
        if (slice) {
                slice = slice - 1;
        }
-       color_info = 0;
+
+       color->info = 0;
        switch (rtex->surface.level[level].mode) {
        default:
        case RADEON_SURF_MODE_LINEAR_ALIGNED:
-               color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED);
+               color->info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED);
                non_disp_tiling = 1;
                break;
        case RADEON_SURF_MODE_1D:
-               color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_1D_TILED_THIN1);
+               color->info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_1D_TILED_THIN1);
                non_disp_tiling = rtex->non_disp_tiling;
                break;
        case RADEON_SURF_MODE_2D:
-               color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_2D_TILED_THIN1);
+               color->info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_2D_TILED_THIN1);
                non_disp_tiling = rtex->non_disp_tiling;
                break;
        }
@@ -1103,34 +1071,32 @@ void evergreen_init_color_surface(struct r600_context *rctx,
        bankh = eg_bank_wh(bankh);
        fmask_bankh = eg_bank_wh(fmask_bankh);
 
-       /* 128 bit formats require tile type = 1 */
        if (rscreen->b.chip_class == CAYMAN) {
-               if (util_format_get_blocksize(surf->base.format) >= 16)
+               if (util_format_get_blocksize(pformat) >= 16)
                        non_disp_tiling = 1;
        }
        nbanks = eg_num_banks(rscreen->b.info.r600_num_banks);
-       desc = util_format_description(surf->base.format);
+       desc = util_format_description(pformat);
        for (i = 0; i < 4; i++) {
                if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
                        break;
                }
        }
-
-       color_attrib = S_028C74_TILE_SPLIT(tile_split)|
-                       S_028C74_NUM_BANKS(nbanks) |
-                       S_028C74_BANK_WIDTH(bankw) |
-                       S_028C74_BANK_HEIGHT(bankh) |
-                       S_028C74_MACRO_TILE_ASPECT(macro_aspect) |
-                       S_028C74_NON_DISP_TILING_ORDER(non_disp_tiling) |
-                       S_028C74_FMASK_BANK_HEIGHT(fmask_bankh);
+       color->attrib = S_028C74_TILE_SPLIT(tile_split)|
+               S_028C74_NUM_BANKS(nbanks) |
+               S_028C74_BANK_WIDTH(bankw) |
+               S_028C74_BANK_HEIGHT(bankh) |
+               S_028C74_MACRO_TILE_ASPECT(macro_aspect) |
+               S_028C74_NON_DISP_TILING_ORDER(non_disp_tiling) |
+               S_028C74_FMASK_BANK_HEIGHT(fmask_bankh);
 
        if (rctx->b.chip_class == CAYMAN) {
-               color_attrib |= S_028C74_FORCE_DST_ALPHA_1(desc->swizzle[3] ==
+               color->attrib |= S_028C74_FORCE_DST_ALPHA_1(desc->swizzle[3] ==
                                                           PIPE_SWIZZLE_1);
 
                if (rtex->resource.b.b.nr_samples > 1) {
                        unsigned log_samples = util_logbase2(rtex->resource.b.b.nr_samples);
-                       color_attrib |= S_028C74_NUM_SAMPLES(log_samples) |
+                       color->attrib |= S_028C74_NUM_SAMPLES(log_samples) |
                                        S_028C74_NUM_FRAGMENTS(log_samples);
                }
        }
@@ -1153,11 +1119,9 @@ void evergreen_init_color_surface(struct r600_context *rctx,
        if (R600_BIG_ENDIAN)
                do_endian_swap = !rtex->db_compatible;
 
-       format = r600_translate_colorformat(rctx->b.chip_class, surf->base.format,
-                                                     do_endian_swap);
+       format = r600_translate_colorformat(rctx->b.chip_class, pformat, do_endian_swap);
        assert(format != ~0);
-
-       swap = r600_translate_colorswap(surf->base.format, do_endian_swap);
+       swap = r600_translate_colorswap(pformat, do_endian_swap);
        assert(swap != ~0);
 
        endian = r600_colorformat_endian_swap(format, do_endian_swap);
@@ -1176,52 +1140,127 @@ void evergreen_init_color_surface(struct r600_context *rctx,
                blend_bypass = 1;
        }
 
-       surf->alphatest_bypass = ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT;
-
-       color_info |= S_028C70_FORMAT(format) |
+       color->ntype = ntype;
+       color->info |= S_028C70_FORMAT(format) |
                S_028C70_COMP_SWAP(swap) |
                S_028C70_BLEND_CLAMP(blend_clamp) |
                S_028C70_BLEND_BYPASS(blend_bypass) |
                S_028C70_NUMBER_TYPE(ntype) |
                S_028C70_ENDIAN(endian);
 
+       if (rtex->fmask.size) {
+               color->info |= S_028C70_COMPRESSION(1);
+       }
+
        /* EXPORT_NORM is an optimzation that can be enabled for better
         * performance in certain cases.
         * EXPORT_NORM can be enabled if:
         * - 11-bit or smaller UNORM/SNORM/SRGB
         * - 16-bit or smaller FLOAT
         */
+       color->export_16bpc = false;
        if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
            ((desc->channel[i].size < 12 &&
              desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT &&
              ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) ||
             (desc->channel[i].size < 17 &&
              desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) {
-               color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC);
-               surf->export_16bpc = true;
+               color->info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC);
+               color->export_16bpc = true;
        }
 
+       color->pitch = S_028C64_PITCH_TILE_MAX(pitch);
+       color->slice = S_028C68_SLICE_TILE_MAX(slice);
+
        if (rtex->fmask.size) {
-               color_info |= S_028C70_COMPRESSION(1);
+               color->fmask = (rtex->resource.gpu_address + rtex->fmask.offset) >> 8;
+               color->fmask_slice = S_028C88_TILE_MAX(rtex->fmask.slice_tile_max);
+       } else {
+               color->fmask = color->offset;
+               color->fmask_slice = S_028C88_TILE_MAX(slice);
        }
+}
+
+/**
+ * This function intializes the CB* register values for RATs.  It is meant
+ * to be used for 1D aligned buffers that do not have an associated
+ * radeon_surf.
+ */
+void evergreen_init_color_surface_rat(struct r600_context *rctx,
+                                       struct r600_surface *surf)
+{
+       struct pipe_resource *pipe_buffer = surf->base.texture;
+       unsigned format = r600_translate_colorformat(rctx->b.chip_class,
+                                                    surf->base.format, FALSE);
+       unsigned endian = r600_colorformat_endian_swap(format, FALSE);
+       unsigned swap = r600_translate_colorswap(surf->base.format, FALSE);
+       unsigned block_size =
+               align(util_format_get_blocksize(pipe_buffer->format), 4);
+       unsigned pitch_alignment =
+               MAX2(64, rctx->screen->b.info.pipe_interleave_bytes / block_size);
+       unsigned pitch = align(pipe_buffer->width0, pitch_alignment);
+
+       surf->cb_color_base = r600_resource(pipe_buffer)->gpu_address >> 8;
+
+       surf->cb_color_pitch = (pitch / 8) - 1;
+
+       surf->cb_color_slice = 0;
+
+       surf->cb_color_view = 0;
+
+       surf->cb_color_info =
+                 S_028C70_ENDIAN(endian)
+               | S_028C70_FORMAT(format)
+               | S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED)
+               | S_028C70_NUMBER_TYPE(V_028C70_NUMBER_UINT)
+               | S_028C70_COMP_SWAP(swap)
+               | S_028C70_BLEND_BYPASS(1) /* We must set this bit because we
+                                           * are using NUMBER_UINT */
+               | S_028C70_RAT(1)
+               ;
+
+       surf->cb_color_attrib = S_028C74_NON_DISP_TILING_ORDER(1);
+
+       /* For buffers, CB_COLOR0_DIM needs to be set to the number of
+        * elements. */
+       surf->cb_color_dim = pipe_buffer->width0;
+
+       /* Set the buffer range the GPU will have access to: */
+       util_range_add(&r600_resource(pipe_buffer)->valid_buffer_range,
+                      0, pipe_buffer->width0);
 
-       base_offset = rtex->resource.gpu_address;
+       surf->cb_color_fmask = surf->cb_color_base;
+       surf->cb_color_fmask_slice = 0;
+}
+
+
+void evergreen_init_color_surface(struct r600_context *rctx,
+                                 struct r600_surface *surf)
+{
+       struct r600_texture *rtex = (struct r600_texture*)surf->base.texture;
+       unsigned level = surf->base.u.tex.level;
+       struct r600_tex_color_info color;
+
+       evergreen_set_color_surface_common(rctx, rtex, level,
+                                          surf->base.u.tex.first_layer,
+                                          surf->base.u.tex.last_layer,
+                                          surf->base.format,
+                                          &color);
+
+       surf->alphatest_bypass = color.ntype == V_028C70_NUMBER_UINT ||
+               color.ntype == V_028C70_NUMBER_SINT;
+       surf->export_16bpc = color.export_16bpc;
 
        /* XXX handle enabling of CB beyond BASE8 which has different offset */
-       surf->cb_color_base = (base_offset + offset) >> 8;
-       surf->cb_color_dim = color_dim;
-       surf->cb_color_info = color_info;
-       surf->cb_color_pitch = S_028C64_PITCH_TILE_MAX(pitch);
-       surf->cb_color_slice = S_028C68_SLICE_TILE_MAX(slice);
-       surf->cb_color_view = color_view;
-       surf->cb_color_attrib = color_attrib;
-       if (rtex->fmask.size) {
-               surf->cb_color_fmask = (base_offset + rtex->fmask.offset) >> 8;
-               surf->cb_color_fmask_slice = S_028C88_TILE_MAX(rtex->fmask.slice_tile_max);
-       } else {
-               surf->cb_color_fmask = surf->cb_color_base;
-               surf->cb_color_fmask_slice = S_028C88_TILE_MAX(slice);
-       }
+       surf->cb_color_base = color.offset;
+       surf->cb_color_dim = color.dim;
+       surf->cb_color_info = color.info;
+       surf->cb_color_pitch = color.pitch;
+       surf->cb_color_slice = color.slice;
+       surf->cb_color_view = color.view;
+       surf->cb_color_attrib = color.attrib;
+       surf->cb_color_fmask = color.fmask;
+       surf->cb_color_fmask_slice = color.fmask_slice;
 
        surf->color_initialized = true;
 }