diff options
Diffstat (limited to 'src/gallium/drivers/freedreno/freedreno_gmem.c')
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_gmem.c | 98 |
1 files changed, 69 insertions, 29 deletions
diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c index 8455b73ccbe..68b4eb607a6 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.c +++ b/src/gallium/drivers/freedreno/freedreno_gmem.c @@ -78,6 +78,7 @@ calculate_tiles(struct fd_context *ctx) uint32_t bin_w, bin_h; uint32_t max_width = 992; uint32_t cpp = 4; + uint32_t i, j, t, p, n, xoff, yoff; if (pfb->cbufs[0]) cpp = util_format_get_blocksize(pfb->cbufs[0]->format); @@ -129,57 +130,96 @@ calculate_tiles(struct fd_context *ctx) gmem->scissor = *scissor; gmem->cpp = cpp; - gmem->minx = minx; - gmem->miny = miny; gmem->bin_h = bin_h; gmem->bin_w = bin_w; gmem->nbins_x = nbins_x; gmem->nbins_y = nbins_y; gmem->width = width; gmem->height = height; -} -static void -render_tiles(struct fd_context *ctx) -{ - struct fd_gmem_stateobj *gmem = &ctx->gmem; - uint32_t i, yoff = gmem->miny; + /* Assign tiles and pipes: + * NOTE we currently take a rather simplistic approach of + * mapping rows of tiles to a pipe. At some point it might + * be worth playing with different strategies and seeing if + * that makes much impact on performance. + */ + t = p = n = 0; + yoff = miny; + for (i = 0; i < nbins_y; i++) { + struct fd_vsc_pipe *pipe = &ctx->pipe[p]; + uint32_t bw, bh; - ctx->emit_tile_init(ctx); + assert(p < ARRAY_SIZE(ctx->pipe)); - for (i = 0; i < gmem->nbins_y; i++) { - uint32_t j, xoff = gmem->minx; - uint32_t bh = gmem->bin_h; + xoff = minx; /* clip bin height: */ - bh = MIN2(bh, gmem->miny + gmem->height - yoff); + bh = MIN2(bin_h, miny + height - yoff); + + for (j = 0; j < nbins_x; j++) { + struct fd_tile *tile = &ctx->tile[t]; - for (j = 0; j < gmem->nbins_x; j++) { - uint32_t bw = gmem->bin_w; + assert(t < ARRAY_SIZE(ctx->tile)); /* clip bin width: */ - bw = MIN2(bw, gmem->minx + gmem->width - xoff); + bw = MIN2(bin_w, minx + width - xoff); - DBG("bin_h=%d, yoff=%d, bin_w=%d, xoff=%d", - bh, yoff, bw, xoff); + tile->n = n++; + tile->p = p; + tile->bin_w = bw; + tile->bin_h = bh; + tile->xoff = xoff; + tile->yoff = yoff; - ctx->emit_tile_prep(ctx, xoff, yoff, bw, bh); + t++; - if (ctx->restore) - ctx->emit_tile_mem2gmem(ctx, xoff, yoff, bw, bh); + xoff += bw; + } - ctx->emit_tile_renderprep(ctx, xoff, yoff, bw, bh); + /* one pipe per row: */ + pipe->x = 0; + pipe->y = i; + pipe->w = nbins_x; + pipe->h = 1; - /* emit IB to drawcmds: */ - OUT_IB(ctx->ring, ctx->draw_start, ctx->draw_end); + p++; + n = 0; - /* emit gmem2mem to transfer tile back to system memory: */ - ctx->emit_tile_gmem2mem(ctx, xoff, yoff, bw, bh); + yoff += bh; + } - xoff += bw; - } + for (; p < ARRAY_SIZE(ctx->pipe); p++) { + struct fd_vsc_pipe *pipe = &ctx->pipe[p]; + pipe->x = pipe->y = pipe->w = pipe->h = 0; + } +} - yoff += bh; +static void +render_tiles(struct fd_context *ctx) +{ + struct fd_gmem_stateobj *gmem = &ctx->gmem; + int i; + + ctx->emit_tile_init(ctx); + + for (i = 0; i < (gmem->nbins_x * gmem->nbins_y); i++) { + struct fd_tile *tile = &ctx->tile[i]; + + DBG("bin_h=%d, yoff=%d, bin_w=%d, xoff=%d", + tile->bin_h, tile->yoff, tile->bin_w, tile->xoff); + + ctx->emit_tile_prep(ctx, tile); + + if (ctx->restore) + ctx->emit_tile_mem2gmem(ctx, tile); + + ctx->emit_tile_renderprep(ctx, tile); + + /* emit IB to drawcmds: */ + OUT_IB(ctx->ring, ctx->draw_start, ctx->draw_end); + + /* emit gmem2mem to transfer tile back to system memory: */ + ctx->emit_tile_gmem2mem(ctx, tile); } } |