diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c index 4736e4f..d4cd77c 100644 --- a/src/radeon_exa_render.c +++ b/src/radeon_exa_render.c @@ -824,7 +824,8 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture, { RINFO_FROM_SCREEN(pDst->drawable.pScreen); uint32_t dst_format, dst_offset, dst_pitch; - uint32_t pp_cntl, blendcntl, cblend, ablend, colorpitch; + uint32_t pp_cntl, blendcntl, colorpitch; + uint32_t src_color, src_alpha, mask_color, mask_alpha; int pixel_shift; ACCEL_PREAMBLE(); @@ -896,37 +897,82 @@ static Bool FUNC_NAME(R200PrepareComposite)(int op, PicturePtr pSrcPicture, * be the source alpha (and there's no source value used), we have to zero * the source's color values. */ - cblend = R200_TXC_OP_MADD | R200_TXC_ARG_C_ZERO; - ablend = R200_TXA_OP_MADD | R200_TXA_ARG_C_ZERO; - if (pDstPicture->format == PICT_a8 || - (pMask && pMaskPicture->componentAlpha && RadeonBlendOp[op].src_alpha)) - { - cblend |= R200_TXC_ARG_A_R0_ALPHA; - } else if (pSrcPicture->format == PICT_a8) - cblend |= R200_TXC_ARG_A_ZERO; + if (PICT_FORMAT_RGB(pSrcPicture->format) == 0) + src_color = R200_TXC_ARG_A_ZERO; else - cblend |= R200_TXC_ARG_A_R0_COLOR; - ablend |= R200_TXA_ARG_A_R0_ALPHA; + src_color = R200_TXC_ARG_A_R0_COLOR; - if (pMask) { - if (pMaskPicture->componentAlpha && - pDstPicture->format != PICT_a8) - cblend |= R200_TXC_ARG_B_R1_COLOR; + if (PICT_FORMAT_A(pSrcPicture->format) == 0) + src_alpha = R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A; + else + src_alpha = R200_TXA_ARG_A_R0_ALPHA; + + if (pMask && pMaskPicture->componentAlpha) { + if (RadeonBlendOp[op].src_alpha) { + if (PICT_FORMAT_A(pSrcPicture->format) == 0) { + src_color = R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A; + src_alpha = R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A; + } else { + src_color = R200_TXC_ARG_A_R0_ALPHA; + src_alpha = R200_TXA_ARG_A_R0_ALPHA; + } + + mask_color = R200_TXC_ARG_B_R1_COLOR; + + if (PICT_FORMAT_A(pMaskPicture->format) == 0) + mask_alpha = R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B; + else + mask_alpha = R200_TXA_ARG_B_R1_ALPHA; + + } else { + src_color = R200_TXC_ARG_A_R0_COLOR; + + if (PICT_FORMAT_A(pSrcPicture->format) == 0) + src_alpha = R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A; + else + src_alpha = R200_TXA_ARG_A_R0_ALPHA; + + mask_color = R200_TXC_ARG_B_R1_COLOR; + + if (PICT_FORMAT_A(pMaskPicture->format) == 0) + mask_alpha = R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B; + else + mask_alpha = R200_TXA_ARG_B_R1_ALPHA; + + } + } else if (pMask) { + if (PICT_FORMAT_A(pMaskPicture->format) == 0) + mask_color = R200_TXC_ARG_B_ZERO | R200_TXC_COMP_ARG_B; else - cblend |= R200_TXC_ARG_B_R1_ALPHA; - ablend |= R200_TXA_ARG_B_R1_ALPHA; + mask_color = R200_TXC_ARG_B_R1_ALPHA; + + if (PICT_FORMAT_A(pMaskPicture->format) == 0) + mask_alpha = R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B; + else + mask_alpha = R200_TXA_ARG_B_R1_ALPHA; } else { - cblend |= R200_TXC_ARG_B_ZERO | R200_TXC_COMP_ARG_B; - ablend |= R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B; + mask_color = R200_TXC_ARG_B_ZERO | R200_TXC_COMP_ARG_B; + mask_alpha = R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B; } - OUT_ACCEL_REG(R200_PP_TXCBLEND_0, cblend); - OUT_ACCEL_REG(R200_PP_TXCBLEND2_0, - R200_TXC_CLAMP_0_1 | R200_TXC_OUTPUT_REG_R0); - OUT_ACCEL_REG(R200_PP_TXABLEND_0, ablend); + OUT_ACCEL_REG(R200_PP_TXCBLEND_0, (src_color | + mask_color | + R200_TXC_OP_MADD | + R200_TXC_ARG_C_ZERO)); + if (pDstPicture->format == PICT_a8) + OUT_ACCEL_REG(R200_PP_TXCBLEND2_0, (R200_TXC_CLAMP_0_1 | + R200_TXC_OUTPUT_REG_R0 | + R200_TXC_OUTPUT_ROTATE_ARG)); + else + OUT_ACCEL_REG(R200_PP_TXCBLEND2_0, (R200_TXC_CLAMP_0_1 | + R200_TXC_OUTPUT_REG_R0)); + OUT_ACCEL_REG(R200_PP_TXABLEND_0, (src_alpha | + mask_alpha | + R200_TXA_OP_MADD | + R200_TXA_ARG_C_ZERO)); OUT_ACCEL_REG(R200_PP_TXABLEND2_0, - R200_TXA_CLAMP_0_1 | R200_TXA_OUTPUT_REG_R0); + R200_TXA_CLAMP_0_1 | R200_TXA_OUTPUT_REG_R0); /* Op operator. */ blendcntl = RADEONGetBlendCntl(op, pMaskPicture, pDstPicture->format); diff --git a/src/radeon_reg.h b/src/radeon_reg.h index fbc724a..41c90b6 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -2862,6 +2862,10 @@ # define R200_TXC_OUTPUT_MASK_G (5 << 20) # define R200_TXC_OUTPUT_MASK_B (6 << 20) # define R200_TXC_OUTPUT_MASK_NONE (7 << 20) +# define R200_TXC_OUTPUT_ROTATE_RGB (0 << 24) +# define R200_TXC_OUTPUT_ROTATE_ARG (1 << 24) +# define R200_TXC_OUTPUT_ROTATE_GBA (2 << 24) +# define R200_TXC_OUTPUT_ROTATE_RGA (3 << 24) # define R200_TXC_REPL_NORMAL 0 # define R200_TXC_REPL_RED 1 # define R200_TXC_REPL_GREEN 2