panvk: Fix the hierarchy_mask selection

Always enable the level covering the whole FB, and disable the finest
levels if we don't have enough to cover everything.

This is suboptimal for small primitives, since it might force primitives
to be walked multiple times even if they don't cover the the tile being
processed. On the other hand, it's hard to guess the draw pattern, so
it's probably good enough for now.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31682>
This commit is contained in:
Boris Brezillon 2024-10-16 14:46:15 +02:00 committed by Marge Bot
parent ad111aed29
commit 27bde761a7
3 changed files with 47 additions and 9 deletions

View file

@ -16,6 +16,7 @@
#include "panvk_cmd_alloc.h"
#include "panvk_cmd_buffer.h"
#include "panvk_cmd_desc_state.h"
#include "panvk_cmd_draw.h"
#include "panvk_cmd_fb_preload.h"
#include "panvk_cmd_meta.h"
#include "panvk_device.h"
@ -742,16 +743,9 @@ get_tiler_desc(struct panvk_cmd_buffer *cmdbuf)
unsigned max_levels = tiler_features.max_levels;
assert(max_levels >= 2);
/* TODO: Select hierarchy mask more effectively */
cfg.hierarchy_mask = (max_levels >= 8) ? 0xFF : 0x28;
/* For large framebuffers, disable the smallest bin size to
* avoid pathological tiler memory usage.
*/
cfg.hierarchy_mask = panvk_select_tiler_hierarchy_mask(cmdbuf);
cfg.fb_width = cmdbuf->state.gfx.render.fb.info.width;
cfg.fb_height = cmdbuf->state.gfx.render.fb.info.height;
if (MAX2(cfg.fb_width, cfg.fb_height) >= 4096)
cfg.hierarchy_mask &= ~1;
cfg.sample_pattern =
pan_sample_pattern(cmdbuf->state.gfx.render.fb.info.nr_samples);

View file

@ -32,6 +32,7 @@
#include "panvk_cmd_alloc.h"
#include "panvk_cmd_buffer.h"
#include "panvk_cmd_desc_state.h"
#include "panvk_cmd_draw.h"
#include "panvk_cmd_fb_preload.h"
#include "panvk_cmd_pool.h"
#include "panvk_cmd_push_constant.h"
@ -252,7 +253,7 @@ panvk_per_arch(cmd_prepare_tiler_context)(struct panvk_cmd_buffer *cmdbuf,
}
pan_pack(&batch->tiler.ctx_templ, TILER_CONTEXT, cfg) {
cfg.hierarchy_mask = 0x28;
cfg.hierarchy_mask = panvk_select_tiler_hierarchy_mask(cmdbuf);
cfg.fb_width = fbinfo->width;
cfg.fb_height = fbinfo->height;
cfg.heap = batch->tiler.heap_desc.gpu;

View file

@ -0,0 +1,43 @@
/*
* Copyright © 2024 Collabora Ltd.
* SPDX-License-Identifier: MIT
*/
#ifndef PANVK_CMD_DRAW_H
#define PANVK_CMD_DRAW_H
#ifndef PAN_ARCH
#error "PAN_ARCH must be defined"
#endif
#include "panvk_cmd_buffer.h"
#include "panvk_physical_device.h"
#include "pan_props.h"
static inline uint32_t
panvk_select_tiler_hierarchy_mask(struct panvk_cmd_buffer *cmdbuf)
{
struct panvk_physical_device *phys_dev =
to_panvk_physical_device(cmdbuf->vk.base.device->physical);
struct panfrost_tiler_features tiler_features =
panfrost_query_tiler_features(&phys_dev->kmod.props);
uint32_t max_fb_wh = MAX2(cmdbuf->state.gfx.render.fb.info.width,
cmdbuf->state.gfx.render.fb.info.height);
uint32_t last_hierarchy_bit = util_last_bit(DIV_ROUND_UP(max_fb_wh, 16));
uint32_t hierarchy_mask = BITFIELD_MASK(tiler_features.max_levels);
/* Always enable the level covering the whole FB, and disable the finest
* levels if we don't have enough to cover everything.
* This is suboptimal for small primitives, since it might force
* primitives to be walked multiple times even if they don't cover the
* the tile being processed. On the other hand, it's hard to guess
* the draw pattern, so it's probably good enough for now.
*/
if (last_hierarchy_bit > tiler_features.max_levels)
hierarchy_mask <<= last_hierarchy_bit - tiler_features.max_levels;
return hierarchy_mask;
}
#endif