u_blitter: add a msaa parameter to util_blitter_clear
[mesa.git] / src / gallium / drivers / svga / svga_pipe_rasterizer.c
index d397c95da98cd92e24fb7f1c156bb552f7e42ca5..7d5936fa1ece2aedf1c75ef7748922bb4dfe625d 100644 (file)
@@ -38,8 +38,8 @@
 
 /* Hardware frontwinding is always set up as SVGA3D_FRONTWINDING_CW.
  */
-static SVGA3dFace svga_translate_cullmode( unsigned mode,
-                                           unsigned front_ccw )
+static SVGA3dFace
+svga_translate_cullmode(unsigned mode, unsigned front_ccw)
 {
    const int hw_front_ccw = 0;  /* hardware is always CW */
    switch (mode) {
@@ -57,7 +57,8 @@ static SVGA3dFace svga_translate_cullmode( unsigned mode,
    }
 }
 
-static SVGA3dShadeMode svga_translate_flatshade( unsigned mode )
+static SVGA3dShadeMode
+svga_translate_flatshade(unsigned mode)
 {
    return mode ? SVGA3D_SHADEMODE_FLAT : SVGA3D_SHADEMODE_SMOOTH;
 }
@@ -104,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);
 
@@ -128,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,
@@ -137,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,
@@ -145,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);
@@ -158,7 +163,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
                              const struct pipe_rasterizer_state *templ)
 {
    struct svga_context *svga = svga_context(pipe);
-   struct svga_rasterizer_state *rast = CALLOC_STRUCT( svga_rasterizer_state );
+   struct svga_rasterizer_state *rast = CALLOC_STRUCT(svga_rasterizer_state);
    struct svga_screen *screen = svga_screen(pipe->screen);
 
    if (!rast)
@@ -167,26 +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->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";
@@ -360,22 +362,32 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
                          "GL_POLYGON_SMOOTH not supported");
    }
 
-   svga->hud.num_state_objects++;
+   svga->hud.num_rasterizer_objects++;
+   SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws,
+                        SVGA_STATS_COUNT_RASTERIZERSTATE);
 
    return rast;
 }
 
-static void svga_bind_rasterizer_state( struct pipe_context *pipe,
-                                        void *state )
+
+static void
+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;
@@ -383,6 +395,7 @@ static void svga_bind_rasterizer_state( struct pipe_context *pipe,
    svga->dirty |= SVGA_NEW_RAST;
 }
 
+
 static void
 svga_delete_rasterizer_state(struct pipe_context *pipe, void *state)
 {
@@ -405,19 +418,14 @@ svga_delete_rasterizer_state(struct pipe_context *pipe, void *state)
    }
 
    FREE(state);
-   svga->hud.num_state_objects--;
+   svga->hud.num_rasterizer_objects--;
 }
 
 
-void svga_init_rasterizer_functions( struct svga_context *svga )
+void
+svga_init_rasterizer_functions(struct svga_context *svga)
 {
    svga->pipe.create_rasterizer_state = svga_create_rasterizer_state;
    svga->pipe.bind_rasterizer_state = svga_bind_rasterizer_state;
    svga->pipe.delete_rasterizer_state = svga_delete_rasterizer_state;
 }
-
-
-/***********************************************************************
- * Hardware state update
- */
-