diff --git a/src/gallium/drivers/panfrost/pan_mfbd.c b/src/gallium/drivers/panfrost/pan_mfbd.c index 1cb19d4cea1..0828d996b4b 100644 --- a/src/gallium/drivers/panfrost/pan_mfbd.c +++ b/src/gallium/drivers/panfrost/pan_mfbd.c @@ -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: diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index abc54300080..c7c8976dd7d 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -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); } diff --git a/src/gallium/drivers/panfrost/pan_sfbd.c b/src/gallium/drivers/panfrost/pan_sfbd.c index 8bfeee1d594..c82bc9b28ee 100644 --- a/src/gallium/drivers/panfrost/pan_sfbd.c +++ b/src/gallium/drivers/panfrost/pan_sfbd.c @@ -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); diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c index b842097304c..1cf6f774fff 100644 --- a/src/panfrost/lib/pan_texture.c +++ b/src/panfrost/lib/pan_texture.c @@ -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); diff --git a/src/panfrost/lib/pan_texture.h b/src/panfrost/lib/pan_texture.h index b4032f849b2..943c9d06f1b 100644 --- a/src/panfrost/lib/pan_texture.h +++ b/src/panfrost/lib/pan_texture.h @@ -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