Mesa (7.8): gallium/draw: use correct rasterization state for wide/ AA points/lines

Brian Paul brianp at kemper.freedesktop.org
Mon Apr 19 14:36:29 UTC 2010


Module: Mesa
Branch: 7.8
Commit: e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7

Author: Brian Paul <brianp at vmware.com>
Date:   Mon Apr 19 08:35:53 2010 -0600

gallium/draw: use correct rasterization state for wide/AA points/lines

When points or lines are decomposed into triangles, we need to be sure
to disable polygon culling, stippling, "un-filled" modes, etc.

This patch sets the rasterization state to disable those things prior to
drawing points/lines with triangles, then restores the previous state
afterward.

The new piglit point-no-line-cull test checks this problem & solution.

---

 src/gallium/auxiliary/draw/draw_context.c          |   65 ++++++++++++++++++--
 src/gallium/auxiliary/draw/draw_context.h          |    5 +-
 src/gallium/auxiliary/draw/draw_pipe_aaline.c      |   49 +++++++++------
 src/gallium/auxiliary/draw/draw_pipe_aapoint.c     |   39 ++++++++----
 src/gallium/auxiliary/draw/draw_pipe_wide_line.c   |   34 ++++++++++-
 src/gallium/auxiliary/draw/draw_pipe_wide_point.c  |   20 ++++++
 src/gallium/auxiliary/draw/draw_private.h          |   15 ++++-
 src/gallium/drivers/i915/i915_context.c            |    2 +-
 src/gallium/drivers/i915/i915_state.c              |    3 +-
 src/gallium/drivers/llvmpipe/lp_context.c          |    2 +-
 src/gallium/drivers/llvmpipe/lp_state_rasterizer.c |   14 +++-
 src/gallium/drivers/nv50/nv50_context.c            |    2 +-
 src/gallium/drivers/r300/r300_context.c            |    2 +-
 src/gallium/drivers/r300/r300_state.c              |    2 +-
 src/gallium/drivers/softpipe/sp_context.c          |    2 +-
 src/gallium/drivers/softpipe/sp_state_rasterizer.c |    2 +-
 src/gallium/drivers/svga/svga_pipe_rasterizer.c    |    3 +-
 src/gallium/drivers/svga/svga_swtnl_draw.c         |    2 +-
 src/gallium/drivers/svga/svga_swtnl_state.c        |    3 +-
 src/mesa/state_tracker/st_context.c                |    2 +-
 src/mesa/state_tracker/st_draw_feedback.c          |    2 +-
 21 files changed, 213 insertions(+), 57 deletions(-)

diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index bb09885..18435af 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -31,6 +31,7 @@
   */
 
 
+#include "pipe/p_context.h"
 #include "util/u_memory.h"
 #include "util/u_math.h"
 #include "draw_context.h"
@@ -38,7 +39,7 @@
 #include "draw_gs.h"
 
 
-struct draw_context *draw_create( void )
+struct draw_context *draw_create( struct pipe_context *pipe )
 {
    struct draw_context *draw = CALLOC_STRUCT( draw_context );
    if (draw == NULL)
@@ -68,6 +69,8 @@ struct draw_context *draw_create( void )
    if (!draw_gs_init( draw ))
       goto fail;
 
+   draw->pipe = pipe;
+
    return draw;
 
 fail:
@@ -78,10 +81,21 @@ fail:
 
 void draw_destroy( struct draw_context *draw )
 {
+   struct pipe_context *pipe = draw->pipe;
+   int i, j;
+
    if (!draw)
       return;
 
-
+   /* free any rasterizer CSOs that we may have created.
+    */
+   for (i = 0; i < 2; i++) {
+      for (j = 0; j < 2; j++) {
+         if (draw->rasterizer_no_cull[i][j]) {
+            pipe->delete_rasterizer_state(pipe, draw->rasterizer_no_cull[i][j]);
+         }
+      }
+   }
 
    /* Not so fast -- we're just borrowing this at the moment.
     * 
@@ -123,12 +137,17 @@ void draw_set_mrd(struct draw_context *draw, double mrd)
  * This causes the drawing pipeline to be rebuilt.
  */
 void draw_set_rasterizer_state( struct draw_context *draw,
-                                const struct pipe_rasterizer_state *raster )
+                                const struct pipe_rasterizer_state *raster,
+                                void *rast_handle )
 {
-   draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
+   if (!draw->suspend_flushing) {
+      draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
 
-   draw->rasterizer = raster;
-   draw->bypass_clipping = draw->driver.bypass_clipping;
+      draw->rasterizer = raster;
+      draw->rast_handle = rast_handle;
+
+      draw->bypass_clipping = draw->driver.bypass_clipping;
+   }
 }
 
 
@@ -481,3 +500,37 @@ draw_current_shader_position_output(const struct draw_context *draw)
       return draw->gs.position_output;
    return draw->vs.position_output;
 }
