v3d: Implement noperspective varyings on V3D 4.x.
authorEric Anholt <eric@anholt.net>
Fri, 6 Jul 2018 22:48:46 +0000 (15:48 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 9 Jul 2018 18:48:32 +0000 (11:48 -0700)
Fixes a bunch of piglit interpolation tests, and reduces my concern about
some MSAA blit shaders with noperspective varyings.

src/broadcom/cle/v3d_packet_v33.xml
src/broadcom/compiler/nir_to_vir.c
src/broadcom/compiler/v3d_compiler.h
src/broadcom/compiler/vir.c
src/gallium/drivers/v3d/v3d_context.h
src/gallium/drivers/v3d/v3d_program.c
src/gallium/drivers/v3d/v3dx_emit.c

index f93b824..eef29da 100644 (file)
   <packet code="100" name="Non-perspective Flags" min_ver="41">
     <field name="Non-perspective Flags for varyings V0*24" size="24" start="8" type="uint"/>
     <field name="Action for Non-perspective Flags of higher numbered varyings" size="2" start="6" type="Varying Flags Action"/>
-    <field name="Action for Non-perspectivey Flags of lower numbered varyings" size="2" start="4" type="Varying Flags Action"/>
+    <field name="Action for Non-perspective Flags of lower numbered varyings" size="2" start="4" type="Varying Flags Action"/>
     <field name="Varying offset V0" size="4" start="0" type="uint"/>
   </packet>
 
index 89e4bc9..426b41e 100644 (file)
@@ -443,9 +443,7 @@ emit_fragment_varying(struct v3d_compile *c, nir_variable *var,
                         return vir_FADD(c, vir_FMUL(c, vary, c->payload_w), r5);
                 }
         case INTERP_MODE_NOPERSPECTIVE:
-                /* C appears after the mov from the varying.
-                   XXX: improve ldvary setup.
-                */
+                BITSET_SET(c->noperspective_flags, i);
                 return vir_FADD(c, vir_MOV(c, vary), r5);
         case INTERP_MODE_FLAT:
                 BITSET_SET(c->flat_shade_flags, i);
index 24af18e..f3e3875 100644 (file)
@@ -476,6 +476,8 @@ struct v3d_compile {
          */
         uint32_t flat_shade_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
 
+        uint32_t noperspective_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
+
         uint32_t centroid_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
 
         bool uses_center_w;
@@ -659,6 +661,8 @@ struct v3d_fs_prog_data {
          */
         uint32_t flat_shade_flags[((V3D_MAX_FS_INPUTS - 1) / 24) + 1];
 
+        uint32_t noperspective_flags[((V3D_MAX_FS_INPUTS - 1) / 24) + 1];
+
         uint32_t centroid_flags[((V3D_MAX_FS_INPUTS - 1) / 24) + 1];
 
         bool writes_z;
index 2754924..ee0f329 100644 (file)
@@ -759,6 +759,9 @@ v3d_set_fs_prog_data_inputs(struct v3d_compile *c,
                 if (BITSET_TEST(c->flat_shade_flags, i))
                         prog_data->flat_shade_flags[i / 24] |= 1 << (i % 24);
 
+                if (BITSET_TEST(c->noperspective_flags, i))
+                        prog_data->noperspective_flags[i / 24] |= 1 << (i % 24);
+
                 if (BITSET_TEST(c->centroid_flags, i))
                         prog_data->centroid_flags[i / 24] |= 1 << (i % 24);
         }
index dea9f9f..5822ca9 100644 (file)
@@ -81,6 +81,7 @@ void v3d_job_add_bo(struct v3d_job *job, struct v3d_bo *bo);
 #define VC5_DIRTY_STREAMOUT     (1 << 27)
 #define VC5_DIRTY_OQ            (1 << 28)
 #define VC5_DIRTY_CENTROID_FLAGS (1 << 29)
+#define VC5_DIRTY_NOPERSPECTIVE_FLAGS (1 << 30)
 
 #define VC5_MAX_FS_INPUTS 64
 
index 93228b5..8555458 100644 (file)
@@ -485,6 +485,11 @@ v3d_update_compiled_fs(struct v3d_context *v3d, uint8_t prim_mode)
                         v3d->dirty |= VC5_DIRTY_FLAT_SHADE_FLAGS;
                 }
 
+                if (v3d->prog.fs->prog_data.fs->noperspective_flags !=
+                    old_fs->prog_data.fs->noperspective_flags) {
+                        v3d->dirty |= VC5_DIRTY_NOPERSPECTIVE_FLAGS;
+                }
+
                 if (v3d->prog.fs->prog_data.fs->centroid_flags !=
                     old_fs->prog_data.fs->centroid_flags) {
                         v3d->dirty |= VC5_DIRTY_CENTROID_FLAGS;
index 09965f6..9c97bb6 100644 (file)
@@ -328,6 +328,23 @@ emit_flat_shade_flags(struct v3d_job *job,
 
 #if V3D_VERSION >= 40
 static void
+emit_noperspective_flags(struct v3d_job *job,
+                         int varying_offset,
+                         uint32_t varyings,
+                         enum V3DX(Varying_Flags_Action) lower,
+                         enum V3DX(Varying_Flags_Action) higher)
+{
+        cl_emit(&job->bcl, NON_PERSPECTIVE_FLAGS, flags) {
+                flags.varying_offset_v0 = varying_offset;
+                flags.non_perspective_flags_for_varyings_v024 = varyings;
+                flags.action_for_non_perspective_flags_of_lower_numbered_varyings =
+                        lower;
+                flags.action_for_non_perspective_flags_of_higher_numbered_varyings =
+                        higher;
+        }
+}
+
+static void
 emit_centroid_flags(struct v3d_job *job,
                     int varying_offset,
                     uint32_t varyings,
@@ -648,6 +665,14 @@ v3dX(emit_state)(struct pipe_context *pctx)
         }
 
 #if V3D_VERSION >= 40
+        if (v3d->dirty & VC5_DIRTY_NOPERSPECTIVE_FLAGS) {
+                if (!emit_varying_flags(job,
+                                        v3d->prog.fs->prog_data.fs->noperspective_flags,
+                                        emit_noperspective_flags)) {
+                        cl_emit(&job->bcl, ZERO_ALL_NON_PERSPECTIVE_FLAGS, flags);
+                }
+        }
+
         if (v3d->dirty & VC5_DIRTY_CENTROID_FLAGS) {
                 if (!emit_varying_flags(job,
                                         v3d->prog.fs->prog_data.fs->centroid_flags,