draw_pipe_validate.c File Reference

Include dependency graph for draw_pipe_validate.c:

Go to the source code of this file.

Functions

static boolean points (unsigned prim)
static boolean lines (unsigned prim)
static boolean triangles (unsigned prim)
boolean draw_need_pipeline (const struct draw_context *draw, const struct pipe_rasterizer_state *rasterizer, unsigned int prim)
 Default version of a function to check if we need any special pipeline stages, or whether prims/verts can go through untouched.
static struct draw_stagevalidate_pipeline (struct draw_stage *stage)
 Rebuild the rendering pipeline.
static void validate_tri (struct draw_stage *stage, struct prim_header *header)
static void validate_line (struct draw_stage *stage, struct prim_header *header)
static void validate_point (struct draw_stage *stage, struct prim_header *header)
static void validate_reset_stipple_counter (struct draw_stage *stage)
static void validate_flush (struct draw_stage *stage, unsigned flags)
static void validate_destroy (struct draw_stage *stage)
struct draw_stagedraw_validate_stage (struct draw_context *draw)
 Create validate pipeline stage.


Function Documentation

boolean draw_need_pipeline ( const struct draw_context draw,
const struct pipe_rasterizer_state rasterizer,
unsigned int  prim 
)

Default version of a function to check if we need any special pipeline stages, or whether prims/verts can go through untouched.

Don't test for bypass clipping or vs modes, this function is just about the primitive pipeline stages.

This can be overridden by the driver.

Definition at line 64 of file draw_pipe_validate.c.

References draw_context::aaline, draw_context::aapoint, FALSE, pipe_rasterizer_state::fill_ccw, pipe_rasterizer_state::fill_cw, pipe_rasterizer_state::light_twoside, pipe_rasterizer_state::line_smooth, draw_context::line_stipple, pipe_rasterizer_state::line_stipple_enable, pipe_rasterizer_state::line_width, lines(), vbuf_render::need_pipeline, pipe_rasterizer_state::offset_ccw, pipe_rasterizer_state::offset_cw, PIPE_POLYGON_MODE_FILL, draw_context::pipeline, pipe_rasterizer_state::point_size, pipe_rasterizer_state::point_smooth, draw_context::point_sprite, pipe_rasterizer_state::point_sprite, points(), pipe_rasterizer_state::poly_stipple_enable, draw_context::pstipple, draw_context::render, triangles(), TRUE, draw_context::wide_line_threshold, and draw_context::wide_point_threshold.

00067 {
00068    /* If the driver has overridden this, use that version: 
00069     */
00070    if (draw->render &&
00071        draw->render->need_pipeline) 
00072    {
00073       return draw->render->need_pipeline( draw->render,
00074                                           rasterizer,
00075                                           prim );
00076    }
00077 
00078    /* Don't have to worry about triangles turning into lines/points
00079     * and triggering the pipeline, because we have to trigger the
00080     * pipeline *anyway* if unfilled mode is active.
00081     */
00082    if (lines(prim)) 
00083    {
00084       /* line stipple */
00085       if (rasterizer->line_stipple_enable && draw->pipeline.line_stipple)
00086          return TRUE;
00087 
00088       /* wide lines */
00089       if (rasterizer->line_width > draw->pipeline.wide_line_threshold)
00090          return TRUE;
00091 
00092       /* AA lines */
00093       if (rasterizer->line_smooth && draw->pipeline.aaline)
00094          return TRUE;
00095    }
00096 
00097    if (points(prim))
00098    {
00099       /* large points */
00100       if (rasterizer->point_size > draw->pipeline.wide_point_threshold)
00101          return TRUE;
00102 
00103       /* AA points */
00104       if (rasterizer->point_smooth && draw->pipeline.aapoint)
00105          return TRUE;
00106 
00107       /* point sprites */
00108       if (rasterizer->point_sprite && draw->pipeline.point_sprite)
00109          return TRUE;
00110    }
00111 
00112 
00113    if (triangles(prim)) 
00114    {
00115       /* polygon stipple */
00116       if (rasterizer->poly_stipple_enable && draw->pipeline.pstipple)
00117          return TRUE;
00118 
00119       /* unfilled polygons */
00120       if (rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
00121           rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL)
00122          return TRUE;
00123       
00124       /* polygon offset */
00125       if (rasterizer->offset_cw || rasterizer->offset_ccw)
00126          return TRUE;
00127 
00128       /* two-side lighting */
00129       if (rasterizer->light_twoside)
00130          return TRUE;
00131    }
00132 
00133    /* polygon cull - this is difficult - hardware can cull just fine
00134     * most of the time (though sometimes CULL_NEITHER is unsupported.
00135     * 
00136     * Generally this isn't a reason to require the pipeline, though.
00137     *
00138    if (rasterizer->cull_mode)
00139       return TRUE;
00140     */
00141 
00142    return FALSE;
00143 }

