r600g: workaround hyperz lockup on evergreen
authorJerome Glisse <jglisse@redhat.com>
Wed, 20 Feb 2013 21:20:17 +0000 (16:20 -0500)
committerJerome Glisse <jglisse@redhat.com>
Thu, 28 Feb 2013 14:48:05 +0000 (09:48 -0500)
This work around disable hyperz if write to zbuffer is disabled. Somehow
using hyperz when not writting to the zbuffer trigger GPU lockup. See :

https://bugs.freedesktop.org/show_bug.cgi?id=60848

Candidate for 9.1

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_pipe.h
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_common.c

index 4a91942..2e301bc 100644 (file)
@@ -858,6 +858,7 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx,
        dsa->valuemask[1] = state->stencil[1].valuemask;
        dsa->writemask[0] = state->stencil[0].writemask;
        dsa->writemask[1] = state->stencil[1].writemask;
+       dsa->zwritemask = state->depth.writemask;
 
        db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) |
                S_028800_Z_WRITE_ENABLE(state->depth.writemask) |
@@ -2286,7 +2287,14 @@ static void evergreen_emit_db_misc_state(struct r600_context *rctx, struct r600_
                }
                db_render_override |= S_02800C_NOOP_CULL_DISABLE(1);
        }
-       if (rctx->db_state.rsurf && rctx->db_state.rsurf->htile_enabled) {
+       /* FIXME we should be able to use hyperz even if we are not writing to
+        * zbuffer but somehow this trigger GPU lockup. See :
+        *
+        * https://bugs.freedesktop.org/show_bug.cgi?id=60848
+        *
+        * Disable hyperz for now if not writing to zbuffer.
+        */
+       if (rctx->db_state.rsurf && rctx->db_state.rsurf->htile_enabled && rctx->zwritemask) {
                /* FORCE_OFF means HiZ/HiS are determined by DB_SHADER_CONTROL */
                db_render_override |= S_02800C_FORCE_HIZ_ENABLE(V_02800C_FORCE_OFF);
                /* This is to fix a lockup when hyperz and alpha test are enabled at
index 88b587e..1d0ad79 100644 (file)
@@ -298,7 +298,8 @@ struct r600_dsa_state {
        unsigned                        alpha_ref;
        ubyte                           valuemask[2];
        ubyte                           writemask[2];
-       unsigned                        sx_alpha_test_control;
+       unsigned                        zwritemask;
+       unsigned                        sx_alpha_test_control;
 };
 
 struct r600_pipe_shader;
@@ -513,6 +514,7 @@ struct r600_context {
        bool                            alpha_to_one;
        bool                            force_blend_disable;
        boolean                         dual_src_blend;
+       unsigned                        zwritemask;
 
        /* Index buffer. */
        struct pipe_index_buffer        index_buffer;
index c6559bb..2d3ec93 100644 (file)
@@ -842,6 +842,7 @@ static void *r600_create_dsa_state(struct pipe_context *ctx,
        dsa->valuemask[1] = state->stencil[1].valuemask;
        dsa->writemask[0] = state->stencil[0].writemask;
        dsa->writemask[1] = state->stencil[1].writemask;
+       dsa->zwritemask = state->depth.writemask;
 
        db_depth_control = S_028800_Z_ENABLE(state->depth.enabled) |
                S_028800_Z_WRITE_ENABLE(state->depth.writemask) |
index 1654233..fae28bc 100644 (file)
@@ -284,6 +284,16 @@ static void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
        ref.valuemask[1] = dsa->valuemask[1];
        ref.writemask[0] = dsa->writemask[0];
        ref.writemask[1] = dsa->writemask[1];
+       if (rctx->zwritemask != dsa->zwritemask) {
+               rctx->zwritemask = dsa->zwritemask;
+               if (rctx->chip_class >= EVERGREEN) {
+                       /* work around some issue when not writting to zbuffer
+                        * we are having lockup on evergreen so do not enable
+                        * hyperz when not writting zbuffer
+                        */
+                       rctx->db_misc_state.atom.dirty = true;
+               }
+       }
 
        r600_set_stencil_ref(ctx, &ref);