panfrost: Calculate the row stride at resource creation time

So we don't have to calculate it again when we create a texture or
framebuffer descriptor.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7653>
This commit is contained in:
Boris Brezillon 2020-11-21 15:58:41 +01:00
parent 690232c90f
commit 00360cd5c8
5 changed files with 47 additions and 66 deletions

View file

@ -134,7 +134,7 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf,
unsigned level = surf->u.tex.level;
unsigned first_layer = surf->u.tex.first_layer;
assert(surf->u.tex.last_layer == first_layer);
int stride = rsrc->slices[level].stride;
int row_stride = rsrc->slices[level].row_stride;
/* Only set layer_stride for layered MSAA rendering */
@ -158,7 +158,7 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf,
rt->midgard.writeback_block_format = MALI_BLOCK_FORMAT_LINEAR;
rt->rgb.base = base;
rt->rgb.row_stride = stride;
rt->rgb.row_stride = row_stride;
rt->rgb.surface_stride = layer_stride;
} else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
if (version >= 7)
@ -167,7 +167,7 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf,
rt->midgard.writeback_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED;
rt->rgb.base = base;
rt->rgb.row_stride = stride * 16;
rt->rgb.row_stride = row_stride;
rt->rgb.surface_stride = layer_stride;
} else if (drm_is_afbc(rsrc->modifier)) {
if (version >= 7)
@ -305,12 +305,12 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch,
rsrc->modifier == DRM_FORMAT_MOD_LINEAR);
/* TODO: Z32F(S8) support, which is always linear */
int stride = rsrc->slices[level].stride;
int row_stride = rsrc->slices[level].row_stride;
unsigned layer_stride = (nr_samples > 1) ? rsrc->slices[level].size0 : 0;
ext->zs_writeback_base = base;
ext->zs_writeback_row_stride = stride;
ext->zs_writeback_row_stride = row_stride;
ext->zs_writeback_surface_stride = layer_stride;
if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) {
@ -319,7 +319,6 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch,
else
ext->zs_block_format = MALI_BLOCK_FORMAT_LINEAR;
} else {
ext->zs_writeback_row_stride *= 16;
if (version >= 7)
ext->zs_block_format_v7 = MALI_BLOCK_FORMAT_V7_TILED_U_INTERLEAVED;
else
@ -352,9 +351,7 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch,
unsigned stencil_layer_stride = (nr_samples > 1) ? stencil_slice.size0 : 0;
ext->s_writeback_base = panfrost_get_texture_address(stencil, level, first_layer, 0);
ext->s_writeback_row_stride = stencil_slice.stride;
if (rsrc->modifier != DRM_FORMAT_MOD_LINEAR)
ext->s_writeback_row_stride *= 16;
ext->s_writeback_row_stride = stencil_slice.row_stride;
ext->s_writeback_surface_stride = stencil_layer_stride;
break;
default:

View file

@ -80,7 +80,19 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen,
rsc->modifier = (whandle->modifier == DRM_FORMAT_MOD_INVALID) ?
DRM_FORMAT_MOD_LINEAR : whandle->modifier;
rsc->modifier_constant = true;
rsc->slices[0].stride = whandle->stride;
rsc->slices[0].line_stride = whandle->stride;
rsc->slices[0].row_stride = whandle->stride;
if (rsc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED ||
drm_is_afbc(rsc->modifier)) {
unsigned tile_h = panfrost_block_dim(rsc->modifier, false, 0);
if (util_format_is_compressed(rsc->internal_format))
tile_h >>= 2;
rsc->slices[0].row_stride *= tile_h;
}
rsc->slices[0].offset = whandle->offset;
rsc->slices[0].initialized = true;
panfrost_resource_set_damage_region(NULL, &rsc->base, 0, NULL);
@ -128,7 +140,7 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
return true;
handle->handle = rsrc->bo->gem_handle;
handle->stride = rsrc->slices[0].stride;
handle->stride = rsrc->slices[0].line_stride;
handle->offset = rsrc->slices[0].offset;
return TRUE;
} else if (handle->type == WINSYS_HANDLE_TYPE_FD) {
@ -153,7 +165,7 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen,
return false;
handle->handle = fd;
handle->stride = rsrc->slices[0].stride;
handle->stride = rsrc->slices[0].line_stride;
handle->offset = rsrc->slices[0].offset;
return true;
}
@ -317,6 +329,14 @@ panfrost_setup_slices(struct panfrost_device *dev,
unsigned offset = 0;
unsigned size_2d = 0;
unsigned tile_h = 1, tile_w = 1, tile_shift = 0;
if (tiled || afbc) {
tile_w = panfrost_block_dim(pres->modifier, true, 0);
tile_h = panfrost_block_dim(pres->modifier, false, 0);
if (util_format_is_compressed(pres->internal_format))
tile_shift = 2;
}
for (unsigned l = 0; l <= res->last_level; ++l) {
struct panfrost_slice *slice = &pres->slices[l];
@ -326,8 +346,8 @@ panfrost_setup_slices(struct panfrost_device *dev,
unsigned effective_depth = depth;
if (should_align) {
effective_width = ALIGN_POT(effective_width, 16);
effective_height = ALIGN_POT(effective_height, 16);
effective_width = ALIGN_POT(effective_width, tile_w) >> tile_shift;
effective_height = ALIGN_POT(effective_height, tile_h);
/* We don't need to align depth */
}
@ -342,9 +362,6 @@ panfrost_setup_slices(struct panfrost_device *dev,
/* Compute the would-be stride */
unsigned stride = bytes_per_pixel * effective_width;
if (util_format_is_compressed(pres->internal_format))
stride /= 4;
/* On Bifrost, pixel lines have to be aligned on 64 bytes otherwise
* we end up with DATA_INVALID faults. That doesn't seem to be
* mandatory on Midgard, but we keep the alignment for performance.
@ -352,9 +369,10 @@ panfrost_setup_slices(struct panfrost_device *dev,
if (linear)
stride = ALIGN_POT(stride, 64);
slice->stride = stride;
slice->line_stride = stride;
slice->row_stride = stride * (tile_h >> tile_shift);
unsigned slice_one_size = slice->stride * effective_height;
unsigned slice_one_size = slice->line_stride * effective_height;
unsigned slice_full_size = slice_one_size * effective_depth;
slice->size0 = slice_one_size;
@ -791,7 +809,7 @@ panfrost_ptr_map(struct pipe_context *pctx,
/* We don't have s/w routines for AFBC, so use a staging texture */
if (drm_is_afbc(rsrc->modifier)) {
struct panfrost_resource *staging = pan_alloc_staging(ctx, rsrc, level, box);
transfer->base.stride = staging->slices[0].stride;
transfer->base.stride = staging->slices[0].line_stride;
transfer->base.layer_stride = transfer->base.stride * box->height;
transfer->staging.rsrc = &staging->base;
@ -907,7 +925,7 @@ panfrost_ptr_map(struct pipe_context *pctx,
bo->ptr.cpu + rsrc->slices[level].offset,
box->x, box->y, box->width, box->height,
transfer->base.stride,
rsrc->slices[level].stride,
rsrc->slices[level].line_stride,
rsrc->internal_format);
}
@ -924,7 +942,7 @@ panfrost_ptr_map(struct pipe_context *pctx,
if ((usage & dpw) == dpw && rsrc->index_cache)
return NULL;
transfer->base.stride = rsrc->slices[level].stride;
transfer->base.stride = rsrc->slices[level].line_stride;
transfer->base.layer_stride = panfrost_get_layer_stride(
rsrc->slices, rsrc->base.target == PIPE_TEXTURE_3D,
rsrc->cubemap_stride, level);
@ -940,7 +958,7 @@ panfrost_ptr_map(struct pipe_context *pctx,
return bo->ptr.cpu
+ rsrc->slices[level].offset
+ transfer->base.box.z * transfer->base.layer_stride
+ transfer->base.box.y * rsrc->slices[level].stride
+ transfer->base.box.y * rsrc->slices[level].line_stride
+ transfer->base.box.x * bytes_per_pixel;
}
}
@ -1024,7 +1042,7 @@ panfrost_ptr_unmap(struct pipe_context *pctx,
util_copy_rect(
bo->ptr.cpu + prsrc->slices[0].offset,
prsrc->base.format,
prsrc->slices[0].stride,
prsrc->slices[0].line_stride,
0, 0,
transfer->box.width,
transfer->box.height,
@ -1037,7 +1055,7 @@ panfrost_ptr_unmap(struct pipe_context *pctx,
trans->map,
transfer->box.x, transfer->box.y,
transfer->box.width, transfer->box.height,
prsrc->slices[transfer->level].stride,
prsrc->slices[transfer->level].line_stride,
transfer->stride,
prsrc->internal_format);
}

View file

@ -84,7 +84,7 @@ panfrost_sfbd_set_cbuf(
unsigned level = surf->u.tex.level;
unsigned first_layer = surf->u.tex.first_layer;
assert(surf->u.tex.last_layer == first_layer);
signed stride = rsrc->slices[level].stride;
signed row_stride = rsrc->slices[level].row_stride;
mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0);
@ -92,13 +92,12 @@ panfrost_sfbd_set_cbuf(
fb->color_write_enable = true;
fb->color_writeback.base = base;
fb->color_writeback.row_stride = stride;
fb->color_writeback.row_stride = row_stride;
if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR)
fb->color_block_format = MALI_BLOCK_FORMAT_LINEAR;
else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
fb->color_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED;
fb->color_writeback.row_stride *= 16;
} else {
fprintf(stderr, "Invalid render modifier\n");
assert(0);
@ -116,13 +115,12 @@ panfrost_sfbd_set_zsbuf(
assert(surf->u.tex.first_layer == 0);
fb->zs_writeback.base = rsrc->bo->ptr.gpu + rsrc->slices[level].offset;
fb->zs_writeback.row_stride = rsrc->slices[level].stride;
fb->zs_writeback.row_stride = rsrc->slices[level].row_stride;
if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR)
fb->zs_block_format = MALI_BLOCK_FORMAT_LINEAR;
else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
fb->zs_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED;
fb->zs_writeback.row_stride *= 16;
} else {
fprintf(stderr, "Invalid render modifier\n");
assert(0);

View file

@ -92,7 +92,7 @@ panfrost_needs_explicit_stride(uint64_t modifier,
unsigned block_w = util_format_get_blockwidth(format);
for (unsigned l = first_level; l <= last_level; ++l) {
unsigned actual = slices[l].stride;
unsigned actual = slices[l].line_stride;
unsigned expected =
DIV_ROUND_UP(u_minify(width, l), block_w) *
bytes_per_block;
@ -237,29 +237,6 @@ panfrost_block_dim(uint64_t modifier, bool width, unsigned plane)
}
}
static unsigned
panfrost_nonlinear_stride(uint64_t modifier,
unsigned bytes_per_block,
unsigned pixels_per_block,
unsigned width,
unsigned height,
bool plane)
{
unsigned block_w = panfrost_block_dim(modifier, true, plane);
unsigned block_h = panfrost_block_dim(modifier, false, plane);
/* Calculate block size. Ensure the division happens only at the end to
* avoid rounding errors if bytes per block < pixels per block */
unsigned block_size = (block_w * block_h * bytes_per_block)
/ pixels_per_block;
if (height <= block_h)
return 0;
else
return DIV_ROUND_UP(width, block_w) * block_size;
}
static uint64_t
panfrost_get_surface_strides(struct panfrost_slice *slices,
const struct util_format_description *desc,
@ -269,18 +246,8 @@ panfrost_get_surface_strides(struct panfrost_slice *slices,
unsigned l, unsigned cube_stride)
{
bool is_3d = dim == MALI_TEXTURE_DIMENSION_3D;
bool is_linear = modifier == DRM_FORMAT_MOD_LINEAR;
unsigned line_stride =
is_linear ?
slices[l].stride :
panfrost_nonlinear_stride(modifier,
MAX2(desc->block.bits / 8, 1),
desc->block.width * desc->block.height,
u_minify(width, l),
u_minify(height, l),
false);
unsigned line_stride = slices[l].row_stride;
unsigned layer_stride =
panfrost_get_layer_stride(slices, is_3d, cube_stride, l);

View file

@ -40,7 +40,8 @@ extern uint64_t pan_best_modifiers[PAN_MODIFIER_COUNT];
struct panfrost_slice {
unsigned offset;
unsigned stride;
unsigned line_stride;
unsigned row_stride;
unsigned size0;
/* If there is a header preceding each slice, how big is