draw: add support for num_samples + sample_stride to the image paths
[mesa.git] / src / gallium / drivers / llvmpipe / lp_state_rasterizer.c
index 6df3ef25b0ee8a024d46966652f3f1717b033548..ef6958d99feac5e6d044cf5435e73f03af8b90d4 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2007 VMware, Inc.
  * All Rights Reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +18,7 @@
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "lp_setup.h"
 #include "draw/draw_context.h"
 
+struct lp_rast_state {
+   struct pipe_rasterizer_state lp_state;
+   struct pipe_rasterizer_state draw_state;
+};
+
+/* State which might be handled in either the draw module or locally.
+ * This function is used to turn that state off in one of the two
+ * places.
+ */
+static void
+clear_flags(struct pipe_rasterizer_state *rast)
+{
+   rast->light_twoside = 0;
+   rast->offset_tri = 0;
+   rast->offset_line = 0;
+   rast->offset_point = 0;
+   rast->offset_units = 0.0f;
+   rast->offset_scale = 0.0f;
+}
 
 
-void *
+
+static void *
 llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
                                  const struct pipe_rasterizer_state *rast)
 {
-   return mem_dup(rast, sizeof(*rast));
+   boolean need_pipeline;
+
+   /* Partition rasterizer state into what we want the draw module to
+    * handle, and what we'll look after ourselves.
+    */
+   struct lp_rast_state *state = MALLOC_STRUCT(lp_rast_state);
+   if (!state)
+      return NULL;
+
+   memcpy(&state->draw_state, rast, sizeof *rast);
+   memcpy(&state->lp_state, rast, sizeof *rast);
+
+   /* We rely on draw module to do unfilled polyons, AA lines and
+    * points and stipple.
+    * 
+    * Over time, reduce this list of conditions, and expand the list
+    * of flags which get cleared in clear_flags().
+    */
+   need_pipeline = (rast->fill_front != PIPE_POLYGON_MODE_FILL ||
+                   rast->fill_back != PIPE_POLYGON_MODE_FILL ||
+                   rast->point_smooth ||
+                   rast->line_smooth ||
+                   rast->line_stipple_enable ||
+                   rast->poly_stipple_enable);
+
+   /* If not using the pipeline, clear out the flags which we can
+    * handle ourselves.  If we *are* using the pipeline, do everything
+    * on the pipeline and clear those flags on our internal copy of
+    * the state.
+    */
+   if (need_pipeline)
+      clear_flags(&state->lp_state);
+   else
+      clear_flags(&state->draw_state);
+
+   return state;
 }
 
-void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
-                                    void *rasterizer)
-{
-   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 
-   if (llvmpipe->rasterizer == rasterizer)
-      return;
 
-   /* pass-through to draw module */
-   draw_set_rasterizer_state(llvmpipe->draw, rasterizer);
+static void
+llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
+{
+   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+   const struct lp_rast_state *state =
+      (const struct lp_rast_state *) handle;
 
-   llvmpipe->rasterizer = rasterizer;
+   if (state) {
+      llvmpipe->rasterizer = &state->lp_state;
+      draw_set_rasterizer_state(llvmpipe->draw, &state->draw_state, handle);
 
-   /* Note: we can immediately set the triangle state here and
-    * not worry about binning because we handle culling during
-    * triangle setup, not when rasterizing the bins.
-    */
-   if (llvmpipe->rasterizer) {
+      /* XXX: just pass lp_state directly to setup.
+       */
       lp_setup_set_triangle_state( llvmpipe->setup,
-                   llvmpipe->rasterizer->cull_mode,
-                   llvmpipe->rasterizer->front_winding == PIPE_WINDING_CCW,
-                   llvmpipe->rasterizer->scissor,
-                   llvmpipe->rasterizer->gl_rasterization_rules);
+                                  state->lp_state.cull_face,
+                                  state->lp_state.front_ccw,
+                                  state->lp_state.scissor,
+                                  state->lp_state.half_pixel_center,
+                                  state->lp_state.bottom_edge_rule);
+      lp_setup_set_flatshade_first( llvmpipe->setup,
+                                   state->lp_state.flatshade_first);
+      lp_setup_set_line_state( llvmpipe->setup,
+                              state->lp_state.line_width);
+      lp_setup_set_point_state( llvmpipe->setup,
+                               state->lp_state.point_size,
+                               state->lp_state.point_size_per_vertex,
+                               state->lp_state.sprite_coord_enable,
+                               state->lp_state.sprite_coord_mode);
+   }
+   else {
+      llvmpipe->rasterizer = NULL;
+      draw_set_rasterizer_state(llvmpipe->draw, NULL, handle);      
    }
 
    llvmpipe->dirty |= LP_NEW_RASTERIZER;
 }
 
-void llvmpipe_delete_rasterizer_state(struct pipe_context *pipe,
-                                      void *rasterizer)
+
+static void
+llvmpipe_delete_rasterizer_state(struct pipe_context *pipe,
+                                 void *rasterizer)
 {
    FREE( rasterizer );
 }
 
 
+
+void
+llvmpipe_init_rasterizer_funcs(struct llvmpipe_context *llvmpipe)
+{
+   llvmpipe->pipe.create_rasterizer_state = llvmpipe_create_rasterizer_state;
+   llvmpipe->pipe.bind_rasterizer_state   = llvmpipe_bind_rasterizer_state;
+   llvmpipe->pipe.delete_rasterizer_state = llvmpipe_delete_rasterizer_state;
+}