From 39ac7df612b6a5b9d0477d600ce5134502bd00b9 Mon Sep 17 00:00:00 2001 From: Utku Iseri Date: Mon, 13 Oct 2025 12:39:38 +0200 Subject: [PATCH] panfrost,panvk: distinguish fbd bounding box from framebuffer size On panvk, we can use the render area to set fbd bbox extents instead of setting them based on image sizes. Doing this improves partial updates (eg. loadOp:load with renderArea < image_size) of AFBC render targets. This commit introduces a new structure for this setting and uses it on both panvk and panfrost. We can't reuse the existing extent here as that is based on viewport+scissor, which can change within a renderpass/batch, which causes issues on panfrost. No functional changes for panfrost, as it doesn't have an equivalent to renderpass::renderArea so we can't do the same thing there, it still uses the entire framebuffer extent. Reviewed-by: Lars-Ivar Hesselberg Simonsen Part-of: --- src/gallium/drivers/panfrost/pan_job.c | 2 ++ src/panfrost/lib/pan_desc.c | 7 ++++--- src/panfrost/lib/pan_desc.h | 17 ++++++++++++----- src/panfrost/vulkan/panvk_vX_cmd_draw.c | 2 ++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c index 0905209bde9..86ba62d549e 100644 --- a/src/gallium/drivers/panfrost/pan_job.c +++ b/src/gallium/drivers/panfrost/pan_job.c @@ -486,6 +486,8 @@ panfrost_batch_to_fb_info(const struct panfrost_batch *batch, fb->z_tile_buf_budget = dev->optimal_z_tib_size; fb->width = batch->key.width; fb->height = batch->key.height; + fb->frame_bounding_box.maxx = batch->key.width - 1; + fb->frame_bounding_box.maxy = batch->key.height - 1; fb->draw_extent.minx = batch->minx; fb->draw_extent.miny = batch->miny; fb->draw_extent.maxx = batch->maxx - 1; diff --git a/src/panfrost/lib/pan_desc.c b/src/panfrost/lib/pan_desc.c index b606b0d9203..074850f3372 100644 --- a/src/panfrost/lib/pan_desc.c +++ b/src/panfrost/lib/pan_desc.c @@ -1089,9 +1089,10 @@ GENX(pan_emit_fbd)(const struct pan_fb_info *fb, unsigned layer_idx, #endif cfg.width = fb->width; cfg.height = fb->height; - cfg.bound_max_x = fb->width - 1; - cfg.bound_max_y = fb->height - 1; - + cfg.bound_min_x = fb->frame_bounding_box.minx; + cfg.bound_min_y = fb->frame_bounding_box.miny; + cfg.bound_max_x = fb->frame_bounding_box.maxx; + cfg.bound_max_y = fb->frame_bounding_box.maxy; cfg.effective_tile_size = fb->tile_size; /* Ensure we cover the samples on the edge for 16x MSAA */ cfg.tie_break_rule = fb->nr_samples == 16 ? diff --git a/src/panfrost/lib/pan_desc.h b/src/panfrost/lib/pan_desc.h index 5cf3946b8e0..b021ebc523a 100644 --- a/src/panfrost/lib/pan_desc.h +++ b/src/panfrost/lib/pan_desc.h @@ -129,13 +129,20 @@ struct pan_fb_bifrost_info { } pre_post; }; +struct pan_bbox { + unsigned minx, miny, maxx, maxy; +}; + struct pan_fb_info { unsigned width, height; - /* Draw-extent controlled by viewports/scissors. */ - struct { - /* Max values are exclusive */ - unsigned minx, miny, maxx, maxy; - } draw_extent; + /* Draw-extent controlled by viewports/scissors. + * Max values are exclusive */ + struct pan_bbox draw_extent; + /* frame_bounding_box controls the bounding box in the framebuffer + * descriptor for the entire pass. This is being controlled by the + * renderArea of a renderpass in Vulkan. On GL, this covers the + * entire frame. Max values are exclusive. */ + struct pan_bbox frame_bounding_box; unsigned nr_samples; unsigned force_samples; /* samples used for rasterization */ unsigned rt_count; diff --git a/src/panfrost/vulkan/panvk_vX_cmd_draw.c b/src/panfrost/vulkan/panvk_vX_cmd_draw.c index 5d48b5529b2..10cc8444cec 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_draw.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_draw.c @@ -343,6 +343,8 @@ panvk_per_arch(cmd_init_render_state)(struct panvk_cmd_buffer *cmdbuf, fbinfo->draw_extent.maxy = pRenderingInfo->renderArea.offset.y + pRenderingInfo->renderArea.extent.height - 1; + fbinfo->frame_bounding_box = fbinfo->draw_extent; + if (state->render.bound_attachments) { fbinfo->width = att_width; fbinfo->height = att_height;