Mesa (main): panfrost: Make pan_select_max_tile_size O(1)
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jul 13 19:14:02 UTC 2022
Module: Mesa
Branch: main
Commit: d67681c4ead6f6fd33beda7643056df355109312
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=d67681c4ead6f6fd33beda7643056df355109312
Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date: Tue Jul 12 16:45:09 2022 -0400
panfrost: Make pan_select_max_tile_size O(1)
Separate out "calculating the size of each pixel", "selecting a tile size", and
"calculating the colour buffer allocation". Then implement the middle (selecting
a tile size) with a simple constant time expression, rather than a loop. There's
a bit of related clean up in here.
Signed-off-by: Alyssa Rosenzweig <alyssa at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17432>
---
src/panfrost/lib/pan_cs.c | 50 +++++++++++++++++++++++++++++------------------
1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/src/panfrost/lib/pan_cs.c b/src/panfrost/lib/pan_cs.c
index 377fef670c9..dbec8c4a3fc 100644
--- a/src/panfrost/lib/pan_cs.c
+++ b/src/panfrost/lib/pan_cs.c
@@ -319,34 +319,37 @@ pan_bytes_per_pixel_tib(enum pipe_format format)
}
static unsigned
-pan_internal_cbuf_size(const struct pan_fb_info *fb,
- unsigned *tile_size)
+pan_cbuf_bytes_per_pixel(const struct pan_fb_info *fb)
{
- unsigned total_size = 0;
+ unsigned sum = 0;
- *tile_size = 16 * 16;
for (int cb = 0; cb < fb->rt_count; ++cb) {
const struct pan_image_view *rt = fb->rts[cb].view;
if (!rt)
continue;
- total_size += pan_bytes_per_pixel_tib(rt->format) *
- rt->nr_samples * (*tile_size);
+ sum += pan_bytes_per_pixel_tib(rt->format) * rt->nr_samples;
}
- /* We have a 4KB budget, let's reduce the tile size until it fits. */
- while (total_size > 4096) {
- total_size >>= 1;
- *tile_size >>= 1;
- }
+ return sum;
+}
- /* Align on 1k. */
- total_size = ALIGN_POT(total_size, 1024);
+/*
+ * Select the largest tile size that fits within the tilebuffer budget.
+ * Formally, maximize (pixels per tile) such that it is a power of two and
+ *
+ * (bytes per pixel) (pixels per tile) <= (max bytes per tile)
+ *
+ * A bit of algebra gives the following formula.
+ */
+static unsigned
+pan_select_max_tile_size(unsigned tile_buffer_bytes, unsigned bytes_per_pixel)
+{
+ assert(util_is_power_of_two_nonzero(tile_buffer_bytes));
+ assert(tile_buffer_bytes >= 1024);
- /* Minimum tile size is 4x4. */
- assert(*tile_size >= 4 * 4);
- return total_size;
+ return tile_buffer_bytes >> util_logbase2_ceil(bytes_per_pixel);
}
static enum mali_color_format
@@ -705,8 +708,17 @@ GENX(pan_emit_fbd)(const struct panfrost_device *dev,
pan_section_ptr(fbd, FRAMEBUFFER, LOCAL_STORAGE));
#endif
- unsigned tile_size;
- unsigned internal_cbuf_size = pan_internal_cbuf_size(fb, &tile_size);
+ unsigned bytes_per_pixel = pan_cbuf_bytes_per_pixel(fb);
+ unsigned tile_size = pan_select_max_tile_size(4096, bytes_per_pixel);
+
+ /* Clamp tile size to hardware limits */
+ tile_size = MIN2(tile_size, 16 * 16);
+ assert(tile_size >= 4 * 4);
+
+ /* Colour buffer allocations must be 1K aligned. */
+ unsigned cbuf_allocation = ALIGN_POT(bytes_per_pixel * tile_size, 1024);
+ assert(cbuf_allocation <= 4096 && "tile too big");
+
int crc_rt = GENX(pan_select_crc_rt)(fb, tile_size);
bool has_zs_crc_ext = (fb->zs.view.zs || fb->zs.view.s || crc_rt >= 0);
@@ -739,7 +751,7 @@ GENX(pan_emit_fbd)(const struct panfrost_device *dev,
cfg.z_clear = fb->zs.clear_value.depth;
cfg.s_clear = fb->zs.clear_value.stencil;
- cfg.color_buffer_allocation = internal_cbuf_size;
+ cfg.color_buffer_allocation = cbuf_allocation;
cfg.sample_count = fb->nr_samples;
cfg.sample_pattern = pan_sample_pattern(fb->nr_samples);
cfg.z_write_enable = (fb->zs.view.zs && !fb->zs.discard.z);
More information about the mesa-commit
mailing list