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> template <chip CHIP>
static void static void
fdl6_lrz_layout_init(struct fdl_lrz_layout *lrz_layout, 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, const struct fd_dev_info *dev_info, uint32_t lrz_offset,
uint32_t array_layers) uint32_t array_layers)
{ {
unsigned width = layout->width0; unsigned width = layout->width0 + extra_width;
unsigned height = layout->height0; unsigned height = layout->height0 + extra_height;
/* LRZ buffer is super-sampled */ /* LRZ buffer is super-sampled */
switch (layout->nr_samples) { switch (layout->nr_samples) {

View file

@ -650,6 +650,7 @@ struct tu_bin_size_params {
bool force_lrz_write_dis; bool force_lrz_write_dis;
enum a6xx_buffers_location buffers_location; enum a6xx_buffers_location buffers_location;
enum a6xx_lrz_feedback_mask lrz_feedback_zmode_mask; enum a6xx_lrz_feedback_mask lrz_feedback_zmode_mask;
bool force_lrz_dis;
}; };
template <chip CHIP> template <chip CHIP>
@ -674,7 +675,8 @@ tu6_emit_bin_size(struct tu_cs *cs,
.render_mode = p.render_mode, .render_mode = p.render_mode,
.force_lrz_write_dis = p.force_lrz_write_dis, .force_lrz_write_dis = p.force_lrz_write_dis,
.lrz_feedback_zmode_mask = .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, 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 && views <= MAX_HW_SCALED_VIEWS && !cmd->state.rp.shared_viewport &&
bin_is_scaled; 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>( tu6_emit_bin_size<CHIP>(
cs, tiling->tile0.width, tiling->tile0.height, 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, .force_lrz_write_dis = !phys_dev->info->a6xx.has_lrz_feedback,
.buffers_location = BUFFERS_IN_GMEM, .buffers_location = BUFFERS_IN_GMEM,
.lrz_feedback_zmode_mask = .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 : ? (hw_binning ? LRZ_FEEDBACK_EARLY_Z_OR_EARLY_Z_LATE_Z :
LRZ_FEEDBACK_EARLY_Z_LATE_Z) LRZ_FEEDBACK_EARLY_Z_LATE_Z)
: LRZ_FEEDBACK_NONE, : LRZ_FEEDBACK_NONE,
.force_lrz_dis = CHIP >= A7XX && disable_lrz,
}); });
tu_cs_emit_regs(cs, 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); const struct util_format_description *desc = util_format_description(image->layout[0].format);
if (util_format_has_depth(desc) && device->use_lrz) { 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], fdl6_lrz_layout_init<CHIP>(&image->lrz_layout, &image->layout[0],
extra_width, extra_height,
device->physical_device->info, device->physical_device->info,
image->total_size, image->vk.array_layers); 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) if (!has_gpu_tracking && !clears_depth)
return; 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 /* 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 * depth attachment, there are any secondaries, and GPU tracking is
* enabled, in order not to rely on loadOp state which doesn't exist with * 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 /* FDM isn't compatible with LRZ, because the LRZ image uses the original
* resolution and we would need to use the low resolution. * 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; shader->fs.lrz.status = TU_LRZ_FORCE_DISABLE_LRZ;
if (!fs->fs.early_fragment_tests && if (!fs->fs.early_fragment_tests &&
(fs->no_earlyz || fs->writes_stencilref)) { (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); struct fd_screen *screen = fd_screen(rsc->b.b.screen);
uint32_t nr_layers = 1; uint32_t nr_layers = 1;
fdl6_lrz_layout_init<CHIP>(&rsc->lrz_layout, &rsc->layout, screen->info, 0, fdl6_lrz_layout_init<CHIP>(&rsc->lrz_layout, &rsc->layout, 0, 0,
nr_layers); screen->info, 0, nr_layers);
rsc->lrz = fd_bo_new(screen->dev, rsc->lrz_layout.lrz_total_size, rsc->lrz = fd_bo_new(screen->dev, rsc->lrz_layout.lrz_total_size,
FD_BO_NOMAP, "lrz"); FD_BO_NOMAP, "lrz");