From: Marek Olšák Date: Fri, 28 Jul 2017 23:35:46 +0000 (+0200) Subject: radeonsi: program tile swizzle for color and FMASK surfaces for GFX & SDMA X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=da942a4b81312c64459b3b54cfd8889cbc2a14aa;p=mesa.git radeonsi: program tile swizzle for color and FMASK surfaces for GFX & SDMA Reviewed-by: Dave Airlie Reviewed-by: Nicolai Hähnle --- diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h index b391cbb82a6..fb52dfb5297 100644 --- a/src/gallium/drivers/radeon/r600_pipe_common.h +++ b/src/gallium/drivers/radeon/r600_pipe_common.h @@ -202,6 +202,7 @@ struct r600_fmask_info { unsigned bank_height; unsigned slice_tile_max; unsigned tile_mode_index; + unsigned tile_swizzle; }; struct r600_cmask_info { diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 07df2d43017..e3d462ea80a 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -757,6 +757,7 @@ void r600_texture_get_fmask_info(struct r600_common_screen *rscreen, out->tile_mode_index = fmask.u.legacy.tiling_index[0]; out->pitch_in_pixels = fmask.u.legacy.level[0].nblk_x; out->bank_height = fmask.u.legacy.bankh; + out->tile_swizzle = fmask.tile_swizzle; out->alignment = MAX2(256, fmask.surf_alignment); out->size = fmask.surf_size; } @@ -1447,7 +1448,7 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen struct pb_buffer *buf = NULL; unsigned stride = 0, offset = 0; unsigned array_mode; - struct radeon_surf surface; + struct radeon_surf surface = {}; int r; struct radeon_bo_metadata metadata = {}; struct r600_texture *rtex; @@ -1511,6 +1512,7 @@ static struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen assert(metadata.u.gfx9.swizzle_mode == surface.u.gfx9.surf.swizzle_mode); } + assert(rtex->surface.tile_swizzle == 0); return &rtex->resource.b.b; } diff --git a/src/gallium/drivers/radeonsi/cik_sdma.c b/src/gallium/drivers/radeonsi/cik_sdma.c index 99285a6de17..8154d720dc2 100644 --- a/src/gallium/drivers/radeonsi/cik_sdma.c +++ b/src/gallium/drivers/radeonsi/cik_sdma.c @@ -162,6 +162,10 @@ static bool cik_sdma_copy_texture(struct si_context *sctx, unsigned src_tile_mode = info->si_tile_mode_array[src_tile_index]; unsigned dst_micro_mode = G_009910_MICRO_TILE_MODE_NEW(dst_tile_mode); unsigned src_micro_mode = G_009910_MICRO_TILE_MODE_NEW(src_tile_mode); + unsigned dst_tile_swizzle = dst_mode == RADEON_SURF_MODE_2D ? + rdst->surface.tile_swizzle : 0; + unsigned src_tile_swizzle = src_mode == RADEON_SURF_MODE_2D ? + rsrc->surface.tile_swizzle : 0; unsigned dst_pitch = rdst->surface.u.legacy.level[dst_level].nblk_x; unsigned src_pitch = rsrc->surface.u.legacy.level[src_level].nblk_x; uint64_t dst_slice_pitch = rdst->surface.u.legacy.level[dst_level].slice_size / bpp; @@ -205,6 +209,9 @@ static bool cik_sdma_copy_texture(struct si_context *sctx, dstz >= (1 << 11)) return false; + dst_address |= dst_tile_swizzle << 8; + src_address |= src_tile_swizzle << 8; + /* Linear -> linear sub-window copy. */ if (dst_mode == RADEON_SURF_MODE_LINEAR_ALIGNED && src_mode == RADEON_SURF_MODE_LINEAR_ALIGNED && diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c index 26a8d815183..02f921e5be1 100644 --- a/src/gallium/drivers/radeonsi/si_descriptors.c +++ b/src/gallium/drivers/radeonsi/si_descriptors.c @@ -422,6 +422,13 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen, state[1] &= C_008F14_BASE_ADDRESS_HI; state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40); + /* Only macrotiled modes can set tile swizzle. + * GFX9 doesn't use (legacy) base_level_info. + */ + if (sscreen->b.chip_class >= GFX9 || + base_level_info->mode == RADEON_SURF_MODE_2D) + state[0] |= tex->surface.tile_swizzle; + if (sscreen->b.chip_class >= VI) { state[6] &= C_008F28_COMPRESSION_EN; state[7] = 0; @@ -430,8 +437,12 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen, meta_va = (!tex->dcc_separate_buffer ? tex->resource.gpu_address : 0) + tex->dcc_offset; - if (sscreen->b.chip_class <= VI) + if (sscreen->b.chip_class == VI) { meta_va += base_level_info->dcc_offset; + assert(base_level_info->mode == RADEON_SURF_MODE_2D); + } + + meta_va |= (uint32_t)tex->surface.tile_swizzle << 8; } else if (tex->tc_compatible_htile && first_level == 0) { meta_va = tex->resource.gpu_address + tex->htile_offset; } diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 6e678242a2c..c9bb108cc16 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2767,8 +2767,10 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom cb_color_info = cb->cb_color_info | tex->cb_color_info; cb_color_attrib = cb->cb_color_attrib; - if (tex->fmask.size) + if (tex->fmask.size) { cb_color_fmask = (tex->resource.gpu_address + tex->fmask.offset) >> 8; + cb_color_fmask |= tex->fmask.tile_swizzle; + } /* Set up DCC. */ if (vi_dcc_enabled(tex, cb->base.u.tex.level)) { @@ -2782,6 +2784,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom cb_dcc_base = ((!tex->dcc_separate_buffer ? tex->resource.gpu_address : 0) + tex->dcc_offset) >> 8; + cb_dcc_base |= tex->surface.tile_swizzle; } if (sctx->b.chip_class >= GFX9) { @@ -2794,6 +2797,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom /* Set mutable surface parameters. */ cb_color_base += tex->surface.u.gfx9.surf_offset >> 8; + cb_color_base |= tex->surface.tile_swizzle; if (!tex->fmask.size) cb_color_fmask = cb_color_base; cb_color_attrib |= S_028C74_COLOR_SW_MODE(tex->surface.u.gfx9.surf.swizzle_mode) | @@ -2828,6 +2832,10 @@ static void si_emit_framebuffer_state(struct si_context *sctx, struct r600_atom unsigned cb_color_pitch, cb_color_slice, cb_color_fmask_slice; cb_color_base += level_info->offset >> 8; + /* Only macrotiled modes can set tile swizzle. */ + if (level_info->mode == RADEON_SURF_MODE_2D) + cb_color_base |= tex->surface.tile_swizzle; + if (!tex->fmask.size) cb_color_fmask = cb_color_base; if (cb_dcc_base) @@ -3416,7 +3424,7 @@ si_make_texture_descriptor(struct si_screen *screen, num_format = V_008F14_IMG_NUM_FORMAT_UINT; } - fmask_state[0] = va >> 8; + fmask_state[0] = (va >> 8) | tex->fmask.tile_swizzle; fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) | S_008F14_DATA_FORMAT_GFX6(data_format) | S_008F14_NUM_FORMAT_GFX6(num_format);