freedreno/a4xx: lower srgb in shader for astc textures
authorRob Clark <robclark@freedesktop.org>
Tue, 19 Apr 2016 13:02:23 +0000 (09:02 -0400)
committerRob Clark <robclark@freedesktop.org>
Tue, 19 Apr 2016 21:14:04 +0000 (17:14 -0400)
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@freedesktop.org>
src/gallium/drivers/freedreno/a4xx/fd4_context.h
src/gallium/drivers/freedreno/a4xx/fd4_draw.c
src/gallium/drivers/freedreno/a4xx/fd4_texture.c
src/gallium/drivers/freedreno/a4xx/fd4_texture.h
src/gallium/drivers/freedreno/ir3/ir3_nir.c
src/gallium/drivers/freedreno/ir3/ir3_shader.c
src/gallium/drivers/freedreno/ir3/ir3_shader.h

index 8996de932b8576bef9a15aca3d1cc4fbc99ea7be..a08c3c3119b1d2368bc2df172b45d2602a4e7ac5 100644 (file)
@@ -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()
index e874d223187549601ab5c8ea8dd7651effaa9430..a0866261fcb263dfc33bd873dcfb505ecc2680c0 100644 (file)
@@ -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,
index 38348580e2169c940b5c2f69bcd2e55106d8347c..eee7a39adfd9ab97b3e883ca95537a5c7767476a 100644 (file)
@@ -209,6 +209,13 @@ tex_type(unsigned target)
        }
 }
 
+static bool
+use_srgb_lowering(struct pipe_context *pctx, enum pipe_format format)
+{
+       return (fd_screen(pctx->screen)->gpu_id == 420) &&
+               (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;
+       }
+}
+
 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;
 }
index 6ca34ade60db3043148f47bb41c200efcd9c9c08..af2140db504b4fc9faccd0b9fa95c9ef0abbcd48 100644 (file)
@@ -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 *
index 897b3b963becd2dd98d1f2d7501790451d9bb5bc..7836789de8ffb2c2c093dcd427c57282ccf97a10 100644 (file)
@@ -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;
                }
        }
index c05b52e7a5e1627754ec388a6bfd87b40cfa5f6d..3d38088510ad3a9ec96667885f8322a174601b6e 100644 (file)
@@ -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;
        }
index c89dc29ff08784956934e611e66b91aa9cec3f94..82cde51e635a50790a358de6dc3396fd9fd656ac 100644 (file)
@@ -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