+
+
+/**
+ * Return a pointer/handle for a driver/CSO rasterizer object which
+ * disabled culling, stippling, unfilled tris, etc.
+ * This is used by some pipeline stages (such as wide_point, aa_line
+ * and aa_point) which convert points/lines into triangles.  In those
+ * cases we don't want to accidentally cull the triangles.
+ *
+ * \param scissor  should the rasterizer state enable scissoring?
+ * \param flatshade  should the rasterizer state use flat shading?
+ * \return  rasterizer CSO handle
+ */
+void *
+draw_get_rasterizer_no_cull( struct draw_context *draw,
+                             boolean scissor,
+                             boolean flatshade )
+{
+   if (!draw->rasterizer_no_cull[scissor][flatshade]) {
+      /* create now */
+      struct pipe_context *pipe = draw->pipe;
+      struct pipe_rasterizer_state rast;
+
+      memset(&rast, 0, sizeof(rast));
+      rast.scissor = scissor;
+      rast.flatshade = flatshade;
+      rast.front_winding = PIPE_WINDING_CCW;
+      rast.gl_rasterization_rules = draw->rasterizer->gl_rasterization_rules;
+
+      draw->rasterizer_no_cull[scissor][flatshade] =
+         pipe->create_rasterizer_state(pipe, &rast);
+   }
+   return draw->rasterizer_no_cull[scissor][flatshade];
+}
diff --git a/src/gallium/auxiliary/draw/draw_context.h b/src/gallium/auxiliary/draw/draw_context.h
index acd81b9..3b21a88 100644
--- a/src/gallium/auxiliary/draw/draw_context.h
+++ b/src/gallium/auxiliary/draw/draw_context.h
@@ -49,7 +49,7 @@ struct draw_geometry_shader;
 struct tgsi_sampler;
 
 
-struct draw_context *draw_create( void );
+struct draw_context *draw_create( struct pipe_context *pipe );
 
 void draw_destroy( struct draw_context *draw );
 
@@ -60,7 +60,8 @@ void draw_set_clip_state( struct draw_context *pipe,
                           const struct pipe_clip_state *clip );
 
 void draw_set_rasterizer_state( struct draw_context *draw,
-                                const struct pipe_rasterizer_state *raster );
+                                const struct pipe_rasterizer_state *raster,
+                                void *rast_handle );
 
 void draw_set_rasterize_stage( struct draw_context *draw,
                                struct draw_stage *stage );
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index 8f6ca15..72d7480 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -113,8 +113,6 @@ struct aaline_stage
                                       void **);
    void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
                                        struct pipe_texture **);
-
-   struct pipe_context *pipe;
 };
 
 
@@ -339,6 +337,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
 static boolean
 generate_aaline_fs(struct aaline_stage *aaline)
 {
+   struct pipe_context *pipe = aaline->stage.draw->pipe;
    const struct pipe_shader_state *orig_fs = &aaline->fs->state;
    struct pipe_shader_state aaline_fs;
    struct aa_transform_context transform;
@@ -371,7 +370,7 @@ generate_aaline_fs(struct aaline_stage *aaline)
    aaline->fs->sampler_unit = transform.freeSampler;
 
    aaline->fs->aaline_fs
-      = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs);
+      = aaline->driver_create_fs_state(pipe, &aaline_fs);
    if (aaline->fs->aaline_fs == NULL)
       goto fail;
 
