u_blitter: add a msaa parameter to util_blitter_clear
[mesa.git] / src / gallium / drivers / svga / svga_pipe_rasterizer.c
index b01b04c2cfc159e3da6100766d2fdc3d62de18dd..7d5936fa1ece2aedf1c75ef7748922bb4dfe625d 100644 (file)
@@ -105,18 +105,20 @@ static void
 define_rasterizer_object(struct svga_context *svga,
                          struct svga_rasterizer_state *rast)
 {
+   struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
    unsigned fill_mode = translate_fill_mode(rast->templ.fill_front);
-   unsigned cull_mode = translate_cull_mode(rast->templ.cull_face);
-   int depth_bias = rast->templ.offset_units;
-   float slope_scaled_depth_bias =  rast->templ.offset_scale;
-   float depth_bias_clamp = 0.0; /* XXX fix me */
-   unsigned try;
+   const unsigned cull_mode = translate_cull_mode(rast->templ.cull_face);
+   const int depth_bias = rast->templ.offset_units;
+   const float slope_scaled_depth_bias = rast->templ.offset_scale;
+   /* PIPE_CAP_POLYGON_OFFSET_CLAMP not supported: */
+   const float depth_bias_clamp = 0.0;
    const float line_width = rast->templ.line_width > 0.0f ?
       rast->templ.line_width : 1.0f;
    const uint8 line_factor = rast->templ.line_stipple_enable ?
       rast->templ.line_stipple_factor : 0;
    const uint16 line_pattern = rast->templ.line_stipple_enable ?
       rast->templ.line_stipple_pattern : 0;
+   unsigned try;
 
    rast->id = util_bitmask_add(svga->rast_object_id_bm);
 
@@ -129,6 +131,8 @@ define_rasterizer_object(struct svga_context *svga,
    }
 
    for (try = 0; try < 2; try++) {
+      const uint8 pv_last = !rast->templ.flatshade_first &&
+         svgascreen->haveProvokingVertex;
       enum pipe_error ret =
          SVGA3D_vgpu10_DefineRasterizerState(svga->swc,
                                              rast->id,
@@ -138,7 +142,7 @@ define_rasterizer_object(struct svga_context *svga,
                                              depth_bias,
                                              depth_bias_clamp,
                                              slope_scaled_depth_bias,
-                                             rast->templ.depth_clip,
+                                             rast->templ.depth_clip_near,
                                              rast->templ.scissor,
                                              rast->templ.multisample,
                                              rast->templ.line_smooth,
@@ -146,7 +150,7 @@ define_rasterizer_object(struct svga_context *svga,
                                              rast->templ.line_stipple_enable,
                                              line_factor,
                                              line_pattern,
-                                             !rast->templ.flatshade_first);
+                                             pv_last);
       if (ret == PIPE_OK)
          return;
       svga_context_flush(svga, NULL);
@@ -168,25 +172,27 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
    /* need this for draw module. */
    rast->templ = *templ;
 
-   /* light_twoside          - XXX: need fragment shader variant */
-   /* poly_smooth            - XXX: no fallback available */
-   /* poly_stipple_enable    - draw module */
-   /* sprite_coord_enable    - ? */
-   /* point_quad_rasterization - ? */
-   /* point_size_per_vertex  - ? */
-   /* sprite_coord_mode      - ??? */
-   /* flatshade_first        - handled by index translation */
-   /* half_pixel_center      - XXX - viewport code */
-   /* line_width             - draw module */
-   /* fill_cw, fill_ccw      - draw module or index translation */
-
    rast->shademode = svga_translate_flatshade(templ->flatshade);
    rast->cullmode = svga_translate_cullmode(templ->cull_face, templ->front_ccw);
    rast->scissortestenable = templ->scissor;
    rast->multisampleantialias = templ->multisample;
    rast->antialiasedlineenable = templ->line_smooth;
    rast->lastpixel = templ->line_last_pixel;
-   rast->pointsprite = templ->sprite_coord_enable != 0x0;
+   rast->pointsprite = templ->point_quad_rasterization;
+
+   if (rast->templ.multisample) {
+      /* The OpenGL 3.0 spec says points are always drawn as circles when
+       * MSAA is enabled.  Note that our implementation isn't 100% correct,
+       * though.  Our smooth point implementation involves drawing a square,
+       * computing fragment distance from point center, then attenuating
+       * the fragment alpha value.  We should not attenuate alpha if msaa
+       * is enabled.  We should kill fragments entirely outside the circle
+       * and let the GPU compute per-fragment coverage.
+       * But as-is, our implementation gives acceptable results and passes
+       * Piglit's MSAA point smooth test.
+       */
+      rast->templ.point_smooth = TRUE;
+   }
 
    if (templ->point_smooth) {
       /* For smooth points we need to generate fragments for at least
@@ -229,7 +235,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
          rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES;
          rast->need_pipeline_lines_str = "line stipple";
       }
-   } 
+   }
 
    if (!svga_have_vgpu10(svga) && templ->point_smooth) {
       rast->need_pipeline |= SVGA_PIPELINE_FLAG_POINTS;
@@ -263,23 +269,23 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
          break;
 
       case PIPE_FACE_FRONT:
-         offset = offset_front;
-         fill = fill_front;
+         offset = offset_back;
+         fill = fill_back;
          break;
 
       case PIPE_FACE_BACK:
-         offset = offset_back;
-         fill = fill_back;
+         offset = offset_front;
+         fill = fill_front;
          break;
 
       case PIPE_FACE_NONE:
-         if (fill_front != fill_back || offset_front != offset_back) 
-         {
+         if (fill_front != fill_back || offset_front != offset_back) {
             /* Always need the draw module to work out different
              * front/back fill modes:
              */
             rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
             rast->need_pipeline_tris_str = "different front/back fillmodes";
+            fill = PIPE_POLYGON_MODE_FILL;
          }
          else {
             offset = offset_front;
@@ -299,9 +305,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
       if (fill != PIPE_POLYGON_MODE_FILL &&
           (templ->flatshade ||
            templ->light_twoside ||
-           offset ||
-           templ->cull_face != PIPE_FACE_NONE)) 
-      {
+           offset)) {
          fill = PIPE_POLYGON_MODE_FILL;
          rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
          rast->need_pipeline_tris_str = "unfilled primitives with no index manipulation";
@@ -311,8 +315,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
        * then we also need the pipeline for tris.
        */
       if (fill == PIPE_POLYGON_MODE_LINE &&
-          (rast->need_pipeline & SVGA_PIPELINE_FLAG_LINES))
-      {
+          (rast->need_pipeline & SVGA_PIPELINE_FLAG_LINES)) {
          fill = PIPE_POLYGON_MODE_FILL;
          rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
          rast->need_pipeline_tris_str = "decomposing lines";
@@ -321,8 +324,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
       /* Similarly for points:
        */
       if (fill == PIPE_POLYGON_MODE_POINT &&
-          (rast->need_pipeline & SVGA_PIPELINE_FLAG_POINTS))
-      {
+          (rast->need_pipeline & SVGA_PIPELINE_FLAG_POINTS)) {
          fill = PIPE_POLYGON_MODE_FILL;
          rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
          rast->need_pipeline_tris_str = "decomposing points";
@@ -361,6 +363,8 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
    }
 
    svga->hud.num_rasterizer_objects++;
+   SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws,
+                        SVGA_STATS_COUNT_RASTERIZERSTATE);
 
    return rast;
 }
@@ -372,11 +376,18 @@ svga_bind_rasterizer_state(struct pipe_context *pipe, void *state)
    struct svga_context *svga = svga_context(pipe);
    struct svga_rasterizer_state *raster = (struct svga_rasterizer_state *)state;
 
-   if (!raster ||
-       !svga->curr.rast ||
-       raster->templ.poly_stipple_enable !=
-       svga->curr.rast->templ.poly_stipple_enable) {
-      svga->dirty |= SVGA_NEW_STIPPLE;
+   if (!raster || !svga->curr.rast) {
+      svga->dirty |= SVGA_NEW_STIPPLE | SVGA_NEW_DEPTH_STENCIL_ALPHA;
+   }
+   else {
+      if (raster->templ.poly_stipple_enable !=
+          svga->curr.rast->templ.poly_stipple_enable) {
+         svga->dirty |= SVGA_NEW_STIPPLE;
+      }
+      if (raster->templ.rasterizer_discard !=
+          svga->curr.rast->templ.rasterizer_discard) {
+         svga->dirty |= SVGA_NEW_DEPTH_STENCIL_ALPHA;
+      }
    }
 
    svga->curr.rast = raster;