freedreno/a6xx: refactor fd6_tex_swiz()
authorRob Clark <robdclark@gmail.com>
Wed, 6 Mar 2019 15:04:21 +0000 (10:04 -0500)
committerRob Clark <robdclark@gmail.com>
Thu, 7 Mar 2019 20:33:42 +0000 (15:33 -0500)
We need a version of fd6_tex_swiz() that just returns the composed
swizzle without building part of the TEX_CONST_0 state.  So just
refactor the existing function to build more of the TEX_CONST_0 state,
and leave fd6_tex_swiz() simply composing swizzles.

The small IBO state change (to use LINEAR for smaller sizes/levels) is
to match the state in fd6_tex_const_0().  It seems like maybe tiled
actually works at the smaller sizes but not if minification is in play,
so best just to make images match what we do for textures.

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

index 2016d31501ed65100c8232362beeea6e3179f35e..5ba641d50a55a9018a5a7d61d75257a7f4cade56 100644 (file)
@@ -434,16 +434,13 @@ fd6_pipe2swiz(unsigned swiz)
        }
 }
 
-uint32_t
-fd6_tex_swiz(struct pipe_resource *prsc, enum pipe_format format,
+void
+fd6_tex_swiz(enum pipe_format format, unsigned char *swiz,
                         unsigned swizzle_r, unsigned swizzle_g,
                         unsigned swizzle_b, unsigned swizzle_a)
 {
        const struct util_format_description *desc =
                        util_format_description(format);
-
-       uint32_t swap = fd6_pipe2swap(format);
-       unsigned char swiz[4];
        const unsigned char uswiz[4] = {
                swizzle_r, swizzle_g, swizzle_b, swizzle_a
        };
@@ -456,25 +453,54 @@ fd6_tex_swiz(struct pipe_resource *prsc, enum pipe_format format,
                        PIPE_SWIZZLE_X, PIPE_SWIZZLE_X, PIPE_SWIZZLE_X, PIPE_SWIZZLE_X
                };
                util_format_compose_swizzles(stencil_swiz, uswiz, swiz);
-       } else if (swap != WZYX) {
+       } else if (fd6_pipe2swap(format) != WZYX) {
                /* Formats with a non-pass-through swap are permutations of RGBA
                 * formats. We program the permutation using the swap and don't
                 * need to compose the format swizzle with the user swizzle.
                 */
-               memcpy(swiz, uswiz, sizeof(swiz));
+               memcpy(swiz, uswiz, sizeof(uswiz));
        } else {
                /* Otherwise, it's an unswapped RGBA format or a format like L8 where
                 * we need the XXX1 swizzle from the gallium format description.
                 */
                util_format_compose_swizzles(desc->swizzle, uswiz, swiz);
        }
+}
+
+/* Compute the TEX_CONST_0 value for texture state, including SWIZ/SWAP/etc: */
+uint32_t
+fd6_tex_const_0(struct pipe_resource *prsc,
+                        unsigned level, enum pipe_format format,
+                        unsigned swizzle_r, unsigned swizzle_g,
+                        unsigned swizzle_b, unsigned swizzle_a)
+{
+       struct fd_resource *rsc = fd_resource(prsc);
+       uint32_t swap, texconst0 = 0;
+       unsigned char swiz[4];
+
+       if (util_format_is_srgb(format)) {
+               texconst0 |= A6XX_TEX_CONST_0_SRGB;
+       }
 
-       swap = fd_resource(prsc)->tile_mode ? WZYX : fd6_pipe2swap(format);
+       if (rsc->tile_mode && !fd_resource_level_linear(prsc, level)) {
+               texconst0 |= A6XX_TEX_CONST_0_TILE_MODE(rsc->tile_mode);
+               swap = WZYX;
+       } else {
+               swap = fd6_pipe2swap(format);
+       }
 
-       return
+       fd6_tex_swiz(format, swiz,
+                       swizzle_r, swizzle_g,
+                       swizzle_b, swizzle_a);
+
+       texconst0 |=
+               A6XX_TEX_CONST_0_FMT(fd6_pipe2tex(format)) |
+               A6XX_TEX_CONST_0_SAMPLES(fd_msaa_samples(prsc->nr_samples)) |
                A6XX_TEX_CONST_0_SWAP(swap) |
                A6XX_TEX_CONST_0_SWIZ_X(fd6_pipe2swiz(swiz[0])) |
                A6XX_TEX_CONST_0_SWIZ_Y(fd6_pipe2swiz(swiz[1])) |
                A6XX_TEX_CONST_0_SWIZ_Z(fd6_pipe2swiz(swiz[2])) |
                A6XX_TEX_CONST_0_SWIZ_W(fd6_pipe2swiz(swiz[3]));
+
+       return texconst0;
 }
index a1ed03d60f44587d344df9c90ef3f84c78fcf22d..2c4f58655276bdcb38c807fb156967c2b7528941 100644 (file)
@@ -41,9 +41,14 @@ 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(struct pipe_resource *prsc, enum pipe_format format,
-                                         unsigned swizzle_r,
-                                         unsigned swizzle_g, unsigned swizzle_b, unsigned swizzle_a);
+void fd6_tex_swiz(enum pipe_format format, unsigned char *swiz,
+                        unsigned swizzle_r, unsigned swizzle_g,
+                        unsigned swizzle_b, unsigned swizzle_a);
+
+uint32_t fd6_tex_const_0(struct pipe_resource *prsc,
+                                         unsigned level, enum pipe_format format,
+                                         unsigned swizzle_r, unsigned swizzle_g,
+                                         unsigned swizzle_b, unsigned swizzle_a);
 
 static inline enum a6xx_2d_ifmt
 fd6_ifmt(enum a6xx_color_fmt fmt)