struct draw_stage* draw_validate_stage ( struct draw_context draw  )  [read]

Create validate pipeline stage.

Definition at line 314 of file draw_pipe_validate.c.

References CALLOC_STRUCT, draw_stage::destroy, draw_stage::draw, draw_stage::flush, draw_stage::line, draw_stage::next, draw_stage::point, draw_stage::reset_stipple_counter, draw_stage::tri, validate_destroy(), validate_flush(), validate_line(), validate_point(), validate_reset_stipple_counter(), and validate_tri().

00315 {
00316    struct draw_stage *stage = CALLOC_STRUCT(draw_stage);
00317    if (stage == NULL)
00318       return NULL;
00319 
00320    stage->draw = draw;
00321    stage->next = NULL;
00322    stage->point = validate_point;
00323    stage->line = validate_line;
00324    stage->tri = validate_tri;
00325    stage->flush = validate_flush;
00326    stage->reset_stipple_counter = validate_reset_stipple_counter;
00327    stage->destroy = validate_destroy;
00328 
00329    return stage;
00330 }

static boolean lines ( unsigned  prim  )  [static]

Definition at line 43 of file draw_pipe_validate.c.

References PIPE_PRIM_LINE_LOOP, PIPE_PRIM_LINE_STRIP, and PIPE_PRIM_LINES.

00044 {
00045    return (prim == PIPE_PRIM_LINES ||
00046            prim == PIPE_PRIM_LINE_STRIP ||
00047            prim == PIPE_PRIM_LINE_LOOP);
00048 }

static boolean points ( unsigned  prim  )  [static]

Definition at line 38 of file draw_pipe_validate.c.

References PIPE_PRIM_POINTS.

00039 {
00040    return (prim == PIPE_PRIM_POINTS);
00041 }

static boolean triangles ( unsigned  prim  )  [static]

Definition at line 50 of file draw_pipe_validate.c.

References PIPE_PRIM_TRIANGLES.

00051 {
00052    return prim >= PIPE_PRIM_TRIANGLES;
00053 }

static void validate_destroy ( struct draw_stage stage  )  [static]

Definition at line 305 of file draw_pipe_validate.c.

References FREE.

00306 {
00307    FREE( stage );
00308 }

static void validate_flush ( struct draw_stage stage,
unsigned  flags 
) [static]

Definition at line 295 of file draw_pipe_validate.c.

References draw_stage::flush, and draw_stage::next.

00297 {
00298    /* May need to pass a backend flush on to the rasterize stage.
00299     */
00300    if (stage->next)
00301       stage->next->flush( stage->next, flags );
00302 }

static void validate_line ( struct draw_stage stage,
struct prim_header header 
) [static]

Definition at line 275 of file draw_pipe_validate.c.

References draw_stage::line, and validate_pipeline().

00277 {
00278    struct draw_stage *pipeline = validate_pipeline( stage );
00279    pipeline->line( pipeline, header );
00280 }

static struct draw_stage* validate_pipeline ( struct draw_stage stage  )  [static, read]

Rebuild the rendering pipeline.

Definition at line 150 of file draw_pipe_validate.c.

References draw_context::aaline, draw_context::aapoint, draw_context::bypass_clipping, draw_context::clip, draw_context::cull, pipe_rasterizer_state::cull_mode, draw_stage::draw, draw, FALSE, pipe_rasterizer_state::fill_ccw, pipe_rasterizer_state::fill_cw, draw_context::first, draw_context::flatshade, pipe_rasterizer_state::flatshade, pipe_rasterizer_state::light_twoside, pipe_rasterizer_state::line_smooth, draw_context::line_stipple, pipe_rasterizer_state::line_stipple_enable, pipe_rasterizer_state::line_width, draw_stage::next, draw_context::offset, pipe_rasterizer_state::offset_ccw, pipe_rasterizer_state::offset_cw, PIPE_POLYGON_MODE_FILL, draw_context::pipeline, pipe_rasterizer_state::point_size, pipe_rasterizer_state::point_smooth, draw_context::point_sprite, pipe_rasterizer_state::point_sprite, pipe_rasterizer_state::poly_stipple_enable, draw_context::pstipple, draw_context::rasterize, draw_context::rasterizer, draw_context::stipple, TRUE, draw_context::twoside, draw_context::unfilled, draw_context::wide_line, draw_context::wide_line_threshold, draw_context::wide_point, and draw_context::wide_point_threshold.

