diff --git a/src/gallium/drivers/panfrost/pan_blend_cso.c b/src/gallium/drivers/panfrost/pan_blend_cso.c index c18a3a2a9b8..e7c4bd87d2a 100644 --- a/src/gallium/drivers/panfrost/pan_blend_cso.c +++ b/src/gallium/drivers/panfrost/pan_blend_cso.c @@ -145,9 +145,12 @@ panfrost_get_blend_for_context(struct panfrost_context *ctx, unsigned rti, struc /* 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, }; diff --git a/src/panfrost/lib/pan_blend.c b/src/panfrost/lib/pan_blend.c index 59bd0d57c07..2eabfc10513 100644 --- a/src/panfrost/lib/pan_blend.c +++ b/src/panfrost/lib/pan_blend.c @@ -78,15 +78,12 @@ blend_factor_constant_mask(enum blend_factor factor) } 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 @@ -94,7 +91,7 @@ can_blend_constant(const struct panfrost_device *dev, 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; @@ -107,33 +104,16 @@ can_blend_constant(const struct panfrost_device *dev, 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, @@ -642,7 +622,7 @@ pan_blend_get_shader_locked(const struct panfrost_device *dev, .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, diff --git a/src/panfrost/lib/pan_blend.h b/src/panfrost/lib/pan_blend.h index cad8c32611f..bcba3e87a91 100644 --- a/src/panfrost/lib/pan_blend.h +++ b/src/panfrost/lib/pan_blend.h @@ -108,13 +108,17 @@ bool 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); -float -pan_blend_get_constant(const struct panfrost_device *dev, - const struct pan_blend_state *state, - unsigned rt); +/* 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. */ + +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,