tu: Enable LRZ with FDM

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36475>
This commit is contained in:
Connor Abbott 2025-07-30 14:52:53 -04:00 committed by Marge Bot
parent b34b089ca1
commit 2797069e9a
6 changed files with 50 additions and 9 deletions

View file

@ -33,12 +33,13 @@ ENDC;
template <chip CHIP>
static void
fdl6_lrz_layout_init(struct fdl_lrz_layout *lrz_layout,
struct fdl_layout *layout,
struct fdl_layout *layout, uint32_t extra_width,
uint32_t extra_height,
const struct fd_dev_info *dev_info, uint32_t lrz_offset,
uint32_t array_layers)
{
unsigned width = layout->width0;
unsigned height = layout->height0;
unsigned width = layout->width0 + extra_width;
unsigned height = layout->height0 + extra_height;
/* LRZ buffer is super-sampled */
switch (layout->nr_samples) {

View file

@ -650,6 +650,7 @@ struct tu_bin_size_params {
bool force_lrz_write_dis;
enum a6xx_buffers_location buffers_location;
enum a6xx_lrz_feedback_mask lrz_feedback_zmode_mask;
bool force_lrz_dis;
};
template <chip CHIP>
@ -674,7 +675,8 @@ tu6_emit_bin_size(struct tu_cs *cs,
.render_mode = p.render_mode,
.force_lrz_write_dis = p.force_lrz_write_dis,
.lrz_feedback_zmode_mask =
p.lrz_feedback_zmode_mask, ));
p.lrz_feedback_zmode_mask,
.force_lrz_dis = p.force_lrz_dis));
}
tu_cs_emit_regs(cs, RB_CNTL(CHIP,
@ -1270,6 +1272,17 @@ tu6_emit_tile_select(struct tu_cmd_buffer *cmd,
views <= MAX_HW_SCALED_VIEWS && !cmd->state.rp.shared_viewport &&
bin_is_scaled;
/* We cannot support LRZ if we cannot use HW bin scaling and the bin is
* scaled (i.e. less than full resolution)
*/
bool disable_lrz = bin_is_scaled && !bin_scale_en;
/* We cannot support LRZ for the first row and column because the offset
* required wouldn't be aligned to HW requirements.
*/
if (fdm_offsets && (tile->pos.x == 0 || tile->pos.y == 0))
disable_lrz = true;
tu6_emit_bin_size<CHIP>(
cs, tiling->tile0.width, tiling->tile0.height,
{
@ -1277,10 +1290,11 @@ tu6_emit_tile_select(struct tu_cmd_buffer *cmd,
.force_lrz_write_dis = !phys_dev->info->a6xx.has_lrz_feedback,
.buffers_location = BUFFERS_IN_GMEM,
.lrz_feedback_zmode_mask =
phys_dev->info->a6xx.has_lrz_feedback
phys_dev->info->a6xx.has_lrz_feedback && !bin_is_scaled
? (hw_binning ? LRZ_FEEDBACK_EARLY_Z_OR_EARLY_Z_LATE_Z :
LRZ_FEEDBACK_EARLY_Z_LATE_Z)
: LRZ_FEEDBACK_NONE,
.force_lrz_dis = CHIP >= A7XX && disable_lrz,
});
tu_cs_emit_regs(cs,

View file

@ -587,7 +587,24 @@ tu_image_update_layout(struct tu_device *device, struct tu_image *image,
const struct util_format_description *desc = util_format_description(image->layout[0].format);
if (util_format_has_depth(desc) && device->use_lrz) {
/* If FDM offset is enabled, then the LRZ image will be shifted over. We
* have to overallocate it, but we have no idea how large the tiles it's
* used with will be. Try to calculate the worst-case width and height.
*/
uint32_t extra_width = 0, extra_height = 0;
if (image->vk.create_flags &
VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_EXT) {
uint32_t gmem_pixels =
device->physical_device->gmem_size /
(desc->block.bits / 8);
extra_width = gmem_pixels /
device->physical_device->info->tile_align_h;
extra_height = gmem_pixels /
device->physical_device->info->tile_align_w;
}
fdl6_lrz_layout_init<CHIP>(&image->lrz_layout, &image->layout[0],
extra_width, extra_height,
device->physical_device->info,
image->total_size, image->vk.array_layers);

View file

@ -210,6 +210,14 @@ tu_lrz_init_state(struct tu_cmd_buffer *cmd,
if (!has_gpu_tracking && !clears_depth)
return;
/* Reusing previous state doesn't work with FDM offset because the LRZ
* image is offsetted.
*/
if ((view->image->vk.create_flags &
VK_IMAGE_CREATE_FRAGMENT_DENSITY_MAP_OFFSET_BIT_EXT) &&
!clears_depth)
return;
/* We need to always have an LRZ view just to disable it if there is a
* depth attachment, there are any secondaries, and GPU tracking is
* enabled, in order not to rely on loadOp state which doesn't exist with

View file

@ -2840,9 +2840,10 @@ tu_shader_create(struct tu_device *dev,
/* FDM isn't compatible with LRZ, because the LRZ image uses the original
* resolution and we would need to use the low resolution.
*
* TODO: Use a patchpoint to only disable LRZ for scaled bins.
* TODO: Use a patchpoint to only disable LRZ for scaled bins. On a7xx
* we use GRAS_SC_BIN_CNTL::FORCE_LRZ_DIS instead.
*/
if (key->fragment_density_map)
if (key->fragment_density_map && dev->physical_device->info->chip < 7)
shader->fs.lrz.status = TU_LRZ_FORCE_DISABLE_LRZ;
if (!fs->fs.early_fragment_tests &&
(fs->no_earlyz || fs->writes_stencilref)) {

View file

@ -243,8 +243,8 @@ setup_lrz(struct fd_resource *rsc)
{
struct fd_screen *screen = fd_screen(rsc->b.b.screen);
uint32_t nr_layers = 1;
fdl6_lrz_layout_init<CHIP>(&rsc->lrz_layout, &rsc->layout, screen->info, 0,
nr_layers);
fdl6_lrz_layout_init<CHIP>(&rsc->lrz_layout, &rsc->layout, 0, 0,
screen->info, 0, nr_layers);
rsc->lrz = fd_bo_new(screen->dev, rsc->lrz_layout.lrz_total_size,
FD_BO_NOMAP, "lrz");