[Mesa-dev] [PATCH 15/19] radeonsi: move CMASK size computation into ac_surface
Marek Olšák
maraeo at gmail.com
Fri Jun 22 22:32:06 UTC 2018
From: Marek Olšák <marek.olsak at amd.com>
---
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
@@ -540,20 +540,80 @@ static int gfx6_surface_settings(ADDR_HANDLE addrlib,
if (r != ADDR_OK)
return r;
assert(AddrBaseSwizzleOut.tileSwizzle <=
u_bit_consecutive(0, sizeof(surf->tile_swizzle) * 8));
surf->tile_swizzle = AddrBaseSwizzleOut.tileSwizzle;
}
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.
*
* The following fields of \p surf must be initialized by the caller:
* blk_w, blk_h, bpe, flags.
*/
static int gfx6_compute_surface(ADDR_HANDLE addrlib,
const struct radeon_info *info,
const struct ac_surf_config *config,
enum radeon_surf_mode mode,
@@ -955,20 +1015,21 @@ static int gfx6_compute_surface(ADDR_HANDLE addrlib,
/* The rotated micro tile mode doesn't work if both CMASK and RB+ are
* used at the same time. This case is not currently expected to occur
* because we don't use rotated. Enforce this restriction on all chips
* to facilitate testing.
*/
if (surf->micro_tile_mode == RADEON_MICRO_MODE_ROTATED) {
assert(!"rotate micro tile mode is unsupported");
return ADDR_ERROR;
}
+ ac_compute_cmask(info, config, surf);
return 0;
}
/* This is only called when expecting a tiled layout. */
static int
gfx9_get_preferred_swizzle_mode(ADDR_HANDLE addrlib,
ADDR2_COMPUTE_SURFACE_INFO_INPUT *in,
bool is_fmask, unsigned flags,
AddrSwizzleMode *swizzle_mode)
{
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
@@ -102,20 +102,21 @@ struct legacy_surf_layout {
* sampled from.
*/
unsigned depth_adjusted:1;
unsigned stencil_adjusted:1;
struct legacy_surf_level level[RADEON_SURF_MAX_LEVELS];
struct legacy_surf_level stencil_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;
+ unsigned cmask_slice_tile_max;
};
/* Same as addrlib - AddrResourceType. */
enum gfx9_resource_type {
RADEON_RESOURCE_1D = 0,
RADEON_RESOURCE_2D,
RADEON_RESOURCE_3D,
};
struct gfx9_surf_flags {
@@ -241,15 +242,19 @@ struct ac_surf_config {
ADDR_HANDLE amdgpu_addr_create(const struct radeon_info *info,
const struct amdgpu_gpu_info *amdinfo,
uint64_t *max_alignment);
int ac_compute_surface(ADDR_HANDLE addrlib, const struct radeon_info *info,
const struct ac_surf_config * config,
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
#endif /* AC_SURFACE_H */
diff --git a/src/gallium/drivers/radeonsi/si_clear.c b/src/gallium/drivers/radeonsi/si_clear.c
index 050bbf3c181..7ea4459d512 100644
--- a/src/gallium/drivers/radeonsi/si_clear.c
+++ b/src/gallium/drivers/radeonsi/si_clear.c
@@ -35,38 +35,34 @@ enum {
};
static void si_alloc_separate_cmask(struct si_screen *sscreen,
struct si_texture *tex)
{
if (tex->cmask_buffer)
return;
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);
}
static bool si_set_clear_color(struct si_texture *tex,
enum pipe_format surface_format,
const union pipe_color_union *color)
{
union util_color uc;
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
@@ -225,24 +225,22 @@ struct r600_resource {
};
struct r600_transfer {
struct threaded_transfer b;
struct r600_resource *staging;
unsigned offset;
};
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 {
struct r600_resource buffer;
struct radeon_surf surface;
uint64_t size;
struct si_texture *flushed_depth_texture;
/* Colorbuffer compression and fast clear. */
@@ -1218,23 +1216,20 @@ void si_update_vs_viewport_state(struct si_context *ctx);
void si_init_viewport_functions(struct si_context *ctx);
/* si_texture.c */
bool si_prepare_for_dma_blit(struct si_context *sctx,
struct si_texture *dst,
unsigned dst_level, unsigned dstx,
unsigned dsty, unsigned dstz,
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,
struct si_texture *tex);
bool si_init_flushed_depth_texture(struct pipe_context *ctx,
struct pipe_resource *texture,
struct si_texture **staging);
void si_print_texture_info(struct si_screen *sscreen,
struct si_texture *tex, struct u_log_context *log);
struct pipe_resource *si_texture_create(struct pipe_screen *screen,
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
@@ -3123,21 +3123,21 @@ static void si_emit_framebuffer_state(struct si_context *sctx)
radeon_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C,
sctx->chip_class >= VI ? 14 : 13);
radeon_emit(cs, cb_color_base); /* CB_COLOR0_BASE */
radeon_emit(cs, cb_color_pitch); /* CB_COLOR0_PITCH */
radeon_emit(cs, cb_color_slice); /* CB_COLOR0_SLICE */
radeon_emit(cs, cb->cb_color_view); /* CB_COLOR0_VIEW */
radeon_emit(cs, cb_color_info); /* CB_COLOR0_INFO */
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 */
radeon_emit(cs, tex->color_clear_value[1]); /* CB_COLOR0_CLEAR_WORD1 */
if (sctx->chip_class >= VI) /* R_028C94_CB_COLOR0_DCC_BASE */
radeon_emit(cs, cb_dcc_base);
}
}
for (; i < 8 ; i++)
diff --git a/src/gallium/drivers/radeonsi/si_texture.c b/src/gallium/drivers/radeonsi/si_texture.c
index 4cc8786429a..b0ad144c6d5 100644
--- a/src/gallium/drivers/radeonsi/si_texture.c
+++ b/src/gallium/drivers/radeonsi/si_texture.c
@@ -862,85 +862,20 @@ static void si_texture_destroy(struct pipe_screen *screen,
r600_resource_reference(&tex->cmask_buffer, NULL);
}
pb_reference(&resource->buf, NULL);
r600_resource_reference(&tex->dcc_separate_buffer, NULL);
r600_resource_reference(&tex->last_dcc_separate_buffer, NULL);
FREE(tex);
}
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)
{
unsigned cl_width, cl_height, width, height;
unsigned slice_elements, slice_bytes, pipe_interleave_bytes, base_align;
unsigned num_pipes = sscreen->info.num_tile_pipes;
assert(sscreen->info.chip_class <= VI);
tex->surface.htile_size = 0;
@@ -1097,24 +1032,24 @@ void si_print_texture_info(struct si_screen *sscreen,
if (tex->surface.fmask_size)
u_log_printf(log, " FMask: offset=%"PRIu64", size=%"PRIu64", alignment=%u, pitch_in_pixels=%u, "
"bankh=%u, slice_tile_max=%u, tile_mode_index=%u\n",
tex->fmask_offset, tex->surface.fmask_size, tex->surface.fmask_alignment,
tex->surface.u.legacy.fmask.pitch_in_pixels,
tex->surface.u.legacy.fmask.bankh,
tex->surface.u.legacy.fmask.slice_tile_max,
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, "
"alignment=%u, TC_compatible = %u\n",
tex->htile_offset, tex->surface.htile_size,
tex->surface.htile_alignment,
tex->tc_compatible_htile);
if (tex->dcc_offset) {
u_log_printf(log, " DCC: offset=%"PRIu64", size=%u, alignment=%u\n",
@@ -1240,21 +1175,25 @@ si_texture_create_object(struct pipe_screen *screen,
}
} else {
if (base->nr_samples > 1 &&
!buf &&
!(sscreen->debug_flags & DBG(NO_FMASK))) {
/* Allocate FMASK. */
tex->fmask_offset = align64(tex->size,
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) {
FREE(tex);
return NULL;
}
}
/* Shared textures must always set up DCC here.
* If it's not present, it will be disabled by
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
@@ -286,17 +286,30 @@ static int radeon_winsys_surface_init(struct radeon_winsys *rws,
surf_ws->u.legacy.fmask.slice_tile_max =
(fmask.u.legacy.level[0].nblk_x * fmask.u.legacy.level[0].nblk_y) / 64;
if (surf_ws->u.legacy.fmask.slice_tile_max)
surf_ws->u.legacy.fmask.slice_tile_max -= 1;
surf_ws->u.legacy.fmask.tiling_index = fmask.u.legacy.tiling_index[0];
surf_ws->u.legacy.fmask.bankh = fmask.u.legacy.bankh;
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;
}
void radeon_surface_init_functions(struct radeon_drm_winsys *ws)
{
ws->base.surface_init = radeon_winsys_surface_init;
}
--
2.17.1
More information about the mesa-dev
mailing list