panfrost: Fix calculation of body/header pointers for 3D AFBC

When using 3D AFBC, all headers are placed at the beginning instead of
being interleaved with each surface body, which forces us to adjust
the calculation in that case.

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/8125>
This commit is contained in:
Boris Brezillon 2020-12-16 14:48:57 +01:00
parent a6b269a39d
commit 4ffe73547d
3 changed files with 40 additions and 7 deletions

View file

@ -147,7 +147,6 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf,
unsigned nr_samples = surf->texture->nr_samples;
unsigned layer_stride = (nr_samples > 1) ? rsrc->layout.slices[level].surface_stride : 0;
mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0);
if (layer_stride)
rt->writeback_msaa = MALI_MSAA_LAYERED;
@ -159,6 +158,8 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf,
panfrost_mfbd_rt_init_format(dev, surf, rt);
if (rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR) {
mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0);
if (version >= 7)
rt->bifrost_v7.writeback_block_format = MALI_BLOCK_FORMAT_V7_LINEAR;
else
@ -168,6 +169,8 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf,
rt->rgb.row_stride = row_stride;
rt->rgb.surface_stride = layer_stride;
} else if (rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0);
if (version >= 7)
rt->bifrost_v7.writeback_block_format = MALI_BLOCK_FORMAT_V7_TILED_U_INTERLEAVED;
else
@ -192,8 +195,9 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf,
rt->afbc.body_size = slice->afbc.body_size;
}
rt->afbc.header = base;
rt->afbc.body = base + slice->afbc.header_size;
panfrost_get_afbc_pointers(rsrc, level, first_layer,
&rt->afbc.header,
&rt->afbc.body);
if (rsrc->layout.modifier & AFBC_FORMAT_MOD_YTR)
rt->afbc.yuv_transform_enable = true;
@ -291,8 +295,6 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch,
unsigned first_layer = zs_surf->u.tex.first_layer;
assert(zs_surf->u.tex.last_layer == first_layer);
mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0);
if (version < 7)
ext->zs_msaa = nr_samples > 1 ? MALI_MSAA_LAYERED : MALI_MSAA_SINGLE;
else
@ -301,8 +303,9 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch,
if (drm_is_afbc(rsrc->layout.modifier)) {
struct panfrost_slice *slice = &rsrc->layout.slices[level];
ext->zs_afbc_header = base;
ext->zs_afbc_body = base + slice->afbc.header_size;
panfrost_get_afbc_pointers(rsrc, level, first_layer,
&ext->zs_afbc_header,
&ext->zs_afbc_body);
if (version >= 7) {
ext->zs_block_format_v7 = MALI_BLOCK_FORMAT_V7_AFBC;
@ -317,6 +320,8 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch,
} else {
assert(rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED ||
rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR);
mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0);
/* TODO: Z32F(S8) support, which is always linear */
ext->zs_writeback_base = base;

View file

@ -1278,6 +1278,29 @@ panfrost_get_texture_address(struct panfrost_resource *rsrc,
array_idx, surface_idx);
}
void
panfrost_get_afbc_pointers(struct panfrost_resource *rsrc,
unsigned level, unsigned layer,
mali_ptr *header, mali_ptr *body)
{
assert(drm_is_afbc(rsrc->layout.modifier));
struct panfrost_slice *slice = &rsrc->layout.slices[level];
if (rsrc->base.target == PIPE_TEXTURE_3D) {
*header = rsrc->bo->ptr.gpu + slice->offset +
(layer * slice->afbc.surface_stride);
*body = rsrc->bo->ptr.gpu + slice->offset +
slice->afbc.header_size +
(slice->surface_stride * layer);
} else {
*header = rsrc->bo->ptr.gpu +
panfrost_texture_offset(&rsrc->layout,
level, layer, 0);
*body = *header + slice->afbc.header_size;
}
}
static void
panfrost_resource_set_stencil(struct pipe_resource *prsrc,
struct pipe_resource *stencil)

View file

@ -99,6 +99,11 @@ panfrost_get_texture_address(struct panfrost_resource *rsrc,
unsigned level, unsigned layer,
unsigned sample);
void
panfrost_get_afbc_pointers(struct panfrost_resource *rsrc,
unsigned level, unsigned layer,
mali_ptr *header, mali_ptr *body);
void panfrost_resource_screen_init(struct pipe_screen *screen);
void panfrost_resource_context_init(struct pipe_context *pctx);