Clip triangles against softpipe->cliprect which includes scissor and surface bounds.
authorBrian <brian.paul@tungstengraphics.com>
Fri, 27 Jul 2007 16:50:35 +0000 (10:50 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Fri, 27 Jul 2007 16:50:35 +0000 (10:50 -0600)
This prevents rendering out of bounds when the viewport is partially outside the surface bounds.

src/mesa/pipe/softpipe/sp_prim_setup.c
src/mesa/pipe/softpipe/sp_state_derived.c

index 63568404dc03d9a3a895cf3e1e5326132b664ebe..d07bd5381deac221a85081d70b03f69f28a071e7 100644 (file)
@@ -110,28 +110,31 @@ static inline struct setup_stage *setup_stage( struct draw_stage *stage )
 static INLINE void
 quad_clip(struct setup_stage *setup)
 {
-   const struct softpipe_context *sp = setup->softpipe;
-   if (setup->quad.x0 >= sp->cliprect.maxx ||
-       setup->quad.y0 >= sp->cliprect.maxy ||
-       setup->quad.x0 + 1 < sp->cliprect.minx ||
-       setup->quad.y0 + 1 < sp->cliprect.miny) {
+   const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect;
+   if (setup->quad.x0 >= cliprect->maxx ||
+       setup->quad.y0 >= cliprect->maxy ||
+       setup->quad.x0 + 1 < cliprect->minx ||
+       setup->quad.y0 + 1 < cliprect->miny) {
       /* totally clipped */
       setup->quad.mask = 0x0;
       return;
    }
-   if (setup->quad.x0 < sp->cliprect.minx)
+   if (setup->quad.x0 < cliprect->minx)
       setup->quad.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT);
-   if (setup->quad.y0 < sp->cliprect.miny)
+   if (setup->quad.y0 < cliprect->miny)
       setup->quad.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT);
-   if (setup->quad.x0 == sp->cliprect.maxx - 1)
+   if (setup->quad.x0 == cliprect->maxx - 1)
       setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT);
-   if (setup->quad.y0 == sp->cliprect.maxy - 1)
+   if (setup->quad.y0 == cliprect->maxy - 1)
       setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT);
 }
 
 
 /**
  * Emit/render a quad.
+ * Called during point/line rendering.  For triangles, we call
+ * run_shader_block() which doesn't do clipping (since clipping is
+ * done at a higher level for tris).
  * This passes the quad to the first stage of per-fragment operations.
  */
 static INLINE void
@@ -162,11 +165,11 @@ static inline GLint block( GLint x )
 static void run_shader_block( struct setup_stage *setup, 
                              GLint x, GLint y, GLuint mask )
 {
+   struct softpipe_context *sp = setup->softpipe;
    setup->quad.x0 = x;
    setup->quad.y0 = y;
    setup->quad.mask = mask;
-
-   quad_emit(setup);
+   sp->quad.first->run(sp->quad.first, &setup->quad);
 }
 
 
@@ -501,38 +504,31 @@ static void setup_tri_edges( struct setup_stage *setup )
 
 /**
  * Render the upper or lower half of a triangle.
- * Scissoring is applied here too.
+ * Scissoring/cliprect is applied here too.
  */
 static void subtriangle( struct setup_stage *setup,
                         struct edge *eleft,
                         struct edge *eright,
                         GLuint lines )
 {
+   const struct pipe_scissor_state *cliprect = &setup->softpipe->cliprect;
    GLint y, start_y, finish_y;
    GLint sy = (GLint)eleft->sy;
 
    assert((GLint)eleft->sy == (GLint) eright->sy);
-   assert((GLint)eleft->sy >= 0);      /* catch bug in x64? */
 
-   /* scissor y:
-    */
-   if (setup->softpipe->setup.scissor) {
-      start_y = sy;
-      finish_y = start_y + lines;
+   /* clip top/bottom */
+   start_y = sy;
+   finish_y = sy + lines;
 
-      if (start_y < setup->softpipe->scissor.miny) 
-        start_y = setup->softpipe->scissor.miny;
+   if (start_y < cliprect->miny)
+      start_y = cliprect->miny;
 
-      if (finish_y > setup->softpipe->scissor.maxy) 
-        finish_y = setup->softpipe->scissor.maxy;
+   if (finish_y > cliprect->maxy)
+      finish_y = cliprect->maxy;
 
-      start_y -= sy;
-      finish_y -= sy;
-   }
-   else {
-      start_y = 0;
-      finish_y = lines;
-   }
+   start_y -= sy;
+   finish_y -= sy;
 
    /*
    _mesa_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y);  
@@ -549,15 +545,11 @@ static void subtriangle( struct setup_stage *setup,
       GLint left = (GLint)(eleft->sx + y * eleft->dxdy);
       GLint right = (GLint)(eright->sx + y * eright->dxdy);
 
-      /* scissor x: 
-       */
-      if (setup->softpipe->setup.scissor) {
-        if (left  < setup->softpipe->scissor.minx) 
-           left  = setup->softpipe->scissor.minx;
-
-        if (right > setup->softpipe->scissor.maxx) 
-           right = setup->softpipe->scissor.maxx;
-      }
+      /* clip left/right */
+      if (left < cliprect->minx)
+         left = cliprect->minx;
+      if (right > cliprect->maxx)
+         right = cliprect->maxx;
 
       if (left < right) {
         GLint _y = sy+y;
@@ -875,8 +867,8 @@ setup_point(struct draw_stage *stage, struct prim_header *prim)
 {
    struct setup_stage *setup = setup_stage( stage );
    /*XXX this should be a vertex attrib! */
-   GLfloat halfSize = 0.5 * setup->softpipe->setup.point_size;
-   GLboolean round = setup->softpipe->setup.point_smooth;
+   const GLfloat halfSize = 0.5 * setup->softpipe->setup.point_size;
+   const GLboolean round = setup->softpipe->setup.point_smooth;
    const struct vertex_header *v0 = prim->v[0];
    const GLfloat x = v0->data[FRAG_ATTRIB_WPOS][0];
    const GLfloat y = v0->data[FRAG_ATTRIB_WPOS][1];
index 9572890afec8c5785e8cf99466fce78000f265e6..e1faaed93ce759cef26962eb03b54b3b1a32d42a 100644 (file)
@@ -185,15 +185,15 @@ compute_cliprect(struct softpipe_context *sp)
       /* clip to scissor rect */
       sp->cliprect.minx = MAX2(sp->scissor.minx, 0);
       sp->cliprect.miny = MAX2(sp->scissor.miny, 0);
-      sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth - 1);
-      sp->cliprect.maxy = MIN2(sp->scissor.maxy, surfHeight - 1);
+      sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth);
+      sp->cliprect.maxy = MIN2(sp->scissor.maxy, surfHeight);
    }
    else {
       /* clip to surface bounds */
       sp->cliprect.minx = 0;
       sp->cliprect.miny = 0;
-      sp->cliprect.maxx = surfWidth - 1;
-      sp->cliprect.maxy = surfHeight - 1;
+      sp->cliprect.maxx = surfWidth;
+      sp->cliprect.maxy = surfHeight;
    }
 }