diff options
| author | Brian <brian.paul@tungstengraphics.com> | 2007-07-25 15:48:09 -0600 | 
|---|---|---|
| committer | Brian <brian.paul@tungstengraphics.com> | 2007-07-25 15:48:09 -0600 | 
| commit | 0360b49afbcd839f99ba0745d01cf9dc5be4d122 (patch) | |
| tree | f2746f209352f65cec01360ef88c2a018eb8b68b /src/mesa | |
| parent | 1f6b4b0f75d7cd7306e6aa24c27fd478f6b6c52d (diff) | |
Implement line stippling.
Also added draw_stage::reset_line_stipple().  There may be a better way
of doing that though.
Diffstat (limited to 'src/mesa')
| -rw-r--r-- | src/mesa/pipe/draw/draw_clip.c | 7 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_cull.c | 6 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_flatshade.c | 7 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_offset.c | 7 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_private.h | 2 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_twoside.c | 7 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_unfilled.c | 7 | ||||
| -rw-r--r-- | src/mesa/pipe/draw/draw_vb.c | 8 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_context.h | 4 | ||||
| -rw-r--r-- | src/mesa/pipe/softpipe/sp_prim_setup.c | 38 | 
10 files changed, 90 insertions, 3 deletions
| diff --git a/src/mesa/pipe/draw/draw_clip.c b/src/mesa/pipe/draw/draw_clip.c index b220cc3643..f8bacf8a81 100644 --- a/src/mesa/pipe/draw/draw_clip.c +++ b/src/mesa/pipe/draw/draw_clip.c @@ -433,6 +433,12 @@ static void clip_end( struct draw_stage *stage )  } +static void clip_reset_stipple_counter( struct draw_stage *stage ) +{ +   stage->next->reset_stipple_counter( stage->next ); +} + +  /**   * Allocate a new clipper stage.   * \return pointer to new stage object @@ -449,6 +455,7 @@ struct draw_stage *draw_clip_stage( struct draw_context *draw )     clipper->stage.line = clip_line;     clipper->stage.tri = clip_tri;     clipper->stage.end = clip_end; +   clipper->stage.reset_stipple_counter = clip_reset_stipple_counter;     clipper->plane = draw->plane; diff --git a/src/mesa/pipe/draw/draw_cull.c b/src/mesa/pipe/draw/draw_cull.c index e563f9f45f..8b2ac5ea5f 100644 --- a/src/mesa/pipe/draw/draw_cull.c +++ b/src/mesa/pipe/draw/draw_cull.c @@ -111,6 +111,11 @@ static void cull_end( struct draw_stage *stage )  } +static void cull_reset_stipple_counter( struct draw_stage *stage ) +{ +   stage->next->reset_stipple_counter( stage->next ); +} +  /**   * Create a new polygon culling stage.   */ @@ -127,6 +132,7 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw )     cull->stage.line = cull_line;     cull->stage.tri = cull_tri;     cull->stage.end = cull_end; +   cull->stage.reset_stipple_counter = cull_reset_stipple_counter;     return &cull->stage;  } diff --git a/src/mesa/pipe/draw/draw_flatshade.c b/src/mesa/pipe/draw/draw_flatshade.c index 09547865fa..cf5e762079 100644 --- a/src/mesa/pipe/draw/draw_flatshade.c +++ b/src/mesa/pipe/draw/draw_flatshade.c @@ -130,6 +130,12 @@ static void flatshade_end( struct draw_stage *stage )  } +static void flatshade_reset_stipple_counter( struct draw_stage *stage ) +{ +   stage->next->reset_stipple_counter( stage->next ); +} + +  /**   * Create flatshading drawing stage.   */ @@ -146,6 +152,7 @@ struct draw_stage *draw_flatshade_stage( struct draw_context *draw )     flatshade->stage.line = flatshade_line;     flatshade->stage.tri = flatshade_tri;     flatshade->stage.end = flatshade_end; +   flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter;     flatshade->lookup = draw->vf_attr_to_slot; diff --git a/src/mesa/pipe/draw/draw_offset.c b/src/mesa/pipe/draw/draw_offset.c index 1a7f56d0c5..9f66566353 100644 --- a/src/mesa/pipe/draw/draw_offset.c +++ b/src/mesa/pipe/draw/draw_offset.c @@ -145,6 +145,12 @@ static void offset_end( struct draw_stage *stage )  } +static void offset_reset_stipple_counter( struct draw_stage *stage ) +{ +   stage->next->reset_stipple_counter( stage->next ); +} + +  /**   * Create polygon offset drawing stage.   */ @@ -161,6 +167,7 @@ struct draw_stage *draw_offset_stage( struct draw_context *draw )     offset->stage.line = offset_line;     offset->stage.tri = offset_tri;     offset->stage.end = offset_end; +   offset->stage.reset_stipple_counter = offset_reset_stipple_counter;     return &offset->stage;  } diff --git a/src/mesa/pipe/draw/draw_private.h b/src/mesa/pipe/draw/draw_private.h index 573b5bf588..3dfaa0581d 100644 --- a/src/mesa/pipe/draw/draw_private.h +++ b/src/mesa/pipe/draw/draw_private.h @@ -98,6 +98,8 @@ struct draw_stage  		struct prim_header * );     void (*end)( struct draw_stage * ); + +   void (*reset_stipple_counter)( struct draw_stage * );  }; diff --git a/src/mesa/pipe/draw/draw_twoside.c b/src/mesa/pipe/draw/draw_twoside.c index 9f26335fb6..fdda6b362f 100644 --- a/src/mesa/pipe/draw/draw_twoside.c +++ b/src/mesa/pipe/draw/draw_twoside.c @@ -139,6 +139,12 @@ static void twoside_end( struct draw_stage *stage )  } +static void twoside_reset_stipple_counter( struct draw_stage *stage ) +{ +   stage->next->reset_stipple_counter( stage->next ); +} + +  /**   * Create twoside pipeline stage.   */ @@ -155,6 +161,7 @@ struct draw_stage *draw_twoside_stage( struct draw_context *draw )     twoside->stage.line = twoside_line;     twoside->stage.tri = twoside_tri;     twoside->stage.end = twoside_end; +   twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter;     twoside->lookup = draw->vf_attr_to_slot; diff --git a/src/mesa/pipe/draw/draw_unfilled.c b/src/mesa/pipe/draw/draw_unfilled.c index f0aee58333..82e8775f59 100644 --- a/src/mesa/pipe/draw/draw_unfilled.c +++ b/src/mesa/pipe/draw/draw_unfilled.c @@ -156,6 +156,12 @@ static void unfilled_end( struct draw_stage *stage )  } +static void unfilled_reset_stipple_counter( struct draw_stage *stage ) +{ +   stage->next->reset_stipple_counter( stage->next ); +} + +  /**   * Create unfilled triangle stage.   */ @@ -173,6 +179,7 @@ struct draw_stage *draw_unfilled_stage( struct draw_context *draw )     unfilled->stage.line = unfilled_line;     unfilled->stage.tri = unfilled_tri;     unfilled->stage.end = unfilled_end; +   unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter;     return &unfilled->stage;  } diff --git a/src/mesa/pipe/draw/draw_vb.c b/src/mesa/pipe/draw/draw_vb.c index ac721c589d..ac126c5baa 100644 --- a/src/mesa/pipe/draw/draw_vb.c +++ b/src/mesa/pipe/draw/draw_vb.c @@ -151,12 +151,14 @@ static void draw_indexed_prim( struct draw_context *draw,  	 prim.v[0] = get_vertex( draw, elts[i + 0] );  	 prim.v[1] = get_vertex( draw, elts[i + 1] ); +         first->reset_stipple_counter( first );  	 first->line( first, &prim );        }        break;     case GL_LINE_LOOP:          if (count >= 2) { +         first->reset_stipple_counter( first );  	 for (i = 1; i < count; i++) {  	    prim.v[0] = get_vertex( draw, elts[i-1] );  	    prim.v[1] = get_vertex( draw, elts[i] );	     @@ -178,6 +180,7 @@ static void draw_indexed_prim( struct draw_context *draw,         * require more complex code here.         */        if (count >= 2) { +         first->reset_stipple_counter( first );  	 prim.v[0] = 0;  	 prim.v[1] = get_vertex( draw, elts[0] ); @@ -313,13 +316,15 @@ static void draw_prim( struct draw_context *draw,        for (i = 0; i+1 < count; i += 2) {  	 prim.v[0] = get_vertex( draw, start + i + 0 );  	 prim.v[1] = get_vertex( draw, start + i + 1 ); -       + +         first->reset_stipple_counter( first );  	 first->line( first, &prim );        }        break;     case GL_LINE_LOOP:          if (count >= 2) { +         first->reset_stipple_counter( first );  	 for (i = 1; i < count; i++) {  	    prim.v[0] = get_vertex( draw, start + i - 1 );  	    prim.v[1] = get_vertex( draw, start + i );	     @@ -334,6 +339,7 @@ static void draw_prim( struct draw_context *draw,     case GL_LINE_STRIP:        if (count >= 2) { +         first->reset_stipple_counter( first );  	 prim.v[0] = 0;  	 prim.v[1] = get_vertex( draw, start + 0 ); diff --git a/src/mesa/pipe/softpipe/sp_context.h b/src/mesa/pipe/softpipe/sp_context.h index ef1a06ccaf..8871b45d4f 100644 --- a/src/mesa/pipe/softpipe/sp_context.h +++ b/src/mesa/pipe/softpipe/sp_context.h @@ -111,12 +111,16 @@ struct softpipe_context {     GLboolean need_z;  /**< produce quad/fragment Z values? */     GLboolean need_w;  /**< produce quad/fragment W values? */ +#if 0     /* Stipple derived state:      */     GLubyte stipple_masks[16][16]; +#endif     GLuint occlusion_counter; +   GLuint line_stipple_counter; +     /** Software quad rendering pipeline */     struct {        struct quad_stage *polygon_stipple; diff --git a/src/mesa/pipe/softpipe/sp_prim_setup.c b/src/mesa/pipe/softpipe/sp_prim_setup.c index 6420fc8809..091a2343a9 100644 --- a/src/mesa/pipe/softpipe/sp_prim_setup.c +++ b/src/mesa/pipe/softpipe/sp_prim_setup.c @@ -706,6 +706,17 @@ plot(struct setup_stage *setup, GLint x, GLint y)  } +/** + * Determine whether or not to emit a line fragment by checking + * line stipple pattern. + */ +static INLINE GLuint +stipple_test(GLint counter, GLushort pattern, GLint factor) +{ +   GLint b = (counter / factor) & 0xf; +   return (1 << b) & pattern; +} +  /**   * Do setup for line rasterization, then render the line. @@ -718,6 +729,7 @@ setup_line(struct draw_stage *stage, struct prim_header *prim)     const struct vertex_header *v0 = prim->v[0];     const struct vertex_header *v1 = prim->v[1];     struct setup_stage *setup = setup_stage( stage ); +   struct softpipe_context *sp = setup->softpipe;     GLint x0 = (GLint) v0->data[0][0];     GLint x1 = (GLint) v1->data[0][0]; @@ -763,7 +775,12 @@ setup_line(struct draw_stage *stage, struct prim_header *prim)        const GLint errorDec = error - dx;        for (i = 0; i < dx; i++) { -         plot(setup, x0, y0); +         if (!sp->setup.line_stipple_enable || +             stipple_test(sp->line_stipple_counter, +                          sp->setup.line_stipple_pattern, +                          sp->setup.line_stipple_factor + 1)) { +             plot(setup, x0, y0); +         }           x0 += xstep;           if (error < 0) { @@ -773,6 +790,8 @@ setup_line(struct draw_stage *stage, struct prim_header *prim)              error += errorDec;              y0 += ystep;           } + +         sp->line_stipple_counter++;        }     }     else { @@ -783,7 +802,12 @@ setup_line(struct draw_stage *stage, struct prim_header *prim)        const GLint errorDec = error - dy;        for (i = 0; i < dy; i++) { -         plot(setup, x0, y0); +         if (!sp->setup.line_stipple_enable || +             stipple_test(sp->line_stipple_counter, +                          sp->setup.line_stipple_pattern, +                          sp->setup.line_stipple_factor + 1)) { +            plot(setup, x0, y0); +         }           y0 += ystep; @@ -794,6 +818,8 @@ setup_line(struct draw_stage *stage, struct prim_header *prim)              error += errorDec;              x0 += xstep;           } + +         sp->line_stipple_counter++;        }     } @@ -984,6 +1010,13 @@ static void setup_end( struct draw_stage *stage )  } +static void reset_stipple_counter( struct draw_stage *stage ) +{ +   struct setup_stage *setup = setup_stage(stage); +   setup->softpipe->line_stipple_counter = 0; +} + +  /**   * Create a new primitive setup/render stage.   */ @@ -998,6 +1031,7 @@ struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe )     setup->stage.line = setup_line;     setup->stage.tri = setup_tri;     setup->stage.end = setup_end; +   setup->stage.reset_stipple_counter = reset_stipple_counter;     setup->quad.coef = setup->coef; | 
