mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 19:40:10 +01:00
fdno/resource: Rewrite layout selection for allocation
The previous code had a number of errors, the most glaring of which was forcing linear when it was one of the possible layouts requested. When modifiers are being used, a list of _acceptable_ modifiers is supplied; it's up to the driver to then make a decision as to which it thinks is most optimal. Normally we would select between linear/tiled/UBWC in ascending order of preference according to what's possible, however we can't use a tiled layout with explicit modifiers as there is no modifier token defined for it. Rewrite the layout-selection mechanism to always try to do the most optimal thing. If the use flags force us to, or we have a shared resource without explicit modifiers, we use linear. Failing that, we use UBWC wherever possible; if this is not possible, we use tiled for internal resources only or linear for shared resources. v2 (Rob): respect FD_FORMAT_MOD_QCOM_TILED; do not print perf warning on user choice of disabling UBWC; v3: fix several issues breaking CI tests: revert removal of using MOD_INVALID in various places, and assume implicit modifiers if present; do not attempt to set UBWC flags when screen->tile_mode(prsc) falls back to LINEAR (e.g. for small mip-maps levels); use TILED for implicit modifier case with non-shared resources v4: fix unintended demotion of UBWC, i.e. only check QCOM_COMPRESSED modifier and demote UBWC to less optimal format when using explicit modifiers Signed-off-by: Daniel Stone <daniels@collabora.com> Tested-by: Heinrich Fink <hfink@snap.com> Signed-off-by: Heinrich Fink <hfink@snap.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12595>
This commit is contained in:
parent
f8a37832df
commit
0e15d5af81
1 changed files with 89 additions and 49 deletions
|
|
@ -1118,6 +1118,87 @@ alloc_resource_struct(struct pipe_screen *pscreen,
|
|||
return rsc;
|
||||
}
|
||||
|
||||
enum fd_layout_type {
|
||||
ERROR,
|
||||
LINEAR,
|
||||
TILED,
|
||||
UBWC,
|
||||
};
|
||||
|
||||
static enum fd_layout_type
|
||||
get_best_layout(struct fd_screen *screen, struct pipe_resource *prsc,
|
||||
const struct pipe_resource *tmpl, const uint64_t *modifiers,
|
||||
int count)
|
||||
{
|
||||
bool implicit_modifiers =
|
||||
(count == 0 ||
|
||||
drm_find_modifier(DRM_FORMAT_MOD_INVALID, modifiers, count));
|
||||
|
||||
/* First, find all the conditions which would force us to linear */
|
||||
if (!screen->tile_mode)
|
||||
return LINEAR;
|
||||
|
||||
if (!screen->tile_mode(prsc))
|
||||
return LINEAR;
|
||||
|
||||
if (tmpl->target == PIPE_BUFFER)
|
||||
return LINEAR;
|
||||
|
||||
if (tmpl->bind & PIPE_BIND_LINEAR) {
|
||||
if (tmpl->usage != PIPE_USAGE_STAGING)
|
||||
perf_debug("%" PRSC_FMT ": forcing linear: bind flags",
|
||||
PRSC_ARGS(prsc));
|
||||
return LINEAR;
|
||||
}
|
||||
|
||||
if (FD_DBG(NOTILE))
|
||||
return LINEAR;
|
||||
|
||||
/* Shared resources with implicit modifiers must always be linear */
|
||||
if (implicit_modifiers && (tmpl->bind & PIPE_BIND_SHARED)) {
|
||||
perf_debug("%" PRSC_FMT
|
||||
": forcing linear: shared resource + implicit modifiers",
|
||||
PRSC_ARGS(prsc));
|
||||
return LINEAR;
|
||||
}
|
||||
|
||||
bool ubwc_ok = is_a6xx(screen);
|
||||
if (FD_DBG(NOUBWC))
|
||||
ubwc_ok = false;
|
||||
|
||||
if (ubwc_ok && !implicit_modifiers &&
|
||||
!drm_find_modifier(DRM_FORMAT_MOD_QCOM_COMPRESSED, modifiers, count)) {
|
||||
perf_debug("%" PRSC_FMT
|
||||
": not using UBWC: not in acceptable modifier set",
|
||||
PRSC_ARGS(prsc));
|
||||
ubwc_ok = false;
|
||||
}
|
||||
|
||||
if (ubwc_ok)
|
||||
return UBWC;
|
||||
|
||||
/* We can't use tiled with explicit modifiers, as there is no modifier token
|
||||
* defined for it. But we might internally force tiled allocation using a
|
||||
* private modifier token.
|
||||
*
|
||||
* TODO we should probably also limit TILED in a similar way to UBWC above,
|
||||
* once we have a public modifier token defined.
|
||||
*/
|
||||
if (implicit_modifiers ||
|
||||
drm_find_modifier(FD_FORMAT_MOD_QCOM_TILED, modifiers, count))
|
||||
return TILED;
|
||||
|
||||
if (!drm_find_modifier(DRM_FORMAT_MOD_LINEAR, modifiers, count)) {
|
||||
perf_debug("%" PRSC_FMT ": need linear but not in modifier set",
|
||||
PRSC_ARGS(prsc));
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
perf_debug("%" PRSC_FMT ": not using tiling: explicit modifiers and no UBWC",
|
||||
PRSC_ARGS(prsc));
|
||||
return LINEAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that allocates a resource and resolves its layout (but doesn't
|
||||
* allocate its bo).
|
||||
|
|
@ -1150,61 +1231,20 @@ fd_resource_allocate_and_resolve(struct pipe_screen *pscreen,
|
|||
|
||||
fd_resource_layout_init(prsc);
|
||||
|
||||
#define LINEAR (PIPE_BIND_SCANOUT | PIPE_BIND_LINEAR | PIPE_BIND_DISPLAY_TARGET)
|
||||
|
||||
bool linear = drm_find_modifier(DRM_FORMAT_MOD_LINEAR, modifiers, count);
|
||||
if (linear) {
|
||||
perf_debug("%" PRSC_FMT ": linear: DRM_FORMAT_MOD_LINEAR requested!",
|
||||
PRSC_ARGS(prsc));
|
||||
} else if (tmpl->bind & LINEAR) {
|
||||
if (tmpl->usage != PIPE_USAGE_STAGING)
|
||||
perf_debug("%" PRSC_FMT ": linear: LINEAR bind requested!",
|
||||
PRSC_ARGS(prsc));
|
||||
linear = true;
|
||||
enum fd_layout_type layout =
|
||||
get_best_layout(screen, prsc, tmpl, modifiers, count);
|
||||
if (layout == ERROR) {
|
||||
free(prsc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (FD_DBG(NOTILE))
|
||||
linear = true;
|
||||
|
||||
/* Normally, for non-shared buffers, allow buffer compression if
|
||||
* not shared, otherwise only allow if QCOM_COMPRESSED modifier
|
||||
* is requested:
|
||||
*
|
||||
* TODO we should probably also limit tiled in a similar way,
|
||||
* except we don't have a format modifier for tiled. (We probably
|
||||
* should.)
|
||||
*/
|
||||
bool allow_ubwc = false;
|
||||
if (!linear) {
|
||||
allow_ubwc = drm_find_modifier(DRM_FORMAT_MOD_INVALID, modifiers, count);
|
||||
if (!allow_ubwc) {
|
||||
perf_debug("%" PRSC_FMT
|
||||
": not UBWC: DRM_FORMAT_MOD_INVALID not requested!",
|
||||
PRSC_ARGS(prsc));
|
||||
}
|
||||
if (tmpl->bind & PIPE_BIND_SHARED) {
|
||||
allow_ubwc =
|
||||
drm_find_modifier(DRM_FORMAT_MOD_QCOM_COMPRESSED, modifiers, count);
|
||||
if (!allow_ubwc) {
|
||||
perf_debug("%" PRSC_FMT
|
||||
": not UBWC: shared and DRM_FORMAT_MOD_QCOM_COMPRESSED "
|
||||
"not requested!",
|
||||
PRSC_ARGS(prsc));
|
||||
linear = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allow_ubwc &= !FD_DBG(NOUBWC);
|
||||
|
||||
if (screen->tile_mode && (tmpl->target != PIPE_BUFFER) && !linear) {
|
||||
if (layout >= TILED)
|
||||
rsc->layout.tile_mode = screen->tile_mode(prsc);
|
||||
}
|
||||
if (layout == UBWC)
|
||||
rsc->layout.ubwc = true;
|
||||
|
||||
rsc->internal_format = format;
|
||||
|
||||
rsc->layout.ubwc = rsc->layout.tile_mode && is_a6xx(screen) && allow_ubwc;
|
||||
|
||||
if (prsc->target == PIPE_BUFFER) {
|
||||
assert(prsc->format == PIPE_FORMAT_R8_UNORM);
|
||||
size = prsc->width0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue