v3d: Use stvpmd for non-uniform offsets in GS

The offset for the VPM write for storing outputs from the geometry
shader isn’t necessarily uniform across all the lanes. This can happen
if some of the lanes don’t emit some of the vertices. In that case the
offset for the subsequent vertices will be different in each lane. In
that case we need to use the stvpmd instruction instead of stvpmv
because it will scatter the values out.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3150

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5621>
This commit is contained in:
Neil Roberts 2020-06-24 00:16:43 +02:00
parent dab8a9169c
commit 3b1c511b09
1 changed files with 12 additions and 1 deletions

View File

@ -2027,7 +2027,18 @@ emit_store_output_gs(struct v3d_compile *c, nir_intrinsic_instr *instr)
V3D_QPU_PF_PUSHZ);
}
vir_VPM_WRITE_indirect(c, ntq_get_src(c, instr->src[0], 0), offset);
struct qreg val = ntq_get_src(c, instr->src[0], 0);
/* The offset isnt necessarily dynamically uniform for a geometry
* shader. This can happen if the shader sometimes doesnt emit one of
* the vertices. In that case subsequent vertices will be written to
* different offsets in the VPM and we need to use the scatter write
* instruction to have a different offset for each lane.
*/
if (nir_src_is_dynamically_uniform(instr->src[1]))
vir_VPM_WRITE_indirect(c, val, offset);
else
vir_STVPMD(c, offset, val);
if (vir_in_nonuniform_control_flow(c)) {
struct qinst *last_inst =