@@ -391,7 +390,7 @@ fail:
 static boolean
 aaline_create_texture(struct aaline_stage *aaline)
 {
-   struct pipe_context *pipe = aaline->pipe;
+   struct pipe_context *pipe = aaline->stage.draw->pipe;
    struct pipe_screen *screen = pipe->screen;
    struct pipe_texture texTemp;
    uint level;
@@ -464,7 +463,7 @@ static boolean
 aaline_create_sampler(struct aaline_stage *aaline)
 {
    struct pipe_sampler_state sampler;
-   struct pipe_context *pipe = aaline->pipe;
+   struct pipe_context *pipe = aaline->stage.draw->pipe;
 
    memset(&sampler, 0, sizeof(sampler));
    sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
@@ -493,13 +492,14 @@ static boolean
 bind_aaline_fragment_shader(struct aaline_stage *aaline)
 {
    struct draw_context *draw = aaline->stage.draw;
+   struct pipe_context *pipe = draw->pipe;
 
    if (!aaline->fs->aaline_fs && 
        !generate_aaline_fs(aaline))
       return FALSE;
 
    draw->suspend_flushing = TRUE;
-   aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs);
+   aaline->driver_bind_fs_state(pipe, aaline->fs->aaline_fs);
    draw->suspend_flushing = FALSE;
 
    return TRUE;
@@ -639,8 +639,10 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
 {
    auto struct aaline_stage *aaline = aaline_stage(stage);
    struct draw_context *draw = stage->draw;
-   struct pipe_context *pipe = aaline->pipe;
+   struct pipe_context *pipe = draw->pipe;
+   const struct pipe_rasterizer_state *rast = draw->rasterizer;
    uint num_samplers;
+   void *r;
 
    assert(draw->rasterizer->line_smooth);
 
@@ -679,6 +681,11 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
    draw->suspend_flushing = TRUE;
    aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
    aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture);
+
+   /* Disable triangle culling, stippling, unfilled mode etc. */
+   r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
+   pipe->bind_rasterizer_state(pipe, r);
+
    draw->suspend_flushing = FALSE;
 
    /* now really draw first line */
@@ -692,7 +699,7 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
 {
    struct draw_context *draw = stage->draw;
    struct aaline_stage *aaline = aaline_stage(stage);
-   struct pipe_context *pipe = aaline->pipe;
+   struct pipe_context *pipe = draw->pipe;
 
    stage->line = aaline_first_line;
    stage->next->flush( stage->next, flags );
@@ -704,6 +711,12 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
                                       aaline->state.sampler);
    aaline->driver_set_sampler_textures(pipe, aaline->num_textures,
                                        aaline->state.texture);
+
+   /* restore original rasterizer state */
+   if (draw->rast_handle) {
+      pipe->bind_rasterizer_state(pipe, draw->rast_handle);
+   }
+
    draw->suspend_flushing = FALSE;
 
    draw->extra_shader_outputs.slot = 0;
@@ -721,6 +734,7 @@ static void
 aaline_destroy(struct draw_stage *stage)
 {
    struct aaline_stage *aaline = aaline_stage(stage);
+   struct pipe_context *pipe = stage->draw->pipe;
    uint i;
 
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
@@ -728,7 +742,7 @@ aaline_destroy(struct draw_stage *stage)
    }
 
    if (aaline->sampler_cso)
-      aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso);
+      pipe->delete_sampler_state(pipe, aaline->sampler_cso);
 
    if (aaline->texture)
       pipe_texture_reference(&aaline->texture, NULL);
@@ -787,13 +801,14 @@ aaline_create_fs_state(struct pipe_context *pipe,
 {
    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
    struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader);
+
    if (aafs == NULL)
       return NULL;
 
    aafs->state = *fs;
 
    /* pass-through */
-   aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs);
+   aafs->driver_fs = aaline->driver_create_fs_state(pipe, fs);
 
    return aafs;
 }
