+static unsigned rgba_cmask(unsigned mask)
+{
+ return mask & PIPE_MASK_RGBA;
+}
+
+static unsigned rrrr_cmask(unsigned mask)
+{
+ return (mask & PIPE_MASK_R) |
+ ((mask & PIPE_MASK_R) << 1) |
+ ((mask & PIPE_MASK_R) << 2) |
+ ((mask & PIPE_MASK_R) << 3);
+}
+
+static unsigned aaaa_cmask(unsigned mask)
+{
+ return ((mask & PIPE_MASK_A) >> 3) |
+ ((mask & PIPE_MASK_A) >> 2) |
+ ((mask & PIPE_MASK_A) >> 1) |
+ (mask & PIPE_MASK_A);
+}
+
+static unsigned grrg_cmask(unsigned mask)
+{
+ return ((mask & PIPE_MASK_R) << 1) |
+ ((mask & PIPE_MASK_R) << 2) |
+ ((mask & PIPE_MASK_G) >> 1) |
+ ((mask & PIPE_MASK_G) << 2);
+}
+
+static unsigned arra_cmask(unsigned mask)
+{
+ return ((mask & PIPE_MASK_R) << 1) |
+ ((mask & PIPE_MASK_R) << 2) |
+ ((mask & PIPE_MASK_A) >> 3) |
+ (mask & PIPE_MASK_A);
+}
+
+static unsigned blend_read_enable(unsigned eqRGB, unsigned eqA,
+ unsigned dstRGB, unsigned dstA,
+ unsigned srcRGB, unsigned srcA,
+ boolean src_alpha_optz)
+{
+ unsigned blend_control = 0;
+
+ /* Optimization: some operations do not require the destination color.
+ *
+ * When SRC_ALPHA_SATURATE is used, colorbuffer reads must be enabled,
+ * otherwise blending gives incorrect results. It seems to be
+ * a hardware bug. */
+ if (eqRGB == PIPE_BLEND_MIN || eqA == PIPE_BLEND_MIN ||
+ eqRGB == PIPE_BLEND_MAX || eqA == PIPE_BLEND_MAX ||
+ dstRGB != PIPE_BLENDFACTOR_ZERO ||
+ dstA != PIPE_BLENDFACTOR_ZERO ||
+ util_blend_factor_uses_dest(srcRGB, false) ||
+ util_blend_factor_uses_dest(srcA, true)) {
+ /* Enable reading from the colorbuffer. */
+ blend_control |= R300_READ_ENABLE;
+
+ if (src_alpha_optz) {
+ /* Optimization: Depending on incoming pixels, we can
+ * conditionally disable the reading in hardware... */
+ if (eqRGB != PIPE_BLEND_MIN && eqA != PIPE_BLEND_MIN &&
+ eqRGB != PIPE_BLEND_MAX && eqA != PIPE_BLEND_MAX) {
+ /* Disable reading if SRC_ALPHA == 0. */
+ if ((dstRGB == PIPE_BLENDFACTOR_SRC_ALPHA ||
+ dstRGB == PIPE_BLENDFACTOR_ZERO) &&
+ (dstA == PIPE_BLENDFACTOR_SRC_COLOR ||
+ dstA == PIPE_BLENDFACTOR_SRC_ALPHA ||
+ dstA == PIPE_BLENDFACTOR_ZERO) &&
+ (srcRGB != PIPE_BLENDFACTOR_DST_COLOR &&
+ srcRGB != PIPE_BLENDFACTOR_DST_ALPHA &&
+ srcRGB != PIPE_BLENDFACTOR_INV_DST_COLOR &&
+ srcRGB != PIPE_BLENDFACTOR_INV_DST_ALPHA)) {
+ blend_control |= R500_SRC_ALPHA_0_NO_READ;
+ }
+
+ /* Disable reading if SRC_ALPHA == 1. */
+ if ((dstRGB == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+ dstRGB == PIPE_BLENDFACTOR_ZERO) &&
+ (dstA == PIPE_BLENDFACTOR_INV_SRC_COLOR ||
+ dstA == PIPE_BLENDFACTOR_INV_SRC_ALPHA ||
+ dstA == PIPE_BLENDFACTOR_ZERO) &&
+ (srcRGB != PIPE_BLENDFACTOR_DST_COLOR &&
+ srcRGB != PIPE_BLENDFACTOR_DST_ALPHA &&
+ srcRGB != PIPE_BLENDFACTOR_INV_DST_COLOR &&
+ srcRGB != PIPE_BLENDFACTOR_INV_DST_ALPHA)) {
+ blend_control |= R500_SRC_ALPHA_1_NO_READ;
+ }
+ }
+ }
+ }
+ return blend_control;
+}
+