From: Ilia Mirkin Date: Mon, 30 Mar 2015 00:54:42 +0000 (-0400) Subject: freedreno: add support for laying out MRTs in gmem X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d9992ab35a51c574dcfa8049859c0887956ecdf6;p=mesa.git freedreno: add support for laying out MRTs in gmem Signed-off-by: Ilia Mirkin --- diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c index afe088ac261..6bdd7704b86 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.c +++ b/src/gallium/drivers/freedreno/freedreno_gmem.c @@ -76,6 +76,27 @@ static uint32_t bin_width(struct fd_context *ctx) return 512; } +static uint32_t +total_size(uint8_t cbuf_cpp[], uint8_t zsbuf_cpp, + uint32_t bin_w, uint32_t bin_h, struct fd_gmem_stateobj *gmem) +{ + uint32_t total = 0, i; + + for (i = 0; i < 4; i++) { + if (cbuf_cpp[i]) { + gmem->cbuf_base[i] = align(total, 0x4000); + total = gmem->cbuf_base[i] + cbuf_cpp[i] * bin_w * bin_h; + } + } + + if (zsbuf_cpp) { + gmem->zsbuf_base = align(total, 0x4000); + total = gmem->zsbuf_base + zsbuf_cpp * bin_w * bin_h; + } + + return total; +} + static void calculate_tiles(struct fd_context *ctx) { @@ -87,26 +108,27 @@ calculate_tiles(struct fd_context *ctx) uint32_t nbins_x = 1, nbins_y = 1; uint32_t bin_w, bin_h; uint32_t max_width = bin_width(ctx); - uint32_t cpp = 4; + uint8_t cbuf_cpp[4] = {0}, zsbuf_cpp = 0; uint32_t i, j, t, xoff, yoff; uint32_t tpp_x, tpp_y; bool has_zs = !!(ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)); - if (pfb->cbufs[0]) - cpp = util_format_get_blocksize(pfb->cbufs[0]->format); + if (has_zs) + zsbuf_cpp = util_format_get_blocksize(pfb->zsbuf->format); + for (i = 0; i < pfb->nr_cbufs; i++) { + if (pfb->cbufs[i]) + cbuf_cpp[i] = util_format_get_blocksize(pfb->cbufs[i]->format); + else + cbuf_cpp[i] = 4; + } - if ((gmem->cpp == cpp) && (gmem->has_zs == has_zs) && - !memcmp(&gmem->scissor, scissor, sizeof(gmem->scissor))) { + if (gmem->zsbuf_cpp == zsbuf_cpp && + !memcmp(gmem->cbuf_cpp, cbuf_cpp, sizeof(cbuf_cpp)) && + !memcmp(&gmem->scissor, scissor, sizeof(gmem->scissor))) { /* everything is up-to-date */ return; } - /* if have depth/stencil, we need to leave room: */ - if (has_zs) { - gmem_size /= 2; - max_width /= 2; - } - if (fd_mesa_debug & FD_DBG_NOSCIS) { minx = 0; miny = 0; @@ -133,7 +155,10 @@ calculate_tiles(struct fd_context *ctx) /* then find a bin width/height that satisfies the memory * constraints: */ - while ((bin_w * bin_h * cpp) > gmem_size) { + DBG("binning input: cbuf cpp: %d %d %d %d, zsbuf cpp: %d; %dx%d", + cbuf_cpp[0], cbuf_cpp[1], cbuf_cpp[2], cbuf_cpp[3], zsbuf_cpp, + width, height); + while (total_size(cbuf_cpp, zsbuf_cpp, bin_w, bin_h, gmem) > gmem_size) { if (bin_w > bin_h) { nbins_x++; bin_w = align(width / nbins_x, 32); @@ -146,8 +171,8 @@ calculate_tiles(struct fd_context *ctx) DBG("using %d bins of size %dx%d", nbins_x*nbins_y, bin_w, bin_h); gmem->scissor = *scissor; - gmem->cpp = cpp; - gmem->has_zs = has_zs; + memcpy(gmem->cbuf_cpp, cbuf_cpp, sizeof(cbuf_cpp)); + gmem->zsbuf_cpp = zsbuf_cpp; gmem->bin_h = bin_h; gmem->bin_w = bin_w; gmem->nbins_x = nbins_x; diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.h b/src/gallium/drivers/freedreno/freedreno_gmem.h index ff322df3c2f..81f9b6abe98 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.h +++ b/src/gallium/drivers/freedreno/freedreno_gmem.h @@ -47,12 +47,14 @@ struct fd_tile { struct fd_gmem_stateobj { struct pipe_scissor_state scissor; - uint cpp; + uint32_t cbuf_base[4]; + uint32_t zsbuf_base; + uint8_t cbuf_cpp[4]; + uint8_t zsbuf_cpp; uint16_t bin_h, nbins_y; uint16_t bin_w, nbins_x; uint16_t minx, miny; uint16_t width, height; - bool has_zs; /* gmem config using depth/stencil? */ }; struct fd_context;