From: Rob Clark Date: Sat, 23 May 2020 19:27:17 +0000 (-0700) Subject: freedreno/gmem: fix nbins_x/y mismatch X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fcecdcd82252013020a224f9e2887fcedbe23789;p=mesa.git freedreno/gmem: fix nbins_x/y mismatch `layout_gmem()` recalculates the # of bins in x/y dimensions after aligning the bin width/height to required dimensions. Because of this, the resulting gmem config could have fewer bins in either dimension. But the tile/bin layout and the pipe assignment logic were still using the original values. Which could result in extraneous bins with a width and/or height of zero. Because the gmem rendering code uses `gmem->bin_w`/`h` to determine the number of bins, this could result in some zero size bins being executed, while later valid bins are skipped. Which can leave un- rendered portions of the screen (generally lower-right). To fix this, be sure to use `gmem->bin_w`/`h` rather than the local variables. Fixes: 1bd38746d5a ("freedreno/gmem: rework gmem layout algo") Signed-off-by: Rob Clark Part-of: --- diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c index 3becea434df..f9130b6b5c8 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.c +++ b/src/gallium/drivers/freedreno/freedreno_gmem.c @@ -310,10 +310,10 @@ gmem_stateobj_init(struct fd_screen *screen, struct gmem_key *key) tpp_y = 6; } else { tpp_x = tpp_y = 1; - while (div_round_up(nbins_y, tpp_y) > npipes) + while (div_round_up(gmem->nbins_y, tpp_y) > npipes) tpp_y += 2; - while ((div_round_up(nbins_y, tpp_y) * - div_round_up(nbins_x, tpp_x)) > npipes) + while ((div_round_up(gmem->nbins_y, tpp_y) * + div_round_up(gmem->nbins_x, tpp_x)) > npipes) tpp_x += 1; } @@ -325,19 +325,19 @@ gmem_stateobj_init(struct fd_screen *screen, struct gmem_key *key) for (i = 0; i < npipes; i++) { struct fd_vsc_pipe *pipe = &gmem->vsc_pipe[i]; - if (xoff >= nbins_x) { + if (xoff >= gmem->nbins_x) { xoff = 0; yoff += tpp_y; } - if (yoff >= nbins_y) { + if (yoff >= gmem->nbins_y) { break; } pipe->x = xoff; pipe->y = yoff; - pipe->w = MIN2(tpp_x, nbins_x - xoff); - pipe->h = MIN2(tpp_y, nbins_y - yoff); + pipe->w = MIN2(tpp_x, gmem->nbins_x - xoff); + pipe->h = MIN2(tpp_y, gmem->nbins_y - yoff); xoff += tpp_x; } @@ -351,7 +351,7 @@ gmem_stateobj_init(struct fd_screen *screen, struct gmem_key *key) } if (BIN_DEBUG) { - printf("%dx%d ... tpp=%dx%d\n", nbins_x, nbins_y, tpp_x, tpp_y); + printf("%dx%d ... tpp=%dx%d\n", gmem->nbins_x, gmem->nbins_y, tpp_x, tpp_y); for (i = 0; i < ARRAY_SIZE(gmem->vsc_pipe); i++) { struct fd_vsc_pipe *pipe = &gmem->vsc_pipe[i]; printf("pipe[%d]: %ux%u @ %u,%u\n", i, @@ -363,7 +363,7 @@ gmem_stateobj_init(struct fd_screen *screen, struct gmem_key *key) t = 0; yoff = key->miny; memset(tile_n, 0, sizeof(tile_n)); - for (i = 0; i < nbins_y; i++) { + for (i = 0; i < gmem->nbins_y; i++) { int bw, bh; xoff = key->minx; @@ -372,14 +372,14 @@ gmem_stateobj_init(struct fd_screen *screen, struct gmem_key *key) bh = MIN2(gmem->bin_h, key->miny + key->height - yoff); assert(bh > 0); - for (j = 0; j < nbins_x; j++) { + for (j = 0; j < gmem->nbins_x; j++) { struct fd_tile *tile = &gmem->tile[t]; uint32_t p; assert(t < ARRAY_SIZE(gmem->tile)); /* pipe number: */ - p = ((i / tpp_y) * div_round_up(nbins_x, tpp_x)) + (j / tpp_x); + p = ((i / tpp_y) * div_round_up(gmem->nbins_x, tpp_x)) + (j / tpp_x); assert(p < gmem->num_vsc_pipes); /* clip bin width: */ @@ -409,8 +409,8 @@ gmem_stateobj_init(struct fd_screen *screen, struct gmem_key *key) if (BIN_DEBUG) { t = 0; - for (i = 0; i < nbins_y; i++) { - for (j = 0; j < nbins_x; j++) { + for (i = 0; i < gmem->nbins_y; i++) { + for (j = 0; j < gmem->nbins_x; j++) { struct fd_tile *tile = &gmem->tile[t++]; printf("|p:%u n:%u|", tile->p, tile->n); }