llvmpipe: avoid left-shifting a negative number.
[mesa.git] / src / gallium / drivers / llvmpipe / lp_setup_line.c
index f6e1198d03639a5a0900aa3cb231e6d3b8b9c9d4..5e26b1e9ffc08a8eca2e3b297d6428c7829f019f 100644 (file)
@@ -288,7 +288,9 @@ try_setup_line( struct lp_setup_context *setup,
    struct lp_rast_plane *plane;
    struct lp_line_info info;
    float width = MAX2(1.0, setup->line_width);
-   struct u_rect bbox;
+   const struct u_rect *scissor;
+   struct u_rect bbox, bboxpos;
+   boolean s_planes[4];
    unsigned tri_bytes;
    int x[4]; 
    int y[4];
@@ -579,10 +581,12 @@ try_setup_line( struct lp_setup_context *setup,
       return TRUE;
    }
 
+   bboxpos = bbox;
+
    /* Can safely discard negative regions:
     */
-   bbox.x0 = MAX2(bbox.x0, 0);
-   bbox.y0 = MAX2(bbox.y0, 0);
+   bboxpos.x0 = MAX2(bboxpos.x0, 0);
+   bboxpos.y0 = MAX2(bboxpos.y0, 0);
 
    nr_planes = 4;
    /*
@@ -591,11 +595,9 @@ try_setup_line( struct lp_setup_context *setup,
     */
    if (setup->scissor_test) {
       /* why not just use draw_regions */
-      struct u_rect *scissor = &setup->scissors[viewport_index];
-      nr_planes += (bbox.x0 < scissor->x0);
-      nr_planes += (bbox.x1 > scissor->x1);
-      nr_planes += (bbox.y0 < scissor->y0);
-      nr_planes += (bbox.y1 > scissor->y1);
+      scissor = &setup->scissors[viewport_index];
+      scissor_planes_needed(s_planes, &bboxpos, scissor);
+      nr_planes += s_planes[0] + s_planes[1] + s_planes[2] + s_planes[3];
    }
 
    line = lp_setup_alloc_triangle(scene,
@@ -614,8 +616,7 @@ try_setup_line( struct lp_setup_context *setup,
 
    LP_COUNT(nr_tris);
 
-   if (lp_context->active_statistics_queries &&
-       !llvmpipe_rasterization_disabled(lp_context)) {
+   if (lp_context->active_statistics_queries) {
       lp_context->pipeline_statistics.c_primitives++;
    }
 
@@ -720,34 +721,32 @@ try_setup_line( struct lp_setup_context *setup,
     * (easier to evaluate) to ordinary planes.)
     */
    if (nr_planes > 4) {
-      /* why not just use draw_regions */
-      struct u_rect *scissor = &setup->scissors[viewport_index];
       struct lp_rast_plane *plane_s = &plane[4];
 
-      if (bbox.x0 < scissor->x0) {
-         plane_s->dcdx = -1 << 8;
+      if (s_planes[0]) {
+         plane_s->dcdx = ~0U << 8;
          plane_s->dcdy = 0;
          plane_s->c = (1-scissor->x0) << 8;
          plane_s->eo = 1 << 8;
          plane_s++;
       }
-      if (bbox.x1 > scissor->x1) {
+      if (s_planes[1]) {
          plane_s->dcdx = 1 << 8;
          plane_s->dcdy = 0;
          plane_s->c = (scissor->x1+1) << 8;
          plane_s->eo = 0 << 8;
          plane_s++;
       }
-      if (bbox.y0 < scissor->y0) {
+      if (s_planes[2]) {
          plane_s->dcdx = 0;
          plane_s->dcdy = 1 << 8;
          plane_s->c = (1-scissor->y0) << 8;
          plane_s->eo = 1 << 8;
          plane_s++;
       }
-      if (bbox.y1 > scissor->y1) {
+      if (s_planes[3]) {
          plane_s->dcdx = 0;
-         plane_s->dcdy = -1 << 8;
+         plane_s->dcdy = ~0U << 8;
          plane_s->c = (scissor->y1+1) << 8;
          plane_s->eo = 0;
          plane_s++;
@@ -755,28 +754,37 @@ try_setup_line( struct lp_setup_context *setup,
       assert(plane_s == &plane[nr_planes]);
    }
 
-   return lp_setup_bin_triangle(setup, line, &bbox, nr_planes, viewport_index);
+   return lp_setup_bin_triangle(setup, line, &bbox, &bboxpos, nr_planes, viewport_index);
 }
 
 
-static void lp_setup_linestruct lp_setup_context *setup,
-                           const float (*v0)[4],
-                           const float (*v1)[4] )
+static void lp_setup_line_discard(struct lp_setup_context *setup,
+                                  const float (*v0)[4],
+                                  const float (*v1)[4])
 {
-   if (!try_setup_line( setup, v0, v1 ))
-   {
+}
+
+static void lp_setup_line(struct lp_setup_context *setup,
+                          const float (*v0)[4],
+                          const float (*v1)[4])
+{
+   if (!try_setup_line(setup, v0, v1)) {
       if (!lp_setup_flush_and_restart(setup))
          return;
 
-      if (!try_setup_line( setup, v0, v1 ))
+      if (!try_setup_line(setup, v0, v1))
          return;
    }
 }
 
 
-void lp_setup_choose_line( struct lp_setup_context *setup ) 
+void lp_setup_choose_line(struct lp_setup_context *setup)
 { 
-   setup->line = lp_setup_line;
+   if (setup->rasterizer_discard) {
+      setup->line = lp_setup_line_discard;
+   } else {
+      setup->line = lp_setup_line;
+   }
 }