From: Marek Olšák <marek.ol...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev