aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Roberts <nroberts@igalia.com>2020-06-24 00:16:43 +0200
committerNeil Roberts <nroberts@igalia.com>2020-06-26 09:36:15 +0200
commit3b1c511b099e88d1b153de784e3bf7e951a6288f (patch)
tree73a3bd459aa9eaf405ac4c2bfe635bf9fab916fb
parentdab8a9169c197a98df23f2bd0eb5e18cdeb71c99 (diff)
downloadexternal_mesa3d-3b1c511b099e88d1b153de784e3bf7e951a6288f.tar.gz
external_mesa3d-3b1c511b099e88d1b153de784e3bf7e951a6288f.tar.bz2
external_mesa3d-3b1c511b099e88d1b153de784e3bf7e951a6288f.zip
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>
-rw-r--r--src/broadcom/compiler/nir_to_vir.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c
index 1086e288a60..e7b8cf9cb3a 100644
--- a/src/broadcom/compiler/nir_to_vir.c
+++ b/src/broadcom/compiler/nir_to_vir.c
@@ -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 isn’t necessarily dynamically uniform for a geometry
+ * shader. This can happen if the shader sometimes doesn’t 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 =