panfrost: Tiled to linear layout conversion
Tiling is expensive, so this patch converts textures that appear to be used for streaming to a linear layout. Performance of mpv is significantly improved, with software-decoded 1080p mp4 playback on RK3288 going from 30fps to 50fps when testing with `--untimed --no-audio`. To keep things simple, conversion only happens when updating the whole texture and no mipmapping is used. v2: Make it clear that the heuristic doesn't rely on a texture being uninitialized, since layout switching code can get confusing (Alyssa). Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4628>
This commit is contained in:
@@ -427,6 +427,7 @@ panfrost_resource_create_bo(struct panfrost_device *dev, struct panfrost_resourc
|
||||
/* Set the layout appropriately */
|
||||
assert(!(must_tile && !can_tile)); /* must_tile => can_tile */
|
||||
pres->layout = ((can_tile && should_tile) || must_tile) ? MALI_TEXTURE_TILED : MALI_TEXTURE_LINEAR;
|
||||
pres->layout_constant = must_tile || !can_tile;
|
||||
|
||||
size_t bo_size;
|
||||
|
||||
@@ -725,14 +726,48 @@ panfrost_transfer_unmap(struct pipe_context *pctx,
|
||||
} else if (prsrc->layout == MALI_TEXTURE_TILED) {
|
||||
assert(transfer->box.depth == 1);
|
||||
|
||||
panfrost_store_tiled_image(
|
||||
bo->cpu + prsrc->slices[transfer->level].offset,
|
||||
trans->map,
|
||||
transfer->box.x, transfer->box.y,
|
||||
transfer->box.width, transfer->box.height,
|
||||
prsrc->slices[transfer->level].stride,
|
||||
transfer->stride,
|
||||
prsrc->internal_format);
|
||||
/* Do we overwrite the entire resource? If so,
|
||||
* we don't need an intermediate blit so it's a
|
||||
* good time to switch the layout. */
|
||||
|
||||
bool discards_content = prsrc->base.last_level == 0
|
||||
&& transfer->box.width == prsrc->base.width0
|
||||
&& transfer->box.height == prsrc->base.height0
|
||||
&& transfer->box.x == 0
|
||||
&& transfer->box.y == 0
|
||||
&& !prsrc->layout_constant;
|
||||
|
||||
/* It also serves as a good heuristic for
|
||||
* streaming textures (e.g. in video players),
|
||||
* but we could do better */
|
||||
|
||||
if (discards_content)
|
||||
++prsrc->layout_updates;
|
||||
|
||||
if (prsrc->layout_updates >= LAYOUT_CONVERT_THRESHOLD)
|
||||
{
|
||||
prsrc->layout = MALI_TEXTURE_LINEAR;
|
||||
|
||||
util_copy_rect(
|
||||
bo->cpu + prsrc->slices[0].offset,
|
||||
prsrc->base.format,
|
||||
prsrc->slices[0].stride,
|
||||
0, 0,
|
||||
transfer->box.width,
|
||||
transfer->box.height,
|
||||
trans->map,
|
||||
transfer->stride,
|
||||
0, 0);
|
||||
} else {
|
||||
panfrost_store_tiled_image(
|
||||
bo->cpu + prsrc->slices[transfer->level].offset,
|
||||
trans->map,
|
||||
transfer->box.x, transfer->box.y,
|
||||
transfer->box.width, transfer->box.height,
|
||||
prsrc->slices[transfer->level].stride,
|
||||
transfer->stride,
|
||||
prsrc->internal_format);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -34,6 +34,8 @@
|
||||
#include "drm-uapi/drm.h"
|
||||
#include "util/u_range.h"
|
||||
|
||||
#define LAYOUT_CONVERT_THRESHOLD 8
|
||||
|
||||
struct panfrost_resource {
|
||||
struct pipe_resource base;
|
||||
struct {
|
||||
@@ -57,9 +59,15 @@ struct panfrost_resource {
|
||||
/* Internal layout (tiled?) */
|
||||
enum mali_texture_layout layout;
|
||||
|
||||
/* Whether the layout can be changed */
|
||||
bool layout_constant;
|
||||
|
||||
/* Is transaciton elimination enabled? */
|
||||
bool checksummed;
|
||||
|
||||
/* Used to decide when to convert to another layout */
|
||||
uint16_t layout_updates;
|
||||
|
||||
enum pipe_format internal_format;
|
||||
|
||||
/* Cached min/max values for index buffers */
|
||||
|
Reference in New Issue
Block a user