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

Reply via email to