summaryrefslogtreecommitdiffstats
path: root/src/broadcom
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2018-01-05 17:23:13 -0800
committerEric Anholt <[email protected]>2018-01-12 21:55:15 -0800
commita075bb67262bd48c882f0c8fcc18e0e642c76b86 (patch)
tree750289dd86786b3e55633c505c4bcf9c00324bc8 /src/broadcom
parent57965755e2c8089e5b52897fa86305e595f6792f (diff)
broadcom/vc5: Implement GFXH-1684 workaround.
Apparently the VPM writes need to be flushed out before we end the shader.
Diffstat (limited to 'src/broadcom')
-rw-r--r--src/broadcom/compiler/nir_to_vir.c5
-rw-r--r--src/broadcom/compiler/qpu_schedule.c4
-rw-r--r--src/broadcom/compiler/v3d_compiler.h10
-rw-r--r--src/broadcom/compiler/vir.c1
4 files changed, 20 insertions, 0 deletions
diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c
index 87ce06a49cc..1882c5ace7e 100644
--- a/src/broadcom/compiler/nir_to_vir.c
+++ b/src/broadcom/compiler/nir_to_vir.c
@@ -1362,6 +1362,11 @@ emit_vert_end(struct v3d_compile *c)
vir_VPM_WRITE(c, vir_uniform_f(c, 0.0),
&vpm_index);
}
+
+ /* GFXH-1684: VPM writes need to be complete by the end of the shader.
+ */
+ if (c->devinfo->ver >= 40 && c->devinfo->ver <= 41)
+ vir_VPMWT(c);
}
void
diff --git a/src/broadcom/compiler/qpu_schedule.c b/src/broadcom/compiler/qpu_schedule.c
index cab117b523e..dff8438d94e 100644
--- a/src/broadcom/compiler/qpu_schedule.c
+++ b/src/broadcom/compiler/qpu_schedule.c
@@ -310,6 +310,10 @@ calculate_deps(struct schedule_state *state, struct schedule_node *n)
add_write_dep(state, &state->last_vpm, n);
break;
+ case V3D_QPU_A_VPMWT:
+ add_read_dep(state, state->last_vpm, n);
+ break;
+
case V3D_QPU_A_MSF:
add_read_dep(state, state->last_tlb, n);
break;
diff --git a/src/broadcom/compiler/v3d_compiler.h b/src/broadcom/compiler/v3d_compiler.h
index 72641bb7be3..e17a108233f 100644
--- a/src/broadcom/compiler/v3d_compiler.h
+++ b/src/broadcom/compiler/v3d_compiler.h
@@ -744,6 +744,14 @@ vir_##name##_dest(struct v3d_compile *c, struct qreg dest, \
return vir_emit_nondef(c, vir_inst(op, dest, a, b)); \
}
+#define VIR_NODST_0(name, vir_inst, op) \
+static inline struct qinst * \
+vir_##name(struct v3d_compile *c) \
+{ \
+ return vir_emit_nondef(c, vir_inst(op, c->undef, \
+ c->undef, c->undef)); \
+}
+
#define VIR_NODST_1(name, vir_inst, op) \
static inline struct qinst * \
vir_##name(struct v3d_compile *c, struct qreg a) \
@@ -770,6 +778,7 @@ vir_##name(struct v3d_compile *c, struct qreg a, struct qreg b) \
#define VIR_M_NODST_2(name) VIR_NODST_2(name, vir_mul_inst, V3D_QPU_M_##name)
#define VIR_A_NODST_1(name) VIR_NODST_1(name, vir_add_inst, V3D_QPU_A_##name)
#define VIR_M_NODST_1(name) VIR_NODST_1(name, vir_mul_inst, V3D_QPU_M_##name)
+#define VIR_A_NODST_0(name) VIR_NODST_0(name, vir_add_inst, V3D_QPU_A_##name)
VIR_A_ALU2(FADD)
VIR_A_ALU2(VFPACK)
@@ -812,6 +821,7 @@ VIR_A_ALU0(YCD)
VIR_A_ALU0(MSF)
VIR_A_ALU0(REVF)
VIR_A_NODST_1(VPMSETUP)
+VIR_A_NODST_0(VPMWT)
VIR_A_ALU2(FCMP)
VIR_A_ALU2(VFMAX)
diff --git a/src/broadcom/compiler/vir.c b/src/broadcom/compiler/vir.c
index 80d11aaf7f6..da4ece2cffe 100644
--- a/src/broadcom/compiler/vir.c
+++ b/src/broadcom/compiler/vir.c
@@ -95,6 +95,7 @@ vir_has_side_effects(struct v3d_compile *c, struct qinst *inst)
case V3D_QPU_A_STVPMV:
case V3D_QPU_A_STVPMD:
case V3D_QPU_A_STVPMP:
+ case V3D_QPU_A_VPMWT:
return true;
default:
break;