i965/blorp: Support overriding destination alpha to 1.0.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 29 Jan 2013 06:03:18 +0000 (22:03 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 6 Feb 2013 18:00:53 +0000 (10:00 -0800)
Currently, Blorp requires the source and destination formats to be
equal.  However, we'd really like to be able to blit between XRGB and
ARGB formats; our BLT engine paths have supported this for a long time.

For ARGB -> XRGB, nothing needs to occur: the missing alpha is already
interpreted as 1.0.  For XRGB -> ARGB, we need to smash the alpha
channel to 1.0 when writing the destination colors.  This is fairly
straightforward with blending.

For now, this code is never used, as the source and destination formats
still must be equal.  The next patch will relax that restriction.

NOTE: This is a candidate for the 9.1 branch.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Tested-by: Martin Steigerwald <martin@lichtvoll.de>
src/mesa/drivers/dri/i965/gen6_blorp.cpp

index eb618988f2ad29dc6c0333ffe44802e8aed0e67f..3834ae230bfeb2b0e87d1b6aabd54aa300406f83 100644 (file)
@@ -283,6 +283,25 @@ gen6_blorp_emit_blend_state(struct brw_context *brw,
    blend->blend1.write_disable_b = false;
    blend->blend1.write_disable_a = false;
 
+   /* When blitting from an XRGB source to a ARGB destination, we need to
+    * interpret the missing channel as 1.0.  Blending can do that for us:
+    * we simply use the RGB values from the fragment shader ("source RGB"),
+    * but smash the alpha channel to 1.
+    */
+   if (_mesa_get_format_bits(params->dst.mt->format, GL_ALPHA_BITS) > 0 &&
+       _mesa_get_format_bits(params->src.mt->format, GL_ALPHA_BITS) == 0) {
+      blend->blend0.blend_enable = 1;
+      blend->blend0.ia_blend_enable = 1;
+
+      blend->blend0.blend_func = BRW_BLENDFUNCTION_ADD;
+      blend->blend0.ia_blend_func = BRW_BLENDFUNCTION_ADD;
+
+      blend->blend0.source_blend_factor = BRW_BLENDFACTOR_SRC_COLOR;
+      blend->blend0.dest_blend_factor = BRW_BLENDFACTOR_ZERO;
+      blend->blend0.ia_source_blend_factor = BRW_BLENDFACTOR_ONE;
+      blend->blend0.ia_dest_blend_factor = BRW_BLENDFACTOR_ZERO;
+   }
+
    return cc_blend_state_offset;
 }