freedreno/a6xx: Turn on texture tiling by default
authorKristian H. Kristensen <hoegsberg@chromium.org>
Fri, 21 Dec 2018 17:14:28 +0000 (09:14 -0800)
committerKristian H. Kristensen <hoegsberg@chromium.org>
Fri, 18 Jan 2019 22:27:15 +0000 (14:27 -0800)
The color swap isn't available for tiled formats and it's not needed
either. We pick one channel order and use for all non-linear formats.

Signed-off-by: Kristian H. Kristensen <hoegsberg@chromium.org>
Reviewed-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/a6xx/fd6_blitter.c
src/gallium/drivers/freedreno/a6xx/fd6_format.c
src/gallium/drivers/freedreno/a6xx/fd6_format.h
src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
src/gallium/drivers/freedreno/a6xx/fd6_image.c
src/gallium/drivers/freedreno/a6xx/fd6_screen.c
src/gallium/drivers/freedreno/a6xx/fd6_texture.c

index 546661b06bf91be388e0b139e673bc4fa86cc9ee..3e14e71933de13b288b40f7cfe3c62c6c604b266 100644 (file)
@@ -102,15 +102,6 @@ can_do_blit(const struct pipe_blit_info *info)
        fail_if(util_format_is_compressed(info->src.format) &&
                        info->src.format != info->dst.format);
 
-       /* hw ignores {SRC,DST}_INFO.COLOR_SWAP if {SRC,DST}_INFO.TILE_MODE
-        * is set (not linear).  We can kind of get around that when tiling/
-        * untiling by setting both src and dst COLOR_SWAP=WZYX, but that
-        * means the formats must match:
-        */
-       fail_if((fd_resource(info->dst.resource)->tile_mode ||
-                        fd_resource(info->src.resource)->tile_mode) &&
-                       info->dst.format != info->src.format);
-
        /* src box can be inverted, which we don't support.. dst box cannot: */
        fail_if((info->src.box.width < 0) || (info->src.box.height < 0));
 
@@ -358,8 +349,8 @@ emit_blit_texture(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
        dtile = fd_resource_level_linear(info->dst.resource, info->dst.level) ?
                        TILE6_LINEAR : dst->tile_mode;
 
-       sswap = fd6_pipe2swap(info->src.format);
-       dswap = fd6_pipe2swap(info->dst.format);
+       sswap = stile ? WZYX : fd6_pipe2swap(info->src.format);
+       dswap = dtile ? WZYX : fd6_pipe2swap(info->dst.format);
 
        if (util_format_is_compressed(info->src.format)) {
                debug_assert(info->src.format == info->dst.format);
@@ -386,16 +377,6 @@ emit_blit_texture(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
        uint32_t width = DIV_ROUND_UP(u_minify(src->base.width0, info->src.level), blockwidth) * nelements;
        uint32_t height = DIV_ROUND_UP(u_minify(src->base.height0, info->src.level), blockheight);
 
-       /* if dtile, then dswap ignored by hw, and likewise if stile then sswap
-        * ignored by hw.. but in this case we have already rejected the blit
-        * if src and dst formats differ, so juse use WZYX for both src and
-        * dst swap mode (so we don't change component order)
-        */
-       if (stile || dtile) {
-               debug_assert(info->src.format == info->dst.format);
-               sswap = dswap = WZYX;
-       }
-
        OUT_PKT7(ring, CP_SET_MARKER, 1);
        OUT_RING(ring, A2XX_CP_SET_MARKER_0_MODE(RM6_BLIT2DSCALE));
 
@@ -582,5 +563,8 @@ fd6_tile_mode(const struct pipe_resource *tmpl)
        /* basically just has to be a format we can blit, so uploads/downloads
         * via linear staging buffer works:
         */
-       return TILE6_3;
+       if (ok_format(tmpl->format))
+               return TILE6_3;
+
+       return TILE6_LINEAR;
 }
index 6a55d4e6388c9c6c2d4fc8591b0a5910ca1877f1..dc1a54243a35bb9ee70f86cef9024427a56b0de0 100644 (file)
@@ -29,6 +29,7 @@
 #include "util/u_format.h"
 
 #include "fd6_format.h"
+#include "freedreno_resource.h"
 
 
 /* Specifies the table of all the formats and their features. Also supplies
@@ -419,8 +420,8 @@ fd6_pipe2depth(enum pipe_format format)
        }
 }
 
-static inline enum a6xx_tex_swiz
-tex_swiz(unsigned swiz)
+enum a6xx_tex_swiz
+fd6_pipe2swiz(unsigned swiz)
 {
        switch (swiz) {
        default:
@@ -434,19 +435,37 @@ tex_swiz(unsigned swiz)
 }
 
 uint32_t
-fd6_tex_swiz(enum pipe_format format, unsigned swizzle_r, unsigned swizzle_g,
+fd6_tex_swiz(struct pipe_resource *prsc, unsigned swizzle_r, unsigned swizzle_g,
                unsigned swizzle_b, unsigned swizzle_a)
 {
        const struct util_format_description *desc =
-                       util_format_description(format);
+                       util_format_description(prsc->format);
        unsigned char swiz[4] = {
                        swizzle_r, swizzle_g, swizzle_b, swizzle_a,
-       }, rswiz[4];
+       }, rswiz[4], *swizp;
 
        util_format_compose_swizzles(desc->swizzle, swiz, rswiz);
 
-       return A6XX_TEX_CONST_0_SWIZ_X(tex_swiz(rswiz[0])) |
-                       A6XX_TEX_CONST_0_SWIZ_Y(tex_swiz(rswiz[1])) |
-                       A6XX_TEX_CONST_0_SWIZ_Z(tex_swiz(rswiz[2])) |
-                       A6XX_TEX_CONST_0_SWIZ_W(tex_swiz(rswiz[3]));
+       if (fd_resource(prsc)->tile_mode) {
+               /* for tiled modes, we don't get SWAP, so manually apply that
+                * extra step of swizzle:
+                */
+               enum a3xx_color_swap swap = fd6_pipe2swap(prsc->format);
+               unsigned char swapswiz[][4] = {
+                               [WZYX] = { 0, 1, 2, 3 },
+                               [WXYZ] = { 2, 1, 0, 3 },
+                               [ZYXW] = { 3, 0, 1, 2 },
+                               [XYZW] = { 3, 2, 1, 0 },
+               };
+
+               util_format_compose_swizzles(swapswiz[swap], rswiz, swiz);
+               swizp = swiz;
+       } else {
+               swizp = rswiz;
+       }
+
+       return A6XX_TEX_CONST_0_SWIZ_X(fd6_pipe2swiz(swizp[0])) |
+                       A6XX_TEX_CONST_0_SWIZ_Y(fd6_pipe2swiz(swizp[1])) |
+                       A6XX_TEX_CONST_0_SWIZ_Z(fd6_pipe2swiz(swizp[2])) |
+                       A6XX_TEX_CONST_0_SWIZ_W(fd6_pipe2swiz(swizp[3]));
 }
