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>tags/19.1-branchpoint
| @@ -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; | |||
| } | |||
| @@ -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) | |||
| @@ -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) | | |||
| @@ -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); | |||