From 7cb672227bea9f61c6fd25b3eef534e7f79442fb Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Fri, 11 Oct 2019 13:56:20 -0700 Subject: [PATCH] freedreno/a6xx: Support layered render targets Signed-off-by: Kristian H. Kristensen --- src/gallium/drivers/freedreno/a6xx/fd6_gmem.c | 24 +++++++++++++++++++++- .../drivers/freedreno/a6xx/fd6_rasterizer.c | 2 -- src/gallium/drivers/freedreno/freedreno_gmem.c | 9 ++++++++ src/gallium/drivers/freedreno/freedreno_surface.c | 1 - 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c index 678541c..065f072 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c @@ -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; diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_rasterizer.c b/src/gallium/drivers/freedreno/a6xx/fd6_rasterizer.c index ef4cdc0..1800ecb 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_rasterizer.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_rasterizer.c @@ -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); diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c index 14f7c58..d7f4465 100644 --- a/src/gallium/drivers/freedreno/freedreno_gmem.c +++ b/src/gallium/drivers/freedreno/freedreno_gmem.c @@ -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++; diff --git a/src/gallium/drivers/freedreno/freedreno_surface.c b/src/gallium/drivers/freedreno/freedreno_surface.c index 24da547..602471b 100644 --- a/src/gallium/drivers/freedreno/freedreno_surface.c +++ b/src/gallium/drivers/freedreno/freedreno_surface.c @@ -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; -- 2.7.4