((A6XX_MAX_RENDER_TARGETS * 4) + 6) * 4);
so->stateobj = ring;
- for (unsigned i = 0; i < A6XX_MAX_RENDER_TARGETS; i++) {
+ for (unsigned i = 0; i <= cso->max_rt; i++) {
const struct pipe_rt_blend_state *rt;
if (cso->independent_blend_enable)
OUT_REG(ring, A6XX_RB_BLEND_CNTL(
.enable_blend = mrt_blend,
.alpha_to_coverage = cso->alpha_to_coverage,
+ .alpha_to_one = cso->alpha_to_one,
.independent_blend = cso->independent_blend_enable,
.sample_mask = sample_mask
));
const struct pipe_blend_state *cso)
{
struct fd6_blend_stateobj *so;
- bool reads_dest = false;
-
- if (cso->logicop_enable) {
- reads_dest = util_logicop_reads_dest(cso->logicop_func);
- }
so = rzalloc_size(NULL, sizeof(*so));
if (!so)
so->base = *cso;
so->ctx = fd_context(pctx);
- so->lrz_write = true; /* unless blend enabled for any MRT */
- unsigned nr = cso->independent_blend_enable ? A6XX_MAX_RENDER_TARGETS : 1;
- for (unsigned i = 0; i < nr; i++) {
+ if (cso->logicop_enable) {
+ so->reads_dest |= util_logicop_reads_dest(cso->logicop_func);
+ }
+
+ unsigned nr = cso->independent_blend_enable ? cso->max_rt : 0;
+ for (unsigned i = 0; i <= nr; i++) {
const struct pipe_rt_blend_state *rt = &cso->rt[i];
- if (rt->blend_enable) {
- so->lrz_write = false;
+ so->reads_dest |= rt->blend_enable;
+
+ /* From the PoV of LRZ, having masked color channels is
+ * the same as having blend enabled, in that the draw will
+ * care about the fragments from an earlier draw.
+ *
+ * NOTE we actually don't care about masked color channels
+ * that don't actually exist in the render target, but we
+ * don't know the render target format here to determine
+ * that. It is probably not worth worrying about, but if
+ * we find a game/benchmark that goes out of it's way to
+ * mask off non-existent channels, we should fixup the
+ * pipe_blend_state to give us more info.
+ */
+ if (rt->blend_enable || (rt->colormask != 0xf)) {
+ so->reads_dest = true;
}
}
- if (reads_dest) {
- so->lrz_write = false;
- }
-
util_dynarray_init(&so->variants, so);
return so;