ac/surface: split dcc level info from surface_info to save space

stencil level info doesn't have DCC

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10083>
This commit is contained in:
Marek Olšák 2021-04-02 12:37:42 -04:00 committed by Marge Bot
parent e9dc3df868
commit 2fd8018845
10 changed files with 40 additions and 34 deletions

View file

@ -742,6 +742,7 @@ static int gfx6_compute_level(ADDR_HANDLE addrlib, const struct ac_surf_config *
ADDR_COMPUTE_HTILE_INFO_OUTPUT *AddrHtileOut)
{
struct legacy_surf_level *surf_level;
struct legacy_surf_dcc_level *dcc_level;
ADDR_E_RETURNCODE ret;
AddrSurfInfoIn->mipLevel = level;
@ -795,6 +796,7 @@ static int gfx6_compute_level(ADDR_HANDLE addrlib, const struct ac_surf_config *
}
surf_level = is_stencil ? &surf->u.legacy.stencil_level[level] : &surf->u.legacy.level[level];
dcc_level = &surf->u.legacy.dcc_level[level];
surf_level->offset = align64(surf->surf_size, AddrSurfInfoOut->baseAlign);
surf_level->slice_size_dw = AddrSurfInfoOut->sliceSize / 4;
surf_level->nblk_x = AddrSurfInfoOut->pitch;
@ -836,7 +838,7 @@ static int gfx6_compute_level(ADDR_HANDLE addrlib, const struct ac_surf_config *
surf->surf_size = surf_level->offset + AddrSurfInfoOut->surfSize;
/* Clear DCC fields at the beginning. */
surf_level->dcc_offset = 0;
dcc_level->dcc_offset = 0;
/* The previous level's flag tells us if we can use DCC for this level. */
if (AddrSurfInfoIn->flags.dccCompatible && (level == 0 || AddrDccOut->subLvlCompressible)) {
@ -851,9 +853,9 @@ static int gfx6_compute_level(ADDR_HANDLE addrlib, const struct ac_surf_config *
ret = AddrComputeDccInfo(addrlib, AddrDccIn, AddrDccOut);
if (ret == ADDR_OK) {
surf_level->dcc_offset = surf->dcc_size;
dcc_level->dcc_offset = surf->dcc_size;
surf->num_dcc_levels = level + 1;
surf->dcc_size = surf_level->dcc_offset + AddrDccOut->dccRamSize;
surf->dcc_size = dcc_level->dcc_offset + AddrDccOut->dccRamSize;
surf->dcc_alignment = MAX2(surf->dcc_alignment, AddrDccOut->dccRamBaseAlign);
/* If the DCC size of a subresource (1 mip level or 1 slice)
@ -869,9 +871,9 @@ static int gfx6_compute_level(ADDR_HANDLE addrlib, const struct ac_surf_config *
*/
if (AddrDccOut->dccRamSizeAligned ||
(prev_level_clearable && level == config->info.levels - 1))
surf_level->dcc_fast_clear_size = AddrDccOut->dccFastClearSize;
dcc_level->dcc_fast_clear_size = AddrDccOut->dccFastClearSize;
else
surf_level->dcc_fast_clear_size = 0;
dcc_level->dcc_fast_clear_size = 0;
/* Compute the DCC slice size because addrlib doesn't
* provide this info. As DCC memory is linear (each
@ -897,19 +899,19 @@ static int gfx6_compute_level(ADDR_HANDLE addrlib, const struct ac_surf_config *
* accross slices.
*/
if (AddrDccOut->dccRamSizeAligned)
surf_level->dcc_slice_fast_clear_size = AddrDccOut->dccFastClearSize;
dcc_level->dcc_slice_fast_clear_size = AddrDccOut->dccFastClearSize;
else
surf_level->dcc_slice_fast_clear_size = 0;
dcc_level->dcc_slice_fast_clear_size = 0;
}
if (surf->flags & RADEON_SURF_CONTIGUOUS_DCC_LAYERS &&
surf->dcc_slice_size != surf_level->dcc_slice_fast_clear_size) {
surf->dcc_slice_size != dcc_level->dcc_slice_fast_clear_size) {
surf->dcc_size = 0;
surf->num_dcc_levels = 0;
AddrDccOut->subLvlCompressible = false;
}
} else {
surf_level->dcc_slice_fast_clear_size = surf_level->dcc_fast_clear_size;
dcc_level->dcc_slice_fast_clear_size = dcc_level->dcc_fast_clear_size;
}
}
}

View file

@ -87,14 +87,17 @@ enum radeon_micro_mode
struct legacy_surf_level {
uint64_t offset;
uint32_t slice_size_dw; /* in dwords; max = 4GB / 4. */
uint32_t dcc_offset; /* relative offset within DCC mip tree */
uint32_t dcc_fast_clear_size;
uint32_t dcc_slice_fast_clear_size;
unsigned nblk_x : 15;
unsigned nblk_y : 15;
enum radeon_surf_mode mode : 2;
};
struct legacy_surf_dcc_level {
uint32_t dcc_offset; /* relative offset within DCC mip tree */
uint32_t dcc_fast_clear_size;
uint32_t dcc_slice_fast_clear_size;
};
struct legacy_surf_fmask {
unsigned slice_tile_max; /* max 4M */
uint8_t tiling_index; /* max 31 */
@ -122,6 +125,7 @@ struct legacy_surf_layout {
struct legacy_surf_level level[RADEON_SURF_MAX_LEVELS];
struct legacy_surf_level stencil_level[RADEON_SURF_MAX_LEVELS];
struct legacy_surf_dcc_level dcc_level[RADEON_SURF_MAX_LEVELS];
uint8_t tiling_index[RADEON_SURF_MAX_LEVELS];
uint8_t stencil_tiling_index[RADEON_SURF_MAX_LEVELS];
struct legacy_surf_fmask fmask;

View file

@ -5906,14 +5906,14 @@ radv_init_dcc(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image,
*/
/* Compute the size of all fast clearable DCC levels. */
for (unsigned i = 0; i < image->planes[0].surface.num_dcc_levels; i++) {
struct legacy_surf_level *surf_level = &image->planes[0].surface.u.legacy.level[i];
struct legacy_surf_dcc_level *dcc_level = &image->planes[0].surface.u.legacy.dcc_level[i];
unsigned dcc_fast_clear_size =
surf_level->dcc_slice_fast_clear_size * image->info.array_size;
dcc_level->dcc_slice_fast_clear_size * image->info.array_size;
if (!dcc_fast_clear_size)
break;
size = surf_level->dcc_offset + dcc_fast_clear_size;
size = dcc_level->dcc_offset + dcc_fast_clear_size;
}
/* Initialize the mipmap levels without DCC. */

View file

@ -6361,7 +6361,7 @@ radv_initialise_color_surface(struct radv_device *device, struct radv_color_buff
if (radv_dcc_enabled(iview->image, iview->base_mip) &&
device->physical_device->rad_info.chip_class <= GFX8)
va += plane->surface.u.legacy.level[iview->base_mip].dcc_offset;
va += plane->surface.u.legacy.dcc_level[iview->base_mip].dcc_offset;
unsigned dcc_tile_swizzle = surf->tile_swizzle;
dcc_tile_swizzle &= (surf->dcc_alignment - 1) >> 8;

View file

@ -702,7 +702,7 @@ si_set_mutable_tex_desc_fields(struct radv_device *device, struct radv_image *im
if (!disable_compression && radv_dcc_enabled(image, first_level)) {
meta_va = gpu_address + plane->surface.dcc_offset;
if (chip_class <= GFX8)
meta_va += base_level_info->dcc_offset;
meta_va += plane->surface.u.legacy.dcc_level[base_level].dcc_offset;
unsigned dcc_tile_swizzle = plane->surface.tile_swizzle << 8;
dcc_tile_swizzle &= plane->surface.dcc_alignment - 1;

View file

@ -1289,8 +1289,8 @@ radv_clear_dcc(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image,
assert(level == 0);
size = image->planes[0].surface.dcc_size;
} else {
const struct legacy_surf_level *surf_level =
&image->planes[0].surface.u.legacy.level[level];
const struct legacy_surf_dcc_level *dcc_level =
&image->planes[0].surface.u.legacy.dcc_level[level];
/* If dcc_fast_clear_size is 0 (which might happens for
* mipmaps) the fill buffer operation below is a no-op.
@ -1299,8 +1299,8 @@ radv_clear_dcc(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image,
* level can't be fast cleared.
*/
offset +=
surf_level->dcc_offset + surf_level->dcc_slice_fast_clear_size * range->baseArrayLayer;
size = surf_level->dcc_slice_fast_clear_size * radv_get_layerCount(image, range);
dcc_level->dcc_offset + dcc_level->dcc_slice_fast_clear_size * range->baseArrayLayer;
size = dcc_level->dcc_slice_fast_clear_size * radv_get_layerCount(image, range);
}
/* Do not clear this level if it can't be compressed. */
@ -1514,13 +1514,13 @@ radv_can_fast_clear_color(struct radv_cmd_buffer *cmd_buffer, const struct radv_
cmd_buffer->device->physical_device->rad_info.chip_class == GFX8) {
for (uint32_t l = 0; l < iview->level_count; l++) {
uint32_t level = iview->base_mip + l;
struct legacy_surf_level *surf_level =
&iview->image->planes[0].surface.u.legacy.level[level];
struct legacy_surf_dcc_level *dcc_level =
&iview->image->planes[0].surface.u.legacy.dcc_level[level];
/* Do not fast clears if one level can't be
* fast cleared.
*/
if (!surf_level->dcc_fast_clear_size)
if (!dcc_level->dcc_fast_clear_size)
return false;
}
}

View file

@ -294,7 +294,7 @@ bool vi_dcc_get_clear_info(struct si_context *sctx, struct si_texture *tex, unsi
unsigned num_layers = util_num_layers(&tex->buffer.b.b, level);
/* If this is 0, fast clear isn't possible. (can occur with MSAA) */
if (!tex->surface.u.legacy.level[level].dcc_fast_clear_size)
if (!tex->surface.u.legacy.dcc_level[level].dcc_fast_clear_size)
return false;
/* Layered 4x and 8x MSAA DCC fast clears need to clear
@ -304,8 +304,8 @@ bool vi_dcc_get_clear_info(struct si_context *sctx, struct si_texture *tex, unsi
if (tex->buffer.b.b.nr_storage_samples >= 4 && num_layers > 1)
return false;
dcc_offset += tex->surface.u.legacy.level[level].dcc_offset;
clear_size = tex->surface.u.legacy.level[level].dcc_fast_clear_size * num_layers;
dcc_offset += tex->surface.u.legacy.dcc_level[level].dcc_offset;
clear_size = tex->surface.u.legacy.dcc_level[level].dcc_fast_clear_size * num_layers;
}
si_init_buffer_clear(out, dcc_buffer, dcc_offset, clear_size, clear_value);

View file

@ -335,7 +335,7 @@ void si_set_mutable_tex_desc_fields(struct si_screen *sscreen, struct si_texture
(!tex->dcc_separate_buffer ? tex->buffer.gpu_address : 0) + tex->surface.dcc_offset;
if (sscreen->info.chip_class == GFX8) {
meta_va += base_level_info->dcc_offset;
meta_va += tex->surface.u.legacy.dcc_level[base_level].dcc_offset;
assert(base_level_info->mode == RADEON_SURF_MODE_2D);
}

View file

@ -3137,7 +3137,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx)
if (cb->base.u.tex.level > 0)
cb_color_cmask = cb_color_base;
if (cb_dcc_base)
cb_dcc_base += level_info->dcc_offset >> 8;
cb_dcc_base += tex->surface.u.legacy.dcc_level[cb->base.u.tex.level].dcc_offset >> 8;
pitch_tile_max = level_info->nblk_x / 8 - 1;
slice_tile_max = level_info->nblk_x * level_info->nblk_y / 64 - 1;

View file

@ -837,8 +837,8 @@ void si_print_texture_info(struct si_screen *sscreen, struct si_texture *tex,
u_log_printf(log,
" DCCLevel[%i]: enabled=%u, offset=%u, "
"fast_clear_size=%u\n",
i, i < tex->surface.num_dcc_levels, tex->surface.u.legacy.level[i].dcc_offset,
tex->surface.u.legacy.level[i].dcc_fast_clear_size);
i, i < tex->surface.num_dcc_levels, tex->surface.u.legacy.dcc_level[i].dcc_offset,
tex->surface.u.legacy.dcc_level[i].dcc_fast_clear_size);
}
for (i = 0; i <= tex->buffer.b.b.last_level; i++)
@ -1071,11 +1071,11 @@ static struct si_texture *si_texture_create_object(struct pipe_screen *screen,
unsigned size = 0;
for (unsigned i = 0; i < tex->surface.num_dcc_levels; i++) {
if (!tex->surface.u.legacy.level[i].dcc_fast_clear_size)
if (!tex->surface.u.legacy.dcc_level[i].dcc_fast_clear_size)
break;
size = tex->surface.u.legacy.level[i].dcc_offset +
tex->surface.u.legacy.level[i].dcc_fast_clear_size;
size = tex->surface.u.legacy.dcc_level[i].dcc_offset +
tex->surface.u.legacy.dcc_level[i].dcc_fast_clear_size;
}
/* Mipmap levels with DCC. */