In order to keep early-Z from writing early in a discard shader, you need
to set the "modifies Z" bit in the shader state (which the new
prog_data.discards will indicate). Then, in the shader we do a TLB write
to make Z passthrough happen (the QPU result is ignored, so we use a NULL
source).
TLB_TYPE_DEPTH |
TLB_DEPTH_TYPE_PER_PIXEL |
0xffffff00);
+ } else if (c->s->info.fs.uses_discard) {
+ struct qinst *inst = vir_MOV_dest(c,
+ vir_reg(QFILE_TLBU, 0),
+ vir_reg(QFILE_NULL, 0));
+ vir_set_cond(inst, discard_cond);
+
+ inst->src[vir_get_implicit_uniform_src(inst)] =
+ vir_uniform_ui(c,
+ TLB_TYPE_DEPTH |
+ TLB_DEPTH_TYPE_INVARIANT |
+ 0xffffff00);
}
/* XXX: Performance improvement: Merge Z write and color writes TLB
BITSET_WORD flat_shade_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
bool writes_z;
+ bool discard;
};
/* Special nir_load_input intrinsic index for loading the current TLB
v3d_set_prog_data(c, &prog_data->base);
v3d_set_fs_prog_data_inputs(c, prog_data);
- if (c->s->info.outputs_written & (1 << FRAG_RESULT_DEPTH))
- prog_data->writes_z = true;
+ prog_data->writes_z = (c->s->info.outputs_written &
+ (1 << FRAG_RESULT_DEPTH));
+ prog_data->discard = c->s->info.fs.uses_discard;
return v3d_return_qpu_insts(c, final_assembly_size);
}