i965/gen5,6: Fix hang when emitting hiz buffer without stencil buffer
authorChad Versace <chad@chad-versace.us>
Thu, 9 Jun 2011 04:51:10 +0000 (21:51 -0700)
committerChad Versace <chad@chad-versace.us>
Wed, 15 Jun 2011 22:47:59 +0000 (15:47 -0700)
When emitting either a hiz or stencil buffer, the 'separate stencil
enable' and 'hiz enable' bits are set in 3DSTATE_DEPTH_BUFFER. Therefore
we must emit both 3DSTATE_HIER_DEPTH_BUFFER and 3DSTATE_STENCIL_BUFFER.

Even if there is no stencil buffer, 3DSTATE_STENCIL_BUFFER must be
emitted; failure to do so causes a hang on gen5 and a stall on gen6.

This also fixes a silly, obvious segfault that occured when a hiz buffer
xor separate stencil buffer existed.

Fixes the piglit tests below on Gen5 when hiz and separate stencil are
manually enabled:
    fbo-alphatest-nocolor
    fbo-depth-sample-compare
    fbo
    hiz-depth-read-fbo-d24-s0
    hiz-depth-stencil-test-fbo-d24-s0
    hiz-depth-test-fbo-d24-s0
    hiz-stencil-read-fbo-d0-s8
    hiz-stencil-test-fbo-d0-s8
    fbo-missing-attachment-clear
    fbo-clear-formats
    fbo-depth-*

Changes piglit test result from crash to fail:
    hiz-depth-stencil-test-fbo-d0-s8

Signed-off-by: Chad Versace <chad@chad-versace.us>
src/mesa/drivers/dri/i965/brw_misc_state.c

index 2b5ec8ac6770e94312c1abf1a843e39bf7c0b09e..1f3b64fd53834e4562afca095fc0a4e99431ad97 100644 (file)
@@ -355,26 +355,48 @@ static void emit_depthbuffer(struct brw_context *brw)
       ADVANCE_BATCH();
    }
 
-   /* Emit hiz buffer. */
    if (hiz_region || stencil_irb) {
-      BEGIN_BATCH(3);
-      OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
-      OUT_BATCH(hiz_region->pitch * hiz_region->cpp - 1);
-      OUT_RELOC(hiz_region->buffer,
-               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-               0);
-      ADVANCE_BATCH();
-   }
+      /*
+       * In the 3DSTATE_DEPTH_BUFFER batch emitted above, the 'separate
+       * stencil enable' and 'hiz enable' bits were set. Therefore we must
+       * emit 3DSTATE_HIER_DEPTH_BUFFER and 3DSTATE_STENCIL_BUFFER. Even if
+       * there is no stencil buffer, 3DSTATE_STENCIL_BUFFER must be emitted;
+       * failure to do so causes hangs on gen5 and a stall on gen6.
+       */
 
-   /* Emit stencil buffer. */
-   if (hiz_region || stencil_irb) {
-      BEGIN_BATCH(3);
-      OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
-      OUT_BATCH(stencil_irb->region->pitch * stencil_irb->region->cpp - 1);
-      OUT_RELOC(stencil_irb->region->buffer,
-               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
-               0);
-      ADVANCE_BATCH();
+      /* Emit hiz buffer. */
+      if (hiz_region) {
+        BEGIN_BATCH(3);
+        OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
+        OUT_BATCH(hiz_region->pitch * hiz_region->cpp - 1);
+        OUT_RELOC(hiz_region->buffer,
+                  I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+                  0);
+        ADVANCE_BATCH();
+      } else {
+        BEGIN_BATCH(3);
+        OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
+        OUT_BATCH(0);
+        OUT_BATCH(0);
+        ADVANCE_BATCH();
+      }
+
+      /* Emit stencil buffer. */
+      if (stencil_irb) {
+        BEGIN_BATCH(3);
+        OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
+        OUT_BATCH(stencil_irb->region->pitch * stencil_irb->region->cpp - 1);
+        OUT_RELOC(stencil_irb->region->buffer,
+                  I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
+                  0);
+        ADVANCE_BATCH();
+      } else {
+        BEGIN_BATCH(3);
+        OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
+        OUT_BATCH(0);
+        OUT_BATCH(0);
+        ADVANCE_BATCH();
+      }
    }
 
    /*