All of lore.kernel.org
 help / color / mirror / Atom feed
From: Olivier Galibert <galibert@pobox.com>
To: intel-gfx@lists.freedesktop.org, mesa-dev@lists.freedesktop.org
Cc: Olivier Galibert <galibert@pobox.com>
Subject: [PATCH 8/9] intel gen4-5: Make noperspective clipping work.
Date: Thu, 19 Jul 2012 22:00:23 +0200	[thread overview]
Message-ID: <1342728024-15055-9-git-send-email-galibert@pobox.com> (raw)
In-Reply-To: <1342728024-15055-1-git-send-email-galibert@pobox.com>

At this point all interpolation tests with fixed clipping work.

Signed-off-by: Olivier Galibert <galibert@pobox.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
---
 src/mesa/drivers/dri/i965/brw_clip.c      |    9 ++
 src/mesa/drivers/dri/i965/brw_clip.h      |    1 +
 src/mesa/drivers/dri/i965/brw_clip_util.c |  147 ++++++++++++++++++++++++++---
 3 files changed, 146 insertions(+), 11 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index 8512172..eca2844 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.c
+++ b/src/mesa/drivers/dri/i965/brw_clip.c
@@ -239,6 +239,15 @@ brw_upload_clip_prog(struct brw_context *brw)
          break;
       }
    }
+   key.has_noperspective_shading = 0;
+   for (i = 0; i < BRW_VERT_RESULT_MAX; i++) {
+      if (brw->interpolation_mode[i] == INTERP_QUALIFIER_NOPERSPECTIVE &&
+          brw->vs.prog_data->vue_map.slot_to_vert_result[i] != VERT_RESULT_HPOS) {
+         key.has_noperspective_shading = 1;
+         break;
+      }
+   }
+
    key.pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION);
 
    memcpy(key.interpolation_mode, brw->interpolation_mode, BRW_VERT_RESULT_MAX);
diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h
index 3ad2e13..66dd928 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.h
+++ b/src/mesa/drivers/dri/i965/brw_clip.h
@@ -47,6 +47,7 @@ struct brw_clip_prog_key {
    GLuint primitive:4;
    GLuint nr_userclip:4;
    GLuint has_flat_shading:1;
+   GLuint has_noperspective_shading:1;
    GLuint pv_first:1;
    GLuint do_unfilled:1;
    GLuint fill_cw:2;		/* includes cull information */
diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c
index 692573e..b06ad1d 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_util.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_util.c
@@ -129,6 +129,8 @@ static void brw_clip_project_vertex( struct brw_clip_compile *c,
 
 /* Interpolate between two vertices and put the result into a0.0.  
  * Increment a0.0 accordingly.
+ *
+ * Beware that dest_ptr can be equal to v0_ptr.
  */
 void brw_clip_interp_vertex( struct brw_clip_compile *c,
 			     struct brw_indirect dest_ptr,
@@ -138,7 +140,8 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
 			     bool force_edgeflag)
 {
    struct brw_compile *p = &c->func;
-   struct brw_reg tmp = get_tmp(c);
+   struct brw_context *brw = p->brw;
+   struct brw_reg t_nopersp, v0_ndc_copy;
    GLuint slot;
 
    /* Just copy the vertex header:
@@ -148,13 +151,130 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
     * back on Ironlake, so needn't change it
     */
    brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1);
-      
-   /* Iterate over each attribute (could be done in pairs?)
+
+   /*
+    * First handle the 3D and NDC positioning, in case we need
+    * noperspective interpolation.  Doing it early has no performance
+    * impact in any case.
+    */
+
+   /* Start by picking up the v0 NDC coordinates, because that vertex
+    * may be shared with the destination.
+    */
+   if (c->key.has_noperspective_shading) {
+      GLuint offset = brw_vert_result_to_offset(&c->vue_map,
+                                                BRW_VERT_RESULT_NDC);
+      v0_ndc_copy = get_tmp(c);
+      brw_MOV(p, v0_ndc_copy, deref_4f(v0_ptr, offset));
+   }      
+
+   /*
+    * Compute the new 3D position
+    *
+    * dest_hpos = v0_hpos * (1 - t0) + v1_hpos * t0
+    */
+   {
+      GLuint delta = brw_vert_result_to_offset(&c->vue_map, VERT_RESULT_HPOS);
+      struct brw_reg tmp = get_tmp(c);
+      brw_MUL(p, 
+              vec4(brw_null_reg()),
+              deref_4f(v1_ptr, delta),
+              t0);
+
+      brw_MAC(p,
+              tmp,	      
+              negate(deref_4f(v0_ptr, delta)),
+              t0);
+	      
+      brw_ADD(p,
+              deref_4f(dest_ptr, delta), 
+              deref_4f(v0_ptr, delta),
+              tmp);
+      release_tmp(c, tmp);
+   }
+
+   /* Then recreate the projected (NDC) coordinate in the new vertex
+    * header
+    */
+   brw_clip_project_vertex(c, dest_ptr);
+
+   /*
+    * If we have noperspective attributes, we now need to compute the
+    * screen-space t.
+    */
+   if (c->key.has_noperspective_shading) {
+      GLuint delta = brw_vert_result_to_offset(&c->vue_map, BRW_VERT_RESULT_NDC);
+      struct brw_reg tmp = get_tmp(c);
+      t_nopersp = get_tmp(c);
+
+      /* Build a register with coordinates from the second and new vertices
+       *
+       * t_nopersp = vec4(v1.xy, dest.xy)
+       */
+      brw_MOV(p, t_nopersp, deref_4f(v1_ptr, delta));
+      brw_MOV(p, tmp, deref_4f(dest_ptr, delta));
+      brw_set_access_mode(p, BRW_ALIGN_16);
+      brw_MOV(p,
+              brw_writemask(t_nopersp, WRITEMASK_ZW),
+              brw_swizzle(tmp, 0,1,0,1));
+
+      /* Subtract the coordinates of the first vertex
+       *
+       * t_nopersp = vec4(v1.xy, dest.xy) - v0.xyxy
+       */
+      brw_ADD(p, t_nopersp, t_nopersp, negate(brw_swizzle(v0_ndc_copy, 0,1,0,1)));
+
+      /* Add the absolute value of the X and Y deltas so that if the
+       * points aren't in the same place on the screen we get non-zero
+       * values to divide.
+       *
+       * After that we have vert1-vert0 in t_nopersp.x and vertnew-vert0 in t_nopersp.y.
+       *
+       * t_nopersp = vec2(|v1.x  -v0.x| + |v1.y  -v0.y|,
+       *                  |dest.x-v0.x| + |dest.y-v0.y|)
+       */
+      brw_ADD(p,
+              brw_writemask(t_nopersp, WRITEMASK_XY),
+              brw_abs(brw_swizzle(t_nopersp, 0,2,0,0)),
+              brw_abs(brw_swizzle(t_nopersp, 1,3,0,0)));
+      brw_set_access_mode(p, BRW_ALIGN_1);
+
+      /* If the points are in the same place (vert1-vert0 == 0), just
+       * substitute a value that will ensure that we don't divide by
+       * 0.
+       */
+      brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_EQ,
+              vec1(t_nopersp),
+              brw_imm_f(0));
+      brw_IF(p, BRW_EXECUTE_1);
+      brw_MOV(p, t_nopersp, brw_imm_vf4(VF_ONE, VF_ZERO, VF_ZERO, VF_ZERO));
+      brw_ENDIF(p);
+
+      /* Now compute t_nopersp = t_nopersp.y/t_nopersp.x and broadcast it */
+      brw_math_invert(p, get_element(t_nopersp, 0), get_element(t_nopersp, 0));
+      brw_MUL(p,
+              vec1(t_nopersp),
+              vec1(t_nopersp),
+              vec1(suboffset(t_nopersp, 1)));
+      brw_set_access_mode(p, BRW_ALIGN_16);
+      brw_MOV(p, t_nopersp, brw_swizzle(t_nopersp, 0,0,0,0));
+      brw_set_access_mode(p, BRW_ALIGN_1);
+
+      release_tmp(c, tmp);
+      release_tmp(c, v0_ndc_copy);
+   }
+
+   /* Now we can iterate over each attribute
+    * (could be done in pairs?)
     */
    for (slot = 0; slot < c->vue_map.num_slots; slot++) {
       int vert_result = c->vue_map.slot_to_vert_result[slot];
       GLuint delta = brw_vue_slot_to_offset(slot);
 
+      /* HPOS is already handled */
+      if(vert_result == VERT_RESULT_HPOS)
+         continue;
+
       if (vert_result == VERT_RESULT_EDGE) {
 	 if (force_edgeflag) 
 	    brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1));
@@ -174,20 +294,29 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
 	  *
 	  *        New = attr0 + t*attr1 - t*attr0
 	  */
+
+         struct brw_reg tmp = get_tmp(c);
+
+         struct brw_reg t =
+            brw->interpolation_mode[slot] == INTERP_QUALIFIER_NOPERSPECTIVE ?
+            t_nopersp : t0;
+
 	 brw_MUL(p, 
 		 vec4(brw_null_reg()),
 		 deref_4f(v1_ptr, delta),
-		 t0);
+		 t);
 
 	 brw_MAC(p, 
 		 tmp,	      
 		 negate(deref_4f(v0_ptr, delta)),
-		 t0); 
+		 t); 
 	      
 	 brw_ADD(p,
 		 deref_4f(dest_ptr, delta), 
 		 deref_4f(v0_ptr, delta),
 		 tmp);
