Home | History | Annotate | Download | only in draw
      1 /**************************************************************************
      2  *
      3  * Copyright 2007 VMware, Inc.
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 /**
     29  * \brief  Clipping stage
     30  *
     31  * \author  Keith Whitwell <keithw (at) vmware.com>
     32  */
     33 
     34 
     35 #include "util/u_bitcast.h"
     36 #include "util/u_memory.h"
     37 #include "util/u_math.h"
     38 
     39 #include "pipe/p_shader_tokens.h"
     40 
     41 #include "draw_vs.h"
     42 #include "draw_pipe.h"
     43 #include "draw_fs.h"
     44 #include "draw_gs.h"
     45 
     46 
     47 /** Set to 1 to enable printing of coords before/after clipping */
     48 #define DEBUG_CLIP 0
     49 
     50 
     51 #ifndef DIFFERENT_SIGNS
     52 #define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F)
     53 #endif
     54 
     55 #define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1)
     56 
     57 
     58 
     59 struct clip_stage {
     60    struct draw_stage stage;      /**< base class */
     61 
     62    unsigned pos_attr;
     63    boolean have_clipdist;
     64    int cv_attr;
     65 
     66    /* List of the attributes to be constant interpolated. */
     67    uint num_const_attribs;
     68    uint8_t const_attribs[PIPE_MAX_SHADER_OUTPUTS];
     69    /* List of the attributes to be linear interpolated. */
     70    uint num_linear_attribs;
     71    uint8_t linear_attribs[PIPE_MAX_SHADER_OUTPUTS];
     72    /* List of the attributes to be perspective interpolated. */
     73    uint num_perspect_attribs;
     74    uint8_t perspect_attribs[PIPE_MAX_SHADER_OUTPUTS];
     75 
     76    float (*plane)[4];
     77 };
     78 
     79 
     80 /** Cast wrapper */
     81 static inline struct clip_stage *clip_stage(struct draw_stage *stage)
     82 {
     83    return (struct clip_stage *)stage;
     84 }
     85 
     86 static inline unsigned
     87 draw_viewport_index(struct draw_context *draw,
     88                     const struct vertex_header *leading_vertex)
     89 {
     90    if (draw_current_shader_uses_viewport_index(draw)) {
     91       unsigned viewport_index_output =
     92          draw_current_shader_viewport_index_output(draw);
     93       unsigned viewport_index =
     94          u_bitcast_f2u(leading_vertex->data[viewport_index_output][0]);
     95       return draw_clamp_viewport_idx(viewport_index);
     96    } else {
     97       return 0;
     98    }
     99 }
    100 
    101 
    102 #define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT)))
    103 
    104 
    105 /* All attributes are float[4], so this is easy:
    106  */
    107 static void interp_attr(float dst[4],
    108                         float t,
    109                         const float in[4],
    110                         const float out[4])
    111 {
    112    dst[0] = LINTERP( t, out[0], in[0] );
    113    dst[1] = LINTERP( t, out[1], in[1] );
    114    dst[2] = LINTERP( t, out[2], in[2] );
    115    dst[3] = LINTERP( t, out[3], in[3] );
    116 }
    117 
    118 
    119 /**
    120  * Copy flat shaded attributes src vertex to dst vertex.
    121  */
    122 static void copy_flat(struct draw_stage *stage,
    123                       struct vertex_header *dst,
    124                       const struct vertex_header *src)
    125 {
    126    const struct clip_stage *clipper = clip_stage(stage);
    127    uint i;
    128    for (i = 0; i < clipper->num_const_attribs; i++) {
    129       const uint attr = clipper->const_attribs[i];
    130       COPY_4FV(dst->data[attr], src->data[attr]);
    131    }
    132 }
    133 
    134 /* Interpolate between two vertices to produce a third.
    135  */
    136 static void interp(const struct clip_stage *clip,
    137                    struct vertex_header *dst,
    138                    float t,
    139                    const struct vertex_header *out,
    140                    const struct vertex_header *in,
    141                    unsigned viewport_index)
    142 {
    143    const unsigned pos_attr = clip->pos_attr;
    144    unsigned j;
    145    float t_nopersp;
    146 
    147    /* Vertex header.
    148     */
    149    dst->clipmask = 0;
    150    dst->edgeflag = 0;        /* will get overwritten later */
    151    dst->pad = 0;
    152    dst->vertex_id = UNDEFINED_VERTEX_ID;
    153 
    154    /* Interpolate the clip-space coords.
    155     */
    156    if (clip->cv_attr >= 0) {
    157       interp_attr(dst->data[clip->cv_attr], t,
    158                   in->data[clip->cv_attr], out->data[clip->cv_attr]);
    159    }
    160    /* interpolate the clip-space position */
    161    interp_attr(dst->clip_pos, t, in->clip_pos, out->clip_pos);
    162 
    163    /* Do the projective divide and viewport transformation to get
    164     * new window coordinates:
    165     */
    166    {
    167       const float *pos = dst->clip_pos;
    168       const float *scale =
    169          clip->stage.draw->viewports[viewport_index].scale;
    170       const float *trans =
    171          clip->stage.draw->viewports[viewport_index].translate;
    172       const float oow = 1.0f / pos[3];
    173 
    174       dst->data[pos_attr][0] = pos[0] * oow * scale[0] + trans[0];
    175       dst->data[pos_attr][1] = pos[1] * oow * scale[1] + trans[1];
    176       dst->data[pos_attr][2] = pos[2] * oow * scale[2] + trans[2];
    177       dst->data[pos_attr][3] = oow;
    178    }
    179 
    180 
    181    /* interp perspective attribs */
    182    for (j = 0; j < clip->num_perspect_attribs; j++) {
    183       const unsigned attr = clip->perspect_attribs[j];
    184       interp_attr(dst->data[attr], t, in->data[attr], out->data[attr]);
    185    }
    186 
    187    /**
    188     * Compute the t in screen-space instead of 3d space to use
    189     * for noperspective interpolation.
    190     *
    191     * The points can be aligned with the X axis, so in that case try
    192     * the Y.  When both points are at the same screen position, we can
    193     * pick whatever value (the interpolated point won't be in front
    194     * anyway), so just use the 3d t.
    195     */
    196    if (clip->num_linear_attribs) {
    197       int k;
    198       t_nopersp = t;
    199       /* find either in.x != out.x or in.y != out.y */
    200       for (k = 0; k < 2; k++) {
    201          if (in->clip_pos[k] != out->clip_pos[k]) {
    202             /* do divide by W, then compute linear interpolation factor */
    203             float in_coord = in->clip_pos[k] / in->clip_pos[3];
    204             float out_coord = out->clip_pos[k] / out->clip_pos[3];
    205             float dst_coord = dst->clip_pos[k] / dst->clip_pos[3];
    206             t_nopersp = (dst_coord - out_coord) / (in_coord - out_coord);
    207             break;
    208          }
    209       }
    210       for (j = 0; j < clip->num_linear_attribs; j++) {
    211          const unsigned attr = clip->linear_attribs[j];
    212          interp_attr(dst->data[attr], t_nopersp, in->data[attr], out->data[attr]);
    213       }
    214    }
    215 }
    216 
    217 /**
    218  * Checks whether the specified triangle is empty and if it is returns
    219  * true, otherwise returns false.
    220  * Triangle is considered null/empty if its area is equal to zero.
    221  */
    222 static inline boolean
    223 is_tri_null(const struct clip_stage *clip, const struct prim_header *header)
    224 {
    225    const unsigned pos_attr = clip->pos_attr;
    226    float x1 = header->v[1]->data[pos_attr][0] - header->v[0]->data[pos_attr][0];
    227    float y1 = header->v[1]->data[pos_attr][1] - header->v[0]->data[pos_attr][1];
    228    float z1 = header->v[1]->data[pos_attr][2] - header->v[0]->data[pos_attr][2];
    229 
    230    float x2 = header->v[2]->data[pos_attr][0] - header->v[0]->data[pos_attr][0];
    231    float y2 = header->v[2]->data[pos_attr][1] - header->v[0]->data[pos_attr][1];
    232    float z2 = header->v[2]->data[pos_attr][2] - header->v[0]->data[pos_attr][2];
    233 
    234    float vx = y1 * z2 - z1 * y2;
    235    float vy = x1 * z2 - z1 * x2;
    236    float vz = x1 * y2 - y1 * x2;
    237 
    238    return (vx*vx  + vy*vy + vz*vz) == 0.f;
    239 }
    240 
    241 /**
    242  * Emit a post-clip polygon to the next pipeline stage.  The polygon
    243  * will be convex and the provoking vertex will always be vertex[0].
    244  */
    245 static void emit_poly(struct draw_stage *stage,
    246                       struct vertex_header **inlist,
    247                       const boolean *edgeflags,
    248                       unsigned n,
    249                       const struct prim_header *origPrim)
    250 {
    251    const struct clip_stage *clipper = clip_stage(stage);
    252    struct prim_header header;
    253    unsigned i;
    254    ushort edge_first, edge_middle, edge_last;
    255    boolean last_tri_was_null = FALSE;
    256    boolean tri_was_not_null = FALSE;
    257 
    258    if (stage->draw->rasterizer->flatshade_first) {
    259       edge_first  = DRAW_PIPE_EDGE_FLAG_0;
    260       edge_middle = DRAW_PIPE_EDGE_FLAG_1;
    261       edge_last   = DRAW_PIPE_EDGE_FLAG_2;
    262    }
    263    else {
    264       edge_first  = DRAW_PIPE_EDGE_FLAG_2;
    265       edge_middle = DRAW_PIPE_EDGE_FLAG_0;
    266       edge_last   = DRAW_PIPE_EDGE_FLAG_1;
    267    }
    268 
    269    if (!edgeflags[0])
    270       edge_first = 0;
    271 
    272    /* later stages may need the determinant, but only the sign matters */
    273    header.det = origPrim->det;
    274    header.flags = DRAW_PIPE_RESET_STIPPLE | edge_first | edge_middle;
    275    header.pad = 0;
    276 
    277    for (i = 2; i < n; i++, header.flags = edge_middle) {
    278       boolean tri_null;
    279       /* order the triangle verts to respect the provoking vertex mode */
    280       if (stage->draw->rasterizer->flatshade_first) {
    281          header.v[0] = inlist[0];  /* the provoking vertex */
    282          header.v[1] = inlist[i-1];
    283          header.v[2] = inlist[i];
    284       }
    285       else {
    286          header.v[0] = inlist[i-1];
    287          header.v[1] = inlist[i];
    288          header.v[2] = inlist[0];  /* the provoking vertex */
    289       }
    290 
    291       tri_null = is_tri_null(clipper, &header);
    292       /* If we generated a triangle with an area, aka. non-null triangle,
    293        * or if the previous triangle was also null then skip all subsequent
    294        * null triangles */
    295       if ((tri_was_not_null && tri_null) || (last_tri_was_null && tri_null)) {
    296          last_tri_was_null = tri_null;
    297          continue;
    298       }
    299       last_tri_was_null = tri_null;
    300       if (!tri_null) {
    301          tri_was_not_null = TRUE;
    302       }
    303 
    304       if (!edgeflags[i-1]) {
    305          header.flags &= ~edge_middle;
    306       }
    307 
    308       if (i == n - 1 && edgeflags[i])
    309          header.flags |= edge_last;
    310 
    311       if (DEBUG_CLIP) {
    312          uint j, k;
    313          debug_printf("Clipped tri: (flat-shade-first = %d)\n",
    314                       stage->draw->rasterizer->flatshade_first);
    315          for (j = 0; j < 3; j++) {
    316             debug_printf("  Vert %d: clip pos: %f %f %f %f\n", j,
    317                          header.v[j]->clip_pos[0],
    318                          header.v[j]->clip_pos[1],
    319                          header.v[j]->clip_pos[2],
    320                          header.v[j]->clip_pos[3]);
    321             if (clipper->cv_attr >= 0) {
    322                debug_printf("  Vert %d: cv: %f %f %f %f\n", j,
    323                             header.v[j]->data[clipper->cv_attr][0],
    324                             header.v[j]->data[clipper->cv_attr][1],
    325                             header.v[j]->data[clipper->cv_attr][2],
    326                             header.v[j]->data[clipper->cv_attr][3]);
    327             }
    328             for (k = 0; k < draw_num_shader_outputs(stage->draw); k++) {
    329                debug_printf("  Vert %d: Attr %d:  %f %f %f %f\n", j, k,
    330                             header.v[j]->data[k][0],
    331                             header.v[j]->data[k][1],
    332                             header.v[j]->data[k][2],
    333                             header.v[j]->data[k][3]);
    334             }
    335          }
    336       }
    337       stage->next->tri(stage->next, &header);
    338    }
    339 }
    340 
    341 
    342 static inline float
    343 dot4(const float *a, const float *b)
    344 {
    345    return (a[0] * b[0] +
    346            a[1] * b[1] +
    347            a[2] * b[2] +
    348            a[3] * b[3]);
    349 }
    350 
    351 /*
    352  * this function extracts the clip distance for the current plane,
    353  * it first checks if the shader provided a clip distance, otherwise
    354  * it works out the value using the clipvertex
    355  */
    356 static inline float getclipdist(const struct clip_stage *clipper,
    357                                 struct vertex_header *vert,
    358                                 int plane_idx)
    359 {
    360    const float *plane;
    361    float dp;
    362    if (plane_idx < 6) {
    363       /* ordinary xyz view volume clipping uses pos output */
    364       plane = clipper->plane[plane_idx];
    365       dp = dot4(vert->clip_pos, plane);
    366    }
    367    else if (clipper->have_clipdist) {
    368       /* pick the correct clipdistance element from the output vectors */
    369       int _idx = plane_idx - 6;
    370       int cdi = _idx >= 4;
    371       int vidx = cdi ? _idx - 4 : _idx;
    372       dp = vert->data[draw_current_shader_ccdistance_output(clipper->stage.draw, cdi)][vidx];
    373    } else {
    374       /*
    375        * legacy user clip planes or gl_ClipVertex
    376        */
    377       plane = clipper->plane[plane_idx];
    378       if (clipper->cv_attr >= 0) {
    379          dp = dot4(vert->data[clipper->cv_attr], plane);
    380       }
    381       else {
    382          dp = dot4(vert->clip_pos, plane);
    383       }
    384    }
    385    return dp;
    386 }
    387 
    388 /* Clip a triangle against the viewport and user clip planes.
    389  */
    390 static void
    391 do_clip_tri(struct draw_stage *stage,
    392             struct prim_header *header,
    393             unsigned clipmask)
    394 {
    395    struct clip_stage *clipper = clip_stage( stage );
    396    struct vertex_header *a[MAX_CLIPPED_VERTICES];
    397    struct vertex_header *b[MAX_CLIPPED_VERTICES];
    398    struct vertex_header **inlist = a;
    399    struct vertex_header **outlist = b;
    400    struct vertex_header *prov_vertex;
    401    unsigned tmpnr = 0;
    402    unsigned n = 3;
    403    unsigned i;
    404    boolean aEdges[MAX_CLIPPED_VERTICES];
    405    boolean bEdges[MAX_CLIPPED_VERTICES];
    406    boolean *inEdges = aEdges;
    407    boolean *outEdges = bEdges;
    408    int viewport_index = 0;
    409 
    410    inlist[0] = header->v[0];
    411    inlist[1] = header->v[1];
    412    inlist[2] = header->v[2];
    413 
    414    /*
    415     * For d3d10, we need to take this from the leading (first) vertex.
    416     * For GL, we could do anything (as long as we advertize
    417     * GL_UNDEFINED_VERTEX for the VIEWPORT_INDEX_PROVOKING_VERTEX query),
    418     * but it needs to be consistent with what other parts (i.e. driver)
    419     * will do, and that seems easier with GL_PROVOKING_VERTEX logic.
    420     */
    421    if (stage->draw->rasterizer->flatshade_first) {
    422       prov_vertex = inlist[0];
    423    }
    424    else {
    425       prov_vertex = inlist[2];
    426    }
    427    viewport_index = draw_viewport_index(clipper->stage.draw, prov_vertex);
    428 
    429    if (DEBUG_CLIP) {
    430       const float *v0 = header->v[0]->clip_pos;
    431       const float *v1 = header->v[1]->clip_pos;
    432       const float *v2 = header->v[2]->clip_pos;
    433       debug_printf("Clip triangle pos:\n");
    434       debug_printf(" %f, %f, %f, %f\n", v0[0], v0[1], v0[2], v0[3]);
    435       debug_printf(" %f, %f, %f, %f\n", v1[0], v1[1], v1[2], v1[3]);
    436       debug_printf(" %f, %f, %f, %f\n", v2[0], v2[1], v2[2], v2[3]);
    437       if (clipper->cv_attr >= 0) {
    438          const float *v0 = header->v[0]->data[clipper->cv_attr];
    439          const float *v1 = header->v[1]->data[clipper->cv_attr];
    440          const float *v2 = header->v[2]->data[clipper->cv_attr];
    441          debug_printf("Clip triangle cv:\n");
    442          debug_printf(" %f, %f, %f, %f\n", v0[0], v0[1], v0[2], v0[3]);
    443          debug_printf(" %f, %f, %f, %f\n", v1[0], v1[1], v1[2], v1[3]);
    444          debug_printf(" %f, %f, %f, %f\n", v2[0], v2[1], v2[2], v2[3]);
    445       }
    446    }
    447 
    448    /*
    449     * Note: at this point we can't just use the per-vertex edge flags.
    450     * We have to observe the edge flag bits set in header->flags which
    451     * were set during primitive decomposition.  Put those flags into
    452     * an edge flags array which parallels the vertex array.
    453     * Later, in the 'unfilled' pipeline stage we'll draw the edge if both
    454     * the header.flags bit is set AND the per-vertex edgeflag field is set.
    455     */
    456    inEdges[0] = !!(header->flags & DRAW_PIPE_EDGE_FLAG_0);
    457    inEdges[1] = !!(header->flags & DRAW_PIPE_EDGE_FLAG_1);
    458    inEdges[2] = !!(header->flags & DRAW_PIPE_EDGE_FLAG_2);
    459 
    460    while (clipmask && n >= 3) {
    461       const unsigned plane_idx = ffs(clipmask)-1;
    462       const boolean is_user_clip_plane = plane_idx >= 6;
    463       struct vertex_header *vert_prev = inlist[0];
    464       boolean *edge_prev = &inEdges[0];
    465       float dp_prev;
    466       unsigned outcount = 0;
    467 
    468       dp_prev = getclipdist(clipper, vert_prev, plane_idx);
    469       clipmask &= ~(1<<plane_idx);
    470 
    471       if (util_is_inf_or_nan(dp_prev))
    472          return; //discard nan
    473 
    474       assert(n < MAX_CLIPPED_VERTICES);
    475       if (n >= MAX_CLIPPED_VERTICES)
    476          return;
    477       inlist[n] = inlist[0]; /* prevent rotation of vertices */
    478       inEdges[n] = inEdges[0];
    479 
    480       for (i = 1; i <= n; i++) {
    481          struct vertex_header *vert = inlist[i];
    482          boolean *edge = &inEdges[i];
    483 
    484          float dp = getclipdist(clipper, vert, plane_idx);
    485 
    486          if (util_is_inf_or_nan(dp))
    487             return; //discard nan
    488 
    489          if (dp_prev >= 0.0f) {
    490             assert(outcount < MAX_CLIPPED_VERTICES);
    491             if (outcount >= MAX_CLIPPED_VERTICES)
    492                return;
    493             outEdges[outcount] = *edge_prev;
    494             outlist[outcount++] = vert_prev;
    495          }
    496 
    497          if (DIFFERENT_SIGNS(dp, dp_prev)) {
    498             struct vertex_header *new_vert;
    499             boolean *new_edge;
    500 
    501             assert(tmpnr < MAX_CLIPPED_VERTICES + 1);
    502             if (tmpnr >= MAX_CLIPPED_VERTICES + 1)
    503                return;
    504             new_vert = clipper->stage.tmp[tmpnr++];
    505 
    506             assert(outcount < MAX_CLIPPED_VERTICES);
    507             if (outcount >= MAX_CLIPPED_VERTICES)
    508                return;
    509 
    510             new_edge = &outEdges[outcount];
    511             outlist[outcount++] = new_vert;
    512 
    513             if (dp < 0.0f) {
    514                /* Going out of bounds.  Avoid division by zero as we
    515                 * know dp != dp_prev from DIFFERENT_SIGNS, above.
    516                 */
    517                float t = dp / (dp - dp_prev);
    518                interp( clipper, new_vert, t, vert, vert_prev, viewport_index );
    519 
    520                /* Whether or not to set edge flag for the new vert depends
    521                 * on whether it's a user-defined clipping plane.  We're
    522                 * copying NVIDIA's behaviour here.
    523                 */
    524                if (is_user_clip_plane) {
    525                   /* we want to see an edge along the clip plane */
    526                   *new_edge = TRUE;
    527                   new_vert->edgeflag = TRUE;
    528                }
    529                else {
    530                   /* we don't want to see an edge along the frustum clip plane */
    531                   *new_edge = *edge_prev;
    532                   new_vert->edgeflag = FALSE;
    533                }
    534             }
    535             else {
    536                /* Coming back in.
    537                 */
    538                float t = dp_prev / (dp_prev - dp);
    539                interp( clipper, new_vert, t, vert_prev, vert, viewport_index );
    540 
    541                /* Copy starting vert's edgeflag:
    542                 */
    543                new_vert->edgeflag = vert_prev->edgeflag;
    544                *new_edge = *edge_prev;
    545             }
    546          }
    547 
    548          vert_prev = vert;
    549          edge_prev = edge;
    550          dp_prev = dp;
    551       }
    552 
    553       /* swap in/out lists */
    554       {
    555          struct vertex_header **tmp = inlist;
    556          inlist = outlist;
    557          outlist = tmp;
    558          n = outcount;
    559       }
    560       {
    561          boolean *tmp = inEdges;
    562          inEdges = outEdges;
    563          outEdges = tmp;
    564       }
    565 
    566    }
    567 
    568    /* If constant interpolated, copy provoking vertex attrib to polygon vertex[0]
    569     */
    570    if (n >= 3) {
    571       if (clipper->num_const_attribs) {
    572          if (stage->draw->rasterizer->flatshade_first) {
    573             if (inlist[0] != header->v[0]) {
    574                assert(tmpnr < MAX_CLIPPED_VERTICES + 1);
    575                if (tmpnr >= MAX_CLIPPED_VERTICES + 1)
    576                   return;
    577                inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
    578                copy_flat(stage, inlist[0], header->v[0]);
    579             }
    580          }
    581          else {
    582             if (inlist[0] != header->v[2]) {
    583                assert(tmpnr < MAX_CLIPPED_VERTICES + 1);
    584                if (tmpnr >= MAX_CLIPPED_VERTICES + 1)
    585                   return;
    586                inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
    587                copy_flat(stage, inlist[0], header->v[2]);
    588             }
    589          }
    590       }
    591 
    592       /* Emit the polygon as triangles to the setup stage:
    593        */
    594       emit_poly(stage, inlist, inEdges, n, header);
    595    }
    596 }
    597 
    598 
    599 /* Clip a line against the viewport and user clip planes.
    600  */
    601 static void
    602 do_clip_line(struct draw_stage *stage,
    603              struct prim_header *header,
    604              unsigned clipmask)
    605 {
    606    const struct clip_stage *clipper = clip_stage(stage);
    607    struct vertex_header *v0 = header->v[0];
    608    struct vertex_header *v1 = header->v[1];
    609    struct vertex_header *prov_vertex;
    610    float t0 = 0.0F;
    611    float t1 = 0.0F;
    612    struct prim_header newprim;
    613    int viewport_index;
    614 
    615    newprim.flags = header->flags;
    616 
    617    if (stage->draw->rasterizer->flatshade_first) {
    618       prov_vertex = v0;
    619    }
    620    else {
    621       prov_vertex = v1;
    622    }
    623    viewport_index = draw_viewport_index(clipper->stage.draw, prov_vertex);
    624 
    625    while (clipmask) {
    626       const unsigned plane_idx = ffs(clipmask)-1;
    627       const float dp0 = getclipdist(clipper, v0, plane_idx);
    628       const float dp1 = getclipdist(clipper, v1, plane_idx);
    629 
    630       if (util_is_inf_or_nan(dp0) || util_is_inf_or_nan(dp1))
    631          return; //discard nan
    632 
    633       if (dp1 < 0.0F) {
    634          float t = dp1 / (dp1 - dp0);
    635          t1 = MAX2(t1, t);
    636       }
    637 
    638       if (dp0 < 0.0F) {
    639          float t = dp0 / (dp0 - dp1);
    640          t0 = MAX2(t0, t);
    641       }
    642 
    643       if (t0 + t1 >= 1.0F)
    644          return; /* discard */
    645 
    646       clipmask &= ~(1 << plane_idx);  /* turn off this plane's bit */
    647    }
    648 
    649    if (v0->clipmask) {
    650       interp( clipper, stage->tmp[0], t0, v0, v1, viewport_index );
    651       if (stage->draw->rasterizer->flatshade_first) {
    652          copy_flat(stage, stage->tmp[0], v0);  /* copy v0 color to tmp[0] */
    653       }
    654       else {
    655          copy_flat(stage, stage->tmp[0], v1);  /* copy v1 color to tmp[0] */
    656       }
    657       newprim.v[0] = stage->tmp[0];
    658    }
    659    else {
    660       newprim.v[0] = v0;
    661    }
    662 
    663    if (v1->clipmask) {
    664       interp( clipper, stage->tmp[1], t1, v1, v0, viewport_index );
    665       if (stage->draw->rasterizer->flatshade_first) {
    666          copy_flat(stage, stage->tmp[1], v0);  /* copy v0 color to tmp[1] */
    667       }
    668       else {
    669          copy_flat(stage, stage->tmp[1], v1);  /* copy v1 color to tmp[1] */
    670       }
    671       newprim.v[1] = stage->tmp[1];
    672    }
    673    else {
    674       newprim.v[1] = v1;
    675    }
    676 
    677    stage->next->line( stage->next, &newprim );
    678 }
    679 
    680 
    681 static void
    682 clip_point(struct draw_stage *stage, struct prim_header *header)
    683 {
    684    if (header->v[0]->clipmask == 0)
    685       stage->next->point( stage->next, header );
    686 }
    687 
    688 
    689 /*
    690  * Clip points but ignore the first 4 (xy) clip planes.
    691  * (Because the generated clip mask is completely unaffacted by guard band,
    692  * we still need to manually evaluate the x/y planes if they are outside
    693  * the guard band and not just outside the vp.)
    694  */
    695 static void
    696 clip_point_guard_xy(struct draw_stage *stage, struct prim_header *header)
    697 {
    698    unsigned clipmask = header->v[0]->clipmask;
    699    if ((clipmask & 0xffffffff) == 0)
    700       stage->next->point(stage->next, header);
    701    else if ((clipmask & 0xfffffff0) == 0) {
    702       while (clipmask) {
    703          const unsigned plane_idx = ffs(clipmask)-1;
    704          clipmask &= ~(1 << plane_idx);  /* turn off this plane's bit */
    705          /* TODO: this should really do proper guardband clipping,
    706           * currently just throw out infs/nans.
    707           * Also note that vertices with negative w values MUST be tossed
    708           * out (not sure if proper guardband clipping would do this
    709           * automatically). These would usually be captured by depth clip
    710           * too but this can be disabled.
    711           */
    712          if (header->v[0]->clip_pos[3] <= 0.0f ||
    713              util_is_inf_or_nan(header->v[0]->clip_pos[0]) ||
    714              util_is_inf_or_nan(header->v[0]->clip_pos[1]))
    715             return;
    716       }
    717       stage->next->point(stage->next, header);
    718    }
    719 }
    720 
    721 
    722 static void
    723 clip_first_point(struct draw_stage *stage, struct prim_header *header)
    724 {
    725    stage->point = stage->draw->guard_band_points_xy ? clip_point_guard_xy : clip_point;
    726    stage->point(stage, header);
    727 }
    728 
    729 
    730 static void
    731 clip_line(struct draw_stage *stage, struct prim_header *header)
    732 {
    733    unsigned clipmask = (header->v[0]->clipmask |
    734                         header->v[1]->clipmask);
    735 
    736    if (clipmask == 0) {
    737       /* no clipping needed */
    738       stage->next->line( stage->next, header );
    739    }
    740    else if ((header->v[0]->clipmask &
    741              header->v[1]->clipmask) == 0) {
    742       do_clip_line(stage, header, clipmask);
    743    }
    744    /* else, totally clipped */
    745 }
    746 
    747 
    748 static void
    749 clip_tri(struct draw_stage *stage, struct prim_header *header)
    750 {
    751    unsigned clipmask = (header->v[0]->clipmask |
    752                         header->v[1]->clipmask |
    753                         header->v[2]->clipmask);
    754 
    755    if (clipmask == 0) {
    756       /* no clipping needed */
    757       stage->next->tri( stage->next, header );
    758    }
    759    else if ((header->v[0]->clipmask &
    760              header->v[1]->clipmask &
    761              header->v[2]->clipmask) == 0) {
    762       do_clip_tri(stage, header, clipmask);
    763    }
    764 }
    765 
    766 
    767 static int
    768 find_interp(const struct draw_fragment_shader *fs, int *indexed_interp,
    769             uint semantic_name, uint semantic_index)
    770 {
    771    int interp;
    772    /* If it's gl_{Front,Back}{,Secondary}Color, pick up the mode
    773     * from the array we've filled before. */
    774    if (semantic_name == TGSI_SEMANTIC_COLOR ||
    775        semantic_name == TGSI_SEMANTIC_BCOLOR) {
    776       interp = indexed_interp[semantic_index];
    777    } else if (semantic_name == TGSI_SEMANTIC_POSITION ||
    778               semantic_name == TGSI_SEMANTIC_CLIPVERTEX) {
    779       /* these inputs are handled specially always */
    780       return -1;
    781    } else {
    782       /* Otherwise, search in the FS inputs, with a decent default
    783        * if we don't find it.
    784        * This probably only matters for layer, vpindex, culldist, maybe
    785        * front_face.
    786        */
    787       uint j;
    788       if (semantic_name == TGSI_SEMANTIC_LAYER ||
    789           semantic_name == TGSI_SEMANTIC_VIEWPORT_INDEX) {
    790          interp = TGSI_INTERPOLATE_CONSTANT;
    791       }
    792       else {
    793          interp = TGSI_INTERPOLATE_PERSPECTIVE;
    794       }
    795       if (fs) {
    796          for (j = 0; j < fs->info.num_inputs; j++) {
    797             if (semantic_name == fs->info.input_semantic_name[j] &&
    798                 semantic_index == fs->info.input_semantic_index[j]) {
    799                interp = fs->info.input_interpolate[j];
    800                break;
    801             }
    802          }
    803       }
    804    }
    805    return interp;
    806 }
    807 
    808 /* Update state.  Could further delay this until we hit the first
    809  * primitive that really requires clipping.
    810  */
    811 static void
    812 clip_init_state(struct draw_stage *stage)
    813 {
    814    struct clip_stage *clipper = clip_stage(stage);
    815    const struct draw_context *draw = stage->draw;
    816    const struct draw_fragment_shader *fs = draw->fs.fragment_shader;
    817    const struct tgsi_shader_info *info = draw_get_shader_info(draw);
    818    uint i, j;
    819    int indexed_interp[2];
    820 
    821    clipper->pos_attr = draw_current_shader_position_output(draw);
    822    clipper->have_clipdist = draw_current_shader_num_written_clipdistances(draw) > 0;
    823    if (draw_current_shader_clipvertex_output(draw) != clipper->pos_attr) {
    824       clipper->cv_attr = (int)draw_current_shader_clipvertex_output(draw);
    825    }
    826    else {
    827       clipper->cv_attr = -1;
    828    }
    829 
    830    /* We need to know for each attribute what kind of interpolation is
    831     * done on it (flat, smooth or noperspective).  But the information
    832     * is not directly accessible for outputs, only for inputs.  So we
    833     * have to match semantic name and index between the VS (or GS/ES)
    834     * outputs and the FS inputs to get to the interpolation mode.
    835     *
    836     * The only hitch is with gl_FrontColor/gl_BackColor which map to
    837     * gl_Color, and their Secondary versions.  First there are (up to)
    838     * two outputs for one input, so we tuck the information in a
    839     * specific array.  Second if they don't have qualifiers, the
    840     * default value has to be picked from the global shade mode.
    841     *
    842     * Of course, if we don't have a fragment shader in the first
    843     * place, defaults should be used.
    844     */
    845 
    846    /* First pick up the interpolation mode for
    847     * gl_Color/gl_SecondaryColor, with the correct default.
    848     */
    849    indexed_interp[0] = indexed_interp[1] = draw->rasterizer->flatshade ?
    850       TGSI_INTERPOLATE_CONSTANT : TGSI_INTERPOLATE_PERSPECTIVE;
    851 
    852    if (fs) {
    853       for (i = 0; i < fs->info.num_inputs; i++) {
    854          if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
    855             if (fs->info.input_interpolate[i] != TGSI_INTERPOLATE_COLOR)
    856                indexed_interp[fs->info.input_semantic_index[i]] = fs->info.input_interpolate[i];
    857          }
    858       }
    859    }
    860 
    861    /* Then resolve the interpolation mode for every output attribute. */
    862 
    863    clipper->num_const_attribs = 0;
    864    clipper->num_linear_attribs = 0;
    865    clipper->num_perspect_attribs = 0;
    866    for (i = 0; i < info->num_outputs; i++) {
    867       /* Find the interpolation mode for a specific attribute */
    868       int interp = find_interp(fs, indexed_interp,
    869                                info->output_semantic_name[i],
    870                                info->output_semantic_index[i]);
    871       switch (interp) {
    872       case TGSI_INTERPOLATE_CONSTANT:
    873          clipper->const_attribs[clipper->num_const_attribs] = i;
    874          clipper->num_const_attribs++;
    875          break;
    876       case TGSI_INTERPOLATE_LINEAR:
    877          clipper->linear_attribs[clipper->num_linear_attribs] = i;
    878          clipper->num_linear_attribs++;
    879          break;
    880       case TGSI_INTERPOLATE_PERSPECTIVE:
    881          clipper->perspect_attribs[clipper->num_perspect_attribs] = i;
    882          clipper->num_perspect_attribs++;
    883          break;
    884       default:
    885          assert(interp == -1);
    886          break;
    887       }
    888    }
    889    /* Search the extra vertex attributes */
    890    for (j = 0; j < draw->extra_shader_outputs.num; j++) {
    891       /* Find the interpolation mode for a specific attribute */
    892       int interp = find_interp(fs, indexed_interp,
    893                                draw->extra_shader_outputs.semantic_name[j],
    894                                draw->extra_shader_outputs.semantic_index[j]);
    895       switch (interp) {
    896       case TGSI_INTERPOLATE_CONSTANT:
    897          clipper->const_attribs[clipper->num_const_attribs] = i + j;
    898          clipper->num_const_attribs++;
    899          break;
    900       case TGSI_INTERPOLATE_LINEAR:
    901          clipper->linear_attribs[clipper->num_linear_attribs] = i + j;
    902          clipper->num_linear_attribs++;
    903          break;
    904       case TGSI_INTERPOLATE_PERSPECTIVE:
    905          clipper->perspect_attribs[clipper->num_perspect_attribs] = i + j;
    906          clipper->num_perspect_attribs++;
    907          break;
    908       default:
    909          assert(interp == -1);
    910          break;
    911       }
    912    }
    913 
    914    stage->tri = clip_tri;
    915    stage->line = clip_line;
    916 }
    917 
    918 
    919 
    920 static void clip_first_tri(struct draw_stage *stage,
    921                            struct prim_header *header)
    922 {
    923    clip_init_state( stage );
    924    stage->tri( stage, header );
    925 }
    926 
    927 static void clip_first_line(struct draw_stage *stage,
    928                             struct prim_header *header)
    929 {
    930    clip_init_state( stage );
    931    stage->line( stage, header );
    932 }
    933 
    934 
    935 static void clip_flush(struct draw_stage *stage, unsigned flags)
    936 {
    937    stage->tri = clip_first_tri;
    938    stage->line = clip_first_line;
    939    stage->next->flush( stage->next, flags );
    940 }
    941 
    942 
    943 static void clip_reset_stipple_counter(struct draw_stage *stage)
    944 {
    945    stage->next->reset_stipple_counter( stage->next );
    946 }
    947 
    948 
    949 static void clip_destroy(struct draw_stage *stage)
    950 {
    951    draw_free_temp_verts( stage );
    952    FREE( stage );
    953 }
    954 
    955 
    956 /**
    957  * Allocate a new clipper stage.
    958  * \return pointer to new stage object
    959  */
    960 struct draw_stage *draw_clip_stage(struct draw_context *draw)
    961 {
    962    struct clip_stage *clipper = CALLOC_STRUCT(clip_stage);
    963    if (!clipper)
    964       goto fail;
    965 
    966    clipper->stage.draw = draw;
    967    clipper->stage.name = "clipper";
    968    clipper->stage.point = clip_first_point;
    969    clipper->stage.line = clip_first_line;
    970    clipper->stage.tri = clip_first_tri;
    971    clipper->stage.flush = clip_flush;
    972    clipper->stage.reset_stipple_counter = clip_reset_stipple_counter;
    973    clipper->stage.destroy = clip_destroy;
    974 
    975    clipper->plane = draw->plane;
    976 
    977    if (!draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 ))
    978       goto fail;
    979 
    980    return &clipper->stage;
    981 
    982  fail:
    983    if (clipper)
    984       clipper->stage.destroy( &clipper->stage );
    985 
    986    return NULL;
    987 }
    988