i965/msaa: Add backend support for centroid interpolation.
authorPaul Berry <stereotype441@gmail.com>
Mon, 18 Jun 2012 20:52:02 +0000 (13:52 -0700)
committerPaul Berry <stereotype441@gmail.com>
Mon, 25 Jun 2012 18:03:26 +0000 (11:03 -0700)
This patch causes the fragment shader to be configured correctly (and
the correct code to be generated) for centroid interpolation.  This
required two changes: brw_compute_barycentric_interp_modes() needs to
determine when centroid barycentric coordinates need to be included in
the pixel shader thread payload, and
fs_visitor::emit_general_interpolation() needs to interpolate using
the correct set of barycentric coordinates.

Fixes piglit tests "EXT_framebuffer_multisample/interpolation {2,4}
centroid-edges" on i965.

Reviewed-by: Eric Anholt <eric@anholt.net>
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs.h
src/mesa/drivers/dri/i965/brw_wm.c

index c3f851e615c682b148b0bd66b28cb33203d4795d..6cef08a043aa6f413389c6272b23a7c739a602e5 100644 (file)
@@ -421,13 +421,21 @@ fs_visitor::emit_fragcoord_interpolation(ir_variable *ir)
 
 fs_inst *
 fs_visitor::emit_linterp(const fs_reg &attr, const fs_reg &interp,
-                         glsl_interp_qualifier interpolation_mode)
+                         glsl_interp_qualifier interpolation_mode,
+                         bool is_centroid)
 {
    brw_wm_barycentric_interp_mode barycoord_mode;
-   if (interpolation_mode == INTERP_QUALIFIER_SMOOTH)
-      barycoord_mode = BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
-   else
-      barycoord_mode = BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
+   if (is_centroid) {
+      if (interpolation_mode == INTERP_QUALIFIER_SMOOTH)
+         barycoord_mode = BRW_WM_PERSPECTIVE_CENTROID_BARYCENTRIC;
+      else
+         barycoord_mode = BRW_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC;
+   } else {
+      if (interpolation_mode == INTERP_QUALIFIER_SMOOTH)
+         barycoord_mode = BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
+      else
+         barycoord_mode = BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
+   }
    return emit(FS_OPCODE_LINTERP, attr,
                this->delta_x[barycoord_mode],
                this->delta_y[barycoord_mode], interp);
@@ -496,7 +504,8 @@ fs_visitor::emit_general_interpolation(ir_variable *ir)
                  emit(BRW_OPCODE_MOV, attr, fs_reg(1.0f));
               } else {
                  struct brw_reg interp = interp_reg(location, k);
-                  emit_linterp(attr, fs_reg(interp), interpolation_mode);
+                  emit_linterp(attr, fs_reg(interp), interpolation_mode,
+                               ir->centroid);
                  if (intel->gen < 6) {
                     emit(BRW_OPCODE_MUL, attr, attr, this->pixel_w);
                  }
index 3e62d12d2afaa4c1ef18e415dd8ec708b0473637..18d0a9cefa3150b505f00b5eaaaeef0baab1cb52 100644 (file)
@@ -543,7 +543,8 @@ public:
    void emit_dummy_fs();
    fs_reg *emit_fragcoord_interpolation(ir_variable *ir);
    fs_inst *emit_linterp(const fs_reg &attr, const fs_reg &interp,
-                         glsl_interp_qualifier interpolation_mode);
+                         glsl_interp_qualifier interpolation_mode,
+                         bool is_centroid);
    fs_reg *emit_frontfacing_interpolation(ir_variable *ir);
    fs_reg *emit_general_interpolation(ir_variable *ir);
    void emit_interpolation_setup_gen4();
index 300e3bb1187c02ddc0019935cc8c5a15e3ba881e..4a7225c7228d3f930cf7740b5250e8198a96b60a 100644 (file)
@@ -143,6 +143,7 @@ brw_compute_barycentric_interp_modes(bool shade_model_flat,
    for (attr = 0; attr < FRAG_ATTRIB_MAX; ++attr) {
       enum glsl_interp_qualifier interp_qualifier =
          fprog->InterpQualifier[attr];
+      bool is_centroid = fprog->IsCentroid & BITFIELD64_BIT(attr);
       bool is_gl_Color = attr == FRAG_ATTRIB_COL0 || attr == FRAG_ATTRIB_COL1;
 
       /* Ignore unused inputs. */
@@ -154,13 +155,23 @@ brw_compute_barycentric_interp_modes(bool shade_model_flat,
          continue;
 
       if (interp_qualifier == INTERP_QUALIFIER_NOPERSPECTIVE) {
-         barycentric_interp_modes |=
-            1 << BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
+         if (is_centroid) {
+            barycentric_interp_modes |=
+               1 << BRW_WM_NONPERSPECTIVE_CENTROID_BARYCENTRIC;
+         } else {
+            barycentric_interp_modes |=
+               1 << BRW_WM_NONPERSPECTIVE_PIXEL_BARYCENTRIC;
+         }
       } else if (interp_qualifier == INTERP_QUALIFIER_SMOOTH ||
                  (!(shade_model_flat && is_gl_Color) &&
                   interp_qualifier == INTERP_QUALIFIER_NONE)) {
-         barycentric_interp_modes |=
-            1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
+         if (is_centroid) {
+            barycentric_interp_modes |=
+               1 << BRW_WM_PERSPECTIVE_CENTROID_BARYCENTRIC;
+         } else {
+            barycentric_interp_modes |=
+               1 << BRW_WM_PERSPECTIVE_PIXEL_BARYCENTRIC;
+         }
       }
    }