From 222e42e45fc1e91e707343a7e6a32c6bd725eb10 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 31 Mar 2016 15:27:42 +1000 Subject: r600: refactor out CB setup. 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 Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/evergreen_state.c | 247 +++++++++++++++++------------ 1 file changed, 143 insertions(+), 104 deletions(-) (limited to 'src/gallium/drivers/r600') diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 5cb95f85c7..4d86570ade 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -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; } -- cgit v1.2.3