index 5683612c51cf6f3ca7b18a4677e07628fd1a5c3a..9c1182777c02d59408401483de073426f8868beb 100644 (file)
@@ -40,6 +40,7 @@ struct fd6_image {
        enum a6xx_tex_type type;
        bool srgb;
        uint32_t cpp;
+       uint32_t level;
        uint32_t width;
        uint32_t height;
        uint32_t depth;
@@ -120,6 +121,7 @@ static void translate_image(struct fd6_image *img, const struct pipe_image_view
                        break;
                }
 
+               img->level  = lvl;
                img->width  = u_minify(prsc->width0, lvl);
                img->height = u_minify(prsc->height0, lvl);
        }
@@ -161,11 +163,9 @@ static void translate_buf(struct fd6_image *img, const struct pipe_shader_buffer
 
 static void emit_image_tex(struct fd_ringbuffer *ring, struct fd6_image *img)
 {
-       OUT_RING(ring, A6XX_TEX_CONST_0_FMT(img->fmt) |
-               A6XX_TEX_CONST_0_TILE_MODE(fd_resource(img->prsc)->tile_mode) |
-               fd6_tex_swiz(img->prsc, img->pfmt, PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y,
-                       PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W) |
-               COND(img->srgb, A6XX_TEX_CONST_0_SRGB));
+       OUT_RING(ring, fd6_tex_const_0(img->prsc, img->level, img->pfmt,
+                       PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y,
+                       PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W));
        OUT_RING(ring, A6XX_TEX_CONST_1_WIDTH(img->width) |
                A6XX_TEX_CONST_1_HEIGHT(img->height));
        OUT_RING(ring, A6XX_TEX_CONST_2_FETCHSIZE(img->fetchsize) |
@@ -210,8 +210,15 @@ fd6_emit_ssbo_tex(struct fd_ringbuffer *ring, const struct pipe_shader_buffer *p
 
 static void emit_image_ssbo(struct fd_ringbuffer *ring, struct fd6_image *img)
 {
+       struct fd_resource *rsc = fd_resource(img->prsc);
+       enum a6xx_tile_mode tile_mode = TILE6_LINEAR;
+
+       if (rsc->tile_mode && !fd_resource_level_linear(img->prsc, img->level)) {
+               tile_mode = rsc->tile_mode;
+       }
+
        OUT_RING(ring, A6XX_IBO_0_FMT(img->fmt) |
-               A6XX_IBO_0_TILE_MODE(fd_resource(img->prsc)->tile_mode));
+               A6XX_IBO_0_TILE_MODE(tile_mode));
        OUT_RING(ring, A6XX_IBO_1_WIDTH(img->width) |
                A6XX_IBO_1_HEIGHT(img->height));
        OUT_RING(ring, A6XX_IBO_2_PITCH(img->pitch) |
index f2f7276aaa8f0f2e63e30c3492f4e38b267cfaeb..f5f747cd14c4d5189902613cf81db8eeca6ee5eb 100644 (file)
@@ -237,16 +237,6 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
        so->base.context = pctx;
        so->seqno = ++fd6_context(fd_context(pctx))->tex_seqno;
 
-       so->texconst0 =
-               A6XX_TEX_CONST_0_FMT(fd6_pipe2tex(format)) |
-               A6XX_TEX_CONST_0_SAMPLES(fd_msaa_samples(prsc->nr_samples)) |
-               fd6_tex_swiz(prsc, cso->format, cso->swizzle_r, cso->swizzle_g,
-                               cso->swizzle_b, cso->swizzle_a);
-
-       if (util_format_is_srgb(format)) {
-               so->texconst0 |= A6XX_TEX_CONST_0_SRGB;
-       }
-
        if (cso->target == PIPE_BUFFER) {
                unsigned elements = cso->u.buf.size / util_format_get_blocksize(format);
 
@@ -260,17 +250,12 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
                so->offset = cso->u.buf.offset;
        } else {
                unsigned miplevels;
-               enum a6xx_tile_mode tile_mode = TILE6_LINEAR;
 
                lvl = fd_sampler_first_level(cso);
                miplevels = fd_sampler_last_level(cso) - lvl;
                layers = cso->u.tex.last_layer - cso->u.tex.first_layer + 1;
 
-               if (!fd_resource_level_linear(prsc, lvl))
-                       tile_mode = fd_resource(prsc)->tile_mode;
-
-               so->texconst0 |= A6XX_TEX_CONST_0_MIPLVLS(miplevels) |
-                       A6XX_TEX_CONST_0_TILE_MODE(tile_mode);
+               so->texconst0 |= A6XX_TEX_CONST_0_MIPLVLS(miplevels);
                so->texconst1 =
                        A6XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
                        A6XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
@@ -284,6 +269,10 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
                so->ubwc_enabled = rsc->ubwc_size && u_minify(prsc->width0, lvl) >= 16;
        }
 
+       so->texconst0 |= fd6_tex_const_0(prsc, lvl, cso->format,
+                               cso->swizzle_r, cso->swizzle_g,
+                               cso->swizzle_b, cso->swizzle_a);
+
        if (so->ubwc_enabled) {
                so->texconst9 |= A6XX_TEX_CONST_9_FLAG_BUFFER_PITCH(rsc->ubwc_size);
                so->texconst10 |= A6XX_TEX_CONST_10_FLAG_BUFFER_ARRAY_PITCH(rsc->ubwc_pitch);