From f5d80ff2db36736636aede2040c716d7fb437286 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 6 Mar 2019 10:04:21 -0500 Subject: [PATCH] freedreno/a6xx: refactor fd6_tex_swiz() 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 Reviewed-by: Kristian H. Kristensen --- .../drivers/freedreno/a6xx/fd6_format.c | 44 +++++++++++++++---- .../drivers/freedreno/a6xx/fd6_format.h | 11 +++-- .../drivers/freedreno/a6xx/fd6_image.c | 19 +++++--- .../drivers/freedreno/a6xx/fd6_texture.c | 21 +++------ 4 files changed, 61 insertions(+), 34 deletions(-) diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_format.c b/src/gallium/drivers/freedreno/a6xx/fd6_format.c index 2016d31501e..5ba641d50a5 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_format.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_format.c @@ -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; } diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_format.h b/src/gallium/drivers/freedreno/a6xx/fd6_format.h index a1ed03d60f4..2c4f5865527 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_format.h +++ b/src/gallium/drivers/freedreno/a6xx/fd6_format.h @@ -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) diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_image.c b/src/gallium/drivers/freedreno/a6xx/fd6_image.c index 5683612c51c..9c1182777c0 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_image.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_image.c @@ -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) | diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c index f2f7276aaa8..f5f747cd14c 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c @@ -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); -- 2.30.2