@@ -808,8 +823,7 @@ aaline_bind_fs_state(struct pipe_context *pipe, void *fs)
    /* save current */
    aaline->fs = aafs;
    /* pass-through */
-   aaline->driver_bind_fs_state(aaline->pipe,
-                                (aafs ? aafs->driver_fs : NULL));
+   aaline->driver_bind_fs_state(pipe, (aafs ? aafs->driver_fs : NULL));
 }
 
 
@@ -818,11 +832,12 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs)
 {
    struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
    struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
+
    /* pass-through */
-   aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs);
+   aaline->driver_delete_fs_state(pipe, aafs->driver_fs);
 
    if (aafs->aaline_fs)
-      aaline->driver_delete_fs_state(aaline->pipe, aafs->aaline_fs);
+      aaline->driver_delete_fs_state(pipe, aafs->aaline_fs);
 
    FREE(aafs);
 }
@@ -839,7 +854,7 @@ aaline_bind_sampler_states(struct pipe_context *pipe,
    aaline->num_samplers = num;
 
    /* pass-through */
-   aaline->driver_bind_sampler_states(aaline->pipe, num, sampler);
+   aaline->driver_bind_sampler_states(pipe, num, sampler);
 }
 
 
@@ -860,7 +875,7 @@ aaline_set_sampler_textures(struct pipe_context *pipe,
    aaline->num_textures = num;
 
    /* pass-through */
-   aaline->driver_set_sampler_textures(aaline->pipe, num, texture);
+   aaline->driver_set_sampler_textures(pipe, num, texture);
 }
 
 
@@ -883,8 +898,6 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
    if (!aaline)
       goto fail;
 
-   aaline->pipe = pipe;
-
    /* create special texture, sampler state */
    if (!aaline_create_texture(aaline))
       goto fail;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
index 9f9fb43..bba6f50 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
@@ -107,8 +107,6 @@ struct aapoint_stage
                                     const struct pipe_shader_state *);
    void (*driver_bind_fs_state)(struct pipe_context *, void *);
    void (*driver_delete_fs_state)(struct pipe_context *, void *);
-
-   struct pipe_context *pipe;
 };
 
 
@@ -499,6 +497,7 @@ generate_aapoint_fs(struct aapoint_stage *aapoint)
    struct pipe_shader_state aapoint_fs;
    struct aa_transform_context transform;
    const uint newLen = tgsi_num_tokens(orig_fs->tokens) + NUM_NEW_TOKENS;
+   struct pipe_context *pipe = aapoint->stage.draw->pipe;
 
    aapoint_fs = *orig_fs; /* copy to init */
    aapoint_fs.tokens = tgsi_alloc_tokens(newLen);
@@ -527,7 +526,7 @@ generate_aapoint_fs(struct aapoint_stage *aapoint)
 #endif
 
    aapoint->fs->aapoint_fs
-      = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs);
+      = aapoint->driver_create_fs_state(pipe, &aapoint_fs);
    if (aapoint->fs->aapoint_fs == NULL)
       goto fail;
 
@@ -549,13 +548,14 @@ static boolean
 bind_aapoint_fragment_shader(struct aapoint_stage *aapoint)
 {
    struct draw_context *draw = aapoint->stage.draw;
+   struct pipe_context *pipe = draw->pipe;
 
    if (!aapoint->fs->aapoint_fs &&
        !generate_aapoint_fs(aapoint))
       return FALSE;
 
    draw->suspend_flushing = TRUE;
-   aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs);
+   aapoint->driver_bind_fs_state(pipe, aapoint->fs->aapoint_fs);
    draw->suspend_flushing = FALSE;
 
    return TRUE;
@@ -679,6 +679,9 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
 {
    auto struct aapoint_stage *aapoint = aapoint_stage(stage);
    struct draw_context *draw = stage->draw;
+   struct pipe_context *pipe = draw->pipe;
+   const struct pipe_rasterizer_state *rast = draw->rasterizer;
+   void *r;
 
    assert(draw->rasterizer->point_smooth);
 
@@ -716,6 +719,14 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
       }
    }
 