00151 {
00152    struct draw_context *draw = stage->draw;
00153    struct draw_stage *next = draw->pipeline.rasterize;
00154    int need_det = 0;
00155    int precalc_flat = 0;
00156    boolean wide_lines, wide_points;
00157 
00158    /* Set the validate's next stage to the rasterize stage, so that it
00159     * can be found later if needed for flushing.
00160     */
00161    stage->next = next;
00162 
00163    /* drawing wide lines? */
00164    wide_lines = (draw->rasterizer->line_width > draw->pipeline.wide_line_threshold
00165                  && !draw->rasterizer->line_smooth);
00166 
00167    /* drawing large points? */
00168    if (draw->rasterizer->point_sprite && draw->pipeline.point_sprite)
00169       wide_points = TRUE;
00170    else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
00171       wide_points = FALSE;
00172    else if (draw->rasterizer->point_size > draw->pipeline.wide_point_threshold)
00173       wide_points = TRUE;
00174    else
00175       wide_points = FALSE;
00176 
00177    /*
00178     * NOTE: we build up the pipeline in end-to-start order.
00179     *
00180     * TODO: make the current primitive part of the state and build
00181     * shorter pipelines for lines & points.
00182     */
00183 
00184    if (draw->rasterizer->line_smooth && draw->pipeline.aaline) {
00185       draw->pipeline.aaline->next = next;
00186       next = draw->pipeline.aaline;
00187    }
00188 
00189    if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) {
00190       draw->pipeline.aapoint->next = next;
00191       next = draw->pipeline.aapoint;
00192    }
00193 
00194    if (wide_lines) {
00195       draw->pipeline.wide_line->next = next;
00196       next = draw->pipeline.wide_line;
00197       precalc_flat = 1;
00198    }
00199 
00200    if (wide_points || draw->rasterizer->point_sprite) {
00201       draw->pipeline.wide_point->next = next;
00202       next = draw->pipeline.wide_point;
00203    }
00204 
00205    if (draw->rasterizer->line_stipple_enable && draw->pipeline.line_stipple) {
00206       draw->pipeline.stipple->next = next;
00207       next = draw->pipeline.stipple;
00208       precalc_flat = 1;         /* only needed for lines really */
00209    }
00210 
00211    if (draw->rasterizer->poly_stipple_enable
00212        && draw->pipeline.pstipple) {
00213       draw->pipeline.pstipple->next = next;
00214       next = draw->pipeline.pstipple;
00215    }
00216 
00217    if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
00218        draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) {
00219       draw->pipeline.unfilled->next = next;
00220       next = draw->pipeline.unfilled;
00221       precalc_flat = 1;         /* only needed for triangles really */
00222       need_det = 1;
00223    }
00224 
00225    if (draw->rasterizer->flatshade && precalc_flat) {
00226       draw->pipeline.flatshade->next = next;
00227       next = draw->pipeline.flatshade;
00228    }
00229          
00230    if (draw->rasterizer->offset_cw ||
00231        draw->rasterizer->offset_ccw) {
00232       draw->pipeline.offset->next = next;
00233       next = draw->pipeline.offset;
00234       need_det = 1;
00235    }
00236 
00237    if (draw->rasterizer->light_twoside) {
00238       draw->pipeline.twoside->next = next;
00239       next = draw->pipeline.twoside;
00240       need_det = 1;
00241    }
00242 
00243    /* Always run the cull stage as we calculate determinant there
00244     * also.  
00245     *
00246     * This can actually be a win as culling out the triangles can lead
00247     * to less work emitting vertices, smaller vertex buffers, etc.
00248     * It's difficult to say whether this will be true in general.
00249     */
00250    if (need_det || draw->rasterizer->cull_mode) {
00251       draw->pipeline.cull->next = next;
00252       next = draw->pipeline.cull;
00253    }
00254 
00255    /* Clip stage
00256     */
00257    if (!draw->bypass_clipping)
00258    {
00259       draw->pipeline.clip->next = next;
00260       next = draw->pipeline.clip;
00261    }
00262 
00263    
00264    draw->pipeline.first = next;
00265    return next;
00266 }

static void validate_point ( struct draw_stage stage,
struct prim_header header 
) [static]

Definition at line 282 of file draw_pipe_validate.c.

References draw_stage::point, and validate_pipeline().

00284 {
00285    struct draw_stage *pipeline = validate_pipeline( stage );
00286    pipeline->point( pipeline, header );
00287 }

static void validate_reset_stipple_counter ( struct draw_stage stage  )  [static]

Definition at line 289 of file draw_pipe_validate.c.

References draw_stage::reset_stipple_counter, and validate_pipeline().

00290 {
00291    struct draw_stage *pipeline = validate_pipeline( stage );
00292    pipeline->reset_stipple_counter( pipeline );
00293 }

static void validate_tri ( struct draw_stage stage,
struct prim_header header 
) [static]

Definition at line 268 of file draw_pipe_validate.c.

References draw_stage::tri, and validate_pipeline().

00270 {
00271    struct draw_stage *pipeline = validate_pipeline( stage );
00272    pipeline->tri( pipeline, header );
00273 }


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