freedreno/a6xx: Support layered render targets
authorKristian H. Kristensen <hoegsberg@google.com>
Fri, 11 Oct 2019 20:56:20 +0000 (13:56 -0700)
committerKristian H. Kristensen <hoegsberg@google.com>
Thu, 17 Oct 2019 20:43:53 +0000 (13:43 -0700)
Signed-off-by: Kristian H. Kristensen <hoegsberg@google.com>
src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
src/gallium/drivers/freedreno/a6xx/fd6_rasterizer.c
src/gallium/drivers/freedreno/freedreno_gmem.c
src/gallium/drivers/freedreno/freedreno_surface.c

index 678541c0b54681c33c734dda0b91bdfe2f6b6d21..065f0728dc0ca0a3a5dff882390cdbfb5793f98f 100644 (file)
@@ -56,6 +56,9 @@ emit_mrt(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb,
        unsigned srgb_cntl = 0;
        unsigned i;
 
+       bool layered = false;
+       unsigned type = 0;
+
        for (i = 0; i < pfb->nr_cbufs; i++) {
                enum a6xx_color_fmt format = 0;
                enum a3xx_color_swap swap = WZYX;
@@ -102,7 +105,20 @@ emit_mrt(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb,
                else
                        tile_mode = rsc->tile_mode;
 
-               debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
+               if (psurf->u.tex.first_layer < psurf->u.tex.last_layer) {
+                       layered = true;
+                       if (psurf->texture->target == PIPE_TEXTURE_2D_ARRAY && psurf->texture->nr_samples > 0)
+                               type = MULTISAMPLE_ARRAY;
+                       else if (psurf->texture->target == PIPE_TEXTURE_2D_ARRAY)
+                               type = ARRAY;
+                       else if (psurf->texture->target == PIPE_TEXTURE_CUBE)
+                               type = CUBEMAP;
+                       else if (psurf->texture->target == PIPE_TEXTURE_3D)
+                               type = ARRAY;
+
+                       stride /= pfb->samples;
+               }
+
                debug_assert((offset + slice->size0) <= fd_bo_size(rsc->bo));
 
                OUT_PKT4(ring, REG_A6XX_RB_MRT_BUF_INFO(i), 6);
@@ -156,6 +172,10 @@ emit_mrt(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb,
                        A6XX_SP_FS_RENDER_COMPONENTS_RT5(mrt_comp[5]) |
                        A6XX_SP_FS_RENDER_COMPONENTS_RT6(mrt_comp[6]) |
                        A6XX_SP_FS_RENDER_COMPONENTS_RT7(mrt_comp[7]));
+
+       OUT_PKT4(ring, REG_A6XX_GRAS_LAYER_CNTL, 1);
+       OUT_RING(ring, COND(layered, A6XX_GRAS_LAYER_CNTL_LAYERED |
+                                       A6XX_GRAS_LAYER_CNTL_TYPE(type)));
 }
 
 static void
@@ -950,6 +970,8 @@ emit_blit(struct fd_batch *batch,
        uint32_t offset, ubwc_offset;
        bool ubwc_enabled;
 
+       debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
+
        /* separate stencil case: */
        if (stencil) {
                rsc = rsc->stencil;
index ef4cdc0357727912c4343219543fe1d9b8b2b365..1800ecbc86721c923e957c1becc42c6fb6dd520f 100644 (file)
@@ -111,8 +111,6 @@ fd6_rasterizer_state_create(struct pipe_context *pctx,
        OUT_RING(ring, 0x80);
        OUT_PKT4(ring, REG_A6XX_GRAS_UNKNOWN_8001, 1);
        OUT_RING(ring, 0x0);
-       OUT_PKT4(ring, REG_A6XX_GRAS_LAYER_CNTL, 1);
-       OUT_RING(ring, 0x0);
 
        OUT_PKT4(ring, REG_A6XX_GRAS_SU_CNTL, 1);
        OUT_RING(ring, so->gras_su_cntl);
index 14f7c5840a9613525cc9fbb74c6aa8d9a2abcd92..d7f4465ff5117761a31cc30ad263386235d10fbc 100644 (file)
@@ -446,6 +446,15 @@ fd_gmem_render_tiles(struct fd_batch *batch)
                }
        }
 
+       /* Layered rendering always needs bypass. */
+       for (unsigned i = 0; i < pfb->nr_cbufs; i++) {
+               struct pipe_surface *psurf = pfb->cbufs[i];
+               if (!psurf)
+                       continue;
+               if (psurf->u.tex.first_layer < psurf->u.tex.last_layer)
+                       sysmem = true;
+       }
+
        fd_reset_wfi(batch);
 
        ctx->stats.batch_total++;
index 24da54798b62418fe868f3fcaf6a6be01371f3af..602471b24b214f745e97ae589f71eeb89ef18fda 100644 (file)
@@ -59,7 +59,6 @@ fd_create_surface(struct pipe_context *pctx,
                psurf->u.buf.first_element = surf_tmpl->u.buf.first_element;
                psurf->u.buf.last_element = surf_tmpl->u.buf.last_element;
        } else {
-               debug_assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer);
                psurf->u.tex.level = level;
                psurf->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
                psurf->u.tex.last_layer = surf_tmpl->u.tex.last_layer;