broadcom/vc5: Use SETMSF to handle discards.
authorEric Anholt <eric@anholt.net>
Fri, 20 Oct 2017 21:00:11 +0000 (14:00 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 20 Oct 2017 22:59:41 +0000 (15:59 -0700)
A bit of spec text suggested that (like vc4) condition codes should be
used for discards, and the simulator was fine with it, but the 7268
disagrees and you have to use SETMSF instead or the color comes through.
Fixes glsl-fs-discard-01 and many of the interpolation-with-clipping
tests.

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

index 167b80bac932a2508de601ab9d2866caee2e7246..3b032b704ea8ab96ccd0ea5c0192eb2ba1fb3d22 100644 (file)
@@ -1030,12 +1030,6 @@ ntq_emit_alu(struct v3d_compile *c, nir_alu_instr *instr)
 static void
 emit_frag_end(struct v3d_compile *c)
 {
-        uint32_t discard_cond = V3D_QPU_COND_NONE;
-        if (c->s->info.fs.uses_discard) {
-                vir_PF(c, vir_MOV(c, c->discard), V3D_QPU_PF_PUSHZ);
-                discard_cond = V3D_QPU_COND_IFA;
-        }
-
         /* XXX
         if (c->output_sample_mask_index != -1) {
                 vir_MS_MASK(c, c->outputs[c->output_sample_mask_index]);
@@ -1046,7 +1040,6 @@ emit_frag_end(struct v3d_compile *c)
                 struct qinst *inst = vir_MOV_dest(c,
                                                   vir_reg(QFILE_TLBU, 0),
                                                   c->outputs[c->output_position_index]);
-                vir_set_cond(inst, discard_cond);
 
                 inst->src[vir_get_implicit_uniform_src(inst)] =
                         vir_uniform_ui(c,
@@ -1057,7 +1050,6 @@ emit_frag_end(struct v3d_compile *c)
                 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,
@@ -1092,14 +1084,12 @@ emit_frag_end(struct v3d_compile *c)
                                  TLB_VEC_SIZE_MINUS_1_SHIFT);
 
                         inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), color[0]);
-                        vir_set_cond(inst, discard_cond);
                         inst->src[vir_get_implicit_uniform_src(inst)] =
                                 vir_uniform_ui(c, conf);
 
                         for (int i = 1; i < num_components; i++) {
                                 inst = vir_MOV_dest(c, vir_reg(QFILE_TLB, 0),
                                                     color[i]);
-                                vir_set_cond(inst, discard_cond);
                         }
                         break;
 
@@ -1129,14 +1119,12 @@ emit_frag_end(struct v3d_compile *c)
 
                         if (c->fs_key->f32_color_rb & (1 << rt)) {
                                 inst = vir_MOV_dest(c, vir_reg(QFILE_TLBU, 0), color[0]);
-                                vir_set_cond(inst, discard_cond);
                                 inst->src[vir_get_implicit_uniform_src(inst)] =
                                         vir_uniform_ui(c, conf);
 
                                 for (int i = 1; i < num_components; i++) {
                                         inst = vir_MOV_dest(c, vir_reg(QFILE_TLB, 0),
                                                             color[i]);
-                                        vir_set_cond(inst, discard_cond);
                                 }
                         } else {
                                 inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), r, g);
@@ -1145,10 +1133,8 @@ emit_frag_end(struct v3d_compile *c)
                                         inst->src[vir_get_implicit_uniform_src(inst)] =
                                                 vir_uniform_ui(c, conf);
                                 }
-                                vir_set_cond(inst, discard_cond);
 
                                 inst = vir_VFPACK_dest(c, vir_reg(QFILE_TLB, 0), b, a);
-                                vir_set_cond(inst, discard_cond);
                         }
                         break;
                 }
@@ -1665,10 +1651,12 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr)
         case nir_intrinsic_discard:
                 if (c->execute.file != QFILE_NULL) {
                         vir_PF(c, c->execute, V3D_QPU_PF_PUSHZ);
-                        vir_MOV_cond(c, V3D_QPU_COND_IFA, c->discard,
-                                     vir_uniform_ui(c, ~0));
+                        vir_set_cond(vir_SETMSF_dest(c, vir_reg(QFILE_NULL, 0),
+                                                     vir_uniform_ui(c, 0)),
+                                V3D_QPU_COND_IFA);
                 } else {
-                        vir_MOV_dest(c, c->discard, vir_uniform_ui(c, ~0));
+                        vir_SETMSF_dest(c, vir_reg(QFILE_NULL, 0),
+                                        vir_uniform_ui(c, 0));
                 }
                 break;
 
@@ -1683,9 +1671,14 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr)
                          */
                         vir_PF(c, vir_AND(c, c->execute, vir_NOT(c, cond)),
                                V3D_QPU_PF_PUSHZ);
-                        vir_MOV_cond(c, V3D_QPU_COND_IFA, c->discard, cond);
+                        vir_set_cond(vir_SETMSF_dest(c, vir_reg(QFILE_NULL, 0),
+                                                     vir_uniform_ui(c, 0)),
+                                     V3D_QPU_COND_IFA);
                 } else {
-                        vir_OR_dest(c, c->discard, c->discard, cond);
+                        vir_PF(c, cond, V3D_QPU_PF_PUSHZ);
+                        vir_set_cond(vir_SETMSF_dest(c, vir_reg(QFILE_NULL, 0),
+                                                     vir_uniform_ui(c, 0)),
+                                     V3D_QPU_COND_IFNA);
                 }
 
                 break;
@@ -1953,9 +1946,6 @@ nir_to_vir(struct v3d_compile *c)
                 c->payload_w_centroid = vir_MOV(c, vir_reg(QFILE_REG, 1));
                 c->payload_z = vir_MOV(c, vir_reg(QFILE_REG, 2));
 
-                if (c->s->info.fs.uses_discard)
-                        c->discard = vir_MOV(c, vir_uniform_ui(c, 0));
-
                 if (c->fs_key->is_points) {
                         c->point_x = emit_fragment_varying(c, NULL, 0);
                         c->point_y = emit_fragment_varying(c, NULL, 0);
index 08db4fb0e2bb7df8edc86c10e83d356d704c7c63..021c88f7b937cdfd9276d83c2087852e0804e4a5 100644 (file)
@@ -458,9 +458,6 @@ struct v3d_compile {
         /* Fragment shader payload regs. */
         struct qreg payload_w, payload_w_centroid, payload_z;
 
-        /** boolean (~0 -> true) if the fragment has been discarded. */
-        struct qreg discard;
-
         uint8_t vattr_sizes[V3D_MAX_VS_INPUTS];
         uint32_t num_vpm_writes;