+   draw->suspend_flushing = TRUE;
+
+   /* Disable triangle culling, stippling, unfilled mode etc. */
+   r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
+   pipe->bind_rasterizer_state(pipe, r);
+
+   draw->suspend_flushing = FALSE;
+
    /* now really draw first point */
    stage->point = aapoint_point;
    stage->point(stage, header);
@@ -727,7 +738,7 @@ aapoint_flush(struct draw_stage *stage, unsigned flags)
 {
    struct draw_context *draw = stage->draw;
    struct aapoint_stage *aapoint = aapoint_stage(stage);
-   struct pipe_context *pipe = aapoint->pipe;
+   struct pipe_context *pipe = draw->pipe;
 
    stage->point = aapoint_first_point;
    stage->next->flush( stage->next, flags );
@@ -735,6 +746,12 @@ aapoint_flush(struct draw_stage *stage, unsigned flags)
    /* restore original frag shader */
    draw->suspend_flushing = TRUE;
    aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs);
+
+   /* restore original rasterizer state */
+   if (draw->rast_handle) {
+      pipe->bind_rasterizer_state(pipe, draw->rast_handle);
+   }
+
    draw->suspend_flushing = FALSE;
 
    draw->extra_shader_outputs.slot = 0;
@@ -811,7 +828,7 @@ aapoint_create_fs_state(struct pipe_context *pipe,
    aafs->state = *fs;
 
    /* pass-through */
-   aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs);
+   aafs->driver_fs = aapoint->driver_create_fs_state(pipe, fs);
 
    return aafs;
 }
@@ -825,7 +842,7 @@ aapoint_bind_fs_state(struct pipe_context *pipe, void *fs)
    /* save current */
    aapoint->fs = aafs;
    /* pass-through */
-   aapoint->driver_bind_fs_state(aapoint->pipe,
+   aapoint->driver_bind_fs_state(pipe,
                                  (aafs ? aafs->driver_fs : NULL));
 }
 
@@ -837,10 +854,10 @@ aapoint_delete_fs_state(struct pipe_context *pipe, void *fs)
    struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
 
    /* pass-through */
-   aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs);
+   aapoint->driver_delete_fs_state(pipe, aafs->driver_fs);
 
    if (aafs->aapoint_fs)
-      aapoint->driver_delete_fs_state(aapoint->pipe, aafs->aapoint_fs);
+      aapoint->driver_delete_fs_state(pipe, aafs->aapoint_fs);
 
    FREE(aafs);
 }
