Mesa (master): i965: Avoid blending with destination alpha when RB format has no alpha bits

Carl Worth cworth at kemper.freedesktop.org
Mon Jan 14 23:40:05 UTC 2013


Module: Mesa
Branch: master
Commit: 258453716f001eab1288d99765213221d0599ca4
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=258453716f001eab1288d99765213221d0599ca4

Author: Carl Worth <cworth at cworth.org>
Date:   Fri Jan 11 07:15:18 2013 -0800

i965: Avoid blending with destination alpha when RB format has no alpha bits

The hardware does not support a render target without an alpha channel.
So when the user creates a render buffer with no alpha channel, there actually
is storage available for alpha internally. It requires special care to
avoid these unwanted alpha bits from causing any problems.

Specifically, when blending, and when the blend factors would read the
destination alpha values, this commit coerces the blend factors to instead be
either 0 or 1 as appropriate.

A similar fix was made for pre-gen6 hardware in commit eadd9b8e and this
commit shares the fixup function written by Ian then.

This commit the following es3conform test:

	rgb8_rgba8_rgb

As well as the following piglit (sub) tests:

	EXT_framebuffer_object/fbo-blending-formats/3
	EXT_framebuffer_object/fbo-blending-formats/GL_RGB
	EXT_framebuffer_object/fbo-blending-formats/GL_RGB8

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

---

 src/mesa/drivers/dri/i965/brw_cc.c   |   12 ++++++------
 src/mesa/drivers/dri/i965/brw_util.h |    3 +--
 src/mesa/drivers/dri/i965/gen6_cc.c  |   15 +++++++++++++++
 3 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_cc.c b/src/mesa/drivers/dri/i965/brw_cc.c
index 78809da..f5affcf 100644
--- a/src/mesa/drivers/dri/i965/brw_cc.c
+++ b/src/mesa/drivers/dri/i965/brw_cc.c
@@ -75,8 +75,8 @@ const struct brw_tracked_state brw_cc_vp = {
  * replace it with a function that hard-wires destination alpha to 1.0.  This
  * is used when rendering to xRGB targets.
  */
-static GLenum
-fix_xRGB_alpha(GLenum function)
+GLenum
+brw_fix_xRGB_alpha(GLenum function)
 {
    switch (function) {
    case GL_DST_ALPHA:
@@ -159,10 +159,10 @@ static void upload_cc_unit(struct brw_context *brw)
        * with GL_ONE and GL_ONE_MINUS_DST_ALPHA with GL_ZERO.
        */
       if (ctx->DrawBuffer->Visual.alphaBits == 0) {
-	 srcRGB = fix_xRGB_alpha(srcRGB);
-	 srcA   = fix_xRGB_alpha(srcA);
-	 dstRGB = fix_xRGB_alpha(dstRGB);
-	 dstA   = fix_xRGB_alpha(dstA);
+	 srcRGB = brw_fix_xRGB_alpha(srcRGB);
+	 srcA   = brw_fix_xRGB_alpha(srcA);
+	 dstRGB = brw_fix_xRGB_alpha(dstRGB);
+	 dstA   = brw_fix_xRGB_alpha(dstA);
       }
 
       if (eqRGB == GL_MIN || eqRGB == GL_MAX) {
diff --git a/src/mesa/drivers/dri/i965/brw_util.h b/src/mesa/drivers/dri/i965/brw_util.h
index c0fc133..5cba99a 100644
--- a/src/mesa/drivers/dri/i965/brw_util.h
+++ b/src/mesa/drivers/dri/i965/brw_util.h
@@ -39,7 +39,6 @@
 extern GLuint brw_parameter_list_state_flags(struct gl_program_parameter_list *paramList);
 extern GLuint brw_translate_blend_factor( GLenum factor );
 extern GLuint brw_translate_blend_equation( GLenum mode );
-
-
+extern GLenum brw_fix_xRGB_alpha(GLenum function);
 
 #endif
diff --git a/src/mesa/drivers/dri/i965/gen6_cc.c b/src/mesa/drivers/dri/i965/gen6_cc.c
index b61a816c..fcd1794 100644
--- a/src/mesa/drivers/dri/i965/gen6_cc.c
+++ b/src/mesa/drivers/dri/i965/gen6_cc.c
@@ -118,6 +118,21 @@ gen6_upload_blend_state(struct brw_context *brw)
 	    srcA = dstA = GL_ONE;
 	 }
 
+         /* Due to hardware limitations, the destination may have information
+          * in an alpha channel even when the format specifies no alpha
+          * channel. In order to avoid getting any incorrect blending due to
+          * that alpha channel, coerce the blend factors to values that will
+          * not read the alpha channel, but will instead use the correct
+          * implicit value for alpha.
+          */
+         if (_mesa_get_format_bits(rb->Format, GL_ALPHA_BITS) == 0)
+         {
+            srcRGB = brw_fix_xRGB_alpha(srcRGB);
+            srcA = brw_fix_xRGB_alpha(srcA);
+            dstRGB = brw_fix_xRGB_alpha(dstRGB);
+            dstA = brw_fix_xRGB_alpha(dstA);
+         }
+
 	 blend[b].blend0.dest_blend_factor = brw_translate_blend_factor(dstRGB);
 	 blend[b].blend0.source_blend_factor = brw_translate_blend_factor(srcRGB);
 	 blend[b].blend0.blend_func = brw_translate_blend_equation(eqRGB);




More information about the mesa-commit mailing list