freedreno: add support for laying out MRTs in gmem
authorIlia Mirkin <imirkin@alum.mit.edu>
Mon, 30 Mar 2015 00:54:42 +0000 (20:54 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Thu, 2 Apr 2015 04:09:14 +0000 (00:09 -0400)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/freedreno/freedreno_gmem.c
src/gallium/drivers/freedreno/freedreno_gmem.h

index afe088ac261c86070caa5b36cdb265ad9360e335..6bdd7704b863792871cd4dd388c244cb1e52ed4b 100644 (file)
@@ -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;
index ff322df3c2fa1b21a6bc95cd5177c96bcb2d70d3..81f9b6abe98e487889c6cfc996c94ae6fe88c4ba 100644 (file)
@@ -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;