tgsi/ureg: make the dst register match the src indirection
[mesa.git] / src / gallium / auxiliary / draw / draw_pipe_clip.c
index 2d36eb3ddca079274665f6d4ed3c11897d344a62..8da0c41390fd2269dcf8139b197e9a74104c61ea 100644 (file)
 #include "draw_vs.h"
 #include "draw_pipe.h"
 #include "draw_fs.h"
+#include "draw_gs.h"
+
+
+/** Set to 1 to enable printing of coords before/after clipping */
+#define DEBUG_CLIP 0
 
 
 #ifndef IS_NEGATIVE
@@ -163,12 +168,17 @@ static void interp( const struct clip_stage *clip,
    {
       int k;
       t_nopersp = t;
-      for (k = 0; k < 2; k++)
-         if (in->data[pos_attr][k] != out->data[pos_attr][k]) {
-            t_nopersp = (dst->data[pos_attr][k] - out->data[pos_attr][k]) /
-               (in->data[pos_attr][k] - out->data[pos_attr][k]);
+      /* find either in.x != out.x or in.y != out.y */
+      for (k = 0; k < 2; k++) {
+         if (in->clip[k] != out->clip[k]) {
+            /* do divide by W, then compute linear interpolation factor */
+            float in_coord = in->clip[k] / in->clip[3];
+            float out_coord = out->clip[k] / out->clip[3];
+            float dst_coord = dst->clip[k] / dst->clip[3];
+            t_nopersp = (dst_coord - out_coord) / (in_coord - out_coord);
             break;
          }
+      }
    }
 
    /* Other attributes
@@ -237,12 +247,17 @@ static void emit_poly( struct draw_stage *stage,
       if (i == n - 1 && edgeflags[i])
          header.flags |= edge_last;
 
-      if (0) {
+      if (DEBUG_CLIP) {
          const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader;
          uint j, k;
          debug_printf("Clipped tri: (flat-shade-first = %d)\n",
                       stage->draw->rasterizer->flatshade_first);
          for (j = 0; j < 3; j++) {
+            debug_printf("  Vert %d: clip: %f %f %f %f\n", j,
+                         header.v[j]->clip[0],
+                         header.v[j]->clip[1],
+                         header.v[j]->clip[2],
+                         header.v[j]->clip[3]);
             for (k = 0; k < vs->info.num_outputs; k++) {
                debug_printf("  Vert %d: Attr %d:  %f %f %f %f\n", j, k,
                             header.v[j]->data[k][0],
@@ -315,6 +330,16 @@ do_clip_tri( struct draw_stage *stage,
    inlist[1] = header->v[1];
    inlist[2] = header->v[2];
 
+   if (DEBUG_CLIP) {
+      const float *v0 = header->v[0]->clip;
+      const float *v1 = header->v[1]->clip;
+      const float *v2 = header->v[2]->clip;
+      debug_printf("Clip triangle:\n");
+      debug_printf(" %f, %f, %f, %f\n", v0[0], v0[1], v0[2], v0[3]);
+      debug_printf(" %f, %f, %f, %f\n", v1[0], v1[1], v1[2], v1[3]);
+      debug_printf(" %f, %f, %f, %f\n", v2[0], v2[1], v2[2], v2[3]);
+   }
+
    /*
     * Note: at this point we can't just use the per-vertex edge flags.
     * We have to observe the edge flag bits set in header->flags which
@@ -572,8 +597,10 @@ clip_init_state( struct draw_stage *stage )
 {
    struct clip_stage *clipper = clip_stage( stage );
    const struct draw_vertex_shader *vs = stage->draw->vs.vertex_shader;
+   const struct draw_geometry_shader *gs = stage->draw->gs.geometry_shader;
    const struct draw_fragment_shader *fs = stage->draw->fs.fragment_shader;
    uint i;
+   const struct tgsi_shader_info *vs_info = gs ? &gs->info : &vs->info;
 
    /* We need to know for each attribute what kind of interpolation is
     * done on it (flat, smooth or noperspective).  But the information
@@ -586,6 +613,9 @@ clip_init_state( struct draw_stage *stage )
     * two outputs for one input, so we tuck the information in a
     * specific array.  Second if they don't have qualifiers, the
     * default value has to be picked from the global shade mode.
+    *
+    * Of course, if we don't have a fragment shader in the first
+    * place, defaults should be used.
     */
 
    /* First pick up the interpolation mode for
@@ -595,10 +625,12 @@ clip_init_state( struct draw_stage *stage )
    indexed_interp[0] = indexed_interp[1] = stage->draw->rasterizer->flatshade ?
       TGSI_INTERPOLATE_CONSTANT : TGSI_INTERPOLATE_PERSPECTIVE;
 
-   for (i = 0; i < fs->info.num_inputs; i++) {
-      if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
-         if (fs->info.input_interpolate[i] != TGSI_INTERPOLATE_COLOR)
-            indexed_interp[fs->info.input_semantic_index[i]] = fs->info.input_interpolate[i];
+   if (fs) {
+      for (i = 0; i < fs->info.num_inputs; i++) {
+         if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
+            if (fs->info.input_interpolate[i] != TGSI_INTERPOLATE_COLOR)
+               indexed_interp[fs->info.input_semantic_index[i]] = fs->info.input_interpolate[i];
+         }
       }
    }
 
@@ -611,28 +643,30 @@ clip_init_state( struct draw_stage *stage )
 
    clipper->num_flat_attribs = 0;
    memset(clipper->noperspective_attribs, 0, sizeof(clipper->noperspective_attribs));
-   for (i = 0; i < vs->info.num_outputs; i++) {
+   for (i = 0; i < vs_info->num_outputs; i++) {
       /* Find the interpolation mode for a specific attribute
        */
       int interp;
 
       /* If it's gl_{Front,Back}{,Secondary}Color, pick up the mode
        * from the array we've filled before. */
-      if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
-          vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
-         interp = indexed_interp[vs->info.output_semantic_index[i]];
+      if (vs_info->output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
+          vs_info->output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
+         interp = indexed_interp[vs_info->output_semantic_index[i]];
       } else {
          /* Otherwise, search in the FS inputs, with a decent default
           * if we don't find it.
           */
          uint j;
          interp = TGSI_INTERPOLATE_PERSPECTIVE;
-         for (j = 0; j < fs->info.num_inputs; j++) {
-            if (vs->info.output_semantic_name[i] == fs->info.input_semantic_name[j] &&
-                vs->info.output_semantic_index[i] == fs->info.input_semantic_index[j]) {
-               interp = fs->info.input_interpolate[j];
-               break;
-            }               
+         if (fs) {
+            for (j = 0; j < fs->info.num_inputs; j++) {
+               if (vs_info->output_semantic_name[i] == fs->info.input_semantic_name[j] &&
+                   vs_info->output_semantic_index[i] == fs->info.input_semantic_index[j]) {
+                  interp = fs->info.input_interpolate[j];
+                  break;
+               }
+            }
          }
       }