i965/gen6+: Disable blending, alpha test, and dither on integer FBOs.
authorEric Anholt <eric@anholt.net>
Thu, 19 Jan 2012 23:41:12 +0000 (15:41 -0800)
committerEric Anholt <eric@anholt.net>
Wed, 25 Jan 2012 00:00:04 +0000 (16:00 -0800)
Fixes GPU hangs and some rendering failures in piglit
EXT_texture_integer/fbo-blending

NOTE: This is a candidate for the 8.0 branch.

src/mesa/drivers/dri/i965/gen6_cc.c

index 916ec7d0456a90020629023a5c906a95ce102679..dada09ca7dd70274d1933834b8451dc49d124a35 100644 (file)
@@ -57,19 +57,36 @@ gen6_upload_blend_state(struct brw_context *brw)
    memset(blend, 0, size);
 
    for (b = 0; b < nr_draw_buffers; b++) {
+      /* _NEW_BUFFERS */
+      struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[b];
+      GLenum rb_type;
+      bool integer;
+
+      if (rb)
+        rb_type = _mesa_get_format_datatype(rb->Format);
+      else
+        rb_type = GL_UNSIGNED_NORMALIZED;
+
+      /* Used for implementing the following bit of GL_EXT_texture_integer:
+       *
+       *     "Per-fragment operations that require floating-point color
+       *      components, including multisample alpha operations, alpha test,
+       *      blending, and dithering, have no effect when the corresponding
+       *      colors are written to an integer color buffer."
+      */
+      integer = (rb_type == GL_INT || rb_type == GL_UNSIGNED_INT);
+
       /* _NEW_COLOR */
       if (ctx->Color.ColorLogicOpEnabled) {
-        struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[b];
-        /* _NEW_BUFFERS */
         /* Floating point RTs should have no effect from LogicOp,
          * except for disabling of blending
          */
-        if (rb && _mesa_get_format_datatype(rb->Format) != GL_FLOAT) {
+        if (rb_type != GL_FLOAT) {
            blend[b].blend1.logic_op_enable = 1;
            blend[b].blend1.logic_op_func =
               intel_translate_logic_op(ctx->Color.LogicOp);
         }
-      } else if (ctx->Color.BlendEnabled & (1 << b)) {
+      } else if (ctx->Color.BlendEnabled & (1 << b) && !integer) {
         GLenum eqRGB = ctx->Color.Blend[0].EquationRGB;
         GLenum eqA = ctx->Color.Blend[0].EquationA;
         GLenum srcRGB = ctx->Color.Blend[0].SrcRGB;
@@ -121,7 +138,7 @@ gen6_upload_blend_state(struct brw_context *brw)
       blend[b].blend1.clamp_range = BRW_RENDERTARGET_CLAMPRANGE_FORMAT;
 
       /* _NEW_COLOR */
-      if (ctx->Color.AlphaEnabled) {
+      if (ctx->Color.AlphaEnabled && !integer) {
         blend[b].blend1.alpha_test_enable = 1;
         blend[b].blend1.alpha_test_func =
            intel_translate_compare_func(ctx->Color.AlphaFunc);
@@ -129,7 +146,7 @@ gen6_upload_blend_state(struct brw_context *brw)
       }
 
       /* _NEW_COLOR */
-      if (ctx->Color.DitherFlag) {
+      if (ctx->Color.DitherFlag && !integer) {
         blend[b].blend1.dither_enable = 1;
         blend[b].blend1.y_dither_offset = 0;
         blend[b].blend1.x_dither_offset = 0;