/* First, we'll try fixed function, matching equation and constant */
if (pan_blend_can_fixed_function(dev, &pan_blend, rti)) {
+ const struct pan_blend_equation eq = pan_blend.rts[rti].equation;
+ unsigned constant_mask = pan_blend_constant_mask(eq);
+
struct panfrost_blend_final final = {
.load_dest = pan_blend_reads_dest(pan_blend.rts[rti].equation),
- .equation.constant = pan_blend_get_constant(dev, &pan_blend, rti),
+ .equation.constant = pan_blend_get_constant(constant_mask, ctx->blend_color.color),
.opaque = pan_blend_is_opaque(pan_blend.rts[rti].equation),
.no_colour = pan_blend.rts[rti].equation.color_mask == 0,
};
}
unsigned
-pan_blend_constant_mask(const struct pan_blend_state *state,
- unsigned rt)
+pan_blend_constant_mask(const struct pan_blend_equation eq)
{
- const struct pan_blend_equation *e = &state->rts[rt].equation;
-
- return blend_factor_constant_mask(e->rgb_src_factor) |
- blend_factor_constant_mask(e->rgb_dst_factor) |
- blend_factor_constant_mask(e->alpha_src_factor) |
- blend_factor_constant_mask(e->alpha_dst_factor);
+ return blend_factor_constant_mask(eq.rgb_src_factor) |
+ blend_factor_constant_mask(eq.rgb_dst_factor) |
+ blend_factor_constant_mask(eq.alpha_src_factor) |
+ blend_factor_constant_mask(eq.alpha_dst_factor);
}
static bool
const struct pan_blend_state *state,
unsigned rt)
{
- unsigned constant_mask = pan_blend_constant_mask(state, rt);
+ unsigned constant_mask = pan_blend_constant_mask(state->rts[rt].equation);
if (!constant_mask)
return true;
if (dev->arch == 7 && rt > 0)
return false;
- unsigned first_constant = ffs(constant_mask) - 1;
- float constant = state->constants[first_constant];
+ float constant = pan_blend_get_constant(constant_mask, state->constants);
- for (unsigned i = first_constant + 1; i < ARRAY_SIZE(state->constants); i++) {
- if (((1 << i) & constant_mask) &&
- state->constants[i] != constant)
+ u_foreach_bit(i, constant_mask) {
+ if (state->constants[i] != constant)
return false;
}
return true;
}
-float
-pan_blend_get_constant(ASSERTED const struct panfrost_device *dev,
- const struct pan_blend_state *state,
- unsigned rt)
-{
- assert(can_blend_constant(dev, state, rt));
-
- unsigned constant_mask = pan_blend_constant_mask(state, rt);
-
- if (!constant_mask)
- return 0.0f;
-
- return state->constants[ffs(constant_mask) - 1];
-}
-
bool
pan_blend_can_fixed_function(const struct panfrost_device *dev,
const struct pan_blend_state *state,
.src0_type = src0_type,
.src1_type = src1_type,
.rt = rt,
- .has_constants = pan_blend_constant_mask(state, rt) != 0,
+ .has_constants = pan_blend_constant_mask(state->rts[rt].equation) != 0,
.logicop_enable = state->logicop_enable,
.logicop_func = state->logicop_func,
.nr_samples = state->rts[rt].nr_samples,
pan_blend_is_opaque(const struct pan_blend_equation eq);
unsigned
-pan_blend_constant_mask(const struct pan_blend_state *state,
- unsigned rt);
+pan_blend_constant_mask(const struct pan_blend_equation eq);
+
+/* Fixed-function blending only supports a single constant, so if multiple bits
+ * are set in constant_mask, the constants must match. Therefore we may pick
+ * just the first constant. */
-float
-pan_blend_get_constant(const struct panfrost_device *dev,
- const struct pan_blend_state *state,
- unsigned rt);
+static inline float
+pan_blend_get_constant(unsigned mask, float *constants)
+{
+ return mask ? constants[ffs(mask) - 1] : 0.0;
+}
void
pan_blend_to_fixed_function_equation(const struct panfrost_device *dev,