broadcom/vc5: Implement GFXH-1684 workaround.
authorEric Anholt <eric@anholt.net>
Sat, 6 Jan 2018 01:23:13 +0000 (17:23 -0800)
committerEric Anholt <eric@anholt.net>
Sat, 13 Jan 2018 05:55:15 +0000 (21:55 -0800)
Apparently the VPM writes need to be flushed out before we end the shader.

src/broadcom/compiler/nir_to_vir.c
src/broadcom/compiler/qpu_schedule.c
src/broadcom/compiler/v3d_compiler.h
src/broadcom/compiler/vir.c

index 87ce06a..1882c5a 100644 (file)
@@ -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
index cab117b..dff8438 100644 (file)
@@ -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;
index 72641bb..e17a108 100644 (file)
@@ -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)
 
index 80d11aa..da4ece2 100644 (file)
@@ -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;