From 166250f4e5486e1e44ed97a8ab2ee0691e41cfa1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 21 Jun 2018 22:54:59 -0400 Subject: [PATCH] radeonsi: move CMASK size computation into ac_surface Reviewed-by: Timothy Arceri --- src/amd/common/ac_surface.c | 61 +++++++++++++++ src/amd/common/ac_surface.h | 5 ++ src/gallium/drivers/radeonsi/si_clear.c | 14 ++-- src/gallium/drivers/radeonsi/si_pipe.h | 7 +- src/gallium/drivers/radeonsi/si_state.c | 2 +- src/gallium/drivers/radeonsi/si_texture.c | 77 ++----------------- .../winsys/radeon/drm/radeon_drm_surface.c | 13 ++++ 7 files changed, 94 insertions(+), 85 deletions(-) diff --git a/src/amd/common/ac_surface.c b/src/amd/common/ac_surface.c index f5f88c1e791..9eb63bab038 100644 --- a/src/amd/common/ac_surface.c +++ b/src/amd/common/ac_surface.c @@ -547,6 +547,66 @@ static int gfx6_surface_settings(ADDR_HANDLE addrlib, return 0; } +void ac_compute_cmask(const struct radeon_info *info, + const struct ac_surf_config *config, + struct radeon_surf *surf) +{ + unsigned pipe_interleave_bytes = info->pipe_interleave_bytes; + unsigned num_pipes = info->num_tile_pipes; + unsigned cl_width, cl_height; + + if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) + return; + + assert(info->chip_class <= VI); + + switch (num_pipes) { + case 2: + cl_width = 32; + cl_height = 16; + break; + case 4: + cl_width = 32; + cl_height = 32; + break; + case 8: + cl_width = 64; + cl_height = 32; + break; + case 16: /* Hawaii */ + cl_width = 64; + cl_height = 64; + break; + default: + assert(0); + return; + } + + unsigned base_align = num_pipes * pipe_interleave_bytes; + + unsigned width = align(config->info.width, cl_width*8); + unsigned height = align(config->info.height, cl_height*8); + unsigned slice_elements = (width * height) / (8*8); + + /* Each element of CMASK is a nibble. */ + unsigned slice_bytes = slice_elements / 2; + + surf->u.legacy.cmask_slice_tile_max = (width * height) / (128*128); + if (surf->u.legacy.cmask_slice_tile_max) + surf->u.legacy.cmask_slice_tile_max -= 1; + + unsigned num_layers; + if (config->is_3d) + num_layers = config->info.depth; + else if (config->is_cube) + num_layers = 6; + else + num_layers = config->info.array_size; + + surf->cmask_alignment = MAX2(256, base_align); + surf->cmask_size = align(slice_bytes, base_align) * num_layers; +} + /** * Fill in the tiling information in \p surf based on the given surface config. * @@ -962,6 +1022,7 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib, return ADDR_ERROR; } + ac_compute_cmask(info, config, surf); return 0; } diff --git a/src/amd/common/ac_surface.h b/src/amd/common/ac_surface.h index 01f1cc8dbac..6d95e610a59 100644 --- a/src/amd/common/ac_surface.h +++ b/src/amd/common/ac_surface.h @@ -109,6 +109,7 @@ struct legacy_surf_layout { uint8_t tiling_index[RADEON_SURF_MAX_LEVELS]; uint8_t stencil_tiling_index[RADEON_SURF_MAX_LEVELS]; struct legacy_surf_fmask fmask; + unsigned cmask_slice_tile_max; }; /* Same as addrlib - AddrResourceType. */ @@ -248,6 +249,10 @@ int ac_compute_surface(ADDR_HANDLE addrlib, const struct radeon_info *info, enum radeon_surf_mode mode, struct radeon_surf *surf); +void ac_compute_cmask(const struct radeon_info *info, + const struct ac_surf_config *config, + struct radeon_surf *surf); + #ifdef __cplusplus } #endif diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c index 53c255c5808..2054e753530 100644 --- a/src/gallium/drivers/radeonsi/si_clear.c +++ b/src/gallium/drivers/radeonsi/si_clear.c @@ -42,24 +42,20 @@ static void si_alloc_separate_cmask(struct si_screen *sscreen, assert(tex->cmask.size == 0); - si_texture_get_cmask_info(sscreen, tex, &tex->cmask); - if (!tex->cmask.size) + if (!tex->surface.cmask_size) return; tex->cmask_buffer = si_aligned_buffer_create(&sscreen->b, SI_RESOURCE_FLAG_UNMAPPABLE, PIPE_USAGE_DEFAULT, - tex->cmask.size, - tex->cmask.alignment); - if (tex->cmask_buffer == NULL) { - tex->cmask.size = 0; + tex->surface.cmask_size, + tex->surface.cmask_alignment); + if (tex->cmask_buffer == NULL) return; - } - /* update colorbuffer state bits */ + tex->cmask.size = tex->surface.cmask_size; tex->cmask.base_address_reg = tex->cmask_buffer->gpu_address >> 8; - tex->cb_color_info |= S_028C70_FAST_CLEAR(1); p_atomic_inc(&sscreen->compressed_colortex_counter); diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index ddd1dfbf762..b6ef60cbe3e 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -232,10 +232,8 @@ struct r600_transfer { struct r600_cmask_info { uint64_t offset; - uint64_t size; - unsigned alignment; - unsigned slice_tile_max; uint64_t base_address_reg; + uint32_t size; }; struct si_texture { @@ -1225,9 +1223,6 @@ bool si_prepare_for_dma_blit(struct si_context *sctx, struct si_texture *src, unsigned src_level, const struct pipe_box *src_box); -void si_texture_get_cmask_info(struct si_screen *sscreen, - struct si_texture *tex, - struct r600_cmask_info *out); void si_eliminate_fast_color_clear(struct si_context *sctx, struct si_texture *tex); void si_texture_discard_cmask(struct si_screen *sscreen, diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index e23666b4019..cb05de2ca9d 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -3130,7 +3130,7 @@ static void si_emit_framebuffer_state(struct si_context *sctx) radeon_emit(cs, cb_color_attrib); /* CB_COLOR0_ATTRIB */ radeon_emit(cs, cb->cb_dcc_control); /* CB_COLOR0_DCC_CONTROL */ radeon_emit(cs, cb_color_cmask); /* CB_COLOR0_CMASK */ - radeon_emit(cs, tex->cmask.slice_tile_max); /* CB_COLOR0_CMASK_SLICE */ + radeon_emit(cs, tex->surface.u.legacy.cmask_slice_tile_max); /* CB_COLOR0_CMASK_SLICE */ radeon_emit(cs, cb_color_fmask); /* CB_COLOR0_FMASK */ radeon_emit(cs, cb_color_fmask_slice); /* CB_COLOR0_FMASK_SLICE */ radeon_emit(cs, tex->color_clear_value[0]); /* CB_COLOR0_CLEAR_WORD0 */ diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c index 4ae02669443..96104bc70b5 100644 --- a/src/gallium/drivers/radeonsi/si_texture.c +++ b/src/gallium/drivers/radeonsi/si_texture.c @@ -869,71 +869,6 @@ static void si_texture_destroy(struct pipe_screen *screen, static const struct u_resource_vtbl si_texture_vtbl; -void si_texture_get_cmask_info(struct si_screen *sscreen, - struct si_texture *tex, - struct r600_cmask_info *out) -{ - unsigned pipe_interleave_bytes = sscreen->info.pipe_interleave_bytes; - unsigned num_pipes = sscreen->info.num_tile_pipes; - unsigned cl_width, cl_height; - - if (sscreen->info.chip_class >= GFX9) { - out->alignment = tex->surface.u.gfx9.cmask_alignment; - out->size = tex->surface.u.gfx9.cmask_size; - return; - } - - switch (num_pipes) { - case 2: - cl_width = 32; - cl_height = 16; - break; - case 4: - cl_width = 32; - cl_height = 32; - break; - case 8: - cl_width = 64; - cl_height = 32; - break; - case 16: /* Hawaii */ - cl_width = 64; - cl_height = 64; - break; - default: - assert(0); - return; - } - - unsigned base_align = num_pipes * pipe_interleave_bytes; - - unsigned width = align(tex->buffer.b.b.width0, cl_width*8); - unsigned height = align(tex->buffer.b.b.height0, cl_height*8); - unsigned slice_elements = (width * height) / (8*8); - - /* Each element of CMASK is a nibble. */ - unsigned slice_bytes = slice_elements / 2; - - out->slice_tile_max = (width * height) / (128*128); - if (out->slice_tile_max) - out->slice_tile_max -= 1; - - out->alignment = MAX2(256, base_align); - out->size = util_num_layers(&tex->buffer.b.b, 0) * - align(slice_bytes, base_align); -} - -static void si_texture_allocate_cmask(struct si_screen *sscreen, - struct si_texture *tex) -{ - si_texture_get_cmask_info(sscreen, tex, &tex->cmask); - - tex->cmask.offset = align64(tex->size, tex->cmask.alignment); - tex->size = tex->cmask.offset + tex->cmask.size; - - tex->cb_color_info |= S_028C70_FAST_CLEAR(1); -} - static void si_texture_get_htile_size(struct si_screen *sscreen, struct si_texture *tex) { @@ -1104,10 +1039,10 @@ void si_print_texture_info(struct si_screen *sscreen, tex->surface.u.legacy.fmask.tiling_index); if (tex->cmask.size) - u_log_printf(log, " CMask: offset=%"PRIu64", size=%"PRIu64", alignment=%u, " + u_log_printf(log, " CMask: offset=%"PRIu64", size=%u, alignment=%u, " "slice_tile_max=%u\n", - tex->cmask.offset, tex->cmask.size, tex->cmask.alignment, - tex->cmask.slice_tile_max); + tex->cmask.offset, tex->cmask.size, tex->surface.cmask_alignment, + tex->surface.u.legacy.cmask_slice_tile_max); if (tex->htile_offset) u_log_printf(log, " HTile: offset=%"PRIu64", size=%u, " @@ -1247,7 +1182,11 @@ si_texture_create_object(struct pipe_screen *screen, tex->surface.fmask_alignment); tex->size = tex->fmask_offset + tex->surface.fmask_size; - si_texture_allocate_cmask(sscreen, tex); + /* Allocate CMASK. */ + tex->cmask.size = tex->surface.cmask_size; + tex->cmask.offset = align64(tex->size, tex->surface.cmask_alignment); + tex->size = tex->cmask.offset + tex->cmask.size; + tex->cb_color_info |= S_028C70_FAST_CLEAR(1); tex->cmask_buffer = &tex->buffer; if (!tex->surface.fmask_size || !tex->cmask.size) { diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c index 4677a3bea7c..5e6978c58ef 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_surface.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_surface.c @@ -293,6 +293,19 @@ static int radeon_winsys_surface_init(struct radeon_winsys *rws, surf_ws->u.legacy.fmask.pitch_in_pixels = fmask.u.legacy.level[0].nblk_x; } + if (ws->gen == DRV_SI) { + struct ac_surf_config config; + + /* Only these fields need to be set for the CMASK computation. */ + config.info.width = tex->width0; + config.info.height = tex->height0; + config.info.depth = tex->depth0; + config.info.array_size = tex->array_size; + config.is_3d = !!(tex->target == PIPE_TEXTURE_3D); + config.is_cube = !!(tex->target == PIPE_TEXTURE_CUBE); + + ac_compute_cmask(&ws->info, &config, surf_ws); + } return 0; } -- 2.30.2