Mesa (main): panfrost: Use implementation-specific tile size
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Jul 13 19:14:02 UTC 2022
Module: Mesa
Branch: main
Commit: 96d65b47c715155bb0403f3e0b5555b348d68539
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=96d65b47c715155bb0403f3e0b5555b348d68539
Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date: Thu Jul 7 18:39:17 2022 -0400
panfrost: Use implementation-specific tile size
The physical tile buffer size (and hence the maximum available tilebuffer size)
are implementation-defined. Track this information on the device so we can
correctly select tile sizes, instead of hardcoding the value for Midgard.
Implementation values are pulled from the "Tile bits/pixel" row of the public
Mali data sheet [1]. That row lists the maximum number of bits available for a
pixel given the maximum tile size and pipelining. For currently supported
hardware (v9 and older), that maximum tile size is 16x16. So those values should
be multiplied by (16 * 16 * 2) / 8 to get the physical size in bytes.
This may improve Bifrost/Valhall performance on workloads using multiple render
targets. It also gets us ready for the dazzling array of tile sizes available
with v10.
[1] https://developer.arm.com/documentation/102849/latest/
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 | 5 ++--
src/panfrost/lib/pan_device.h | 6 +++++
src/panfrost/lib/pan_props.c | 53 ++++++++++++++++++++++++++++++-------------
3 files changed, 46 insertions(+), 18 deletions(-)
diff --git a/src/panfrost/lib/pan_cs.c b/src/panfrost/lib/pan_cs.c
index dbec8c4a3fc..233af107256 100644
--- a/src/panfrost/lib/pan_cs.c
+++ b/src/panfrost/lib/pan_cs.c
@@ -709,7 +709,8 @@ GENX(pan_emit_fbd)(const struct panfrost_device *dev,
#endif
unsigned bytes_per_pixel = pan_cbuf_bytes_per_pixel(fb);
- unsigned tile_size = pan_select_max_tile_size(4096, bytes_per_pixel);
+ unsigned tile_size = pan_select_max_tile_size(dev->optimal_tib_size,
+ bytes_per_pixel);
/* Clamp tile size to hardware limits */
tile_size = MIN2(tile_size, 16 * 16);
@@ -717,7 +718,7 @@ GENX(pan_emit_fbd)(const struct panfrost_device *dev,
/* 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");
+ assert(cbuf_allocation <= dev->optimal_tib_size && "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);
diff --git a/src/panfrost/lib/pan_device.h b/src/panfrost/lib/pan_device.h
index 0cbebe09820..ad18d154a2c 100644
--- a/src/panfrost/lib/pan_device.h
+++ b/src/panfrost/lib/pan_device.h
@@ -165,6 +165,9 @@ struct panfrost_model {
*/
uint32_t min_rev_anisotropic;
+ /* Default tilebuffer size in bytes for the model. */
+ unsigned tilebuffer_size;
+
struct {
/* The GPU lacks the capability for hierarchical tiling, without
* an "Advanced Tiling Unit", instead requiring a single bin
@@ -193,6 +196,9 @@ struct panfrost_device {
*/
unsigned core_id_range;
+ /* Maximum tilebuffer size in bytes for optimal performance. */
+ unsigned optimal_tib_size;
+
unsigned thread_tls_alloc;
struct panfrost_tiler_features tiler_features;
const struct panfrost_model *model;
diff --git a/src/panfrost/lib/pan_props.c b/src/panfrost/lib/pan_props.c
index 1627e55e4b8..2c00b1b06a3 100644
--- a/src/panfrost/lib/pan_props.c
+++ b/src/panfrost/lib/pan_props.c
@@ -42,32 +42,33 @@
#define NO_ANISO (~0)
#define HAS_ANISO (0)
-#define MODEL(gpu_id_, shortname, counters_, min_rev_anisotropic_, quirks_) \
+#define MODEL(gpu_id_, shortname, counters_, min_rev_anisotropic_, tib_size_, quirks_) \
{ \
.gpu_id = gpu_id_, \
.name = "Mali-" shortname " (Panfrost)", \
.performance_counters = counters_, \
.min_rev_anisotropic = min_rev_anisotropic_, \
+ .tilebuffer_size = tib_size_, \
.quirks = quirks_, \
}
/* Table of supported Mali GPUs */
const struct panfrost_model panfrost_model_list[] = {
- MODEL(0x720, "T720", "T72x", NO_ANISO, { .no_hierarchical_tiling = true }),
- MODEL(0x750, "T760", "T76x", NO_ANISO, {}),
- MODEL(0x820, "T820", "T82x", NO_ANISO, { .no_hierarchical_tiling = true }),
- MODEL(0x830, "T830", "T83x", NO_ANISO, { .no_hierarchical_tiling = true }),
- MODEL(0x860, "T860", "T86x", NO_ANISO, {}),
- MODEL(0x880, "T880", "T88x", NO_ANISO, {}),
-
- MODEL(0x6000, "G71", "TMIx", NO_ANISO, {}),
- MODEL(0x6221, "G72", "THEx", 0x0030 /* r0p3 */, {}),
- MODEL(0x7090, "G51", "TSIx", 0x1010 /* r1p1 */, {}),
- MODEL(0x7093, "G31", "TDVx", HAS_ANISO, {}),
- MODEL(0x7211, "G76", "TNOx", HAS_ANISO, {}),
- MODEL(0x7212, "G52", "TGOx", HAS_ANISO, {}),
- MODEL(0x7402, "G52 r1", "TGOx", HAS_ANISO, {}),
- MODEL(0x9093, "G57", "TNAx", HAS_ANISO, {}),
+ MODEL(0x720, "T720", "T72x", NO_ANISO, 8192, { .no_hierarchical_tiling = true }),
+ MODEL(0x750, "T760", "T76x", NO_ANISO, 8192, {}),
+ MODEL(0x820, "T820", "T82x", NO_ANISO, 8192, { .no_hierarchical_tiling = true }),
+ MODEL(0x830, "T830", "T83x", NO_ANISO, 8192, { .no_hierarchical_tiling = true }),
+ MODEL(0x860, "T860", "T86x", NO_ANISO, 8192, {}),
+ MODEL(0x880, "T880", "T88x", NO_ANISO, 8192, {}),
+
+ MODEL(0x6000, "G71", "TMIx", NO_ANISO, 8192, {}),
+ MODEL(0x6221, "G72", "THEx", 0x0030 /* r0p3 */, 16384, {}),
+ MODEL(0x7090, "G51", "TSIx", 0x1010 /* r1p1 */, 16384, {}),
+ MODEL(0x7093, "G31", "TDVx", HAS_ANISO, 16384, {}),
+ MODEL(0x7211, "G76", "TNOx", HAS_ANISO, 16384, {}),
+ MODEL(0x7212, "G52", "TGOx", HAS_ANISO, 16384, {}),
+ MODEL(0x7402, "G52 r1", "TGOx", HAS_ANISO, 16384, {}),
+ MODEL(0x9093, "G57", "TNAx", HAS_ANISO, 16384, {}),
};
#undef NO_ANISO
@@ -257,6 +258,25 @@ panfrost_query_afbc(int fd, unsigned arch)
return (arch >= 5) && (reg == 0);
}
+/*
+ * To pipeline multiple tiles, a given tile may use at most half of the tile
+ * buffer. This function returns the optimal size (assuming pipelining).
+ *
+ * For Mali-G510 and Mali-G310, we will need extra logic to query the tilebuffer
+ * size for the particular variant. The CORE_FEATURES register might help.
+ */
+static unsigned
+panfrost_query_optimal_tib_size(const struct panfrost_device *dev)
+{
+ /* Preconditions ensure the returned value is a multiple of 1 KiB, the
+ * granularity of the colour buffer allocation field.
+ */
+ assert(dev->model->tilebuffer_size >= 2048);
+ assert(util_is_power_of_two_nonzero(dev->model->tilebuffer_size));
+
+ return dev->model->tilebuffer_size / 2;
+}
+
void
panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev)
{
@@ -269,6 +289,7 @@ panfrost_open_device(void *memctx, int fd, struct panfrost_device *dev)
dev->kernel_version = drmGetVersion(fd);
dev->revision = panfrost_query_gpu_revision(fd);
dev->model = panfrost_get_model(dev->gpu_id);
+ dev->optimal_tib_size = panfrost_query_optimal_tib_size(dev);
dev->compressed_formats = panfrost_query_compressed_formats(fd);
dev->tiler_features = panfrost_query_tiler_features(fd);
dev->has_afbc = panfrost_query_afbc(fd, dev->arch);
More information about the mesa-commit
mailing list