Module: Mesa Branch: master Commit: 006ce7358c113b7c269e2cb3c9e483551e7fcea5 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=006ce7358c113b7c269e2cb3c9e483551e7fcea5
Author: Rob Clark <[email protected]> Date: Mon Oct 19 10:20:56 2020 -0700 freedreno/gmem: Respect max-height limits too There is an upper bound on # of bits we have to encode bin height on various gens, which we could exceed with larger GMEM sizes and low byte/pixel formats. The max-width limits are initialized based on corresponding bitfield sizes. Signed-off-by: Rob Clark <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7222> --- src/gallium/drivers/freedreno/freedreno_gmem.c | 47 +++++++++++++++++------- src/gallium/drivers/freedreno/freedreno_screen.h | 1 + src/gallium/drivers/freedreno/gmemtool.c | 3 ++ 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c index b803c0acc81..3f528800ae7 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.c +++ b/src/gallium/drivers/freedreno/freedreno_gmem.c @@ -160,15 +160,6 @@ dump_gmem_state(const struct fd_gmem_stateobj *gmem) gmem->screen->gmemsize_bytes); } -static uint32_t bin_width(struct fd_screen *screen) -{ - if (is_a4xx(screen) || is_a5xx(screen) || is_a6xx(screen)) - return 1024; - if (is_a3xx(screen)) - return 992; - return 512; -} - static unsigned div_align(unsigned num, unsigned denom, unsigned al) { @@ -190,6 +181,12 @@ layout_gmem(struct gmem_key *key, uint32_t nbins_x, uint32_t nbins_y, bin_w = div_align(key->width, nbins_x, screen->tile_alignw); bin_h = div_align(key->height, nbins_y, screen->tile_alignh); + if (bin_w > screen->tile_maxw) + return false; + + if (bin_h > screen->tile_maxh) + return false; + gmem->bin_w = bin_w; gmem->bin_h = bin_h; @@ -224,7 +221,8 @@ calc_nbins(struct gmem_key *key, struct fd_gmem_stateobj *gmem) { struct fd_screen *screen = gmem->screen; uint32_t nbins_x = 1, nbins_y = 1; - uint32_t max_width = bin_width(screen); + uint32_t max_width = screen->tile_maxw; + uint32_t max_height = screen->tile_maxh; if (fd_mesa_debug & FD_DBG_MSGS) { debug_printf("binning input: cbuf cpp:"); @@ -234,13 +232,17 @@ calc_nbins(struct gmem_key *key, struct fd_gmem_stateobj *gmem) key->zsbuf_cpp[0], key->width, key->height); } - /* first, find a bin width that satisfies the maximum width - * restrictions: + /* first, find a bin size that satisfies the maximum width/ + * height restrictions: */ while (div_align(key->width, nbins_x, screen->tile_alignw) > max_width) { nbins_x++; } + while (div_align(key->height, nbins_y, screen->tile_alignh) > max_height) { + nbins_y++; + } + /* then find a bin width/height that satisfies the memory * constraints: */ @@ -266,7 +268,6 @@ calc_nbins(struct gmem_key *key, struct fd_gmem_stateobj *gmem) } layout_gmem(key, nbins_x, nbins_y, gmem); - } static struct fd_gmem_stateobj * @@ -779,6 +780,12 @@ fd_gmem_needs_restore(struct fd_batch *batch, const struct fd_tile *tile, return true; } +static inline unsigned +max_bitfield_val(unsigned high, unsigned low, unsigned shift) +{ + return BITFIELD_MASK(high - low) << shift; +} + void fd_gmem_init_limits(struct pipe_screen *pscreen) { @@ -790,26 +797,40 @@ fd_gmem_init_limits(struct pipe_screen *pscreen) screen->gmem_alignh = 4; screen->tile_alignw = is_a650(screen) ? 96 : 32; screen->tile_alignh = 32; + /* based on GRAS_BIN_CONTROL: */ + screen->tile_maxw = 1024; /* max_bitfield_val(5, 0, 5) */ + screen->tile_maxh = max_bitfield_val(14, 8, 4); screen->num_vsc_pipes = 32; break; case 500 ... 599: screen->gmem_alignw = screen->tile_alignw = 64; screen->gmem_alignh = screen->tile_alignh = 32; + /* based on VSC_BIN_SIZE: */ + screen->tile_maxw = 1024; /* max_bitfield_val(7, 0, 5) */ + screen->tile_maxh = max_bitfield_val(16, 9, 5); screen->num_vsc_pipes = 16; break; case 400 ... 499: screen->gmem_alignw = screen->tile_alignw = 32; screen->gmem_alignh = screen->tile_alignh = 32; + /* based on VSC_BIN_SIZE: */ + screen->tile_maxw = 1024; /* max_bitfield_val(4, 0, 5) */ + screen->tile_maxh = max_bitfield_val(9, 5, 5); screen->num_vsc_pipes = 8; break; case 300 ... 399: screen->gmem_alignw = screen->tile_alignw = 32; screen->gmem_alignh = screen->tile_alignh = 32; + /* based on VSC_BIN_SIZE: */ + screen->tile_maxw = 992; /* max_bitfield_val(4, 0, 5) */ + screen->tile_maxh = max_bitfield_val(9, 5, 5); screen->num_vsc_pipes = 8; break; case 200 ... 299: screen->gmem_alignw = screen->tile_alignw = 32; screen->gmem_alignh = screen->tile_alignh = 32; + screen->tile_maxw = 512; + screen->tile_maxh = ~0; // TODO screen->num_vsc_pipes = 8; break; default: diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h index 2a657cc42d9..99a754475d8 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.h +++ b/src/gallium/drivers/freedreno/freedreno_screen.h @@ -73,6 +73,7 @@ struct fd_screen { uint32_t max_rts; /* max # of render targets */ uint32_t gmem_alignw, gmem_alignh; /* gmem load/store granularity */ uint32_t tile_alignw, tile_alignh; /* alignment for tile sizes */ + uint32_t tile_maxw, tile_maxh; /* max tile size */ uint32_t num_vsc_pipes; uint32_t priority_mask; bool has_timestamp; diff --git a/src/gallium/drivers/freedreno/gmemtool.c b/src/gallium/drivers/freedreno/gmemtool.c index faa01a9e90b..1303fbf8e64 100644 --- a/src/gallium/drivers/freedreno/gmemtool.c +++ b/src/gallium/drivers/freedreno/gmemtool.c @@ -33,6 +33,7 @@ static bool bin_debug = false; * in a single bin) are commented out, but retained for posterity. */ static const struct gmem_key keys[] = { + { .minx=0, .miny=0, .width=1536, .height=2048, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {1,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}}, /* manhattan: */ { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {0,0,}}, { .minx=0, .miny=0, .width=1920, .height=1080, .gmem_page_align=1, .nr_cbufs=1, .cbuf_cpp = {4,0,0,0,0,0,0,0,}, .zsbuf_cpp = {4,0,}}, @@ -177,6 +178,8 @@ main(int argc, char **argv) assert((gmem->bin_w * gmem->nbins_x) >= key.width); assert((gmem->bin_h * gmem->nbins_y) >= key.height); + assert(gmem->bin_w < screen.tile_maxw); + assert(gmem->bin_h < screen.tile_maxh); ralloc_free(gmem); } _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