index 56166dc4505d688784ae7cf9404127c1fc1ac1a8..bc188ca17a850673cb554b421570f5acab1ef075 100644 (file)
@@ -38,8 +38,9 @@ enum a6xx_color_fmt fd6_pipe2color(enum pipe_format format);
 enum a3xx_color_swap fd6_pipe2swap(enum pipe_format format);
 enum a6xx_tex_fetchsize fd6_pipe2fetchsize(enum pipe_format format);
 enum a6xx_depth_format fd6_pipe2depth(enum pipe_format format);
+enum a6xx_tex_swiz fd6_pipe2swiz(unsigned swiz);
 
-uint32_t fd6_tex_swiz(enum pipe_format format, unsigned swizzle_r,
+uint32_t fd6_tex_swiz(struct pipe_resource *prsc, unsigned swizzle_r,
                unsigned swizzle_g, unsigned swizzle_b, unsigned swizzle_a);
 
 static inline enum a6xx_2d_ifmt
index 75d8025e2a61286c9c35e7512e4ccd9675265fc2..cb5c582476ff7ebfcb4ca942a60f118d4c971f8b 100644 (file)
@@ -64,6 +64,7 @@ emit_mrt(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb,
                struct fd_resource_slice *slice = NULL;
                uint32_t stride = 0;
                uint32_t offset = 0;
+               uint32_t tile_mode;
 
                if (!pfb->cbufs[i])
                        continue;
@@ -79,7 +80,6 @@ emit_mrt(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb,
                uint32_t base = gmem ? gmem->cbuf_base[i] : 0;
                slice = fd_resource_slice(rsc, psurf->u.tex.level);
                format = fd6_pipe2color(pformat);
-               swap = fd6_pipe2swap(pformat);
                sint = util_format_is_pure_sint(pformat);
                uint = util_format_is_pure_uint(pformat);
 
@@ -90,13 +90,20 @@ emit_mrt(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb,
                                                                        psurf->u.tex.first_layer);
 
                stride = slice->pitch * rsc->cpp * pfb->samples;
+               swap = rsc->tile_mode ? WZYX : fd6_pipe2swap(pformat);
+
+               if (rsc->tile_mode &&
+                       fd_resource_level_linear(psurf->texture, psurf->u.tex.level))
+                       tile_mode = TILE6_LINEAR;
+               else
+                       tile_mode = rsc->tile_mode;
 
                debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
                debug_assert((offset + slice->size0) <= fd_bo_size(rsc->bo));
 
                OUT_PKT4(ring, REG_A6XX_RB_MRT_BUF_INFO(i), 6);
                OUT_RING(ring, A6XX_RB_MRT_BUF_INFO_COLOR_FORMAT(format) |
-                               A6XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(rsc->tile_mode) |
+                               A6XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(tile_mode) |
                                A6XX_RB_MRT_BUF_INFO_COLOR_SWAP(swap));
                OUT_RING(ring, A6XX_RB_MRT_PITCH(stride));
                OUT_RING(ring, A6XX_RB_MRT_ARRAY_PITCH(slice->size0));
@@ -617,18 +624,20 @@ emit_blit(struct fd_batch *batch,
        enum a6xx_color_fmt format = fd6_pipe2color(pfmt);
        uint32_t stride = slice->pitch * rsc->cpp;
        uint32_t size = slice->size0;
-       enum a3xx_color_swap swap = fd6_pipe2swap(pfmt);
+       enum a3xx_color_swap swap = rsc->tile_mode ? WZYX : fd6_pipe2swap(pfmt);
        enum a3xx_msaa_samples samples =
                        fd_msaa_samples(rsc->base.nr_samples);
+       uint32_t tile_mode;
 
-       // TODO: tile mode
-       // bool tiled;
-       // tiled = rsc->tile_mode &&
-       //   !fd_resource_level_linear(&rsc->base, psurf->u.tex.level);
+       if (rsc->tile_mode &&
+               fd_resource_level_linear(&rsc->base, psurf->u.tex.level))
+               tile_mode = TILE6_LINEAR;
+       else
+               tile_mode = rsc->tile_mode;
 
        OUT_PKT4(ring, REG_A6XX_RB_BLIT_DST_INFO, 5);
        OUT_RING(ring,
-                        A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR) |
+                        A6XX_RB_BLIT_DST_INFO_TILE_MODE(tile_mode) |
                         A6XX_RB_BLIT_DST_INFO_SAMPLES(samples) |
                         A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format) |
                         A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(swap));
index e79ee2f90ada64c095ff6a26d048e9e1162e273f..f7419d8d9ac234ce5f0eadf941d6ea74eeced0c0 100644 (file)
@@ -43,6 +43,7 @@ static enum a6xx_state_block imgsb[] = {
 };
 
 struct fd6_image {
+       struct pipe_resource *prsc;
        enum pipe_format pfmt;
        enum a6xx_tex_fmt fmt;
        enum a6xx_tex_fetchsize fetchsize;
@@ -70,6 +71,7 @@ static void translate_image(struct fd6_image *img, struct pipe_image_view *pimg)
                return;
        }
 
+       img->prsc      = prsc;
        img->pfmt      = format;
        img->fmt       = fd6_pipe2tex(format);
        img->fetchsize = fd6_pipe2fetchsize(format);
@@ -112,7 +114,7 @@ static void emit_image_tex(struct fd_ringbuffer *ring, unsigned slot,
        OUT_RING(ring, CP_LOAD_STATE6_2_EXT_SRC_ADDR_HI(0));
 
        OUT_RING(ring, A6XX_TEX_CONST_0_FMT(img->fmt) |
-               fd6_tex_swiz(img->pfmt, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y,
+               fd6_tex_swiz(img->prsc, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y,
                        PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W) |
                COND(img->srgb, A6XX_TEX_CONST_0_SRGB));
        OUT_RING(ring, A6XX_TEX_CONST_1_WIDTH(img->width) |
index 910a71ccc96d5d8d71991b8a4a95c428965cb84d..be92d4a877b96eed15d6c964da8f0a136526efff 100644 (file)
@@ -29,6 +29,7 @@
 #include "util/u_format.h"
 
 #include "fd6_screen.h"
+#include "fd6_blitter.h"
 #include "fd6_context.h"
 #include "fd6_format.h"
 #include "fd6_resource.h"
@@ -134,4 +135,5 @@ fd6_screen_init(struct pipe_screen *pscreen)
        pscreen->is_format_supported = fd6_screen_is_format_supported;
 
        screen->setup_slices = fd6_setup_slices;
+       screen->tile_mode = fd6_tile_mode;
 }
index e516e94b0d928010287c89859b6d3f7c61da382b..af5f49fd3f2854620491f96ddc7b0812b30bf390 100644 (file)
@@ -246,7 +246,7 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
        so->texconst0 =
                A6XX_TEX_CONST_0_FMT(fd6_pipe2tex(format)) |
                A6XX_TEX_CONST_0_SAMPLES(fd_msaa_samples(prsc->nr_samples)) |
-               fd6_tex_swiz(format, cso->swizzle_r, cso->swizzle_g,
+               fd6_tex_swiz(prsc, cso->swizzle_r, cso->swizzle_g,
                                cso->swizzle_b, cso->swizzle_a);
 
        /* NOTE: since we sample z24s8 using 8888_UINT format, the swizzle
@@ -257,8 +257,12 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
         * Note that gallium expects stencil sampler to return (s,s,s,s)
         * which isn't quite true.  To make that happen we'd have to massage
         * the swizzle.  But in practice only the .x component is used.
+        *
+        * Skip this in the tile case because tiled formats are not swapped
+        * and we have already applied the inverse swap in fd6_tex_swiz()
+        * to componsate for that.
         */
-       if (format == PIPE_FORMAT_X24S8_UINT) {
+       if ((format == PIPE_FORMAT_X24S8_UINT) && !rsc->tile_mode) {
                so->texconst0 |= A6XX_TEX_CONST_0_SWAP(XYZW);
        }