+
+         release_tmp(c, tmp);
       }
    }
 
@@ -197,12 +326,8 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
       brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0));
    }
 
-   release_tmp(c, tmp);
-
-   /* Recreate the projected (NDC) coordinate in the new vertex
-    * header:
-    */
-   brw_clip_project_vertex(c, dest_ptr );
+   if (c->key.has_noperspective_shading)
+      release_tmp(c, t_nopersp);
 }
 
 void brw_clip_emit_vue(struct brw_clip_compile *c, 
-- 
1.7.10.280.gaa39

  parent reply	other threads:[~2012-07-19 20:00 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-19 20:00 (no subject) Olivier Galibert
2012-07-19 20:00 ` [PATCH 1/9] intel gen4-5: fix the vue view in the fs Olivier Galibert
2012-07-26 17:18   ` [Mesa-dev] " Eric Anholt
2012-07-27  9:21     ` Olivier Galibert
2012-07-19 20:00 ` [PATCH 2/9] intel gen4-5: simplify the bfc copy in the sf Olivier Galibert
2012-07-26 17:20   ` Eric Anholt
2012-07-19 20:00 ` [PATCH 3/9] intel gen4-5: fix GL_VERTEX_PROGRAM_TWO_SIDE selection Olivier Galibert
2012-07-26 17:19   ` Eric Anholt
2012-07-19 20:00 ` [PATCH 4/9] intel gen4-5: Fix backface/frontface selection when one one color is written to Olivier Galibert
2012-07-20 17:01   ` Eric Anholt
2012-07-20 18:03     ` Olivier Galibert
2012-07-19 20:00 ` [PATCH 5/9] intel gen4-5: Compute the interpolation status for every variable in one place Olivier Galibert
2012-07-26 17:22   ` [Mesa-dev] " Eric Anholt
2012-07-27  9:12     ` Olivier Galibert
2012-07-19 20:00 ` [PATCH 6/9] intel gen4-5: Correctly setup the parameters in the sf Olivier Galibert
2012-07-19 20:00 ` [PATCH 7/9] intel gen4-5: Correctly handle flat vs. non-flat in the clipper Olivier Galibert
2012-07-19 20:00 ` Olivier Galibert [this message]
2012-07-19 20:00 ` [PATCH 9/9] intel gen4-5: Don't touch flatshaded values when clipping, only copy them Olivier Galibert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1342728024-15055-9-git-send-email-galibert@pobox.com \
    --to=galibert@pobox.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=mesa-dev@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.