summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2006-09-19 10:27:36 +0800
committerWang Zhenyu <zhenyu.z.wang@intel.com>2006-09-19 10:27:36 +0800
commite3ab89b0327ef6ff790ab53bba29c721aef032cd (patch)
tree287d142c30e3ae866ed3336e868b8418d914851a
parent37429c3ecb97df8faf0f3f56128d7a2b22eb8a5e (diff)
shader program fix for component alpha set
If CA is set and blend op needs src alpha, the src value is not needed and should be (src.A * mask.X). This is found in handling exa magic two pass composite.
-rw-r--r--src/i915_exa_render.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/src/i915_exa_render.c b/src/i915_exa_render.c
index 62b2507a..3bc2c0b9 100644
--- a/src/i915_exa_render.c
+++ b/src/i915_exa_render.c
@@ -473,15 +473,23 @@ I915EXAPrepareComposite(int op, PicturePtr pSrcPicture,
if (PICT_FORMAT_A(pMaskPicture->format) == 0)
i915_fs_mov_masked(FS_R1, MASK_W, i915_fs_operand_one());
- /* If component alpha is set in the mask, then we need to provide
- * the source alpha component (channelwise multiplication) as the
- * output color. If it isn't set, then we need to provide the
- * source value component, which is the multipliction of the source
- * by the mask alpha.
+ /* If component alpha is set in the mask and the blend operation
+ * uses the source alpha, then we know we don't need the source
+ * value (otherwise we would have hit a fallback earlier), so we
+ * provide the source alpha (src.A * mask.X) as output color.
+ * Conversely, if CA is set and we don't need the source alpha, then
+ * we produce the source value (src.X * mask.X) and the source alpha
+ * is unused.. Otherwise, we provide the non-CA source value
+ * (src.X * mask.A).
*/
- if (pMaskPicture->componentAlpha && pDstPicture->format != PICT_a8) {
- i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
- i915_fs_operand_reg(FS_R1));
+ if (pMaskPicture->componentAlpha) {
+ if (I915BlendOp[op].src_alpha) {
+ i915_fs_mul(FS_OC, i915_fs_operand(FS_R0, W, W, W, W),
+ i915_fs_operand_reg(FS_R1));
+ } else {
+ i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
+ i915_fs_operand_reg(FS_R1));
+ }
} else {
i915_fs_mul(FS_OC, i915_fs_operand_reg(FS_R0),
i915_fs_operand(FS_R1, W, W, W, W));