draw_pipe.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00028  /*
00029   * Authors:
00030   *   Keith Whitwell <keith@tungstengraphics.com>
00031   */
00032 
00033 #include "draw/draw_private.h"
00034 #include "draw/draw_pipe.h"
00035 
00036 
00037 
00038 boolean draw_pipeline_init( struct draw_context *draw )
00039 {
00040    /* create pipeline stages */
00041    draw->pipeline.wide_line  = draw_wide_line_stage( draw );
00042    draw->pipeline.wide_point = draw_wide_point_stage( draw );
00043    draw->pipeline.stipple   = draw_stipple_stage( draw );
00044    draw->pipeline.unfilled  = draw_unfilled_stage( draw );
00045    draw->pipeline.twoside   = draw_twoside_stage( draw );
00046    draw->pipeline.offset    = draw_offset_stage( draw );
00047    draw->pipeline.clip      = draw_clip_stage( draw );
00048    draw->pipeline.flatshade = draw_flatshade_stage( draw );
00049    draw->pipeline.cull      = draw_cull_stage( draw );
00050    draw->pipeline.validate  = draw_validate_stage( draw );
00051    draw->pipeline.first     = draw->pipeline.validate;
00052 
00053    if (!draw->pipeline.wide_line ||
00054        !draw->pipeline.wide_point ||
00055        !draw->pipeline.stipple ||
00056        !draw->pipeline.unfilled ||
00057        !draw->pipeline.twoside ||
00058        !draw->pipeline.offset ||
00059        !draw->pipeline.clip ||
00060        !draw->pipeline.flatshade ||
00061        !draw->pipeline.cull ||
00062        !draw->pipeline.validate)
00063       return FALSE;
00064 
00065    /* these defaults are oriented toward the needs of softpipe */
00066    draw->pipeline.wide_point_threshold = 1000000.0; /* infinity */
00067    draw->pipeline.wide_line_threshold = 1.0;
00068    draw->pipeline.line_stipple = TRUE;
00069    draw->pipeline.point_sprite = TRUE;
00070 
00071    return TRUE;
00072 }
00073 
00074 
00075 void draw_pipeline_destroy( struct draw_context *draw )
00076 {
00077    if (draw->pipeline.wide_line)
00078       draw->pipeline.wide_line->destroy( draw->pipeline.wide_line );
00079    if (draw->pipeline.wide_point)
00080       draw->pipeline.wide_point->destroy( draw->pipeline.wide_point );
00081    if (draw->pipeline.stipple)
00082       draw->pipeline.stipple->destroy( draw->pipeline.stipple );
00083    if (draw->pipeline.unfilled)
00084       draw->pipeline.unfilled->destroy( draw->pipeline.unfilled );
00085    if (draw->pipeline.twoside)
00086       draw->pipeline.twoside->destroy( draw->pipeline.twoside );
00087    if (draw->pipeline.offset)
00088       draw->pipeline.offset->destroy( draw->pipeline.offset );
00089    if (draw->pipeline.clip)
00090       draw->pipeline.clip->destroy( draw->pipeline.clip );
00091    if (draw->pipeline.flatshade)
00092       draw->pipeline.flatshade->destroy( draw->pipeline.flatshade );
00093    if (draw->pipeline.cull)
00094       draw->pipeline.cull->destroy( draw->pipeline.cull );
00095    if (draw->pipeline.validate)
00096       draw->pipeline.validate->destroy( draw->pipeline.validate );
00097    if (draw->pipeline.aaline)
00098       draw->pipeline.aaline->destroy( draw->pipeline.aaline );
00099    if (draw->pipeline.aapoint)
00100       draw->pipeline.aapoint->destroy( draw->pipeline.aapoint );
00101    if (draw->pipeline.pstipple)
00102       draw->pipeline.pstipple->destroy( draw->pipeline.pstipple );
00103    if (draw->pipeline.rasterize)
00104       draw->pipeline.rasterize->destroy( draw->pipeline.rasterize );
00105 }
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 static void do_point( struct draw_context *draw,
00114                       const char *v0 )
00115 {
00116    struct prim_header prim;
00117    
00118    prim.flags = 0;
00119    prim.pad = 0;
00120    prim.v[0] = (struct vertex_header *)v0;
00121 
00122    draw->pipeline.first->point( draw->pipeline.first, &prim );
00123 }
00124 
00125 
00126 static void do_line( struct draw_context *draw,
00127                      ushort flags,
00128                      const char *v0,
00129                      const char *v1 )
00130 {
00131    struct prim_header prim;
00132    
00133    prim.flags = flags;
00134    prim.pad = 0;
00135    prim.v[0] = (struct vertex_header *)v0;
00136    prim.v[1] = (struct vertex_header *)v1;
00137 
00138    draw->pipeline.first->line( draw->pipeline.first, &prim );
00139 }
00140 
00141 
00142 static void do_triangle( struct draw_context *draw,
00143                          ushort flags,
00144                          char *v0,
00145                          char *v1,
00146                          char *v2 )
00147 {
00148    struct prim_header prim;
00149    
00150    prim.v[0] = (struct vertex_header *)v0;
00151    prim.v[1] = (struct vertex_header *)v1;
00152    prim.v[2] = (struct vertex_header *)v2;
00153    prim.flags = flags;
00154    prim.pad = 0;
00155 
00156    draw->pipeline.first->tri( draw->pipeline.first, &prim );
00157 }
00158 
00159 
00160 
00161 #define QUAD(i0,i1,i2,i3)                       \
00162    do_triangle( draw,                           \
00163                 ( DRAW_PIPE_RESET_STIPPLE |     \
00164                   DRAW_PIPE_EDGE_FLAG_0 |       \
00165                   DRAW_PIPE_EDGE_FLAG_2 ),      \
00166                 verts + stride * elts[i0],      \
00167                 verts + stride * elts[i1],      \
00168                 verts + stride * elts[i3]);     \
00169    do_triangle( draw,                           \
00170                 ( DRAW_PIPE_EDGE_FLAG_0 |       \
00171                   DRAW_PIPE_EDGE_FLAG_1 ),      \
00172                 verts + stride * elts[i1],      \
00173                 verts + stride * elts[i2],      \
00174                 verts + stride * elts[i3])
00175 
00176 #define TRIANGLE(flags,i0,i1,i2)                                        \
00177    do_triangle( draw,                                                   \
00178                 elts[i0],  /* flags */                          \
00179                 verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK),     \
00180                 verts + stride * elts[i1],                              \
00181                 verts + stride * elts[i2])
00182 
00183 #define LINE(flags,i0,i1)                                       \
00184    do_line( draw,                                               \
00185             elts[i0],                                   \
00186             verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
00187             verts + stride * elts[i1])
00188 
00189 #define POINT(i0)                               \
00190    do_point( draw,                              \
00191              verts + stride * elts[i0] )
00192 
00193 #define FUNC pipe_run
00194 #define ARGS                                    \
00195     struct draw_context *draw,                  \
00196     unsigned prim,                              \
00197     struct vertex_header *vertices,             \
00198     unsigned stride,                            \
00199     const ushort *elts
00200 
00201 #define LOCAL_VARS                                           \
00202    char *verts = (char *)vertices;                           \
00203    boolean flatfirst = (draw->rasterizer->flatshade &&       \
00204                         draw->rasterizer->flatshade_first);  \
00205    unsigned i;                                               \
00206    ushort flags
00207 
00208 #define FLUSH
00209 
00210 #include "draw_pt_decompose.h"
00211 #undef ARGS
00212 #undef LOCAL_VARS
00213 
00214 
00215 
00216 /* Code to run the pipeline on a fairly arbitary collection of vertices.
00217  *
00218  * Vertex headers must be pre-initialized with the
00219  * UNDEFINED_VERTEX_ID, this code will cause that id to become
00220  * overwritten, so it may have to be reset if there is the intention
00221  * to reuse the vertices.
00222  *
00223  * This code provides a callback to reset the vertex id's which the
00224  * draw_vbuf.c code uses when it has to perform a flush.
00225  */
00226 void draw_pipeline_run( struct draw_context *draw,
00227                         unsigned prim,
00228                         struct vertex_header *vertices,
00229                         unsigned vertex_count,
00230                         unsigned stride,
00231                         const ushort *elts,
00232                         unsigned count )
00233 {
00234    char *verts = (char *)vertices;
00235 
00236    draw->pipeline.verts = verts;
00237    draw->pipeline.vertex_stride = stride;
00238    draw->pipeline.vertex_count = vertex_count;
00239    
00240    pipe_run(draw, prim, vertices, stride, elts, count);
00241    
00242    draw->pipeline.verts = NULL;
00243    draw->pipeline.vertex_count = 0;
00244 }
00245 
00246 #define QUAD(i0,i1,i2,i3)                                        \
00247    do_triangle( draw,                                            \
00248                 ( DRAW_PIPE_RESET_STIPPLE |                      \
00249                   DRAW_PIPE_EDGE_FLAG_0 |                        \
00250                   DRAW_PIPE_EDGE_FLAG_2 ),                       \
00251                  verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
00252                  verts + stride * (i1),                          \
00253                 verts + stride * (i3));                          \
00254       do_triangle( draw,                                         \
00255                    ( DRAW_PIPE_EDGE_FLAG_0 |                     \
00256                      DRAW_PIPE_EDGE_FLAG_1 ),                    \
00257                  verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK), \
00258                  verts + stride * (i2),                          \
00259                  verts + stride * (i3))
00260 
00261 #define TRIANGLE(flags,i0,i1,i2)                                 \
00262    do_triangle( draw,                                            \
00263                 flags,  /* flags */                              \
00264                  verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
00265                  verts + stride * (i1),                          \
00266                  verts + stride * (i2))
00267 
00268 #define LINE(flags,i0,i1)                                   \
00269    do_line( draw,                                           \
00270             flags,                                          \
00271             verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
00272             verts + stride * (i1))
00273 
00274 #define POINT(i0)                               \
00275    do_point( draw,                              \
00276              verts + stride * i0 )
00277 
00278 #define FUNC pipe_run_linear
00279 #define ARGS                                    \
00280     struct draw_context *draw,                  \
00281     unsigned prim,                              \
00282     struct vertex_header *vertices,             \
00283     unsigned stride
00284 
00285 #define LOCAL_VARS                                           \
00286    char *verts = (char *)vertices;                           \
00287    boolean flatfirst = (draw->rasterizer->flatshade &&       \
00288                         draw->rasterizer->flatshade_first);  \
00289    unsigned i;                                               \
00290    ushort flags
00291 
00292 #define FLUSH
00293 
00294 #include "draw_pt_decompose.h"
00295 
00296 void draw_pipeline_run_linear( struct draw_context *draw,
00297                                unsigned prim,
00298                                struct vertex_header *vertices,
00299                                unsigned count,
00300                                unsigned stride )
00301 {
00302    char *verts = (char *)vertices;
00303    draw->pipeline.verts = verts;
00304    draw->pipeline.vertex_stride = stride;
00305    draw->pipeline.vertex_count = count;
00306 
00307    pipe_run_linear(draw, prim, vertices, stride, count);
00308 
00309    draw->pipeline.verts = NULL;
00310    draw->pipeline.vertex_count = 0;
00311 }
00312 
00313 
00314 void draw_pipeline_flush( struct draw_context *draw, 
00315                           unsigned flags )
00316 {
00317    draw->pipeline.first->flush( draw->pipeline.first, flags );
00318    draw->pipeline.first = draw->pipeline.validate;
00319 }

Generated on Tue Sep 29 06:25:14 2009 for Gallium3D by  doxygen 1.5.4