Maintain cliprect (scissor) info in sp_state_derived.c.
authorBrian <brian.paul@tungstengraphics.com>
Fri, 27 Jul 2007 16:21:34 +0000 (10:21 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Fri, 27 Jul 2007 16:21:34 +0000 (10:21 -0600)
The cliprect depends on the scissor rect (if enabled), otherwise the drawing
surface bounds.

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

index 8871b45d4fff6ace48deb77dcbb048575f7d34b7..3c379c9091add1e5f04f2ae6a48b0e7310574f2b 100644 (file)
@@ -117,6 +117,9 @@ struct softpipe_context {
    GLubyte stipple_masks[16][16];
 #endif
 
+   /** Derived from scissor and surface bounds: */
+   struct pipe_scissor_state cliprect;
+
    GLuint occlusion_counter;
 
    GLuint line_stipple_counter;
index 8f4fa41f447084f6ef67fc239703ab2dcd74dce3..d18f4f341410928bbc1bc36611a067028997246c 100644 (file)
@@ -91,8 +91,6 @@ struct setup_stage {
       GLuint y_flags;
       GLuint mask;     /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */
    } span;
-
-   struct pipe_scissor_state scissor;
 };
 
 
@@ -112,21 +110,22 @@ static inline struct setup_stage *setup_stage( struct draw_stage *stage )
 static INLINE void
 quad_clip(struct setup_stage *setup)
 {
-   if (setup->quad.x0 >= setup->scissor.maxx ||
-       setup->quad.y0 >= setup->scissor.maxy ||
-       setup->quad.x0 + 1 < setup->scissor.minx ||
-       setup->quad.y0 + 1 < setup->scissor.miny) {
+   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) {
       /* totally clipped */
       setup->quad.mask = 0x0;
       return;
    }
-   if (setup->quad.x0 < setup->scissor.minx)
+   if (setup->quad.x0 < sp->cliprect.minx)
       setup->quad.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT);
-   if (setup->quad.y0 < setup->scissor.miny)
+   if (setup->quad.y0 < sp->cliprect.miny)
       setup->quad.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT);
-   if (setup->quad.x0 == setup->scissor.maxx - 1)
+   if (setup->quad.x0 == sp->cliprect.maxx - 1)
       setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT);
-   if (setup->quad.y0 == setup->scissor.maxy - 1)
+   if (setup->quad.y0 == sp->cliprect.maxy - 1)
       setup->quad.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT);
 }
 
@@ -1031,27 +1030,6 @@ static void setup_begin( struct draw_stage *stage )
 
    setup->quad.nr_attrs = setup->softpipe->nr_frag_attrs;
 
-   /* compute scissor/drawing bounds.
-    * XXX we should probably move this into the sp_state_derived.c file
-    * and only compute when scissor or setup state changes.
-    */
-   {
-      const struct softpipe_context *sp = setup->softpipe;
-      const struct pipe_surface *surf = sp->cbuf;
-      if (sp->setup.scissor) {
-         setup->scissor.minx = MAX2(sp->scissor.minx, 0);
-         setup->scissor.miny = MAX2(sp->scissor.miny, 0);
-         setup->scissor.maxx = MIN2(sp->scissor.maxx, surf->width - 1);
-         setup->scissor.maxy = MIN2(sp->scissor.maxy, surf->height - 1);
-      }
-      else {
-         setup->scissor.minx = 0;
-         setup->scissor.miny = 0;
-         setup->scissor.maxx = surf->width - 1;
-         setup->scissor.maxy = surf->height - 1;
-      }
-   }
-
    /*
     * XXX this is where we might map() the renderbuffers to begin
     * s/w rendering.
index 26083c29628e58df8b240428ddb9b71a98e6b9c2..9572890afec8c5785e8cf99466fce78000f265e6 100644 (file)
@@ -163,6 +163,41 @@ static void calculate_vertex_layout( struct softpipe_context *softpipe )
 }
 
 
+/**
+ * Recompute cliprect from scissor bounds, scissor enable and surface size.
+ */
+static void
+compute_cliprect(struct softpipe_context *sp)
+{
+   GLint surfWidth, surfHeight;
+
+   if (sp->framebuffer.num_cbufs > 0) {
+      surfWidth = sp->framebuffer.cbufs[0]->width;
+      surfHeight = sp->framebuffer.cbufs[0]->height;
+   }
+   else {
+      /* no surface? */
+      surfWidth = sp->scissor.maxx;
+      surfHeight = sp->scissor.maxy;
+   }
+
+   if (sp->setup.scissor) {
+      /* 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);
+   }
+   else {
+      /* clip to surface bounds */
+      sp->cliprect.minx = 0;
+      sp->cliprect.miny = 0;
+      sp->cliprect.maxx = surfWidth - 1;
+      sp->cliprect.maxy = surfHeight - 1;
+   }
+}
+
+
 /* Hopefully this will remain quite simple, otherwise need to pull in
  * something like the state tracker mechanism.
  */
@@ -171,6 +206,11 @@ void softpipe_update_derived( struct softpipe_context *softpipe )
    if (softpipe->dirty & (SP_NEW_SETUP | SP_NEW_FS))
       calculate_vertex_layout( softpipe );
 
+   if (softpipe->dirty & (SP_NEW_SCISSOR |
+                          SP_NEW_STENCIL |
+                          SP_NEW_FRAMEBUFFER))
+      compute_cliprect(softpipe);
+
    if (softpipe->dirty & (SP_NEW_BLEND |
                           SP_NEW_DEPTH_TEST |
                           SP_NEW_ALPHA_TEST |