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:
Icecream95
2020-04-19 15:44:17 +12:00
committed by Marge Bot
parent fafc305600
commit 7ef648c0f3
2 changed files with 51 additions and 8 deletions

View File

@@ -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);
}
}
}
}

View File

@@ -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 */