@@ -857,8 +874,6 @@ draw_install_aapoint_stage(struct draw_context *draw,
 {
    struct aapoint_stage *aapoint;
 
-   pipe->draw = (void *) draw;
-
    /*
     * Create / install AA point drawing / prim stage
     */
@@ -866,8 +881,6 @@ draw_install_aapoint_stage(struct draw_context *draw,
    if (aapoint == NULL)
       return FALSE;
 
-   aapoint->pipe = pipe;
-
    /* save original driver functions */
    aapoint->driver_create_fs_state = pipe->create_fs_state;
    aapoint->driver_bind_fs_state = pipe->bind_fs_state;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
index 3073c87..265a420 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
@@ -28,6 +28,7 @@
 /* Authors:  Keith Whitwell <keith at tungstengraphics.com>
  */
 
+#include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_shader_tokens.h"
 #include "util/u_math.h"
@@ -142,9 +143,40 @@ static void wideline_line( struct draw_stage *stage,
 }
 
 
+static void wideline_first_line( struct draw_stage *stage, 
+                                 struct prim_header *header )
+{
+   struct draw_context *draw = stage->draw;
+   struct pipe_context *pipe = draw->pipe;
+   const struct pipe_rasterizer_state *rast = draw->rasterizer;
+   void *r;
+
+   /* Disable triangle culling, stippling, unfilled mode etc. */
+   r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
+   draw->suspend_flushing = TRUE;
+   pipe->bind_rasterizer_state(pipe, r);
+   draw->suspend_flushing = FALSE;
+
+   stage->line = wideline_line;
+
+   wideline_line(stage, header);
+}
+
+
 static void wideline_flush( struct draw_stage *stage, unsigned flags )
 {
+   struct draw_context *draw = stage->draw;
+   struct pipe_context *pipe = draw->pipe;
+
+   stage->line = wideline_first_line;
    stage->next->flush( stage->next, flags );
+
+   /* restore original rasterizer state */
+   if (draw->rast_handle) {
+      draw->suspend_flushing = TRUE;
+      pipe->bind_rasterizer_state(pipe, draw->rast_handle);
+      draw->suspend_flushing = FALSE;
+   }
 }
 
 
@@ -171,7 +203,7 @@ struct draw_stage *draw_wide_line_stage( struct draw_context *draw )
    wide->stage.name = "wide-line";
    wide->stage.next = NULL;
    wide->stage.point = draw_pipe_passthrough_point;
-   wide->stage.line = wideline_line;
+   wide->stage.line = wideline_first_line;
    wide->stage.tri = draw_pipe_passthrough_tri;
    wide->stage.flush = wideline_flush;
    wide->stage.reset_stipple_counter = wideline_reset_stipple_counter;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
index fdabce7..d6d7513 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
@@ -52,6 +52,7 @@
  */
 
 
+#include "pipe/p_context.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "pipe/p_defines.h"
@@ -213,6 +214,9 @@ static void widepoint_first_point( struct draw_stage *stage,
 {
    struct widepoint_stage *wide = widepoint_stage(stage);
    struct draw_context *draw = stage->draw;
+   struct pipe_context *pipe = draw->pipe;
+   const struct pipe_rasterizer_state *rast = draw->rasterizer;
+   void *r;
 
    wide->half_point_size = 0.5f * draw->rasterizer->point_size;
    wide->xbias = 0.0;
@@ -222,6 +226,12 @@ static void widepoint_first_point( struct draw_stage *stage,
       wide->xbias = 0.125;
    }
 
+   /* Disable triangle culling, stippling, unfilled mode etc. */
+   r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
+   draw->suspend_flushing = TRUE;
+   pipe->bind_rasterizer_state(pipe, r);
+   draw->suspend_flushing = FALSE;
+
    /* XXX we won't know the real size if it's computed by the vertex shader! */
    if ((draw->rasterizer->point_size > draw->pipeline.wide_point_threshold) ||
        (draw->rasterizer->sprite_coord_enable && draw->pipeline.point_sprite)) {
@@ -277,9 +287,19 @@ static void widepoint_first_point( struct draw_stage *stage,
 
 static void widepoint_flush( struct draw_stage *stage, unsigned flags )
 {
+   struct draw_context *draw = stage->draw;
+   struct pipe_context *pipe = draw->pipe;
+
    stage->point = widepoint_first_point;
    stage->next->flush( stage->next, flags );
    stage->draw->extra_shader_outputs.slot = 0;
+
+   /* restore original rasterizer state */
+   if (draw->rast_handle) {
+      draw->suspend_flushing = TRUE;
+      pipe->bind_rasterizer_state(pipe, draw->rast_handle);
+      draw->suspend_flushing = FALSE;
+   }
 }
 
 
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 1e6e01a..3fe3dc5 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -82,6 +82,8 @@ struct vertex_header {
  */
 struct draw_context
 {
+   struct pipe_context *pipe;
+
    /** Drawing/primitive pipeline stages */
    struct {
       struct draw_stage *first;  /**< one of the following */
@@ -174,8 +176,14 @@ struct draw_context
 
    double mrd;  /**< minimum resolvable depth value, for polygon offset */
 
-   /* pipe state that we need: */
+   /** Current rasterizer state given to us by the driver */
    const struct pipe_rasterizer_state *rasterizer;
+   /** Driver CSO handle for the current rasterizer state */
+   void *rast_handle;
+
+   /** Rasterizer CSOs without culling/stipple/etc */
+   void *rasterizer_no_cull[2][2];
+
    struct pipe_viewport_state viewport;
    boolean identity_viewport;
 
@@ -345,5 +353,10 @@ void draw_do_flush( struct draw_context *draw, unsigned flags );
 
 
 
+void *
+draw_get_rasterizer_no_cull( struct draw_context *draw,
+                             boolean scissor,
+                             boolean flatshade );
+
 
 #endif /* DRAW_PRIVATE_H */
diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index 3d45a22..2f1ab75 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -210,7 +210,7 @@ i915_create_context(struct pipe_screen *screen, void *priv)
    /*
     * Create drawing context and plug our rendering stage into it.
     */
-   i915->draw = draw_create();
+   i915->draw = draw_create(&i915->base);
    assert(i915->draw);
    if (!debug_get_bool_option("I915_NO_VBUF", FALSE)) {
       draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915));
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index 6216991..7a19cec 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -714,7 +714,8 @@ static void i915_bind_rasterizer_state( struct pipe_context *pipe,
 
    /* pass-through to draw module */
    draw_set_rasterizer_state(i915->draw,
-                          (i915->rasterizer ? i915->rasterizer->templ : NULL));
+                           (i915->rasterizer ? i915->rasterizer->templ : NULL),
+                           raster);
 
    i915->dirty |= I915_NEW_RASTERIZER;
 }
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index e31ae6a..6962a79 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -174,7 +174,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
    /*
     * Create drawing context and plug our rendering stage into it.
     */
-   llvmpipe->draw = draw_create();
+   llvmpipe->draw = draw_create(&llvmpipe->pipe);
    if (!llvmpipe->draw) 
       goto fail;
 
diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
index feb0128..8592da0 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
@@ -38,19 +38,26 @@ void *
 llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
                                  const struct pipe_rasterizer_state *rast)
 {
+   /* We do nothing special with rasterizer state.
+    * The CSO handle is just a pointer to a pipe_rasterizer_state object.
+    */
    return mem_dup(rast, sizeof(*rast));
 }
 
-void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
-                                    void *rasterizer)
+
+
+void
+llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+   const struct pipe_rasterizer_state *rasterizer =
+      (const struct pipe_rasterizer_state *) handle;
 
    if (llvmpipe->rasterizer == rasterizer)
       return;
 
    /* pass-through to draw module */
-   draw_set_rasterizer_state(llvmpipe->draw, rasterizer);
+   draw_set_rasterizer_state(llvmpipe->draw, rasterizer, handle);
 
    llvmpipe->rasterizer = rasterizer;
 
@@ -68,6 +75,7 @@ void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
    llvmpipe->dirty |= LP_NEW_RASTERIZER;
 }
 
+
 void llvmpipe_delete_rasterizer_state(struct pipe_context *pipe,
                                       void *rasterizer)
 {
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 7be12fc..031cc12 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -129,7 +129,7 @@ nv50_create(struct pipe_screen *pscreen, void *priv)
 	nv50_init_state_functions(nv50);
 	nv50_init_query_functions(nv50);
 
-	nv50->draw = draw_create();
+	nv50->draw = draw_create(&nv50->pipe);
 	assert(nv50->draw);
 	draw_set_rasterize_stage(nv50->draw, nv50_draw_render_stage(nv50));
 
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 86b98a4..0d5ebdf 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -181,7 +181,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
         r300->context.draw_range_elements = r300_swtcl_draw_range_elements;
 
         /* Create a Draw. This is used for SW TCL. */
-        r300->draw = draw_create();
+        r300->draw = draw_create(&r300->context);
         /* Enable our renderer. */
         draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
         /* Enable Draw's clipping. */
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 1f6f99d..9c5eba4 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -810,7 +810,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
 
     if (r300->draw) {
         draw_flush(r300->draw);
-        draw_set_rasterizer_state(r300->draw, &rs->rs);
+        draw_set_rasterizer_state(r300->draw, &rs->rs, state);
     }
 
     if (rs) {
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index ddc35bc..7c7abc9 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -298,7 +298,7 @@ softpipe_create_context( struct pipe_screen *screen,
    /*
     * Create drawing context and plug our rendering stage into it.
     */
-   softpipe->draw = draw_create();
+   softpipe->draw = draw_create(&softpipe->pipe);
    if (!softpipe->draw) 
       goto fail;
 
diff --git a/src/gallium/drivers/softpipe/sp_state_rasterizer.c b/src/gallium/drivers/softpipe/sp_state_rasterizer.c
index a5b0033..c9ede09 100644
--- a/src/gallium/drivers/softpipe/sp_state_rasterizer.c
+++ b/src/gallium/drivers/softpipe/sp_state_rasterizer.c
@@ -49,7 +49,7 @@ void softpipe_bind_rasterizer_state(struct pipe_context *pipe,
       return;
 
    /* pass-through to draw module */
-   draw_set_rasterizer_state(softpipe->draw, rasterizer);
+   draw_set_rasterizer_state(softpipe->draw, rasterizer, rasterizer);
 
    softpipe->rasterizer = rasterizer;
 
diff --git a/src/gallium/drivers/svga/svga_pipe_rasterizer.c b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
index 3571778..5253c45 100644
--- a/src/gallium/drivers/svga/svga_pipe_rasterizer.c
+++ b/src/gallium/drivers/svga/svga_pipe_rasterizer.c
@@ -222,7 +222,8 @@ static void svga_bind_rasterizer_state( struct pipe_context *pipe,
 
    svga->curr.rast = raster;
 
-   draw_set_rasterizer_state(svga->swtnl.draw, raster ? &raster->templ : NULL);
+   draw_set_rasterizer_state(svga->swtnl.draw, raster ? &raster->templ : NULL,
+                             state);
    
    svga->dirty |= SVGA_NEW_RAST;
 }
diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c b/src/gallium/drivers/svga/svga_swtnl_draw.c
index da15be1..0758f3f 100644
--- a/src/gallium/drivers/svga/svga_swtnl_draw.c
+++ b/src/gallium/drivers/svga/svga_swtnl_draw.c
@@ -134,7 +134,7 @@ boolean svga_init_swtnl( struct svga_context *svga )
    /*
     * Create drawing context and plug our rendering stage into it.
     */
-   svga->swtnl.draw = draw_create();
+   svga->swtnl.draw = draw_create(&svga->pipe);
    if (svga->swtnl.draw == NULL)
       goto fail;
 
diff --git a/src/gallium/drivers/svga/svga_swtnl_state.c b/src/gallium/drivers/svga/svga_swtnl_state.c
index 35f36a8..6dfdb5e 100644
--- a/src/gallium/drivers/svga/svga_swtnl_state.c
+++ b/src/gallium/drivers/svga/svga_swtnl_state.c
@@ -113,7 +113,8 @@ static int update_swtnl_draw( struct svga_context *svga,
 
    if (dirty & SVGA_NEW_RAST)
       draw_set_rasterizer_state(svga->swtnl.draw,
-                                &svga->curr.rast->templ);
+                                &svga->curr.rast->templ,
+                                (void *) svga->curr.rast);
 
    if (dirty & SVGA_NEW_FRAME_BUFFER)
       draw_set_mrd(svga->swtnl.draw, 
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index de8beaf..684a60b 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -115,7 +115,7 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
    _vbo_CreateContext(ctx);
 
 #if FEATURE_feedback || FEATURE_drawpix
-   st->draw = draw_create(); /* for selection/feedback */
+   st->draw = draw_create(pipe); /* for selection/feedback */
 
    /* Disable draw options that might convert points/lines to tris, etc.
     * as that would foul-up feedback/selection mode.
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index 087f2f2..6bffdd8 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -134,7 +134,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
    assert(draw);
    draw_set_viewport_state(draw, &st->state.viewport);
    draw_set_clip_state(draw, &st->state.clip);
-   draw_set_rasterizer_state(draw, &st->state.rasterizer);
+   draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL);
    draw_bind_vertex_shader(draw, st->vp_varient->draw_shader);
    set_feedback_vertex_format(ctx);
 




More information about the mesa-commit mailing list