[Mesa-dev] [PATCH 3/3] freedreno/a4xx: lower srgb in shader for astc textures
Ilia Mirkin
imirkin at alum.mit.edu
Tue Apr 19 14:09:15 UTC 2016
On Tue, Apr 19, 2016 at 9:58 AM, Rob Clark <robdclark at gmail.com> wrote:
> From: Rob Clark <robclark at freedesktop.org>
>
> This *seems* like a hw bug, and maybe only applies to certain a4xx
> variants/revisions. But setting the SRGB bit in sampler view state
> (texconst0) causes invalid alpha for ASTC textures. Work around this
> by doing the srgb->linear conversion in the shader instead.
>
> This fixes 392 dEQP tests: dEQP-GLES3.functional.texture.*astc*srgb*
>
> (The remaining fails seem to be a bug w/ ASTC + linear filtering, also
> possibly a420.0 specific.)
>
> Signed-off-by: Rob Clark <robclark at freedesktop.org>
> ---
> src/gallium/drivers/freedreno/a4xx/fd4_context.h | 3 ++
> src/gallium/drivers/freedreno/a4xx/fd4_draw.c | 11 ++++--
> src/gallium/drivers/freedreno/a4xx/fd4_texture.c | 45 ++++++++++++++++++++++--
> src/gallium/drivers/freedreno/a4xx/fd4_texture.h | 1 +
> src/gallium/drivers/freedreno/ir3/ir3_nir.c | 3 ++
> src/gallium/drivers/freedreno/ir3/ir3_shader.c | 2 ++
> src/gallium/drivers/freedreno/ir3/ir3_shader.h | 3 ++
> 7 files changed, 62 insertions(+), 6 deletions(-)
>
> diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_context.h b/src/gallium/drivers/freedreno/a4xx/fd4_context.h
> index 8996de9..a08c3c3 100644
> --- a/src/gallium/drivers/freedreno/a4xx/fd4_context.h
> +++ b/src/gallium/drivers/freedreno/a4xx/fd4_context.h
> @@ -85,6 +85,9 @@ struct fd4_context {
> */
> uint16_t fsaturate_s, fsaturate_t, fsaturate_r;
>
> + /* bitmask of samplers which need srgb lowering in vertex/frag shader: */
> + uint16_t vlower_srgb, flower_srgb;
> +
> /* some state changes require a different shader variant. Keep
> * track of this so we know when we need to re-emit shader state
> * due to variant change. See fixup_shader_state()
> diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c
> index e874d22..a086626 100644
> --- a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c
> +++ b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c
> @@ -93,12 +93,14 @@ fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
> if (last_key->has_per_samp || key->has_per_samp) {
> if ((last_key->vsaturate_s != key->vsaturate_s) ||
> (last_key->vsaturate_t != key->vsaturate_t) ||
> - (last_key->vsaturate_r != key->vsaturate_r))
> + (last_key->vsaturate_r != key->vsaturate_r) ||
> + (last_key->vlower_srgb != key->vlower_srgb))
> ctx->prog.dirty |= FD_SHADER_DIRTY_VP;
>
> if ((last_key->fsaturate_s != key->fsaturate_s) ||
> (last_key->fsaturate_t != key->fsaturate_t) ||
> - (last_key->fsaturate_r != key->fsaturate_r))
> + (last_key->fsaturate_r != key->fsaturate_r) ||
> + (last_key->flower_srgb != key->flower_srgb))
> ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
> }
>
> @@ -132,13 +134,16 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
> // ie. float16 and smaller use half, float32 use full..
> .half_precision = !!(fd_mesa_debug & FD_DBG_FRAGHALF),
> .ucp_enables = ctx->rasterizer->clip_plane_enable,
> - .has_per_samp = (fd4_ctx->fsaturate || fd4_ctx->vsaturate),
> + .has_per_samp = (fd4_ctx->fsaturate || fd4_ctx->vsaturate ||
> + fd4_ctx->flower_srgb || fd4_ctx->vlower_srgb),
> .vsaturate_s = fd4_ctx->vsaturate_s,
> .vsaturate_t = fd4_ctx->vsaturate_t,
> .vsaturate_r = fd4_ctx->vsaturate_r,
> .fsaturate_s = fd4_ctx->fsaturate_s,
> .fsaturate_t = fd4_ctx->fsaturate_t,
> .fsaturate_r = fd4_ctx->fsaturate_r,
> + .vlower_srgb = fd4_ctx->vlower_srgb,
> + .flower_srgb = fd4_ctx->flower_srgb,
> },
> .rasterflat = ctx->rasterizer->flatshade,
> .sprite_coord_enable = ctx->rasterizer->sprite_coord_enable,
> diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
> index 3834858..1b0b45f 100644
> --- a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
> +++ b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
> @@ -209,6 +209,13 @@ tex_type(unsigned target)
> }
> }
>
> +static bool
> +use_srgb_lowering(struct pipe_context *pctx, enum pipe_format format)
> +{
> + /* TODO maybe this is only needed for a420? or certain patch-levels? */
> + return (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_ASTC);
> +}
> +
> static struct pipe_sampler_view *
> fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
> const struct pipe_sampler_view *cso)
> @@ -233,8 +240,12 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
> fd4_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
> cso->swizzle_b, cso->swizzle_a);
>
> - if (util_format_is_srgb(cso->format))
> - so->texconst0 |= A4XX_TEX_CONST_0_SRGB;
> + if (util_format_is_srgb(cso->format)) {
> + if (use_srgb_lowering(pctx, cso->format))
> + so->lower_srgb = true;
> + else
> + so->texconst0 |= A4XX_TEX_CONST_0_SRGB;
> + }
>
> if (cso->target == PIPE_BUFFER) {
> unsigned elements = cso->u.buf.last_element -
> @@ -296,11 +307,39 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
> return &so->base;
> }
>
> +static void
> +fd4_set_sampler_views(struct pipe_context *pctx, unsigned shader,
> + unsigned start, unsigned nr,
> + struct pipe_sampler_view **views)
> +{
> + struct fd_context *ctx = fd_context(pctx);
> + struct fd4_context *fd4_ctx = fd4_context(ctx);
> + uint16_t lower_srgb = 0;
> + unsigned i;
> +
> + for (i = 0; i < nr; i++) {
> + if (views[i]) {
> + struct fd4_pipe_sampler_view *view =
> + fd4_pipe_sampler_view(views[i]);
> + if (view->lower_srgb)
> + lower_srgb |= (1 << i);
> + }
> + }
> +
> + fd_set_sampler_views(pctx, shader, start, nr, views);
> +
> + if (shader == PIPE_SHADER_FRAGMENT) {
> + fd4_ctx->flower_srgb = lower_srgb;
> + } else if (shader == PIPE_SHADER_VERTEX) {
> + fd4_ctx->vlower_srgb = lower_srgb;
> + }
I think you want something a bit more complex... the API allows start
!= 0, and nr != 16. So you need to mask out the relevant bits, and
shift lower_srgb into the right spot.
> +}
> +
> void
> fd4_texture_init(struct pipe_context *pctx)
> {
> pctx->create_sampler_state = fd4_sampler_state_create;
> pctx->bind_sampler_states = fd4_sampler_states_bind;
> pctx->create_sampler_view = fd4_sampler_view_create;
> - pctx->set_sampler_views = fd_set_sampler_views;
> + pctx->set_sampler_views = fd4_set_sampler_views;
> }
> diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_texture.h b/src/gallium/drivers/freedreno/a4xx/fd4_texture.h
> index 6ca34ad..af2140d 100644
> --- a/src/gallium/drivers/freedreno/a4xx/fd4_texture.h
> +++ b/src/gallium/drivers/freedreno/a4xx/fd4_texture.h
> @@ -53,6 +53,7 @@ struct fd4_pipe_sampler_view {
> struct pipe_sampler_view base;
> uint32_t texconst0, texconst1, texconst2, texconst3, texconst4;
> uint32_t offset;
> + bool lower_srgb;
> };
>
> static inline struct fd4_pipe_sampler_view *
> diff --git a/src/gallium/drivers/freedreno/ir3/ir3_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_nir.c
> index 897b3b9..7836789 100644
> --- a/src/gallium/drivers/freedreno/ir3/ir3_nir.c
> +++ b/src/gallium/drivers/freedreno/ir3/ir3_nir.c
> @@ -58,6 +58,7 @@ ir3_key_lowers_nir(const struct ir3_shader_key *key)
> {
> return key->fsaturate_s | key->fsaturate_t | key->fsaturate_r |
> key->vsaturate_s | key->vsaturate_t | key->vsaturate_r |
> + key->vlower_srgb | key->flower_srgb |
> key->ucp_enables | key->color_two_side;
> }
>
> @@ -85,11 +86,13 @@ ir3_optimize_nir(struct ir3_shader *shader, nir_shader *s,
> tex_options.saturate_s = key->fsaturate_s;
> tex_options.saturate_t = key->fsaturate_t;
> tex_options.saturate_r = key->fsaturate_r;
> + tex_options.lower_srgb = key->flower_srgb;
> break;
> case SHADER_VERTEX:
> tex_options.saturate_s = key->vsaturate_s;
> tex_options.saturate_t = key->vsaturate_t;
> tex_options.saturate_r = key->vsaturate_r;
> + tex_options.lower_srgb = key->vlower_srgb;
> break;
> }
> }
> diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c
> index c05b52e..3d38088 100644
> --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c
> +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c
> @@ -223,6 +223,7 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key)
> key.vsaturate_s = 0;
> key.vsaturate_t = 0;
> key.vsaturate_r = 0;
> + key.vlower_srgb = 0;
> }
> break;
> case SHADER_VERTEX:
> @@ -233,6 +234,7 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key)
> key.fsaturate_s = 0;
> key.fsaturate_t = 0;
> key.fsaturate_r = 0;
> + key.flower_srgb = 0;
> }
> break;
> }
> diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.h b/src/gallium/drivers/freedreno/ir3/ir3_shader.h
> index c89dc29..82cde51 100644
> --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.h
> +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.h
> @@ -104,6 +104,9 @@ struct ir3_shader_key {
> * shader:
> */
> uint16_t fsaturate_s, fsaturate_t, fsaturate_r;
> +
> + /* bitmask of samplers which need srgb->linear lowering: */
> + uint16_t vlower_srgb, flower_srgb;
> };
>
> static inline bool
> --
> 2.5.5
>
More information about the mesa-dev
mailing list