mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-27 10:30:08 +01:00
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:
parent
690232c90f
commit
00360cd5c8
5 changed files with 47 additions and 66 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue