i965: interpolate colors with perspective correction by default
authorBrian Paul <brianp@vmware.com>
Fri, 12 Jun 2009 22:21:20 +0000 (16:21 -0600)
committerBrian Paul <brianp@vmware.com>
Fri, 12 Jun 2009 22:21:20 +0000 (16:21 -0600)
...rather than with linear interpolation.  Modern hardware should use
perspective-corrected interpolation for colors (as for texcoords).
glHint(GL_PERSPECTIVE_CORRECTION_HINT, mode) can be used to get
linear interpolation if mode = GL_FASTEST.

src/mesa/drivers/dri/i965/brw_sf.c
src/mesa/drivers/dri/i965/brw_sf.h
src/mesa/drivers/dri/i965/brw_sf_emit.c
src/mesa/drivers/dri/i965/brw_wm.c
src/mesa/drivers/dri/i965/brw_wm.h
src/mesa/drivers/dri/i965/brw_wm_fp.c

index c3c8597..e1c2c77 100644 (file)
@@ -166,6 +166,9 @@ static void upload_sf_prog(struct brw_context *brw)
    key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT);
    key.do_twoside_color = (ctx->Light.Enabled && ctx->Light.Model.TwoSide);
 
+   /* _NEW_HINT */
+   key.linear_color = (ctx->Hint.PerspectiveCorrection == GL_FASTEST);
+
    /* _NEW_POLYGON */
    if (key.do_twoside_color) {
       /* If we're rendering to a FBO, we have to invert the polygon
@@ -188,7 +191,7 @@ static void upload_sf_prog(struct brw_context *brw)
 
 const struct brw_tracked_state brw_sf_prog = {
    .dirty = {
-      .mesa  = (_NEW_LIGHT|_NEW_POLYGON|_NEW_POINT),
+      .mesa  = (_NEW_HINT | _NEW_LIGHT | _NEW_POLYGON | _NEW_POINT),
       .brw   = (BRW_NEW_REDUCED_PRIMITIVE),
       .cache = CACHE_NEW_VS_PROG
    },
index 1c0fb70..6426b6d 100644 (file)
@@ -51,7 +51,8 @@ struct brw_sf_prog_key {
    GLuint do_flat_shading:1;
    GLuint frontface_ccw:1;
    GLuint do_point_sprite:1;
-   GLuint pad:10;
+   GLuint linear_color:1;  /**< linear interp vs. perspective interp */
+   GLuint pad:25;
    GLenum SpriteOrigin;
 };
 
index 862835f..2f63610 100644 (file)
@@ -295,9 +295,6 @@ static void invert_det( struct brw_sf_compile *c)
 
 }
 
-#define NON_PERPECTIVE_ATTRS  (FRAG_BIT_WPOS | \
-                               FRAG_BIT_COL0 | \
-                              FRAG_BIT_COL1)
 
 static GLboolean calculate_masks( struct brw_sf_compile *c,
                                  GLuint reg,
@@ -306,9 +303,16 @@ static GLboolean calculate_masks( struct brw_sf_compile *c,
                                  GLushort *pc_linear)
 {
    GLboolean is_last_attr = (reg == c->nr_setup_regs - 1);
-   GLuint persp_mask = c->key.attrs & ~NON_PERPECTIVE_ATTRS;
+   GLuint persp_mask;
    GLuint linear_mask;
 
+   if (c->key.do_flat_shading || c->key.linear_color)
+      persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS |
+                                    FRAG_BIT_COL0 |
+                                    FRAG_BIT_COL1);
+   else
+      persp_mask = c->key.attrs & ~(FRAG_BIT_WPOS);
+
    if (c->key.do_flat_shading)
       linear_mask = c->key.attrs & ~(FRAG_BIT_COL0|FRAG_BIT_COL1);
    else
index 3e476fd..34c8ced 100644 (file)
@@ -272,6 +272,9 @@ static void brw_wm_populate_key( struct brw_context *brw,
    /* _NEW_LIGHT */
    key->flat_shade = (ctx->Light.ShadeModel == GL_FLAT);
 
+   /* _NEW_HINT */
+   key->linear_color = (ctx->Hint.PerspectiveCorrection == GL_FASTEST);
+
    /* _NEW_TEXTURE */
    for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
       const struct gl_texture_unit *unit = &ctx->Texture.Unit[i];
@@ -351,6 +354,7 @@ const struct brw_tracked_state brw_wm_prog = {
    .dirty = {
       .mesa  = (_NEW_COLOR |
                _NEW_DEPTH |
+                _NEW_HINT |
                _NEW_STENCIL |
                _NEW_POLYGON |
                _NEW_LINE |
index fb15c03..ab0ab8b 100644 (file)
@@ -63,6 +63,7 @@ struct brw_wm_prog_key {
    GLuint computes_depth:1;    /* could be derived from program string */
    GLuint source_depth_to_render_target:1;
    GLuint flat_shade:1;
+   GLuint linear_color:1;  /**< linear interpolation vs perspective interp */
    GLuint runtime_check_aads_emit:1;
    
    GLuint projtex_mask:16;
index 1798d84..5b302cc 100644 (file)
@@ -354,13 +354,25 @@ static void emit_interp( struct brw_wm_compile *c,
                 src_undef());
       }
       else {
-        emit_op(c,
-                WM_LINTERP,
-                dst,
-                0,
-                interp,
-                deltas,
-                src_undef());
+         if (c->key.linear_color) {
+            emit_op(c,
+                    WM_LINTERP,
+                    dst,
+                    0,
+                    interp,
+                    deltas,
+                    src_undef());
+         }
+         else {
+            /* perspective-corrected color interpolation */
+            emit_op(c,
+                    WM_PINTERP,
+                    dst,
+                    0,
+                    interp,
+                    deltas,
+                    get_pixel_w(c));
+         }
       }
       break;
    case FRAG_ATTRIB_FOGC: